1 // 2 // detail/recycling_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_DETAIL_RECYCLING_ALLOCATOR_HPP 12 #define BOOST_ASIO_DETAIL_RECYCLING_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 <boost/asio/detail/memory.hpp> 20 #include <boost/asio/detail/thread_context.hpp> 21 #include <boost/asio/detail/thread_info_base.hpp> 22 23 #include <boost/asio/detail/push_options.hpp> 24 25 namespace boost { 26 namespace asio { 27 namespace detail { 28 29 template <typename T, typename Purpose = thread_info_base::default_tag> 30 class recycling_allocator 31 { 32 public: 33 typedef T value_type; 34 35 template <typename U> 36 struct rebind 37 { 38 typedef recycling_allocator<U, Purpose> other; 39 }; 40 recycling_allocator()41 recycling_allocator() 42 { 43 } 44 45 template <typename U> recycling_allocator(const recycling_allocator<U,Purpose> &)46 recycling_allocator(const recycling_allocator<U, Purpose>&) 47 { 48 } 49 allocate(std::size_t n)50 T* allocate(std::size_t n) 51 { 52 void* p = thread_info_base::allocate(Purpose(), 53 thread_context::top_of_thread_call_stack(), sizeof(T) * n); 54 return static_cast<T*>(p); 55 } 56 deallocate(T * p,std::size_t n)57 void deallocate(T* p, std::size_t n) 58 { 59 thread_info_base::deallocate(Purpose(), 60 thread_context::top_of_thread_call_stack(), p, sizeof(T) * n); 61 } 62 }; 63 64 template <typename Purpose> 65 class recycling_allocator<void, Purpose> 66 { 67 public: 68 typedef void value_type; 69 70 template <typename U> 71 struct rebind 72 { 73 typedef recycling_allocator<U, Purpose> other; 74 }; 75 recycling_allocator()76 recycling_allocator() 77 { 78 } 79 80 template <typename U> recycling_allocator(const recycling_allocator<U,Purpose> &)81 recycling_allocator(const recycling_allocator<U, Purpose>&) 82 { 83 } 84 }; 85 86 template <typename Allocator, typename Purpose> 87 struct get_recycling_allocator 88 { 89 typedef Allocator type; getboost::asio::detail::get_recycling_allocator90 static type get(const Allocator& a) { return a; } 91 }; 92 93 template <typename T, typename Purpose> 94 struct get_recycling_allocator<std::allocator<T>, Purpose> 95 { 96 typedef recycling_allocator<T, Purpose> type; getboost::asio::detail::get_recycling_allocator97 static type get(const std::allocator<T>&) { return type(); } 98 }; 99 100 } // namespace detail 101 } // namespace asio 102 } // namespace boost 103 104 #include <boost/asio/detail/pop_options.hpp> 105 106 #endif // BOOST_ASIO_DETAIL_RECYCLING_ALLOCATOR_HPP 107