NCBI C++ ToolKit
simple_buffer.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef UTIL_SIMPLE_BUFFER__HPP
2 #define UTIL_SIMPLE_BUFFER__HPP
3 
4 /* $Id: simple_buffer.hpp 92290 2021-01-04 18:13:16Z grichenk $
5  * ===========================================================================
6  *
7  * PUBLIC DOMAIN NOTICE
8  * National Center for Biotechnology Information
9  *
10  * This software/database is a "United States Government Work" under the
11  * terms of the United States Copyright Act. It was written as part of
12  * the author's official duties as a United States Government employee and
13  * thus cannot be copyrighted. This software/database is freely available
14  * to the public for use. The National Library of Medicine and the U.S.
15  * Government have not placed any restriction on its use or reproduction.
16  *
17  * Although all reasonable efforts have been taken to ensure the accuracy
18  * and reliability of the software and data, the NLM and the U.S.
19  * Government do not and cannot warrant the performance or results that
20  * may be obtained by using this software or data. The NLM and the U.S.
21  * Government disclaim all warranties, express or implied, including
22  * warranties of performance, merchantability or fitness for any particular
23  * purpose.
24  *
25  * Please cite the author in any work or product based on this material.
26  *
27  * ===========================================================================
28  *
29  * Authors: Anatoliy Kuznetsov
30  *
31  * File Description: Simple (fast) resizable buffer
32  *
33  */
34 
35 #include <corelib/ncbistd.hpp>
36 
38 
39 
41 {
42 public:
43  static size_t GetNewCapacity(size_t /*cur_capacity*/,
44  size_t requested_size)
45  { return requested_size; }
46 };
47 
49 {
50 public:
51  static size_t GetNewCapacity(size_t /*cur_capacity*/,
52  size_t requested_size)
53  {
54  size_t new_size = requested_size + requested_size / 2;
55 
56  // Overrun
57  if (new_size < requested_size)
59  return new_size;
60  }
61 };
62 
64 {
65 public:
66  static size_t GetNewCapacity(size_t /*cur_capacity*/,
67  size_t required_size)
68  {
69  size_t new_size = required_size * 2;
70  // Overrun
71  if (new_size < required_size)
73  return new_size;
74  }
75 };
76 
77 /// Reallocable memory buffer (no memory copy overhead)
78 /// Mimics vector<>, without the overhead of explicit initialization of all
79 /// items
80 ///
81 
82 template <typename T = unsigned char,
83  typename ResizeStrategy = CPowerOfTwoResizeStrategy>
85 {
86 public:
87  typedef T value_type;
88  typedef size_t size_type;
89 public:
90  explicit CSimpleBufferT(size_type new_size = 0)
91  {
92  m_Buffer = NULL;
93  if (new_size) {
94  m_Buffer = x_Allocate(new_size);
95  }
96  m_Size = m_Capacity = new_size;
97  }
99  {
100  x_Deallocate();
101  }
102 
104  {
105  size_type new_size = sb.capacity();
106  m_Capacity = new_size;
107  m_Size = sb.size();
108  if (new_size) {
109  m_Buffer = x_Allocate(new_size);
110  memcpy(m_Buffer, sb.data(), m_Size * sizeof(value_type));
111  } else {
112  m_Buffer = NULL;
113  }
114  }
115 
117  {
118  if (this != &sb) {
119  if (sb.size() <= m_Capacity) {
120  if (sb.size() < m_Size) {
121  x_Fill(m_Buffer + sb.size(), 0xcd, m_Capacity - sb.size());
122  }
123  m_Size = sb.size();
124  } else {
125  x_Deallocate();
126  m_Buffer = x_Allocate(sb.capacity());
127  m_Capacity = sb.capacity();
128  m_Size = sb.size();
129  }
130  memcpy(m_Buffer, sb.data(), m_Size * sizeof(value_type));
131  }
132  return *this;
133  }
134 
135  CSimpleBufferT& append(const void* buf, size_t len)
136  {
137  size_t offs = m_Size;
138 
139  resize( m_Size + len );
140  memcpy( m_Buffer + offs, buf, len );
141  return *this;
142  }
143 
144  size_type size() const { return m_Size; }
145  size_type capacity() const { return m_Capacity; }
146 
147  void reserve(size_type new_size)
148  {
149  if (new_size > m_Capacity) {
150  value_type* new_buffer = x_Allocate(new_size);
151  if (m_Size) {
152  memcpy(new_buffer, m_Buffer, m_Size*sizeof(value_type));
153  }
154  x_Deallocate();
155  m_Buffer = new_buffer;
156  m_Capacity = new_size;
157  }
158  }
159 
160  void resize(size_type new_size)
161  {
163  if (new_size <= m_Capacity) {
164  if (new_size < m_Size) {
165  x_Fill(m_Buffer + new_size, 0xcd, m_Capacity - new_size);
166  }
167  m_Size = new_size;
168  } else {
169  size_t new_capacity =
170  ResizeStrategy::GetNewCapacity(m_Capacity,new_size);
171  value_type* new_buffer = x_Allocate(new_capacity);
172  if (m_Size) {
173  memcpy(new_buffer, m_Buffer, m_Size*sizeof(value_type));
174  }
175  x_Deallocate();
176  m_Buffer = new_buffer;
177  m_Capacity = new_capacity;
178  m_Size = new_size;
179  }
180  }
181 
182  /// Resize the buffer. No data preservation.
183  void resize_mem(size_type new_size)
184  {
185  if (new_size <= m_Capacity) {
186  if (new_size < m_Size) {
187  x_Fill(m_Buffer + new_size, 0xcd, m_Capacity - new_size);
188  }
189  m_Size = new_size;
190  } else {
191  x_Deallocate();
192  size_t new_capacity = ResizeStrategy::GetNewCapacity(m_Capacity,new_size);
193  m_Buffer = x_Allocate(new_capacity);
194  m_Capacity = new_capacity;
195  m_Size = new_size;
196  }
197  }
198 
199  void swap(CSimpleBufferT<T>& other)
200  {
201  std::swap(m_Buffer, other.m_Buffer);
202  std::swap(m_Size, other.m_Size);
204  }
205 
206  /// Reserve memory. No data preservation guarantees.
207  void reserve_mem(size_type new_size)
208  {
209  if (new_size > m_Capacity) {
210  x_Deallocate();
211  m_Buffer = x_Allocate(new_size);
212  m_Capacity = new_size;
213  x_Fill(m_Buffer, 0xcd, m_Capacity);
214  }
215  }
216 
217  void clear()
218  {
219  resize(0);
220  }
221 
223  {
224  _ASSERT(m_Buffer);
225  _ASSERT(i < m_Size);
226  return m_Buffer[i];
227  }
229  {
230  _ASSERT(m_Buffer);
231  _ASSERT(i < m_Size);
232  return m_Buffer[i];
233  }
234 
235  const value_type* data() const
236  {
237  return m_Buffer;
238  }
239 
241  {
242  return m_Buffer;
243  }
244 
245 
246 private:
247 
248 #ifdef _DEBUG
249  void x_Fill(value_type* buffer, int value, size_t elem)
250  {
251  if (m_Buffer) {
252  memset(buffer, value, elem * sizeof(value_type));
253  }
254  }
255 #else
256  void x_Fill(value_type*, int, size_t) {}
257 #endif
258 
260  {
261  if (m_Buffer) {
262  x_Fill(m_Buffer, 0xfd, m_Capacity);
263  delete [] m_Buffer;
264  }
265  m_Buffer = NULL;
266  m_Size = m_Capacity = 0;
267  }
268 
269  value_type* x_Allocate(size_t elem)
270  {
271  value_type* buf = new value_type[elem];
272  x_Fill(buf, 0xcd, elem);
273  return buf;
274  }
275 
276 private:
280 };
281 
283 
284 
286 
287 #endif
static size_t GetNewCapacity(size_t, size_t requested_size)
static size_t GetNewCapacity(size_t, size_t required_size)
Reallocable memory buffer (no memory copy overhead) Mimics vector<>, without the overhead of explicit...
const value_type * data() const
value_type * m_Buffer
value_type * x_Allocate(size_t elem)
CSimpleBufferT & append(const void *buf, size_t len)
const value_type & operator[](size_type i) const
void resize_mem(size_type new_size)
Resize the buffer. No data preservation.
size_type m_Capacity
value_type * data()
void resize(size_type new_size)
CSimpleBufferT(size_type new_size=0)
void swap(CSimpleBufferT< T > &other)
size_type size() const
void reserve_mem(size_type new_size)
Reserve memory. No data preservation guarantees.
void reserve(size_type new_size)
value_type & operator[](size_type i)
CSimpleBufferT(const CSimpleBufferT &sb)
CSimpleBufferT & operator=(const CSimpleBufferT &sb)
size_type capacity() const
void x_Fill(value_type *buffer, int value, size_t elem)
static size_t GetNewCapacity(size_t, size_t requested_size)
char value[7]
Definition: config.c:431
Include a standard set of the NCBI C++ Toolkit most basic headers.
#define T(s)
Definition: common.h:230
void swap(NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair1, NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair2)
Definition: ncbimisc.hpp:1508
#define NULL
Definition: ncbistd.hpp:225
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
char * buf
int i
int len
T max(T x_, T y_)
static pcre_uint8 * buffer
Definition: pcretest.c:1051
CSimpleBufferT CSimpleBuffer
#define _ASSERT
Modified on Fri Jan 05 07:24:19 2024 by modify_doxy.py rev. 669887