7 #ifndef TREELITE_DETAIL_CONTIGUOUS_ARRAY_H_
8 #define TREELITE_DETAIL_CONTIGUOUS_ARRAY_H_
21 : buffer_(nullptr), size_(0), capacity_(0), owned_buffer_(true) {}
25 if (buffer_ && owned_buffer_) {
32 buffer_ =
static_cast<T*
>(std::malloc(
sizeof(T) * other.capacity()));
34 std::memcpy(buffer_, other.data(),
sizeof(T) * other.size());
36 capacity_ = other.capacity();
42 if (buffer_ && owned_buffer_) {
45 buffer_ =
static_cast<T*
>(std::malloc(
sizeof(T) * other.capacity()));
47 std::memcpy(buffer_, other.data(),
sizeof(T) * other.size());
49 capacity_ = other.capacity();
56 : buffer_(other.buffer_),
58 capacity_(other.capacity_),
59 owned_buffer_(other.owned_buffer_) {
60 other.buffer_ =
nullptr;
61 other.size_ = other.capacity_ = 0;
66 if (buffer_ && owned_buffer_) {
69 buffer_ = other.buffer_;
71 capacity_ = other.capacity_;
72 owned_buffer_ = other.owned_buffer_;
73 other.buffer_ =
nullptr;
74 other.size_ = other.capacity_ = 0;
82 clone.buffer_ =
static_cast<T*
>(std::malloc(
sizeof(T) * capacity_));
83 TREELITE_CHECK(clone.buffer_) <<
"Could not allocate memory for the clone";
84 std::memcpy(clone.buffer_, buffer_,
sizeof(T) * size_);
88 clone.buffer_ =
nullptr;
91 clone.capacity_ = capacity_;
92 clone.owned_buffer_ =
true;
98 if (buffer_ && owned_buffer_) {
101 buffer_ =
static_cast<T*
>(prealloc_buf);
104 owned_buffer_ =
false;
107 template <
typename T>
112 template <
typename T>
117 template <
typename T>
119 return &buffer_[Size()];
122 template <
typename T>
124 return &buffer_[Size()];
127 template <
typename T>
129 return buffer_[Size() - 1];
132 template <
typename T>
134 return buffer_[Size() - 1];
137 template <
typename T>
142 template <
typename T>
144 return (Size() == 0);
147 template <
typename T>
149 TREELITE_CHECK(owned_buffer_) <<
"Cannot resize when using a foreign buffer; clone first";
150 T* newbuf =
static_cast<T*
>(std::realloc(
static_cast<void*
>(buffer_),
sizeof(T) * newsize));
156 template <
typename T>
158 Resize(newsize, T{});
161 template <
typename T>
163 TREELITE_CHECK(owned_buffer_) <<
"Cannot resize when using a foreign buffer; clone first";
164 std::size_t oldsize = Size();
165 if (newsize > capacity_) {
166 std::size_t newcapacity = capacity_;
167 if (newcapacity == 0) {
170 while (newcapacity < newsize) {
173 Reserve(newcapacity);
175 for (std::size_t i = oldsize; i < newsize; ++i) {
181 template <
typename T>
183 TREELITE_CHECK(owned_buffer_) <<
"Cannot clear when using a foreign buffer; clone first";
187 template <
typename T>
189 TREELITE_CHECK(owned_buffer_) <<
"Cannot add element when using a foreign buffer; clone first";
190 if (size_ == capacity_) {
191 if (capacity_ == 0) {
194 Reserve(capacity_ * 2);
197 buffer_[size_++] = t;
200 template <
typename T>
202 TREELITE_CHECK(owned_buffer_) <<
"Cannot add elements when using a foreign buffer; clone first";
206 std::size_t newsize = size_ + other.size();
207 if (newsize > capacity_) {
208 std::size_t newcapacity = capacity_;
209 if (newcapacity == 0) {
212 while (newcapacity <= newsize) {
215 Reserve(newcapacity);
217 std::memcpy(&buffer_[size_],
static_cast<void const*
>(other.data()),
sizeof(T) * other.size());
221 template <
typename T>
223 TREELITE_CHECK(owned_buffer_) <<
"Cannot add elements when using a foreign buffer; clone first";
227 std::size_t newsize = size_ + other.
Size();
228 if (newsize > capacity_) {
229 std::size_t newcapacity = capacity_;
230 if (newcapacity == 0) {
233 while (newcapacity <= newsize) {
236 Reserve(newcapacity);
238 std::memcpy(&buffer_[size_],
static_cast<void const*
>(other.
Data()),
sizeof(T) * other.
Size());
242 template <
typename T>
244 auto const size = Size();
245 std::vector<T> vec(size);
246 std::copy(buffer_, buffer_ + size, vec.begin());
250 template <
typename T>
252 if (Size() != other.
Size()) {
255 for (std::size_t i = 0; i < Size(); ++i) {
256 if (buffer_[i] != other.buffer_[i]) {
263 template <
typename T>
268 template <
typename T>
273 template <
typename T>
279 template <
typename T>
285 template <
typename T>
287 if (idx < 0 ||
static_cast<std::size_t
>(idx) >= Size()) {
290 return buffer_[
static_cast<std::size_t
>(idx)];
293 template <
typename T>
295 if (idx < 0 ||
static_cast<std::size_t
>(idx) >= Size()) {
298 return buffer_[
static_cast<std::size_t
>(idx)];
Definition: contiguous_array.h:17
T * End()
Definition: contiguous_array.h:118
T & Back()
Definition: contiguous_array.h:128
ContiguousArray Clone() const
Definition: contiguous_array.h:79
bool Empty() const
Definition: contiguous_array.h:143
~ContiguousArray()
Definition: contiguous_array.h:24
T & operator[](std::size_t idx)
Definition: contiguous_array.h:264
std::vector< T > AsVector() const
Definition: contiguous_array.h:243
void Reserve(std::size_t newsize)
Definition: contiguous_array.h:148
T * Data()
Definition: contiguous_array.h:108
std::size_t Size() const
Definition: contiguous_array.h:138
T & at(std::size_t idx)
Definition: contiguous_array.h:274
void PushBack(T t)
Definition: contiguous_array.h:188
void Resize(std::size_t newsize)
Definition: contiguous_array.h:157
ContiguousArray()
Definition: contiguous_array.h:20
void UseForeignBuffer(void *prealloc_buf, std::size_t size)
Definition: contiguous_array.h:97
ContiguousArray & operator=(ContiguousArray const &)=delete
void Clear()
Definition: contiguous_array.h:182
void Extend(std::vector< T > const &other)
Definition: contiguous_array.h:201
bool operator==(ContiguousArray const &other)
Definition: contiguous_array.h:251
logging facility for Treelite
#define TREELITE_LOG(severity)
Definition: logging.h:84
#define TREELITE_CHECK(x)
Definition: logging.h:70
#define TREELITE_CHECK_EQ(x, y)
Definition: logging.h:77
#define TREELITE_CHECK_LT(x, y)
Definition: logging.h:73
Definition: contiguous_array.h:14