Line data Source code
1 :
2 : /* Copyright (c) 2007-2016, Stefan Eilemann <eile@equalizergraphics.com>
3 : * Daniel Nachbaur <danielnachbaur@gmail.com>
4 : *
5 : * This library is free software; you can redistribute it and/or modify it under
6 : * the terms of the GNU Lesser General Public License version 2.1 as published
7 : * by the Free Software Foundation.
8 : *
9 : * This library is distributed in the hope that it will be useful, but WITHOUT
10 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12 : * details.
13 : *
14 : * You should have received a copy of the GNU Lesser General Public License
15 : * along with this library; if not, write to the Free Software Foundation, Inc.,
16 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 : */
18 :
19 : namespace lunchbox
20 : {
21 : template <class T>
22 1 : Buffer<T>::Buffer(const Buffer<T>& from)
23 : : _data(nullptr)
24 : , _size(0)
25 1 : , _maxSize(0)
26 : {
27 1 : if (!from.isEmpty())
28 0 : *this = from;
29 1 : }
30 :
31 : template <class T>
32 : Buffer<T>::Buffer(Buffer<T>&& from)
33 : : _data(std::move(from._data))
34 : , _size(from._size)
35 : , _maxSize(from._maxSize)
36 : {
37 : from._data = nullptr;
38 : from._size = 0;
39 : from._maxSize = 0;
40 : }
41 :
42 : template <class T>
43 : T* Buffer<T>::pack()
44 : {
45 : if (_maxSize != _size)
46 : {
47 : _data = static_cast<T*>(realloc(_data, _size * sizeof(T)));
48 : _maxSize = _size;
49 : }
50 : return _data;
51 : }
52 :
53 : template <class T>
54 0 : Buffer<T>& Buffer<T>::operator=(const Buffer<T>& from)
55 : {
56 0 : if (this != &from)
57 0 : replace(from);
58 0 : return *this;
59 : }
60 :
61 : template <class T>
62 : Buffer<T>& Buffer<T>::operator=(Buffer<T>&& from)
63 : {
64 : if (this == &from)
65 : return *this;
66 : std::swap(_data, from._data);
67 : std::swap(_size, from._size);
68 : std::swap(_maxSize, from._maxSize);
69 : return *this;
70 : }
71 :
72 : template <class T>
73 : T* Buffer<T>::resize(const uint64_t newSize)
74 : {
75 : _size = newSize;
76 : if (newSize <= _maxSize)
77 : return _data;
78 :
79 : // avoid excessive reallocs
80 : const uint64_t nElems = newSize + (newSize >> 3);
81 : const uint64_t nBytes = nElems * sizeof(T);
82 : _data = static_cast<T*>(realloc(_data, nBytes));
83 : _maxSize = nElems;
84 : return _data;
85 : }
86 :
87 : template <class T>
88 : void Buffer<T>::grow(const uint64_t newSize)
89 : {
90 : if (newSize > _size)
91 : resize(newSize);
92 : }
93 :
94 : template <class T>
95 0 : T* Buffer<T>::reserve(const uint64_t newSize)
96 : {
97 0 : if (newSize <= _maxSize)
98 0 : return _data;
99 :
100 0 : _data = static_cast<T*>(realloc(_data, newSize * sizeof(T)));
101 0 : _maxSize = newSize;
102 0 : return _data;
103 : }
104 :
105 : template <class T>
106 : T* Buffer<T>::reset(const uint64_t newSize)
107 : {
108 : reserve(newSize);
109 : setSize(newSize);
110 : return _data;
111 : }
112 :
113 : template <class T>
114 : void Buffer<T>::append(const T* data, const uint64_t size)
115 : {
116 : LBASSERT(data);
117 : LBASSERT(size);
118 :
119 : const uint64_t oldSize = _size;
120 : resize(oldSize + size);
121 : memcpy(_data + oldSize, data, size * sizeof(T));
122 : }
123 :
124 : template <class T>
125 : void Buffer<T>::append(const T& element)
126 : {
127 : append(&element, 1);
128 : }
129 :
130 : template <class T>
131 0 : void Buffer<T>::replace(const void* data, const uint64_t size)
132 : {
133 0 : LBASSERT(data);
134 0 : LBASSERT(size);
135 :
136 0 : reserve(size);
137 0 : memcpy(_data, data, size * sizeof(T));
138 0 : _size = size;
139 0 : }
140 :
141 : template <class T>
142 : void Buffer<T>::swap(Buffer<T>& buffer)
143 : {
144 : T* tmpData = buffer._data;
145 : const uint64_t tmpSize = buffer._size;
146 : const uint64_t tmpMaxSize = buffer._maxSize;
147 :
148 : buffer._data = _data;
149 : buffer._size = _size;
150 : buffer._maxSize = _maxSize;
151 :
152 : _data = tmpData;
153 : _size = tmpSize;
154 : _maxSize = tmpMaxSize;
155 : }
156 :
157 : template <class T>
158 : bool Buffer<T>::setSize(const uint64_t size)
159 : {
160 : LBASSERT(size <= _maxSize);
161 : if (size > _maxSize)
162 : return false;
163 :
164 : _size = size;
165 : return true;
166 : }
167 : }
|