Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 09:54:03

0001 // Copyright David Abrahams 2003.
0002 // Distributed under the Boost Software License, Version 1.0. (See
0003 // accompanying file LICENSE_1_0.txt or copy at
0004 // http://www.boost.org/LICENSE_1_0.txt)
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 // Try to detect numeric types at compile time in ways compatible
0033 // with the limitations of the compiler and library.
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 // Some compilers fail to have a numeric_limits specialization
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 // std::numeric_limits, which is used by numeric_traits, is not specialized for __int128 in some standard libraries
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 >, // self
0123         Incrementable,                                           // Base
0124 #ifndef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
0125         const  // MSVC won't strip this.  Instead we enable Thomas'
0126                // criterion (see boost/iterator/detail/facade_iterator_category.hpp)
0127 #endif
0128         Incrementable,                                           // Value
0129         typename iterator_types::traversal,
0130         Incrementable const&,                                    // reference
0131         typename iterator_types::difference
0132     >;
0133 };
0134 
0135 // A distance calculation policy for wrapped iterators
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 // A distance calculation policy for wrapped numbers
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 } // namespace detail
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 // Manufacture a counting iterator for an arbitrary incrementable type
0207 template< typename Incrementable >
0208 inline counting_iterator< Incrementable > make_counting_iterator(Incrementable x)
0209 {
0210     return counting_iterator< Incrementable >(x);
0211 }
0212 
0213 } // namespace iterators
0214 
0215 using iterators::counting_iterator;
0216 using iterators::make_counting_iterator;
0217 
0218 } // namespace boost
0219 
0220 #endif // BOOST_ITERATOR_COUNTING_ITERATOR_DWA200348_HPP