From 45bd9bf69b7d67289452deac631015b93f5b6410 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Thu, 16 Oct 2025 18:38:16 +0300 Subject: [PATCH] Use std::data and std::size for boost equivalents, when possible. This avoids the potential ambiguity between boost:: and std:: functions when the user calls data() or size() unqualified and both alternatives are found via ADL. Refs https://github.com/boostorg/core/issues/206. --- include/boost/core/data.hpp | 16 +++++++++++++++- include/boost/core/size.hpp | 14 ++++++++++++++ test/data_test.cpp | 17 +++++++++++++++++ test/size_test.cpp | 17 +++++++++++++++++ 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/include/boost/core/data.hpp b/include/boost/core/data.hpp index 44cf426..03ac522 100644 --- a/include/boost/core/data.hpp +++ b/include/boost/core/data.hpp @@ -8,8 +8,20 @@ Distributed under the Boost Software License, Version 1.0. #ifndef BOOST_CORE_DATA_HPP #define BOOST_CORE_DATA_HPP -#include +#include + +// Note: MSVC doesn't define __cpp_lib_nonmember_container_access but supports the feature even in C++14 mode +#if (defined(__cpp_lib_nonmember_container_access) && (__cpp_lib_nonmember_container_access >= 201411l)) || \ + (defined(_MSC_VER) && (_MSC_VER >= 1900)) + +namespace boost { +using std::data; +} /* boost */ + +#else // (defined(__cpp_lib_nonmember_container_access) ... + #include +#include namespace boost { @@ -43,4 +55,6 @@ data(std::initializer_list l) noexcept } /* boost */ +#endif // (defined(__cpp_lib_nonmember_container_access) ... + #endif diff --git a/include/boost/core/size.hpp b/include/boost/core/size.hpp index 449ccb9..dd04daa 100644 --- a/include/boost/core/size.hpp +++ b/include/boost/core/size.hpp @@ -8,6 +8,18 @@ Distributed under the Boost Software License, Version 1.0. #ifndef BOOST_CORE_SIZE_HPP #define BOOST_CORE_SIZE_HPP +#include + +// Note: MSVC doesn't define __cpp_lib_nonmember_container_access but supports the feature even in C++14 mode +#if (defined(__cpp_lib_nonmember_container_access) && (__cpp_lib_nonmember_container_access >= 201411l)) || \ + (defined(_MSC_VER) && (_MSC_VER >= 1900)) + +namespace boost { +using std::size; +} /* boost */ + +#else // (defined(__cpp_lib_nonmember_container_access) ... + #include namespace boost { @@ -28,4 +40,6 @@ size(T(&)[N]) noexcept } /* boost */ +#endif // (defined(__cpp_lib_nonmember_container_access) ... + #endif diff --git a/test/data_test.cpp b/test/data_test.cpp index f312d86..9849a9e 100644 --- a/test/data_test.cpp +++ b/test/data_test.cpp @@ -9,6 +9,7 @@ Distributed under the Boost Software License, Version 1.0. #if !defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CXX11_DECLTYPE) #include #include +#include class range { public: @@ -52,12 +53,28 @@ void test_initializer_list() BOOST_TEST_EQ(boost::data(l), l.begin()); } +void test_ambiguity_with_std_data() +{ +// Note: This preprocessor check should be equivalent to that in boost/core/data.hpp +#if (defined(__cpp_lib_nonmember_container_access) && (__cpp_lib_nonmember_container_access >= 201411l)) || \ + (defined(_MSC_VER) && (_MSC_VER >= 1900)) + + // https://github.com/boostorg/core/issues/206 + range c; + using std::data; + using boost::data; + BOOST_TEST_EQ(data(c), c.data()); + +#endif +} + int main() { test_range(); test_const_range(); test_array(); test_initializer_list(); + test_ambiguity_with_std_data(); return boost::report_errors(); } #else diff --git a/test/size_test.cpp b/test/size_test.cpp index 140d403..905ca8d 100644 --- a/test/size_test.cpp +++ b/test/size_test.cpp @@ -9,6 +9,7 @@ Distributed under the Boost Software License, Version 1.0. #if !defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CXX11_DECLTYPE) #include #include +#include struct range { std::size_t size() const { @@ -28,10 +29,26 @@ void test_array() BOOST_TEST_EQ(boost::size(a), 4); } +void test_ambiguity_with_std_size() +{ +// Note: This preprocessor check should be equivalent to that in boost/core/size.hpp +#if (defined(__cpp_lib_nonmember_container_access) && (__cpp_lib_nonmember_container_access >= 201411l)) || \ + (defined(_MSC_VER) && (_MSC_VER >= 1900)) + + // https://github.com/boostorg/core/issues/206 + range c; + using std::size; + using boost::size; + BOOST_TEST_EQ(size(c), c.size()); + +#endif +} + int main() { test_range(); test_array(); + test_ambiguity_with_std_size(); return boost::report_errors(); } #else