3 #ifndef CDSLIB_OPT_BUFFER_H
4 #define CDSLIB_OPT_BUFFER_H
6 #include <cds/details/defs.h>
7 #include <cds/user_setup/allocator.h>
8 #include <cds/details/allocator.h>
9 #include <cds/algo/int_algo.h>
11 namespace cds { namespace opt {
13 /// [type-option] Option setter for user-provided plain buffer
15 This option is used by some container as a random access array for storing
16 container's item; for example, a bounded queue may use
17 this option to define underlying buffer implementation.
19 The template parameter \p Type should be rebindable.
22 - \p opt::v::static_buffer
23 - \p opt::v::dynamic_buffer
25 template <typename Type>
28 template <typename Base> struct pack: public Base
39 One of available type for \p opt::buffer option.
41 This buffer maintains static array. No dynamic memory allocation performed.
43 \par Template parameters:
44 - \p T - item type the buffer stores
45 - \p Capacity - the capacity of buffer. The value must be power of two if \p Exp2 is \p true
46 - \p Exp2 - a boolean flag. If it is \p true the buffer capacity must be power of two.
47 Otherwise it can be any positive number. Usually, it is required that the buffer has
48 size of a power of two.
50 template <typename T, size_t Capacity, bool Exp2 = true>
54 typedef T value_type ; ///< value type
55 static CDS_CONSTEXPR const size_t c_nCapacity = Capacity ; ///< Capacity
56 static CDS_CONSTEXPR const bool c_bExp2 = Exp2; ///< \p Exp2 flag
58 /// Rebind buffer for other template parameters
59 template <typename Q, size_t Capacity2 = c_nCapacity, bool Exp22 = c_bExp2>
61 typedef static_buffer<Q, Capacity2, Exp22> other ; ///< Rebind result type
64 // Capacity must be power of 2
65 static_assert(!c_bExp2 || (c_nCapacity & (c_nCapacity - 1)) == 0, "Capacity must be power of two");
69 value_type m_buffer[c_nCapacity];
72 /// Construct static buffer
73 static_buffer() CDS_NOEXCEPT
75 /// Construct buffer of given capacity
77 This ctor ignores \p nCapacity argument. The capacity of static buffer
78 is defined by template argument \p Capacity
80 static_buffer( size_t nCapacity ) CDS_NOEXCEPT
82 CDS_UNUSED( nCapacity );
85 static_buffer( const static_buffer& ) = delete;
86 static_buffer& operator =( const static_buffer& ) = delete;
89 value_type& operator []( size_t i )
91 assert( i < capacity() );
95 /// Get item \p i, const version
96 const value_type& operator []( size_t i ) const
98 assert( i < capacity() );
102 /// Returns buffer capacity
103 CDS_CONSTEXPR size_t capacity() const CDS_NOEXCEPT
108 /// Zeroize the buffer
111 memset( m_buffer, 0, capacity() * sizeof(m_buffer[0]) );
114 /// Returns pointer to buffer array
115 value_type * buffer() CDS_NOEXCEPT
120 /// Returns pointer to buffer array
121 value_type * buffer() const CDS_NOEXCEPT
128 /// Dynamically allocated buffer
130 One of available type for \p opt::buffer option.
132 This buffer maintains dynamically allocated array.
133 Allocation is performed at construction time.
135 \par Template parameters:
136 - \p T - item type storing in the buffer
137 - \p Alloc - an allocator used for allocating internal buffer (\p std::allocator interface)
138 - \p Exp2 - a boolean flag. If it is \p true the buffer capacity must be power of two.
139 Otherwise it can be any positive number. Usually, it is required that the buffer has
140 size of a power of two.
142 template <typename T, class Alloc = CDS_DEFAULT_ALLOCATOR, bool Exp2 = true>
146 typedef T value_type ; ///< Value type
147 static CDS_CONSTEXPR const bool c_bExp2 = Exp2; ///< \p Exp2 flag
149 /// Rebind buffer for other template parameters
150 template <typename Q, typename Alloc2=Alloc, bool Exp22 = c_bExp2>
152 typedef dynamic_buffer<Q, Alloc2, Exp22> other ; ///< Rebinding result type
156 typedef cds::details::Allocator<value_type, Alloc> allocator_type;
161 value_type * m_buffer;
162 size_t const m_nCapacity;
165 /// Allocates dynamic buffer of given \p nCapacity
167 If \p Exp2 class template parameter is \p true then actual capacity
168 of allocating buffer is nearest upper to \p nCapacity power of two.
170 dynamic_buffer( size_t nCapacity )
171 : m_nCapacity( c_bExp2 ? beans::ceil2(nCapacity) : nCapacity )
173 assert( m_nCapacity >= 2 );
174 // Capacity must be power of 2
175 assert( !c_bExp2 || (m_nCapacity & (m_nCapacity - 1)) == 0 );
178 m_buffer = a.NewArray( m_nCapacity );
181 /// Destroys dynamically allocated buffer
185 a.Delete( m_buffer, m_nCapacity );
188 dynamic_buffer( const dynamic_buffer& ) = delete;
189 dynamic_buffer& operator =( const dynamic_buffer& ) = delete;
192 value_type& operator []( size_t i )
194 assert( i < capacity() );
198 /// Get item \p i, const version
199 const value_type& operator []( size_t i ) const
201 assert( i < capacity() );
205 /// Returns buffer capacity
206 size_t capacity() const CDS_NOEXCEPT
211 /// Zeroize the buffer
214 memset( m_buffer, 0, capacity() * sizeof(m_buffer[0]) );
217 /// Returns pointer to buffer array
218 value_type * buffer() CDS_NOEXCEPT
223 /// Returns pointer to buffer array
224 value_type * buffer() const CDS_NOEXCEPT
232 }} // namespace cds::opt
234 #endif // #ifndef CDSLIB_OPT_BUFFER_H