From b181c05fd3d9eec4a515511f8bb201dda4b6cb6f Mon Sep 17 00:00:00 2001 From: "Jeremy W. Murphy" Date: Wed, 13 May 2026 14:06:39 +0900 Subject: [PATCH 1/8] Constrain distance function using is_iterator type trait --- include/boost/iterator/distance.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/boost/iterator/distance.hpp b/include/boost/iterator/distance.hpp index b1e32451f..1808111f7 100644 --- a/include/boost/iterator/distance.hpp +++ b/include/boost/iterator/distance.hpp @@ -8,6 +8,7 @@ #define BOOST_ITERATOR_DISTANCE_HPP #include +#include #include #include @@ -40,7 +41,9 @@ 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 +boost::enable_if_c< boost::is_iterator< SinglePassIterator >::value, + typename iterator_difference< SinglePassIterator >::type > distance(SinglePassIterator first, SinglePassIterator last) { return detail::distance_impl(first, last, typename iterator_traversal< SinglePassIterator >::type()); From 668fdd0a1f7265be1e058ff0d98d18f95771f1f2 Mon Sep 17 00:00:00 2001 From: "Jeremy W. Murphy" Date: Wed, 13 May 2026 14:09:42 +0900 Subject: [PATCH 2/8] Add enable_if include --- include/boost/iterator/distance.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/boost/iterator/distance.hpp b/include/boost/iterator/distance.hpp index 1808111f7..f26ea6a16 100644 --- a/include/boost/iterator/distance.hpp +++ b/include/boost/iterator/distance.hpp @@ -8,6 +8,7 @@ #define BOOST_ITERATOR_DISTANCE_HPP #include +#include #include #include #include From d95f074fc53258b9f3530d838f160d93c7bfd927 Mon Sep 17 00:00:00 2001 From: "Jeremy W. Murphy" Date: Wed, 13 May 2026 14:21:44 +0900 Subject: [PATCH 3/8] Fix template syntax in distance function --- include/boost/iterator/distance.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/iterator/distance.hpp b/include/boost/iterator/distance.hpp index f26ea6a16..58b15c255 100644 --- a/include/boost/iterator/distance.hpp +++ b/include/boost/iterator/distance.hpp @@ -43,8 +43,8 @@ namespace distance_adl_barrier { template< typename SinglePassIterator > inline BOOST_CXX14_CONSTEXPR -boost::enable_if_c< boost::is_iterator< SinglePassIterator >::value, - typename iterator_difference< SinglePassIterator >::type > +boost::enable_if< boost::is_iterator< SinglePassIterator >, + typename iterator_difference< SinglePassIterator >::type >::type distance(SinglePassIterator first, SinglePassIterator last) { return detail::distance_impl(first, last, typename iterator_traversal< SinglePassIterator >::type()); From a3123502c856171cd93002e743304511660a122f Mon Sep 17 00:00:00 2001 From: "Jeremy W. Murphy" Date: Wed, 13 May 2026 14:23:03 +0900 Subject: [PATCH 4/8] Fix syntax issue in distance enable_if --- include/boost/iterator/distance.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/iterator/distance.hpp b/include/boost/iterator/distance.hpp index 58b15c255..bf19d0853 100644 --- a/include/boost/iterator/distance.hpp +++ b/include/boost/iterator/distance.hpp @@ -43,8 +43,8 @@ namespace distance_adl_barrier { template< typename SinglePassIterator > inline BOOST_CXX14_CONSTEXPR -boost::enable_if< boost::is_iterator< SinglePassIterator >, - typename iterator_difference< SinglePassIterator >::type >::type +typename boost::enable_if< boost::is_iterator< SinglePassIterator >, + typename iterator_difference< SinglePassIterator >::type >::type distance(SinglePassIterator first, SinglePassIterator last) { return detail::distance_impl(first, last, typename iterator_traversal< SinglePassIterator >::type()); From ec485797cc5adc046236828c26c7f9aa1a227c96 Mon Sep 17 00:00:00 2001 From: "Jeremy W. Murphy" Date: Thu, 14 May 2026 17:51:22 +0900 Subject: [PATCH 5/8] Test which overload of distance is called Added a test for custom distance function using Foo struct. --- test/distance_test.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/distance_test.cpp b/test/distance_test.cpp index 91587d670..d0b83df3d 100644 --- a/test/distance_test.cpp +++ b/test/distance_test.cpp @@ -80,5 +80,17 @@ int main() ); } + { + // Definitely not an iterator. + struct Foo + { + friend + std::ptr_diff distance(Foo const &, Foo const &) { return -1; } + }; + // Make it visible. + using boost::distance; + auto result = distance(Foo{}, Foo{}); + BOOST_TEST(result == -1); + } return boost::report_errors(); } From 71d8fb26668d57ea0552a34a11bccf6469c8247a Mon Sep 17 00:00:00 2001 From: "Jeremy W. Murphy" Date: Thu, 14 May 2026 17:58:10 +0900 Subject: [PATCH 6/8] Fix wrong spelling of std::ptrdiff_t --- test/distance_test.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/distance_test.cpp b/test/distance_test.cpp index d0b83df3d..e91f71260 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 @@ -84,10 +85,10 @@ int main() // Definitely not an iterator. struct Foo { - friend - std::ptr_diff distance(Foo const &, Foo const &) { return -1; } + constexpr friend + std::ptrdiff_t distance(Foo const &, Foo const &) { return -1; } }; - // Make it visible. + // 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); From c9e4a8db47d5ef676d9a1cc951669789e652a633 Mon Sep 17 00:00:00 2001 From: "Jeremy W. Murphy" Date: Thu, 14 May 2026 18:03:18 +0900 Subject: [PATCH 7/8] Move Foo struct to global scope --- test/distance_test.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/test/distance_test.cpp b/test/distance_test.cpp index e91f71260..ab79e2391 100644 --- a/test/distance_test.cpp +++ b/test/distance_test.cpp @@ -20,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}; @@ -82,12 +89,6 @@ int main() } { - // Definitely not an iterator. - struct Foo - { - constexpr friend - std::ptrdiff_t distance(Foo const &, Foo const &) { return -1; } - }; // Make boost::distance visible since we're not actually in the boost namespace here. using boost::distance; auto result = distance(Foo{}, Foo{}); From 66cdd2ed2a4799330f1b9aafdf41b2933bd5e497 Mon Sep 17 00:00:00 2001 From: "Jeremy W. Murphy" Date: Thu, 14 May 2026 18:45:18 +0900 Subject: [PATCH 8/8] Andrey magic --- include/boost/iterator/distance.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/boost/iterator/distance.hpp b/include/boost/iterator/distance.hpp index bf19d0853..e8a95993d 100644 --- a/include/boost/iterator/distance.hpp +++ b/include/boost/iterator/distance.hpp @@ -43,8 +43,10 @@ namespace distance_adl_barrier { template< typename SinglePassIterator > inline BOOST_CXX14_CONSTEXPR -typename boost::enable_if< boost::is_iterator< SinglePassIterator >, - typename iterator_difference< SinglePassIterator >::type >::type +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());