This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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>(); 
 }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]