This commit is contained in:
2026-03-23 20:54:41 +08:00
commit e13b3650e9
4596 changed files with 1015768 additions and 0 deletions

View 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

View 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

View 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

View 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

View 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_

View 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

View 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_

View 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_

View 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_

View 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_

View 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_

View 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

View 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_

View 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

View 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_

View 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_

View 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_

View 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

View 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

View 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_

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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_

View 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_

View 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

View 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_

View 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

View 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_

View 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

View 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