1 //
2 // associated_allocator.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10
11 #ifndef BOOST_ASIO_ASSOCIATED_ALLOCATOR_HPP
12 #define BOOST_ASIO_ASSOCIATED_ALLOCATOR_HPP
13
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
18 #include <boost/asio/detail/config.hpp>
19 #include <memory>
20 #include <boost/asio/detail/type_traits.hpp>
21
22 #include <boost/asio/detail/push_options.hpp>
23
24 namespace boost {
25 namespace asio {
26 namespace detail {
27
28 template <typename T, typename E, typename = void>
29 struct associated_allocator_impl
30 {
31 typedef E type;
32
getboost::asio::detail::associated_allocator_impl33 static type get(const T&, const E& e) BOOST_ASIO_NOEXCEPT
34 {
35 return e;
36 }
37 };
38
39 template <typename T, typename E>
40 struct associated_allocator_impl<T, E,
41 typename void_type<typename T::allocator_type>::type>
42 {
43 typedef typename T::allocator_type type;
44
getboost::asio::detail::associated_allocator_impl45 static type get(const T& t, const E&) BOOST_ASIO_NOEXCEPT
46 {
47 return t.get_allocator();
48 }
49 };
50
51 } // namespace detail
52
53 /// Traits type used to obtain the allocator associated with an object.
54 /**
55 * A program may specialise this traits type if the @c T template parameter in
56 * the specialisation is a user-defined type. The template parameter @c
57 * Allocator shall be a type meeting the Allocator requirements.
58 *
59 * Specialisations shall meet the following requirements, where @c t is a const
60 * reference to an object of type @c T, and @c a is an object of type @c
61 * Allocator.
62 *
63 * @li Provide a nested typedef @c type that identifies a type meeting the
64 * Allocator requirements.
65 *
66 * @li Provide a noexcept static member function named @c get, callable as @c
67 * get(t) and with return type @c type.
68 *
69 * @li Provide a noexcept static member function named @c get, callable as @c
70 * get(t,a) and with return type @c type.
71 */
72 template <typename T, typename Allocator = std::allocator<void> >
73 struct associated_allocator
74 {
75 /// If @c T has a nested type @c allocator_type, <tt>T::allocator_type</tt>.
76 /// Otherwise @c Allocator.
77 #if defined(GENERATING_DOCUMENTATION)
78 typedef see_below type;
79 #else // defined(GENERATING_DOCUMENTATION)
80 typedef typename detail::associated_allocator_impl<T, Allocator>::type type;
81 #endif // defined(GENERATING_DOCUMENTATION)
82
83 /// If @c T has a nested type @c allocator_type, returns
84 /// <tt>t.get_allocator()</tt>. Otherwise returns @c a.
getboost::asio::associated_allocator85 static type get(const T& t,
86 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
87 {
88 return detail::associated_allocator_impl<T, Allocator>::get(t, a);
89 }
90 };
91
92 /// Helper function to obtain an object's associated allocator.
93 /**
94 * @returns <tt>associated_allocator<T>::get(t)</tt>
95 */
96 template <typename T>
97 inline typename associated_allocator<T>::type
get_associated_allocator(const T & t)98 get_associated_allocator(const T& t) BOOST_ASIO_NOEXCEPT
99 {
100 return associated_allocator<T>::get(t);
101 }
102
103 /// Helper function to obtain an object's associated allocator.
104 /**
105 * @returns <tt>associated_allocator<T, Allocator>::get(t, a)</tt>
106 */
107 template <typename T, typename Allocator>
108 inline typename associated_allocator<T, Allocator>::type
get_associated_allocator(const T & t,const Allocator & a)109 get_associated_allocator(const T& t, const Allocator& a) BOOST_ASIO_NOEXCEPT
110 {
111 return associated_allocator<T, Allocator>::get(t, a);
112 }
113
114 #if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
115
116 template <typename T, typename Allocator = std::allocator<void> >
117 using associated_allocator_t
118 = typename associated_allocator<T, Allocator>::type;
119
120 #endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
121
122 } // namespace asio
123 } // namespace boost
124
125 #include <boost/asio/detail/pop_options.hpp>
126
127 #endif // BOOST_ASIO_ASSOCIATED_ALLOCATOR_HPP
128