File indexing completed on 2025-11-04 09:49:55
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