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 - 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 CDS_UNUSED( nCapacity );
82 // Capacity must be power of 2
83 static_assert( !c_bExp2 || (c_nCapacity & (c_nCapacity - 1)) == 0, "Capacity must be power of two");
84 //assert( c_nCapacity == nCapacity );
88 value_type& operator []( size_t i )
90 assert( i < capacity() );
94 /// Get item \p i, const version
95 const value_type& operator []( size_t i ) const
97 assert( i < capacity() );
101 /// Returns buffer capacity
102 CDS_CONSTEXPR size_t capacity() const CDS_NOEXCEPT
107 /// Zeroize the buffer
110 memset( m_buffer, 0, capacity() * sizeof(m_buffer[0]) );
113 /// Returns pointer to buffer array
114 value_type * buffer()
119 /// Returns pointer to buffer array (const version)
120 value_type * buffer() const
128 static_buffer(const static_buffer&);
129 void operator =(const static_buffer&);
134 /// Dynamically allocated buffer
136 One of available \p cds::opt::buffer type-option.
138 This buffer maintains dynamically allocated array.
139 Allocation is performed at construction time.
141 \par Template parameters:
142 - \p T - item type storing in the buffer
143 - \p Alloc - an allocator used for allocating internal buffer (\p std::allocator interface)
144 - \p Exp2 - a boolean flag. If it is \p true the buffer capacity must be power of two.
145 Otherwise it can be any positive number. Usually, it is required that the buffer has
146 size of a power of two.
148 template <typename T, class Alloc = CDS_DEFAULT_ALLOCATOR, bool Exp2 = true>
152 typedef T value_type ; ///< Value type
153 static CDS_CONSTEXPR const bool c_bExp2 = Exp2; ///< \p Exp2 flag
155 /// Rebind buffer for other template parameters
156 template <typename Q, typename Alloc2=Alloc, bool Exp22 = c_bExp2>
158 typedef dynamic_buffer<Q, Alloc2, Exp22> other ; ///< Rebinding result type
162 typedef cds::details::Allocator<value_type, Alloc> allocator_type;
167 value_type * m_buffer;
168 size_t const m_nCapacity;
171 /// Allocates dynamic buffer of given \p nCapacity
173 If \p Exp2 class template parameter is \p true then actual capacity
174 of allocating buffer is nearest upper to \p nCapacity power of two.
176 dynamic_buffer( size_t nCapacity )
177 : m_nCapacity( c_bExp2 ? beans::ceil2(nCapacity) : nCapacity )
179 assert( m_nCapacity >= 2 );
180 // Capacity must be power of 2
181 assert( !c_bExp2 || (m_nCapacity & (m_nCapacity - 1)) == 0 );
184 m_buffer = a.NewArray( m_nCapacity );
187 /// Destroys dynamically allocated buffer
191 a.Delete( m_buffer, m_nCapacity );
195 value_type& operator []( size_t i )
197 assert( i < capacity() );
201 /// Get item \p i, const version
202 const value_type& operator []( size_t i ) const
204 assert( i < capacity() );
208 /// Returns buffer capacity
209 size_t capacity() const CDS_NOEXCEPT
214 /// Zeroize the buffer
217 memset( m_buffer, 0, capacity() * sizeof(m_buffer[0]) );
220 /// Returns pointer to buffer array
221 value_type * buffer()
226 /// Returns pointer to buffer array (const version)
227 value_type * buffer() const
235 dynamic_buffer(const dynamic_buffer&);
236 void operator =(const dynamic_buffer&);
242 }} // namespace cds::opt
244 #endif // #ifndef CDSLIB_OPT_BUFFER_H