From 15b5b6677663b80912c387fdb2f0e7aac5ce343f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 10 Feb 2001 00:26:55 +0000 Subject: [PATCH] Improved interface to indirect_ and reverse_ iterators [SVN r9065] --- include/boost/iterator_adaptors.hpp | 159 +++++++++++++++++++++------- 1 file changed, 121 insertions(+), 38 deletions(-) diff --git a/include/boost/iterator_adaptors.hpp b/include/boost/iterator_adaptors.hpp index d9111c8..30e88a2 100644 --- a/include/boost/iterator_adaptors.hpp +++ b/include/boost/iterator_adaptors.hpp @@ -13,6 +13,8 @@ // Revision History: // 09 Feb 2001 David Abrahams +// Improved interface to indirect_ and reverse_ iterators +// // Rolled back Jeremy's new constructor for now; it was causing // problems with counting_iterator_test // @@ -658,39 +660,77 @@ struct indirect_iterator_policies : public default_iterator_policies { return **x; } }; +// This macro definition is only temporary in this file +# if !defined(BOOST_MSVC) +# define BOOST_ARG_DEPENDENT_TYPENAME typename +# else +# define BOOST_ARG_DEPENDENT_TYPENAME +# endif + +} template struct undefined; namespace boost { + +namespace detail { +# if !defined(BOOST_MSVC) // stragely instantiated even when unused! Maybe try a recursive template someday ;-) + template + struct value_type_of_value_type { + typedef typename boost::detail::iterator_traits::value_type outer_value; + typedef typename boost::detail::iterator_traits::value_type type; + }; +# endif +} + template mutable indirect iterator; - // Immutable reference and pointer type in traits class -> immutable indirect iterator - class InnerTraits = boost::detail::iterator_traits::value_type> + class Value +#if !defined(BOOST_MSVC) + = BOOST_ARG_DEPENDENT_TYPENAME detail::value_type_of_value_type::type +#endif + , class Pointer = Value* + , class Reference = Value& > class indirect_iterator_generator { - typedef boost::detail::iterator_traits OuterTraits; - typedef typename OuterTraits::difference_type difference_type; - typedef typename OuterTraits::iterator_category iterator_category; + typedef boost::detail::iterator_traits outer_traits; + typedef typename outer_traits::difference_type difference_type; + typedef typename outer_traits::iterator_category iterator_category; - typedef typename InnerTraits::value_type value_type; - typedef typename InnerTraits::pointer pointer; - typedef typename InnerTraits::reference reference; + typedef typename boost::remove_const::type value_type; + typedef Pointer pointer; + typedef Reference reference; public: typedef boost::iterator indirect_traits; typedef iterator_adaptor type; }; template , - class InnerTraits = boost::detail::iterator_traits::value_type> + class Value +#if !defined(BOOST_MSVC) + = BOOST_ARG_DEPENDENT_TYPENAME detail::value_type_of_value_type::type +#endif + , class Pointer = Value* + , class Reference = Value& + , class ConstPointer = const Value* + , class ConstReference = const Value& > struct indirect_iterator_pair_generator { typedef typename indirect_iterator_generator::type iterator; + Value, Pointer, Reference>::type iterator; typedef typename indirect_iterator_generator::type const_iterator; + Value, ConstPointer, ConstReference>::type const_iterator; }; -#ifndef BOOST_NO_STD_ITERATOR_TRAITS +// Tried to allow InnerTraits to be provided by explicit template +// argument to the function, but could not get it to work. -Jeremy Siek +template +inline typename indirect_iterator_generator::type +make_indirect_iterator(OuterIterator base, Value* = 0) +{ + typedef typename indirect_iterator_generator + ::type result_t; + return result_t(base); +} + +# if 0 // This just doesn't seem to work under any circumstances! template inline typename indirect_iterator_generator::type make_indirect_iterator(OuterIterator base) @@ -699,18 +739,7 @@ make_indirect_iterator(OuterIterator base) ::type result_t; return result_t(base); } -#endif - -// Tried to allow InnerTraits to be provided by explicit template -// argument to the function, but could not get it to work. -Jeremy Siek -template -inline typename indirect_iterator_generator::type -make_indirect_iterator(OuterIterator base, InnerTraits) -{ - typedef typename indirect_iterator_generator - ::type result_t; - return result_t(base); -} +# endif //============================================================================= @@ -757,10 +786,6 @@ struct reverse_iterator_generator Traits> type; }; -// WARNING: Do not use the one template parameter version of -// make_reverse_iterator() if the iterator is a builtin pointer type -// and if your compiler does not support partial specialization. - template inline typename reverse_iterator_generator::type make_reverse_iterator(Iterator base) @@ -769,17 +794,73 @@ make_reverse_iterator(Iterator base) return result_t(base); } -// Specify Traits type with an explicit argument, -// i.e., make_reverse_iterator(base) +template struct undefined; -template -inline typename reverse_iterator_generator::type -make_reverse_iterator(Iterator base, Traits* = 0) +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +namespace detail { + template + struct iterator_defaults_select + { + template + struct traits + { + typedef typename boost::detail::iterator_traits::value_type value_type; + typedef typename boost::detail::iterator_traits::pointer pointer; + typedef typename boost::detail::iterator_traits::reference reference; + }; + }; + + template <> + struct iterator_defaults_select + { + template + struct traits + { + typedef Value value_type; + typedef Value* pointer; + typedef Value& reference; + }; + }; + + template + struct iterator_defaults + { + enum { is_ptr = boost::is_pointer::value }; + typedef iterator_defaults_select::template traits traits; + typedef typename traits::pointer pointer; + typedef typename traits::reference reference; + }; +} +#endif + +template ::value_type, +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + class Pointer = BOOST_ARG_DEPENDENT_TYPENAME boost::detail::iterator_traits::pointer, + class Reference = BOOST_ARG_DEPENDENT_TYPENAME boost::detail::iterator_traits::reference, +#else + class Pointer = BOOST_ARG_DEPENDENT_TYPENAME boost::detail::iterator_defaults::pointer, + class Reference = BOOST_ARG_DEPENDENT_TYPENAME boost::detail::iterator_defaults::reference, +#endif + class Category = BOOST_ARG_DEPENDENT_TYPENAME boost::detail::iterator_traits::iterator_category, + class Distance = BOOST_ARG_DEPENDENT_TYPENAME boost::detail::iterator_traits::difference_type + > +struct reverse_iterator_generator2 { - typedef typename reverse_iterator_generator::type result_t; + typedef typename boost::remove_const::type value_type; + typedef typename boost::iterator traits; + typedef iterator_adaptor type; +}; + +//#ifndef BOOST_MSVC +template +inline typename reverse_iterator_generator2::type +make_reverse_iterator2(Iterator base) +{ + typedef typename reverse_iterator_generator2::type result_t; return result_t(base); } - +//#endif //============================================================================= // Projection Iterators Adaptor @@ -929,6 +1010,8 @@ make_filter_iterator(Iterator first, Iterator last, const Predicate& p = Predica } // namespace boost +# undef BOOST_ARG_DEPENDENT_TYPENAME + #endif