// associated_allocator.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// 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)
#include <boost/asio/detail/config.hpp>
#include <memory>
+#include <boost/asio/associator.hpp>
+#include <boost/asio/detail/functional.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
+
+template <typename T, typename Allocator>
+struct associated_allocator;
+
namespace detail {
-template <typename T, typename E, typename = void>
+template <typename T, typename = void>
+struct has_allocator_type : false_type
+{
+};
+
+template <typename T>
+struct has_allocator_type<T,
+ typename void_type<typename T::allocator_type>::type>
+ : true_type
+{
+};
+
+template <typename T, typename E, typename = void, typename = void>
struct associated_allocator_impl
{
typedef E type;
}
};
+template <typename T, typename E>
+struct associated_allocator_impl<T, E,
+ typename enable_if<
+ !has_allocator_type<T>::value
+ >::type,
+ typename void_type<
+ typename associator<associated_allocator, T, E>::type
+ >::type> : associator<associated_allocator, T, E>
+{
+};
+
} // namespace detail
/// Traits type used to obtain the allocator associated with an object.
* @returns <tt>associated_allocator<T>::get(t)</tt>
*/
template <typename T>
-inline typename associated_allocator<T>::type
+BOOST_ASIO_NODISCARD inline typename associated_allocator<T>::type
get_associated_allocator(const T& t) BOOST_ASIO_NOEXCEPT
{
return associated_allocator<T>::get(t);
* @returns <tt>associated_allocator<T, Allocator>::get(t, a)</tt>
*/
template <typename T, typename Allocator>
-inline typename associated_allocator<T, Allocator>::type
+BOOST_ASIO_NODISCARD inline typename associated_allocator<T, Allocator>::type
get_associated_allocator(const T& t, const Allocator& a) BOOST_ASIO_NOEXCEPT
{
return associated_allocator<T, Allocator>::get(t, a);
#endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
+#if defined(BOOST_ASIO_HAS_STD_REFERENCE_WRAPPER) \
+ || defined(GENERATING_DOCUMENTATION)
+
+/// Specialisation of associated_allocator for @c std::reference_wrapper.
+template <typename T, typename Allocator>
+struct associated_allocator<reference_wrapper<T>, Allocator>
+{
+ /// Forwards @c type to the associator specialisation for the unwrapped type
+ /// @c T.
+ typedef typename associated_allocator<T, Allocator>::type type;
+
+ /// Forwards the request to get the allocator to the associator specialisation
+ /// for the unwrapped type @c T.
+ static type get(reference_wrapper<T> t,
+ const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
+ {
+ return associated_allocator<T, Allocator>::get(t.get(), a);
+ }
+};
+
+#endif // defined(BOOST_ASIO_HAS_STD_REFERENCE_WRAPPER)
+ // || defined(GENERATING_DOCUMENTATION)
+
} // namespace asio
} // namespace boost