]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // |
2 | // Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com) | |
3 | // | |
4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
5 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
6 | // | |
7 | ||
8 | #ifndef BEAST_HANDLER_ALLOC_HPP | |
9 | #define BEAST_HANDLER_ALLOC_HPP | |
10 | ||
11 | #include <beast/config.hpp> | |
12 | #include <beast/core/handler_helpers.hpp> | |
13 | #include <cstdlib> | |
14 | #include <memory> | |
15 | #include <type_traits> | |
16 | #include <utility> | |
17 | ||
18 | namespace beast { | |
19 | ||
20 | // Guidance from | |
21 | // http://howardhinnant.github.io/allocator_boilerplate.html | |
22 | ||
23 | /** An allocator that uses handler customizations. | |
24 | ||
25 | This allocator uses the handler customizations `asio_handler_allocate` | |
26 | and `asio_handler_deallocate` to manage memory. It meets the requirements | |
27 | of @b Allocator and can be used anywhere a `std::allocator` is | |
28 | accepted. | |
29 | ||
30 | @tparam T The type of objects allocated by the allocator. | |
31 | ||
32 | @tparam Handler The type of handler. | |
33 | ||
34 | @note Memory allocated by this allocator must be freed before | |
35 | the handler is invoked or undefined behavior results. This behavior | |
36 | is described as the "deallocate before invocation" Asio guarantee. | |
37 | */ | |
38 | #if BEAST_DOXYGEN | |
39 | template<class T, class Handler> | |
40 | class handler_alloc; | |
41 | #else | |
42 | template<class T, class Handler> | |
43 | class handler_alloc | |
44 | { | |
45 | private: | |
46 | // We want a partial template specialization as a friend | |
47 | // but that isn't allowed so we friend all versions. This | |
48 | // should produce a compile error if Handler is not | |
49 | // constructible from H. | |
50 | // | |
51 | template<class U, class H> | |
52 | friend class handler_alloc; | |
53 | ||
54 | Handler& h_; | |
55 | ||
56 | public: | |
57 | using value_type = T; | |
58 | using is_always_equal = std::true_type; | |
59 | ||
60 | template<class U> | |
61 | struct rebind | |
62 | { | |
63 | using other = handler_alloc<U, Handler>; | |
64 | }; | |
65 | ||
66 | handler_alloc() = delete; | |
67 | handler_alloc(handler_alloc&&) = default; | |
68 | handler_alloc(handler_alloc const&) = default; | |
69 | handler_alloc& operator=(handler_alloc&&) = default; | |
70 | handler_alloc& operator=(handler_alloc const&) = default; | |
71 | ||
72 | /** Construct the allocator. | |
73 | ||
74 | A reference of the handler is stored. The handler must | |
75 | remain valid for at least the lifetime of the allocator. | |
76 | */ | |
77 | explicit | |
78 | handler_alloc(Handler& h) | |
79 | : h_(h) | |
80 | { | |
81 | } | |
82 | ||
83 | /// Copy constructor | |
84 | template<class U> | |
85 | handler_alloc( | |
86 | handler_alloc<U, Handler> const& other) | |
87 | : h_(other.h_) | |
88 | { | |
89 | } | |
90 | ||
91 | value_type* | |
92 | allocate(std::ptrdiff_t n) | |
93 | { | |
94 | auto const size = n * sizeof(T); | |
95 | return static_cast<value_type*>( | |
96 | beast_asio_helpers::allocate( | |
97 | size, h_)); | |
98 | } | |
99 | ||
100 | void | |
101 | deallocate(value_type* p, std::ptrdiff_t n) | |
102 | { | |
103 | auto const size = n * sizeof(T); | |
104 | beast_asio_helpers::deallocate( | |
105 | p, size, h_); | |
106 | } | |
107 | ||
108 | #ifdef _MSC_VER | |
109 | // Work-around for MSVC not using allocator_traits | |
110 | // in the implementation of shared_ptr | |
111 | // | |
112 | void | |
113 | destroy(T* t) | |
114 | { | |
115 | t->~T(); | |
116 | } | |
117 | #endif | |
118 | ||
119 | template<class U> | |
120 | friend | |
121 | bool | |
122 | operator==(handler_alloc const& lhs, | |
123 | handler_alloc<U, Handler> const& rhs) | |
124 | { | |
125 | return true; | |
126 | } | |
127 | ||
128 | template<class U> | |
129 | friend | |
130 | bool | |
131 | operator!=(handler_alloc const& lhs, | |
132 | handler_alloc<U, Handler> const& rhs) | |
133 | { | |
134 | return ! (lhs == rhs); | |
135 | } | |
136 | }; | |
137 | #endif | |
138 | ||
139 | } // beast | |
140 | ||
141 | #endif |