Removed workarounds for older compilers from counting_iterator.hpp.

This commit is contained in:
Andrey Semashev
2025-01-29 03:38:46 +03:00
parent e5ee9a6168
commit d6a68dc6eb

View File

@ -5,209 +5,171 @@
#ifndef COUNTING_ITERATOR_DWA200348_HPP #ifndef COUNTING_ITERATOR_DWA200348_HPP
#define COUNTING_ITERATOR_DWA200348_HPP #define COUNTING_ITERATOR_DWA200348_HPP
#include <limits>
#include <type_traits> #include <type_traits>
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
#include <limits>
#endif
#include <boost/core/use_default.hpp> #include <boost/core/use_default.hpp>
#include <boost/detail/numeric_traits.hpp> #include <boost/detail/numeric_traits.hpp>
#include <boost/iterator/iterator_adaptor.hpp> #include <boost/iterator/iterator_adaptor.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/iterator/detail/type_traits/type_identity.hpp> #include <boost/iterator/detail/type_traits/type_identity.hpp>
namespace boost { namespace boost {
namespace iterators { namespace iterators {
template < template<
class Incrementable class Incrementable,
, class CategoryOrTraversal class CategoryOrTraversal,
, class Difference class Difference
> >
class counting_iterator; class counting_iterator;
namespace detail namespace detail {
// Try to detect numeric types at compile time in ways compatible
// with the limitations of the compiler and library.
template <class T>
struct is_numeric :
public std::integral_constant<bool, std::numeric_limits<T>::is_specialized>
{};
template <>
struct is_numeric<long long> :
public std::true_type
{};
template <>
struct is_numeric<unsigned long long> :
public std::true_type
{};
#if defined(BOOST_HAS_INT128)
template <>
struct is_numeric<boost::int128_type> :
public std::true_type
{};
template <>
struct is_numeric<boost::uint128_type> :
public std::true_type
{};
#endif
// Some compilers fail to have a numeric_limits specialization
template <>
struct is_numeric<wchar_t> :
public std::true_type
{};
template <class T>
struct numeric_difference
{ {
// Try to detect numeric types at compile time in ways compatible using type = typename boost::detail::numeric_traits<T>::difference_type;
// with the limitations of the compiler and library. };
template <class T>
struct is_numeric_impl
{
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
BOOST_STATIC_CONSTANT(bool, value = std::numeric_limits<T>::is_specialized);
#else
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551))
BOOST_STATIC_CONSTANT(
bool, value = (
std::is_convertible<int,T>::value
&& std::is_convertible<T,int>::value
));
#else
BOOST_STATIC_CONSTANT(bool, value = std::is_arithmetic<T>::value);
#endif
#endif
};
template <class T>
struct is_numeric
: std::integral_constant<bool, ::boost::iterators::detail::is_numeric_impl<T>::value>
{};
template <>
struct is_numeric<long long>
: std::true_type {};
template <>
struct is_numeric<unsigned long long>
: std::true_type {};
#if defined(BOOST_HAS_INT128) #if defined(BOOST_HAS_INT128)
template <> // std::numeric_limits, which is used by numeric_traits, is not specialized for __int128 in some standard libraries
struct is_numeric<boost::int128_type> template <>
: std::true_type {}; struct numeric_difference<boost::int128_type>
{
using type = boost::int128_type;
};
template <> template <>
struct is_numeric<boost::uint128_type> struct numeric_difference<boost::uint128_type>
: std::true_type {}; {
using type = boost::int128_type;
};
#endif #endif
// Some compilers fail to have a numeric_limits specialization template <class Incrementable, class CategoryOrTraversal, class Difference>
template <> struct counting_iterator_base
struct is_numeric<wchar_t> {
: std::true_type {}; using traversal = typename detail::ia_dflt_help<
CategoryOrTraversal,
template <class T> typename std::conditional<
struct numeric_difference is_numeric<Incrementable>::value,
{ iterators::detail::type_identity<random_access_traversal_tag>,
typedef typename boost::detail::numeric_traits<T>::difference_type type; iterator_traversal<Incrementable>
};
#if defined(BOOST_HAS_INT128)
// std::numeric_limits, which is used by numeric_traits, is not specialized for __int128 in some standard libraries
template <>
struct numeric_difference<boost::int128_type>
{
typedef boost::int128_type type;
};
template <>
struct numeric_difference<boost::uint128_type>
{
typedef boost::int128_type type;
};
#endif
template <class Incrementable, class CategoryOrTraversal, class Difference>
struct counting_iterator_base
{
typedef typename detail::ia_dflt_help<
CategoryOrTraversal
, typename std::conditional<
is_numeric<Incrementable>::value
, iterators::detail::type_identity<random_access_traversal_tag>
, iterator_traversal<Incrementable>
>::type >::type
>::type traversal; >::type;
typedef typename detail::ia_dflt_help< using difference = typename detail::ia_dflt_help<
Difference Difference,
, typename std::conditional< typename std::conditional<
is_numeric<Incrementable>::value is_numeric<Incrementable>::value,
, numeric_difference<Incrementable> numeric_difference<Incrementable>,
, iterator_difference<Incrementable> iterator_difference<Incrementable>
>::type >::type
>::type difference; >::type;
typedef iterator_adaptor< using type = iterator_adaptor<
counting_iterator<Incrementable, CategoryOrTraversal, Difference> // self counting_iterator<Incrementable, CategoryOrTraversal, Difference>, // self
, Incrementable // Base Incrementable, // Base
, Incrementable // Value
#ifndef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY #ifndef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
const // MSVC won't strip this. Instead we enable Thomas' const // MSVC won't strip this. Instead we enable Thomas'
// criterion (see boost/iterator/detail/facade_iterator_category.hpp) // criterion (see boost/iterator/detail/facade_iterator_category.hpp)
#endif #endif
, traversal Incrementable, // Value
, Incrementable const& // reference traversal,
, difference Incrementable const&, // reference
> type; difference
}; >;
};
// Template class distance_policy_select -- choose a policy for computing the // A distance calculation policy for wrapped iterators
// distance between counting_iterators at compile-time based on whether or not template <class Difference, class Incrementable1, class Incrementable2>
// the iterator wraps an integer or an iterator, using "poor man's partial struct iterator_distance
// specialization". {
template <bool is_integer> struct distance_policy_select;
// A policy for wrapped iterators
template <class Difference, class Incrementable1, class Incrementable2>
struct iterator_distance
{
static Difference distance(Incrementable1 x, Incrementable2 y) static Difference distance(Incrementable1 x, Incrementable2 y)
{ {
return y - x; return y - x;
} }
}; };
// A policy for wrapped numbers // A distance calculation policy for wrapped numbers
template <class Difference, class Incrementable1, class Incrementable2> template <class Difference, class Incrementable1, class Incrementable2>
struct number_distance struct number_distance
{ {
static Difference distance(Incrementable1 x, Incrementable2 y) static Difference distance(Incrementable1 x, Incrementable2 y)
{ {
return boost::detail::numeric_distance(x, y); return boost::detail::numeric_distance(x, y);
} }
}; };
}
template < } // namespace detail
class Incrementable
, class CategoryOrTraversal = use_default template<
, class Difference = use_default class Incrementable,
class CategoryOrTraversal = use_default,
class Difference = use_default
> >
class counting_iterator class counting_iterator :
: public detail::counting_iterator_base< public detail::counting_iterator_base<Incrementable, CategoryOrTraversal, Difference>::type
Incrementable, CategoryOrTraversal, Difference
>::type
{ {
typedef typename detail::counting_iterator_base< using super_t = typename detail::counting_iterator_base<
Incrementable, CategoryOrTraversal, Difference Incrementable, CategoryOrTraversal, Difference
>::type super_t; >::type;
friend class iterator_core_access; friend class iterator_core_access;
public: public:
typedef typename super_t::difference_type difference_type; using reference = typename super_t::reference;
using difference_type = typename super_t::difference_type;
BOOST_DEFAULTED_FUNCTION(counting_iterator(), {}) counting_iterator() = default;
BOOST_DEFAULTED_FUNCTION(counting_iterator(counting_iterator const& rhs), : super_t(rhs.base()) {}) counting_iterator(counting_iterator const&) = default;
counting_iterator& operator=(counting_iterator const&) = default;
counting_iterator(Incrementable x) counting_iterator(Incrementable x) :
: super_t(x) super_t(x)
{ {
} }
#if 0 private:
template<class OtherIncrementable> reference dereference() const
counting_iterator(
counting_iterator<OtherIncrementable, CategoryOrTraversal, Difference> const& t
, typename enable_if_convertible<OtherIncrementable, Incrementable>::type* = 0
)
: super_t(t.base())
{}
#endif
BOOST_DEFAULTED_FUNCTION(counting_iterator& operator=(counting_iterator const& rhs), { *static_cast< super_t* >(this) = static_cast< super_t const& >(rhs); return *this; })
private:
typename super_t::reference dereference() const
{ {
return this->base_reference(); return this->base_reference();
} }
@ -216,23 +178,21 @@ class counting_iterator
difference_type difference_type
distance_to(counting_iterator<OtherIncrementable, CategoryOrTraversal, Difference> const& y) const distance_to(counting_iterator<OtherIncrementable, CategoryOrTraversal, Difference> const& y) const
{ {
typedef typename std::conditional< using distance_traits = typename std::conditional<
detail::is_numeric<Incrementable>::value detail::is_numeric<Incrementable>::value,
, detail::number_distance<difference_type, Incrementable, OtherIncrementable> detail::number_distance<difference_type, Incrementable, OtherIncrementable>,
, detail::iterator_distance<difference_type, Incrementable, OtherIncrementable> detail::iterator_distance<difference_type, Incrementable, OtherIncrementable>
>::type d; >::type;
return d::distance(this->base(), y.base()); return distance_traits::distance(this->base(), y.base());
} }
}; };
// Manufacture a counting iterator for an arbitrary incrementable type // Manufacture a counting iterator for an arbitrary incrementable type
template <class Incrementable> template <class Incrementable>
inline counting_iterator<Incrementable> inline counting_iterator<Incrementable> make_counting_iterator(Incrementable x)
make_counting_iterator(Incrementable x)
{ {
typedef counting_iterator<Incrementable> result_t; return counting_iterator<Incrementable>(x);
return result_t(x);
} }
} // namespace iterators } // namespace iterators