This is the mail archive of the libstdc++@sourceware.cygnus.com 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]

Re: algorithm specialisations for vector/basic_string iterators


Philip Martin <pm@corris.dircon.co.uk> writes:

> An alternative might
> be to use some sort of traits mechanism to dispatch __normal_iterators
> to the appropriate specialisation.

Here is a traits based solution.  I think this is better than adding
more template functions for copy().

At present this only fixes the problem for copy(). If we can agree
that this is the best way to solve the problem then it can be extended
to any other algorithms that need it. My I guess is that copy() is the
most important.

Two points:
- I still don't know how to get the testsuite to test for this
  behaviour.
- I put a forward declaration of __normal_iterator in type_traits.h,
  perhaps an include would be better but things never seem to be in
  the right header file.

Philip



diff -c3prN libstdc++/ChangeLog libstdc++-modified/ChangeLog
*** libstdc++/ChangeLog	Mon Nov 15 11:19:41 1999
--- libstdc++-modified/ChangeLog	Mon Nov 15 17:29:46 1999
***************
*** 1,3 ****
--- 1,10 ----
+ 1999-11-15  Philip Martin  <pm@corris.dircon.co.uk>
+ 
+ 	* src/stl-inst.cc: Use typedef to refer to iterator
+ 	* stl/bits/stl_algobase.h: Add traits based dispatch for
+ 	__normal_iterator in the copy()algorithm
+ 	* stl/bits/type_traits.h: Add _Is_normal_iterator trait support
+ 
  1999-11-11  Matthias Klose  <doko@cs.tu-berlin.de>
  
  	* stl_deque.h: Use static_casts<size_type>(signed_type).
diff -c3prN libstdc++/src/stl-inst.cc libstdc++-modified/src/stl-inst.cc
*** libstdc++/src/stl-inst.cc	Fri May 14 22:24:47 1999
--- libstdc++-modified/src/stl-inst.cc	Mon Nov 15 15:20:50 1999
*************** namespace std {
*** 47,53 ****
    template
      void
      vector<unsigned int>::
!     _M_insert_aux(__normal_iterator<unsigned int *, vector<unsigned int> >, 
! 		  unsigned int const &);
  
  } //std
--- 47,52 ----
    template
      void
      vector<unsigned int>::
!     _M_insert_aux(vector<unsigned int>::iterator, unsigned int const &);
  
  } //std
diff -c3prN libstdc++/stl/bits/stl_algobase.h libstdc++-modified/stl/bits/stl_algobase.h
*** libstdc++/stl/bits/stl_algobase.h	Sun May 23 15:52:06 1999
--- libstdc++-modified/stl/bits/stl_algobase.h	Mon Nov 15 15:33:38 1999
*************** inline _OutputIter __copy_aux(_InputIter
*** 183,192 ****
    return __copy_aux2(__first, __last, __result, _Trivial());
  }
  
  template <class _InputIter, class _OutputIter>
  inline _OutputIter copy(_InputIter __first, _InputIter __last,
                          _OutputIter __result) {
!   return __copy_aux(__first, __last, __result, __VALUE_TYPE(__first));
  }
  
  // Hack for compilers that don't have partial ordering of function templates
--- 183,220 ----
    return __copy_aux2(__first, __last, __result, _Trivial());
  }
  
+ template<typename _InputIter, typename _OutputIter>
+ inline _OutputIter __copy_ni2(_InputIter __first, _InputIter __last,
+                               _OutputIter __result, __true_type) {
+   return _OutputIter(__copy_aux(__first, __last, __result.base(),
+                                 __VALUE_TYPE(__first)));
+ }
+ 
+ template<typename _InputIter, typename _OutputIter>
+ inline _OutputIter __copy_ni2(_InputIter __first, _InputIter __last,
+                               _OutputIter __result, __false_type) {
+   return __copy_aux(__first, __last, __result, __VALUE_TYPE(__first));
+ }
+ 
+ template<typename _InputIter, typename _OutputIter>
+ inline _OutputIter __copy_ni1(_InputIter __first, _InputIter __last,
+                               _OutputIter __result, __true_type) {
+    typedef typename _Is_normal_iterator<_OutputIter>::_Normal __Normal;
+    return __copy_ni2(__first.base(), __last.base(), __result, __Normal());
+ }
+ 
+ template<typename _InputIter, typename _OutputIter>
+ inline _OutputIter __copy_ni1(_InputIter __first, _InputIter __last,
+                               _OutputIter __result, __false_type) {
+    typedef typename _Is_normal_iterator<_OutputIter>::_Normal __Normal;
+    return __copy_ni2(__first, __last, __result, __Normal());
+ }
+ 
  template <class _InputIter, class _OutputIter>
  inline _OutputIter copy(_InputIter __first, _InputIter __last,
                          _OutputIter __result) {
!    typedef typename _Is_normal_iterator<_InputIter>::_Normal __Normal;
!    return __copy_ni1(__first, __last, __result, __Normal());
  }
  
  // Hack for compilers that don't have partial ordering of function templates
diff -c3prN libstdc++/stl/bits/type_traits.h libstdc++-modified/stl/bits/type_traits.h
*** libstdc++/stl/bits/type_traits.h	Fri Jul 24 19:42:07 1998
--- libstdc++-modified/stl/bits/type_traits.h	Mon Nov 15 15:41:47 1999
*************** __STL_TEMPLATE_NULL struct _Is_integer<u
*** 366,371 ****
--- 366,385 ----
  
  #endif /* __STL_LONG_LONG */
  
+ template<typename _T> struct _Is_normal_iterator {
+    typedef __false_type _Normal;
+ };
+ 
+ // forward declaration hack, should really include this from somewhere
+ namespace std {
+    template<typename _Iterator, typename _Container> class __normal_iterator;
+ };
+ 
+ template<typename _Iterator, typename _Container>
+ struct _Is_normal_iterator< std::__normal_iterator<_Iterator, _Container> > {
+    typedef __true_type _Normal;
+ };
+ 
  #endif /* _CPP_BITS_TYPE_TRAITS_H */
  
  // Local Variables:

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