File indexing completed on 2025-01-30 09:34:51
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_CONTAINER_DETAIL_BLOCK_SLIST_HEADER
0012 #define BOOST_CONTAINER_DETAIL_BLOCK_SLIST_HEADER
0013
0014 #ifndef BOOST_CONFIG_HPP
0015 # include <boost/config.hpp>
0016 #endif
0017
0018 #if defined(BOOST_HAS_PRAGMA_ONCE)
0019 # pragma once
0020 #endif
0021
0022
0023 #include <boost/container/detail/config_begin.hpp>
0024 #include <boost/container/detail/workaround.hpp>
0025 #include <boost/container/container_fwd.hpp>
0026 #include <boost/container/pmr/memory_resource.hpp>
0027 #include <boost/container/throw_exception.hpp>
0028 #include <boost/container/detail/placement_new.hpp>
0029
0030 #include <boost/move/detail/type_traits.hpp>
0031 #include <boost/intrusive/linear_slist_algorithms.hpp>
0032 #include <boost/assert.hpp>
0033
0034 #include <cstddef>
0035
0036 namespace boost {
0037 namespace container {
0038 namespace pmr {
0039
0040 struct slist_node
0041 {
0042 slist_node *next;
0043 };
0044
0045 struct slist_node_traits
0046 {
0047 typedef slist_node node;
0048 typedef slist_node* node_ptr;
0049 typedef const slist_node* const_node_ptr;
0050
0051 static node_ptr get_next(const_node_ptr n)
0052 { return n->next; }
0053
0054 static void set_next(const node_ptr & n, const node_ptr & next)
0055 { n->next = next; }
0056 };
0057
0058 struct block_slist_header
0059 : public slist_node
0060 {
0061 std::size_t size;
0062 };
0063
0064 typedef bi::linear_slist_algorithms<slist_node_traits> slist_algo;
0065
0066 template<class DerivedFromBlockSlistHeader = block_slist_header>
0067 class block_slist_base
0068 {
0069 slist_node m_slist;
0070
0071 static const std::size_t MaxAlignMinus1 = memory_resource::max_align-1u;
0072
0073 public:
0074
0075 static const std::size_t header_size = std::size_t(sizeof(DerivedFromBlockSlistHeader) + MaxAlignMinus1) & std::size_t(~MaxAlignMinus1);
0076
0077 explicit block_slist_base()
0078 { slist_algo::init_header(&m_slist); }
0079
0080 #if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0081 block_slist_base(const block_slist_base&) = delete;
0082 block_slist_base operator=(const block_slist_base&) = delete;
0083 #else
0084 private:
0085 block_slist_base (const block_slist_base&);
0086 block_slist_base operator=(const block_slist_base&);
0087 public:
0088 #endif
0089
0090 ~block_slist_base()
0091 {}
0092
0093 void *allocate(std::size_t size, memory_resource &mr)
0094 {
0095 if((size_t(-1) - header_size) < size)
0096 throw_bad_alloc();
0097 void *p = mr.allocate(size+header_size);
0098 block_slist_header &mb = *::new((void*)p, boost_container_new_t()) DerivedFromBlockSlistHeader;
0099 mb.size = size+header_size;
0100 slist_algo::link_after(&m_slist, &mb);
0101 return (char *)p + header_size;
0102 }
0103
0104 void release(memory_resource &mr) BOOST_NOEXCEPT
0105 {
0106 slist_node *n = slist_algo::node_traits::get_next(&m_slist);
0107 while(n){
0108 DerivedFromBlockSlistHeader &d = static_cast<DerivedFromBlockSlistHeader&>(*n);
0109 n = slist_algo::node_traits::get_next(n);
0110 std::size_t size = d.block_slist_header::size;
0111 d.~DerivedFromBlockSlistHeader();
0112 mr.deallocate(reinterpret_cast<char*>(&d), size, memory_resource::max_align);
0113 }
0114 slist_algo::init_header(&m_slist);
0115 }
0116 };
0117
0118 class block_slist
0119 : public block_slist_base<>
0120 {
0121 memory_resource &m_upstream_rsrc;
0122
0123 public:
0124
0125 explicit block_slist(memory_resource &upstream_rsrc)
0126 : block_slist_base<>(), m_upstream_rsrc(upstream_rsrc)
0127 {}
0128
0129 #if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0130 block_slist(const block_slist&) = delete;
0131 block_slist operator=(const block_slist&) = delete;
0132 #else
0133 private:
0134 block_slist (const block_slist&);
0135 block_slist operator=(const block_slist&);
0136 public:
0137 #endif
0138
0139 ~block_slist()
0140 { this->release(); }
0141
0142 void *allocate(std::size_t size)
0143 { return this->block_slist_base<>::allocate(size, m_upstream_rsrc); }
0144
0145 void release() BOOST_NOEXCEPT
0146 { return this->block_slist_base<>::release(m_upstream_rsrc); }
0147
0148 memory_resource& upstream_resource() const BOOST_NOEXCEPT
0149 { return m_upstream_rsrc; }
0150 };
0151
0152 }
0153 }
0154 }
0155
0156 #include <boost/container/detail/config_end.hpp>
0157
0158 #endif