Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 08:47:26

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 <iterator>
0008 #include <type_traits>
0009 
0010 #include <boost/mp11/utility.hpp>
0011 
0012 #include <boost/iterator/iterator_categories.hpp>
0013 #include <boost/iterator/detail/type_traits/conjunction.hpp>
0014 #include <boost/iterator/detail/type_traits/disjunction.hpp>
0015 #include <boost/iterator/detail/config_def.hpp> // try to keep this last
0016 
0017 //
0018 // iterator_category deduction for iterator_facade
0019 //
0020 
0021 namespace boost {
0022 namespace iterators {
0023 namespace detail {
0024 
0025 #ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
0026 
0027 template< typename T >
0028 struct is_const_lvalue_reference :
0029     public std::false_type
0030 {};
0031 
0032 template< typename T >
0033 struct is_const_lvalue_reference< T const& > :
0034     public std::true_type
0035 {};
0036 
0037 #endif // BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
0038 
0039 //
0040 // True iff the user has explicitly disabled writability of this
0041 // iterator.  Pass the iterator_facade's Value parameter and its
0042 // nested ::reference type.
0043 //
0044 template< typename ValueParam, typename Reference >
0045 struct iterator_writability_disabled :
0046 # ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY // Adding Thomas' logic?
0047     public detail::disjunction<
0048         detail::is_const_lvalue_reference< Reference >,
0049         std::is_const< Reference >,
0050         std::is_const< ValueParam >
0051     >
0052 # else
0053     public std::is_const< ValueParam >
0054 # endif
0055 {};
0056 
0057 
0058 template< typename Traversal, typename ValueParam, typename Reference >
0059 using is_traversal_of_input_iterator = detail::conjunction<
0060     std::is_convertible< Traversal, single_pass_traversal_tag >,
0061 
0062     // check for readability
0063     std::is_convertible< Reference, ValueParam >
0064 >;
0065 
0066 //
0067 // Convert an iterator_facade's traversal category, Value parameter,
0068 // and ::reference type to an appropriate old-style category.
0069 //
0070 // Due to changeset 21683, this now never results in a category convertible
0071 // to output_iterator_tag.
0072 //
0073 // Change at: https://svn.boost.org/trac/boost/changeset/21683
0074 template< typename Traversal, typename ValueParam, typename Reference >
0075 struct iterator_facade_default_category
0076 {
0077     using type = typename std::conditional<
0078         detail::is_traversal_of_input_iterator< Traversal, ValueParam, Reference >::value,
0079         std::input_iterator_tag,
0080         Traversal
0081     >::type;
0082 };
0083 
0084 // Specialization for the (typical) case when the reference type is an actual reference
0085 template< typename Traversal, typename ValueParam, typename Referenced >
0086 struct iterator_facade_default_category< Traversal, ValueParam, Referenced& >
0087 {
0088     using type = mp11::mp_cond<
0089         std::is_convertible< Traversal, random_access_traversal_tag >, std::random_access_iterator_tag,
0090         std::is_convertible< Traversal, bidirectional_traversal_tag >, std::bidirectional_iterator_tag,
0091         std::is_convertible< Traversal, forward_traversal_tag >, std::forward_iterator_tag,
0092         detail::is_traversal_of_input_iterator< Traversal, ValueParam, Referenced& >, std::input_iterator_tag,
0093         std::true_type, Traversal
0094     >;
0095 };
0096 
0097 template< typename Traversal, typename ValueParam, typename Reference >
0098 using iterator_facade_default_category_t = typename iterator_facade_default_category< Traversal, ValueParam, Reference >::type;
0099 
0100 // True iff T is convertible to an old-style iterator category.
0101 template< typename T >
0102 struct is_iterator_category :
0103     public detail::disjunction<
0104         std::is_convertible< T, std::input_iterator_tag >,
0105         std::is_convertible< T, std::output_iterator_tag >
0106     >
0107 {};
0108 
0109 template< typename T >
0110 struct is_iterator_traversal :
0111     public std::is_convertible< T, incrementable_traversal_tag >
0112 {};
0113 
0114 
0115 //
0116 // A composite iterator_category tag convertible to Category (a pure
0117 // old-style category) and Traversal (a pure traversal tag).
0118 // Traversal must be a strict increase of the traversal power given by
0119 // Category.
0120 //
0121 template< typename Category, typename Traversal >
0122 struct iterator_category_with_traversal :
0123     public Category,
0124     public Traversal
0125 {
0126     // Make sure this isn't used to build any categories where
0127     // convertibility to Traversal is redundant.  Should just use the
0128     // Category element in that case.
0129     static_assert(
0130         !std::is_convertible< iterator_category_to_traversal_t< Category >, Traversal >::value,
0131         "Category transformed to corresponding traversal must be convertible to Traversal."
0132     );
0133 
0134     static_assert(is_iterator_category< Category >::value, "Category must be an STL iterator category.");
0135     static_assert(!is_iterator_category< Traversal >::value, "Traversal must not be an STL iterator category.");
0136     static_assert(!is_iterator_traversal< Category >::value, "Category must not be a traversal tag.");
0137     static_assert(is_iterator_traversal< Traversal >::value, "Traversal must be a traversal tag.");
0138 };
0139 
0140 // Computes an iterator_category tag whose traversal is Traversal and
0141 // which is appropriate for an iterator
0142 template< typename Traversal, typename ValueParam, typename Reference >
0143 struct facade_iterator_category_impl
0144 {
0145     static_assert(!is_iterator_category< Traversal >::value, "Traversal must not be an STL iterator category.");
0146 
0147     using category = iterator_facade_default_category_t< Traversal, ValueParam, Reference >;
0148 
0149     using type = typename std::conditional<
0150         std::is_same<
0151             Traversal,
0152             typename iterator_category_to_traversal< category >::type
0153         >::value,
0154         category,
0155         iterator_category_with_traversal< category, Traversal >
0156     >::type;
0157 };
0158 
0159 template< typename Traversal, typename ValueParam, typename Reference >
0160 using facade_iterator_category_impl_t = typename facade_iterator_category_impl< Traversal, ValueParam, Reference >::type;
0161 
0162 //
0163 // Compute an iterator_category for iterator_facade
0164 //
0165 template< typename CategoryOrTraversal, typename ValueParam, typename Reference >
0166 struct facade_iterator_category
0167 {
0168     using type = mp11::mp_eval_if<
0169         is_iterator_category< CategoryOrTraversal >,
0170         CategoryOrTraversal, // old-style categories are fine as-is
0171         facade_iterator_category_impl_t, CategoryOrTraversal, ValueParam, Reference
0172     >;
0173 };
0174 
0175 }}} // namespace boost::iterators::detail
0176 
0177 #include <boost/iterator/detail/config_undef.hpp>
0178 
0179 #endif // FACADE_ITERATOR_CATEGORY_DWA20031118_HPP