File indexing completed on 2025-09-18 08:47:26
0001
0002
0003
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
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
0038
0039
0040
0041
0042
0043
0044 template< typename ValueParam, typename Reference >
0045 struct iterator_writability_disabled :
0046 # ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
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
0063 std::is_convertible< Reference, ValueParam >
0064 >;
0065
0066
0067
0068
0069
0070
0071
0072
0073
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
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
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
0117
0118
0119
0120
0121 template< typename Category, typename Traversal >
0122 struct iterator_category_with_traversal :
0123 public Category,
0124 public Traversal
0125 {
0126
0127
0128
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
0141
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
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,
0171 facade_iterator_category_impl_t, CategoryOrTraversal, ValueParam, Reference
0172 >;
0173 };
0174
0175 }}}
0176
0177 #include <boost/iterator/detail/config_undef.hpp>
0178
0179 #endif