3 #ifndef __CDS_OPT_BUFFER_H
4 #define __CDS_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 - opt::v::static_buffer
23 - opt::v::dynamic_buffer
25 template <typename Type>
28 template <typename Base> struct pack: public Base
37 /// Static buffer (see \p cds::opt::buffer option)
39 One of available type for opt::buffer type-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 const size_t c_nCapacity = Capacity ; ///< Capacity
56 static 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
65 value_type m_buffer[c_nCapacity];
68 /// Construct static buffer
71 // Capacity must be power of 2
72 static_assert( !c_bExp2 || (c_nCapacity & (c_nCapacity - 1)) == 0, "Capacity must be power of two" );
74 /// Construct buffer of given capacity
76 This ctor ignores \p nCapacity argument. The capacity of static buffer
77 is defined by template argument \p Capacity
79 static_buffer( size_t nCapacity )
81 // Capacity must be power of 2
82 static_assert( !c_bExp2 || (c_nCapacity & (c_nCapacity - 1)) == 0, "Capacity must be power of two");
83 //assert( c_nCapacity == nCapacity );
87 value_type& operator []( size_t i )
89 assert( i < capacity() );
93 /// Get item \p i, const version
94 const value_type& operator []( size_t i ) const
96 assert( i < capacity() );
100 /// Returns buffer capacity
101 CDS_CONSTEXPR size_t capacity() const CDS_NOEXCEPT
106 /// Zeroize the buffer
109 memset( m_buffer, 0, capacity() * sizeof(m_buffer[0]) );
112 /// Returns pointer to buffer array
113 value_type * buffer()
118 /// Returns pointer to buffer array (const version)
119 value_type * buffer() const
127 static_buffer(const static_buffer&);
128 void operator =(const static_buffer&);
133 /// Dynamically allocated buffer
135 One of available \p cds::opt::buffer type-option.
137 This buffer maintains dynamically allocated array.
138 Allocation is performed at construction time.
140 \par Template parameters:
141 - \p T - item type storing in the buffer
142 - \p Alloc - an allocator used for allocating internal buffer (\p std::allocator interface)
143 - \p Exp2 - a boolean flag. If it is \p true the buffer capacity must be power of two.
144 Otherwise it can be any positive number. Usually, it is required that the buffer has
145 size of a power of two.
147 template <typename T, class Alloc = CDS_DEFAULT_ALLOCATOR, bool Exp2 = true>
151 typedef T value_type ; ///< Value type
152 static CDS_CONSTEXPR_CONST bool c_bExp2 = Exp2; ///< \p Exp2 flag
154 /// Rebind buffer for other template parameters
155 template <typename Q, typename Alloc2=Alloc, bool Exp22 = c_bExp2>
157 typedef dynamic_buffer<Q, Alloc2, Exp22> other ; ///< Rebinding result type
161 typedef cds::details::Allocator<value_type, Alloc> allocator_type;
166 value_type * m_buffer;
167 size_t const m_nCapacity;
170 /// Allocates dynamic buffer of given \p nCapacity
172 If \p Exp2 class template parameter is \p true then actual capacity
173 of allocating buffer is nearest upper to \p nCapacity power of two.
175 dynamic_buffer( size_t nCapacity )
176 : m_nCapacity( c_bExp2 ? beans::ceil2(nCapacity) : nCapacity )
178 assert( m_nCapacity >= 2 );
179 // Capacity must be power of 2
180 assert( !c_bExp2 || (m_nCapacity & (m_nCapacity - 1)) == 0 );
183 m_buffer = a.NewArray( m_nCapacity );
186 /// Destroys dynamically allocated buffer
190 a.Delete( m_buffer, m_nCapacity );
194 value_type& operator []( size_t i )
196 assert( i < capacity() );
200 /// Get item \p i, const version
201 const value_type& operator []( size_t i ) const
203 assert( i < capacity() );
207 /// Returns buffer capacity
208 size_t capacity() const CDS_NOEXCEPT
213 /// Zeroize the buffer
216 memset( m_buffer, 0, capacity() * sizeof(m_buffer[0]) );
219 /// Returns pointer to buffer array
220 value_type * buffer()
225 /// Returns pointer to buffer array (const version)
226 value_type * buffer() const
234 dynamic_buffer(const dynamic_buffer&);
235 void operator =(const dynamic_buffer&);
241 }} // namespace cds::opt
243 #endif // #ifndef __CDS_OPT_BUFFER_H