整理
This commit is contained in:
74
include/boost/iterator/advance.hpp
Normal file
74
include/boost/iterator/advance.hpp
Normal file
@@ -0,0 +1,74 @@
|
||||
// Copyright (C) 2017 Michel Morin.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_ITERATOR_ADVANCE_HPP
|
||||
#define BOOST_ITERATOR_ADVANCE_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
namespace detail {
|
||||
|
||||
template< typename InputIterator, typename Distance >
|
||||
inline BOOST_CXX14_CONSTEXPR void advance_impl(InputIterator& it, Distance n, incrementable_traversal_tag)
|
||||
{
|
||||
while (n > 0)
|
||||
{
|
||||
++it;
|
||||
--n;
|
||||
}
|
||||
}
|
||||
|
||||
template< typename BidirectionalIterator, typename Distance >
|
||||
inline BOOST_CXX14_CONSTEXPR void advance_impl(BidirectionalIterator& it, Distance n, bidirectional_traversal_tag)
|
||||
{
|
||||
if (n >= 0)
|
||||
{
|
||||
while (n > 0)
|
||||
{
|
||||
++it;
|
||||
--n;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (n < 0)
|
||||
{
|
||||
--it;
|
||||
++n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template< typename RandomAccessIterator, typename Distance >
|
||||
inline BOOST_CXX14_CONSTEXPR void advance_impl(RandomAccessIterator& it, Distance n, random_access_traversal_tag)
|
||||
{
|
||||
it += n;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
namespace advance_adl_barrier {
|
||||
|
||||
template< typename InputIterator, typename Distance >
|
||||
inline BOOST_CXX14_CONSTEXPR void advance(InputIterator& it, Distance n)
|
||||
{
|
||||
detail::advance_impl(it, n, typename iterator_traversal< InputIterator >::type());
|
||||
}
|
||||
|
||||
} // namespace advance_adl_barrier
|
||||
|
||||
using namespace advance_adl_barrier;
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using namespace iterators::advance_adl_barrier;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
220
include/boost/iterator/counting_iterator.hpp
Normal file
220
include/boost/iterator/counting_iterator.hpp
Normal file
@@ -0,0 +1,220 @@
|
||||
// Copyright David Abrahams 2003.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_ITERATOR_COUNTING_ITERATOR_DWA200348_HPP
|
||||
#define BOOST_ITERATOR_COUNTING_ITERATOR_DWA200348_HPP
|
||||
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/core/use_default.hpp>
|
||||
#include <boost/detail/numeric_traits.hpp>
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/iterator/detail/if_default.hpp>
|
||||
#include <boost/iterator/detail/eval_if_default.hpp>
|
||||
#include <boost/iterator/detail/type_traits/type_identity.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
template<
|
||||
typename Incrementable,
|
||||
typename CategoryOrTraversal,
|
||||
typename Difference
|
||||
>
|
||||
class counting_iterator;
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Try to detect numeric types at compile time in ways compatible
|
||||
// with the limitations of the compiler and library.
|
||||
template< typename 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< typename T >
|
||||
struct numeric_difference
|
||||
{
|
||||
using type = typename boost::detail::numeric_traits< T >::difference_type;
|
||||
};
|
||||
|
||||
#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 >
|
||||
{
|
||||
using type = boost::int128_type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct numeric_difference< boost::uint128_type >
|
||||
{
|
||||
using type = boost::int128_type;
|
||||
};
|
||||
#endif
|
||||
|
||||
template< typename Incrementable, typename CategoryOrTraversal, typename Difference, bool IsNumeric = is_numeric< Incrementable >::value >
|
||||
struct counting_iterator_types
|
||||
{
|
||||
using traversal = detail::eval_if_default_t<
|
||||
CategoryOrTraversal,
|
||||
iterator_traversal< Incrementable >
|
||||
>;
|
||||
|
||||
using difference = detail::eval_if_default_t<
|
||||
Difference,
|
||||
iterator_difference< Incrementable >
|
||||
>;
|
||||
};
|
||||
|
||||
template< typename Incrementable, typename CategoryOrTraversal, typename Difference >
|
||||
struct counting_iterator_types< Incrementable, CategoryOrTraversal, Difference, true >
|
||||
{
|
||||
using traversal = detail::if_default_t<
|
||||
CategoryOrTraversal,
|
||||
random_access_traversal_tag
|
||||
>;
|
||||
|
||||
using difference = detail::eval_if_default_t<
|
||||
Difference,
|
||||
numeric_difference< Incrementable >
|
||||
>;
|
||||
};
|
||||
|
||||
template< typename Incrementable, typename CategoryOrTraversal, typename Difference >
|
||||
struct counting_iterator_base
|
||||
{
|
||||
using iterator_types = counting_iterator_types< Incrementable, CategoryOrTraversal, Difference >;
|
||||
|
||||
using type = iterator_adaptor<
|
||||
counting_iterator< Incrementable, CategoryOrTraversal, Difference >, // self
|
||||
Incrementable, // Base
|
||||
#ifndef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
||||
const // MSVC won't strip this. Instead we enable Thomas'
|
||||
// criterion (see boost/iterator/detail/facade_iterator_category.hpp)
|
||||
#endif
|
||||
Incrementable, // Value
|
||||
typename iterator_types::traversal,
|
||||
Incrementable const&, // reference
|
||||
typename iterator_types::difference
|
||||
>;
|
||||
};
|
||||
|
||||
// A distance calculation policy for wrapped iterators
|
||||
template< typename Difference, typename Incrementable1, typename Incrementable2 >
|
||||
struct iterator_distance
|
||||
{
|
||||
static Difference distance(Incrementable1 x, Incrementable2 y)
|
||||
{
|
||||
return y - x;
|
||||
}
|
||||
};
|
||||
|
||||
// A distance calculation policy for wrapped numbers
|
||||
template< typename Difference, typename Incrementable1, typename Incrementable2 >
|
||||
struct number_distance
|
||||
{
|
||||
static Difference distance(Incrementable1 x, Incrementable2 y)
|
||||
{
|
||||
return boost::detail::numeric_distance(x, y);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<
|
||||
typename Incrementable,
|
||||
typename CategoryOrTraversal = use_default,
|
||||
typename Difference = use_default
|
||||
>
|
||||
class counting_iterator :
|
||||
public detail::counting_iterator_base< Incrementable, CategoryOrTraversal, Difference >::type
|
||||
{
|
||||
friend class iterator_core_access;
|
||||
|
||||
private:
|
||||
using super_t = typename detail::counting_iterator_base<
|
||||
Incrementable, CategoryOrTraversal, Difference
|
||||
>::type;
|
||||
|
||||
public:
|
||||
using reference = typename super_t::reference;
|
||||
using difference_type = typename super_t::difference_type;
|
||||
|
||||
counting_iterator() = default;
|
||||
|
||||
counting_iterator(counting_iterator const&) = default;
|
||||
counting_iterator& operator=(counting_iterator const&) = default;
|
||||
|
||||
counting_iterator(Incrementable x) :
|
||||
super_t(x)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
reference dereference() const
|
||||
{
|
||||
return this->base_reference();
|
||||
}
|
||||
|
||||
template< typename OtherIncrementable >
|
||||
difference_type
|
||||
distance_to(counting_iterator< OtherIncrementable, CategoryOrTraversal, Difference > const& y) const
|
||||
{
|
||||
using distance_traits = typename std::conditional<
|
||||
detail::is_numeric< Incrementable >::value,
|
||||
detail::number_distance< difference_type, Incrementable, OtherIncrementable >,
|
||||
detail::iterator_distance< difference_type, Incrementable, OtherIncrementable >
|
||||
>::type;
|
||||
|
||||
return distance_traits::distance(this->base(), y.base());
|
||||
}
|
||||
};
|
||||
|
||||
// Manufacture a counting iterator for an arbitrary incrementable type
|
||||
template< typename Incrementable >
|
||||
inline counting_iterator< Incrementable > make_counting_iterator(Incrementable x)
|
||||
{
|
||||
return counting_iterator< Incrementable >(x);
|
||||
}
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::counting_iterator;
|
||||
using iterators::make_counting_iterator;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_COUNTING_ITERATOR_DWA200348_HPP
|
||||
45
include/boost/iterator/detail/config_def.hpp
Normal file
45
include/boost/iterator/detail/config_def.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
// (C) Copyright David Abrahams 2002.
|
||||
// (C) Copyright Jeremy Siek 2002.
|
||||
// (C) Copyright Thomas Witt 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// no include guard multiple inclusion intended
|
||||
|
||||
//
|
||||
// This is a temporary workaround until the bulk of this is
|
||||
// available in boost config.
|
||||
// 23/02/03 thw
|
||||
//
|
||||
|
||||
#include <boost/config.hpp> // for prior
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#ifdef BOOST_ITERATOR_CONFIG_DEF
|
||||
# error you have nested config_def #inclusion.
|
||||
#else
|
||||
# define BOOST_ITERATOR_CONFIG_DEF
|
||||
#endif
|
||||
|
||||
// We enable this always now. Otherwise, the simple case in
|
||||
// libs/iterator/test/constant_iterator_arrow.cpp fails to compile
|
||||
// because the operator-> return is improperly deduced as a non-const
|
||||
// pointer.
|
||||
|
||||
// Recall that in general, compilers without partial specialization
|
||||
// can't strip constness. Consider counting_iterator, which normally
|
||||
// passes a const Value to iterator_facade. As a result, any code
|
||||
// which makes a std::vector of the iterator's value_type will fail
|
||||
// when its allocator declares functions overloaded on reference and
|
||||
// const_reference (the same type).
|
||||
//
|
||||
// Furthermore, Borland 5.5.1 drops constness in enough ways that we
|
||||
// end up using a proxy for operator[] when we otherwise shouldn't.
|
||||
// Using reference constness gives it an extra hint that it can
|
||||
// return the value_type from operator[] directly, but is not
|
||||
// strictly necessary. Not sure how best to resolve this one.
|
||||
|
||||
# define BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY 1
|
||||
|
||||
// no include guard; multiple inclusion intended
|
||||
20
include/boost/iterator/detail/config_undef.hpp
Normal file
20
include/boost/iterator/detail/config_undef.hpp
Normal file
@@ -0,0 +1,20 @@
|
||||
// (C) Copyright Thomas Witt 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// no include guard multiple inclusion intended
|
||||
|
||||
//
|
||||
// This is a temporary workaround until the bulk of this is
|
||||
// available in boost config.
|
||||
// 23/02/03 thw
|
||||
//
|
||||
|
||||
#undef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
||||
|
||||
#ifdef BOOST_ITERATOR_CONFIG_DEF
|
||||
# undef BOOST_ITERATOR_CONFIG_DEF
|
||||
#else
|
||||
# error missing or nested #include config_def
|
||||
#endif
|
||||
44
include/boost/iterator/detail/eval_if_default.hpp
Normal file
44
include/boost/iterator/detail/eval_if_default.hpp
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* https://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* Copyright (c) 2025 Andrey Semashev
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ITERATOR_DETAIL_EVAL_IF_DEFAULT_HPP_INCLUDED_
|
||||
#define BOOST_ITERATOR_DETAIL_EVAL_IF_DEFAULT_HPP_INCLUDED_
|
||||
|
||||
#include <boost/core/use_default.hpp>
|
||||
#include <boost/iterator/detail/type_traits/type_identity.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
namespace detail {
|
||||
|
||||
// If T is use_default, return the result of invoking
|
||||
// DefaultNullaryFn, otherwise - of NondefaultNullaryFn.
|
||||
// By default, NondefaultNullaryFn returns T, which means
|
||||
// the metafunction can be called with just two parameters
|
||||
// and in that case will return either T or the result of
|
||||
// invoking DefaultNullaryFn.
|
||||
template< typename T, typename DefaultNullaryFn, typename NondefaultNullaryFn = detail::type_identity< T > >
|
||||
struct eval_if_default
|
||||
{
|
||||
using type = typename NondefaultNullaryFn::type;
|
||||
};
|
||||
|
||||
template< typename DefaultNullaryFn, typename NondefaultNullaryFn >
|
||||
struct eval_if_default< use_default, DefaultNullaryFn, NondefaultNullaryFn >
|
||||
{
|
||||
using type = typename DefaultNullaryFn::type;
|
||||
};
|
||||
|
||||
template< typename T, typename DefaultNullaryFn, typename NondefaultNullaryFn = detail::type_identity< T > >
|
||||
using eval_if_default_t = typename eval_if_default< T, DefaultNullaryFn, NondefaultNullaryFn >::type;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace iterators
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_DETAIL_EVAL_IF_DEFAULT_HPP_INCLUDED_
|
||||
179
include/boost/iterator/detail/facade_iterator_category.hpp
Normal file
179
include/boost/iterator/detail/facade_iterator_category.hpp
Normal file
@@ -0,0 +1,179 @@
|
||||
// Copyright David Abrahams 2003. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
|
||||
#define FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/mp11/utility.hpp>
|
||||
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/iterator/detail/type_traits/conjunction.hpp>
|
||||
#include <boost/iterator/detail/type_traits/disjunction.hpp>
|
||||
#include <boost/iterator/detail/config_def.hpp> // try to keep this last
|
||||
|
||||
//
|
||||
// iterator_category deduction for iterator_facade
|
||||
//
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
namespace detail {
|
||||
|
||||
#ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
||||
|
||||
template< typename T >
|
||||
struct is_const_lvalue_reference :
|
||||
public std::false_type
|
||||
{};
|
||||
|
||||
template< typename T >
|
||||
struct is_const_lvalue_reference< T const& > :
|
||||
public std::true_type
|
||||
{};
|
||||
|
||||
#endif // BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
||||
|
||||
//
|
||||
// True iff the user has explicitly disabled writability of this
|
||||
// iterator. Pass the iterator_facade's Value parameter and its
|
||||
// nested ::reference type.
|
||||
//
|
||||
template< typename ValueParam, typename Reference >
|
||||
struct iterator_writability_disabled :
|
||||
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY // Adding Thomas' logic?
|
||||
public detail::disjunction<
|
||||
detail::is_const_lvalue_reference< Reference >,
|
||||
std::is_const< Reference >,
|
||||
std::is_const< ValueParam >
|
||||
>
|
||||
# else
|
||||
public std::is_const< ValueParam >
|
||||
# endif
|
||||
{};
|
||||
|
||||
|
||||
template< typename Traversal, typename ValueParam, typename Reference >
|
||||
using is_traversal_of_input_iterator = detail::conjunction<
|
||||
std::is_convertible< Traversal, single_pass_traversal_tag >,
|
||||
|
||||
// check for readability
|
||||
std::is_convertible< Reference, ValueParam >
|
||||
>;
|
||||
|
||||
//
|
||||
// Convert an iterator_facade's traversal category, Value parameter,
|
||||
// and ::reference type to an appropriate old-style category.
|
||||
//
|
||||
// Due to changeset 21683, this now never results in a category convertible
|
||||
// to output_iterator_tag.
|
||||
//
|
||||
// Change at: https://svn.boost.org/trac/boost/changeset/21683
|
||||
template< typename Traversal, typename ValueParam, typename Reference >
|
||||
struct iterator_facade_default_category
|
||||
{
|
||||
using type = typename std::conditional<
|
||||
detail::is_traversal_of_input_iterator< Traversal, ValueParam, Reference >::value,
|
||||
std::input_iterator_tag,
|
||||
Traversal
|
||||
>::type;
|
||||
};
|
||||
|
||||
// Specialization for the (typical) case when the reference type is an actual reference
|
||||
template< typename Traversal, typename ValueParam, typename Referenced >
|
||||
struct iterator_facade_default_category< Traversal, ValueParam, Referenced& >
|
||||
{
|
||||
using type = mp11::mp_cond<
|
||||
std::is_convertible< Traversal, random_access_traversal_tag >, std::random_access_iterator_tag,
|
||||
std::is_convertible< Traversal, bidirectional_traversal_tag >, std::bidirectional_iterator_tag,
|
||||
std::is_convertible< Traversal, forward_traversal_tag >, std::forward_iterator_tag,
|
||||
detail::is_traversal_of_input_iterator< Traversal, ValueParam, Referenced& >, std::input_iterator_tag,
|
||||
std::true_type, Traversal
|
||||
>;
|
||||
};
|
||||
|
||||
template< typename Traversal, typename ValueParam, typename Reference >
|
||||
using iterator_facade_default_category_t = typename iterator_facade_default_category< Traversal, ValueParam, Reference >::type;
|
||||
|
||||
// True iff T is convertible to an old-style iterator category.
|
||||
template< typename T >
|
||||
struct is_iterator_category :
|
||||
public detail::disjunction<
|
||||
std::is_convertible< T, std::input_iterator_tag >,
|
||||
std::is_convertible< T, std::output_iterator_tag >
|
||||
>
|
||||
{};
|
||||
|
||||
template< typename T >
|
||||
struct is_iterator_traversal :
|
||||
public std::is_convertible< T, incrementable_traversal_tag >
|
||||
{};
|
||||
|
||||
|
||||
//
|
||||
// A composite iterator_category tag convertible to Category (a pure
|
||||
// old-style category) and Traversal (a pure traversal tag).
|
||||
// Traversal must be a strict increase of the traversal power given by
|
||||
// Category.
|
||||
//
|
||||
template< typename Category, typename Traversal >
|
||||
struct iterator_category_with_traversal :
|
||||
public Category,
|
||||
public Traversal
|
||||
{
|
||||
// Make sure this isn't used to build any categories where
|
||||
// convertibility to Traversal is redundant. Should just use the
|
||||
// Category element in that case.
|
||||
static_assert(
|
||||
!std::is_convertible< iterator_category_to_traversal_t< Category >, Traversal >::value,
|
||||
"Category transformed to corresponding traversal must be convertible to Traversal."
|
||||
);
|
||||
|
||||
static_assert(is_iterator_category< Category >::value, "Category must be an STL iterator category.");
|
||||
static_assert(!is_iterator_category< Traversal >::value, "Traversal must not be an STL iterator category.");
|
||||
static_assert(!is_iterator_traversal< Category >::value, "Category must not be a traversal tag.");
|
||||
static_assert(is_iterator_traversal< Traversal >::value, "Traversal must be a traversal tag.");
|
||||
};
|
||||
|
||||
// Computes an iterator_category tag whose traversal is Traversal and
|
||||
// which is appropriate for an iterator
|
||||
template< typename Traversal, typename ValueParam, typename Reference >
|
||||
struct facade_iterator_category_impl
|
||||
{
|
||||
static_assert(!is_iterator_category< Traversal >::value, "Traversal must not be an STL iterator category.");
|
||||
|
||||
using category = iterator_facade_default_category_t< Traversal, ValueParam, Reference >;
|
||||
|
||||
using type = typename std::conditional<
|
||||
std::is_same<
|
||||
Traversal,
|
||||
typename iterator_category_to_traversal< category >::type
|
||||
>::value,
|
||||
category,
|
||||
iterator_category_with_traversal< category, Traversal >
|
||||
>::type;
|
||||
};
|
||||
|
||||
template< typename Traversal, typename ValueParam, typename Reference >
|
||||
using facade_iterator_category_impl_t = typename facade_iterator_category_impl< Traversal, ValueParam, Reference >::type;
|
||||
|
||||
//
|
||||
// Compute an iterator_category for iterator_facade
|
||||
//
|
||||
template< typename CategoryOrTraversal, typename ValueParam, typename Reference >
|
||||
struct facade_iterator_category
|
||||
{
|
||||
using type = mp11::mp_eval_if<
|
||||
is_iterator_category< CategoryOrTraversal >,
|
||||
CategoryOrTraversal, // old-style categories are fine as-is
|
||||
facade_iterator_category_impl_t, CategoryOrTraversal, ValueParam, Reference
|
||||
>;
|
||||
};
|
||||
|
||||
}}} // namespace boost::iterators::detail
|
||||
|
||||
#include <boost/iterator/detail/config_undef.hpp>
|
||||
|
||||
#endif // FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
|
||||
41
include/boost/iterator/detail/if_default.hpp
Normal file
41
include/boost/iterator/detail/if_default.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* https://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* Copyright (c) 2025 Andrey Semashev
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ITERATOR_DETAIL_IF_DEFAULT_HPP_INCLUDED_
|
||||
#define BOOST_ITERATOR_DETAIL_IF_DEFAULT_HPP_INCLUDED_
|
||||
|
||||
#include <boost/core/use_default.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
namespace detail {
|
||||
|
||||
// If T is use_default, return Default, otherwise - Nondefault.
|
||||
// By default, Nondefault is T, which means
|
||||
// the metafunction can be called with just two parameters
|
||||
// and in that case will return either T or Default.
|
||||
template< typename T, typename Default, typename Nondefault = T >
|
||||
struct if_default
|
||||
{
|
||||
using type = Nondefault;
|
||||
};
|
||||
|
||||
template< typename Default, typename Nondefault >
|
||||
struct if_default< use_default, Default, Nondefault >
|
||||
{
|
||||
using type = Default;
|
||||
};
|
||||
|
||||
template< typename T, typename Default, typename Nondefault = T >
|
||||
using if_default_t = typename if_default< T, Default, Nondefault >::type;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace iterators
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_DETAIL_IF_DEFAULT_HPP_INCLUDED_
|
||||
53
include/boost/iterator/detail/type_traits/conjunction.hpp
Normal file
53
include/boost/iterator/detail/type_traits/conjunction.hpp
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* https://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* Copyright (c) 2024 Georgiy Guminov
|
||||
*/
|
||||
/*!
|
||||
* \file iterator/detail/type_traits/conjunction.hpp
|
||||
*
|
||||
* This header contains definition of \c conjunction type trait.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ITERATOR_DETAIL_TYPE_TRAITS_CONJUNCTION_HPP_INCLUDED_
|
||||
#define BOOST_ITERATOR_DETAIL_TYPE_TRAITS_CONJUNCTION_HPP_INCLUDED_
|
||||
|
||||
#include <type_traits>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if (defined(__cpp_lib_logical_traits) && (__cpp_lib_logical_traits >= 201510l)) || \
|
||||
(defined(BOOST_MSSTL_VERSION) && (BOOST_MSSTL_VERSION >= 140) && (_MSC_FULL_VER >= 190023918) && (BOOST_CXX_VERSION >= 201703l))
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
namespace detail {
|
||||
|
||||
using std::conjunction;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace iterator
|
||||
} // namespace boost
|
||||
|
||||
#else
|
||||
|
||||
#include <boost/type_traits/conjunction.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
namespace detail {
|
||||
|
||||
using boost::conjunction;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace iterator
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
#endif // BOOST_ITERATOR_DETAIL_TYPE_TRAITS_CONJUNCTION_HPP_INCLUDED_
|
||||
53
include/boost/iterator/detail/type_traits/disjunction.hpp
Normal file
53
include/boost/iterator/detail/type_traits/disjunction.hpp
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* https://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* Copyright (c) 2024 Georgiy Guminov
|
||||
*/
|
||||
/*!
|
||||
* \file iterator/detail/type_traits/disjunction.hpp
|
||||
*
|
||||
* This header contains definition of \c disjunction type trait.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ITERATOR_DETAIL_TYPE_TRAITS_DISJUNCTION_HPP_INCLUDED_
|
||||
#define BOOST_ITERATOR_DETAIL_TYPE_TRAITS_DISJUNCTION_HPP_INCLUDED_
|
||||
|
||||
#include <type_traits>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if (defined(__cpp_lib_logical_traits) && (__cpp_lib_logical_traits >= 201510l)) || \
|
||||
(defined(BOOST_MSSTL_VERSION) && (BOOST_MSSTL_VERSION >= 140) && (_MSC_FULL_VER >= 190023918) && (BOOST_CXX_VERSION >= 201703l))
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
namespace detail {
|
||||
|
||||
using std::disjunction;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace iterator
|
||||
} // namespace boost
|
||||
|
||||
#else
|
||||
|
||||
#include <boost/type_traits/disjunction.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
namespace detail {
|
||||
|
||||
using boost::disjunction;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace iterator
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
#endif // BOOST_ITERATOR_DETAIL_TYPE_TRAITS_DISJUNCTION_HPP_INCLUDED_
|
||||
53
include/boost/iterator/detail/type_traits/negation.hpp
Normal file
53
include/boost/iterator/detail/type_traits/negation.hpp
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* https://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* Copyright (c) 2024 Georgiy Guminov
|
||||
*/
|
||||
/*!
|
||||
* \file iterator/detail/type_traits/negation.hpp
|
||||
*
|
||||
* This header contains definition of \c negation type trait.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ITERATOR_DETAIL_TYPE_TRAITS_NEGATION_HPP_INCLUDED_
|
||||
#define BOOST_ITERATOR_DETAIL_TYPE_TRAITS_NEGATION_HPP_INCLUDED_
|
||||
|
||||
#include <type_traits>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if (defined(__cpp_lib_logical_traits) && (__cpp_lib_logical_traits >= 201510l)) || \
|
||||
(defined(BOOST_MSSTL_VERSION) && (BOOST_MSSTL_VERSION >= 140) && (_MSC_FULL_VER >= 190023918) && (BOOST_CXX_VERSION >= 201703l))
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
namespace detail {
|
||||
|
||||
using std::negation;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace iterator
|
||||
} // namespace boost
|
||||
|
||||
#else
|
||||
|
||||
#include <boost/type_traits/negation.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
namespace detail {
|
||||
|
||||
using boost::negation;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace iterator
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
#endif // BOOST_ITERATOR_DETAIL_TYPE_TRAITS_NEGATION_HPP_INCLUDED_
|
||||
54
include/boost/iterator/detail/type_traits/type_identity.hpp
Normal file
54
include/boost/iterator/detail/type_traits/type_identity.hpp
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* https://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* Copyright (c) 2025 Andrey Semashev
|
||||
*/
|
||||
/*!
|
||||
* \file iterator/detail/type_traits/type_identity.hpp
|
||||
*
|
||||
* This header contains definition of \c negation type trait.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ITERATOR_DETAIL_TYPE_TRAITS_TYPE_IDENTITY_HPP_INCLUDED_
|
||||
#define BOOST_ITERATOR_DETAIL_TYPE_TRAITS_TYPE_IDENTITY_HPP_INCLUDED_
|
||||
|
||||
#include <type_traits>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if (defined(__cpp_lib_type_identity) && (__cpp_lib_type_identity >= 201806l)) || \
|
||||
/* Note: MSVC 19.21 does not define _MSVC_LANG to 202002 in c++latest (C++20) mode but to a value larger than 201703 */ \
|
||||
(defined(BOOST_MSSTL_VERSION) && (BOOST_MSSTL_VERSION >= 142) && (_MSC_VER >= 1921) && (BOOST_CXX_VERSION > 201703l))
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
namespace detail {
|
||||
|
||||
using std::type_identity;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace iterator
|
||||
} // namespace boost
|
||||
|
||||
#else
|
||||
|
||||
#include <boost/type_traits/type_identity.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
namespace detail {
|
||||
|
||||
using boost::type_identity;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace iterator
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
#endif // BOOST_ITERATOR_DETAIL_TYPE_TRAITS_TYPE_IDENTITY_HPP_INCLUDED_
|
||||
59
include/boost/iterator/distance.hpp
Normal file
59
include/boost/iterator/distance.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright (C) 2017 Michel Morin.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_ITERATOR_DISTANCE_HPP
|
||||
#define BOOST_ITERATOR_DISTANCE_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
namespace detail {
|
||||
|
||||
template< typename SinglePassIterator >
|
||||
inline BOOST_CXX14_CONSTEXPR typename iterator_difference< SinglePassIterator >::type
|
||||
distance_impl(SinglePassIterator first, SinglePassIterator last, single_pass_traversal_tag)
|
||||
{
|
||||
typename iterator_difference< SinglePassIterator >::type n = 0;
|
||||
while (first != last)
|
||||
{
|
||||
++first;
|
||||
++n;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
template< typename RandomAccessIterator >
|
||||
inline BOOST_CXX14_CONSTEXPR typename iterator_difference< RandomAccessIterator >::type
|
||||
distance_impl(RandomAccessIterator first, RandomAccessIterator last, random_access_traversal_tag)
|
||||
{
|
||||
return last - first;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
namespace distance_adl_barrier {
|
||||
|
||||
template< typename SinglePassIterator >
|
||||
inline BOOST_CXX14_CONSTEXPR typename iterator_difference< SinglePassIterator >::type
|
||||
distance(SinglePassIterator first, SinglePassIterator last)
|
||||
{
|
||||
return detail::distance_impl(first, last, typename iterator_traversal< SinglePassIterator >::type());
|
||||
}
|
||||
|
||||
} // namespace distance_adl_barrier
|
||||
|
||||
using namespace distance_adl_barrier;
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using namespace iterators::distance_adl_barrier;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
84
include/boost/iterator/enable_if_convertible.hpp
Normal file
84
include/boost/iterator/enable_if_convertible.hpp
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* https://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* Copyright (c) 2025 Andrey Semashev
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ITERATOR_ENABLE_IF_CONVERTIBLE_HPP_INCLUDED_
|
||||
#define BOOST_ITERATOR_ENABLE_IF_CONVERTIBLE_HPP_INCLUDED_
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
namespace detail {
|
||||
|
||||
//
|
||||
// Result type used in enable_if_convertible meta function.
|
||||
// This can be an incomplete type, as only pointers to
|
||||
// enable_if_convertible< ... >::type are used.
|
||||
// We could have used void for this, but conversion to
|
||||
// void* is just too easy.
|
||||
//
|
||||
struct enable_type;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
//
|
||||
// enable_if for use in adapted iterators constructors.
|
||||
//
|
||||
// In order to provide interoperability between adapted constant and
|
||||
// mutable iterators, adapted iterators will usually provide templated
|
||||
// conversion constructors of the following form
|
||||
//
|
||||
// template <class BaseIterator>
|
||||
// class adapted_iterator :
|
||||
// public iterator_adaptor< adapted_iterator<Iterator>, Iterator >
|
||||
// {
|
||||
// public:
|
||||
//
|
||||
// ...
|
||||
//
|
||||
// template <class OtherIterator>
|
||||
// adapted_iterator(
|
||||
// OtherIterator const& it
|
||||
// , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0);
|
||||
//
|
||||
// ...
|
||||
// };
|
||||
//
|
||||
// enable_if_convertible is used to remove those overloads from the overload
|
||||
// set that cannot be instantiated. For all practical purposes only overloads
|
||||
// for constant/mutable interaction will remain. This has the advantage that
|
||||
// meta functions like boost::is_convertible do not return false positives,
|
||||
// as they can only look at the signature of the conversion constructor
|
||||
// and not at the actual instantiation.
|
||||
//
|
||||
// enable_if_interoperable can be safely used in user code. It falls back to
|
||||
// always enabled for compilers that don't support enable_if or is_convertible.
|
||||
// There is no need for compiler specific workarounds in user code.
|
||||
//
|
||||
// The operators implementation relies on boost::is_convertible not returning
|
||||
// false positives for user/library defined iterator types. See comments
|
||||
// on operator implementation for consequences.
|
||||
//
|
||||
template< typename From, typename To >
|
||||
struct enable_if_convertible :
|
||||
public std::enable_if<
|
||||
std::is_convertible< From, To >::value,
|
||||
boost::iterators::detail::enable_type
|
||||
>
|
||||
{};
|
||||
|
||||
template< typename From, typename To >
|
||||
using enable_if_convertible_t = typename enable_if_convertible< From, To >::type;
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::enable_if_convertible;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_ENABLE_IF_CONVERTIBLE_HPP_INCLUDED_
|
||||
157
include/boost/iterator/filter_iterator.hpp
Normal file
157
include/boost/iterator/filter_iterator.hpp
Normal file
@@ -0,0 +1,157 @@
|
||||
// (C) Copyright David Abrahams 2002.
|
||||
// (C) Copyright Jeremy Siek 2002.
|
||||
// (C) Copyright Thomas Witt 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_FILTER_ITERATOR_23022003THW_HPP
|
||||
#define BOOST_FILTER_ITERATOR_23022003THW_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/core/use_default.hpp>
|
||||
#include <boost/core/empty_value.hpp>
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/iterator/enable_if_convertible.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
template< typename Predicate, typename Iterator >
|
||||
class filter_iterator;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template< typename Predicate, typename Iterator >
|
||||
using filter_iterator_base_t = iterator_adaptor<
|
||||
filter_iterator< Predicate, Iterator >,
|
||||
Iterator,
|
||||
use_default,
|
||||
typename std::conditional<
|
||||
std::is_convertible<
|
||||
iterator_traversal_t< Iterator >,
|
||||
random_access_traversal_tag
|
||||
>::value,
|
||||
bidirectional_traversal_tag,
|
||||
use_default
|
||||
>::type
|
||||
>;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template< typename Predicate, typename Iterator >
|
||||
class filter_iterator :
|
||||
public detail::filter_iterator_base_t< Predicate, Iterator >
|
||||
{
|
||||
friend class iterator_core_access;
|
||||
|
||||
template< typename, typename >
|
||||
friend class filter_iterator;
|
||||
|
||||
private:
|
||||
using super_t = detail::filter_iterator_base_t< Predicate, Iterator >;
|
||||
|
||||
// Storage class to leverage EBO, when possible
|
||||
struct storage :
|
||||
private boost::empty_value< Predicate >
|
||||
{
|
||||
using predicate_base = boost::empty_value< Predicate >;
|
||||
|
||||
Iterator m_end;
|
||||
|
||||
storage() = default;
|
||||
|
||||
template<
|
||||
typename Iter,
|
||||
typename = typename std::enable_if<
|
||||
!std::is_same<
|
||||
typename std::remove_cv< typename std::remove_reference< Iter >::type >::type,
|
||||
storage
|
||||
>::value
|
||||
>
|
||||
>
|
||||
explicit storage(Iter&& end) :
|
||||
predicate_base(boost::empty_init_t{}), m_end(static_cast< Iterator&& >(end))
|
||||
{
|
||||
}
|
||||
|
||||
template< typename Pred, typename Iter >
|
||||
storage(Pred&& pred, Iter&& end) :
|
||||
predicate_base(boost::empty_init_t{}, static_cast< Pred&& >(pred)), m_end(static_cast< Iter&& >(end))
|
||||
{
|
||||
}
|
||||
|
||||
Predicate& predicate() noexcept { return predicate_base::get(); }
|
||||
Predicate const& predicate() const noexcept { return predicate_base::get(); }
|
||||
};
|
||||
|
||||
public:
|
||||
filter_iterator() = default;
|
||||
|
||||
filter_iterator(Predicate f, Iterator x, Iterator end = Iterator()) :
|
||||
super_t(static_cast< Iterator&& >(x)), m_storage(static_cast< Predicate&& >(f), static_cast< Iterator&& >(end))
|
||||
{
|
||||
satisfy_predicate();
|
||||
}
|
||||
|
||||
template< bool Requires = std::is_class< Predicate >::value, typename = typename std::enable_if< Requires >::type >
|
||||
filter_iterator(Iterator x, Iterator end = Iterator()) :
|
||||
super_t(static_cast< Iterator&& >(x)), m_storage(static_cast< Iterator&& >(end))
|
||||
{
|
||||
satisfy_predicate();
|
||||
}
|
||||
|
||||
template< typename OtherIterator, typename = enable_if_convertible_t< OtherIterator, Iterator > >
|
||||
filter_iterator(filter_iterator< Predicate, OtherIterator > const& t) :
|
||||
super_t(t.base()), m_storage(t.m_storage.predicate(), t.m_storage.m_end)
|
||||
{}
|
||||
|
||||
Predicate predicate() const { return m_storage.predicate(); }
|
||||
Iterator end() const { return m_storage.m_end; }
|
||||
|
||||
private:
|
||||
void increment()
|
||||
{
|
||||
++(this->base_reference());
|
||||
satisfy_predicate();
|
||||
}
|
||||
|
||||
void decrement()
|
||||
{
|
||||
while (!m_storage.predicate()(*--(this->base_reference()))) {}
|
||||
}
|
||||
|
||||
void satisfy_predicate()
|
||||
{
|
||||
while (this->base() != m_storage.m_end && !m_storage.predicate()(*this->base()))
|
||||
++(this->base_reference());
|
||||
}
|
||||
|
||||
private:
|
||||
storage m_storage;
|
||||
};
|
||||
|
||||
template< typename Predicate, typename Iterator >
|
||||
inline filter_iterator< Predicate, Iterator > make_filter_iterator(Predicate f, Iterator x, Iterator end = Iterator())
|
||||
{
|
||||
return filter_iterator< Predicate, Iterator >(static_cast< Predicate&& >(f), static_cast< Iterator&& >(x), static_cast< Iterator&& >(end));
|
||||
}
|
||||
|
||||
template< typename Predicate, typename Iterator >
|
||||
inline typename std::enable_if<
|
||||
std::is_class< Predicate >::value,
|
||||
filter_iterator< Predicate, Iterator >
|
||||
>::type make_filter_iterator(Iterator x, Iterator end = Iterator())
|
||||
{
|
||||
return filter_iterator< Predicate, Iterator >(static_cast< Iterator&& >(x), static_cast< Iterator&& >(end));
|
||||
}
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::filter_iterator;
|
||||
using iterators::make_filter_iterator;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_FILTER_ITERATOR_23022003THW_HPP
|
||||
162
include/boost/iterator/function_input_iterator.hpp
Normal file
162
include/boost/iterator/function_input_iterator.hpp
Normal file
@@ -0,0 +1,162 @@
|
||||
// Copyright 2009 (C) Dean Michael Berris <me@deanberris.com>
|
||||
// Copyright 2012 (C) Google, Inc.
|
||||
// Copyright 2012 (C) Jeffrey Lee Hellrung, Jr.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BOOST_ITERATOR_FUNCTION_INPUT_ITERATOR_HPP_INCLUDED_
|
||||
#define BOOST_ITERATOR_FUNCTION_INPUT_ITERATOR_HPP_INCLUDED_
|
||||
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/iterator/detail/type_traits/conjunction.hpp>
|
||||
#include <boost/optional/optional.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
template< typename Function, typename Input >
|
||||
class function_input_iterator;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template< typename Function, typename Input >
|
||||
using function_input_iterator_facade_base_t = iterator_facade<
|
||||
iterators::function_input_iterator< Function, Input >,
|
||||
decltype(std::declval< Function& >()()),
|
||||
single_pass_traversal_tag,
|
||||
decltype(std::declval< Function& >()()) const&
|
||||
>;
|
||||
|
||||
template< typename Function, typename Input >
|
||||
class function_object_input_iterator :
|
||||
public function_input_iterator_facade_base_t< Function, Input >
|
||||
{
|
||||
private:
|
||||
using base_type = function_input_iterator_facade_base_t< Function, Input >;
|
||||
|
||||
protected:
|
||||
using function_arg_type = Function&;
|
||||
|
||||
public:
|
||||
using value_type = typename base_type::value_type;
|
||||
|
||||
public:
|
||||
function_object_input_iterator(function_arg_type f, Input state) :
|
||||
m_f(std::addressof(f)), m_state(state)
|
||||
{}
|
||||
|
||||
protected:
|
||||
typename std::add_pointer< Function >::type m_f;
|
||||
Input m_state;
|
||||
mutable optional< value_type > m_value;
|
||||
};
|
||||
|
||||
template< typename Function, typename Input >
|
||||
class function_pointer_input_iterator :
|
||||
public function_input_iterator_facade_base_t< Function, Input >
|
||||
{
|
||||
private:
|
||||
using base_type = function_input_iterator_facade_base_t< Function, Input >;
|
||||
|
||||
protected:
|
||||
using function_arg_type = Function;
|
||||
|
||||
public:
|
||||
using value_type = typename base_type::value_type;
|
||||
|
||||
public:
|
||||
function_pointer_input_iterator(function_arg_type f, Input state) :
|
||||
m_f(f), m_state(state)
|
||||
{}
|
||||
|
||||
protected:
|
||||
Function m_f;
|
||||
Input m_state;
|
||||
mutable optional< value_type > m_value;
|
||||
};
|
||||
|
||||
template< typename Function, typename Input >
|
||||
using function_input_iterator_base_t = typename std::conditional<
|
||||
detail::conjunction<
|
||||
std::is_pointer< Function >,
|
||||
std::is_function< typename std::remove_pointer< Function >::type >
|
||||
>::value,
|
||||
detail::function_pointer_input_iterator< Function, Input >,
|
||||
detail::function_object_input_iterator< Function, Input >
|
||||
>::type;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template< typename Function, typename Input >
|
||||
class function_input_iterator :
|
||||
public detail::function_input_iterator_base_t< Function, Input >
|
||||
{
|
||||
private:
|
||||
using base_type = detail::function_input_iterator_base_t< Function, Input >;
|
||||
using function_arg_type = typename base_type::function_arg_type;
|
||||
|
||||
public:
|
||||
using reference = typename base_type::reference;
|
||||
|
||||
public:
|
||||
function_input_iterator(function_arg_type f, Input i) :
|
||||
base_type(f, i)
|
||||
{}
|
||||
|
||||
void increment()
|
||||
{
|
||||
if (this->m_value)
|
||||
this->m_value.reset();
|
||||
else
|
||||
(*this->m_f)();
|
||||
++this->m_state;
|
||||
}
|
||||
|
||||
reference dereference() const
|
||||
{
|
||||
if (!this->m_value)
|
||||
this->m_value = (*this->m_f)();
|
||||
return this->m_value.get();
|
||||
}
|
||||
|
||||
bool equal(function_input_iterator const& other) const
|
||||
{
|
||||
return this->m_f == other.m_f && this->m_state == other.m_state;
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Function, typename Input >
|
||||
inline function_input_iterator< Function, Input > make_function_input_iterator(Function& f, Input state)
|
||||
{
|
||||
return function_input_iterator< Function, Input >(f, state);
|
||||
}
|
||||
|
||||
template< typename Function, typename Input >
|
||||
inline function_input_iterator< Function*, Input > make_function_input_iterator(Function* f, Input state)
|
||||
{
|
||||
return function_input_iterator< Function*, Input >(f, state);
|
||||
}
|
||||
|
||||
struct infinite
|
||||
{
|
||||
infinite& operator++() { return *this; }
|
||||
infinite& operator++(int) { return *this; }
|
||||
bool operator==(infinite&) const { return false; };
|
||||
bool operator==(infinite const&) const { return false; };
|
||||
};
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::function_input_iterator;
|
||||
using iterators::make_function_input_iterator;
|
||||
using iterators::infinite;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_FUNCTION_INPUT_ITERATOR_HPP_INCLUDED_
|
||||
89
include/boost/iterator/function_output_iterator.hpp
Normal file
89
include/boost/iterator/function_output_iterator.hpp
Normal file
@@ -0,0 +1,89 @@
|
||||
// (C) Copyright Jeremy Siek 2001.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Revision History:
|
||||
|
||||
// 27 Feb 2001 Jeremy Siek
|
||||
// Initial checkin.
|
||||
|
||||
#ifndef BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP_INCLUDED_
|
||||
#define BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP_INCLUDED_
|
||||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
template< typename UnaryFunction >
|
||||
class function_output_iterator
|
||||
{
|
||||
private:
|
||||
class output_proxy
|
||||
{
|
||||
public:
|
||||
explicit output_proxy(UnaryFunction& f) noexcept :
|
||||
m_f(f)
|
||||
{}
|
||||
|
||||
template< typename T >
|
||||
typename std::enable_if<
|
||||
!std::is_same< typename std::remove_cv< typename std::remove_reference< T >::type >::type, output_proxy >::value,
|
||||
output_proxy const&
|
||||
>::type operator=(T&& value) const
|
||||
{
|
||||
m_f(static_cast< T&& >(value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
output_proxy(output_proxy const& that) = default;
|
||||
output_proxy& operator=(output_proxy const&) = delete;
|
||||
|
||||
private:
|
||||
UnaryFunction& m_f;
|
||||
};
|
||||
|
||||
public:
|
||||
using iterator_category = std::output_iterator_tag;
|
||||
using value_type = void;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = void;
|
||||
using reference = void;
|
||||
|
||||
template<
|
||||
bool Requires = std::is_class< UnaryFunction >::value,
|
||||
typename = typename std::enable_if< Requires >::type
|
||||
>
|
||||
function_output_iterator() :
|
||||
m_f()
|
||||
{}
|
||||
|
||||
explicit function_output_iterator(UnaryFunction const& f) :
|
||||
m_f(f)
|
||||
{}
|
||||
|
||||
output_proxy operator*() { return output_proxy(m_f); }
|
||||
function_output_iterator& operator++() { return *this; }
|
||||
function_output_iterator& operator++(int) { return *this; }
|
||||
|
||||
private:
|
||||
UnaryFunction m_f;
|
||||
};
|
||||
|
||||
template< typename UnaryFunction >
|
||||
inline function_output_iterator< UnaryFunction > make_function_output_iterator(UnaryFunction const& f = UnaryFunction())
|
||||
{
|
||||
return function_output_iterator< UnaryFunction >(f);
|
||||
}
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::function_output_iterator;
|
||||
using iterators::make_function_output_iterator;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP_INCLUDED_
|
||||
96
include/boost/iterator/generator_iterator.hpp
Normal file
96
include/boost/iterator/generator_iterator.hpp
Normal file
@@ -0,0 +1,96 @@
|
||||
// (C) Copyright Jens Maurer 2001.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Revision History:
|
||||
|
||||
// 15 Nov 2001 Jens Maurer
|
||||
// created.
|
||||
|
||||
// See http://www.boost.org/libs/utility/iterator_adaptors.htm for documentation.
|
||||
|
||||
#ifndef BOOST_ITERATOR_GENERATOR_ITERATOR_HPP_INCLUDED_
|
||||
#define BOOST_ITERATOR_GENERATOR_ITERATOR_HPP_INCLUDED_
|
||||
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
template< typename Generator >
|
||||
class generator_iterator :
|
||||
public iterator_facade<
|
||||
generator_iterator< Generator >,
|
||||
decltype(std::declval< Generator& >()()),
|
||||
single_pass_traversal_tag,
|
||||
decltype(std::declval< Generator& >()()) const&
|
||||
>
|
||||
{
|
||||
friend class iterator_core_access;
|
||||
|
||||
private:
|
||||
using super_t = iterator_facade<
|
||||
generator_iterator< Generator >,
|
||||
decltype(std::declval< Generator& >()()),
|
||||
single_pass_traversal_tag,
|
||||
decltype(std::declval< Generator& >()()) const&
|
||||
>;
|
||||
|
||||
public:
|
||||
generator_iterator() :
|
||||
m_g(nullptr),
|
||||
m_value()
|
||||
{}
|
||||
|
||||
generator_iterator(Generator* g) :
|
||||
m_g(g),
|
||||
m_value((*m_g)())
|
||||
{}
|
||||
|
||||
private:
|
||||
void increment()
|
||||
{
|
||||
m_value = (*m_g)();
|
||||
}
|
||||
|
||||
typename super_t::reference dereference() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
bool equal(generator_iterator const& y) const
|
||||
{
|
||||
return m_g == y.m_g && m_value == y.m_value;
|
||||
}
|
||||
|
||||
private:
|
||||
Generator* m_g;
|
||||
typename Generator::result_type m_value;
|
||||
};
|
||||
|
||||
template< typename Generator >
|
||||
struct generator_iterator_generator
|
||||
{
|
||||
using type = generator_iterator< Generator >;
|
||||
};
|
||||
|
||||
template< typename Generator >
|
||||
inline generator_iterator< Generator > make_generator_iterator(Generator& gen)
|
||||
{
|
||||
return generator_iterator< Generator >(std::addressof(gen));
|
||||
}
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::generator_iterator;
|
||||
using iterators::generator_iterator_generator;
|
||||
using iterators::make_generator_iterator;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_GENERATOR_ITERATOR_HPP_INCLUDED_
|
||||
121
include/boost/iterator/indirect_iterator.hpp
Normal file
121
include/boost/iterator/indirect_iterator.hpp
Normal file
@@ -0,0 +1,121 @@
|
||||
// (C) Copyright David Abrahams 2002.
|
||||
// (C) Copyright Jeremy Siek 2002.
|
||||
// (C) Copyright Thomas Witt 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_INDIRECT_ITERATOR_23022003THW_HPP
|
||||
#define BOOST_INDIRECT_ITERATOR_23022003THW_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/iterator/enable_if_convertible.hpp>
|
||||
#include <boost/iterator/detail/eval_if_default.hpp>
|
||||
|
||||
#include <boost/pointee.hpp>
|
||||
#include <boost/indirect_reference.hpp>
|
||||
|
||||
#include <boost/core/use_default.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
template< typename Iter, typename Value, typename Category, typename Reference, typename Difference >
|
||||
class indirect_iterator;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template< typename Iter, typename Value, typename Category, typename Reference, typename Difference >
|
||||
struct indirect_base
|
||||
{
|
||||
using dereferenceable = typename std::iterator_traits< Iter >::value_type;
|
||||
|
||||
using type = iterator_adaptor<
|
||||
indirect_iterator< Iter, Value, Category, Reference, Difference >,
|
||||
Iter,
|
||||
detail::eval_if_default_t<
|
||||
Value,
|
||||
pointee< dereferenceable >
|
||||
>,
|
||||
Category,
|
||||
detail::eval_if_default_t<
|
||||
Reference,
|
||||
detail::eval_if_default<
|
||||
Value,
|
||||
indirect_reference< dereferenceable >,
|
||||
std::add_lvalue_reference< Value >
|
||||
>
|
||||
>,
|
||||
Difference
|
||||
>;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
template<
|
||||
typename Iterator,
|
||||
typename Value = use_default,
|
||||
typename Category = use_default,
|
||||
typename Reference = use_default,
|
||||
typename Difference = use_default
|
||||
>
|
||||
class indirect_iterator :
|
||||
public detail::indirect_base<
|
||||
Iterator, Value, Category, Reference, Difference
|
||||
>::type
|
||||
{
|
||||
using super_t = typename detail::indirect_base<
|
||||
Iterator, Value, Category, Reference, Difference
|
||||
>::type;
|
||||
|
||||
friend class iterator_core_access;
|
||||
|
||||
public:
|
||||
indirect_iterator() = default;
|
||||
|
||||
indirect_iterator(Iterator iter) :
|
||||
super_t(iter)
|
||||
{}
|
||||
|
||||
template<
|
||||
typename Iterator2,
|
||||
typename Value2,
|
||||
typename Category2,
|
||||
typename Reference2,
|
||||
typename Difference2,
|
||||
typename = enable_if_convertible_t< Iterator2, Iterator >
|
||||
>
|
||||
indirect_iterator(indirect_iterator< Iterator2, Value2, Category2, Reference2, Difference2 > const& y) :
|
||||
super_t(y.base())
|
||||
{}
|
||||
|
||||
private:
|
||||
typename super_t::reference dereference() const
|
||||
{
|
||||
return **this->base();
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Iter >
|
||||
inline indirect_iterator< Iter > make_indirect_iterator(Iter x)
|
||||
{
|
||||
return indirect_iterator< Iter >(x);
|
||||
}
|
||||
|
||||
template< typename Value, typename Iter >
|
||||
inline indirect_iterator< Iter, Value > make_indirect_iterator(Iter x)
|
||||
{
|
||||
return indirect_iterator< Iter, Value >(x);
|
||||
}
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::indirect_iterator;
|
||||
using iterators::make_indirect_iterator;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_INDIRECT_ITERATOR_23022003THW_HPP
|
||||
42
include/boost/iterator/interoperable.hpp
Normal file
42
include/boost/iterator/interoperable.hpp
Normal file
@@ -0,0 +1,42 @@
|
||||
// (C) Copyright David Abrahams 2002.
|
||||
// (C) Copyright Jeremy Siek 2002.
|
||||
// (C) Copyright Thomas Witt 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_INTEROPERABLE_23022003THW_HPP
|
||||
#define BOOST_INTEROPERABLE_23022003THW_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <boost/iterator/detail/type_traits/disjunction.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
//
|
||||
// Meta function that determines whether two
|
||||
// iterator types are considered interoperable.
|
||||
//
|
||||
// Two iterator types A,B are considered interoperable if either
|
||||
// A is convertible to B or vice versa.
|
||||
// This interoperability definition is in sync with the
|
||||
// standards requirements on constant/mutable container
|
||||
// iterators (23.1 [lib.container.requirements]).
|
||||
//
|
||||
// For compilers that don't support is_convertible
|
||||
// is_interoperable gives false positives. See comments
|
||||
// on operator implementation for consequences.
|
||||
//
|
||||
template< typename A, typename B >
|
||||
struct is_interoperable :
|
||||
public detail::disjunction< std::is_convertible< A, B >, std::is_convertible< B, A > >
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::is_interoperable;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_INTEROPERABLE_23022003THW_HPP
|
||||
148
include/boost/iterator/is_iterator.hpp
Normal file
148
include/boost/iterator/is_iterator.hpp
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* https://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* Copyright (c) 2023 Andrey Semashev
|
||||
*/
|
||||
/*!
|
||||
* \file iterator/is_iterator.hpp
|
||||
*
|
||||
* This header contains definition of the \c is_iterator type trait.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ITERATOR_IS_ITERATOR_HPP_INCLUDED_
|
||||
#define BOOST_ITERATOR_IS_ITERATOR_HPP_INCLUDED_
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/type_traits/is_complete.hpp>
|
||||
#include <boost/iterator/detail/type_traits/conjunction.hpp>
|
||||
#include <boost/iterator/detail/type_traits/negation.hpp>
|
||||
#if !defined(BOOST_NO_CXX17_ITERATOR_TRAITS)
|
||||
#include <iterator>
|
||||
#endif
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
namespace detail {
|
||||
|
||||
// The trait attempts to detect if the T type is an iterator class. Class-type iterators are assumed
|
||||
// to have the nested type iterator_category. Strictly speaking, this is not required to be the
|
||||
// case (e.g. a user can specialize iterator_traits for T without defining T::iterator_category).
|
||||
// Still, this is a good heuristic in practice, and we can't do anything better anyway.
|
||||
// Since C++17 we can test for iterator_traits<T>::iterator_category presence instead as it is
|
||||
// required to be only present for iterators.
|
||||
namespace has_iterator_category_detail {
|
||||
|
||||
typedef char yes_type;
|
||||
struct no_type { char padding[2]; };
|
||||
|
||||
template< typename T >
|
||||
yes_type check(
|
||||
#if !defined(BOOST_NO_CXX17_ITERATOR_TRAITS)
|
||||
typename std::iterator_traits< T >::iterator_category*
|
||||
#else
|
||||
typename T::iterator_category*
|
||||
#endif
|
||||
);
|
||||
template< typename >
|
||||
no_type check(...);
|
||||
|
||||
} // namespace has_iterator_category_detail
|
||||
|
||||
template< typename T >
|
||||
struct is_iterator_impl :
|
||||
public std::integral_constant<
|
||||
bool,
|
||||
sizeof(has_iterator_category_detail::check<T>(0)) == sizeof(has_iterator_category_detail::yes_type)
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
struct is_iterator_impl< T* > :
|
||||
public conjunction<
|
||||
boost::is_complete<T>,
|
||||
negation< std::is_function< T > >
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
template< typename T, typename U >
|
||||
struct is_iterator_impl< T U::* > :
|
||||
public std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
struct is_iterator_impl<T&> :
|
||||
public std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template< typename T, std::size_t N >
|
||||
struct is_iterator_impl< T[N] > :
|
||||
public std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
#if !defined(BOOST_TT_HAS_WORKING_IS_COMPLETE)
|
||||
template< typename T >
|
||||
struct is_iterator_impl< T[] > :
|
||||
public std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template< >
|
||||
struct is_iterator_impl< void > :
|
||||
public std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template< >
|
||||
struct is_iterator_impl< void* > :
|
||||
public std::false_type
|
||||
{
|
||||
};
|
||||
#endif // !defined(BOOST_TT_HAS_WORKING_IS_COMPLETE)
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/*!
|
||||
* \brief The type trait detects whether the type \c T is an iterator type.
|
||||
*
|
||||
* The type trait yields \c true if its argument type \c T, after stripping top level
|
||||
* cv qualifiers, is one of the following:
|
||||
*
|
||||
* - A pointer type, other than a pointer to function, a pointer to a class member,
|
||||
* or a pointer to an incomplete type, including `void`.
|
||||
* - A class type for which an iterator category is obtainable. Prior to C++17,
|
||||
* the iterator category must be defined as a public `T::iterator_category` type.
|
||||
* Since C++17, the expression `std::iterator_traits< T >::iterator_category` must
|
||||
* be valid and produce the iterator category type.
|
||||
*
|
||||
* Otherwise, the type trait yields \c false.
|
||||
*/
|
||||
template< typename T >
|
||||
struct is_iterator : public detail::is_iterator_impl< T >::type {};
|
||||
template< typename T >
|
||||
struct is_iterator< const T > : public detail::is_iterator_impl< T >::type {};
|
||||
template< typename T >
|
||||
struct is_iterator< volatile T > : public detail::is_iterator_impl< T >::type {};
|
||||
template< typename T >
|
||||
struct is_iterator< const volatile T > : public detail::is_iterator_impl< T >::type {};
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::is_iterator;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_IS_ITERATOR_HPP_INCLUDED_
|
||||
81
include/boost/iterator/is_lvalue_iterator.hpp
Normal file
81
include/boost/iterator/is_lvalue_iterator.hpp
Normal file
@@ -0,0 +1,81 @@
|
||||
// Copyright David Abrahams 2003. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef IS_LVALUE_ITERATOR_DWA2003112_HPP
|
||||
#define IS_LVALUE_ITERATOR_DWA2003112_HPP
|
||||
|
||||
#include <boost/iterator/detail/type_traits/conjunction.hpp>
|
||||
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
namespace detail {
|
||||
|
||||
// Guts of is_lvalue_iterator. It is the iterator type and
|
||||
// Value is the iterator's value_type.
|
||||
template< typename It, typename Value >
|
||||
struct is_lvalue_iterator_impl :
|
||||
public detail::conjunction<
|
||||
std::is_convertible< decltype(*std::declval< It& >()), typename std::add_lvalue_reference< Value >::type >,
|
||||
std::is_lvalue_reference< decltype(*std::declval< It& >()) >
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
//
|
||||
// void specializations to handle std input and output iterators
|
||||
//
|
||||
template< typename It >
|
||||
struct is_lvalue_iterator_impl< It, void > :
|
||||
public std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template< typename It >
|
||||
struct is_lvalue_iterator_impl< It, const void > :
|
||||
public std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template< typename It >
|
||||
struct is_lvalue_iterator_impl< It, volatile void > :
|
||||
public std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template< typename It >
|
||||
struct is_lvalue_iterator_impl< It, const volatile void > :
|
||||
public std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template< typename T >
|
||||
struct is_lvalue_iterator :
|
||||
public iterators::detail::is_lvalue_iterator_impl<
|
||||
T,
|
||||
typename std::iterator_traits< T >::value_type const
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
struct is_non_const_lvalue_iterator :
|
||||
public iterators::detail::is_lvalue_iterator_impl<
|
||||
T,
|
||||
typename std::iterator_traits< T >::value_type
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::is_lvalue_iterator;
|
||||
using iterators::is_non_const_lvalue_iterator;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // IS_LVALUE_ITERATOR_DWA2003112_HPP
|
||||
69
include/boost/iterator/is_readable_iterator.hpp
Normal file
69
include/boost/iterator/is_readable_iterator.hpp
Normal file
@@ -0,0 +1,69 @@
|
||||
// Copyright David Abrahams 2003. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef IS_READABLE_ITERATOR_DWA2003112_HPP
|
||||
#define IS_READABLE_ITERATOR_DWA2003112_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
namespace detail {
|
||||
|
||||
// Guts of is_readable_iterator. It is the iterator type and
|
||||
// Value is the iterator's value_type.
|
||||
template< typename It, typename Value >
|
||||
struct is_readable_iterator_impl :
|
||||
public std::is_convertible<
|
||||
decltype(*std::declval< It& >()),
|
||||
typename std::add_lvalue_reference< Value >::type
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
//
|
||||
// void specializations to handle std input and output iterators
|
||||
//
|
||||
template< typename It >
|
||||
struct is_readable_iterator_impl< It, void > :
|
||||
public std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template< typename It >
|
||||
struct is_readable_iterator_impl< It, const void > :
|
||||
public std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template< typename It >
|
||||
struct is_readable_iterator_impl< It, volatile void > :
|
||||
public std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template< typename It >
|
||||
struct is_readable_iterator_impl< It, const volatile void > :
|
||||
public std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template< typename T >
|
||||
struct is_readable_iterator :
|
||||
public iterators::detail::is_readable_iterator_impl<
|
||||
T,
|
||||
typename std::iterator_traits< T >::value_type const
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::is_readable_iterator;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // IS_READABLE_ITERATOR_DWA2003112_HPP
|
||||
211
include/boost/iterator/iterator_adaptor.hpp
Normal file
211
include/boost/iterator/iterator_adaptor.hpp
Normal file
@@ -0,0 +1,211 @@
|
||||
// (C) Copyright David Abrahams 2002.
|
||||
// (C) Copyright Jeremy Siek 2002.
|
||||
// (C) Copyright Thomas Witt 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
|
||||
#define BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/core/use_default.hpp>
|
||||
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
#include <boost/iterator/enable_if_convertible.hpp> // for backward compatibility; remove once downstream users are updated
|
||||
#include <boost/iterator/detail/eval_if_default.hpp>
|
||||
|
||||
#include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
// Used as a default template argument internally, merely to
|
||||
// indicate "use the default", this can also be passed by users
|
||||
// explicitly in order to specify that the default should be used.
|
||||
using boost::use_default;
|
||||
|
||||
namespace detail {
|
||||
|
||||
// A metafunction which computes an iterator_adaptor's base class,
|
||||
// a specialization of iterator_facade.
|
||||
template<
|
||||
typename Derived,
|
||||
typename Base,
|
||||
typename Value,
|
||||
typename Traversal,
|
||||
typename Reference,
|
||||
typename Difference
|
||||
>
|
||||
using iterator_adaptor_base_t = iterator_facade<
|
||||
Derived,
|
||||
|
||||
#ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
||||
detail::eval_if_default_t<
|
||||
Value,
|
||||
detail::eval_if_default<
|
||||
Reference,
|
||||
iterator_value< Base >,
|
||||
std::remove_reference< Reference >
|
||||
>
|
||||
>,
|
||||
#else
|
||||
detail::eval_if_default_t<
|
||||
Value,
|
||||
iterator_value< Base >
|
||||
>,
|
||||
#endif
|
||||
|
||||
detail::eval_if_default_t<
|
||||
Traversal,
|
||||
iterator_traversal< Base >
|
||||
>,
|
||||
|
||||
detail::eval_if_default_t<
|
||||
Reference,
|
||||
detail::eval_if_default<
|
||||
Value,
|
||||
iterator_reference< Base >,
|
||||
std::add_lvalue_reference< Value >
|
||||
>
|
||||
>,
|
||||
|
||||
detail::eval_if_default_t<
|
||||
Difference,
|
||||
iterator_difference< Base >
|
||||
>
|
||||
>;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
//
|
||||
// Iterator Adaptor
|
||||
//
|
||||
// The parameter ordering changed slightly with respect to former
|
||||
// versions of iterator_adaptor The idea is that when the user needs
|
||||
// to fiddle with the reference type it is highly likely that the
|
||||
// iterator category has to be adjusted as well. Any of the
|
||||
// following four template arguments may be omitted or explicitly
|
||||
// replaced by use_default.
|
||||
//
|
||||
// Value - if supplied, the value_type of the resulting iterator, unless
|
||||
// const. If const, a conforming compiler strips constness for the
|
||||
// value_type. If not supplied, iterator_traits<Base>::value_type is used
|
||||
//
|
||||
// Category - the traversal category of the resulting iterator. If not
|
||||
// supplied, iterator_traversal<Base>::type is used.
|
||||
//
|
||||
// Reference - the reference type of the resulting iterator, and in
|
||||
// particular, the result type of operator*(). If not supplied but
|
||||
// Value is supplied, Value& is used. Otherwise
|
||||
// iterator_traits<Base>::reference is used.
|
||||
//
|
||||
// Difference - the difference_type of the resulting iterator. If not
|
||||
// supplied, iterator_traits<Base>::difference_type is used.
|
||||
//
|
||||
template<
|
||||
typename Derived,
|
||||
typename Base,
|
||||
typename Value = use_default,
|
||||
typename Traversal = use_default,
|
||||
typename Reference = use_default,
|
||||
typename Difference = use_default
|
||||
>
|
||||
class iterator_adaptor :
|
||||
public detail::iterator_adaptor_base_t<
|
||||
Derived, Base, Value, Traversal, Reference, Difference
|
||||
>
|
||||
{
|
||||
friend class iterator_core_access;
|
||||
|
||||
protected:
|
||||
using super_t = detail::iterator_adaptor_base_t<
|
||||
Derived, Base, Value, Traversal, Reference, Difference
|
||||
>;
|
||||
|
||||
public:
|
||||
using base_type = Base;
|
||||
|
||||
iterator_adaptor() = default;
|
||||
|
||||
explicit iterator_adaptor(Base const& iter) :
|
||||
m_iterator(iter)
|
||||
{
|
||||
}
|
||||
|
||||
base_type const& base() const { return m_iterator; }
|
||||
|
||||
protected:
|
||||
// for convenience in derived classes
|
||||
using iterator_adaptor_ = iterator_adaptor< Derived, Base, Value, Traversal, Reference, Difference >;
|
||||
|
||||
//
|
||||
// lvalue access to the Base object for Derived
|
||||
//
|
||||
Base& base_reference() { return m_iterator; }
|
||||
Base const& base_reference() const { return m_iterator; }
|
||||
|
||||
private:
|
||||
//
|
||||
// Core iterator interface for iterator_facade. This is private
|
||||
// to prevent temptation for Derived classes to use it, which
|
||||
// will often result in an error. Derived classes should use
|
||||
// base_reference(), above, to get direct access to m_iterator.
|
||||
//
|
||||
typename super_t::reference dereference() const { return *m_iterator; }
|
||||
|
||||
template< typename OtherDerived, typename OtherIterator, typename V, typename C, typename R, typename D >
|
||||
bool equal(iterator_adaptor< OtherDerived, OtherIterator, V, C, R, D > const& x) const
|
||||
{
|
||||
// Maybe readd with same_distance
|
||||
// BOOST_STATIC_ASSERT(
|
||||
// (detail::same_category_and_difference<Derived,OtherDerived>::value)
|
||||
// );
|
||||
return m_iterator == x.base();
|
||||
}
|
||||
|
||||
using my_traversal = typename iterator_category_to_traversal< typename super_t::iterator_category >::type;
|
||||
|
||||
void advance(typename super_t::difference_type n)
|
||||
{
|
||||
static_assert(detail::is_traversal_at_least< my_traversal, random_access_traversal_tag >::value,
|
||||
"Iterator must support random access traversal.");
|
||||
m_iterator += n;
|
||||
}
|
||||
|
||||
void increment() { ++m_iterator; }
|
||||
|
||||
void decrement()
|
||||
{
|
||||
static_assert(detail::is_traversal_at_least< my_traversal, bidirectional_traversal_tag >::value,
|
||||
"Iterator must support bidirectional traversal.");
|
||||
--m_iterator;
|
||||
}
|
||||
|
||||
template< typename OtherDerived, typename OtherIterator, typename V, typename C, typename R, typename D >
|
||||
typename super_t::difference_type distance_to(iterator_adaptor< OtherDerived, OtherIterator, V, C, R, D > const& y) const
|
||||
{
|
||||
static_assert(detail::is_traversal_at_least< my_traversal, random_access_traversal_tag >::value,
|
||||
"Super iterator must support random access traversal.");
|
||||
// Maybe readd with same_distance
|
||||
// BOOST_STATIC_ASSERT(
|
||||
// (detail::same_category_and_difference<Derived,OtherDerived>::value)
|
||||
// );
|
||||
return y.base() - m_iterator;
|
||||
}
|
||||
|
||||
private: // data members
|
||||
Base m_iterator;
|
||||
};
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::iterator_adaptor;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/iterator/detail/config_undef.hpp>
|
||||
|
||||
#endif // BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
|
||||
479
include/boost/iterator/iterator_archetypes.hpp
Normal file
479
include/boost/iterator/iterator_archetypes.hpp
Normal file
@@ -0,0 +1,479 @@
|
||||
// (C) Copyright Jeremy Siek 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_ITERATOR_ARCHETYPES_HPP
|
||||
#define BOOST_ITERATOR_ARCHETYPES_HPP
|
||||
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/iterator/detail/facade_iterator_category.hpp>
|
||||
|
||||
#include <boost/operators.hpp>
|
||||
#include <boost/concept_archetype.hpp>
|
||||
#include <boost/mp11/utility.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
template <class Value, class AccessCategory>
|
||||
struct access_archetype;
|
||||
|
||||
template <class Derived, class Value, class AccessCategory, class TraversalCategory>
|
||||
struct traversal_archetype;
|
||||
|
||||
namespace archetypes {
|
||||
|
||||
enum
|
||||
{
|
||||
readable_iterator_bit = 1,
|
||||
writable_iterator_bit = 2,
|
||||
swappable_iterator_bit = 4,
|
||||
lvalue_iterator_bit = 8
|
||||
};
|
||||
|
||||
// Not quite tags, since dispatching wouldn't work.
|
||||
using readable_iterator_t = std::integral_constant<unsigned int, readable_iterator_bit>;
|
||||
using writable_iterator_t = std::integral_constant<unsigned int, writable_iterator_bit>;
|
||||
|
||||
using readable_writable_iterator_t = std::integral_constant<
|
||||
unsigned int,
|
||||
(readable_iterator_bit | writable_iterator_bit)
|
||||
>;
|
||||
|
||||
using readable_lvalue_iterator_t = std::integral_constant<
|
||||
unsigned int,
|
||||
(readable_iterator_bit | lvalue_iterator_bit)
|
||||
>;
|
||||
|
||||
using writable_lvalue_iterator_t = std::integral_constant<
|
||||
unsigned int,
|
||||
(lvalue_iterator_bit | writable_iterator_bit)
|
||||
>;
|
||||
|
||||
using swappable_iterator_t = std::integral_constant<unsigned int, swappable_iterator_bit>;
|
||||
using lvalue_iterator_t = std::integral_constant<unsigned int, lvalue_iterator_bit>;
|
||||
|
||||
template <class Derived, class Base>
|
||||
struct has_access :
|
||||
public std::integral_constant<bool, (Derived::value & Base::value) == Base::value>
|
||||
{};
|
||||
|
||||
} // namespace archetypes
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class T>
|
||||
struct assign_proxy
|
||||
{
|
||||
assign_proxy& operator=(T) { return *this; }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct read_proxy
|
||||
{
|
||||
operator T() { return static_object<T>::get(); }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct read_write_proxy :
|
||||
public read_proxy<T> // Used to inherit from assign_proxy, but that doesn't work. -JGS
|
||||
{
|
||||
read_write_proxy& operator=(T) { return *this; }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct arrow_proxy
|
||||
{
|
||||
T const* operator->() const { return 0; }
|
||||
};
|
||||
|
||||
struct no_operator_brackets {};
|
||||
|
||||
template <class ValueType>
|
||||
struct readable_operator_brackets
|
||||
{
|
||||
read_proxy<ValueType> operator[](std::ptrdiff_t n) const { return read_proxy<ValueType>(); }
|
||||
};
|
||||
|
||||
template <class ValueType>
|
||||
struct writable_operator_brackets
|
||||
{
|
||||
read_write_proxy<ValueType> operator[](std::ptrdiff_t n) const { return read_write_proxy<ValueType>(); }
|
||||
};
|
||||
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct operator_brackets :
|
||||
public mp11::mp_eval_if_c<
|
||||
!std::is_convertible<TraversalCategory, random_access_traversal_tag>::value,
|
||||
no_operator_brackets,
|
||||
mp11::mp_cond,
|
||||
archetypes::has_access<AccessCategory, archetypes::writable_iterator_t>, writable_operator_brackets<Value>,
|
||||
archetypes::has_access<AccessCategory, archetypes::readable_iterator_t>, readable_operator_brackets<Value>,
|
||||
std::true_type, no_operator_brackets
|
||||
>
|
||||
{};
|
||||
|
||||
template <class TraversalCategory>
|
||||
struct traversal_archetype_impl
|
||||
{
|
||||
template <class Derived,class Value> struct archetype;
|
||||
};
|
||||
|
||||
// Constructor argument for those iterators that
|
||||
// are not default constructible
|
||||
struct ctor_arg {};
|
||||
|
||||
template <class Derived, class Value, class TraversalCategory>
|
||||
struct traversal_archetype_ :
|
||||
public traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
|
||||
{
|
||||
using base = typename traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>;
|
||||
|
||||
traversal_archetype_() {}
|
||||
|
||||
traversal_archetype_(ctor_arg arg) : base(arg)
|
||||
{}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct traversal_archetype_impl<incrementable_traversal_tag>
|
||||
{
|
||||
template<class Derived, class Value>
|
||||
struct archetype
|
||||
{
|
||||
explicit archetype(ctor_arg) {}
|
||||
|
||||
struct bogus { }; // This used to be void, but that causes trouble for iterator_facade. Need more research. -JGS
|
||||
using difference_type = bogus;
|
||||
|
||||
Derived& operator++() { return (Derived&)static_object<Derived>::get(); }
|
||||
Derived operator++(int) const { return (Derived&)static_object<Derived>::get(); }
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct traversal_archetype_impl<single_pass_traversal_tag>
|
||||
{
|
||||
template<class Derived, class Value>
|
||||
struct archetype :
|
||||
public equality_comparable< traversal_archetype_<Derived, Value, single_pass_traversal_tag> >,
|
||||
public traversal_archetype_<Derived, Value, incrementable_traversal_tag>
|
||||
{
|
||||
explicit archetype(ctor_arg arg) :
|
||||
traversal_archetype_<Derived, Value, incrementable_traversal_tag>(arg)
|
||||
{}
|
||||
|
||||
using difference_type = std::ptrdiff_t;
|
||||
};
|
||||
};
|
||||
|
||||
template <class Derived, class Value>
|
||||
bool operator==(
|
||||
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
|
||||
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&) { return true; }
|
||||
|
||||
template <>
|
||||
struct traversal_archetype_impl<forward_traversal_tag>
|
||||
{
|
||||
template<class Derived, class Value>
|
||||
struct archetype :
|
||||
public traversal_archetype_<Derived, Value, single_pass_traversal_tag>
|
||||
{
|
||||
archetype() :
|
||||
traversal_archetype_<Derived, Value, single_pass_traversal_tag>(ctor_arg())
|
||||
{}
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct traversal_archetype_impl<bidirectional_traversal_tag>
|
||||
{
|
||||
template<class Derived, class Value>
|
||||
struct archetype :
|
||||
public traversal_archetype_<Derived, Value, forward_traversal_tag>
|
||||
{
|
||||
Derived& operator--() { return static_object<Derived>::get(); }
|
||||
Derived operator--(int) const { return static_object<Derived>::get(); }
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct traversal_archetype_impl<random_access_traversal_tag>
|
||||
{
|
||||
template<class Derived, class Value>
|
||||
struct archetype :
|
||||
public traversal_archetype_<Derived, Value, bidirectional_traversal_tag>
|
||||
{
|
||||
Derived& operator+=(std::ptrdiff_t) { return static_object<Derived>::get(); }
|
||||
Derived& operator-=(std::ptrdiff_t) { return static_object<Derived>::get(); }
|
||||
};
|
||||
};
|
||||
|
||||
template <class Derived, class Value>
|
||||
Derived& operator+(
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||
std::ptrdiff_t) { return static_object<Derived>::get(); }
|
||||
|
||||
template <class Derived, class Value>
|
||||
Derived& operator+(
|
||||
std::ptrdiff_t,
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
|
||||
{ return static_object<Derived>::get(); }
|
||||
|
||||
template <class Derived, class Value>
|
||||
Derived& operator-(
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||
std::ptrdiff_t) { return static_object<Derived>::get(); }
|
||||
|
||||
template <class Derived, class Value>
|
||||
std::ptrdiff_t operator-(
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
|
||||
{ return 0; }
|
||||
|
||||
template <class Derived, class Value>
|
||||
bool operator<(
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
|
||||
{ return true; }
|
||||
|
||||
template <class Derived, class Value>
|
||||
bool operator>(
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
|
||||
{ return true; }
|
||||
|
||||
template <class Derived, class Value>
|
||||
bool operator<=(
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
|
||||
{ return true; }
|
||||
|
||||
template <class Derived, class Value>
|
||||
bool operator>=(
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
|
||||
{ return true; }
|
||||
|
||||
struct bogus_type;
|
||||
|
||||
template <class Value>
|
||||
struct convertible_type
|
||||
{
|
||||
using type = bogus_type;
|
||||
};
|
||||
|
||||
template <class Value>
|
||||
struct convertible_type<const Value>
|
||||
{
|
||||
using type = Value;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
template <class> struct undefined;
|
||||
|
||||
template <class AccessCategory>
|
||||
struct iterator_access_archetype_impl
|
||||
{
|
||||
template <class Value> struct archetype;
|
||||
};
|
||||
|
||||
template <class Value, class AccessCategory>
|
||||
struct iterator_access_archetype :
|
||||
public iterator_access_archetype_impl<AccessCategory>::template archetype<Value>
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterator_access_archetype_impl<archetypes::readable_iterator_t>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype
|
||||
{
|
||||
using value_type = typename std::remove_cv<Value>::type;
|
||||
using reference = Value;
|
||||
using pointer = Value*;
|
||||
|
||||
value_type operator*() const { return static_object<value_type>::get(); }
|
||||
|
||||
detail::arrow_proxy<Value> operator->() const { return detail::arrow_proxy<Value>(); }
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterator_access_archetype_impl<archetypes::writable_iterator_t>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype
|
||||
{
|
||||
static_assert(!std::is_const<Value>::value, "Value type must not be const.");
|
||||
using value_type = void;
|
||||
using reference = void;
|
||||
using pointer = void;
|
||||
|
||||
detail::assign_proxy<Value> operator*() const { return detail::assign_proxy<Value>(); }
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterator_access_archetype_impl<archetypes::readable_writable_iterator_t>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype :
|
||||
public virtual iterator_access_archetype<Value, archetypes::readable_iterator_t>
|
||||
{
|
||||
using reference = detail::read_write_proxy<Value>;
|
||||
|
||||
detail::read_write_proxy<Value> operator*() const { return detail::read_write_proxy<Value>(); }
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterator_access_archetype_impl<archetypes::readable_lvalue_iterator_t>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype :
|
||||
public virtual iterator_access_archetype<Value, archetypes::readable_iterator_t>
|
||||
{
|
||||
using reference = Value&;
|
||||
|
||||
Value& operator*() const { return static_object<Value>::get(); }
|
||||
Value* operator->() const { return 0; }
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterator_access_archetype_impl<archetypes::writable_lvalue_iterator_t>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype :
|
||||
public virtual iterator_access_archetype<Value, archetypes::readable_lvalue_iterator_t>
|
||||
{
|
||||
static_assert(!std::is_const<Value>::value, "Value type must not be const.");
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct iterator_archetype;
|
||||
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct traversal_archetype_base :
|
||||
public detail::operator_brackets<
|
||||
typename std::remove_cv<Value>::type,
|
||||
AccessCategory,
|
||||
TraversalCategory
|
||||
>,
|
||||
public detail::traversal_archetype_<
|
||||
iterator_archetype<Value, AccessCategory, TraversalCategory>,
|
||||
Value,
|
||||
TraversalCategory
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct iterator_archetype_base :
|
||||
public iterator_access_archetype<Value, AccessCategory>,
|
||||
public traversal_archetype_base<Value, AccessCategory, TraversalCategory>
|
||||
{
|
||||
using access = iterator_access_archetype<Value, AccessCategory>;
|
||||
|
||||
using iterator_category = typename detail::facade_iterator_category<
|
||||
TraversalCategory,
|
||||
typename std::conditional<
|
||||
archetypes::has_access<
|
||||
AccessCategory, archetypes::writable_iterator_t
|
||||
>::value,
|
||||
std::remove_const<Value>,
|
||||
std::add_const<Value>
|
||||
>::type::type,
|
||||
typename access::reference
|
||||
>::type;
|
||||
|
||||
// Needed for some broken libraries (see below)
|
||||
struct workaround_iterator_base
|
||||
{
|
||||
using iterator_category = typename iterator_archetype_base::iterator_category;
|
||||
using value_type = Value;
|
||||
using difference_type = typename traversal_archetype_base<
|
||||
Value, AccessCategory, TraversalCategory
|
||||
>::difference_type;
|
||||
using pointer = typename access::pointer;
|
||||
using reference = typename access::reference;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct iterator_archetype :
|
||||
public detail::iterator_archetype_base<Value, AccessCategory, TraversalCategory>
|
||||
|
||||
// These broken libraries require derivation from std::iterator
|
||||
// (or related magic) in order to handle iter_swap and other
|
||||
// iterator operations
|
||||
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
|
||||
|| BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
|
||||
, public detail::iterator_archetype_base<
|
||||
Value, AccessCategory, TraversalCategory
|
||||
>::workaround_iterator_base
|
||||
# endif
|
||||
{
|
||||
// Derivation from std::iterator above caused references to nested
|
||||
// types to be ambiguous, so now we have to redeclare them all
|
||||
// here.
|
||||
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
|
||||
|| BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
|
||||
|
||||
using base = detail::iterator_archetype_base<
|
||||
Value, AccessCategory, TraversalCategory
|
||||
>;
|
||||
|
||||
using value_type = typename base::value_type;
|
||||
using reference = typename base::reference;
|
||||
using pointer = typename base::pointer;
|
||||
using difference_type = typename base::difference_type;
|
||||
using iterator_category = typename base::iterator_category;
|
||||
# endif
|
||||
|
||||
iterator_archetype() { }
|
||||
iterator_archetype(iterator_archetype const& x) :
|
||||
detail::iterator_archetype_base<Value, AccessCategory, TraversalCategory>(x)
|
||||
{}
|
||||
|
||||
iterator_archetype& operator=(iterator_archetype const&) { return *this; }
|
||||
|
||||
# if 0
|
||||
// Optional conversion from mutable
|
||||
iterator_archetype(
|
||||
iterator_archetype<
|
||||
typename detail::convertible_type<Value>::type
|
||||
, AccessCategory
|
||||
, TraversalCategory> const&
|
||||
);
|
||||
# endif
|
||||
};
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
// Backward compatibility names
|
||||
namespace iterator_archetypes = iterators::archetypes;
|
||||
using iterators::access_archetype;
|
||||
using iterators::traversal_archetype;
|
||||
using iterators::iterator_archetype;
|
||||
using iterators::undefined;
|
||||
using iterators::iterator_access_archetype_impl;
|
||||
using iterators::traversal_archetype_base;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_ARCHETYPES_HPP
|
||||
107
include/boost/iterator/iterator_categories.hpp
Normal file
107
include/boost/iterator/iterator_categories.hpp
Normal file
@@ -0,0 +1,107 @@
|
||||
// (C) Copyright Jeremy Siek 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_ITERATOR_CATEGORIES_HPP
|
||||
#define BOOST_ITERATOR_CATEGORIES_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/mpl/arg_fwd.hpp>
|
||||
#include <boost/mp11/utility.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
//
|
||||
// Traversal Categories
|
||||
//
|
||||
struct no_traversal_tag {};
|
||||
struct incrementable_traversal_tag : public no_traversal_tag {};
|
||||
struct single_pass_traversal_tag : public incrementable_traversal_tag {};
|
||||
struct forward_traversal_tag : public single_pass_traversal_tag {};
|
||||
struct bidirectional_traversal_tag : public forward_traversal_tag {};
|
||||
struct random_access_traversal_tag : public bidirectional_traversal_tag {};
|
||||
|
||||
//
|
||||
// Convert an iterator category into a traversal tag
|
||||
//
|
||||
template< typename Cat >
|
||||
using iterator_category_to_traversal_t = mp11::mp_cond<
|
||||
// if already convertible to a traversal tag, we're done.
|
||||
std::is_convertible< Cat, incrementable_traversal_tag >, Cat,
|
||||
std::is_convertible< Cat, std::random_access_iterator_tag >, random_access_traversal_tag,
|
||||
std::is_convertible< Cat, std::bidirectional_iterator_tag >, bidirectional_traversal_tag,
|
||||
std::is_convertible< Cat, std::forward_iterator_tag >, forward_traversal_tag,
|
||||
std::is_convertible< Cat, std::input_iterator_tag >, single_pass_traversal_tag,
|
||||
std::is_convertible< Cat, std::output_iterator_tag >, incrementable_traversal_tag,
|
||||
std::true_type, void
|
||||
>;
|
||||
|
||||
template< typename Cat >
|
||||
struct iterator_category_to_traversal
|
||||
{
|
||||
using type = iterator_category_to_traversal_t< Cat >;
|
||||
};
|
||||
|
||||
// Trait to get an iterator's traversal category
|
||||
template< typename Iterator >
|
||||
using iterator_traversal_t = iterator_category_to_traversal_t<
|
||||
typename std::iterator_traits< Iterator >::iterator_category
|
||||
>;
|
||||
|
||||
template< typename Iterator = mpl::arg< 1 > >
|
||||
struct iterator_traversal
|
||||
{
|
||||
using type = iterator_traversal_t< Iterator >;
|
||||
};
|
||||
|
||||
//
|
||||
// Convert an iterator traversal to one of the traversal tags.
|
||||
//
|
||||
template< typename Traversal >
|
||||
using pure_traversal_tag_t = mp11::mp_cond<
|
||||
std::is_convertible< Traversal, random_access_traversal_tag >, random_access_traversal_tag,
|
||||
std::is_convertible< Traversal, bidirectional_traversal_tag >, bidirectional_traversal_tag,
|
||||
std::is_convertible< Traversal, forward_traversal_tag >, forward_traversal_tag,
|
||||
std::is_convertible< Traversal, single_pass_traversal_tag >, single_pass_traversal_tag,
|
||||
std::is_convertible< Traversal, incrementable_traversal_tag >, incrementable_traversal_tag,
|
||||
std::true_type, void
|
||||
>;
|
||||
|
||||
template< typename Traversal >
|
||||
struct pure_traversal_tag
|
||||
{
|
||||
using type = pure_traversal_tag_t< Traversal >;
|
||||
};
|
||||
|
||||
//
|
||||
// Trait to retrieve one of the iterator traversal tags from the iterator category or traversal.
|
||||
//
|
||||
template< typename Iterator >
|
||||
using pure_iterator_traversal_t = pure_traversal_tag_t<
|
||||
iterator_traversal_t< Iterator >
|
||||
>;
|
||||
|
||||
template< typename Iterator = mpl::arg< 1 > >
|
||||
struct pure_iterator_traversal
|
||||
{
|
||||
using type = pure_iterator_traversal_t< Iterator >;
|
||||
};
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::no_traversal_tag;
|
||||
using iterators::incrementable_traversal_tag;
|
||||
using iterators::single_pass_traversal_tag;
|
||||
using iterators::forward_traversal_tag;
|
||||
using iterators::bidirectional_traversal_tag;
|
||||
using iterators::random_access_traversal_tag;
|
||||
using iterators::iterator_category_to_traversal;
|
||||
using iterators::iterator_traversal;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_CATEGORIES_HPP
|
||||
265
include/boost/iterator/iterator_concepts.hpp
Normal file
265
include/boost/iterator/iterator_concepts.hpp
Normal file
@@ -0,0 +1,265 @@
|
||||
// (C) Copyright Jeremy Siek 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_ITERATOR_CONCEPTS_HPP
|
||||
#define BOOST_ITERATOR_CONCEPTS_HPP
|
||||
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
// Use boost/limits to work around missing limits headers on some compilers
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#include <boost/concept/detail/concept_def.hpp>
|
||||
|
||||
namespace boost_concepts
|
||||
{
|
||||
// Used a different namespace here (instead of "boost") so that the
|
||||
// concept descriptions do not take for granted the names in
|
||||
// namespace boost.
|
||||
|
||||
//===========================================================================
|
||||
// Iterator Access Concepts
|
||||
|
||||
BOOST_concept(ReadableIterator,(Iterator))
|
||||
: boost::Assignable<Iterator>
|
||||
, boost::CopyConstructible<Iterator>
|
||||
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::value_type value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::reference reference;
|
||||
|
||||
BOOST_CONCEPT_USAGE(ReadableIterator)
|
||||
{
|
||||
|
||||
value_type v = *i;
|
||||
boost::ignore_unused_variable_warning(v);
|
||||
}
|
||||
private:
|
||||
Iterator i;
|
||||
};
|
||||
|
||||
template <
|
||||
typename Iterator
|
||||
, typename ValueType = BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::value_type
|
||||
>
|
||||
struct WritableIterator
|
||||
: boost::CopyConstructible<Iterator>
|
||||
{
|
||||
BOOST_CONCEPT_USAGE(WritableIterator)
|
||||
{
|
||||
*i = v;
|
||||
}
|
||||
private:
|
||||
ValueType v;
|
||||
Iterator i;
|
||||
};
|
||||
|
||||
template <
|
||||
typename Iterator
|
||||
, typename ValueType = BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::value_type
|
||||
>
|
||||
struct WritableIteratorConcept : WritableIterator<Iterator,ValueType> {};
|
||||
|
||||
BOOST_concept(SwappableIterator,(Iterator))
|
||||
{
|
||||
BOOST_CONCEPT_USAGE(SwappableIterator)
|
||||
{
|
||||
std::iter_swap(i1, i2);
|
||||
}
|
||||
private:
|
||||
Iterator i1;
|
||||
Iterator i2;
|
||||
};
|
||||
|
||||
BOOST_concept(LvalueIterator,(Iterator))
|
||||
{
|
||||
typedef typename std::iterator_traits<Iterator>::value_type value_type;
|
||||
|
||||
BOOST_CONCEPT_USAGE(LvalueIterator)
|
||||
{
|
||||
value_type& r = const_cast<value_type&>(*i);
|
||||
boost::ignore_unused_variable_warning(r);
|
||||
}
|
||||
private:
|
||||
Iterator i;
|
||||
};
|
||||
|
||||
|
||||
//===========================================================================
|
||||
// Iterator Traversal Concepts
|
||||
|
||||
BOOST_concept(IncrementableIterator,(Iterator))
|
||||
: boost::Assignable<Iterator>
|
||||
, boost::CopyConstructible<Iterator>
|
||||
{
|
||||
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
|
||||
|
||||
BOOST_CONCEPT_ASSERT((
|
||||
boost::Convertible<
|
||||
traversal_category
|
||||
, boost::incrementable_traversal_tag
|
||||
>));
|
||||
|
||||
BOOST_CONCEPT_USAGE(IncrementableIterator)
|
||||
{
|
||||
++i;
|
||||
(void)i++;
|
||||
}
|
||||
private:
|
||||
Iterator i;
|
||||
};
|
||||
|
||||
BOOST_concept(SinglePassIterator,(Iterator))
|
||||
: IncrementableIterator<Iterator>
|
||||
, boost::EqualityComparable<Iterator>
|
||||
|
||||
{
|
||||
BOOST_CONCEPT_ASSERT((
|
||||
boost::Convertible<
|
||||
BOOST_DEDUCED_TYPENAME SinglePassIterator::traversal_category
|
||||
, boost::single_pass_traversal_tag
|
||||
> ));
|
||||
};
|
||||
|
||||
BOOST_concept(ForwardTraversal,(Iterator))
|
||||
: SinglePassIterator<Iterator>
|
||||
, boost::DefaultConstructible<Iterator>
|
||||
{
|
||||
typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
|
||||
|
||||
static_assert(std::is_integral<difference_type>::value, "difference_type must be integral.");
|
||||
static_assert(std::numeric_limits<difference_type>::is_signed, "difference_type must be signed.");
|
||||
|
||||
BOOST_CONCEPT_ASSERT((
|
||||
boost::Convertible<
|
||||
BOOST_DEDUCED_TYPENAME ForwardTraversal::traversal_category
|
||||
, boost::forward_traversal_tag
|
||||
> ));
|
||||
};
|
||||
|
||||
BOOST_concept(BidirectionalTraversal,(Iterator))
|
||||
: ForwardTraversal<Iterator>
|
||||
{
|
||||
BOOST_CONCEPT_ASSERT((
|
||||
boost::Convertible<
|
||||
BOOST_DEDUCED_TYPENAME BidirectionalTraversal::traversal_category
|
||||
, boost::bidirectional_traversal_tag
|
||||
> ));
|
||||
|
||||
BOOST_CONCEPT_USAGE(BidirectionalTraversal)
|
||||
{
|
||||
--i;
|
||||
(void)i--;
|
||||
}
|
||||
private:
|
||||
Iterator i;
|
||||
};
|
||||
|
||||
BOOST_concept(RandomAccessTraversal,(Iterator))
|
||||
: BidirectionalTraversal<Iterator>
|
||||
{
|
||||
BOOST_CONCEPT_ASSERT((
|
||||
boost::Convertible<
|
||||
BOOST_DEDUCED_TYPENAME RandomAccessTraversal::traversal_category
|
||||
, boost::random_access_traversal_tag
|
||||
> ));
|
||||
|
||||
BOOST_CONCEPT_USAGE(RandomAccessTraversal)
|
||||
{
|
||||
i += n;
|
||||
i = i + n;
|
||||
i = n + i;
|
||||
i -= n;
|
||||
i = i - n;
|
||||
n = i - j;
|
||||
}
|
||||
|
||||
private:
|
||||
typename BidirectionalTraversal<Iterator>::difference_type n;
|
||||
Iterator i, j;
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
// Iterator Interoperability
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename Iterator1, typename Iterator2>
|
||||
void interop_single_pass_constraints(Iterator1 const& i1, Iterator2 const& i2)
|
||||
{
|
||||
bool b;
|
||||
b = i1 == i2;
|
||||
b = i1 != i2;
|
||||
|
||||
b = i2 == i1;
|
||||
b = i2 != i1;
|
||||
boost::ignore_unused_variable_warning(b);
|
||||
}
|
||||
|
||||
template <typename Iterator1, typename Iterator2>
|
||||
void interop_rand_access_constraints(
|
||||
Iterator1 const& i1, Iterator2 const& i2,
|
||||
boost::random_access_traversal_tag, boost::random_access_traversal_tag)
|
||||
{
|
||||
bool b;
|
||||
typename std::iterator_traits<Iterator2>::difference_type n;
|
||||
b = i1 < i2;
|
||||
b = i1 <= i2;
|
||||
b = i1 > i2;
|
||||
b = i1 >= i2;
|
||||
n = i1 - i2;
|
||||
|
||||
b = i2 < i1;
|
||||
b = i2 <= i1;
|
||||
b = i2 > i1;
|
||||
b = i2 >= i1;
|
||||
n = i2 - i1;
|
||||
boost::ignore_unused_variable_warning(b);
|
||||
boost::ignore_unused_variable_warning(n);
|
||||
}
|
||||
|
||||
template <typename Iterator1, typename Iterator2>
|
||||
void interop_rand_access_constraints(
|
||||
Iterator1 const&, Iterator2 const&,
|
||||
boost::single_pass_traversal_tag, boost::single_pass_traversal_tag)
|
||||
{ }
|
||||
|
||||
} // namespace detail
|
||||
|
||||
BOOST_concept(InteroperableIterator,(Iterator)(ConstIterator))
|
||||
{
|
||||
private:
|
||||
typedef typename boost::iterators::pure_iterator_traversal<Iterator>::type traversal_category;
|
||||
typedef typename boost::iterators::pure_iterator_traversal<ConstIterator>::type const_traversal_category;
|
||||
|
||||
public:
|
||||
BOOST_CONCEPT_ASSERT((SinglePassIterator<Iterator>));
|
||||
BOOST_CONCEPT_ASSERT((SinglePassIterator<ConstIterator>));
|
||||
|
||||
BOOST_CONCEPT_USAGE(InteroperableIterator)
|
||||
{
|
||||
detail::interop_single_pass_constraints(i, ci);
|
||||
detail::interop_rand_access_constraints(i, ci, traversal_category(), const_traversal_category());
|
||||
|
||||
ci = i;
|
||||
}
|
||||
|
||||
private:
|
||||
Iterator i;
|
||||
ConstIterator ci;
|
||||
};
|
||||
|
||||
} // namespace boost_concepts
|
||||
|
||||
#include <boost/concept/detail/concept_undef.hpp>
|
||||
|
||||
#endif // BOOST_ITERATOR_CONCEPTS_HPP
|
||||
889
include/boost/iterator/iterator_facade.hpp
Normal file
889
include/boost/iterator/iterator_facade.hpp
Normal file
@@ -0,0 +1,889 @@
|
||||
// (C) Copyright David Abrahams 2002.
|
||||
// (C) Copyright Jeremy Siek 2002.
|
||||
// (C) Copyright Thomas Witt 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_ITERATOR_FACADE_23022003THW_HPP
|
||||
#define BOOST_ITERATOR_FACADE_23022003THW_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/mp11/utility.hpp>
|
||||
|
||||
#include <boost/iterator/interoperable.hpp>
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/iterator/detail/facade_iterator_category.hpp>
|
||||
#include <boost/iterator/detail/type_traits/conjunction.hpp>
|
||||
#include <boost/iterator/detail/type_traits/negation.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
// This forward declaration is required for the friend declaration
|
||||
// in iterator_core_access
|
||||
template<
|
||||
typename Derived,
|
||||
typename Value,
|
||||
typename CategoryOrTraversal,
|
||||
typename Reference = Value&,
|
||||
typename Difference = std::ptrdiff_t
|
||||
>
|
||||
class iterator_facade;
|
||||
|
||||
namespace detail {
|
||||
|
||||
// The type trait checks if the category or traversal is at least as advanced as the specified required traversal
|
||||
template< typename CategoryOrTraversal, typename Required >
|
||||
struct is_traversal_at_least :
|
||||
public std::is_convertible< typename iterator_category_to_traversal< CategoryOrTraversal >::type, Required >
|
||||
{};
|
||||
|
||||
//
|
||||
// enable if for use in operator implementation.
|
||||
//
|
||||
template<
|
||||
typename Facade1,
|
||||
typename Facade2,
|
||||
typename Return
|
||||
>
|
||||
struct enable_if_interoperable :
|
||||
public std::enable_if<
|
||||
is_interoperable< Facade1, Facade2 >::value,
|
||||
Return
|
||||
>
|
||||
{};
|
||||
|
||||
//
|
||||
// enable if for use in implementation of operators specific for random access traversal.
|
||||
//
|
||||
template<
|
||||
typename Facade1,
|
||||
typename Facade2,
|
||||
typename Return
|
||||
>
|
||||
struct enable_if_interoperable_and_random_access_traversal :
|
||||
public std::enable_if<
|
||||
detail::conjunction<
|
||||
is_interoperable< Facade1, Facade2 >,
|
||||
is_traversal_at_least< typename iterator_category< Facade1 >::type, random_access_traversal_tag >,
|
||||
is_traversal_at_least< typename iterator_category< Facade2 >::type, random_access_traversal_tag >
|
||||
>::value,
|
||||
Return
|
||||
>
|
||||
{};
|
||||
|
||||
//
|
||||
// Generates associated types for an iterator_facade with the
|
||||
// given parameters.
|
||||
//
|
||||
template<
|
||||
typename ValueParam,
|
||||
typename CategoryOrTraversal,
|
||||
typename Reference,
|
||||
typename Difference
|
||||
>
|
||||
struct iterator_facade_types
|
||||
{
|
||||
using iterator_category = typename facade_iterator_category<
|
||||
CategoryOrTraversal, ValueParam, Reference
|
||||
>::type;
|
||||
|
||||
using value_type = typename std::remove_const< ValueParam >::type;
|
||||
|
||||
// Not the real associated pointer type
|
||||
using pointer = typename std::add_pointer<
|
||||
typename std::conditional<
|
||||
boost::iterators::detail::iterator_writability_disabled< ValueParam, Reference >::value,
|
||||
const value_type,
|
||||
value_type
|
||||
>::type
|
||||
>::type;
|
||||
};
|
||||
|
||||
// iterators whose dereference operators reference the same value
|
||||
// for all iterators into the same sequence (like many input
|
||||
// iterators) need help with their postfix ++: the referenced
|
||||
// value must be read and stored away before the increment occurs
|
||||
// so that *a++ yields the originally referenced element and not
|
||||
// the next one.
|
||||
template< typename Iterator >
|
||||
class postfix_increment_proxy
|
||||
{
|
||||
using value_type = typename iterator_value< Iterator >::type;
|
||||
|
||||
public:
|
||||
explicit postfix_increment_proxy(Iterator const& x) :
|
||||
stored_iterator(x),
|
||||
stored_value(*x)
|
||||
{}
|
||||
|
||||
// Returning a mutable reference allows nonsense like
|
||||
// (*r++).mutate(), but it imposes fewer assumptions about the
|
||||
// behavior of the value_type. In particular, recall that
|
||||
// (*r).mutate() is legal if operator* returns by value.
|
||||
// Provides readability of *r++
|
||||
value_type& operator*() const
|
||||
{
|
||||
return stored_value;
|
||||
}
|
||||
|
||||
// Provides X(r++)
|
||||
operator Iterator const&() const
|
||||
{
|
||||
return stored_iterator;
|
||||
}
|
||||
|
||||
// Provides (r++)->foo()
|
||||
value_type* operator->() const
|
||||
{
|
||||
return std::addressof(stored_value);
|
||||
}
|
||||
|
||||
private:
|
||||
Iterator stored_iterator;
|
||||
mutable value_type stored_value;
|
||||
};
|
||||
|
||||
|
||||
template< typename Iterator >
|
||||
class writable_postfix_increment_dereference_proxy;
|
||||
|
||||
template< typename T >
|
||||
struct is_not_writable_postfix_increment_dereference_proxy :
|
||||
public std::true_type
|
||||
{};
|
||||
|
||||
template< typename Iterator >
|
||||
struct is_not_writable_postfix_increment_dereference_proxy<
|
||||
writable_postfix_increment_dereference_proxy< Iterator >
|
||||
> :
|
||||
public std::false_type
|
||||
{};
|
||||
|
||||
template< typename Iterator >
|
||||
class writable_postfix_increment_proxy;
|
||||
|
||||
//
|
||||
// In general, we can't determine that such an iterator isn't
|
||||
// writable -- we also need to store a copy of the old iterator so
|
||||
// that it can be written into.
|
||||
template< typename Iterator >
|
||||
class writable_postfix_increment_dereference_proxy
|
||||
{
|
||||
friend class writable_postfix_increment_proxy< Iterator >;
|
||||
|
||||
using value_type = typename iterator_value< Iterator >::type;
|
||||
|
||||
public:
|
||||
explicit writable_postfix_increment_dereference_proxy(Iterator const& x) :
|
||||
stored_iterator(x),
|
||||
stored_value(*x)
|
||||
{}
|
||||
|
||||
// Provides readability of *r++
|
||||
operator value_type&() const
|
||||
{
|
||||
return this->stored_value;
|
||||
}
|
||||
|
||||
template< typename OtherIterator >
|
||||
writable_postfix_increment_dereference_proxy const&
|
||||
operator=(writable_postfix_increment_dereference_proxy< OtherIterator > const& x) const
|
||||
{
|
||||
typedef typename iterator_value< OtherIterator >::type other_value_type;
|
||||
*this->stored_iterator = static_cast< other_value_type& >(x);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Provides writability of *r++
|
||||
template< typename T >
|
||||
typename std::enable_if<
|
||||
is_not_writable_postfix_increment_dereference_proxy< T >::value,
|
||||
writable_postfix_increment_dereference_proxy const&
|
||||
>::type operator=(T&& x) const
|
||||
{
|
||||
*this->stored_iterator = static_cast< T&& >(x);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
Iterator stored_iterator;
|
||||
mutable value_type stored_value;
|
||||
};
|
||||
|
||||
template< typename Iterator >
|
||||
class writable_postfix_increment_proxy
|
||||
{
|
||||
using value_type = typename iterator_value< Iterator >::type;
|
||||
|
||||
public:
|
||||
explicit writable_postfix_increment_proxy(Iterator const& x) :
|
||||
dereference_proxy(x)
|
||||
{}
|
||||
|
||||
writable_postfix_increment_dereference_proxy< Iterator > const&
|
||||
operator*() const
|
||||
{
|
||||
return dereference_proxy;
|
||||
}
|
||||
|
||||
// Provides X(r++)
|
||||
operator Iterator const&() const
|
||||
{
|
||||
return dereference_proxy.stored_iterator;
|
||||
}
|
||||
|
||||
// Provides (r++)->foo()
|
||||
value_type* operator->() const
|
||||
{
|
||||
return std::addressof(dereference_proxy.stored_value);
|
||||
}
|
||||
|
||||
private:
|
||||
writable_postfix_increment_dereference_proxy< Iterator > dereference_proxy;
|
||||
};
|
||||
|
||||
template< typename Reference, typename Value >
|
||||
struct is_non_proxy_reference :
|
||||
public std::is_convertible<
|
||||
typename std::remove_reference< Reference >::type const volatile*,
|
||||
Value const volatile*
|
||||
>
|
||||
{};
|
||||
|
||||
// A metafunction to choose the result type of postfix ++
|
||||
//
|
||||
// Because the C++98 input iterator requirements say that *r++ has
|
||||
// type T (value_type), implementations of some standard
|
||||
// algorithms like lexicographical_compare may use constructions
|
||||
// like:
|
||||
//
|
||||
// *r++ < *s++
|
||||
//
|
||||
// If *r++ returns a proxy (as required if r is writable but not
|
||||
// multipass), this sort of expression will fail unless the proxy
|
||||
// supports the operator<. Since there are any number of such
|
||||
// operations, we're not going to try to support them. Therefore,
|
||||
// even if r++ returns a proxy, *r++ will only return a proxy if
|
||||
// *r also returns a proxy.
|
||||
template< typename Iterator, typename Value, typename Reference, typename CategoryOrTraversal >
|
||||
struct postfix_increment_result
|
||||
{
|
||||
using type = mp11::mp_eval_if_not<
|
||||
detail::conjunction<
|
||||
// A proxy is only needed for readable iterators
|
||||
std::is_convertible<
|
||||
Reference,
|
||||
// Use add_lvalue_reference to form `reference to Value` due to
|
||||
// some (strict) C++03 compilers (e.g. `gcc -std=c++03`) reject
|
||||
// 'reference-to-reference' in the template which described in CWG
|
||||
// DR106.
|
||||
// http://www.open-std.org/Jtc1/sc22/wg21/docs/cwg_defects.html#106
|
||||
typename std::add_lvalue_reference< Value const >::type
|
||||
>,
|
||||
|
||||
// No multipass iterator can have values that disappear
|
||||
// before positions can be re-visited
|
||||
detail::negation<
|
||||
detail::is_traversal_at_least< CategoryOrTraversal, forward_traversal_tag >
|
||||
>
|
||||
>,
|
||||
Iterator,
|
||||
mp11::mp_if,
|
||||
is_non_proxy_reference< Reference, Value >,
|
||||
postfix_increment_proxy< Iterator >,
|
||||
writable_postfix_increment_proxy< Iterator >
|
||||
>;
|
||||
};
|
||||
|
||||
// operator->() needs special support for input iterators to strictly meet the
|
||||
// standard's requirements. If *i is not a reference type, we must still
|
||||
// produce an lvalue to which a pointer can be formed. We do that by
|
||||
// returning a proxy object containing an instance of the reference object.
|
||||
template< typename Reference, typename Pointer >
|
||||
struct operator_arrow_dispatch // proxy references
|
||||
{
|
||||
struct proxy
|
||||
{
|
||||
explicit proxy(Reference const& x) : m_ref(x) {}
|
||||
Reference* operator->() { return std::addressof(m_ref); }
|
||||
// This function is needed for MWCW and BCC, which won't call
|
||||
// operator-> again automatically per 13.3.1.2 para 8
|
||||
operator Reference*() { return std::addressof(m_ref); }
|
||||
Reference m_ref;
|
||||
};
|
||||
|
||||
using result_type = proxy;
|
||||
|
||||
static result_type apply(Reference const& x)
|
||||
{
|
||||
return result_type(x);
|
||||
}
|
||||
};
|
||||
|
||||
template< typename T, typename Pointer >
|
||||
struct operator_arrow_dispatch< T&, Pointer > // "real" references
|
||||
{
|
||||
using result_type = Pointer;
|
||||
|
||||
static result_type apply(T& x)
|
||||
{
|
||||
return std::addressof(x);
|
||||
}
|
||||
};
|
||||
|
||||
// A proxy return type for operator[], needed to deal with
|
||||
// iterators that may invalidate referents upon destruction.
|
||||
// Consider the temporary iterator in *(a + n)
|
||||
template< typename Iterator >
|
||||
class operator_brackets_proxy
|
||||
{
|
||||
// Iterator is actually an iterator_facade, so we do not have to
|
||||
// go through iterator_traits to access the traits.
|
||||
using reference = typename Iterator::reference;
|
||||
|
||||
public:
|
||||
explicit operator_brackets_proxy(Iterator const& iter) noexcept(std::is_nothrow_copy_constructible< Iterator >::value) :
|
||||
m_iter(iter)
|
||||
{}
|
||||
|
||||
operator reference() const noexcept(noexcept(*std::declval< Iterator const& >()))
|
||||
{
|
||||
return *m_iter;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
typename std::enable_if<
|
||||
detail::conjunction<
|
||||
detail::negation<
|
||||
std::is_same<
|
||||
operator_brackets_proxy< Iterator >,
|
||||
typename std::remove_cv< typename std::remove_reference< T >::type >::type
|
||||
>
|
||||
>,
|
||||
std::is_assignable< reference, T&& >
|
||||
>::value,
|
||||
operator_brackets_proxy&
|
||||
>::type operator= (T&& val) noexcept(noexcept(*std::declval< Iterator& >() = std::declval< T&& >()))
|
||||
{
|
||||
*m_iter = static_cast< T&& >(val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Provides it[n]->foo(). Leverages chaining of operator->.
|
||||
reference operator->() const noexcept(noexcept(*std::declval< Iterator const& >()))
|
||||
{
|
||||
return *m_iter;
|
||||
}
|
||||
|
||||
// Provides (*it[n]).foo()
|
||||
template< typename Ref = reference, typename Result = decltype(*std::declval< Ref >()) >
|
||||
Result operator*() const noexcept(noexcept(**std::declval< Iterator const& >()))
|
||||
{
|
||||
return **m_iter;
|
||||
}
|
||||
|
||||
private:
|
||||
Iterator m_iter;
|
||||
};
|
||||
|
||||
// A binary metafunction class that always returns bool.
|
||||
template< typename Iterator1, typename Iterator2 >
|
||||
using always_bool_t = bool;
|
||||
|
||||
template< typename Iterator1, typename Iterator2 >
|
||||
using choose_difference_type_t = typename std::conditional<
|
||||
std::is_convertible< Iterator2, Iterator1 >::value,
|
||||
iterator_difference< Iterator1 >,
|
||||
iterator_difference< Iterator2 >
|
||||
>::type::type;
|
||||
|
||||
template<
|
||||
typename Derived,
|
||||
typename Value,
|
||||
typename CategoryOrTraversal,
|
||||
typename Reference,
|
||||
typename Difference,
|
||||
bool IsBidirectionalTraversal,
|
||||
bool IsRandomAccessTraversal
|
||||
>
|
||||
class iterator_facade_base;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
// Macros which describe the declarations of binary operators
|
||||
#define BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, enabler) \
|
||||
template< \
|
||||
typename Derived1, typename V1, typename TC1, typename Reference1, typename Difference1, \
|
||||
typename Derived2, typename V2, typename TC2, typename Reference2, typename Difference2 \
|
||||
> \
|
||||
prefix typename enabler< \
|
||||
Derived1, Derived2, \
|
||||
result_type< Derived1, Derived2 > \
|
||||
>::type \
|
||||
operator op( \
|
||||
iterator_facade< Derived1, V1, TC1, Reference1, Difference1 > const& lhs, \
|
||||
iterator_facade< Derived2, V2, TC2, Reference2, Difference2 > const& rhs)
|
||||
|
||||
#define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \
|
||||
BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable)
|
||||
|
||||
#define BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(prefix, op, result_type) \
|
||||
BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable_and_random_access_traversal)
|
||||
|
||||
#define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \
|
||||
template< typename Derived, typename V, typename TC, typename R, typename D > \
|
||||
prefix typename std::enable_if< \
|
||||
boost::iterators::detail::is_traversal_at_least< \
|
||||
TC, \
|
||||
boost::iterators::random_access_traversal_tag \
|
||||
>::value, \
|
||||
Derived \
|
||||
>::type operator+ args
|
||||
|
||||
//
|
||||
// Helper class for granting access to the iterator core interface.
|
||||
//
|
||||
// The simple core interface is used by iterator_facade. The core
|
||||
// interface of a user/library defined iterator type should not be made public
|
||||
// so that it does not clutter the public interface. Instead iterator_core_access
|
||||
// should be made friend so that iterator_facade can access the core
|
||||
// interface through iterator_core_access.
|
||||
//
|
||||
class iterator_core_access
|
||||
{
|
||||
template< typename I, typename V, typename TC, typename R, typename D >
|
||||
friend class iterator_facade;
|
||||
template< typename I, typename V, typename TC, typename R, typename D, bool IsBidirectionalTraversal, bool IsRandomAccessTraversal >
|
||||
friend class detail::iterator_facade_base;
|
||||
|
||||
#define BOOST_ITERATOR_FACADE_RELATION(op) \
|
||||
BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend, op, boost::iterators::detail::always_bool_t);
|
||||
|
||||
BOOST_ITERATOR_FACADE_RELATION(==)
|
||||
BOOST_ITERATOR_FACADE_RELATION(!=)
|
||||
|
||||
#undef BOOST_ITERATOR_FACADE_RELATION
|
||||
|
||||
#define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op) \
|
||||
BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(friend, op, boost::iterators::detail::always_bool_t);
|
||||
|
||||
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<)
|
||||
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>)
|
||||
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<=)
|
||||
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>=)
|
||||
|
||||
#undef BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION
|
||||
|
||||
BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(friend, -, boost::iterators::detail::choose_difference_type_t);
|
||||
|
||||
BOOST_ITERATOR_FACADE_PLUS_HEAD(
|
||||
friend inline,
|
||||
(iterator_facade< Derived, V, TC, R, D > const&, typename Derived::difference_type)
|
||||
);
|
||||
|
||||
BOOST_ITERATOR_FACADE_PLUS_HEAD(
|
||||
friend inline,
|
||||
(typename Derived::difference_type, iterator_facade< Derived, V, TC, R, D > const&)
|
||||
);
|
||||
|
||||
template< typename Facade >
|
||||
static typename Facade::reference dereference(Facade const& f)
|
||||
{
|
||||
return f.dereference();
|
||||
}
|
||||
|
||||
template< typename Facade >
|
||||
static void increment(Facade& f)
|
||||
{
|
||||
f.increment();
|
||||
}
|
||||
|
||||
template< typename Facade >
|
||||
static void decrement(Facade& f)
|
||||
{
|
||||
f.decrement();
|
||||
}
|
||||
|
||||
template< typename Facade1, typename Facade2 >
|
||||
static bool equal(Facade1 const& f1, Facade2 const& f2, std::true_type)
|
||||
{
|
||||
return f1.equal(f2);
|
||||
}
|
||||
|
||||
template< typename Facade1, typename Facade2 >
|
||||
static bool equal(Facade1 const& f1, Facade2 const& f2, std::false_type)
|
||||
{
|
||||
return f2.equal(f1);
|
||||
}
|
||||
|
||||
template< typename Facade >
|
||||
static void advance(Facade& f, typename Facade::difference_type n)
|
||||
{
|
||||
f.advance(n);
|
||||
}
|
||||
|
||||
template< typename Facade1, typename Facade2 >
|
||||
static typename Facade1::difference_type distance_from(Facade1 const& f1, Facade2 const& f2, std::true_type)
|
||||
{
|
||||
return -f1.distance_to(f2);
|
||||
}
|
||||
|
||||
template< typename Facade1, typename Facade2 >
|
||||
static typename Facade2::difference_type distance_from(Facade1 const& f1, Facade2 const& f2, std::false_type)
|
||||
{
|
||||
return f2.distance_to(f1);
|
||||
}
|
||||
|
||||
//
|
||||
// Curiously Recurring Template interface.
|
||||
//
|
||||
template< typename I, typename V, typename TC, typename R, typename D >
|
||||
static I& derived(iterator_facade< I, V, TC, R, D >& facade)
|
||||
{
|
||||
return *static_cast< I* >(&facade);
|
||||
}
|
||||
|
||||
template< typename I, typename V, typename TC, typename R, typename D >
|
||||
static I const& derived(iterator_facade< I, V, TC, R, D > const& facade)
|
||||
{
|
||||
return *static_cast< I const* >(&facade);
|
||||
}
|
||||
|
||||
// objects of this class are useless
|
||||
iterator_core_access() = delete;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Implementation for forward traversal iterators
|
||||
template<
|
||||
typename Derived,
|
||||
typename Value,
|
||||
typename CategoryOrTraversal,
|
||||
typename Reference,
|
||||
typename Difference
|
||||
>
|
||||
class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false >
|
||||
{
|
||||
private:
|
||||
using associated_types = boost::iterators::detail::iterator_facade_types<
|
||||
Value, CategoryOrTraversal, Reference, Difference
|
||||
>;
|
||||
|
||||
using operator_arrow_dispatch_ = boost::iterators::detail::operator_arrow_dispatch<
|
||||
Reference,
|
||||
typename associated_types::pointer
|
||||
>;
|
||||
|
||||
public:
|
||||
using value_type = typename associated_types::value_type;
|
||||
using reference = Reference;
|
||||
using difference_type = Difference;
|
||||
|
||||
using pointer = typename operator_arrow_dispatch_::result_type;
|
||||
|
||||
using iterator_category = typename associated_types::iterator_category;
|
||||
|
||||
public:
|
||||
reference operator*() const
|
||||
{
|
||||
return iterator_core_access::dereference(this->derived());
|
||||
}
|
||||
|
||||
pointer operator->() const
|
||||
{
|
||||
return operator_arrow_dispatch_::apply(*this->derived());
|
||||
}
|
||||
|
||||
Derived& operator++()
|
||||
{
|
||||
iterator_core_access::increment(this->derived());
|
||||
return this->derived();
|
||||
}
|
||||
|
||||
protected:
|
||||
//
|
||||
// Curiously Recurring Template interface.
|
||||
//
|
||||
Derived& derived()
|
||||
{
|
||||
return *static_cast< Derived* >(this);
|
||||
}
|
||||
|
||||
Derived const& derived() const
|
||||
{
|
||||
return *static_cast< Derived const* >(this);
|
||||
}
|
||||
};
|
||||
|
||||
// Implementation for bidirectional traversal iterators
|
||||
template<
|
||||
typename Derived,
|
||||
typename Value,
|
||||
typename CategoryOrTraversal,
|
||||
typename Reference,
|
||||
typename Difference
|
||||
>
|
||||
class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false > :
|
||||
public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false >
|
||||
{
|
||||
public:
|
||||
Derived& operator--()
|
||||
{
|
||||
iterator_core_access::decrement(this->derived());
|
||||
return this->derived();
|
||||
}
|
||||
|
||||
Derived operator--(int)
|
||||
{
|
||||
Derived tmp(this->derived());
|
||||
--*this;
|
||||
return tmp;
|
||||
}
|
||||
};
|
||||
|
||||
// Implementation for random access traversal iterators
|
||||
template<
|
||||
typename Derived,
|
||||
typename Value,
|
||||
typename CategoryOrTraversal,
|
||||
typename Reference,
|
||||
typename Difference
|
||||
>
|
||||
class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, true > :
|
||||
public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false >
|
||||
{
|
||||
private:
|
||||
using base_type = iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false >;
|
||||
|
||||
public:
|
||||
using reference = typename base_type::reference;
|
||||
using difference_type = typename base_type::difference_type;
|
||||
|
||||
public:
|
||||
operator_brackets_proxy< Derived > operator[](difference_type n) const
|
||||
{
|
||||
return operator_brackets_proxy< Derived >(this->derived() + n);
|
||||
}
|
||||
|
||||
Derived& operator+=(difference_type n)
|
||||
{
|
||||
iterator_core_access::advance(this->derived(), n);
|
||||
return this->derived();
|
||||
}
|
||||
|
||||
Derived& operator-=(difference_type n)
|
||||
{
|
||||
iterator_core_access::advance(this->derived(), -n);
|
||||
return this->derived();
|
||||
}
|
||||
|
||||
Derived operator-(difference_type x) const
|
||||
{
|
||||
Derived result(this->derived());
|
||||
return result -= x;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
//
|
||||
// iterator_facade - use as a public base class for defining new
|
||||
// standard-conforming iterators.
|
||||
//
|
||||
template<
|
||||
typename Derived, // The derived iterator type being constructed
|
||||
typename Value,
|
||||
typename CategoryOrTraversal,
|
||||
typename Reference,
|
||||
typename Difference
|
||||
>
|
||||
class iterator_facade :
|
||||
public detail::iterator_facade_base<
|
||||
Derived,
|
||||
Value,
|
||||
CategoryOrTraversal,
|
||||
Reference,
|
||||
Difference,
|
||||
detail::is_traversal_at_least< CategoryOrTraversal, bidirectional_traversal_tag >::value,
|
||||
detail::is_traversal_at_least< CategoryOrTraversal, random_access_traversal_tag >::value
|
||||
>
|
||||
{
|
||||
protected:
|
||||
// For use by derived classes
|
||||
using iterator_facade_ = iterator_facade< Derived, Value, CategoryOrTraversal, Reference, Difference >;
|
||||
};
|
||||
|
||||
template< typename I, typename V, typename TC, typename R, typename D >
|
||||
inline typename boost::iterators::detail::postfix_increment_result< I, V, R, TC >::type
|
||||
operator++(iterator_facade< I, V, TC, R, D >& i, int)
|
||||
{
|
||||
typename boost::iterators::detail::postfix_increment_result< I, V, R, TC >::type
|
||||
tmp(*static_cast< I* >(&i));
|
||||
|
||||
++i;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Comparison operator implementation. The library supplied operators
|
||||
// enables the user to provide fully interoperable constant/mutable
|
||||
// iterator types. I.e. the library provides all operators
|
||||
// for all mutable/constant iterator combinations.
|
||||
//
|
||||
// Note though that this kind of interoperability for constant/mutable
|
||||
// iterators is not required by the standard for container iterators.
|
||||
// All the standard asks for is a conversion mutable -> constant.
|
||||
// Most standard library implementations nowadays provide fully interoperable
|
||||
// iterator implementations, but there are still heavily used implementations
|
||||
// that do not provide them. (Actually it's even worse, they do not provide
|
||||
// them for only a few iterators.)
|
||||
//
|
||||
// ?? Maybe a BOOST_ITERATOR_NO_FULL_INTEROPERABILITY macro should
|
||||
// enable the user to turn off mixed type operators
|
||||
//
|
||||
// The library takes care to provide only the right operator overloads.
|
||||
// I.e.
|
||||
//
|
||||
// bool operator==(Iterator, Iterator);
|
||||
// bool operator==(ConstIterator, Iterator);
|
||||
// bool operator==(Iterator, ConstIterator);
|
||||
// bool operator==(ConstIterator, ConstIterator);
|
||||
//
|
||||
// ...
|
||||
//
|
||||
// In order to do so it uses c++ idioms that are not yet widely supported
|
||||
// by current compiler releases. The library is designed to degrade gracefully
|
||||
// in the face of compiler deficiencies. In general compiler
|
||||
// deficiencies result in less strict error checking and more obscure
|
||||
// error messages, functionality is not affected.
|
||||
//
|
||||
// For full operation compiler support for "Substitution Failure Is Not An Error"
|
||||
// (aka. enable_if) and boost::is_convertible is required.
|
||||
//
|
||||
// The following problems occur if support is lacking.
|
||||
//
|
||||
// Pseudo code
|
||||
//
|
||||
// ---------------
|
||||
// AdaptorA<Iterator1> a1;
|
||||
// AdaptorA<Iterator2> a2;
|
||||
//
|
||||
// // This will result in a no such overload error in full operation
|
||||
// // If enable_if or is_convertible is not supported
|
||||
// // The instantiation will fail with an error hopefully indicating that
|
||||
// // there is no operator== for Iterator1, Iterator2
|
||||
// // The same will happen if no enable_if is used to remove
|
||||
// // false overloads from the templated conversion constructor
|
||||
// // of AdaptorA.
|
||||
//
|
||||
// a1 == a2;
|
||||
// ----------------
|
||||
//
|
||||
// AdaptorA<Iterator> a;
|
||||
// AdaptorB<Iterator> b;
|
||||
//
|
||||
// // This will result in a no such overload error in full operation
|
||||
// // If enable_if is not supported the static assert used
|
||||
// // in the operator implementation will fail.
|
||||
// // This will accidently work if is_convertible is not supported.
|
||||
//
|
||||
// a == b;
|
||||
// ----------------
|
||||
//
|
||||
|
||||
#define BOOST_ITERATOR_FACADE_INTEROP(op, result_type, return_prefix, base_op) \
|
||||
BOOST_ITERATOR_FACADE_INTEROP_HEAD(inline, op, result_type) \
|
||||
{ \
|
||||
return_prefix iterator_core_access::base_op( \
|
||||
*static_cast< Derived1 const* >(&lhs), \
|
||||
*static_cast< Derived2 const* >(&rhs), \
|
||||
std::integral_constant< bool, std::is_convertible< Derived2, Derived1 >::value >() \
|
||||
); \
|
||||
}
|
||||
|
||||
#define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \
|
||||
BOOST_ITERATOR_FACADE_INTEROP( \
|
||||
op, \
|
||||
boost::iterators::detail::always_bool_t, \
|
||||
return_prefix, \
|
||||
base_op \
|
||||
)
|
||||
|
||||
BOOST_ITERATOR_FACADE_RELATION(==, return, equal)
|
||||
BOOST_ITERATOR_FACADE_RELATION(!=, return !, equal)
|
||||
|
||||
#undef BOOST_ITERATOR_FACADE_RELATION
|
||||
|
||||
|
||||
#define BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(op, result_type, return_prefix, base_op) \
|
||||
BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(inline, op, result_type) \
|
||||
{ \
|
||||
return_prefix iterator_core_access::base_op( \
|
||||
*static_cast< Derived1 const* >(&lhs), \
|
||||
*static_cast< Derived2 const* >(&rhs), \
|
||||
std::integral_constant< bool, std::is_convertible< Derived2, Derived1 >::value >() \
|
||||
); \
|
||||
}
|
||||
|
||||
#define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op, return_prefix, base_op) \
|
||||
BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS( \
|
||||
op, \
|
||||
boost::iterators::detail::always_bool_t, \
|
||||
return_prefix, \
|
||||
base_op \
|
||||
)
|
||||
|
||||
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<, return 0 >, distance_from)
|
||||
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>, return 0 <, distance_from)
|
||||
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<=, return 0 >=, distance_from)
|
||||
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>=, return 0 <=, distance_from)
|
||||
|
||||
#undef BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION
|
||||
|
||||
// operator- requires an additional part in the static assertion
|
||||
BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(
|
||||
-,
|
||||
boost::iterators::detail::choose_difference_type_t,
|
||||
return,
|
||||
distance_from
|
||||
)
|
||||
|
||||
#undef BOOST_ITERATOR_FACADE_INTEROP
|
||||
#undef BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS
|
||||
|
||||
#define BOOST_ITERATOR_FACADE_PLUS(args) \
|
||||
BOOST_ITERATOR_FACADE_PLUS_HEAD(inline, args) \
|
||||
{ \
|
||||
Derived tmp(static_cast< Derived const& >(i)); \
|
||||
return tmp += n; \
|
||||
}
|
||||
|
||||
BOOST_ITERATOR_FACADE_PLUS((iterator_facade< Derived, V, TC, R, D > const& i, typename Derived::difference_type n))
|
||||
BOOST_ITERATOR_FACADE_PLUS((typename Derived::difference_type n, iterator_facade< Derived, V, TC, R, D > const& i))
|
||||
|
||||
#undef BOOST_ITERATOR_FACADE_PLUS
|
||||
#undef BOOST_ITERATOR_FACADE_PLUS_HEAD
|
||||
|
||||
#undef BOOST_ITERATOR_FACADE_INTEROP_HEAD
|
||||
#undef BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD
|
||||
#undef BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::iterator_core_access;
|
||||
using iterators::iterator_facade;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_FACADE_23022003THW_HPP
|
||||
68
include/boost/iterator/iterator_traits.hpp
Normal file
68
include/boost/iterator/iterator_traits.hpp
Normal file
@@ -0,0 +1,68 @@
|
||||
// Copyright David Abrahams 2003.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef ITERATOR_TRAITS_DWA200347_HPP
|
||||
#define ITERATOR_TRAITS_DWA200347_HPP
|
||||
|
||||
#include <iterator>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
template< typename Iterator >
|
||||
using iterator_value_t = typename std::iterator_traits< Iterator >::value_type;
|
||||
|
||||
template< typename Iterator >
|
||||
struct iterator_value
|
||||
{
|
||||
using type = iterator_value_t< Iterator >;
|
||||
};
|
||||
|
||||
template< typename Iterator >
|
||||
using iterator_reference_t = typename std::iterator_traits< Iterator >::reference;
|
||||
|
||||
template< typename Iterator >
|
||||
struct iterator_reference
|
||||
{
|
||||
using type = iterator_reference_t< Iterator >;
|
||||
};
|
||||
|
||||
template< typename Iterator >
|
||||
using iterator_pointer_t = typename std::iterator_traits< Iterator >::pointer;
|
||||
|
||||
template< typename Iterator >
|
||||
struct iterator_pointer
|
||||
{
|
||||
using type = iterator_pointer_t< Iterator >;
|
||||
};
|
||||
|
||||
template< typename Iterator >
|
||||
using iterator_difference_t = typename std::iterator_traits< Iterator >::difference_type;
|
||||
|
||||
template< typename Iterator >
|
||||
struct iterator_difference
|
||||
{
|
||||
using type = iterator_difference_t< Iterator >;
|
||||
};
|
||||
|
||||
template< typename Iterator >
|
||||
using iterator_category_t = typename std::iterator_traits< Iterator >::iterator_category;
|
||||
|
||||
template< typename Iterator >
|
||||
struct iterator_category
|
||||
{
|
||||
using type = iterator_category_t< Iterator >;
|
||||
};
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::iterator_value;
|
||||
using iterators::iterator_reference;
|
||||
using iterators::iterator_pointer;
|
||||
using iterators::iterator_difference;
|
||||
using iterators::iterator_category;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // ITERATOR_TRAITS_DWA200347_HPP
|
||||
83
include/boost/iterator/min_category.hpp
Normal file
83
include/boost/iterator/min_category.hpp
Normal file
@@ -0,0 +1,83 @@
|
||||
// Copyright Andrey Semashev 2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_ITERATOR_MIN_CATEGORY_HPP_INCLUDED_
|
||||
#define BOOST_ITERATOR_MIN_CATEGORY_HPP_INCLUDED_
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
namespace detail {
|
||||
|
||||
template<
|
||||
typename T1,
|
||||
typename T2,
|
||||
bool GreaterEqual = std::is_convertible< T1, T2 >::value,
|
||||
bool LessEqual = std::is_convertible< T2, T1 >::value
|
||||
>
|
||||
struct min_category_impl
|
||||
{
|
||||
static_assert(GreaterEqual || LessEqual, "Iterator category types must be related through convertibility.");
|
||||
};
|
||||
|
||||
template< typename T1, typename T2 >
|
||||
struct min_category_impl< T1, T2, true, false >
|
||||
{
|
||||
using type = T2;
|
||||
};
|
||||
|
||||
template< typename T1, typename T2 >
|
||||
struct min_category_impl< T1, T2, false, true >
|
||||
{
|
||||
using type = T1;
|
||||
};
|
||||
|
||||
template< typename T1, typename T2 >
|
||||
struct min_category_impl< T1, T2, true, true >
|
||||
{
|
||||
static_assert(std::is_same< T1, T2 >::value, "Iterator category types must be the same when they are equivalent.");
|
||||
using type = T1;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
//
|
||||
// Returns the minimum iterator category type in the list
|
||||
// or fails to compile if any of the categories are unrelated.
|
||||
//
|
||||
template< typename... Categories >
|
||||
struct min_category;
|
||||
|
||||
template< typename T >
|
||||
struct min_category< T >
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template< typename T1, typename T2, typename... Tail >
|
||||
struct min_category< T1, T2, Tail... >
|
||||
{
|
||||
using type = typename min_category<
|
||||
typename iterators::detail::min_category_impl< T1, T2 >::type,
|
||||
Tail...
|
||||
>::type;
|
||||
};
|
||||
|
||||
// Shortcut to slightly optimize compilation speed
|
||||
template< typename T1, typename T2 >
|
||||
struct min_category< T1, T2 >
|
||||
{
|
||||
using type = typename iterators::detail::min_category_impl< T1, T2 >::type;
|
||||
};
|
||||
|
||||
template< typename... Categories >
|
||||
using min_category_t = typename min_category< Categories... >::type;
|
||||
|
||||
} // namespace iterators
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_MIN_CATEGORY_HPP_INCLUDED_
|
||||
33
include/boost/iterator/minimum_category.hpp
Normal file
33
include/boost/iterator/minimum_category.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
// Copyright David Abrahams 2003. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_
|
||||
#define BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_
|
||||
|
||||
#include <boost/mpl/arg_fwd.hpp>
|
||||
#include <boost/iterator/min_category.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
// Deprecated metafunction for selecting minimum iterator category,
|
||||
// use min_category instead.
|
||||
template< class T1 = mpl::arg<1>, class T2 = mpl::arg<2> >
|
||||
struct minimum_category :
|
||||
public min_category<T1, T2>
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct minimum_category< mpl::arg<1>, mpl::arg<2> >
|
||||
{
|
||||
template <class T1, class T2>
|
||||
struct apply :
|
||||
public min_category<T1, T2>
|
||||
{};
|
||||
};
|
||||
|
||||
} // namespace iterators
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_
|
||||
264
include/boost/iterator/new_iterator_tests.hpp
Normal file
264
include/boost/iterator/new_iterator_tests.hpp
Normal file
@@ -0,0 +1,264 @@
|
||||
#ifndef BOOST_NEW_ITERATOR_TESTS_HPP
|
||||
#define BOOST_NEW_ITERATOR_TESTS_HPP
|
||||
|
||||
//
|
||||
// Copyright (c) David Abrahams 2001.
|
||||
// Copyright (c) Jeremy Siek 2001-2003.
|
||||
// Copyright (c) Thomas Witt 2002.
|
||||
//
|
||||
// Use, modification and distribution is subject to the
|
||||
// Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
// This is meant to be the beginnings of a comprehensive, generic
|
||||
// test suite for STL concepts such as iterators and containers.
|
||||
//
|
||||
// Revision History:
|
||||
// 28 Oct 2002 Started update for new iterator categories
|
||||
// (Jeremy Siek)
|
||||
// 28 Apr 2002 Fixed input iterator requirements.
|
||||
// For a == b a++ == b++ is no longer required.
|
||||
// See 24.1.1/3 for details.
|
||||
// (Thomas Witt)
|
||||
// 08 Feb 2001 Fixed bidirectional iterator test so that
|
||||
// --i is no longer a precondition.
|
||||
// (Jeremy Siek)
|
||||
// 04 Feb 2001 Added lvalue test, corrected preconditions
|
||||
// (David Abrahams)
|
||||
|
||||
#include <boost/concept_archetype.hpp> // for detail::dummy_constructor
|
||||
#include <boost/iterator/is_lvalue_iterator.hpp>
|
||||
#include <boost/iterator/is_readable_iterator.hpp>
|
||||
#include <boost/pending/iterator_tests.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/detail/is_incrementable.hpp>
|
||||
#include <boost/iterator/detail/type_traits/conjunction.hpp>
|
||||
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
|
||||
// Do separate tests for *i++ so we can treat, e.g., smart pointers,
|
||||
// as readable and/or writable iterators.
|
||||
template <class Iterator, class T>
|
||||
void readable_iterator_traversal_test(Iterator i1, T v, std::true_type)
|
||||
{
|
||||
T v2(*i1++);
|
||||
BOOST_TEST(v == v2);
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
void readable_iterator_traversal_test(const Iterator i1, T v, std::false_type)
|
||||
{}
|
||||
|
||||
template <class Iterator, class T>
|
||||
void writable_iterator_traversal_test(Iterator i1, T v, std::true_type)
|
||||
{
|
||||
++i1; // we just wrote into that position
|
||||
*i1++ = v;
|
||||
Iterator x(i1++);
|
||||
(void)x;
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
void writable_iterator_traversal_test(const Iterator i1, T v, std::false_type)
|
||||
{}
|
||||
|
||||
// Preconditions: *i == v
|
||||
template <class Iterator, class T>
|
||||
void readable_iterator_test(const Iterator i1, T v)
|
||||
{
|
||||
Iterator i2(i1); // Copy Constructible
|
||||
typedef typename std::iterator_traits<Iterator>::reference ref_t;
|
||||
ref_t r1 = *i1;
|
||||
ref_t r2 = *i2;
|
||||
T v1 = r1;
|
||||
T v2 = r2;
|
||||
BOOST_TEST(v1 == v);
|
||||
BOOST_TEST(v2 == v);
|
||||
|
||||
readable_iterator_traversal_test(
|
||||
i1, v,
|
||||
std::integral_constant<
|
||||
bool, detail::is_postfix_incrementable<Iterator>::value>{});
|
||||
|
||||
// I think we don't really need this as it checks the same things as
|
||||
// the above code.
|
||||
static_assert(is_readable_iterator<Iterator>::value,
|
||||
"Iterator must be readable.");
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
void writable_iterator_test(Iterator i, T v, T v2)
|
||||
{
|
||||
Iterator i2(i); // Copy Constructible
|
||||
*i2 = v;
|
||||
|
||||
writable_iterator_traversal_test(
|
||||
i, v2,
|
||||
iterators::detail::conjunction<
|
||||
std::integral_constant<bool, detail::is_incrementable<Iterator>::value>,
|
||||
std::integral_constant<bool, detail::is_postfix_incrementable<Iterator>::value>
|
||||
>());
|
||||
}
|
||||
|
||||
template <class Iterator>
|
||||
void swappable_iterator_test(Iterator i, Iterator j)
|
||||
{
|
||||
Iterator i2(i), j2(j);
|
||||
typename std::iterator_traits<Iterator>::value_type bi = *i, bj = *j;
|
||||
iter_swap(i2, j2);
|
||||
typename std::iterator_traits<Iterator>::value_type ai = *i, aj = *j;
|
||||
BOOST_TEST(bi == aj && bj == ai);
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
void constant_lvalue_iterator_test(Iterator i, T v1)
|
||||
{
|
||||
Iterator i2(i);
|
||||
typedef typename std::iterator_traits<Iterator>::value_type value_type;
|
||||
typedef typename std::iterator_traits<Iterator>::reference reference;
|
||||
static_assert(std::is_same<const value_type&, reference>::value,
|
||||
"reference type must be the same as const value_type& for "
|
||||
"constant lvalue iterator.");
|
||||
const T& v2 = *i2;
|
||||
BOOST_TEST(v1 == v2);
|
||||
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
static_assert(is_lvalue_iterator<Iterator>::value
|
||||
&& !is_non_const_lvalue_iterator<Iterator>::value,
|
||||
"Iterator must be a const lvalue iterator.");
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
void non_const_lvalue_iterator_test(Iterator i, T v1, T v2)
|
||||
{
|
||||
Iterator i2(i);
|
||||
typedef typename std::iterator_traits<Iterator>::value_type value_type;
|
||||
typedef typename std::iterator_traits<Iterator>::reference reference;
|
||||
static_assert(std::is_same<value_type&, reference>::value,
|
||||
"reference type must be the same as value_type& for "
|
||||
"non-constant lvalue iterator.");
|
||||
T& v3 = *i2;
|
||||
BOOST_TEST(v1 == v3);
|
||||
|
||||
// A non-const lvalue iterator is not necessarily writable, but we
|
||||
// are assuming the value_type is assignable here
|
||||
*i = v2;
|
||||
|
||||
T& v4 = *i2;
|
||||
BOOST_TEST(v2 == v4);
|
||||
static_assert(is_lvalue_iterator<Iterator>::value,
|
||||
"Iterator must be an lvalue iterator.");
|
||||
static_assert(is_non_const_lvalue_iterator<Iterator>::value,
|
||||
"Iterator must be non-const.");
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
void forward_readable_iterator_test(Iterator i, Iterator j, T val1, T val2)
|
||||
{
|
||||
Iterator i2;
|
||||
Iterator i3(i);
|
||||
i2 = i;
|
||||
BOOST_TEST(i2 == i3);
|
||||
BOOST_TEST(i != j);
|
||||
BOOST_TEST(i2 != j);
|
||||
readable_iterator_test(i, val1);
|
||||
readable_iterator_test(i2, val1);
|
||||
readable_iterator_test(i3, val1);
|
||||
|
||||
BOOST_TEST(i == i2++);
|
||||
BOOST_TEST(i != ++i3);
|
||||
|
||||
readable_iterator_test(i2, val2);
|
||||
readable_iterator_test(i3, val2);
|
||||
|
||||
readable_iterator_test(i, val1);
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
void forward_swappable_iterator_test(Iterator i, Iterator j, T val1, T val2)
|
||||
{
|
||||
forward_readable_iterator_test(i, j, val1, val2);
|
||||
Iterator i2 = i;
|
||||
++i2;
|
||||
swappable_iterator_test(i, i2);
|
||||
}
|
||||
|
||||
// bidirectional
|
||||
// Preconditions: *i == v1, *++i == v2
|
||||
template <class Iterator, class T>
|
||||
void bidirectional_readable_iterator_test(Iterator i, T v1, T v2)
|
||||
{
|
||||
Iterator j(i);
|
||||
++j;
|
||||
forward_readable_iterator_test(i, j, v1, v2);
|
||||
++i;
|
||||
|
||||
Iterator i1 = i, i2 = i;
|
||||
|
||||
BOOST_TEST(i == i1--);
|
||||
BOOST_TEST(i != --i2);
|
||||
|
||||
readable_iterator_test(i, v2);
|
||||
readable_iterator_test(i1, v1);
|
||||
readable_iterator_test(i2, v1);
|
||||
|
||||
--i;
|
||||
BOOST_TEST(i == i1);
|
||||
BOOST_TEST(i == i2);
|
||||
++i1;
|
||||
++i2;
|
||||
|
||||
readable_iterator_test(i, v1);
|
||||
readable_iterator_test(i1, v2);
|
||||
readable_iterator_test(i2, v2);
|
||||
}
|
||||
|
||||
// random access
|
||||
// Preconditions: [i,i+N) is a valid range
|
||||
template <class Iterator, class TrueVals>
|
||||
void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals)
|
||||
{
|
||||
bidirectional_readable_iterator_test(i, vals[0], vals[1]);
|
||||
const Iterator j = i;
|
||||
int c;
|
||||
|
||||
for (c = 0; c < N - 1; ++c)
|
||||
{
|
||||
BOOST_TEST(i == j + c);
|
||||
BOOST_TEST(*i == vals[c]);
|
||||
typename std::iterator_traits<Iterator>::value_type x = j[c];
|
||||
BOOST_TEST(*i == x);
|
||||
BOOST_TEST(*i == *(j + c));
|
||||
BOOST_TEST(*i == *(c + j));
|
||||
++i;
|
||||
BOOST_TEST(i > j);
|
||||
BOOST_TEST(i >= j);
|
||||
BOOST_TEST(j <= i);
|
||||
BOOST_TEST(j < i);
|
||||
}
|
||||
|
||||
Iterator k = j + N - 1;
|
||||
for (c = 0; c < N - 1; ++c)
|
||||
{
|
||||
BOOST_TEST(i == k - c);
|
||||
BOOST_TEST(*i == vals[N - 1 - c]);
|
||||
typename std::iterator_traits<Iterator>::value_type x = j[N - 1 - c];
|
||||
BOOST_TEST(*i == x);
|
||||
Iterator q = k - c;
|
||||
BOOST_TEST(*i == *q);
|
||||
BOOST_TEST(i > j);
|
||||
BOOST_TEST(i >= j);
|
||||
BOOST_TEST(j <= i);
|
||||
BOOST_TEST(j < i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_NEW_ITERATOR_TESTS_HPP
|
||||
85
include/boost/iterator/permutation_iterator.hpp
Normal file
85
include/boost/iterator/permutation_iterator.hpp
Normal file
@@ -0,0 +1,85 @@
|
||||
// (C) Copyright Toon Knapen 2001.
|
||||
// (C) Copyright David Abrahams 2003.
|
||||
// (C) Copyright Roland Richter 2003.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_ITERATOR_PERMUTATION_ITERATOR_HPP_INCLUDED_
|
||||
#define BOOST_ITERATOR_PERMUTATION_ITERATOR_HPP_INCLUDED_
|
||||
|
||||
#include <iterator>
|
||||
|
||||
#include <boost/core/use_default.hpp>
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/iterator/enable_if_convertible.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
template< typename ElementIterator, typename IndexIterator >
|
||||
class permutation_iterator :
|
||||
public iterator_adaptor<
|
||||
permutation_iterator< ElementIterator, IndexIterator >,
|
||||
IndexIterator,
|
||||
typename std::iterator_traits< ElementIterator >::value_type,
|
||||
use_default,
|
||||
typename std::iterator_traits< ElementIterator >::reference
|
||||
>
|
||||
{
|
||||
friend class iterator_core_access;
|
||||
template< typename, typename >
|
||||
friend class permutation_iterator;
|
||||
|
||||
private:
|
||||
using super_t = iterator_adaptor<
|
||||
permutation_iterator< ElementIterator, IndexIterator >,
|
||||
IndexIterator,
|
||||
typename std::iterator_traits< ElementIterator >::value_type,
|
||||
use_default,
|
||||
typename std::iterator_traits< ElementIterator >::reference
|
||||
>;
|
||||
|
||||
public:
|
||||
permutation_iterator() :
|
||||
m_elt_iter()
|
||||
{}
|
||||
|
||||
explicit permutation_iterator(ElementIterator x, IndexIterator y) :
|
||||
super_t(y),
|
||||
m_elt_iter(x)
|
||||
{}
|
||||
|
||||
template<
|
||||
typename OtherElementIterator,
|
||||
typename OtherIndexIterator,
|
||||
typename = enable_if_convertible_t< OtherElementIterator, ElementIterator >,
|
||||
typename = enable_if_convertible_t< OtherIndexIterator, IndexIterator >
|
||||
>
|
||||
permutation_iterator(permutation_iterator< OtherElementIterator, OtherIndexIterator > const& r) :
|
||||
super_t(r.base()),
|
||||
m_elt_iter(r.m_elt_iter)
|
||||
{}
|
||||
|
||||
private:
|
||||
typename super_t::reference dereference() const { return *(m_elt_iter + *this->base()); }
|
||||
|
||||
private:
|
||||
ElementIterator m_elt_iter;
|
||||
};
|
||||
|
||||
|
||||
template< typename ElementIterator, typename IndexIterator >
|
||||
inline permutation_iterator< ElementIterator, IndexIterator > make_permutation_iterator(ElementIterator e, IndexIterator i)
|
||||
{
|
||||
return permutation_iterator< ElementIterator, IndexIterator >(e, i);
|
||||
}
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::permutation_iterator;
|
||||
using iterators::make_permutation_iterator;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_PERMUTATION_ITERATOR_HPP_INCLUDED_
|
||||
76
include/boost/iterator/reverse_iterator.hpp
Normal file
76
include/boost/iterator/reverse_iterator.hpp
Normal file
@@ -0,0 +1,76 @@
|
||||
// (C) Copyright David Abrahams 2002.
|
||||
// (C) Copyright Jeremy Siek 2002.
|
||||
// (C) Copyright Thomas Witt 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_ITERATOR_REVERSE_ITERATOR_23022003THW_HPP
|
||||
#define BOOST_ITERATOR_REVERSE_ITERATOR_23022003THW_HPP
|
||||
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/iterator/enable_if_convertible.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
template< typename Iterator >
|
||||
class reverse_iterator :
|
||||
public iterator_adaptor< reverse_iterator< Iterator >, Iterator >
|
||||
{
|
||||
friend class iterator_core_access;
|
||||
|
||||
private:
|
||||
using super_t = iterator_adaptor< reverse_iterator< Iterator >, Iterator >;
|
||||
|
||||
public:
|
||||
reverse_iterator() = default;
|
||||
|
||||
explicit reverse_iterator(Iterator x) :
|
||||
super_t(x)
|
||||
{}
|
||||
|
||||
template<
|
||||
typename OtherIterator,
|
||||
typename = enable_if_convertible_t< OtherIterator, Iterator >
|
||||
>
|
||||
reverse_iterator(reverse_iterator< OtherIterator > const& r) :
|
||||
super_t(r.base())
|
||||
{}
|
||||
|
||||
private:
|
||||
typename super_t::reference dereference() const
|
||||
{
|
||||
Iterator it = this->base_reference();
|
||||
--it;
|
||||
return *it;
|
||||
}
|
||||
|
||||
void increment() { --this->base_reference(); }
|
||||
void decrement() { ++this->base_reference(); }
|
||||
|
||||
void advance(typename super_t::difference_type n)
|
||||
{
|
||||
this->base_reference() -= n;
|
||||
}
|
||||
|
||||
template< typename OtherIterator >
|
||||
typename super_t::difference_type distance_to(reverse_iterator< OtherIterator > const& y) const
|
||||
{
|
||||
return this->base_reference() - y.base();
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Iterator >
|
||||
inline reverse_iterator< Iterator > make_reverse_iterator(Iterator x)
|
||||
{
|
||||
return reverse_iterator< Iterator >(x);
|
||||
}
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::reverse_iterator;
|
||||
using iterators::make_reverse_iterator;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_REVERSE_ITERATOR_23022003THW_HPP
|
||||
117
include/boost/iterator/shared_container_iterator.hpp
Normal file
117
include/boost/iterator/shared_container_iterator.hpp
Normal file
@@ -0,0 +1,117 @@
|
||||
// (C) Copyright Ronald Garcia 2002. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// See http://www.boost.org/libs/utility/shared_container_iterator.html for documentation.
|
||||
|
||||
#ifndef BOOST_ITERATOR_SHARED_CONTAINER_ITERATOR_HPP_INCLUDED_
|
||||
#define BOOST_ITERATOR_SHARED_CONTAINER_ITERATOR_HPP_INCLUDED_
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
// For backward compatibility with boost::shared_ptr
|
||||
template< class T >
|
||||
class shared_ptr;
|
||||
|
||||
namespace iterators {
|
||||
namespace detail {
|
||||
|
||||
// Fake deleter that holds an instance of boost::shared_ptr and through it keeps the pointed object from deletion
|
||||
template< typename T >
|
||||
class shared_container_iterator_bsptr_holder
|
||||
{
|
||||
private:
|
||||
boost::shared_ptr< T > m_ptr;
|
||||
|
||||
public:
|
||||
explicit shared_container_iterator_bsptr_holder(boost::shared_ptr< T > const& ptr) :
|
||||
m_ptr(ptr)
|
||||
{}
|
||||
|
||||
void operator()(T*) const noexcept {}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template< typename Container >
|
||||
class shared_container_iterator :
|
||||
public iterator_adaptor<
|
||||
shared_container_iterator< Container >,
|
||||
typename Container::iterator
|
||||
>
|
||||
{
|
||||
private:
|
||||
using super_t = iterator_adaptor<
|
||||
shared_container_iterator< Container >,
|
||||
typename Container::iterator
|
||||
>;
|
||||
|
||||
using iterator_t = typename Container::iterator;
|
||||
using container_ref_t = std::shared_ptr< Container >;
|
||||
|
||||
public:
|
||||
shared_container_iterator() = default;
|
||||
|
||||
shared_container_iterator(iterator_t const& x, container_ref_t const& c) :
|
||||
super_t(x),
|
||||
m_container_ref(c)
|
||||
{}
|
||||
|
||||
// Constructor for backward compatibility with boost::shared_ptr
|
||||
shared_container_iterator(iterator_t const& x, boost::shared_ptr< Container > const& c) :
|
||||
super_t(x),
|
||||
m_container_ref(c.get(), detail::shared_container_iterator_bsptr_holder< Container >(c))
|
||||
{}
|
||||
|
||||
private:
|
||||
container_ref_t m_container_ref;
|
||||
};
|
||||
|
||||
template< typename Container >
|
||||
inline shared_container_iterator< Container >
|
||||
make_shared_container_iterator(typename Container::iterator iter, std::shared_ptr< Container > const& container)
|
||||
{
|
||||
return shared_container_iterator< Container >(iter, container);
|
||||
}
|
||||
|
||||
template< typename Container >
|
||||
inline std::pair< shared_container_iterator< Container >, shared_container_iterator< Container > >
|
||||
make_shared_container_range(std::shared_ptr< Container > const& container)
|
||||
{
|
||||
return std::make_pair
|
||||
(
|
||||
iterators::make_shared_container_iterator(container->begin(), container),
|
||||
iterators::make_shared_container_iterator(container->end(), container)
|
||||
);
|
||||
}
|
||||
|
||||
// Factory functions for backward compatibility with boost::shared_ptr
|
||||
template< typename Container >
|
||||
inline shared_container_iterator< Container >
|
||||
make_shared_container_iterator(typename Container::iterator iter, boost::shared_ptr< Container > const& container)
|
||||
{
|
||||
return shared_container_iterator< Container >(iter, container);
|
||||
}
|
||||
|
||||
template< typename Container >
|
||||
inline std::pair< shared_container_iterator< Container >, shared_container_iterator< Container > >
|
||||
make_shared_container_range(boost::shared_ptr< Container > const& container)
|
||||
{
|
||||
std::shared_ptr< Container > c(container.get(), detail::shared_container_iterator_bsptr_holder< Container >(container));
|
||||
return iterators::make_shared_container_range(std::move(c));
|
||||
}
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::shared_container_iterator;
|
||||
using iterators::make_shared_container_iterator;
|
||||
using iterators::make_shared_container_range;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_SHARED_CONTAINER_ITERATOR_HPP_INCLUDED_
|
||||
146
include/boost/iterator/transform_iterator.hpp
Normal file
146
include/boost/iterator/transform_iterator.hpp
Normal file
@@ -0,0 +1,146 @@
|
||||
// (C) Copyright David Abrahams 2002.
|
||||
// (C) Copyright Jeremy Siek 2002.
|
||||
// (C) Copyright Thomas Witt 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_ITERATOR_TRANSFORM_ITERATOR_23022003THW_HPP
|
||||
#define BOOST_ITERATOR_TRANSFORM_ITERATOR_23022003THW_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/core/use_default.hpp>
|
||||
#include <boost/core/empty_value.hpp>
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/iterator/enable_if_convertible.hpp>
|
||||
#include <boost/iterator/detail/eval_if_default.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
template<
|
||||
typename UnaryFunction,
|
||||
typename Iterator,
|
||||
typename Reference = use_default,
|
||||
typename Value = use_default
|
||||
>
|
||||
class transform_iterator;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template< typename UnaryFunc, typename Iterator >
|
||||
struct transform_iterator_default_reference
|
||||
{
|
||||
using type = decltype(std::declval< UnaryFunc const& >()(std::declval< typename std::iterator_traits< Iterator >::reference >()));
|
||||
};
|
||||
|
||||
// Compute the iterator_adaptor instantiation to be used for transform_iterator
|
||||
template< typename UnaryFunc, typename Iterator, typename Reference, typename Value >
|
||||
struct transform_iterator_base
|
||||
{
|
||||
private:
|
||||
// By default, dereferencing the iterator yields the same as
|
||||
// the function.
|
||||
using reference = detail::eval_if_default_t<
|
||||
Reference,
|
||||
transform_iterator_default_reference< UnaryFunc, Iterator >
|
||||
>;
|
||||
|
||||
// To get the default for Value: remove any reference on the
|
||||
// result type, but retain any constness to signal
|
||||
// non-writability. Note that if we adopt Thomas' suggestion
|
||||
// to key non-writability *only* on the Reference argument,
|
||||
// we'd need to strip constness here as well.
|
||||
using cv_value_type = detail::eval_if_default_t<
|
||||
Value,
|
||||
std::remove_reference< reference >
|
||||
>;
|
||||
|
||||
public:
|
||||
using type = iterator_adaptor<
|
||||
transform_iterator< UnaryFunc, Iterator, Reference, Value >,
|
||||
Iterator,
|
||||
cv_value_type,
|
||||
use_default, // Leave the traversal category alone
|
||||
reference
|
||||
>;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template< typename UnaryFunc, typename Iterator, typename Reference, typename Value >
|
||||
class transform_iterator :
|
||||
public detail::transform_iterator_base< UnaryFunc, Iterator, Reference, Value >::type,
|
||||
private boost::empty_value< UnaryFunc >
|
||||
{
|
||||
friend class iterator_core_access;
|
||||
|
||||
private:
|
||||
using super_t = typename detail::transform_iterator_base< UnaryFunc, Iterator, Reference, Value >::type;
|
||||
using functor_base = boost::empty_value< UnaryFunc >;
|
||||
|
||||
public:
|
||||
transform_iterator() = default;
|
||||
|
||||
transform_iterator(Iterator const& x, UnaryFunc f) :
|
||||
super_t(x),
|
||||
functor_base(boost::empty_init_t{}, f)
|
||||
{}
|
||||
|
||||
// don't provide this constructor if UnaryFunc is a
|
||||
// function pointer type, since it will be 0. Too dangerous.
|
||||
template< bool Requires = std::is_class< UnaryFunc >::value, typename = typename std::enable_if< Requires >::type >
|
||||
explicit transform_iterator(Iterator const& x) :
|
||||
super_t(x)
|
||||
{}
|
||||
|
||||
template<
|
||||
typename OtherUnaryFunction,
|
||||
typename OtherIterator,
|
||||
typename OtherReference,
|
||||
typename OtherValue,
|
||||
typename = enable_if_convertible_t< OtherIterator, Iterator >,
|
||||
typename = enable_if_convertible_t< OtherUnaryFunction, UnaryFunc >
|
||||
>
|
||||
transform_iterator(transform_iterator< OtherUnaryFunction, OtherIterator, OtherReference, OtherValue > const& t) :
|
||||
super_t(t.base()),
|
||||
functor_base(boost::empty_init_t{}, t.functor())
|
||||
{}
|
||||
|
||||
UnaryFunc functor() const { return functor_base::get(); }
|
||||
|
||||
private:
|
||||
typename super_t::reference dereference() const { return functor_base::get()(*this->base()); }
|
||||
};
|
||||
|
||||
template< typename UnaryFunc, typename Iterator >
|
||||
inline transform_iterator< UnaryFunc, Iterator > make_transform_iterator(Iterator it, UnaryFunc fun)
|
||||
{
|
||||
return transform_iterator< UnaryFunc, Iterator >(it, fun);
|
||||
}
|
||||
|
||||
// Version which allows explicit specification of the UnaryFunc
|
||||
// type.
|
||||
//
|
||||
// This generator is not provided if UnaryFunc is a function
|
||||
// pointer type, because it's too dangerous: the default-constructed
|
||||
// function pointer in the iterator be 0, leading to a runtime
|
||||
// crash.
|
||||
template< typename UnaryFunc, typename Iterator >
|
||||
inline typename std::enable_if<
|
||||
std::is_class< UnaryFunc >::value, // We should probably find a cheaper test than is_class<>
|
||||
transform_iterator< UnaryFunc, Iterator >
|
||||
>::type make_transform_iterator(Iterator it)
|
||||
{
|
||||
return transform_iterator< UnaryFunc, Iterator >(it);
|
||||
}
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::transform_iterator;
|
||||
using iterators::make_transform_iterator;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_TRANSFORM_ITERATOR_23022003THW_HPP
|
||||
368
include/boost/iterator/zip_iterator.hpp
Normal file
368
include/boost/iterator/zip_iterator.hpp
Normal file
@@ -0,0 +1,368 @@
|
||||
// Copyright David Abrahams and Thomas Becker 2000-2006.
|
||||
// Copyright Kohei Takahashi 2012-2014.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_
|
||||
#define BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_
|
||||
|
||||
#include <utility> // for std::pair
|
||||
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/iterator/enable_if_convertible.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/iterator/min_category.hpp>
|
||||
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <boost/fusion/adapted/boost_tuple.hpp> // for backward compatibility
|
||||
#include <boost/fusion/algorithm/iteration/for_each.hpp>
|
||||
#include <boost/fusion/algorithm/transformation/transform.hpp>
|
||||
#include <boost/fusion/sequence/convert.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/at_c.hpp>
|
||||
#include <boost/fusion/sequence/comparison/equal_to.hpp>
|
||||
#include <boost/fusion/support/tag_of_fwd.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
// Forward declarations for Boost.Tuple support
|
||||
namespace tuples {
|
||||
struct null_type;
|
||||
template< class, class >
|
||||
struct cons;
|
||||
} // namespace tuples
|
||||
|
||||
// Forward declarations for Boost.Fusion support
|
||||
namespace fusion {
|
||||
struct void_;
|
||||
} // namespace fusion
|
||||
|
||||
namespace iterators {
|
||||
|
||||
// Zip iterator forward declaration for zip_iterator_base
|
||||
template< typename IteratorTuple >
|
||||
class zip_iterator;
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Functors to be used with tuple algorithms
|
||||
//
|
||||
template< typename DiffType >
|
||||
class advance_iterator
|
||||
{
|
||||
public:
|
||||
advance_iterator(DiffType step) :
|
||||
m_step(step)
|
||||
{}
|
||||
|
||||
template< typename Iterator >
|
||||
void operator()(Iterator& it) const { it += m_step; }
|
||||
|
||||
private:
|
||||
DiffType m_step;
|
||||
};
|
||||
|
||||
struct increment_iterator
|
||||
{
|
||||
template< typename Iterator >
|
||||
void operator()(Iterator& it) const { ++it; }
|
||||
};
|
||||
|
||||
struct decrement_iterator
|
||||
{
|
||||
template< typename Iterator >
|
||||
void operator()(Iterator& it) const { --it; }
|
||||
};
|
||||
|
||||
struct dereference_iterator
|
||||
{
|
||||
template< typename >
|
||||
struct result;
|
||||
|
||||
template< typename This, typename Iterator >
|
||||
struct result< This(Iterator) >
|
||||
{
|
||||
using type = iterator_reference_t<
|
||||
typename std::remove_cv< typename std::remove_reference< Iterator >::type >::type
|
||||
>;
|
||||
};
|
||||
|
||||
template< typename Iterator >
|
||||
typename result< dereference_iterator(Iterator) >::type operator()(Iterator const& it) const
|
||||
{
|
||||
return *it;
|
||||
}
|
||||
};
|
||||
|
||||
// The trait checks if the type is a trailing "null" type used to indicate unused template parameters in non-variadic types
|
||||
template< typename T >
|
||||
struct is_trailing_null_type : std::false_type {};
|
||||
template< typename T >
|
||||
struct is_trailing_null_type< const T > : is_trailing_null_type< T > {};
|
||||
template< >
|
||||
struct is_trailing_null_type< tuples::null_type > : std::true_type {};
|
||||
template< >
|
||||
struct is_trailing_null_type< fusion::void_ > : std::true_type {};
|
||||
|
||||
// Metafunction to obtain the type of the tuple whose element types
|
||||
// are the reference types of an iterator tuple.
|
||||
template< typename IteratorTuple >
|
||||
struct tuple_of_references;
|
||||
|
||||
template< typename IteratorTuple >
|
||||
using tuple_of_references_t = typename tuple_of_references< IteratorTuple >::type;
|
||||
|
||||
template< template< typename... > class Tuple, typename... Iterators >
|
||||
struct tuple_of_references< Tuple< Iterators... > >
|
||||
{
|
||||
// Note: non-variadic Boost.Tuple and Boost.Fusion need special handling
|
||||
// to avoid instantiating iterator traits on the trailing "null" types.
|
||||
// If not that, we could simply do
|
||||
// mp11::mp_transform< iterator_reference_t, IteratorTuple >.
|
||||
using type = Tuple<
|
||||
mp11::mp_eval_if<
|
||||
detail::is_trailing_null_type< Iterators >,
|
||||
Iterators,
|
||||
iterator_reference_t, Iterators
|
||||
>...
|
||||
>;
|
||||
};
|
||||
|
||||
template< typename Front, typename Tail >
|
||||
struct tuple_of_references< tuples::cons< Front, Tail > >
|
||||
{
|
||||
using type = tuples::cons<
|
||||
iterator_reference_t< Front >,
|
||||
mp11::mp_eval_if<
|
||||
detail::is_trailing_null_type< Tail >,
|
||||
Tail,
|
||||
detail::tuple_of_references_t, Tail
|
||||
>
|
||||
>;
|
||||
};
|
||||
|
||||
// Metafunction to obtain the minimal traversal tag in a list
|
||||
// of iterators.
|
||||
template< typename IteratorList >
|
||||
struct minimum_traversal_category_in_iterator_list;
|
||||
|
||||
template< typename IteratorList >
|
||||
using minimum_traversal_category_in_iterator_list_t = typename minimum_traversal_category_in_iterator_list< IteratorList >::type;
|
||||
|
||||
template< template< typename... > class List, typename... Iterators >
|
||||
struct minimum_traversal_category_in_iterator_list< List< Iterators... > >
|
||||
{
|
||||
// Note: non-variadic Boost.Tuple and Boost.Fusion need special handling
|
||||
// to avoid instantiating iterator traits on the trailing "null" types.
|
||||
// For such types just use random_access_traversal_tag, which will not
|
||||
// affect the result of min_category.
|
||||
using type = min_category_t<
|
||||
mp11::mp_eval_if<
|
||||
detail::is_trailing_null_type< Iterators >,
|
||||
random_access_traversal_tag,
|
||||
pure_iterator_traversal_t, Iterators
|
||||
>...
|
||||
>;
|
||||
};
|
||||
|
||||
template< typename FrontTraversal, typename Tail >
|
||||
using minimum_traversal_category_in_tail_t = min_category_t<
|
||||
FrontTraversal,
|
||||
minimum_traversal_category_in_iterator_list_t< Tail >
|
||||
>;
|
||||
|
||||
template< typename Front, typename Tail >
|
||||
struct minimum_traversal_category_in_iterator_list< tuples::cons< Front, Tail > >
|
||||
{
|
||||
using front_traversal = pure_iterator_traversal_t< Front >;
|
||||
|
||||
using type = mp11::mp_eval_if<
|
||||
detail::is_trailing_null_type< Tail >,
|
||||
front_traversal,
|
||||
minimum_traversal_category_in_tail_t,
|
||||
front_traversal,
|
||||
Tail
|
||||
>;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Class zip_iterator_base
|
||||
//
|
||||
// Builds and exposes the iterator facade type from which the zip
|
||||
// iterator will be derived.
|
||||
//
|
||||
template< typename IteratorTuple >
|
||||
struct zip_iterator_base
|
||||
{
|
||||
private:
|
||||
// Reference type is the type of the tuple obtained from the
|
||||
// iterators' reference types.
|
||||
using reference = detail::tuple_of_references_t< IteratorTuple >;
|
||||
|
||||
// Value type is the same as reference type.
|
||||
using value_type = reference;
|
||||
|
||||
// Difference type is the first iterator's difference type
|
||||
using difference_type = iterator_difference_t< mp11::mp_front< IteratorTuple > >;
|
||||
|
||||
// Traversal catetgory is the minimum traversal category in the
|
||||
// iterator tuple.
|
||||
using traversal_category = detail::minimum_traversal_category_in_iterator_list_t< IteratorTuple >;
|
||||
|
||||
public:
|
||||
// The iterator facade type from which the zip iterator will
|
||||
// be derived.
|
||||
using type = iterator_facade<
|
||||
zip_iterator< IteratorTuple >,
|
||||
value_type,
|
||||
traversal_category,
|
||||
reference,
|
||||
difference_type
|
||||
>;
|
||||
};
|
||||
|
||||
template< typename Reference >
|
||||
struct converter
|
||||
{
|
||||
template< typename Seq >
|
||||
static Reference call(Seq seq)
|
||||
{
|
||||
using tag = typename fusion::traits::tag_of< Reference >::type;
|
||||
return fusion::convert< tag >(seq);
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Reference1, typename Reference2 >
|
||||
struct converter< std::pair< Reference1, Reference2 > >
|
||||
{
|
||||
using reference = std::pair< Reference1, Reference2 >;
|
||||
|
||||
template< typename Seq >
|
||||
static reference call(Seq seq)
|
||||
{
|
||||
return reference(fusion::at_c< 0 >(seq), fusion::at_c< 1 >(seq));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// zip_iterator class definition
|
||||
//
|
||||
template< typename IteratorTuple >
|
||||
class zip_iterator :
|
||||
public detail::zip_iterator_base< IteratorTuple >::type
|
||||
{
|
||||
// Typedef super_t as our base class.
|
||||
using super_t = typename detail::zip_iterator_base< IteratorTuple >::type;
|
||||
|
||||
// iterator_core_access is the iterator's best friend.
|
||||
friend class iterator_core_access;
|
||||
|
||||
public:
|
||||
// Construction
|
||||
// ============
|
||||
|
||||
// Default constructor
|
||||
zip_iterator() = default;
|
||||
|
||||
// Constructor from iterator tuple
|
||||
zip_iterator(IteratorTuple iterator_tuple) :
|
||||
m_iterator_tuple(iterator_tuple)
|
||||
{}
|
||||
|
||||
// Copy constructor
|
||||
template< typename OtherIteratorTuple, typename = enable_if_convertible_t< OtherIteratorTuple, IteratorTuple > >
|
||||
zip_iterator(zip_iterator< OtherIteratorTuple > const& other) :
|
||||
m_iterator_tuple(other.get_iterator_tuple())
|
||||
{}
|
||||
|
||||
// Get method for the iterator tuple.
|
||||
IteratorTuple const& get_iterator_tuple() const { return m_iterator_tuple; }
|
||||
|
||||
private:
|
||||
// Implementation of Iterator Operations
|
||||
// =====================================
|
||||
|
||||
// Dereferencing returns a tuple built from the dereferenced
|
||||
// iterators in the iterator tuple.
|
||||
typename super_t::reference dereference() const
|
||||
{
|
||||
using reference = typename super_t::reference;
|
||||
using gen = detail::converter< reference >;
|
||||
return gen::call(fusion::transform(get_iterator_tuple(), detail::dereference_iterator()));
|
||||
}
|
||||
|
||||
// Two zip iterators are equal if all iterators in the iterator
|
||||
// tuple are equal. NOTE: It should be possible to implement this
|
||||
// as
|
||||
//
|
||||
// return get_iterator_tuple() == other.get_iterator_tuple();
|
||||
//
|
||||
// but equality of tuples currently (7/2003) does not compile
|
||||
// under several compilers. No point in bringing in a bunch
|
||||
// of #ifdefs here.
|
||||
//
|
||||
template< typename OtherIteratorTuple >
|
||||
bool equal(zip_iterator< OtherIteratorTuple > const& other) const
|
||||
{
|
||||
return fusion::equal_to(get_iterator_tuple(), other.get_iterator_tuple());
|
||||
}
|
||||
|
||||
// Advancing a zip iterator means to advance all iterators in the
|
||||
// iterator tuple.
|
||||
void advance(typename super_t::difference_type n)
|
||||
{
|
||||
fusion::for_each(m_iterator_tuple, detail::advance_iterator< typename super_t::difference_type >(n));
|
||||
}
|
||||
|
||||
// Incrementing a zip iterator means to increment all iterators in
|
||||
// the iterator tuple.
|
||||
void increment()
|
||||
{
|
||||
fusion::for_each(m_iterator_tuple, detail::increment_iterator());
|
||||
}
|
||||
|
||||
// Decrementing a zip iterator means to decrement all iterators in
|
||||
// the iterator tuple.
|
||||
void decrement()
|
||||
{
|
||||
fusion::for_each(m_iterator_tuple, detail::decrement_iterator());
|
||||
}
|
||||
|
||||
// Distance is calculated using the first iterator in the tuple.
|
||||
template< typename OtherIteratorTuple >
|
||||
typename super_t::difference_type distance_to(zip_iterator< OtherIteratorTuple > const& other) const
|
||||
{
|
||||
return fusion::at_c< 0 >(other.get_iterator_tuple()) - fusion::at_c< 0 >(this->get_iterator_tuple());
|
||||
}
|
||||
|
||||
private:
|
||||
// Data Members
|
||||
// ============
|
||||
|
||||
// The iterator tuple.
|
||||
IteratorTuple m_iterator_tuple;
|
||||
};
|
||||
|
||||
// Make function for zip iterator
|
||||
//
|
||||
template< typename IteratorTuple >
|
||||
inline zip_iterator< IteratorTuple > make_zip_iterator(IteratorTuple t)
|
||||
{
|
||||
return zip_iterator< IteratorTuple >(t);
|
||||
}
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::zip_iterator;
|
||||
using iterators::make_zip_iterator;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user