mirror of
https://github.com/boostorg/iterator.git
synced 2026-07-04 23:50:57 +02:00
Constrain distance function using is_iterator type trait (#96)
* Constrain distance function using is_iterator type trait * Add enable_if include * Fix template syntax in distance function * Fix syntax issue in distance enable_if * Test which overload of distance is called Added a test for custom distance function using Foo struct. * Fix wrong spelling of std::ptrdiff_t * Move Foo struct to global scope * Andrey magic * Fix headers, add copyright * Constrain advance to iterators * Test contraint of advance function with int overload Added overload for advance function to handle integers. * Fix enable_if condition for advance function * Fix template syntax in advance constraint * Fix advance test * Remove constexpr specifier * Make advance overload require conversion in parameter * Explain choice of type long for n parameter
This commit is contained in:
@@ -8,8 +8,11 @@
|
||||
#define BOOST_ITERATOR_ADVANCE_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/iterator/is_iterator.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
namespace detail {
|
||||
@@ -56,7 +59,9 @@ inline BOOST_CXX14_CONSTEXPR void advance_impl(RandomAccessIterator& it, Distanc
|
||||
namespace advance_adl_barrier {
|
||||
|
||||
template< typename InputIterator, typename Distance >
|
||||
inline BOOST_CXX14_CONSTEXPR void advance(InputIterator& it, Distance n)
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
typename std::enable_if< boost::is_iterator< InputIterator >::value, void >::type
|
||||
advance(InputIterator& it, Distance n)
|
||||
{
|
||||
detail::advance_impl(it, n, typename iterator_traversal< InputIterator >::type());
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// Copyright (C) 2017 Michel Morin.
|
||||
// Copyright (C) 2026 Jeremy W. Murphy
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -8,9 +9,12 @@
|
||||
#define BOOST_ITERATOR_DISTANCE_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/iterator/is_iterator.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
namespace detail {
|
||||
@@ -40,7 +44,11 @@ distance_impl(RandomAccessIterator first, RandomAccessIterator last, random_acce
|
||||
namespace distance_adl_barrier {
|
||||
|
||||
template< typename SinglePassIterator >
|
||||
inline BOOST_CXX14_CONSTEXPR typename iterator_difference< SinglePassIterator >::type
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
typename std::enable_if<
|
||||
boost::is_iterator< SinglePassIterator >::value,
|
||||
iterator_difference< SinglePassIterator >
|
||||
>::type::type
|
||||
distance(SinglePassIterator first, SinglePassIterator last)
|
||||
{
|
||||
return detail::distance_impl(first, last, typename iterator_traversal< SinglePassIterator >::type());
|
||||
|
||||
@@ -20,6 +20,20 @@ void test_advance(Iterator it_from, Iterator it_to, int n)
|
||||
BOOST_TEST(it_from == it_to);
|
||||
}
|
||||
|
||||
// Definitely not an iterator
|
||||
struct Foo
|
||||
{
|
||||
int x = 0;
|
||||
|
||||
// Don't use type "int" for "n", otherwise it matches literal int exactly
|
||||
// and doesn't demonstrate the effect of enable_if.
|
||||
friend
|
||||
void advance(Foo &value, long n)
|
||||
{
|
||||
value.x += 10 * n;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
int array[3] = {1, 2, 3};
|
||||
@@ -87,5 +101,12 @@ int main()
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
using boost::advance;
|
||||
Foo bar;
|
||||
advance(bar, 3);
|
||||
BOOST_TEST(bar.x == 30);
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <boost/container/slist.hpp>
|
||||
@@ -19,6 +20,13 @@ void test_distance(Iterator it_from, Iterator it_to, int n)
|
||||
BOOST_TEST(boost::distance(it_from, it_to) == n);
|
||||
}
|
||||
|
||||
// Definitely not an iterator.
|
||||
struct Foo
|
||||
{
|
||||
constexpr friend
|
||||
std::ptrdiff_t distance(Foo const &, Foo const &) { return -1; }
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
int array[3] = {1, 2, 3};
|
||||
@@ -80,5 +88,11 @@ int main()
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
// Make boost::distance visible since we're not actually in the boost namespace here.
|
||||
using boost::distance;
|
||||
auto result = distance(Foo{}, Foo{});
|
||||
BOOST_TEST(result == -1);
|
||||
}
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user