File indexing completed on 2025-01-18 09:30:11
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef BOOST_CONTAINER_DETAIL_GUARDS_HPP
0013 #define BOOST_CONTAINER_DETAIL_GUARDS_HPP
0014
0015 #include <boost/container/detail/config_begin.hpp>
0016 #include <boost/container/detail/workaround.hpp>
0017
0018 #include <boost/move/core.hpp> // BOOST_MOVABLE_BUT_NOT_COPYABLE
0019
0020
0021 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0022 #include <boost/move/detail/fwd_macros.hpp>
0023 #endif
0024
0025 #include <boost/container/allocator_traits.hpp>
0026
0027 namespace boost {
0028 namespace container {
0029 namespace detail {
0030
0031 class null_construction_guard
0032 {
0033 public:
0034
0035 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0036
0037 template <typename... Args>
0038 null_construction_guard(Args&&...) {}
0039
0040 #else
0041
0042 #define NULL_CONSTRUCTION_GUARD_CODE(N) \
0043 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
0044 BOOST_CONTAINER_FORCEINLINE null_construction_guard(BOOST_MOVE_UREFANON##N)\
0045 {}\
0046
0047 BOOST_MOVE_ITERATE_0TO9(NULL_CONSTRUCTION_GUARD_CODE)
0048 #undef NULL_CONSTRUCTION_GUARD_CODE
0049 #endif
0050
0051 void release() {}
0052 void extend() {}
0053 };
0054
0055 template <typename Allocator>
0056 class construction_guard
0057 {
0058 typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
0059 typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
0060
0061 BOOST_MOVABLE_BUT_NOT_COPYABLE(construction_guard)
0062
0063 public:
0064 construction_guard()
0065 : _alloc_ptr()
0066 , _elem_count()
0067 , _allocator()
0068 {}
0069
0070 construction_guard(pointer alloc_ptr, Allocator& allocator)
0071 :_alloc_ptr(alloc_ptr)
0072 , _elem_count(0)
0073 , _allocator(&allocator)
0074 {}
0075
0076 construction_guard(BOOST_RV_REF(construction_guard) rhs)
0077 :_alloc_ptr(rhs._alloc_ptr)
0078 , _elem_count(rhs._elem_count)
0079 , _allocator(rhs._allocator)
0080 {
0081 rhs._elem_count = 0;
0082 }
0083
0084 ~construction_guard()
0085 {
0086 while (_elem_count) {
0087 --_elem_count;
0088 boost::container::allocator_traits<Allocator>::destroy(*_allocator, _alloc_ptr++);
0089 }
0090 }
0091
0092 void release()
0093 {
0094 _elem_count = 0;
0095 }
0096
0097 void extend()
0098 {
0099 ++_elem_count;
0100 }
0101
0102 private:
0103 pointer _alloc_ptr;
0104 size_type _elem_count;
0105 Allocator* _allocator;
0106 };
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117 template <class Allocator>
0118 class nand_construction_guard
0119 {
0120 typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
0121 typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
0122
0123 construction_guard<Allocator> _src;
0124 construction_guard<Allocator> _dst;
0125 bool _dst_released;
0126
0127 public:
0128 nand_construction_guard()
0129 : _src()
0130 , _dst()
0131 , _dst_released(false)
0132 {}
0133
0134 nand_construction_guard( pointer src, Allocator& src_alloc
0135 , pointer dst, Allocator& dst_alloc)
0136 :_src(src, src_alloc),
0137 _dst(dst, dst_alloc),
0138 _dst_released(false)
0139 {}
0140
0141 void extend()
0142 {
0143 _src.extend();
0144 _dst.extend();
0145 }
0146
0147 void release()
0148 {
0149 _dst.release();
0150 _dst_released = true;
0151 }
0152
0153 ~nand_construction_guard()
0154 {
0155 if (! _dst_released) { _src.release(); }
0156 }
0157 };
0158
0159
0160 template <typename Allocator>
0161 class allocation_guard
0162 {
0163 typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
0164 typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
0165
0166 BOOST_MOVABLE_BUT_NOT_COPYABLE(allocation_guard)
0167
0168 public:
0169 allocation_guard(pointer alloc_ptr, size_type alloc_size, Allocator& allocator)
0170 :_alloc_ptr(alloc_ptr),
0171 _alloc_size(alloc_size),
0172 _allocator(allocator)
0173 {}
0174
0175 ~allocation_guard()
0176 {
0177 if (_alloc_ptr)
0178 {
0179 boost::container::allocator_traits<Allocator>::deallocate(_allocator, _alloc_ptr, _alloc_size);
0180 }
0181 }
0182
0183 void release()
0184 {
0185 _alloc_ptr = 0;
0186 }
0187
0188 private:
0189 pointer _alloc_ptr;
0190 size_type _alloc_size;
0191 Allocator& _allocator;
0192 };
0193
0194 }}}
0195
0196 #include <boost/container/detail/config_end.hpp>
0197
0198 #endif