Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:54

0001 // Copyright David Abrahams 2003. Use, modification and distribution is
0002 // subject to the Boost Software License, Version 1.0. (See accompanying
0003 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0004 #ifndef FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
0005 # define FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
0006 
0007 # include <boost/core/use_default.hpp>
0008 
0009 # include <boost/iterator/iterator_categories.hpp>
0010 
0011 # include <boost/mpl/or.hpp>  // used in iterator_tag inheritance logic
0012 # include <boost/mpl/and.hpp>
0013 # include <boost/mpl/if.hpp>
0014 # include <boost/mpl/eval_if.hpp>
0015 # include <boost/mpl/identity.hpp>
0016 
0017 # include <boost/static_assert.hpp>
0018 
0019 # include <boost/type_traits/is_same.hpp>
0020 # include <boost/type_traits/is_const.hpp>
0021 # include <boost/type_traits/is_reference.hpp>
0022 # include <boost/type_traits/is_convertible.hpp>
0023 
0024 # include <boost/iterator/detail/config_def.hpp> // try to keep this last
0025 
0026 # ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
0027 #  include <boost/detail/indirect_traits.hpp>
0028 # endif
0029 
0030 //
0031 // iterator_category deduction for iterator_facade
0032 //
0033 
0034 namespace boost {
0035 namespace iterators {
0036 
0037 using boost::use_default;
0038 
0039 namespace detail {
0040 
0041 struct input_output_iterator_tag
0042   : std::input_iterator_tag
0043 {
0044     // Using inheritance for only input_iterator_tag helps to avoid
0045     // ambiguities when a stdlib implementation dispatches on a
0046     // function which is overloaded on both input_iterator_tag and
0047     // output_iterator_tag, as STLPort does, in its __valid_range
0048     // function.  I claim it's better to avoid the ambiguity in these
0049     // cases.
0050     operator std::output_iterator_tag() const
0051     {
0052         return std::output_iterator_tag();
0053     }
0054 };
0055 
0056 //
0057 // True iff the user has explicitly disabled writability of this
0058 // iterator.  Pass the iterator_facade's Value parameter and its
0059 // nested ::reference type.
0060 //
0061 template <class ValueParam, class Reference>
0062 struct iterator_writability_disabled
0063 # ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY // Adding Thomas' logic?
0064   : mpl::or_<
0065         is_const<Reference>
0066       , boost::detail::indirect_traits::is_reference_to_const<Reference>
0067       , is_const<ValueParam>
0068     >
0069 # else
0070   : is_const<ValueParam>
0071 # endif
0072 {};
0073 
0074 
0075 //
0076 // Convert an iterator_facade's traversal category, Value parameter,
0077 // and ::reference type to an appropriate old-style category.
0078 //
0079 // Due to changeset 21683, this now never results in a category convertible
0080 // to output_iterator_tag.
0081 //
0082 // Change at: https://svn.boost.org/trac/boost/changeset/21683
0083 template <class Traversal, class ValueParam, class Reference>
0084 struct iterator_facade_default_category
0085   : mpl::eval_if<
0086         mpl::and_<
0087             is_reference<Reference>
0088           , is_convertible<Traversal,forward_traversal_tag>
0089         >
0090       , mpl::eval_if<
0091             is_convertible<Traversal,random_access_traversal_tag>
0092           , mpl::identity<std::random_access_iterator_tag>
0093           , mpl::if_<
0094                 is_convertible<Traversal,bidirectional_traversal_tag>
0095               , std::bidirectional_iterator_tag
0096               , std::forward_iterator_tag
0097             >
0098         >
0099       , typename mpl::eval_if<
0100             mpl::and_<
0101                 is_convertible<Traversal, single_pass_traversal_tag>
0102 
0103                 // check for readability
0104               , is_convertible<Reference, ValueParam>
0105             >
0106           , mpl::identity<std::input_iterator_tag>
0107           , mpl::identity<Traversal>
0108         >
0109     >
0110 {
0111 };
0112 
0113 // True iff T is convertible to an old-style iterator category.
0114 template <class T>
0115 struct is_iterator_category
0116   : mpl::or_<
0117         is_convertible<T,std::input_iterator_tag>
0118       , is_convertible<T,std::output_iterator_tag>
0119     >
0120 {
0121 };
0122 
0123 template <class T>
0124 struct is_iterator_traversal
0125   : is_convertible<T,incrementable_traversal_tag>
0126 {};
0127 
0128 //
0129 // A composite iterator_category tag convertible to Category (a pure
0130 // old-style category) and Traversal (a pure traversal tag).
0131 // Traversal must be a strict increase of the traversal power given by
0132 // Category.
0133 //
0134 template <class Category, class Traversal>
0135 struct iterator_category_with_traversal
0136   : Category, Traversal
0137 {
0138     // Make sure this isn't used to build any categories where
0139     // convertibility to Traversal is redundant.  Should just use the
0140     // Category element in that case.
0141     BOOST_STATIC_ASSERT((
0142         !is_convertible<
0143               typename iterator_category_to_traversal<Category>::type
0144             , Traversal
0145           >::value));
0146 
0147     BOOST_STATIC_ASSERT(is_iterator_category<Category>::value);
0148     BOOST_STATIC_ASSERT(!is_iterator_category<Traversal>::value);
0149     BOOST_STATIC_ASSERT(!is_iterator_traversal<Category>::value);
0150 #  if !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
0151     BOOST_STATIC_ASSERT(is_iterator_traversal<Traversal>::value);
0152 #  endif
0153 };
0154 
0155 // Computes an iterator_category tag whose traversal is Traversal and
0156 // which is appropriate for an iterator
0157 template <class Traversal, class ValueParam, class Reference>
0158 struct facade_iterator_category_impl
0159 {
0160     BOOST_STATIC_ASSERT(!is_iterator_category<Traversal>::value);
0161 
0162     typedef typename iterator_facade_default_category<
0163         Traversal,ValueParam,Reference
0164     >::type category;
0165 
0166     typedef typename mpl::if_<
0167         is_same<
0168             Traversal
0169           , typename iterator_category_to_traversal<category>::type
0170         >
0171       , category
0172       , iterator_category_with_traversal<category,Traversal>
0173     >::type type;
0174 };
0175 
0176 //
0177 // Compute an iterator_category for iterator_facade
0178 //
0179 template <class CategoryOrTraversal, class ValueParam, class Reference>
0180 struct facade_iterator_category
0181   : mpl::eval_if<
0182         is_iterator_category<CategoryOrTraversal>
0183       , mpl::identity<CategoryOrTraversal> // old-style categories are fine as-is
0184       , facade_iterator_category_impl<CategoryOrTraversal,ValueParam,Reference>
0185     >
0186 {
0187 };
0188 
0189 }}} // namespace boost::iterators::detail
0190 
0191 # include <boost/iterator/detail/config_undef.hpp>
0192 
0193 #endif // FACADE_ITERATOR_CATEGORY_DWA20031118_HPP