diff --git a/include/boost/iterator/detail/minimum_category.hpp b/include/boost/iterator/detail/minimum_category.hpp index 68a41a5..748c0d3 100644 --- a/include/boost/iterator/detail/minimum_category.hpp +++ b/include/boost/iterator/detail/minimum_category.hpp @@ -4,98 +4,14 @@ #ifndef MINIMUM_CATEGORY_DWA20031119_HPP # define MINIMUM_CATEGORY_DWA20031119_HPP -# include -# include - -# include +# include namespace boost { -namespace iterators { + +// This import below (as well as the whole header) is for backward compatibility +// with boost/token_iterator.hpp. It should be removed as soon as that header is fixed. namespace detail { -// -// Returns the minimum category type or error_type -// if T1 and T2 are unrelated. -// -// For compilers not supporting is_convertible this only -// works with the new boost return and traversal category -// types. The exact boost _types_ are required. No derived types -// will work. -// -// -template -struct minimum_category_impl; - -template -struct error_not_related_by_convertibility; - -template <> -struct minimum_category_impl -{ - template struct apply - { - typedef T2 type; - }; -}; - -template <> -struct minimum_category_impl -{ - template struct apply - { - typedef T1 type; - }; -}; - -template <> -struct minimum_category_impl -{ - template struct apply - { - BOOST_STATIC_ASSERT((is_same::value)); - typedef T1 type; - }; -}; - -template <> -struct minimum_category_impl -{ - template struct apply - : error_not_related_by_convertibility - { - }; -}; - -template -struct minimum_category -{ - typedef minimum_category_impl< - ::boost::is_convertible::value - , ::boost::is_convertible::value - > outer; - - typedef typename outer::template apply inner; - typedef typename inner::type type; - - BOOST_MPL_AUX_LAMBDA_SUPPORT(2,minimum_category,(T1,T2)) -}; - -template <> -struct minimum_category -{ - template - struct apply : minimum_category - {}; - - BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2,minimum_category,(mpl::_1,mpl::_2)) -}; - -} // namespace detail -} // namespace iterators - -// This import below is for backward compatibility with boost/token_iterator.hpp. -// It should be removed as soon as that header is fixed. -namespace detail { -using iterators::detail::minimum_category; +using iterators::minimum_category; } // namespace detail } // namespace boost diff --git a/include/boost/iterator/iterator_categories.hpp b/include/boost/iterator/iterator_categories.hpp index 20baf6d..31b2a9d 100644 --- a/include/boost/iterator/iterator_categories.hpp +++ b/include/boost/iterator/iterator_categories.hpp @@ -98,35 +98,8 @@ namespace detail > {}; - template - struct pure_traversal_tag - : mpl::eval_if< - is_convertible - , mpl::identity - , mpl::eval_if< - is_convertible - , mpl::identity - , mpl::eval_if< - is_convertible - , mpl::identity - , mpl::eval_if< - is_convertible - , mpl::identity - , mpl::eval_if< - is_convertible - , mpl::identity - , void - > - > - > - > - > - { - }; - } // namespace detail - // // Convert an iterator category into a traversal tag // @@ -166,6 +139,64 @@ struct iterator_traversal {}; # endif +// +// Convert an iterator traversal to one of the traversal tags. +// +template +struct pure_traversal_tag + : mpl::eval_if< + is_convertible + , mpl::identity + , mpl::eval_if< + is_convertible + , mpl::identity + , mpl::eval_if< + is_convertible + , mpl::identity + , mpl::eval_if< + is_convertible + , mpl::identity + , mpl::eval_if< + is_convertible + , mpl::identity + , void + > + > + > + > + > +{ +}; + +// This import is needed for backward compatibility with Boost.Range: +// boost/range/detail/demote_iterator_traversal_tag.hpp +// It should be removed when that header is fixed. +namespace detail { +using iterators::pure_traversal_tag; +} // namespace detail + +// +// Trait to retrieve one of the iterator traversal tags from the iterator category or traversal. +// +template +struct pure_iterator_traversal + : pure_traversal_tag::type> +{}; + +# ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT +template <> +struct pure_iterator_traversal +{ + template + struct apply : pure_iterator_traversal + {}; +}; +template <> +struct pure_iterator_traversal + : pure_iterator_traversal +{}; +# endif + } // namespace iterators using iterators::no_traversal_tag; @@ -177,6 +208,13 @@ using iterators::random_access_traversal_tag; using iterators::iterator_category_to_traversal; using iterators::iterator_traversal; +// This import is needed for backward compatibility with Boost.Range: +// boost/range/detail/demote_iterator_traversal_tag.hpp +// It should be removed when that header is fixed. +namespace detail { +using iterators::pure_traversal_tag; +} // namespace detail + } // namespace boost #include diff --git a/include/boost/iterator/iterator_concepts.hpp b/include/boost/iterator/iterator_concepts.hpp index ae6c4b3..1a9f7d6 100644 --- a/include/boost/iterator/iterator_concepts.hpp +++ b/include/boost/iterator/iterator_concepts.hpp @@ -248,19 +248,10 @@ namespace boost_concepts BOOST_concept(InteroperableIterator,(Iterator)(ConstIterator)) { private: - typedef typename boost::iterators::detail::pure_traversal_tag< - typename boost::iterator_traversal< - Iterator - >::type - >::type traversal_category; + typedef typename boost::iterators::pure_iterator_traversal::type traversal_category; + typedef typename boost::iterators::pure_iterator_traversal::type const_traversal_category; - typedef typename boost::iterators::detail::pure_traversal_tag< - typename boost::iterator_traversal< - ConstIterator - >::type - >::type const_traversal_category; - - public: + public: BOOST_CONCEPT_ASSERT((SinglePassIterator)); BOOST_CONCEPT_ASSERT((SinglePassIterator)); diff --git a/include/boost/iterator/minimum_category.hpp b/include/boost/iterator/minimum_category.hpp new file mode 100644 index 0000000..15679bc --- /dev/null +++ b/include/boost/iterator/minimum_category.hpp @@ -0,0 +1,95 @@ +// Copyright David Abrahams 2003. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_ +# define BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_ + +# include +# include +# include + +# include +# include + +namespace boost { +namespace iterators { +namespace detail { + +template +struct minimum_category_impl; + +template +struct error_not_related_by_convertibility; + +template <> +struct minimum_category_impl +{ + template struct apply + { + typedef T2 type; + }; +}; + +template <> +struct minimum_category_impl +{ + template struct apply + { + typedef T1 type; + }; +}; + +template <> +struct minimum_category_impl +{ + template struct apply + { + BOOST_STATIC_ASSERT((is_same::value)); + typedef T1 type; + }; +}; + +template <> +struct minimum_category_impl +{ + template struct apply + : error_not_related_by_convertibility + { + }; +}; + +} // namespace detail + +// +// Returns the minimum category type or fails to compile +// if T1 and T2 are unrelated. +// +template +struct minimum_category +{ + typedef boost::iterators::detail::minimum_category_impl< + ::boost::is_convertible::value + , ::boost::is_convertible::value + > outer; + + typedef typename outer::template apply inner; + typedef typename inner::type type; + + BOOST_MPL_AUX_LAMBDA_SUPPORT(2,minimum_category,(T1,T2)) +}; + +template <> +struct minimum_category +{ + template + struct apply : minimum_category + {}; + + BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2,minimum_category,(mpl::_1,mpl::_2)) +}; + +} // namespace iterators + +} // namespace boost + +#endif // BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_ diff --git a/include/boost/iterator/zip_iterator.hpp b/include/boost/iterator/zip_iterator.hpp index fbbc1e7..304f65e 100644 --- a/include/boost/iterator/zip_iterator.hpp +++ b/include/boost/iterator/zip_iterator.hpp @@ -14,7 +14,7 @@ #include #include -#include +#include #include diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 6230469..b187835 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -3,28 +3,28 @@ # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) test-suite iterator - : + : # These first two tests will run last, and are expected to fail # for many less-capable compilers. - + [ compile-fail interoperable_fail.cpp ] # test uses expected success, so that we catch unrelated # compilation problems. - [ run is_convertible_fail.cpp ] + [ run is_convertible_fail.cpp ] [ run zip_iterator_test.cpp - : : : - + : : : + # stlport's debug mode generates long symbols which overwhelm # vc6 - #<*>release + #<*>release ] - + # These tests should work for just about everything. [ compile is_lvalue_iterator.cpp ] [ compile is_readable_iterator.cpp ] [ compile pointee.cpp ] - + [ run unit_tests.cpp ] [ run concept_tests.cpp ] [ run iterator_adaptor_cc.cpp ] @@ -41,9 +41,12 @@ test-suite iterator [ run counting_iterator_test.cpp ] [ run interoperable.cpp ] [ run iterator_traits_test.cpp ] - [ run permutation_iterator_test.cpp : : : # on + [ run permutation_iterator_test.cpp : : : # on ] [ run function_input_iterator_test.cpp ] - + [ run generator_iterator_test.cpp ] + + [ run minimum_category.cpp ] + [ compile-fail minimum_category_compile_fail.cpp ] ; diff --git a/test/minimum_category.cpp b/test/minimum_category.cpp new file mode 100644 index 0000000..3f89d6c --- /dev/null +++ b/test/minimum_category.cpp @@ -0,0 +1,22 @@ +// Copyright Andrey Semashev 2014. +// +// Use, modification and distribution is subject to +// the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include + +using boost::is_same; +using boost::iterators::minimum_category; + +int main(int, char*[]) +{ + BOOST_TEST_TRAIT_TRUE((is_same::type, std::forward_iterator_tag>)); + BOOST_TEST_TRAIT_TRUE((is_same::type, std::forward_iterator_tag>)); + BOOST_TEST_TRAIT_TRUE((is_same::type, std::random_access_iterator_tag>)); + + return boost::report_errors(); +} diff --git a/test/minimum_category_compile_fail.cpp b/test/minimum_category_compile_fail.cpp new file mode 100644 index 0000000..736cc20 --- /dev/null +++ b/test/minimum_category_compile_fail.cpp @@ -0,0 +1,19 @@ +// Copyright Andrey Semashev 2014. +// +// Use, modification and distribution is subject to +// the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include + +using boost::iterators::minimum_category; + +struct A {}; +struct B {}; + +int main(int, char*[]) +{ + minimum_category::type cat; + + return 0; +} diff --git a/test/unit_tests.cpp b/test/unit_tests.cpp index bcad0d6..656e72f 100644 --- a/test/unit_tests.cpp +++ b/test/unit_tests.cpp @@ -7,7 +7,7 @@ #include "static_assert_same.hpp" -#include +#include struct X { int a; }; @@ -29,7 +29,7 @@ void operator_arrow_test() template struct static_assert_min_cat : static_assert_same< - typename boost::iterators::detail::minimum_category::type, Min + typename boost::iterators::minimum_category::type, Min > {}; diff --git a/test/zip_iterator_test.cpp b/test/zip_iterator_test.cpp index fd7628f..b508098 100644 --- a/test/zip_iterator_test.cpp +++ b/test/zip_iterator_test.cpp @@ -55,13 +55,6 @@ #include #include -template -struct pure_traversal - : boost::iterators::detail::pure_traversal_tag< - typename boost::iterator_traversal::type - > -{}; - /// Tests for https://svn.boost.org/trac/boost/ticket/1517 int to_value(int const &v)