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
34 #include <cds/details/defs.h>
35 #include <cds/user_setup/allocator.h>
36 #include <cds/details/allocator.h>
37 #include <cds/algo/int_algo.h>
39 namespace cds { namespace opt {
41 /// [type-option] Option setter for user-provided plain buffer
43 This option is used by some container as a random access array for storing
44 container's item; for example, a bounded queue may use
45 this option to define underlying buffer implementation.
47 The template parameter \p Type should be rebindable.
50 - \p opt::v::static_buffer
51 - \p opt::v::dynamic_buffer
53 template <typename Type>
56 template <typename Base> struct pack: public Base
67 One of available type for \p opt::buffer option.
69 This buffer maintains static array. No dynamic memory allocation performed.
71 \par Template parameters:
72 - \p T - item type the buffer stores
73 - \p Capacity - the capacity of buffer. The value must be power of two if \p Exp2 is \p true
74 - \p Exp2 - a boolean flag. If it is \p true the buffer capacity must be power of two.
75 Otherwise it can be any positive number. Usually, it is required that the buffer has
76 size of a power of two.
78 template <typename T, size_t Capacity, bool Exp2 = true>
82 typedef T value_type ; ///< value type
83 static CDS_CONSTEXPR const size_t c_nCapacity = Capacity ; ///< Capacity
84 static CDS_CONSTEXPR const bool c_bExp2 = Exp2; ///< \p Exp2 flag
86 /// Rebind buffer for other template parameters
87 template <typename Q, size_t Capacity2 = c_nCapacity, bool Exp22 = c_bExp2>
89 typedef static_buffer<Q, Capacity2, Exp22> other ; ///< Rebind result type
92 // Capacity must be power of 2
93 static_assert(!c_bExp2 || (c_nCapacity & (c_nCapacity - 1)) == 0, "Capacity must be power of two");
97 value_type m_buffer[c_nCapacity];
100 /// Construct static buffer
101 static_buffer() CDS_NOEXCEPT
103 /// Construct buffer of given capacity
105 This ctor ignores \p nCapacity argument. The capacity of static buffer
106 is defined by template argument \p Capacity
108 static_buffer( size_t nCapacity ) CDS_NOEXCEPT
110 CDS_UNUSED( nCapacity );
113 static_buffer( const static_buffer& ) = delete;
114 static_buffer& operator =( const static_buffer& ) = delete;
117 value_type& operator []( size_t i )
119 assert( i < capacity() );
123 /// Get item \p i, const version
124 const value_type& operator []( size_t i ) const
126 assert( i < capacity() );
130 /// Returns buffer capacity
131 CDS_CONSTEXPR size_t capacity() const CDS_NOEXCEPT
136 /// Zeroize the buffer
139 memset( m_buffer, 0, capacity() * sizeof(m_buffer[0]) );
142 /// Returns pointer to buffer array
143 value_type * buffer() CDS_NOEXCEPT
148 /// Returns pointer to buffer array
149 value_type * buffer() const CDS_NOEXCEPT
156 /// Dynamically allocated buffer
158 One of available type for \p opt::buffer option.
160 This buffer maintains dynamically allocated array.
161 Allocation is performed at construction time.
163 \par Template parameters:
164 - \p T - item type storing in the buffer
165 - \p Alloc - an allocator used for allocating internal buffer (\p std::allocator interface)
166 - \p Exp2 - a boolean flag. If it is \p true the buffer capacity must be power of two.
167 Otherwise it can be any positive number. Usually, it is required that the buffer has
168 size of a power of two.
170 template <typename T, class Alloc = CDS_DEFAULT_ALLOCATOR, bool Exp2 = true>
174 typedef T value_type ; ///< Value type
175 static CDS_CONSTEXPR const bool c_bExp2 = Exp2; ///< \p Exp2 flag
177 /// Rebind buffer for other template parameters
178 template <typename Q, typename Alloc2=Alloc, bool Exp22 = c_bExp2>
180 typedef dynamic_buffer<Q, Alloc2, Exp22> other ; ///< Rebinding result type
184 typedef cds::details::Allocator<value_type, Alloc> allocator_type;
189 value_type * m_buffer;
190 size_t const m_nCapacity;
193 /// Allocates dynamic buffer of given \p nCapacity
195 If \p Exp2 class template parameter is \p true then actual capacity
196 of allocating buffer is nearest upper to \p nCapacity power of two.
198 dynamic_buffer( size_t nCapacity )
199 : m_nCapacity( c_bExp2 ? beans::ceil2(nCapacity) : nCapacity )
201 assert( m_nCapacity >= 2 );
202 // Capacity must be power of 2
203 assert( !c_bExp2 || (m_nCapacity & (m_nCapacity - 1)) == 0 );
206 m_buffer = a.NewArray( m_nCapacity );
209 /// Destroys dynamically allocated buffer
213 a.Delete( m_buffer, m_nCapacity );
216 dynamic_buffer( const dynamic_buffer& ) = delete;
217 dynamic_buffer& operator =( const dynamic_buffer& ) = delete;
220 value_type& operator []( size_t i )
222 assert( i < capacity() );
226 /// Get item \p i, const version
227 const value_type& operator []( size_t i ) const
229 assert( i < capacity() );
233 /// Returns buffer capacity
234 size_t capacity() const CDS_NOEXCEPT
239 /// Zeroize the buffer
242 memset( m_buffer, 0, capacity() * sizeof(m_buffer[0]) );
245 /// Returns pointer to buffer array
246 value_type * buffer() CDS_NOEXCEPT
251 /// Returns pointer to buffer array
252 value_type * buffer() const CDS_NOEXCEPT
260 }} // namespace cds::opt
262 #endif // #ifndef CDSLIB_OPT_BUFFER_H