diff --git a/include/boost/iterator/distance.hpp b/include/boost/iterator/distance.hpp index b1e32451f..e8a95993d 100644 --- a/include/boost/iterator/distance.hpp +++ b/include/boost/iterator/distance.hpp @@ -8,6 +8,8 @@ #define BOOST_ITERATOR_DISTANCE_HPP #include +#include +#include #include #include @@ -40,7 +42,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()); diff --git a/test/distance_test.cpp b/test/distance_test.cpp index 91587d670..ab79e2391 100644 --- a/test/distance_test.cpp +++ b/test/distance_test.cpp @@ -4,6 +4,7 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#include #include #include #include @@ -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(); }