2 This file is a part of libcds - Concurrent Data Structures library
4 (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
6 Source code repo: http://github.com/khizmax/libcds/
7 Download: http://sourceforge.net/projects/libcds/files/
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are met:
12 * Redistributions of source code must retain the above copyright notice, this
13 list of conditions and the following disclaimer.
15 * Redistributions in binary form must reproduce the above copyright notice,
16 this list of conditions and the following disclaimer in the documentation
17 and/or other materials provided with the distribution.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #ifndef CDSLIB_OPT_BUFFER_H
32 #define CDSLIB_OPT_BUFFER_H
35 #include <cds/details/defs.h>
36 #include <cds/user_setup/allocator.h>
37 #include <cds/details/allocator.h>
38 #include <cds/algo/int_algo.h>
40 namespace cds { namespace opt {
42 /// [type-option] Option setter for user-provided plain buffer
44 This option is used by some container as a random access array for storing
45 container's item; for example, a bounded queue may use
46 this option to define underlying buffer implementation.
48 The template parameter \p Type should be rebindable.
51 - \p opt::v::static_buffer
52 - \p opt::v::dynamic_buffer
54 template <typename Type>
57 template <typename Base> struct pack: public Base
68 One of available type for \p opt::buffer option.
70 This buffer maintains static array. No dynamic memory allocation performed.
72 \par Template parameters:
73 - \p T - item type the buffer stores
74 - \p Capacity - the capacity of buffer. The value must be power of two if \p Exp2 is \p true
75 - \p Exp2 - a boolean flag. If it is \p true the buffer capacity must be power of two.
76 Otherwise it can be any positive number. Usually, it is required that the buffer has
77 size of a power of two.
79 template <typename T, size_t Capacity, bool Exp2 = true>
83 typedef T value_type ; ///< value type
84 static CDS_CONSTEXPR const size_t c_nCapacity = Capacity ; ///< Capacity
85 static CDS_CONSTEXPR const bool c_bExp2 = Exp2; ///< \p Exp2 flag
87 /// Rebind buffer for other template parameters
88 template <typename Q, size_t Capacity2 = c_nCapacity, bool Exp22 = c_bExp2>
90 typedef static_buffer<Q, Capacity2, Exp22> other ; ///< Rebind result type
93 // Capacity must be power of 2
94 static_assert(!c_bExp2 || (c_nCapacity & (c_nCapacity - 1)) == 0, "Capacity must be power of two");
98 value_type m_buffer[c_nCapacity];
101 /// Construct static buffer
102 static_buffer() CDS_NOEXCEPT
104 /// Construct buffer of given capacity
106 This ctor ignores \p nCapacity argument. The capacity of static buffer
107 is defined by template argument \p Capacity
109 static_buffer( size_t nCapacity ) CDS_NOEXCEPT
111 CDS_UNUSED( nCapacity );
114 static_buffer( const static_buffer& ) = delete;
115 static_buffer& operator =( const static_buffer& ) = delete;
118 value_type& operator []( size_t i )
120 assert( i < capacity() );
124 /// Get item \p i, const version
125 const value_type& operator []( size_t i ) const
127 assert( i < capacity() );
131 /// Returns buffer capacity
132 CDS_CONSTEXPR size_t capacity() const CDS_NOEXCEPT
137 /// Zeroize the buffer
140 memset( m_buffer, 0, capacity() * sizeof(m_buffer[0]) );
143 /// Returns pointer to buffer array
144 value_type * buffer() CDS_NOEXCEPT
149 /// Returns pointer to buffer array
150 value_type * buffer() const CDS_NOEXCEPT
157 /// Dynamically allocated buffer
159 One of available type for \p opt::buffer option.
161 This buffer maintains dynamically allocated array.
162 Allocation is performed at construction time.
164 \par Template parameters:
165 - \p T - item type storing in the buffer
166 - \p Alloc - an allocator used for allocating internal buffer (\p std::allocator interface)
167 - \p Exp2 - a boolean flag. If it is \p true the buffer capacity must be power of two.
168 Otherwise it can be any positive number. Usually, it is required that the buffer has
169 size of a power of two.
171 template <typename T, class Alloc = CDS_DEFAULT_ALLOCATOR, bool Exp2 = true>
175 typedef T value_type ; ///< Value type
176 static CDS_CONSTEXPR const bool c_bExp2 = Exp2; ///< \p Exp2 flag
178 /// Rebind buffer for other template parameters
179 template <typename Q, typename Alloc2=Alloc, bool Exp22 = c_bExp2>
181 typedef dynamic_buffer<Q, Alloc2, Exp22> other ; ///< Rebinding result type
185 typedef cds::details::Allocator<value_type, Alloc> allocator_type;
190 value_type * m_buffer;
191 size_t const m_nCapacity;
194 /// Allocates dynamic buffer of given \p nCapacity
196 If \p Exp2 class template parameter is \p true then actual capacity
197 of allocating buffer is nearest upper to \p nCapacity power of two.
199 dynamic_buffer( size_t nCapacity )
200 : m_nCapacity( c_bExp2 ? beans::ceil2(nCapacity) : nCapacity )
202 assert( m_nCapacity >= 2 );
203 // Capacity must be power of 2
204 assert( !c_bExp2 || (m_nCapacity & (m_nCapacity - 1)) == 0 );
207 m_buffer = a.NewArray( m_nCapacity );
210 /// Destroys dynamically allocated buffer
214 a.Delete( m_buffer, m_nCapacity );
217 dynamic_buffer( const dynamic_buffer& ) = delete;
218 dynamic_buffer& operator =( const dynamic_buffer& ) = delete;
221 value_type& operator []( size_t i )
223 assert( i < capacity() );
227 /// Get item \p i, const version
228 const value_type& operator []( size_t i ) const
230 assert( i < capacity() );
234 /// Returns buffer capacity
235 size_t capacity() const CDS_NOEXCEPT
240 /// Zeroize the buffer
243 memset( m_buffer, 0, capacity() * sizeof(m_buffer[0]) );
246 /// Returns pointer to buffer array
247 value_type * buffer() CDS_NOEXCEPT
252 /// Returns pointer to buffer array
253 value_type * buffer() const CDS_NOEXCEPT
261 }} // namespace cds::opt
263 #endif // #ifndef CDSLIB_OPT_BUFFER_H