forked from boostorg/unordered
Avoid exposing functions via ADL.
I'd put the iterators in their own namespace so that they wouldn't pick up functions in detail via ADL, but I forgot that their template parameters would cause that to happen anyway. The simplest way to fix that for now is just to stuff the problematic functions into a sub-namespace, so that they're no longer exposed. [SVN r85280]
This commit is contained in:
@ -234,9 +234,11 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
#pragma warning(disable:4100) // unreferenced formal parameter
|
#pragma warning(disable:4100) // unreferenced formal parameter
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <class T>
|
namespace func {
|
||||||
inline void destroy(T* x) {
|
template <class T>
|
||||||
x->~T();
|
inline void destroy(T* x) {
|
||||||
|
x->~T();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(BOOST_MSVC)
|
#if defined(BOOST_MSVC)
|
||||||
@ -257,13 +259,12 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
|
|
||||||
template <typename T, unsigned int> struct expr_test;
|
template <typename T, unsigned int> struct expr_test;
|
||||||
template <typename T> struct expr_test<T, sizeof(char)> : T {};
|
template <typename T> struct expr_test<T, sizeof(char)> : T {};
|
||||||
template <typename U> static char for_expr_test(U const&);
|
|
||||||
|
|
||||||
# define BOOST_UNORDERED_CHECK_EXPRESSION(count, result, expression) \
|
# define BOOST_UNORDERED_CHECK_EXPRESSION(count, result, expression) \
|
||||||
template <typename U> \
|
template <typename U> \
|
||||||
static typename boost::unordered::detail::expr_test< \
|
static typename boost::unordered::detail::expr_test< \
|
||||||
BOOST_PP_CAT(choice, result), \
|
BOOST_PP_CAT(choice, result), \
|
||||||
sizeof(boost::unordered::detail::for_expr_test(( \
|
sizeof(for_expr_test(( \
|
||||||
(expression), \
|
(expression), \
|
||||||
0)))>::type test( \
|
0)))>::type test( \
|
||||||
BOOST_PP_CAT(choice, count))
|
BOOST_PP_CAT(choice, count))
|
||||||
@ -276,6 +277,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
# define BOOST_UNORDERED_HAS_FUNCTION(name, thing, args, _) \
|
# define BOOST_UNORDERED_HAS_FUNCTION(name, thing, args, _) \
|
||||||
struct BOOST_PP_CAT(has_, name) \
|
struct BOOST_PP_CAT(has_, name) \
|
||||||
{ \
|
{ \
|
||||||
|
template <typename U> static char for_expr_test(U const&); \
|
||||||
BOOST_UNORDERED_CHECK_EXPRESSION(1, 1, \
|
BOOST_UNORDERED_CHECK_EXPRESSION(1, 1, \
|
||||||
boost::unordered::detail::make< thing >().name args); \
|
boost::unordered::detail::make< thing >().name args); \
|
||||||
BOOST_UNORDERED_DEFAULT_EXPRESSION(2, 2); \
|
BOOST_UNORDERED_DEFAULT_EXPRESSION(2, 2); \
|
||||||
@ -473,6 +475,9 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
namespace func
|
||||||
|
{
|
||||||
|
|
||||||
template <typename Alloc>
|
template <typename Alloc>
|
||||||
inline Alloc call_select_on_container_copy_construction(const Alloc& rhs,
|
inline Alloc call_select_on_container_copy_construction(const Alloc& rhs,
|
||||||
typename boost::enable_if_c<
|
typename boost::enable_if_c<
|
||||||
@ -510,6 +515,8 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
return (std::numeric_limits<SizeType>::max)();
|
return (std::numeric_limits<SizeType>::max)();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace func.
|
||||||
|
|
||||||
template <typename Alloc>
|
template <typename Alloc>
|
||||||
struct allocator_traits
|
struct allocator_traits
|
||||||
{
|
{
|
||||||
@ -589,7 +596,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
boost::unordered::detail::has_destroy<Alloc, T>::value>::type
|
boost::unordered::detail::has_destroy<Alloc, T>::value>::type
|
||||||
destroy(Alloc&, T* p)
|
destroy(Alloc&, T* p)
|
||||||
{
|
{
|
||||||
boost::unordered::detail::destroy(p);
|
boost::unordered::detail::func::destroy(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
# elif !defined(BOOST_NO_SFINAE_EXPR)
|
# elif !defined(BOOST_NO_SFINAE_EXPR)
|
||||||
@ -623,7 +630,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
boost::unordered::detail::has_destroy<Alloc, T>::value>::type
|
boost::unordered::detail::has_destroy<Alloc, T>::value>::type
|
||||||
destroy(Alloc&, T* p)
|
destroy(Alloc&, T* p)
|
||||||
{
|
{
|
||||||
boost::unordered::detail::destroy(p);
|
boost::unordered::detail::func::destroy(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
# else
|
# else
|
||||||
@ -669,21 +676,22 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
boost::is_same<T, value_type>::value,
|
boost::is_same<T, value_type>::value,
|
||||||
void*>::type = 0)
|
void*>::type = 0)
|
||||||
{
|
{
|
||||||
boost::unordered::detail::destroy(p);
|
boost::unordered::detail::func::destroy(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
static size_type max_size(const Alloc& a)
|
static size_type max_size(const Alloc& a)
|
||||||
{
|
{
|
||||||
return boost::unordered::detail::call_max_size<size_type>(a);
|
return boost::unordered::detail::func::
|
||||||
|
call_max_size<size_type>(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocator propagation on construction
|
// Allocator propagation on construction
|
||||||
|
|
||||||
static Alloc select_on_container_copy_construction(Alloc const& rhs)
|
static Alloc select_on_container_copy_construction(Alloc const& rhs)
|
||||||
{
|
{
|
||||||
return boost::unordered::detail::
|
return boost::unordered::detail::func::
|
||||||
call_select_on_container_copy_construction(rhs);
|
call_select_on_container_copy_construction(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -758,7 +766,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace boost { namespace unordered { namespace detail {
|
namespace boost { namespace unordered { namespace detail { namespace func {
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// call_construct
|
// call_construct
|
||||||
@ -792,7 +800,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
|
|
||||||
template <typename Alloc, typename T>
|
template <typename Alloc, typename T>
|
||||||
inline void destroy_value_impl(Alloc&, T* x) {
|
inline void destroy_value_impl(Alloc&, T* x) {
|
||||||
boost::unordered::detail::destroy(x);
|
boost::unordered::detail::func::destroy(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -802,7 +810,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
|
|
||||||
template <typename Alloc, typename T>
|
template <typename Alloc, typename T>
|
||||||
inline void destroy_value_impl(Alloc&, T* x) {
|
inline void destroy_value_impl(Alloc&, T* x) {
|
||||||
boost::unordered::detail::destroy(x);
|
boost::unordered::detail::func::destroy(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -818,7 +826,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
template<typename Alloc, typename T> \
|
template<typename Alloc, typename T> \
|
||||||
void construct_from_tuple(Alloc& alloc, T* ptr, namespace_ tuple<>) \
|
void construct_from_tuple(Alloc& alloc, T* ptr, namespace_ tuple<>) \
|
||||||
{ \
|
{ \
|
||||||
boost::unordered::detail::call_construct(alloc, ptr); \
|
boost::unordered::detail::func::call_construct(alloc, ptr); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
BOOST_PP_REPEAT_FROM_TO(1, n, \
|
BOOST_PP_REPEAT_FROM_TO(1, n, \
|
||||||
@ -830,7 +838,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
void construct_from_tuple(Alloc& alloc, T* ptr, \
|
void construct_from_tuple(Alloc& alloc, T* ptr, \
|
||||||
namespace_ tuple<BOOST_PP_ENUM_PARAMS_Z(z, n, A)> const& x) \
|
namespace_ tuple<BOOST_PP_ENUM_PARAMS_Z(z, n, A)> const& x) \
|
||||||
{ \
|
{ \
|
||||||
boost::unordered::detail::call_construct(alloc, ptr, \
|
boost::unordered::detail::func::call_construct(alloc, ptr, \
|
||||||
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_GET_TUPLE_ARG, namespace_) \
|
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_GET_TUPLE_ARG, namespace_) \
|
||||||
); \
|
); \
|
||||||
}
|
}
|
||||||
@ -945,7 +953,7 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::)
|
|||||||
inline void construct_value_impl(Alloc& alloc, T* address,
|
inline void construct_value_impl(Alloc& alloc, T* address,
|
||||||
BOOST_FWD_REF(Args)... args)
|
BOOST_FWD_REF(Args)... args)
|
||||||
{
|
{
|
||||||
boost::unordered::detail::call_construct(alloc,
|
boost::unordered::detail::func::call_construct(alloc,
|
||||||
address, boost::forward<Args>(args)...);
|
address, boost::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -960,9 +968,9 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::)
|
|||||||
construct_value_impl(Alloc& alloc, std::pair<A, B>* address,
|
construct_value_impl(Alloc& alloc, std::pair<A, B>* address,
|
||||||
BOOST_FWD_REF(A0), BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
|
BOOST_FWD_REF(A0), BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
|
||||||
{
|
{
|
||||||
boost::unordered::detail::construct_from_tuple(alloc,
|
boost::unordered::detail::func::construct_from_tuple(alloc,
|
||||||
boost::addressof(address->first), boost::forward<A1>(a1));
|
boost::addressof(address->first), boost::forward<A1>(a1));
|
||||||
boost::unordered::detail::construct_from_tuple(alloc,
|
boost::unordered::detail::func::construct_from_tuple(alloc,
|
||||||
boost::addressof(address->second), boost::forward<A2>(a2));
|
boost::addressof(address->second), boost::forward<A2>(a2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1032,19 +1040,15 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::)
|
|||||||
boost::unordered::detail::emplace_args3<A0, A1, A2> const& args,
|
boost::unordered::detail::emplace_args3<A0, A1, A2> const& args,
|
||||||
typename enable_if<use_piecewise<A0>, void*>::type = 0)
|
typename enable_if<use_piecewise<A0>, void*>::type = 0)
|
||||||
{
|
{
|
||||||
boost::unordered::detail::construct_from_tuple(alloc,
|
boost::unordered::detail::func::construct_from_tuple(alloc,
|
||||||
boost::addressof(address->first), args.a1);
|
boost::addressof(address->first), args.a1);
|
||||||
boost::unordered::detail::construct_from_tuple(alloc,
|
boost::unordered::detail::func::construct_from_tuple(alloc,
|
||||||
boost::addressof(address->second), args.a2);
|
boost::addressof(address->second), args.a2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
||||||
|
|
||||||
}}}
|
}}}}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Some helper functions for allocating & constructing
|
|
||||||
|
|
||||||
namespace boost { namespace unordered { namespace detail {
|
namespace boost { namespace unordered { namespace detail {
|
||||||
|
|
||||||
|
@ -32,6 +32,10 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
|
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
// The 'iterator_detail' namespace was a misguided attempt at avoiding ADL
|
||||||
|
// in the detail namespace. It didn't work because the template parameters
|
||||||
|
// were in detail. I'm not changing it at the moment to be safe. I might
|
||||||
|
// do in the future if I change the iterator types.
|
||||||
namespace boost { namespace unordered { namespace iterator_detail {
|
namespace boost { namespace unordered { namespace iterator_detail {
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
@ -353,7 +357,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
void construct_with_value(BOOST_UNORDERED_EMPLACE_ARGS)
|
void construct_with_value(BOOST_UNORDERED_EMPLACE_ARGS)
|
||||||
{
|
{
|
||||||
construct();
|
construct();
|
||||||
boost::unordered::detail::construct_value_impl(
|
boost::unordered::detail::func::construct_value_impl(
|
||||||
alloc_, node_->value_ptr(), BOOST_UNORDERED_EMPLACE_FORWARD);
|
alloc_, node_->value_ptr(), BOOST_UNORDERED_EMPLACE_FORWARD);
|
||||||
value_constructed_ = true;
|
value_constructed_ = true;
|
||||||
}
|
}
|
||||||
@ -362,7 +366,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
void construct_with_value2(BOOST_FWD_REF(A0) a0)
|
void construct_with_value2(BOOST_FWD_REF(A0) a0)
|
||||||
{
|
{
|
||||||
construct();
|
construct();
|
||||||
boost::unordered::detail::construct_value_impl(
|
boost::unordered::detail::func::construct_value_impl(
|
||||||
alloc_, node_->value_ptr(),
|
alloc_, node_->value_ptr(),
|
||||||
BOOST_UNORDERED_EMPLACE_ARGS1(boost::forward<A0>(a0)));
|
BOOST_UNORDERED_EMPLACE_ARGS1(boost::forward<A0>(a0)));
|
||||||
value_constructed_ = true;
|
value_constructed_ = true;
|
||||||
@ -392,7 +396,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
{
|
{
|
||||||
if (node_) {
|
if (node_) {
|
||||||
if (value_constructed_) {
|
if (value_constructed_) {
|
||||||
boost::unordered::detail::destroy_value_impl(alloc_,
|
boost::unordered::detail::func::destroy_value_impl(alloc_,
|
||||||
node_->value_ptr());
|
node_->value_ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -424,7 +428,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
|
|
||||||
if (value_constructed_)
|
if (value_constructed_)
|
||||||
{
|
{
|
||||||
boost::unordered::detail::destroy_value_impl(alloc_,
|
boost::unordered::detail::func::destroy_value_impl(alloc_,
|
||||||
node_->value_ptr());
|
node_->value_ptr());
|
||||||
value_constructed_ = false;
|
value_constructed_ = false;
|
||||||
}
|
}
|
||||||
@ -541,7 +545,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
node_pointer p = nodes_;
|
node_pointer p = nodes_;
|
||||||
nodes_ = static_cast<node_pointer>(p->next_);
|
nodes_ = static_cast<node_pointer>(p->next_);
|
||||||
|
|
||||||
boost::unordered::detail::destroy_value_impl(this->alloc_,
|
boost::unordered::detail::func::destroy_value_impl(this->alloc_,
|
||||||
p->value_ptr());
|
p->value_ptr());
|
||||||
node_allocator_traits::destroy(this->alloc_, boost::addressof(*p));
|
node_allocator_traits::destroy(this->alloc_, boost::addressof(*p));
|
||||||
node_allocator_traits::deallocate(this->alloc_, p, 1);
|
node_allocator_traits::deallocate(this->alloc_, p, 1);
|
||||||
@ -736,7 +740,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
|
|
||||||
void destroy(bool which)
|
void destroy(bool which)
|
||||||
{
|
{
|
||||||
boost::unordered::detail::destroy((function_pair*)(&funcs_[which]));
|
boost::unordered::detail::func::destroy((function_pair*)(&funcs_[which]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -456,7 +456,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
|
|
||||||
void swap_allocators(table& other, false_type)
|
void swap_allocators(table& other, false_type)
|
||||||
{
|
{
|
||||||
boost::unordered::detail::ignore_unused_variable_warning(other);
|
boost::unordered::detail::func::ignore_unused_variable_warning(other);
|
||||||
|
|
||||||
// According to 23.2.1.8, if propagate_on_container_swap is
|
// According to 23.2.1.8, if propagate_on_container_swap is
|
||||||
// false the behaviour is undefined unless the allocators
|
// false the behaviour is undefined unless the allocators
|
||||||
@ -516,7 +516,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
node_pointer n = static_cast<node_pointer>(prev->next_);
|
node_pointer n = static_cast<node_pointer>(prev->next_);
|
||||||
prev->next_ = n->next_;
|
prev->next_ = n->next_;
|
||||||
|
|
||||||
boost::unordered::detail::destroy_value_impl(node_alloc(),
|
boost::unordered::detail::func::destroy_value_impl(node_alloc(),
|
||||||
n->value_ptr());
|
n->value_ptr());
|
||||||
node_allocator_traits::destroy(node_alloc(),
|
node_allocator_traits::destroy(node_alloc(),
|
||||||
boost::addressof(*n));
|
boost::addressof(*n));
|
||||||
|
@ -28,7 +28,10 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
struct move_tag {};
|
struct move_tag {};
|
||||||
struct empty_emplace {};
|
struct empty_emplace {};
|
||||||
|
|
||||||
template <class T> inline void ignore_unused_variable_warning(T const&) {}
|
namespace func {
|
||||||
|
template <class T>
|
||||||
|
inline void ignore_unused_variable_warning(T const&) {}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// iterator SFINAE
|
// iterator SFINAE
|
||||||
|
Reference in New Issue
Block a user