From 3508ceaa582c97c50add1753cb3c6ad973bd72bd Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sat, 10 Aug 2013 13:09:08 +0000 Subject: [PATCH] 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] --- include/boost/unordered/detail/allocate.hpp | 54 +++++++++++---------- include/boost/unordered/detail/buckets.hpp | 16 +++--- include/boost/unordered/detail/table.hpp | 4 +- include/boost/unordered/detail/util.hpp | 5 +- 4 files changed, 45 insertions(+), 34 deletions(-) diff --git a/include/boost/unordered/detail/allocate.hpp b/include/boost/unordered/detail/allocate.hpp index e07c7082..6671607e 100644 --- a/include/boost/unordered/detail/allocate.hpp +++ b/include/boost/unordered/detail/allocate.hpp @@ -234,9 +234,11 @@ namespace boost { namespace unordered { namespace detail { #pragma warning(disable:4100) // unreferenced formal parameter #endif - template - inline void destroy(T* x) { - x->~T(); + namespace func { + template + inline void destroy(T* x) { + x->~T(); + } } #if defined(BOOST_MSVC) @@ -257,13 +259,12 @@ namespace boost { namespace unordered { namespace detail { template struct expr_test; template struct expr_test : T {}; - template static char for_expr_test(U const&); # define BOOST_UNORDERED_CHECK_EXPRESSION(count, result, expression) \ template \ static typename boost::unordered::detail::expr_test< \ BOOST_PP_CAT(choice, result), \ - sizeof(boost::unordered::detail::for_expr_test(( \ + sizeof(for_expr_test(( \ (expression), \ 0)))>::type test( \ BOOST_PP_CAT(choice, count)) @@ -276,6 +277,7 @@ namespace boost { namespace unordered { namespace detail { # define BOOST_UNORDERED_HAS_FUNCTION(name, thing, args, _) \ struct BOOST_PP_CAT(has_, name) \ { \ + template static char for_expr_test(U const&); \ BOOST_UNORDERED_CHECK_EXPRESSION(1, 1, \ boost::unordered::detail::make< thing >().name args); \ BOOST_UNORDERED_DEFAULT_EXPRESSION(2, 2); \ @@ -473,6 +475,9 @@ namespace boost { namespace unordered { namespace detail { # endif + namespace func + { + template inline Alloc call_select_on_container_copy_construction(const Alloc& rhs, typename boost::enable_if_c< @@ -510,6 +515,8 @@ namespace boost { namespace unordered { namespace detail { return (std::numeric_limits::max)(); } + } // namespace func. + template struct allocator_traits { @@ -589,7 +596,7 @@ namespace boost { namespace unordered { namespace detail { boost::unordered::detail::has_destroy::value>::type destroy(Alloc&, T* p) { - boost::unordered::detail::destroy(p); + boost::unordered::detail::func::destroy(p); } # elif !defined(BOOST_NO_SFINAE_EXPR) @@ -623,7 +630,7 @@ namespace boost { namespace unordered { namespace detail { boost::unordered::detail::has_destroy::value>::type destroy(Alloc&, T* p) { - boost::unordered::detail::destroy(p); + boost::unordered::detail::func::destroy(p); } # else @@ -669,21 +676,22 @@ namespace boost { namespace unordered { namespace detail { boost::is_same::value, void*>::type = 0) { - boost::unordered::detail::destroy(p); + boost::unordered::detail::func::destroy(p); } # endif static size_type max_size(const Alloc& a) { - return boost::unordered::detail::call_max_size(a); + return boost::unordered::detail::func:: + call_max_size(a); } // Allocator propagation on construction 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); } @@ -758,7 +766,7 @@ namespace boost { namespace unordered { namespace detail { #endif -namespace boost { namespace unordered { namespace detail { +namespace boost { namespace unordered { namespace detail { namespace func { //////////////////////////////////////////////////////////////////////////// // call_construct @@ -792,7 +800,7 @@ namespace boost { namespace unordered { namespace detail { template 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 inline void destroy_value_impl(Alloc&, T* x) { - boost::unordered::detail::destroy(x); + boost::unordered::detail::func::destroy(x); } #endif @@ -818,7 +826,7 @@ namespace boost { namespace unordered { namespace detail { template \ 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, \ @@ -830,7 +838,7 @@ namespace boost { namespace unordered { namespace detail { void construct_from_tuple(Alloc& alloc, T* ptr, \ namespace_ tuple 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_) \ ); \ } @@ -945,7 +953,7 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::) inline void construct_value_impl(Alloc& alloc, T* address, BOOST_FWD_REF(Args)... args) { - boost::unordered::detail::call_construct(alloc, + boost::unordered::detail::func::call_construct(alloc, address, boost::forward(args)...); } @@ -960,9 +968,9 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::) construct_value_impl(Alloc& alloc, std::pair* address, 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)); - boost::unordered::detail::construct_from_tuple(alloc, + boost::unordered::detail::func::construct_from_tuple(alloc, boost::addressof(address->second), boost::forward(a2)); } @@ -1032,19 +1040,15 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::) boost::unordered::detail::emplace_args3 const& args, typename enable_if, 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::unordered::detail::construct_from_tuple(alloc, + boost::unordered::detail::func::construct_from_tuple(alloc, boost::addressof(address->second), args.a2); } #endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES -}}} - -//////////////////////////////////////////////////////////////////////////////// -// -// Some helper functions for allocating & constructing +}}}} namespace boost { namespace unordered { namespace detail { diff --git a/include/boost/unordered/detail/buckets.hpp b/include/boost/unordered/detail/buckets.hpp index bd90db4e..a264279d 100644 --- a/include/boost/unordered/detail/buckets.hpp +++ b/include/boost/unordered/detail/buckets.hpp @@ -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 { //////////////////////////////////////////////////////////////////////////// @@ -353,7 +357,7 @@ namespace boost { namespace unordered { namespace detail { void construct_with_value(BOOST_UNORDERED_EMPLACE_ARGS) { construct(); - boost::unordered::detail::construct_value_impl( + boost::unordered::detail::func::construct_value_impl( alloc_, node_->value_ptr(), BOOST_UNORDERED_EMPLACE_FORWARD); value_constructed_ = true; } @@ -362,7 +366,7 @@ namespace boost { namespace unordered { namespace detail { void construct_with_value2(BOOST_FWD_REF(A0) a0) { construct(); - boost::unordered::detail::construct_value_impl( + boost::unordered::detail::func::construct_value_impl( alloc_, node_->value_ptr(), BOOST_UNORDERED_EMPLACE_ARGS1(boost::forward(a0))); value_constructed_ = true; @@ -392,7 +396,7 @@ namespace boost { namespace unordered { namespace detail { { if (node_) { if (value_constructed_) { - boost::unordered::detail::destroy_value_impl(alloc_, + boost::unordered::detail::func::destroy_value_impl(alloc_, node_->value_ptr()); } @@ -424,7 +428,7 @@ namespace boost { namespace unordered { namespace detail { if (value_constructed_) { - boost::unordered::detail::destroy_value_impl(alloc_, + boost::unordered::detail::func::destroy_value_impl(alloc_, node_->value_ptr()); value_constructed_ = false; } @@ -541,7 +545,7 @@ namespace boost { namespace unordered { namespace detail { node_pointer p = nodes_; nodes_ = static_cast(p->next_); - boost::unordered::detail::destroy_value_impl(this->alloc_, + boost::unordered::detail::func::destroy_value_impl(this->alloc_, p->value_ptr()); node_allocator_traits::destroy(this->alloc_, boost::addressof(*p)); node_allocator_traits::deallocate(this->alloc_, p, 1); @@ -736,7 +740,7 @@ namespace boost { namespace unordered { namespace detail { void destroy(bool which) { - boost::unordered::detail::destroy((function_pair*)(&funcs_[which])); + boost::unordered::detail::func::destroy((function_pair*)(&funcs_[which])); } public: diff --git a/include/boost/unordered/detail/table.hpp b/include/boost/unordered/detail/table.hpp index 99f2e4bb..e848b21a 100644 --- a/include/boost/unordered/detail/table.hpp +++ b/include/boost/unordered/detail/table.hpp @@ -456,7 +456,7 @@ namespace boost { namespace unordered { namespace detail { 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 // false the behaviour is undefined unless the allocators @@ -516,7 +516,7 @@ namespace boost { namespace unordered { namespace detail { node_pointer n = static_cast(prev->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()); node_allocator_traits::destroy(node_alloc(), boost::addressof(*n)); diff --git a/include/boost/unordered/detail/util.hpp b/include/boost/unordered/detail/util.hpp index 325124a7..570cf8f8 100644 --- a/include/boost/unordered/detail/util.hpp +++ b/include/boost/unordered/detail/util.hpp @@ -28,7 +28,10 @@ namespace boost { namespace unordered { namespace detail { struct move_tag {}; struct empty_emplace {}; - template inline void ignore_unused_variable_warning(T const&) {} + namespace func { + template + inline void ignore_unused_variable_warning(T const&) {} + } //////////////////////////////////////////////////////////////////////////// // iterator SFINAE