This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[patch] : RFC - expanding the testsuite to try multiple iteratorcategories
- From: Chris Jefferson <caj at cs dot york dot ac dot uk>
- To: libstdc++ <libstdc++ at gcc dot gnu dot org>
- Date: Sat, 19 Mar 2005 13:54:17 +0000
- Subject: [patch] : RFC - expanding the testsuite to try multiple iteratorcategories
Apologises for the continuing postings of not-entirely complete patches,
I'm just trying to gather opinions on another change.
This one is entirely testsuite based, so shouldn't make any real
difference. It changes tests so that they are run on all possible
iterator types a class accepts, rather than just the simplest one it
takes (so that all specialisations will be tested).
Unfortunatly I've been unable to make it look as nice as I'd like, and
it involves wrapping templated tests in a class so that they can be
passed around. If people vote that this just looks too messy /
complicated, then I'll just have eash testcase have 3 or 4 almost
identical blocks which test the various types of iterators...
If I don't hear any specific complaints against this, I'll assume that
no-one has a great problem with it, and I'll start adding them to other
tests (my long-term aim is to get to the point where I can call gcov
over the testsuite and get total coverage of the <algorithm> header.
2005-03-19 Christopher Jefferson <chris@bubblescope.net>
* testsuite/testsuite_iterators.h (container_type) : New.
(test_iterators) : New.
* testsuite/25_algorithms/adjacent_find/1.cc : Adapt to test all
possible iterator types rather than just one
* testsuite/25_algorithms/upper_bound/1.cc : Likewise.
Index: testsuite_iterators.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/testsuite/testsuite_iterators.h,v
retrieving revision 1.1.6.3
diff -u -3 -r1.1.6.3 testsuite_iterators.h
--- testsuite_iterators.h 14 Mar 2005 10:38:04 -0000 1.1.6.3
+++ testsuite_iterators.h 19 Mar 2005 13:20:14 -0000
@@ -536,5 +536,103 @@
end()
{ return it(bounds.last); }
};
+
+ /**
+ * @brief A helper class to build test_containers from iterator_tags
+ */
+ template<class iterator_tag, class contained_type>
+ struct container_type
+ { };
+
+ template<class contained_type>
+ struct container_type<contained_type,std::input_iterator_tag>
+ { typedef test_container<contained_type, input_iterator_wrapper> type; };
+
+ template<class contained_type>
+ struct container_type<contained_type,std::output_iterator_tag>
+ { typedef test_container<contained_type, output_iterator_wrapper> type; };
+
+ template<class contained_type>
+ struct container_type<contained_type, std::forward_iterator_tag>
+ { typedef test_container<contained_type, forward_iterator_wrapper> type; };
+
+ template<class contained_type>
+ struct container_type<contained_type, std::bidirectional_iterator_tag>
+ { typedef test_container<contained_type, bidirectional_iterator_wrapper> type; };
+
+ template<class contained_type>
+ struct container_type<contained_type, std::random_access_iterator_tag>
+ { typedef test_container<contained_type, random_access_iterator_wrapper> type; };
+
+ /**
+ * @brief Class to allow testing a function against some iterator type, and all
+ * later ones (to check specialisations).
+ * test_iterators<tag>::test<obj>(); will test obj::test<tag>() for each iterator tag
+ * from the specified one up to random_access_iterator_tag.
+ */
+ template<class iterator_tag>
+ struct test_iterators
+ { };
+
+ template<>
+ struct test_iterators<std::random_access_iterator_tag>
+ {
+ template<class FunctionObject>
+ void static
+ test()
+ { FunctionObject::template test<std::random_access_iterator_tag>(); }
+ };
+
+
+ template<>
+ struct test_iterators<std::bidirectional_iterator_tag>
+ {
+ template<class FunctionObject>
+ void static
+ test()
+ {
+ FunctionObject::template test<std::bidirectional_iterator_tag>();
+ test_iterators<std::random_access_iterator_tag>::test<FunctionObject>();
+ }
+ };
+
+
+ template<>
+ struct test_iterators<std::forward_iterator_tag>
+ {
+ template<class FunctionObject>
+ void static
+ test()
+ {
+ FunctionObject::template test<std::forward_iterator_tag>();
+ test_iterators<std::bidirectional_iterator_tag>::test<FunctionObject>();
+ }
+ };
+
+ template<>
+ struct test_iterators<std::output_iterator_tag>
+ {
+ template<class FunctionObject>
+ void static
+ test()
+ {
+ FunctionObject::template test<std::output_iterator_tag>();
+ test_iterators<std::forward_iterator_tag>::test<FunctionObject>();
+ }
+ };
+
+ template<>
+ struct test_iterators<std::input_iterator_tag>
+ {
+ template<class FunctionObject>
+ void static
+ test()
+ {
+ FunctionObject::template test<std::input_iterator_tag>();
+ test_iterators<std::forward_iterator_tag>::test<FunctionObject>();
+ }
+ };
+
+
}
#endif
Index: 25_algorithms/adjacent_find/1.cc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/testsuite/25_algorithms/adjacent_find/Attic/1.cc,v
retrieving revision 1.1.2.1
diff -u -3 -r1.1.2.1 1.cc
--- 25_algorithms/adjacent_find/1.cc 1 Feb 2005 11:10:14 -0000 1.1.2.1
+++ 25_algorithms/adjacent_find/1.cc 19 Mar 2005 13:20:22 -0000
@@ -22,46 +22,65 @@
#include <testsuite_hooks.h>
#include <testsuite_iterators.h>
-using __gnu_test::test_container;
-using __gnu_test::forward_iterator_wrapper;
+using __gnu_test::test_iterators;
+using __gnu_test::container_type;
using std::adjacent_find;
-typedef test_container<int, forward_iterator_wrapper> Container;
int array[] = {0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1};
-void
-test01()
+struct test01
{
- Container con(array, array);
- VERIFY(adjacent_find(con.begin(), con.end()).ptr == array);
-}
+ template<typename iterator_tag>
+ static void
+ test()
+ {
+ typedef typename container_type<int, iterator_tag>::type Container;
+ Container con(array, array);
+ VERIFY(adjacent_find(con.begin(), con.end()).ptr == array);
+ }
+};
-void
-test02()
+struct test02
{
- Container con(array, array + 1);
- VERIFY(adjacent_find(con.begin(), con.end()).ptr == array + 1);
-}
+ template<typename iterator_tag>
+ static void
+ test()
+ {
+ typedef typename container_type<int, iterator_tag>::type Container;
+ Container con(array, array + 1);
+ VERIFY(adjacent_find(con.begin(), con.end()).ptr == array + 1);
+ }
+};
-void
-test03()
+struct test03
{
- Container con(array, array + 2);
- VERIFY(adjacent_find(con.begin(), con.end()).ptr == array);
-}
+ template<typename iterator_tag>
+ static void
+ test()
+ {
+ typedef typename container_type<int, iterator_tag>::type Container;
+ Container con(array, array + 2);
+ VERIFY(adjacent_find(con.begin(), con.end()).ptr == array);
+ }
+};
-void
-test04()
+struct test04
{
- Container con(array + 1, array + 10);
- VERIFY(adjacent_find(con.begin(), con.end()).ptr == array + 10);
-}
+ template<typename iterator_tag>
+ static void
+ test()
+ {
+ typedef typename container_type<int, iterator_tag>::type Container;
+ Container con(array + 1, array + 10);
+ VERIFY(adjacent_find(con.begin(), con.end()).ptr == array + 10);
+ }
+};
int
main()
{
- test01();
- test02();
- test03();
- test04();
+ test_iterators<std::forward_iterator_tag>::test<test01>();
+ test_iterators<std::forward_iterator_tag>::test<test02>();
+ test_iterators<std::forward_iterator_tag>::test<test03>();
+ test_iterators<std::forward_iterator_tag>::test<test04>();
}
Index: 25_algorithms/upper_bound/1.cc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/testsuite/25_algorithms/upper_bound/Attic/1.cc,v
retrieving revision 1.1.2.1
diff -u -3 -r1.1.2.1 1.cc
--- 25_algorithms/upper_bound/1.cc 1 Feb 2005 11:10:35 -0000 1.1.2.1
+++ 25_algorithms/upper_bound/1.cc 19 Mar 2005 13:20:23 -0000
@@ -22,26 +22,30 @@
#include <testsuite_hooks.h>
#include <testsuite_iterators.h>
-using __gnu_test::test_container;
-using __gnu_test::forward_iterator_wrapper;
+using __gnu_test::test_iterators;
+using __gnu_test::container_type;
using std::upper_bound;
-typedef test_container<int, forward_iterator_wrapper> Container;
int array[] = {0, 0, 0, 0, 1, 1, 1, 1};
-void
-test1()
+struct test01
{
- for(int i = 0; i < 5; ++i)
- for(int j = 4; j < 7; ++j)
- {
- Container con(array + i, array + j);
- VERIFY(upper_bound(con.begin(), con.end(), 0).ptr == array + 4);
- }
-}
+ template<typename iterator_tag>
+ static void
+ test()
+ {
+ typedef typename container_type<int, iterator_tag>::type Container;
+ for(int i = 0; i < 5; ++i)
+ for(int j = 4; j < 7; ++j)
+ {
+ Container con(array + i, array + j);
+ VERIFY(upper_bound(con.begin(), con.end(), 0).ptr == array + 4);
+ }
+ }
+};
int
main()
{
- test1();
+ test_iterators<std::forward_iterator_tag>::test<test01>();
}