File indexing completed on 2024-11-15 09:02:46
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP
0012 #define BOOST_ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP
0013
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif
0017
0018 #include <boost/asio/detail/config.hpp>
0019 #include <boost/asio/detail/memory.hpp>
0020 #include <boost/asio/detail/noncopyable.hpp>
0021 #include <boost/asio/detail/recycling_allocator.hpp>
0022 #include <boost/asio/detail/thread_info_base.hpp>
0023 #include <boost/asio/associated_allocator.hpp>
0024
0025 #include <boost/asio/detail/push_options.hpp>
0026
0027 namespace boost {
0028 namespace asio {
0029 namespace detail {
0030
0031 inline void* default_allocate(std::size_t s,
0032 std::size_t align = BOOST_ASIO_DEFAULT_ALIGN)
0033 {
0034 #if !defined(BOOST_ASIO_DISABLE_SMALL_BLOCK_RECYCLING)
0035 return boost::asio::detail::thread_info_base::allocate(
0036 boost::asio::detail::thread_context::top_of_thread_call_stack(),
0037 s, align);
0038 #else
0039 return boost::asio::aligned_new(align, s);
0040 #endif
0041 }
0042
0043 inline void default_deallocate(void* p, std::size_t s)
0044 {
0045 #if !defined(BOOST_ASIO_DISABLE_SMALL_BLOCK_RECYCLING)
0046 boost::asio::detail::thread_info_base::deallocate(
0047 boost::asio::detail::thread_context::top_of_thread_call_stack(), p, s);
0048 #else
0049 (void)s;
0050 boost::asio::aligned_delete(p);
0051 #endif
0052 }
0053
0054 template <typename T>
0055 class default_allocator
0056 {
0057 public:
0058 typedef T value_type;
0059
0060 template <typename U>
0061 struct rebind
0062 {
0063 typedef default_allocator<U> other;
0064 };
0065
0066 default_allocator() noexcept
0067 {
0068 }
0069
0070 template <typename U>
0071 default_allocator(const default_allocator<U>&) noexcept
0072 {
0073 }
0074
0075 T* allocate(std::size_t n)
0076 {
0077 return static_cast<T*>(default_allocate(sizeof(T) * n, alignof(T)));
0078 }
0079
0080 void deallocate(T* p, std::size_t n)
0081 {
0082 default_deallocate(p, sizeof(T) * n);
0083 }
0084 };
0085
0086 template <>
0087 class default_allocator<void>
0088 {
0089 public:
0090 typedef void value_type;
0091
0092 template <typename U>
0093 struct rebind
0094 {
0095 typedef default_allocator<U> other;
0096 };
0097
0098 default_allocator() noexcept
0099 {
0100 }
0101
0102 template <typename U>
0103 default_allocator(const default_allocator<U>&) noexcept
0104 {
0105 }
0106 };
0107
0108 template <typename Allocator>
0109 struct get_default_allocator
0110 {
0111 typedef Allocator type;
0112
0113 static type get(const Allocator& a)
0114 {
0115 return a;
0116 }
0117 };
0118
0119 template <typename T>
0120 struct get_default_allocator<std::allocator<T>>
0121 {
0122 typedef default_allocator<T> type;
0123
0124 static type get(const std::allocator<T>&)
0125 {
0126 return type();
0127 }
0128 };
0129
0130 }
0131 }
0132 }
0133
0134 #define BOOST_ASIO_DEFINE_HANDLER_PTR(op) \
0135 struct ptr \
0136 { \
0137 Handler* h; \
0138 op* v; \
0139 op* p; \
0140 ~ptr() \
0141 { \
0142 reset(); \
0143 } \
0144 static op* allocate(Handler& handler) \
0145 { \
0146 typedef typename ::boost::asio::associated_allocator< \
0147 Handler>::type associated_allocator_type; \
0148 typedef typename ::boost::asio::detail::get_default_allocator< \
0149 associated_allocator_type>::type default_allocator_type; \
0150 BOOST_ASIO_REBIND_ALLOC(default_allocator_type, op) a( \
0151 ::boost::asio::detail::get_default_allocator< \
0152 associated_allocator_type>::get( \
0153 ::boost::asio::get_associated_allocator(handler))); \
0154 return a.allocate(1); \
0155 } \
0156 void reset() \
0157 { \
0158 if (p) \
0159 { \
0160 p->~op(); \
0161 p = 0; \
0162 } \
0163 if (v) \
0164 { \
0165 typedef typename ::boost::asio::associated_allocator< \
0166 Handler>::type associated_allocator_type; \
0167 typedef typename ::boost::asio::detail::get_default_allocator< \
0168 associated_allocator_type>::type default_allocator_type; \
0169 BOOST_ASIO_REBIND_ALLOC(default_allocator_type, op) a( \
0170 ::boost::asio::detail::get_default_allocator< \
0171 associated_allocator_type>::get( \
0172 ::boost::asio::get_associated_allocator(*h))); \
0173 a.deallocate(static_cast<op*>(v), 1); \
0174 v = 0; \
0175 } \
0176 } \
0177 } \
0178
0179
0180 #define BOOST_ASIO_DEFINE_TAGGED_HANDLER_ALLOCATOR_PTR(purpose, op) \
0181 struct ptr \
0182 { \
0183 const Alloc* a; \
0184 void* v; \
0185 op* p; \
0186 ~ptr() \
0187 { \
0188 reset(); \
0189 } \
0190 static op* allocate(const Alloc& a) \
0191 { \
0192 typedef typename ::boost::asio::detail::get_recycling_allocator< \
0193 Alloc, purpose>::type recycling_allocator_type; \
0194 BOOST_ASIO_REBIND_ALLOC(recycling_allocator_type, op) a1( \
0195 ::boost::asio::detail::get_recycling_allocator< \
0196 Alloc, purpose>::get(a)); \
0197 return a1.allocate(1); \
0198 } \
0199 void reset() \
0200 { \
0201 if (p) \
0202 { \
0203 p->~op(); \
0204 p = 0; \
0205 } \
0206 if (v) \
0207 { \
0208 typedef typename ::boost::asio::detail::get_recycling_allocator< \
0209 Alloc, purpose>::type recycling_allocator_type; \
0210 BOOST_ASIO_REBIND_ALLOC(recycling_allocator_type, op) a1( \
0211 ::boost::asio::detail::get_recycling_allocator< \
0212 Alloc, purpose>::get(*a)); \
0213 a1.deallocate(static_cast<op*>(v), 1); \
0214 v = 0; \
0215 } \
0216 } \
0217 } \
0218
0219
0220 #define BOOST_ASIO_DEFINE_HANDLER_ALLOCATOR_PTR(op) \
0221 BOOST_ASIO_DEFINE_TAGGED_HANDLER_ALLOCATOR_PTR( \
0222 ::boost::asio::detail::thread_info_base::default_tag, op ) \
0223
0224
0225 #include <boost/asio/detail/pop_options.hpp>
0226
0227 #endif