Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion include/boost/core/data.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,20 @@ Distributed under the Boost Software License, Version 1.0.
#ifndef BOOST_CORE_DATA_HPP
#define BOOST_CORE_DATA_HPP

#include <initializer_list>
#include <iterator>

// 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 <cstddef>
#include <initializer_list>

namespace boost {

Expand Down Expand Up @@ -43,4 +55,6 @@ data(std::initializer_list<T> l) noexcept

} /* boost */

#endif // (defined(__cpp_lib_nonmember_container_access) ...

#endif
14 changes: 14 additions & 0 deletions include/boost/core/size.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@ Distributed under the Boost Software License, Version 1.0.
#ifndef BOOST_CORE_SIZE_HPP
#define BOOST_CORE_SIZE_HPP

#include <iterator>

// 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 <cstddef>

namespace boost {
Expand All @@ -28,4 +40,6 @@ size(T(&)[N]) noexcept

} /* boost */

#endif // (defined(__cpp_lib_nonmember_container_access) ...

#endif
1 change: 1 addition & 0 deletions test/Jamfile.v2
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ run span_constexpr_test.cpp ;
run as_bytes_test.cpp ;
run as_writable_bytes_test.cpp ;
compile span_boost_begin_test.cpp ;
compile span_nonmem_data_size_test.cpp ;
run make_span_test.cpp ;

run splitmix64_test.cpp
Expand Down
17 changes: 17 additions & 0 deletions test/data_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <boost/core/data.hpp>
#include <boost/core/lightweight_test.hpp>
#include <iterator>

class range {
public:
Expand Down Expand Up @@ -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
Expand Down
17 changes: 17 additions & 0 deletions test/size_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <boost/core/size.hpp>
#include <boost/core/lightweight_test.hpp>
#include <iterator>

struct range {
std::size_t size() const {
Expand All @@ -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
Expand Down
44 changes: 44 additions & 0 deletions test/span_nonmem_data_size_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright Andrey Semashev 2025.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*/
/*
* The test verifies that unqualified calls to data() and size()
* don't cause ambiguity between std:: and boost:: implementations.
* The ambiguity used to be caused by ADL bringing boost::data()/size()
* due to namespace of boost::span and a using-declaration of
* std::data()/size().
*
* https://github.com/boostorg/core/issues/206
*/

#include <boost/config.hpp>

#if !defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CXX11_DECLTYPE)

#include <boost/core/span.hpp>
#include <iterator>

// Note: This preprocessor check should be equivalent to those in boost/core/data.hpp and boost/core/size.hpp
#if (defined(__cpp_lib_nonmember_container_access) && (__cpp_lib_nonmember_container_access >= 201411l)) || \
(defined(_MSC_VER) && (_MSC_VER >= 1900))

#include <boost/core/data.hpp>
#include <boost/core/size.hpp>

int* test_data_ambiguity(boost::span<int> sp)
{
using std::data;
return data(sp);
}

boost::span<int>::size_type test_size_ambiguity(boost::span<int> sp)
{
using std::size;
return size(sp);
}

#endif // (defined(__cpp_lib_nonmember_container_access) ...
#endif // !defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CXX11_DECLTYPE)
Loading