mirror of
https://github.com/boostorg/iterator.git
synced 2025-05-09 23:23:54 +00:00
Extracted enable_if_convertible trait to a separate header.
Keep including the new header in iterator_adaptor.hpp for backward compatibility, until downstream users are updated to include the new header.
This commit is contained in:
parent
c22af90b60
commit
cb81a1dfc3
84
include/boost/iterator/enable_if_convertible.hpp
Normal file
84
include/boost/iterator/enable_if_convertible.hpp
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* Distributed under the Boost Software License, Version 1.0.
|
||||||
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
* https://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 Andrey Semashev
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BOOST_ITERATOR_ENABLE_IF_CONVERTIBLE_HPP_INCLUDED_
|
||||||
|
#define BOOST_ITERATOR_ENABLE_IF_CONVERTIBLE_HPP_INCLUDED_
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace iterators {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Result type used in enable_if_convertible meta function.
|
||||||
|
// This can be an incomplete type, as only pointers to
|
||||||
|
// enable_if_convertible< ... >::type are used.
|
||||||
|
// We could have used void for this, but conversion to
|
||||||
|
// void* is just too easy.
|
||||||
|
//
|
||||||
|
struct enable_type;
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
//
|
||||||
|
// enable_if for use in adapted iterators constructors.
|
||||||
|
//
|
||||||
|
// In order to provide interoperability between adapted constant and
|
||||||
|
// mutable iterators, adapted iterators will usually provide templated
|
||||||
|
// conversion constructors of the following form
|
||||||
|
//
|
||||||
|
// template <class BaseIterator>
|
||||||
|
// class adapted_iterator :
|
||||||
|
// public iterator_adaptor< adapted_iterator<Iterator>, Iterator >
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
//
|
||||||
|
// ...
|
||||||
|
//
|
||||||
|
// template <class OtherIterator>
|
||||||
|
// adapted_iterator(
|
||||||
|
// OtherIterator const& it
|
||||||
|
// , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0);
|
||||||
|
//
|
||||||
|
// ...
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// enable_if_convertible is used to remove those overloads from the overload
|
||||||
|
// set that cannot be instantiated. For all practical purposes only overloads
|
||||||
|
// for constant/mutable interaction will remain. This has the advantage that
|
||||||
|
// meta functions like boost::is_convertible do not return false positives,
|
||||||
|
// as they can only look at the signature of the conversion constructor
|
||||||
|
// and not at the actual instantiation.
|
||||||
|
//
|
||||||
|
// enable_if_interoperable can be safely used in user code. It falls back to
|
||||||
|
// always enabled for compilers that don't support enable_if or is_convertible.
|
||||||
|
// There is no need for compiler specific workarounds in user code.
|
||||||
|
//
|
||||||
|
// The operators implementation relies on boost::is_convertible not returning
|
||||||
|
// false positives for user/library defined iterator types. See comments
|
||||||
|
// on operator implementation for consequences.
|
||||||
|
//
|
||||||
|
template< typename From, typename To >
|
||||||
|
struct enable_if_convertible :
|
||||||
|
public std::enable_if<
|
||||||
|
std::is_convertible< From, To >::value,
|
||||||
|
boost::iterators::detail::enable_type
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template< typename From, typename To >
|
||||||
|
using enable_if_convertible_t = typename enable_if_convertible< From, To >::type;
|
||||||
|
|
||||||
|
} // namespace iterators
|
||||||
|
|
||||||
|
using iterators::enable_if_convertible;
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // BOOST_ITERATOR_ENABLE_IF_CONVERTIBLE_HPP_INCLUDED_
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <boost/iterator/iterator_adaptor.hpp>
|
#include <boost/iterator/iterator_adaptor.hpp>
|
||||||
#include <boost/iterator/iterator_categories.hpp>
|
#include <boost/iterator/iterator_categories.hpp>
|
||||||
|
#include <boost/iterator/enable_if_convertible.hpp>
|
||||||
#include <boost/core/use_default.hpp>
|
#include <boost/core/use_default.hpp>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include <boost/iterator/iterator_adaptor.hpp>
|
#include <boost/iterator/iterator_adaptor.hpp>
|
||||||
|
#include <boost/iterator/enable_if_convertible.hpp>
|
||||||
|
|
||||||
#include <boost/pointee.hpp>
|
#include <boost/pointee.hpp>
|
||||||
#include <boost/indirect_reference.hpp>
|
#include <boost/indirect_reference.hpp>
|
||||||
@ -84,7 +85,7 @@ public:
|
|||||||
typename Category2,
|
typename Category2,
|
||||||
typename Reference2,
|
typename Reference2,
|
||||||
typename Difference2,
|
typename Difference2,
|
||||||
typename = typename enable_if_convertible< Iterator2, Iterator >::type
|
typename = enable_if_convertible_t< Iterator2, Iterator >
|
||||||
>
|
>
|
||||||
indirect_iterator(indirect_iterator< Iterator2, Value2, Category2, Reference2, Difference2 > const& y) :
|
indirect_iterator(indirect_iterator< Iterator2, Value2, Category2, Reference2, Difference2 > const& y) :
|
||||||
super_t(y.base())
|
super_t(y.base())
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <boost/iterator/iterator_categories.hpp>
|
#include <boost/iterator/iterator_categories.hpp>
|
||||||
#include <boost/iterator/iterator_facade.hpp>
|
#include <boost/iterator/iterator_facade.hpp>
|
||||||
#include <boost/iterator/iterator_traits.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/config_def.hpp>
|
#include <boost/iterator/detail/config_def.hpp>
|
||||||
|
|
||||||
@ -25,65 +26,6 @@ namespace iterators {
|
|||||||
// explicitly in order to specify that the default should be used.
|
// explicitly in order to specify that the default should be used.
|
||||||
using boost::use_default;
|
using boost::use_default;
|
||||||
|
|
||||||
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
|
|
||||||
>
|
|
||||||
{};
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Default template argument handling for iterator_adaptor
|
// Default template argument handling for iterator_adaptor
|
||||||
//
|
//
|
||||||
@ -297,7 +239,6 @@ private: // data members
|
|||||||
} // namespace iterators
|
} // namespace iterators
|
||||||
|
|
||||||
using iterators::iterator_adaptor;
|
using iterators::iterator_adaptor;
|
||||||
using iterators::enable_if_convertible;
|
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
#include <boost/core/use_default.hpp>
|
#include <boost/core/use_default.hpp>
|
||||||
#include <boost/iterator/iterator_adaptor.hpp>
|
#include <boost/iterator/iterator_adaptor.hpp>
|
||||||
|
#include <boost/iterator/enable_if_convertible.hpp>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace iterators {
|
namespace iterators {
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#define BOOST_REVERSE_ITERATOR_23022003THW_HPP
|
#define BOOST_REVERSE_ITERATOR_23022003THW_HPP
|
||||||
|
|
||||||
#include <boost/iterator/iterator_adaptor.hpp>
|
#include <boost/iterator/iterator_adaptor.hpp>
|
||||||
|
#include <boost/iterator/enable_if_convertible.hpp>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace iterators {
|
namespace iterators {
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
#include <boost/core/use_default.hpp>
|
#include <boost/core/use_default.hpp>
|
||||||
#include <boost/iterator/iterator_adaptor.hpp>
|
#include <boost/iterator/iterator_adaptor.hpp>
|
||||||
#include <boost/iterator/iterator_categories.hpp>
|
#include <boost/iterator/iterator_categories.hpp>
|
||||||
|
#include <boost/iterator/enable_if_convertible.hpp>
|
||||||
|
|
||||||
#include <boost/utility/result_of.hpp>
|
#include <boost/utility/result_of.hpp>
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
#include <boost/iterator/iterator_traits.hpp>
|
#include <boost/iterator/iterator_traits.hpp>
|
||||||
#include <boost/iterator/iterator_facade.hpp>
|
#include <boost/iterator/iterator_facade.hpp>
|
||||||
#include <boost/iterator/iterator_adaptor.hpp> // for enable_if_convertible
|
#include <boost/iterator/enable_if_convertible.hpp>
|
||||||
#include <boost/iterator/iterator_categories.hpp>
|
#include <boost/iterator/iterator_categories.hpp>
|
||||||
#include <boost/iterator/minimum_category.hpp>
|
#include <boost/iterator/minimum_category.hpp>
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include <boost/iterator/iterator_adaptor.hpp>
|
#include <boost/iterator/iterator_adaptor.hpp>
|
||||||
#include <boost/iterator/is_readable_iterator.hpp>
|
#include <boost/iterator/is_readable_iterator.hpp>
|
||||||
#include <boost/iterator/is_lvalue_iterator.hpp>
|
#include <boost/iterator/is_lvalue_iterator.hpp>
|
||||||
|
#include <boost/iterator/enable_if_convertible.hpp>
|
||||||
#include <boost/pending/iterator_tests.hpp>
|
#include <boost/pending/iterator_tests.hpp>
|
||||||
|
|
||||||
# include <boost/core/lightweight_test.hpp>
|
# include <boost/core/lightweight_test.hpp>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user