diff --git a/include/boost/iterator_adaptors.hpp b/include/boost/iterator_adaptors.hpp index 96bc148..6088b8d 100644 --- a/include/boost/iterator_adaptors.hpp +++ b/include/boost/iterator_adaptors.hpp @@ -12,6 +12,9 @@ // // Revision History: +// 08 Jan 2001 David Abrahams +// Moved concept checks into a separate class, which makes MSVC +// better at dealing with them. // 07 Jan 2001 David Abrahams // Choose proxy for operator->() only if the reference type is not a reference. // Updated workarounds for __MWERKS__ == 0x2406 @@ -124,7 +127,7 @@ // I was having some problems with VC6. I couldn't tell whether our hack for // stock GCC was causing problems so I needed an easy way to turn it on and -// off. Now we can test the hack with various compilers and still have an +// off. Now we can test the hack with various compilers and still have an // "out" if it doesn't work. -dwa 7/31/00 # if __GNUC__ == 2 && __GNUC_MINOR__ <= 96 && !defined(__STL_USE_NAMESPACES) # define BOOST_RELOPS_AMBIGUITY_BUG 1 @@ -168,7 +171,7 @@ struct ForwardIteratorPoliciesConcept { typedef typename Traits::iterator_category iterator_category; void constraints() { - function_requires< + function_requires< TrivialIteratorPoliciesConcept >(); @@ -186,7 +189,7 @@ struct BidirectionalIteratorPoliciesConcept { typedef typename Traits::iterator_category iterator_category; void constraints() { - function_requires< + function_requires< ForwardIteratorPoliciesConcept >(); @@ -204,7 +207,7 @@ struct RandomAccessIteratorPoliciesConcept typedef typename Traits::difference_type DifferenceType; typedef typename Traits::iterator_category iterator_category; void constraints() { - function_requires< + function_requires< BidirectionalIteratorPoliciesConcept >(); @@ -262,7 +265,7 @@ struct default_iterator_policies { return x.base() == y.base(); } }; -// putting the comparisons in a base class avoids the g++ +// putting the comparisons in a base class avoids the g++ // ambiguous overload bug due to the relops operators #ifdef BOOST_RELOPS_AMBIGUITY_BUG @@ -270,7 +273,7 @@ template struct iterator_comparisons : Base { }; template -inline bool operator==(const iterator_comparisons& xb, +inline bool operator==(const iterator_comparisons& xb, const iterator_comparisons& yb) { const D1& x = static_cast(xb); @@ -279,7 +282,7 @@ inline bool operator==(const iterator_comparisons& xb, } template -inline bool operator!=(const iterator_comparisons& xb, +inline bool operator!=(const iterator_comparisons& xb, const iterator_comparisons& yb) { const D1& x = static_cast(xb); @@ -288,7 +291,7 @@ inline bool operator!=(const iterator_comparisons& xb, } template -inline bool operator<(const iterator_comparisons& xb, +inline bool operator<(const iterator_comparisons& xb, const iterator_comparisons& yb) { const D1& x = static_cast(xb); @@ -297,16 +300,16 @@ inline bool operator<(const iterator_comparisons& xb, } template -inline bool operator>(const iterator_comparisons& xb, +inline bool operator>(const iterator_comparisons& xb, const iterator_comparisons& yb) -{ +{ const D1& x = static_cast(xb); const D2& y = static_cast(yb); return x.policies().distance(y, x) > 0; } template -inline bool operator>=(const iterator_comparisons& xb, +inline bool operator>=(const iterator_comparisons& xb, const iterator_comparisons& yb) { const D1& x = static_cast(xb); @@ -315,7 +318,7 @@ inline bool operator>=(const iterator_comparisons& xb, } template -inline bool operator<=(const iterator_comparisons& xb, +inline bool operator<=(const iterator_comparisons& xb, const iterator_comparisons& yb) { const D1& x = static_cast(xb); @@ -361,7 +364,7 @@ namespace detail { typedef operator_arrow_proxy proxy; // Borland chokes unless it's an actual enum (!) enum { use_proxy = !boost::is_reference::value }; - + typedef typename boost::detail::if_true<(use_proxy)>::template then< proxy, @@ -424,14 +427,14 @@ namespace detail { typename iterator_traits::pointer, Value* >::type pointer; - + typedef typename if_true<( ::boost::is_same::value_type>::value )>::template then< typename iterator_traits::reference, Value& >::type reference; - + }; # endif @@ -480,7 +483,7 @@ namespace detail { template struct select { typedef typename Traits::value_type Value; - typedef typename boost::detail::iterator_defaults::pointer + typedef typename boost::detail::iterator_defaults::pointer type; }; }; @@ -491,7 +494,7 @@ namespace detail { template struct select { typedef typename Traits::value_type Value; - typedef typename boost::detail::iterator_defaults::reference + typedef typename boost::detail::iterator_defaults::reference type; }; }; @@ -540,7 +543,7 @@ template struct difference_type_is { typedef detail::cons_type type; }; -template struct iterator_category_is +template struct iterator_category_is : public named_template_param_base { typedef detail::cons_type type; @@ -554,7 +557,7 @@ namespace detail { // An associative list is a list of key-value pairs. The list is // built out of cons_type's and is terminated by end_of_list. -#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(__BORLANDC__) +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(__BORLANDC__) template struct find_param; @@ -564,7 +567,7 @@ namespace detail { typedef typename Head::first_type Key1; typedef typename Head::second_type Value; typedef typename if_true<(is_same::value)>::template - then::type >::type type; }; @@ -583,7 +586,7 @@ namespace detail { typedef typename find_param_helper1::type select1; typedef typename select1::template select::type type; }; -#else +# else template struct find_param; template @@ -600,7 +603,7 @@ namespace detail { struct find_param, Rest>, Key2> { typedef typename find_param::type type; }; -#endif +# endif struct make_named_arg { template @@ -617,26 +620,26 @@ namespace detail { enum { value = is_convertible::value }; }; -#if defined(__MWERKS__) && __MWERKS__ <= 0x2406 // workaround for broken is_convertible implementation +# if defined(__MWERKS__) && __MWERKS__ <= 0x2406 // workaround for broken is_convertible implementation template struct is_named_parameter > { enum { value = true }; }; template struct is_named_parameter > { enum { value = true }; }; template struct is_named_parameter > { enum { value = true }; }; template struct is_named_parameter > { enum { value = true }; }; template struct is_named_parameter > { enum { value = true }; }; -#endif +# endif template struct make_arg { -#ifdef __BORLANDC__ +# ifdef __BORLANDC__ // Borland C++ doesn't like the extra indirection of is_named_parameter - typedef typename + typedef typename if_true<(is_convertible::value)>:: template then::type Make; -#else +# else enum { is_named = is_named_parameter::value }; typedef typename if_true<(is_named)>::template then::type Make; -#endif +# endif typedef typename Make::template select::type type; }; @@ -680,7 +683,7 @@ namespace detail { class iterator_adaptor_traits_gen { // Form an associative list out of the template parameters - // If the argument is a normal parameter (not named) then make_arg + // If the argument is a normal parameter (not named) then make_arg // creates a key-value pair. If the argument is a named parameter, // then make_arg extracts the key-value pair defined inside the // named parameter. @@ -705,9 +708,9 @@ namespace detail { typedef typename resolve_default::type value_type; // if getting default value type from iterator_traits, then it won't be const - typedef typename resolve_default::type difference_type; - typedef typename resolve_default::type iterator_category; typedef boost::iterator::type reference; - + public: typedef boost::iterator::type, + typename remove_const::type, difference_type, pointer, reference> type; }; + // This is really a partial concept check for iterators. Should it + // be moved or done differently? + template + struct validator + { + BOOST_STATIC_CONSTANT( + bool, is_input_or_output_iter + = (boost::is_convertible::value + | boost::is_convertible::value)); + + // Iterators should satisfy one of the known categories + BOOST_STATIC_ASSERT(is_input_or_output_iter); + + // Iterators >= ForwardIterator must produce real references + // as required by the C++ standard requirements in Table 74. + BOOST_STATIC_CONSTANT( + bool, forward_iter_with_real_reference + = ((!boost::is_convertible::value) + | boost::is_same::value + | boost::is_same::type&>::value)); + + BOOST_STATIC_ASSERT(forward_iter_with_real_reference); + }; } // namespace detail @@ -738,8 +764,6 @@ namespace detail { # define BOOST_ARG_DEPENDENT_TYPENAME # endif -template struct undefined; - //============================================================================ //iterator_adaptor - Adapts a generic piece of data as an iterator. Adaptation // is especially easy if the data being adapted is itself an iterator @@ -768,7 +792,7 @@ template struct undefined; // // Distance - the difference_type of the resulting iterator. If not // supplied, iterator_traits::difference_type is used. -template ::value - | boost::is_convertible::value)); - - // Iterators should satisfy one of the known categories - BOOST_STATIC_ASSERT(is_input_or_output_iter); - - // Iterators >= ForwardIterator must produce real references - // as required by the C++ standard requirements in Table 74. - BOOST_STATIC_CONSTANT(bool, forward_iter_with_real_reference - = ((!boost::is_convertible::value) - | boost::is_same::value - | boost::is_same::value)); - - // This check gives incorrect results in iter_traits_gen_test.cpp - BOOST_STATIC_ASSERT(forward_iter_with_real_reference); + typedef detail::validator< + iterator_category,value_type,difference_type,pointer,reference + > concept_check; public: - iterator_adaptor() { } + iterator_adaptor() + { + } explicit iterator_adaptor(const Base& it, const Policies& p = Policies()) : m_iter_p(it, p) { - policies().initialize(base()); + policies().initialize(base()); } template @@ -861,7 +874,7 @@ struct iterator_adaptor : value_type operator[](difference_type n) const { return *(*this + n); } - + self& operator++() { #if !defined(__MWERKS__) || __MWERKS__ >= 0x2405 policies().increment(*this); @@ -874,7 +887,7 @@ struct iterator_adaptor : } self operator++(int) { self tmp(*this); ++*this; return tmp; } - + self& operator--() { #if !defined(__MWERKS__) || __MWERKS__ >= 0x2405 policies().decrement(*this); @@ -883,14 +896,14 @@ struct iterator_adaptor : #endif return *this; } - + self operator--(int) { self tmp(*this); --*this; return tmp; } self& operator+=(difference_type n) { policies().advance(*this, n); return *this; } - + self& operator-=(difference_type n) { policies().advance(*this, -n); return *this; @@ -948,7 +961,7 @@ operator-( template -inline bool +inline bool operator==( const iterator_adaptor& x, const iterator_adaptor& y) @@ -959,7 +972,7 @@ operator==( template -inline bool +inline bool operator<( const iterator_adaptor& x, const iterator_adaptor& y) @@ -970,18 +983,18 @@ operator<( template -inline bool +inline bool operator>( const iterator_adaptor& x, const iterator_adaptor& y) -{ +{ return x.policies().distance(y, x) > 0; } template -inline bool +inline bool operator>=( const iterator_adaptor& x, const iterator_adaptor& y) @@ -992,7 +1005,7 @@ operator>=( template -inline bool +inline bool operator<=( const iterator_adaptor& x, const iterator_adaptor& y) @@ -1003,9 +1016,9 @@ operator<=( template -inline bool +inline bool operator!=( - const iterator_adaptor& x, + const iterator_adaptor& x, const iterator_adaptor& y) { return !x.policies().equal(x, y); @@ -1023,7 +1036,7 @@ struct transform_iterator_policies : public default_iterator_policies { transform_iterator_policies() { } transform_iterator_policies(const AdaptableUnaryFunction& f) : m_f(f) { } - + template typename IteratorAdaptor::reference dereference(const IteratorAdaptor& iter) const @@ -1037,7 +1050,7 @@ class transform_iterator_generator { typedef typename AdaptableUnaryFunction::result_type value_type; public: - typedef iterator_adaptor, value_type, value_type, value_type*, std::input_iterator_tag> type; @@ -1093,7 +1106,7 @@ template ::value_type #endif - , class Reference + , class Reference #if !defined(BOOST_MSVC) = BOOST_ARG_DEPENDENT_TYPENAME detail::traits_of_value_type< OuterIterator>::reference @@ -1102,7 +1115,7 @@ template ::iterator_category - , class Pointer + , class Pointer #if !defined(BOOST_MSVC) = BOOST_ARG_DEPENDENT_TYPENAME detail::traits_of_value_type< OuterIterator>::pointer @@ -1122,7 +1135,7 @@ template ::value_type #endif - , class Reference + , class Reference #if !defined(BOOST_MSVC) = BOOST_ARG_DEPENDENT_TYPENAME detail::traits_of_value_type< OuterIterator>::reference @@ -1132,7 +1145,7 @@ template ::iterator_category - , class Pointer + , class Pointer #if !defined(BOOST_MSVC) = BOOST_ARG_DEPENDENT_TYPENAME detail::traits_of_value_type< OuterIterator>::pointer @@ -1168,29 +1181,29 @@ struct reverse_iterator_policies : public default_iterator_policies template typename IteratorAdaptor::reference dereference(const IteratorAdaptor& x) const { return *boost::prior(x.base()); } - + template void increment(BidirectionalIterator& x) const { --x.base(); } - + template void decrement(BidirectionalIterator& x) const { ++x.base(); } - + template void advance(BidirectionalIterator& x, DifferenceType n) const { x.base() -= n; } - + template typename Iterator1::difference_type distance( const Iterator1& x, const Iterator2& y) const { return x.base() - y.base(); } - + template bool equal(const Iterator1& x, const Iterator2& y) const { return x.base() == y.base(); } }; - + template ::value_type, class Reference = BOOST_ARG_DEPENDENT_TYPENAME boost::detail::iterator_defaults::reference, @@ -1226,7 +1239,7 @@ struct projection_iterator_policies : public default_iterator_policies return m_f(*iter.base()); } - AdaptableUnaryFunction m_f; + AdaptableUnaryFunction m_f; }; template @@ -1255,7 +1268,7 @@ struct projection_iterator_pair_generator { template inline typename projection_iterator_generator::type make_projection_iterator( - Iterator iter, + Iterator iter, const AdaptableUnaryFunction& f = AdaptableUnaryFunction()) { typedef typename projection_iterator_generator::type result_t; @@ -1265,7 +1278,7 @@ make_projection_iterator( template inline typename const_projection_iterator_generator::type make_const_projection_iterator( - Iterator iter, + Iterator iter, const AdaptableUnaryFunction& f = AdaptableUnaryFunction()) { typedef typename const_projection_iterator_generator::type result_t; @@ -1281,7 +1294,7 @@ class filter_iterator_policies public: filter_iterator_policies() { } - filter_iterator_policies(const Predicate& p, const Iterator& end) + filter_iterator_policies(const Predicate& p, const Iterator& end) : m_predicate(p), m_end(end) { } void initialize(Iterator& x) { @@ -1361,7 +1374,7 @@ namespace detail { }; } -template ::value_type, class Reference = BOOST_ARG_DEPENDENT_TYPENAME boost::detail::iterator_defaults::reference, class Pointer = BOOST_ARG_DEPENDENT_TYPENAME boost::detail::iterator_defaults::pointer,