File indexing completed on 2025-12-15 09:54:03
0001
0002
0003
0004
0005 #ifndef BOOST_ITERATOR_COUNTING_ITERATOR_DWA200348_HPP
0006 #define BOOST_ITERATOR_COUNTING_ITERATOR_DWA200348_HPP
0007
0008 #include <limits>
0009 #include <type_traits>
0010
0011 #include <boost/config.hpp>
0012 #include <boost/core/use_default.hpp>
0013 #include <boost/detail/numeric_traits.hpp>
0014 #include <boost/iterator/iterator_adaptor.hpp>
0015 #include <boost/iterator/iterator_categories.hpp>
0016 #include <boost/iterator/detail/if_default.hpp>
0017 #include <boost/iterator/detail/eval_if_default.hpp>
0018 #include <boost/iterator/detail/type_traits/type_identity.hpp>
0019
0020 namespace boost {
0021 namespace iterators {
0022
0023 template<
0024 typename Incrementable,
0025 typename CategoryOrTraversal,
0026 typename Difference
0027 >
0028 class counting_iterator;
0029
0030 namespace detail {
0031
0032
0033
0034 template< typename T >
0035 struct is_numeric :
0036 public std::integral_constant< bool, std::numeric_limits< T >::is_specialized >
0037 {};
0038
0039 template<>
0040 struct is_numeric< long long > :
0041 public std::true_type
0042 {};
0043
0044 template<>
0045 struct is_numeric< unsigned long long > :
0046 public std::true_type
0047 {};
0048
0049 #if defined(BOOST_HAS_INT128)
0050 template<>
0051 struct is_numeric< boost::int128_type > :
0052 public std::true_type
0053 {};
0054
0055 template<>
0056 struct is_numeric< boost::uint128_type > :
0057 public std::true_type
0058 {};
0059 #endif
0060
0061
0062 template<>
0063 struct is_numeric< wchar_t > :
0064 public std::true_type
0065 {};
0066
0067 template< typename T >
0068 struct numeric_difference
0069 {
0070 using type = typename boost::detail::numeric_traits< T >::difference_type;
0071 };
0072
0073 #if defined(BOOST_HAS_INT128)
0074
0075 template<>
0076 struct numeric_difference< boost::int128_type >
0077 {
0078 using type = boost::int128_type;
0079 };
0080
0081 template<>
0082 struct numeric_difference< boost::uint128_type >
0083 {
0084 using type = boost::int128_type;
0085 };
0086 #endif
0087
0088 template< typename Incrementable, typename CategoryOrTraversal, typename Difference, bool IsNumeric = is_numeric< Incrementable >::value >
0089 struct counting_iterator_types
0090 {
0091 using traversal = detail::eval_if_default_t<
0092 CategoryOrTraversal,
0093 iterator_traversal< Incrementable >
0094 >;
0095
0096 using difference = detail::eval_if_default_t<
0097 Difference,
0098 iterator_difference< Incrementable >
0099 >;
0100 };
0101
0102 template< typename Incrementable, typename CategoryOrTraversal, typename Difference >
0103 struct counting_iterator_types< Incrementable, CategoryOrTraversal, Difference, true >
0104 {
0105 using traversal = detail::if_default_t<
0106 CategoryOrTraversal,
0107 random_access_traversal_tag
0108 >;
0109
0110 using difference = detail::eval_if_default_t<
0111 Difference,
0112 numeric_difference< Incrementable >
0113 >;
0114 };
0115
0116 template< typename Incrementable, typename CategoryOrTraversal, typename Difference >
0117 struct counting_iterator_base
0118 {
0119 using iterator_types = counting_iterator_types< Incrementable, CategoryOrTraversal, Difference >;
0120
0121 using type = iterator_adaptor<
0122 counting_iterator< Incrementable, CategoryOrTraversal, Difference >,
0123 Incrementable,
0124 #ifndef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
0125 const
0126
0127 #endif
0128 Incrementable,
0129 typename iterator_types::traversal,
0130 Incrementable const&,
0131 typename iterator_types::difference
0132 >;
0133 };
0134
0135
0136 template< typename Difference, typename Incrementable1, typename Incrementable2 >
0137 struct iterator_distance
0138 {
0139 static Difference distance(Incrementable1 x, Incrementable2 y)
0140 {
0141 return y - x;
0142 }
0143 };
0144
0145
0146 template< typename Difference, typename Incrementable1, typename Incrementable2 >
0147 struct number_distance
0148 {
0149 static Difference distance(Incrementable1 x, Incrementable2 y)
0150 {
0151 return boost::detail::numeric_distance(x, y);
0152 }
0153 };
0154
0155 }
0156
0157 template<
0158 typename Incrementable,
0159 typename CategoryOrTraversal = use_default,
0160 typename Difference = use_default
0161 >
0162 class counting_iterator :
0163 public detail::counting_iterator_base< Incrementable, CategoryOrTraversal, Difference >::type
0164 {
0165 friend class iterator_core_access;
0166
0167 private:
0168 using super_t = typename detail::counting_iterator_base<
0169 Incrementable, CategoryOrTraversal, Difference
0170 >::type;
0171
0172 public:
0173 using reference = typename super_t::reference;
0174 using difference_type = typename super_t::difference_type;
0175
0176 counting_iterator() = default;
0177
0178 counting_iterator(counting_iterator const&) = default;
0179 counting_iterator& operator=(counting_iterator const&) = default;
0180
0181 counting_iterator(Incrementable x) :
0182 super_t(x)
0183 {
0184 }
0185
0186 private:
0187 reference dereference() const
0188 {
0189 return this->base_reference();
0190 }
0191
0192 template< typename OtherIncrementable >
0193 difference_type
0194 distance_to(counting_iterator< OtherIncrementable, CategoryOrTraversal, Difference > const& y) const
0195 {
0196 using distance_traits = typename std::conditional<
0197 detail::is_numeric< Incrementable >::value,
0198 detail::number_distance< difference_type, Incrementable, OtherIncrementable >,
0199 detail::iterator_distance< difference_type, Incrementable, OtherIncrementable >
0200 >::type;
0201
0202 return distance_traits::distance(this->base(), y.base());
0203 }
0204 };
0205
0206
0207 template< typename Incrementable >
0208 inline counting_iterator< Incrementable > make_counting_iterator(Incrementable x)
0209 {
0210 return counting_iterator< Incrementable >(x);
0211 }
0212
0213 }
0214
0215 using iterators::counting_iterator;
0216 using iterators::make_counting_iterator;
0217
0218 }
0219
0220 #endif