diff --git a/include/boost/iterator/detail/categories.hpp b/include/boost/iterator/detail/categories.hpp index 5a2e7eb..84e0936 100644 --- a/include/boost/iterator/detail/categories.hpp +++ b/include/boost/iterator/detail/categories.hpp @@ -39,40 +39,12 @@ namespace boost // // Access Categories // - struct readable_iterator_tag + enum iterator_access { - typedef std::input_iterator_tag max_category; - }; - - struct writable_iterator_tag - { - typedef std::output_iterator_tag max_category; - }; - - struct swappable_iterator_tag - { - typedef detail::null_category_tag max_category; - }; - - struct readable_writable_iterator_tag - : virtual readable_iterator_tag - , virtual writable_iterator_tag - , virtual swappable_iterator_tag - { - typedef detail::input_output_iterator_tag max_category; - }; - - struct readable_lvalue_iterator_tag - : virtual readable_iterator_tag - { - typedef std::random_access_iterator_tag max_category; - }; - - struct writable_lvalue_iterator_tag - : virtual public readable_writable_iterator_tag - , virtual public readable_lvalue_iterator_tag - { - typedef std::random_access_iterator_tag max_category; + readable_iterator = 1 + , writable_iterator = 2 + , swappable_iterator = 4 + , lvalue_iterator = 8 }; // @@ -111,6 +83,11 @@ namespace boost namespace detail { + template + access_c : mpl::integral_c + {}; + + // // Tag detection meta functions // @@ -147,7 +124,7 @@ namespace boost // iterators which don't have an actual old-style category. We // need that so there is a valid base class for all new-style // iterators. -# define BOOST_OLD_ITERATOR_CATEGORY(category) \ +# define BOOST_OLD_ITERATOR_CATEGORY(category) \ template <> \ struct is_tag \ : mpl::true_ {}; diff --git a/include/boost/iterator/iterator_adaptor.hpp b/include/boost/iterator/iterator_adaptor.hpp index af14283..a47dad4 100644 --- a/include/boost/iterator/iterator_adaptor.hpp +++ b/include/boost/iterator/iterator_adaptor.hpp @@ -153,10 +153,8 @@ namespace boost typedef typename mpl::apply_if< mpl::or_< is_same - , mpl::or_< - is_access_tag - , is_traversal_tag - > + , is_access_tag + , is_traversal_tag > , BOOST_ITERATOR_CATEGORY , mpl::identity diff --git a/include/boost/iterator/iterator_categories.hpp b/include/boost/iterator/iterator_categories.hpp index cbf1f2f..e7e270b 100644 --- a/include/boost/iterator/iterator_categories.hpp +++ b/include/boost/iterator/iterator_categories.hpp @@ -105,7 +105,7 @@ namespace boost { template struct apply - : mpl::identity {}; + : access_c {}; }; @@ -116,7 +116,7 @@ namespace boost { template struct apply - : mpl::identity {}; + : access_c {}; }; template <> @@ -128,8 +128,8 @@ namespace boost { struct apply : mpl::if_< python::detail::is_reference_to_const - , boost::readable_lvalue_iterator_tag - , boost::writable_lvalue_iterator_tag + , access_c<(readable_iterator|lvalue_iterator)> + , access_c<(readable_iterator|writable_iterator|lvalue_iterator)> > {}; }; @@ -151,30 +151,31 @@ namespace boost { template struct old_tag_converter : std_to_new_tags< + // Take the category down to its most-refined known + // std::tag, in case of derivation/convertibility typename std_category::type > { }; - - template - struct iter_category_to_traversal - : std_to_new_tags< - typename std_category::type - > - {}; + template + struct old_tag_to_traversal + : old_tag_converter + {}; + + template - struct iter_category_to_access + struct old_tag_to_access : mpl::apply1< - iter_category_to_traversal + old_tag_converter , Reference > {}; # if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) // Deal with ETI - template <> struct iter_category_to_access {}; - template <> struct iter_category_to_traversal {}; + template <> struct old_tag_to_access {}; + template <> struct old_tag_converter {}; # endif // A metafunction returning true iff T is boost::iterator_tag @@ -231,71 +232,49 @@ namespace boost { namespace detail { template - struct get_traversal_category { - typedef typename NewCategoryTag::traversal type; + struct new_tag_to_traversal + { + typedef typename NewCategoryTag::traversal type; }; - // Remove all writability from the given access tag. This - // functionality is part of new_category_to_access in order to - // support deduction of the proper default access category for - // iterator_adaptor; when the reference type is a reference to - // constant we must strip writability. - template - struct remove_access_writability - : mpl::apply_if< - is_tag - , mpl::identity - - , mpl::apply_if< - is_tag - , mpl::identity - - , mpl::if_< - is_tag - // Is this OK? I think it may correct be for all - // legitimate cases, because at this point the - // iterator is not readable, so it could not have - // been any more than writable + swappable. - , swappable_iterator_tag - , AccessTag - > - > - > - {}; - template - struct new_category_to_access + struct new_tag_to_access + { + typedef typename NewCategoryTag::access_type type; + } +#if 0 // what was this all about? : mpl::apply_if< python::detail::is_reference_to_const , remove_access_writability , mpl::identity > {}; +#endif template - struct access_category_tag - : mpl::apply_if< - is_new_iterator_tag - , new_category_to_access - , iter_category_to_access - > + struct tag_access_category + : mpl::apply_if< + is_new_iterator_tag + , new_tag_to_access + , old_tag_to_access + > { }; template - struct traversal_category_tag + struct tag_traversal_category : mpl::apply_if< is_new_iterator_tag - , get_traversal_category - , iter_category_to_traversal + , new_tag_to_traversal + , old_tag_to_traversal > { }; # if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) // Deal with ETI - template <> struct access_category_tag { typedef void type; }; - template <> struct traversal_category_tag { typedef void type; }; + template <> struct tag_access_category { typedef void type; }; + template <> struct tag_traversal_category { typedef void type; }; # endif // iterator_tag_base - a metafunction to compute the appropriate @@ -330,14 +309,15 @@ namespace boost { template struct access_category - : detail::access_category_tag< - typename detail::iterator_traits::iterator_category - , typename detail::iterator_traits::reference> + : detail::tag_access_category< + typename detail::iterator_traits::iterator_category + , typename detail::iterator_traits::reference + > {}; template struct traversal_category - : detail::traversal_category_tag< + : detail::tag_traversal_category< typename detail::iterator_traits::iterator_category > { @@ -349,7 +329,7 @@ namespace boost { // requires instantiating iterator_traits on the // placeholder. Instead we just specialize it as a metafunction // class. -template <> + template <> struct access_category { template @@ -370,10 +350,11 @@ template <> template struct access_category - : mpl::if_< + : mpl::if_< is_const - , readable_lvalue_iterator_tag - , writable_lvalue_iterator_tag> + , detail::access_c<(readable_iterator|lvalue_iterator)> + , detail::access_c<(readable_iterator|writable_iterator|lvalue_iterator)> + > { }; @@ -385,15 +366,16 @@ template <> # endif - template + template struct iterator_tag : detail::iterator_tag_base< - typename detail::max_known_access_tag::type + typename detail::max_known_access_tag::type , typename detail::max_known_traversal_tag::type >::type { - typedef AccessTag access; - typedef TraversalTag traversal; + typedef detail::access_c<(Access & ~lvalue_iterator)> access_type; + BOOST_STATIC_CONSTANT(iterator_access, access_type::value); + typedef TraversalTag traversal; }; namespace detail diff --git a/include/boost/iterator/iterator_facade.hpp b/include/boost/iterator/iterator_facade.hpp index 79795ad..7f00495 100644 --- a/include/boost/iterator/iterator_facade.hpp +++ b/include/boost/iterator/iterator_facade.hpp @@ -75,25 +75,6 @@ namespace boost #endif }; - - // - // Add const qualification for iterators which are not writable - // - template - struct const_qualified_ref : - mpl::if_< is_tag< writable_iterator_tag, AccessCategory >, - Value&, - Value const& > - {}; - - // The apparent duplication here works around a Borland problem - template - struct const_qualified_ptr : - mpl::if_< is_tag< writable_iterator_tag, AccessCategory >, - Value*, - Value const* > - {}; - // // Generates the associated types for an iterator_facade with the // given parameters. Additionally generates a 'base' type for @@ -104,7 +85,7 @@ namespace boost class Value , class AccessCategory , class TraversalCategory - , class Reference + , class Reference , class Difference > struct iterator_facade_types @@ -117,17 +98,6 @@ namespace boost typedef typename const_qualified_ptr::type pointer; - // The use_default support is needed for iterator_adaptor. - // For practical reasons iterator_adaptor needs to specify - // a fixed number of template arguments of iterator_facade. - // So use_default is its way to say: "What I really mean - // is your default parameter". - typedef typename mpl::if_< - is_same - , typename const_qualified_ref::type - , Reference - >::type reference; - # if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ && (BOOST_WORKAROUND(_STLPORT_VERSION, BOOST_TESTED_AT(0x452)) \ || BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(310))) \ @@ -372,7 +342,7 @@ namespace boost , class Value , class AccessCategory , class TraversalCategory - , class Reference = BOOST_DEDUCED_TYPENAME detail::const_qualified_ref::type + , class Reference = Value& , class Difference = std::ptrdiff_t > class iterator_facade @@ -384,10 +354,6 @@ namespace boost # endif { private: - typedef typename - detail::iterator_facade_types - types; - // // Curiously Recursive Template interface. // @@ -405,9 +371,9 @@ namespace boost public: - typedef typename types::value_type value_type; - typedef typename types::reference reference; - typedef typename types::difference_type difference_type; + typedef typename remove_cv value_type; + typedef typename Reference reference; + typedef typename Difference difference_type; typedef typename types::pointer pointer; typedef typename types::iterator_category iterator_category;