diff --git a/include/boost/iterator/detail/categories.hpp b/include/boost/iterator/detail/categories.hpp new file mode 100644 index 0000000..9055378 --- /dev/null +++ b/include/boost/iterator/detail/categories.hpp @@ -0,0 +1,318 @@ +// (C) Copyright Thomas Witt 2002. Permission to copy, use, modify, +// sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#ifndef BOOST_ITERATOR_DETAIL_CATEGORIES_HPP +#define BOOST_ITERATOR_DETAIL_CATEGORIES_HPP + +#include +#include +#include +#include +#include +#include +#include + +#if BOOST_WORKAROUND(__MWERKS__, <=0x2407) +# define BOOST_NO_IS_CONVERTIBLE // "Convertible does not provide enough/is not working" +#endif + +namespace boost { + + // Return Type Categories + struct readable_iterator_tag { }; + struct writable_iterator_tag { }; + struct swappable_iterator_tag : + virtual public readable_iterator_tag, // Not sure about this change -JGS + virtual public writable_iterator_tag { }; + struct constant_lvalue_iterator_tag : + virtual public readable_iterator_tag { }; + struct mutable_lvalue_iterator_tag : + virtual public swappable_iterator_tag, + virtual public constant_lvalue_iterator_tag { }; + + // Traversal Categories + struct input_traversal_tag { }; + struct output_traversal_tag { }; + struct forward_traversal_tag : virtual public input_traversal_tag, + virtual public output_traversal_tag { }; + struct bidirectional_traversal_tag : virtual public forward_traversal_tag { }; + struct random_access_traversal_tag : virtual public bidirectional_traversal_tag { }; + + struct error_iterator_tag { }; + + namespace detail + { + // + // Tag detection meta functions + // + // Needed to work with compilers + // without working is_convertible + // + +#ifndef BOOST_NO_IS_CONVERTIBLE + template + struct is_input_iterator : + is_convertible + { + }; + + template + struct is_output_iterator : + is_convertible + { + }; + + template + struct is_forward_iterator : + is_convertible + { + }; + + template + struct is_bidirectional_iterator : + is_convertible + { + }; + + template + struct is_random_access_iterator : + is_convertible + { + }; + + template + struct is_readable_iterator : + is_convertible + { }; + + template + struct is_writable_iterator : + is_convertible + { }; + + template + struct is_swappable_iterator : + is_convertible + { }; + + template + struct is_constant_lvalue_iterator : + is_convertible + { }; + + template + struct is_mutable_lvalue_iterator : + is_convertible + { }; + + template + struct is_input_traversal_iterator : + is_convertible + { }; + + template + struct is_output_traversal_iterator : + is_convertible + { }; + + template + struct is_forward_traversal_iterator : + is_convertible + { }; + + template + struct is_bidirectional_traversal_iterator : + is_convertible + { }; + + template + struct is_random_access_traversal_iterator : + is_convertible + { }; + +#else + // + // We cannot detect the iterator category for custom + // tag types. For custom tag types false_c is returned + // + // As a result the std iterator category detection functions + // can't detect the iterator category of the new iterator_tag template. + // + + // + // std iterator categories + // + + template + struct is_random_access_iterator : + mpl::false_c + {}; + + template <> + struct is_random_access_iterator : + mpl::true_c + {}; + + template + struct is_bidirectional_iterator : + is_random_access_iterator< Category > + {}; + + template <> + struct is_bidirectional_iterator : + mpl::true_c + {}; + + template + struct is_forward_iterator : + is_bidirectional_iterator< Category > + {}; + + template <> + struct is_forward_iterator : + mpl::true_c + {}; + + template + struct is_output_iterator : + is_forward_iterator< Category > + {}; + + template <> + struct is_output_iterator : + mpl::true_c + {}; + + template + struct is_input_iterator : + is_forward_iterator< Category > + {}; + + template <> + struct is_input_iterator : + mpl::true_c + {}; + + // + // Return type + // + + template + struct is_mutable_lvalue_iterator : + mpl::false_c + {}; + + template <> + struct is_mutable_lvalue_iterator : + mpl::true_c + {}; + + template + struct is_constant_lvalue_iterator : + is_mutable_lvalue_iterator + {}; + + template <> + struct is_constant_lvalue_iterator : + mpl::true_c + {}; + + template + struct is_swappable_iterator : + is_constant_lvalue_iterator + {}; + + template <> + struct is_swappable_iterator : + mpl::true_c + {}; + + template + struct is_readable_iterator : + mpl::logical_or< is_swappable_iterator, + is_constant_lvalue_iterator > + {}; + + template <> + struct is_readable_iterator : + mpl::true_c + {}; + + template + struct is_writable_iterator : + is_swappable_iterator + {}; + + template <> + struct is_writable_iterator : + mpl::true_c + {}; + + // + // Traversal + // + + template + struct is_random_access_traversal_iterator : + mpl::false_c + {}; + + template <> + struct is_random_access_traversal_iterator : + mpl::true_c + {}; + + template + struct is_bidirectional_traversal_iterator : + is_random_access_traversal_iterator< Category > + {}; + + template <> + struct is_bidirectional_traversal_iterator : + mpl::true_c + {}; + + template + struct is_forward_traversal_iterator : + is_bidirectional_traversal_iterator< Category > + {}; + + template <> + struct is_forward_traversal_iterator : + mpl::true_c + {}; + + template + struct is_input_traversal_iterator : + is_forward_traversal_iterator< Category > + {}; + + template <> + struct is_input_traversal_iterator : + mpl::true_c + {}; + + template + struct is_output_traversal_iterator : + is_forward_traversal_iterator< Category > + {}; + + template <> + struct is_output_traversal_iterator : + mpl::true_c + {}; + +#endif + + } // namespace detail + +} // namespace boost + +#ifdef BOOST_NO_IS_CONVERTIBLE +# undef BOOST_NO_IS_CONVERTIBLE +#endif + +#endif // BOOST_ITERATOR_DETAIL_CATEGORIES_HPP diff --git a/include/boost/iterator/iterator_categories.hpp b/include/boost/iterator/iterator_categories.hpp index fce5886..f417b58 100644 --- a/include/boost/iterator/iterator_categories.hpp +++ b/include/boost/iterator/iterator_categories.hpp @@ -11,41 +11,26 @@ #define BOOST_ITERATOR_CATEGORIES_HPP #include +#include #include #include #include +#include #include #include #include #include +#include #include #include #include +#if BOOST_WORKAROUND(__MWERKS__, <=0x2407) +# define BOOST_NO_IS_CONVERTIBLE // "Convertible does not provide enough/is not working" +#endif + namespace boost { - // Return Type Categories - struct readable_iterator_tag { }; - struct writable_iterator_tag { }; - struct swappable_iterator_tag : - virtual public readable_iterator_tag, // Not sure about this change -JGS - virtual public writable_iterator_tag { }; - struct constant_lvalue_iterator_tag : - virtual public readable_iterator_tag { }; - struct mutable_lvalue_iterator_tag : - virtual public swappable_iterator_tag, - virtual public constant_lvalue_iterator_tag { }; - - // Traversal Categories - struct input_traversal_tag { }; - struct output_traversal_tag { }; - struct forward_traversal_tag : virtual public input_traversal_tag, - virtual public output_traversal_tag { }; - struct bidirectional_traversal_tag : virtual public forward_traversal_tag { }; - struct random_access_traversal_tag : virtual public bidirectional_traversal_tag { }; - - struct error_iterator_tag { }; - // When creating new iterators, you have three options. // 1) The recommended option is to specialize the return_category @@ -85,13 +70,13 @@ namespace boost { template struct iter_category_to_return : mpl::if_< - is_convertible + is_forward_iterator , typename choose_lvalue_return::type , typename mpl::if_< - is_convertible + is_input_iterator , boost::readable_iterator_tag , typename mpl::if_< - is_convertible + is_output_iterator , boost::writable_iterator_tag , boost::error_iterator_tag >::type @@ -103,16 +88,16 @@ namespace boost { template struct iter_category_to_traversal : mpl::if_< - is_convertible + is_random_access_iterator , random_access_traversal_tag , typename mpl::if_< - is_convertible + is_bidirectional_iterator , bidirectional_traversal_tag , typename mpl::if_< - is_convertible + is_forward_iterator , forward_traversal_tag , typename mpl::if_< - is_convertible + is_input_iterator , input_traversal_tag , output_traversal_tag >::type @@ -122,6 +107,23 @@ namespace boost { { }; +#if BOOST_WORKAROUND(__MWERKS__, <=0x2407) + // + // has_traversal fails for cwpro7, so we have to use + // something less sophisticated. + // + // The solution depends on the fact that only + // std iterator categories work with is_xxx_iterator + // meta functions, as BOOST_NO_IS_CONVERTIBLE is + // defined for cwpro7. + // + template + struct is_new_iterator_tag : + mpl::logical_and< mpl::logical_not< is_input_iterator >, + mpl::logical_not< is_output_iterator > > + {}; + +#else BOOST_MPL_HAS_XXX_TRAIT_DEF(traversal) template @@ -133,6 +135,9 @@ namespace boost { , mpl::bool_c >::type { }; + +#endif + } // namespace detail namespace detail { @@ -202,21 +207,23 @@ namespace boost { #endif + // TODO Fix this for BOOST_NO_IS_CONVERTIBLE + template struct cvt_iterator_category : mpl::if_< mpl::logical_or< - is_convertible - , is_convertible + detail::is_mutable_lvalue_iterator + , detail::is_constant_lvalue_iterator > , typename mpl::if_< - is_convertible + detail::is_random_access_traversal_iterator , std::random_access_iterator_tag , typename mpl::if_< - is_convertible + detail::is_bidirectional_traversal_iterator , std::bidirectional_iterator_tag , typename mpl::if_< - is_convertible + detail::is_forward_traversal_iterator , std::forward_iterator_tag , error_iterator_tag >::type @@ -225,14 +232,14 @@ namespace boost { , typename mpl::if_< mpl::logical_and< - is_convertible - , is_convertible + detail::is_readable_iterator + , detail::is_input_traversal_iterator > , std::input_iterator_tag , typename mpl::if_< mpl::logical_and< - is_convertible - , is_convertible + detail::is_writable_iterator + , detail::is_output_traversal_iterator > , std::output_iterator_tag , error_iterator_tag @@ -249,7 +256,10 @@ namespace boost { typedef TraversalTag traversal; }; - } // namespace boost +#ifdef BOOST_NO_IS_CONVERTIBLE +# undef BOOST_NO_IS_CONVERTIBLE +#endif + #endif // BOOST_ITERATOR_CATEGORIES_HPP