Mostly remove pre-CXX11 workarounds.

С++03 support was deprecated in 1.85 and now can be removed. This PR clears
many of workarounds, which are no longer needed now.

* Remove unused workaround macros (many of).
* Remove BOOST_STATIC_ASSERT usages.
* Minimize Boost::type_traits dependency (in favour of STL's type_traits).

Closes https://github.com/boostorg/iterator/pull/82.

Squashed commit of the following:

commit 741a627b73
Author: Georgy Guminov <gogagum@gmail.com>
Date:   Sat Jan 25 12:13:05 2025 +0300

    Replace testers with standard metafunctions.

commit bf4cce6114
Author: Georgy Guminov <gogagum@gmail.com>
Date:   Sat Jan 25 11:51:32 2025 +0300

    Refactor is_lvalue_iterator.hpp.

commit 8d080c6c58
Author: Georgy Guminov <gogagum@gmail.com>
Date:   Sat Jan 25 10:27:32 2025 +0300

    Remove more workarounds.

commit 5a4ba24d36
Author: Georgy Guminov <gogagum@gmail.com>
Date:   Sun Jan 19 16:38:30 2025 +0300

    Fixes.

commit fdfafce2b9
Author: Georgy Guminov <gogagum@gmail.com>
Date:   Sat Oct 26 15:06:43 2024 +0300

    Remove BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
    Correct static_assert messages.
    Fix messages & replace is_standard_layout with is_copy_constructible.

commit c69ac1408a
Author: Georgy Guminov <gogagum@gmail.com>
Date:   Sat Oct 26 14:48:51 2024 +0300

    Correct static_assert messages.

commit b5df827151
Author: Georqy Guminov <gogagum@gmail.com>
Date:   Sun Jun 23 16:12:29 2024 +0300

    Fixes. Remove some Boost.MPL usages. Remove unused includes.

commit 01fd35e9f8
Author: Georgiy Guminov <gogagum@gmail.com>
Date:   Wed Jun 12 17:14:21 2024 +0300

    abstract conjunction.

commit c02def8acf
Author: Georgiy Guminov <gogagum@gmail.com>
Date:   Wed Jun 12 16:35:43 2024 +0300

    return addressof & conjunction.

commit 3b3d162575
Author: Georgiy Guminov <gogagum@gmail.com>
Date:   Wed Jun 12 16:30:44 2024 +0300

    Make macro more readable.

commit 4ab19e045f
Author: Georgiy Guminov <gogagum@gmail.com>
Date:   Wed Jun 12 15:56:49 2024 +0300

    Add static_assert messages.

commit 82b5c44cd3
Author: Georgiy Guminov <gogagum@gmail.com>
Date:   Wed Jun 12 14:12:10 2024 +0300

    Return is iterator CXX17 test.

commit 2d58d65462
Author: Georgiy Guminov <gogagum@gmail.com>
Date:   Tue Jun 11 14:04:17 2024 +0300

    Omitted.

commit a0d04d9491
Author: Georgiy Guminov <gogagum@gmail.com>
Date:   Tue Jun 11 14:00:35 2024 +0300

    Replace move with static_cast

commit 4a49b8a1a2
Author: Georgiy Guminov <gogagum@gmail.com>
Date:   Mon Jun 10 21:38:53 2024 +0300

    Return BOOST_NOEXCEPT

commit 054c013bba
Author: Georgiy Guminov <gogagum@gmail.com>
Date:   Sun Jun 9 15:20:41 2024 +0300

    CXX11
This commit is contained in:
Georgy Guminov
2025-01-26 15:21:16 +03:00
committed by Andrey Semashev
parent 53101ffab9
commit f9effffb6d
56 changed files with 683 additions and 1181 deletions
+71 -198
View File
@@ -8,37 +8,24 @@
#define BOOST_ITERATOR_FACADE_23022003THW_HPP
#include <boost/config.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/enable_if.hpp>
#include <boost/static_assert.hpp>
#include <boost/core/addressof.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/add_pointer.hpp>
#include <boost/type_traits/add_lvalue_reference.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_pod.hpp>
#include <boost/iterator/detail/type_traits/conjunction.hpp>
#include <boost/iterator/detail/type_traits/negation.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/always.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/if.hpp>
#include <cstddef>
#include <boost/iterator/detail/config_def.hpp> // this goes last
#include <type_traits>
#include <memory>
namespace boost {
namespace iterators {
@@ -64,7 +51,7 @@ namespace iterators {
// 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 boost::is_convertible< typename iterator_category_to_traversal< CategoryOrTraversal >::type, Required >
public std::is_convertible< typename iterator_category_to_traversal< CategoryOrTraversal >::type, Required >
{};
//
@@ -76,8 +63,8 @@ namespace iterators {
, class Return
>
struct enable_if_interoperable :
public boost::iterators::enable_if<
is_interoperable< Facade1, Facade2 >
public std::enable_if<
is_interoperable<Facade1, Facade2>::value
, Return
>
{};
@@ -91,12 +78,12 @@ namespace iterators {
, class Return
>
struct enable_if_interoperable_and_random_access_traversal :
public boost::iterators::enable_if<
mpl::and_<
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
>
{};
@@ -117,31 +104,14 @@ namespace iterators {
CategoryOrTraversal, ValueParam, Reference
>::type iterator_category;
typedef typename remove_const<ValueParam>::type value_type;
typedef typename std::remove_const<ValueParam>::type value_type;
// Not the real associated pointer type
typedef typename mpl::eval_if<
boost::iterators::detail::iterator_writability_disabled<ValueParam,Reference>
, add_pointer<const value_type>
, add_pointer<value_type>
, std::add_pointer<const value_type>
, std::add_pointer<value_type>
>::type pointer;
# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
&& (BOOST_WORKAROUND(_STLPORT_VERSION, BOOST_TESTED_AT(0x452)) \
|| BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(310))) \
|| BOOST_WORKAROUND(BOOST_RWSTD_VER, BOOST_TESTED_AT(0x20101)) \
|| BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, <= 310)
// To interoperate with some broken library/compiler
// combinations, user-defined iterators must be derived from
// std::iterator. It is possible to implement a standard
// library for broken compilers without this limitation.
# define BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE 1
typedef
iterator<iterator_category, value_type, Difference, pointer, Reference>
base;
# endif
};
// iterators whose dereference operators reference the same value
@@ -180,7 +150,7 @@ namespace iterators {
// Provides (r++)->foo()
value_type* operator->() const
{
return boost::addressof(stored_value);
return std::addressof(stored_value);
}
private:
@@ -240,38 +210,15 @@ namespace iterators {
}
// Provides writability of *r++
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <class T>
typename iterators::enable_if<
is_not_writable_postfix_increment_dereference_proxy< 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;
}
#else
template <class T>
typename iterators::enable_if<
is_not_writable_postfix_increment_dereference_proxy< T >,
writable_postfix_increment_dereference_proxy const&
>::type operator=(T const& x) const
{
*this->stored_iterator = x;
return *this;
}
// This overload just in case only non-const objects are writable
template <class T>
typename iterators::enable_if<
is_not_writable_postfix_increment_dereference_proxy< T >,
writable_postfix_increment_dereference_proxy const&
>::type operator=(T& x) const
{
*this->stored_iterator = x;
return *this;
}
#endif
private:
Iterator stored_iterator;
@@ -303,49 +250,21 @@ namespace iterators {
// Provides (r++)->foo()
value_type* operator->() const
{
return boost::addressof(dereference_proxy.stored_value);
return std::addressof(dereference_proxy.stored_value);
}
private:
writable_postfix_increment_dereference_proxy<Iterator> dereference_proxy;
};
# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class Reference, class Value>
struct is_non_proxy_reference_impl
{
static Reference r;
template <class R>
static typename mpl::if_<
is_convertible<
R const volatile*
, Value const volatile*
>
, char[1]
, char[2]
>::type& helper(R const&);
BOOST_STATIC_CONSTANT(bool, value = sizeof(helper(r)) == 1);
};
template <class Reference, class Value>
struct is_non_proxy_reference
: mpl::bool_<
is_non_proxy_reference_impl<Reference, Value>::value
>
{};
# else
template <class Reference, class Value>
struct is_non_proxy_reference
: is_convertible<
typename remove_reference<Reference>::type
: std::is_convertible<
typename std::remove_reference<Reference>::type
const volatile*
, Value const volatile*
>
{};
# endif
// A metafunction to choose the result type of postfix ++
//
@@ -365,22 +284,22 @@ namespace iterators {
template <class Iterator, class Value, class Reference, class CategoryOrTraversal>
struct postfix_increment_result
: mpl::eval_if<
mpl::and_<
detail::conjunction<
// A proxy is only needed for readable iterators
is_convertible<
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 add_lvalue_reference<Value const>::type
, typename std::add_lvalue_reference<Value const>::type
>
// No multipass iterator can have values that disappear
// before positions can be re-visited
, mpl::not_<
is_convertible<
, detail::negation<
std::is_convertible<
typename iterator_category_to_traversal<CategoryOrTraversal>::type
, forward_traversal_tag
>
@@ -404,15 +323,15 @@ namespace iterators {
{
struct proxy
{
explicit proxy(Reference const & x) : m_ref(x) {}
Reference* operator->() { return boost::addressof(m_ref); }
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 boost::addressof(m_ref); }
operator Reference*() { return std::addressof(m_ref); }
Reference m_ref;
};
typedef proxy result_type;
static result_type apply(Reference const & x)
static result_type apply(Reference const& x)
{
return result_type(x);
}
@@ -424,7 +343,7 @@ namespace iterators {
typedef Pointer result_type;
static result_type apply(T& x)
{
return boost::addressof(x);
return std::addressof(x);
}
};
@@ -463,11 +382,10 @@ namespace iterators {
// proxy, or whether it can simply return a copy of the value_type.
template <class ValueType, class Reference>
struct use_operator_brackets_proxy
: mpl::not_<
mpl::and_<
// Really we want an is_copy_constructible trait here,
// but is_POD will have to suffice in the meantime.
boost::is_POD<ValueType>
: detail::negation<
detail::conjunction<
std::is_copy_constructible<ValueType>
, std::is_trivial<ValueType>
, iterator_writability_disabled<ValueType,Reference>
>
>
@@ -476,41 +394,34 @@ namespace iterators {
template <class Iterator, class Value, class Reference>
struct operator_brackets_result
{
typedef typename mpl::if_<
use_operator_brackets_proxy<Value,Reference>
typedef typename std::conditional<
use_operator_brackets_proxy<Value,Reference>::value
, operator_brackets_proxy<Iterator>
, Value
>::type type;
};
template <class Iterator>
operator_brackets_proxy<Iterator> make_operator_brackets_result(Iterator const& iter, mpl::true_)
operator_brackets_proxy<Iterator> make_operator_brackets_result(Iterator const& iter, std::true_type)
{
return operator_brackets_proxy<Iterator>(iter);
}
template <class Iterator>
typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, mpl::false_)
typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, std::false_type)
{
return *iter;
return *iter;
}
struct choose_difference_type
{
template <class I1, class I2>
struct apply
:
# ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
iterator_difference<I1>
# else
mpl::eval_if<
is_convertible<I2,I1>
, iterator_difference<I1>
, iterator_difference<I2>
>
# endif
struct apply : mpl::eval_if<
std::is_convertible<I2,I1>
, iterator_difference<I1>
, iterator_difference<I2>
>
{};
};
template <
@@ -528,17 +439,6 @@ namespace iterators {
// Macros which describe the declarations of binary operators
# ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
# define BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, enabler) \
template < \
class Derived1, class V1, class TC1, class Reference1, class Difference1 \
, class Derived2, class V2, class TC2, class Reference2, class Difference2 \
> \
prefix typename mpl::apply2<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)
# else
# define BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, enabler) \
template < \
class Derived1, class V1, class TC1, class Reference1, class Difference1 \
@@ -551,7 +451,6 @@ namespace iterators {
operator op( \
iterator_facade<Derived1, V1, TC1, Reference1, Difference1> const& lhs \
, iterator_facade<Derived2, V2, TC2, Reference2, Difference2> const& rhs)
# endif
# 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)
@@ -561,9 +460,12 @@ namespace iterators {
# define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \
template <class Derived, class V, class TC, class R, class D> \
prefix typename boost::iterators::enable_if< \
boost::iterators::detail::is_traversal_at_least< TC, boost::iterators::random_access_traversal_tag >, \
Derived \
prefix typename std::enable_if< \
boost::iterators::detail::is_traversal_at_least< \
TC \
, boost::iterators::random_access_traversal_tag \
>::value \
, Derived \
>::type operator+ args
//
@@ -577,12 +479,6 @@ namespace iterators {
//
class iterator_core_access
{
# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
// Tasteless as this may seem, making all members public allows member templates
// to work in the absence of member template friends.
public:
# else
template <class I, class V, class TC, class R, class D> friend class iterator_facade;
template <class I, class V, class TC, class R, class D, bool IsBidirectionalTraversal, bool IsRandomAccessTraversal>
friend class detail::iterator_facade_base;
@@ -623,8 +519,6 @@ namespace iterators {
)
;
# endif
template <class Facade>
static typename Facade::reference dereference(Facade const& f)
{
@@ -644,13 +538,13 @@ namespace iterators {
}
template <class Facade1, class Facade2>
static bool equal(Facade1 const& f1, Facade2 const& f2, mpl::true_)
static bool equal(Facade1 const& f1, Facade2 const& f2, std::true_type)
{
return f1.equal(f2);
}
template <class Facade1, class Facade2>
static bool equal(Facade1 const& f1, Facade2 const& f2, mpl::false_)
static bool equal(Facade1 const& f1, Facade2 const& f2, std::false_type)
{
return f2.equal(f1);
}
@@ -663,14 +557,14 @@ namespace iterators {
template <class Facade1, class Facade2>
static typename Facade1::difference_type distance_from(
Facade1 const& f1, Facade2 const& f2, mpl::true_)
Facade1 const& f1, Facade2 const& f2, std::true_type)
{
return -f1.distance_to(f2);
}
template <class Facade1, class Facade2>
static typename Facade2::difference_type distance_from(
Facade1 const& f1, Facade2 const& f2, mpl::false_)
Facade1 const& f1, Facade2 const& f2, std::false_type)
{
return f2.distance_to(f1);
}
@@ -705,12 +599,6 @@ namespace iterators {
, class Difference
>
class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false >
# ifdef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
: public boost::iterators::detail::iterator_facade_types<
Value, CategoryOrTraversal, Reference, Difference
>::base
# undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
# endif
{
private:
typedef boost::iterators::detail::iterator_facade_types<
@@ -811,11 +699,11 @@ namespace iterators {
typename boost::iterators::detail::operator_brackets_result<Derived, Value, reference>::type
operator[](difference_type n) const
{
typedef boost::iterators::detail::use_operator_brackets_proxy<Value, Reference> use_proxy;
using use_proxy = boost::iterators::detail::use_operator_brackets_proxy<Value, Reference>;
return boost::iterators::detail::make_operator_brackets_result<Derived>(
this->derived() + n
, use_proxy()
, std::integral_constant<bool, use_proxy::value>{}
);
}
@@ -950,19 +838,11 @@ namespace iterators {
// ----------------
//
# ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
# define BOOST_ITERATOR_CONVERTIBLE(a,b) mpl::true_()
# else
# define BOOST_ITERATOR_CONVERTIBLE(a,b) is_convertible<a,b>()
# endif
# define BOOST_ITERATOR_CONVERTIBLE(a,b) std::is_convertible<a,b>()
# define BOOST_ITERATOR_FACADE_INTEROP(op, result_type, return_prefix, base_op) \
BOOST_ITERATOR_FACADE_INTEROP_HEAD(inline, op, result_type) \
{ \
/* For those compilers that do not support enable_if */ \
BOOST_STATIC_ASSERT(( \
is_interoperable< Derived1, Derived2 >::value \
)); \
return_prefix iterator_core_access::base_op( \
*static_cast<Derived1 const*>(&lhs) \
, *static_cast<Derived2 const*>(&rhs) \
@@ -973,7 +853,7 @@ namespace iterators {
# define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \
BOOST_ITERATOR_FACADE_INTEROP( \
op \
, boost::iterators::detail::always_bool2 \
, boost::iterators::detail::always_bool2 \
, return_prefix \
, base_op \
)
@@ -986,26 +866,21 @@ namespace iterators {
# 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) \
{ \
/* For those compilers that do not support enable_if */ \
BOOST_STATIC_ASSERT(( \
is_interoperable< Derived1, Derived2 >::value && \
boost::iterators::detail::is_traversal_at_least< typename iterator_category< Derived1 >::type, random_access_traversal_tag >::value && \
boost::iterators::detail::is_traversal_at_least< typename iterator_category< Derived2 >::type, random_access_traversal_tag >::value \
)); \
return_prefix iterator_core_access::base_op( \
*static_cast<Derived1 const*>(&lhs) \
, *static_cast<Derived2 const*>(&rhs) \
, BOOST_ITERATOR_CONVERTIBLE(Derived2,Derived1) \
); \
{ \
using boost::iterators::detail::is_traversal_at_least; \
return_prefix iterator_core_access::base_op( \
*static_cast<Derived1 const*>(&lhs) \
, *static_cast<Derived2 const*>(&rhs) \
, BOOST_ITERATOR_CONVERTIBLE(Derived2,Derived1) \
); \
}
# define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op, return_prefix, base_op) \
BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS( \
op \
, boost::iterators::detail::always_bool2 \
, return_prefix \
, base_op \
op \
, boost::iterators::detail::always_bool2 \
, return_prefix \
, base_op \
)
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<, return 0 >, distance_from)
@@ -1057,6 +932,4 @@ using iterators::iterator_facade;
} // namespace boost
#include <boost/iterator/detail/config_undef.hpp>
#endif // BOOST_ITERATOR_FACADE_23022003THW_HPP