diff --git a/include/boost/iterator/iterator_adaptor.hpp b/include/boost/iterator/iterator_adaptor.hpp index a9cd88d..1e5e480 100644 --- a/include/boost/iterator/iterator_adaptor.hpp +++ b/include/boost/iterator/iterator_adaptor.hpp @@ -178,18 +178,34 @@ namespace boost > struct iterator_adaptor_base { - private: - typedef typename detail::ia_dflt_help >::type category; - typedef typename detail::ia_dflt_help , iterator_reference >::type reference; + private: + typedef typename detail::ia_dflt_help< + Category, mpl::true_, BOOST_ITERATOR_CATEGORY + >::type category; + + typedef typename detail::ia_dflt_help< + Reference, is_same, iterator_reference + >::type reference; - public: + public: typedef iterator_facade< Derived - , typename detail::ia_dflt_help >::type - , typename access_category_tag< category, reference >::type - , typename traversal_category_tag< category >::type - , typename detail::ia_dflt_help , iterator_reference >::type - , typename detail::ia_dflt_help >::type + + , typename detail::ia_dflt_help< + Value, mpl::true_, iterator_value + >::type + + , typename access_category_tag::type + + , typename traversal_category_tag::type + + , typename detail::ia_dflt_help< + Reference, is_same, iterator_reference + >::type + + , typename detail::ia_dflt_help< + Difference, mpl::true_, iterator_difference + >::type > type; }; diff --git a/include/boost/iterator/iterator_archetypes.hpp b/include/boost/iterator/iterator_archetypes.hpp index 09c3eba..05950c1 100644 --- a/include/boost/iterator/iterator_archetypes.hpp +++ b/include/boost/iterator/iterator_archetypes.hpp @@ -16,6 +16,8 @@ #include #include +#include + #include namespace boost @@ -74,51 +76,81 @@ namespace boost { }; - template - struct traversal_archetype_; - - template - struct traversal_archetype_ + template + struct traversal_archetype_impl { - typedef void difference_type; - - Derived& operator++(); - Derived operator++(int) const; + template struct archetype; }; - template - struct traversal_archetype_ - : public equality_comparable< traversal_archetype_ >, - public traversal_archetype_ + template + struct traversal_archetype_ + : mpl::aux::msvc_eti_base< + typename traversal_archetype_impl::template archetype + >::type + {}; + + template <> + struct traversal_archetype_impl { + template + struct archetype + { + typedef void difference_type; + + Derived& operator++(); + Derived operator++(int) const; + }; + }; + + template <> + struct traversal_archetype_impl + { + template + struct archetype + : public equality_comparable< traversal_archetype_ >, + public traversal_archetype_ + { + }; }; template bool operator==(traversal_archetype_ const&, traversal_archetype_ const&); - template - struct traversal_archetype_ - : public traversal_archetype_ + template <> + struct traversal_archetype_impl { - typedef std::ptrdiff_t difference_type; + template + struct archetype + : public traversal_archetype_ + { + typedef std::ptrdiff_t difference_type; + }; }; - template - struct traversal_archetype_ - : public traversal_archetype_ + template <> + struct traversal_archetype_impl { - Derived& operator--(); - Derived operator--(int) const; + template + struct archetype + : public traversal_archetype_ + { + Derived& operator--(); + Derived operator--(int) const; + }; }; - template - struct traversal_archetype_ - : public partially_ordered< traversal_archetype_ >, - public traversal_archetype_ + template <> + struct traversal_archetype_impl { - Derived& operator+=(std::ptrdiff_t); - Derived& operator-=(std::ptrdiff_t); + template + struct archetype + : public partially_ordered >, + public traversal_archetype_ + { + Derived& operator+=(std::ptrdiff_t); + Derived& operator-=(std::ptrdiff_t); + }; }; template @@ -153,59 +185,95 @@ namespace boost } // namespace detail + template struct undefined; + + template + struct access_archetype_impl + { + template struct archetype; + }; + template - struct access_archetype; - - template - struct access_archetype + struct access_archetype + : mpl::aux::msvc_eti_base< + typename access_archetype_impl::template archetype + >::type { - typedef typename remove_cv::type value_type; - typedef Value reference; - typedef Value* pointer; - - value_type operator*() const; - - detail::arrow_proxy operator->() const; }; - template - struct access_archetype + template <> + struct access_archetype_impl { - BOOST_STATIC_ASSERT((!is_const::value)); + template + struct archetype + { + typedef typename remove_cv::type value_type; + typedef Value reference; + typedef Value* pointer; - typedef void value_type; - typedef void reference; - typedef void pointer; + value_type operator*() const; - detail::assign_proxy operator*() const; + detail::arrow_proxy operator->() const; + }; }; - template - struct access_archetype : - public virtual access_archetype + template <> + struct access_archetype_impl { - typedef detail::read_write_proxy reference; + template + struct archetype + { +# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + BOOST_STATIC_ASSERT(!is_const::value); +# endif + typedef void value_type; + typedef void reference; + typedef void pointer; - detail::read_write_proxy operator*() const; + detail::assign_proxy operator*() const; + }; }; - template - struct access_archetype : - public virtual access_archetype + template <> + struct access_archetype_impl { - typedef Value& reference; + template + struct archetype + : public virtual access_archetype + { + typedef detail::read_write_proxy reference; - Value& operator*() const; - Value* operator->() const; + detail::read_write_proxy operator*() const; + }; }; - template - struct access_archetype - : public virtual access_archetype + template <> + struct access_archetype_impl { - BOOST_STATIC_ASSERT((!is_const::value)); - }; + template + struct archetype + : public virtual access_archetype + { + typedef Value& reference; + Value& operator*() const; + Value* operator->() const; + }; + }; + + template <> + struct access_archetype_impl + { + template + struct archetype + : public virtual access_archetype + { +# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + BOOST_STATIC_ASSERT((!is_const::value)); +# endif + }; + }; + template struct traversal_archetype : detail::operator_brackets< typename remove_cv::type, @@ -217,18 +285,40 @@ namespace boost template struct iterator_archetype - : public traversal_archetype, Value, AccessCategory, TraversalCategory>, - public access_archetype + : public traversal_archetype< + iterator_archetype + , Value, AccessCategory, TraversalCategory + > + , public access_archetype +# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) + , public std::iterator< + iterator_tag + , typename access_archetype::value_type + , typename traversal_archetype< + iterator_archetype + , Value, AccessCategory, TraversalCategory + >::difference_type + > +# endif { - typedef iterator_tag iterator_category; +# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) + typedef typename access_archetype::value_type value_type; + + typedef typename traversal_archetype< + iterator_archetype + , Value, AccessCategory, TraversalCategory + >::difference_type difference_type; +# endif + + typedef iterator_tag iterator_category; - iterator_archetype(); - iterator_archetype(iterator_archetype const&); + iterator_archetype(); + iterator_archetype(iterator_archetype const&); - iterator_archetype& operator=(iterator_archetype const&); + iterator_archetype& operator=(iterator_archetype const&); - // Optional conversion from mutable - // iterator_archetype(iterator_archetype::type, AccessCategory, TraversalCategory> const&); + // Optional conversion from mutable + // iterator_archetype(iterator_archetype::type, AccessCategory, TraversalCategory> const&); }; } // namespace boost diff --git a/include/boost/iterator/iterator_categories.hpp b/include/boost/iterator/iterator_categories.hpp index 5ac82bf..9e82708 100644 --- a/include/boost/iterator/iterator_categories.hpp +++ b/include/boost/iterator/iterator_categories.hpp @@ -28,6 +28,7 @@ #include #include #include +#include #include @@ -257,8 +258,8 @@ namespace boost { # if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) // Deal with ETI - template <> struct access_category_tag {}; - template <> struct traversal_category_tag {}; + template <> struct access_category_tag { typedef void type; }; + template <> struct traversal_category_tag { typedef void type; }; # endif } // namespace detail @@ -299,10 +300,12 @@ namespace boost { template struct iterator_tag - : detail::minimum_category< - typename ReturnTag::max_category - , typename TraversalTag::max_category - >::type + : mpl::aux::msvc_eti_base< + typename detail::minimum_category< + typename ReturnTag::max_category + , typename TraversalTag::max_category + >::type + >::type { typedef ReturnTag returns; typedef TraversalTag traversal; diff --git a/test/iterator_adaptor_test.cpp b/test/iterator_adaptor_test.cpp index aaa6ca7..6399052 100644 --- a/test/iterator_adaptor_test.cpp +++ b/test/iterator_adaptor_test.cpp @@ -184,14 +184,19 @@ main() BOOST_STATIC_ASSERT((boost::is_same::value)); BOOST_STATIC_ASSERT((boost::is_same::value)); BOOST_STATIC_ASSERT((boost::is_same::value)); +#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407) BOOST_STATIC_ASSERT((boost::is_convertible::value)); +#endif } { // Test computation of default when the Value is const typedef ptr_iterator Iter1; BOOST_STATIC_ASSERT((boost::is_same::value)); BOOST_STATIC_ASSERT((boost::is_same::value)); +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) + // Borland has known problems with const BOOST_STATIC_ASSERT((boost::is_same::value)); +#endif } // Test the iterator_adaptor