tesseract v5.3.3.20231005
genericvector.h
Go to the documentation of this file.
1
2// File: genericvector.h
3// Description: Generic vector class
4// Author: Daria Antonova
5//
6// (C) Copyright 2007, Google Inc.
7// Licensed under the Apache License, Version 2.0 (the "License");
8// you may not use this file except in compliance with the License.
9// You may obtain a copy of the License at
10// http://www.apache.org/licenses/LICENSE-2.0
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16//
18//
19#ifndef TESSERACT_CCUTIL_GENERICVECTOR_H_
20#define TESSERACT_CCUTIL_GENERICVECTOR_H_
21
22#include "helpers.h"
23#include "serialis.h"
24
25#include <algorithm>
26#include <cassert>
27#include <climits> // for LONG_MAX
28#include <cstdint> // for uint32_t
29#include <cstdio>
30#include <cstdlib>
31#include <functional> // for std::function
32
33namespace tesseract {
34
35// Use PointerVector<T> below in preference to GenericVector<T*>, as that
36// provides automatic deletion of pointers, [De]Serialize that works, and
37// sort that works.
38template <typename T>
40public:
43 }
44
45 // Copy
47 this->init(other.size());
48 this->operator+=(other);
49 }
52
54
55 // Reserve some memory.
56 void reserve(int size);
57 // Double the size of the internal array.
59
60 // Resizes to size and sets all values to t.
61 void init_to_size(int size, const T &t);
62 void resize(int size, const T &t);
63 // Resizes to size without any initialization.
64 void resize_no_init(int size) {
67 }
68
69 // Return the size used.
70 unsigned size() const {
71 return size_used_;
72 }
73 // Workaround to avoid g++ -Wsign-compare warnings.
74 size_t unsigned_size() const {
75 static_assert(sizeof(size_used_) <= sizeof(size_t), "Wow! sizeof(size_t) < sizeof(int32_t)!!");
76 assert(0 <= size_used_);
77 return static_cast<size_t>(size_used_);
78 }
79 int size_reserved() const {
80 return size_reserved_;
81 }
82
83 // Return true if empty.
84 bool empty() const {
85 return size_used_ == 0;
86 }
87
88 // Return the object from an index.
89 T &at(int index) const {
90 assert(index >= 0 && index < size_used_);
91 return data_[index];
92 }
93
94 T &back() const;
95 T &operator[](int index) const;
96 // Returns the last object and removes it.
98
99 // Return the index of the T object.
100 int get_index(const T &object) const;
101
102 // Push an element in the end of the array
103 int push_back(T object);
104 void operator+=(const T &t);
105
106 // Set the value at the given index
107 void set(const T &t, int index);
108
109 // Insert t at the given index, push other elements to the right.
110 void insert(const T &t, int index);
111
112 // Removes an element at the given index and
113 // shifts the remaining elements to the left.
114 void remove(int index);
115
116 // Truncates the array to the given size by removing the end.
117 // If the current size is less, the array is not expanded.
118 void truncate(int size) {
119 if (size < size_used_) {
121 }
122 }
123
124 // Add a callback to be called to delete the elements when the array took
125 // their ownership.
126 void set_clear_callback(const std::function<void(T)> &cb) {
127 clear_cb_ = cb;
128 }
129
130 // Clear the array, calling the clear callback function if any.
131 // All the owned callbacks are also deleted.
132 // If you don't want the callbacks to be deleted, before calling clear, set
133 // the callback to nullptr.
134 void clear();
135
136 // Delete objects pointed to by data_[i]
138
139 // This method clears the current object, then, does a shallow copy of
140 // its argument, and finally invalidates its argument.
141 // Callbacks are moved to the current object;
143
144 // Read/Write the array to a file. This does _NOT_ read/write the callbacks.
145 // The callback given must be permanent since they will be called more than
146 // once. The given callback will be deleted at the end.
147 // If the callbacks are nullptr, then the data is simply read/written using
148 // fread (and swapping)/fwrite.
149 // Returns false on error or if the callback returns false.
150 // DEPRECATED. Use [De]Serialize[Classes] instead.
151 bool write(FILE *f, const std::function<bool(FILE *, const T &)> &cb) const;
152 bool read(TFile *f, const std::function<bool(TFile *, T *)> &cb);
153 // Writes a vector of simple types to the given file. Assumes that bitwise
154 // read/write of T will work. Returns false in case of error.
155 // TODO(rays) Change all callers to use TFile and remove deprecated methods.
156 bool Serialize(FILE *fp) const;
157 bool Serialize(TFile *fp) const;
158 // Reads a vector of simple types from the given file. Assumes that bitwise
159 // read/write will work with ReverseN according to sizeof(T).
160 // Returns false in case of error.
161 // If swap is true, assumes a big/little-endian swap is needed.
162 // TFile is assumed to know about swapping.
163 bool DeSerialize(bool swap, FILE *fp);
165 // Writes a vector of classes to the given file. Assumes the existence of
166 // bool T::Serialize(FILE* fp) const that returns false in case of error.
167 // Returns false in case of error.
168 bool SerializeClasses(FILE *fp) const;
169 // Reads a vector of classes from the given file. Assumes the existence of
170 // bool T::Deserialize(bool swap, FILE* fp) that returns false in case of
171 // error. Also needs T::T() and T::T(constT&), as init_to_size is used in
172 // this function. Returns false in case of error.
173 // If swap is true, assumes a big/little-endian swap is needed.
175
176 // Reverses the elements of the vector.
177 void reverse() {
178 for (int i = 0; i < size_used_ / 2; ++i) {
179 std::swap(data_[i], data_[size_used_ - 1 - i]);
180 }
181 }
182
183 // Sorts the members of this vector using the less than comparator (cmp_lt),
184 // which compares the values. Useful for GenericVectors to primitive types.
185 // Will not work so great for pointers (unless you just want to sort some
186 // pointers). You need to provide a specialization to sort_cmp to use
187 // your type.
188 void sort();
189
190 // Sort the array into the order defined by the qsort function comparator.
191 // The comparator function is as defined by qsort, ie. it receives pointers
192 // to two Ts and returns negative if the first element is to appear earlier
193 // in the result and positive if it is to appear later, with 0 for equal.
194 void sort(int (*comparator)(const void *, const void *)) {
195 qsort(data_, size_used_, sizeof(*data_), comparator);
196 }
197
198 // Swaps the elements with the given indices.
199 void swap(int index1, int index2) {
200 if (index1 != index2) {
201 T tmp = data_[index1];
202 data_[index1] = data_[index2];
203 data_[index2] = tmp;
204 }
205 }
206 // Returns true if all elements of *this are within the given range.
207 // Only uses operator<
208 /*bool WithinBounds(const T& rangemin, const T& rangemax) const {
209 for (int i = 0; i < size_used_; ++i) {
210 if (data_[i] < rangemin || rangemax < data_[i]) {
211 return false;
212 }
213 }
214 return true;
215}*/
216
217protected:
218 // Init the object, allocating size memory.
219 void init(int size);
220
221 // We are assuming that the object generally placed in the
222 // vector are small enough that for efficiency it makes sense
223 // to start with a larger initial size.
224 static const int kDefaultVectorSize = 4;
225 int32_t size_used_{};
226 int32_t size_reserved_{};
228 std::function<void(T)> clear_cb_;
229};
230
231// The default FileReader loads the whole file into the vector of char,
232// returning false on error.
233inline bool LoadDataFromFile(const char *filename, GenericVector<char> *data) {
234 bool result = false;
235 FILE *fp = fopen(filename, "rb");
236 if (fp != nullptr) {
237 fseek(fp, 0, SEEK_END);
238 auto size = std::ftell(fp);
239 fseek(fp, 0, SEEK_SET);
240 // Trying to open a directory on Linux sets size to LONG_MAX. Catch it here.
241 if (size > 0 && size < LONG_MAX) {
242 // reserve an extra byte in case caller wants to append a '\0' character
243 data->reserve(size + 1);
244 data->resize_no_init(size);
245 result = static_cast<long>(fread(&(*data)[0], 1, size, fp)) == size;
246 }
247 fclose(fp);
248 }
249 return result;
250}
251
252// The default FileWriter writes the vector of char to the filename file,
253// returning false on error.
254inline bool SaveDataToFile(const GenericVector<char> &data, const char *filename) {
255 FILE *fp = fopen(filename, "wb");
256 if (fp == nullptr) {
257 return false;
258 }
259 bool result = fwrite(&data[0], 1, data.size(), fp) == data.size();
260 fclose(fp);
261 return result;
262}
263
264// Used by sort()
265// return < 0 if t1 < t2
266// return 0 if t1 == t2
267// return > 0 if t1 > t2
268template <typename T>
269int sort_cmp(const void *t1, const void *t2) {
270 const T *a = static_cast<const T *>(t1);
271 const T *b = static_cast<const T *>(t2);
272 if (*a < *b) {
273 return -1;
274 }
275 if (*b < *a) {
276 return 1;
277 }
278 return 0;
279}
280
281// Used by PointerVector::sort()
282// return < 0 if t1 < t2
283// return 0 if t1 == t2
284// return > 0 if t1 > t2
285template <typename T>
286int sort_ptr_cmp(const void *t1, const void *t2) {
287 const T *a = *static_cast<T *const *>(t1);
288 const T *b = *static_cast<T *const *>(t2);
289 if (*a < *b) {
290 return -1;
291 }
292 if (*b < *a) {
293 return 1;
294 }
295 return 0;
296}
297
298// Subclass for a vector of pointers. Use in preference to GenericVector<T*>
299// as it provides automatic deletion and correct serialization, with the
300// corollary that all copy operations are deep copies of the pointed-to objects.
301template <typename T>
302class PointerVector : public GenericVector<T *> {
303public:
305 explicit PointerVector(int size) : GenericVector<T *>(size) {}
307 // Clear must be called here, even though it is called again by the base,
308 // as the base will call the wrong clear.
309 clear();
310 }
311 // Copy must be deep, as the pointers will be automatically deleted on
312 // destruction.
313 PointerVector(const PointerVector &other) : GenericVector<T *>(other) {
314 this->init(other.size());
315 this->operator+=(other);
316 }
318 this->reserve(this->size_used_ + other.size_used_);
319 for (unsigned i = 0; i < other.size(); ++i) {
320 this->push_back(new T(*other.data_[i]));
321 }
322 return *this;
323 }
324
326 if (&other != this) {
327 this->truncate(0);
328 this->operator+=(other);
329 }
330 return *this;
331 }
332
333 // Removes an element at the given index and
334 // shifts the remaining elements to the left.
335 void remove(int index) {
336 delete GenericVector<T *>::data_[index];
338 }
339
340 // Truncates the array to the given size by removing the end.
341 // If the current size is less, the array is not expanded.
342 void truncate(int size) {
343 for (int i = size; i < GenericVector<T *>::size_used_; ++i) {
345 }
347 }
348
349 // Clear the array, calling the clear callback function if any.
350 // All the owned callbacks are also deleted.
351 // If you don't want the callbacks to be deleted, before calling clear, set
352 // the callback to nullptr.
353 void clear() {
356 }
357
358 // Writes a vector of (pointers to) classes to the given file. Assumes the
359 // existence of bool T::Serialize(FILE*) const that returns false in case of
360 // error. There is no Serialize for simple types, as you would have a
361 // normal GenericVector of those.
362 // Returns false in case of error.
363 bool Serialize(FILE *fp) const {
364 int32_t used = GenericVector<T *>::size_used_;
365 if (fwrite(&used, sizeof(used), 1, fp) != 1) {
366 return false;
367 }
368 for (int i = 0; i < used; ++i) {
369 int8_t non_null = GenericVector<T *>::data_[i] != nullptr;
370 if (fwrite(&non_null, sizeof(non_null), 1, fp) != 1) {
371 return false;
372 }
373 if (non_null && !GenericVector<T *>::data_[i]->Serialize(fp)) {
374 return false;
375 }
376 }
377 return true;
378 }
379 bool Serialize(TFile *fp) const {
380 int32_t used = GenericVector<T *>::size_used_;
381 if (fp->FWrite(&used, sizeof(used), 1) != 1) {
382 return false;
383 }
384 for (int i = 0; i < used; ++i) {
385 int8_t non_null = GenericVector<T *>::data_[i] != nullptr;
386 if (fp->FWrite(&non_null, sizeof(non_null), 1) != 1) {
387 return false;
388 }
389 if (non_null && !GenericVector<T *>::data_[i]->Serialize(fp)) {
390 return false;
391 }
392 }
393 return true;
394 }
395 // Reads a vector of (pointers to) classes to the given file. Assumes the
396 // existence of bool T::DeSerialize(bool, Tfile*) const that returns false in
397 // case of error. There is no Serialize for simple types, as you would have a
398 // normal GenericVector of those.
399 // If swap is true, assumes a big/little-endian swap is needed.
400 // Also needs T::T(), as new T is used in this function.
401 // Returns false in case of error.
402 bool DeSerialize(bool swap, FILE *fp) {
403 uint32_t reserved;
404 if (fread(&reserved, sizeof(reserved), 1, fp) != 1) {
405 return false;
406 }
407 if (swap) {
408 Reverse32(&reserved);
409 }
410 // Arbitrarily limit the number of elements to protect against bad data.
411 assert(reserved <= UINT16_MAX);
412 if (reserved > UINT16_MAX) {
413 return false;
414 }
416 truncate(0);
417 for (uint32_t i = 0; i < reserved; ++i) {
418 int8_t non_null;
419 if (fread(&non_null, sizeof(non_null), 1, fp) != 1) {
420 return false;
421 }
422 T *item = nullptr;
423 if (non_null != 0) {
424 item = new T;
425 if (!item->DeSerialize(swap, fp)) {
426 delete item;
427 return false;
428 }
429 this->push_back(item);
430 } else {
431 // Null elements should keep their place in the vector.
432 this->push_back(nullptr);
433 }
434 }
435 return true;
436 }
437
438 // Sorts the items pointed to by the members of this vector using
439 // t::operator<().
440 void sort() {
441 this->GenericVector<T *>::sort(&sort_ptr_cmp<T>);
442 }
443};
444
445template <typename T>
447 size_used_ = 0;
448 if (size <= 0) {
449 data_ = nullptr;
450 size_reserved_ = 0;
451 } else {
452 if (size < kDefaultVectorSize) {
453 size = kDefaultVectorSize;
454 }
455 data_ = new T[size];
456 size_reserved_ = size;
457 }
458 clear_cb_ = nullptr;
459}
460
461template <typename T>
463 clear();
464}
465
466// Reserve some memory. If the internal array contains elements, they are
467// copied.
468template <typename T>
470 if (size_reserved_ >= size || size <= 0) {
471 return;
472 }
473 if (size < kDefaultVectorSize) {
474 size = kDefaultVectorSize;
475 }
476 T *new_array = new T[size];
477 for (int i = 0; i < size_used_; ++i) {
478 new_array[i] = data_[i];
479 }
480 delete[] data_;
481 data_ = new_array;
482 size_reserved_ = size;
483}
484
485template <typename T>
487 if (size_reserved_ == 0) {
488 reserve(kDefaultVectorSize);
489 } else {
490 reserve(2 * size_reserved_);
491 }
492}
493
494// Resizes to size and sets all values to t.
495template <typename T>
496void GenericVector<T>::init_to_size(int size, const T &t) {
497 reserve(size);
498 size_used_ = size;
499 for (int i = 0; i < size; ++i) {
500 data_[i] = t;
501 }
502}
503
504template <typename T>
505void GenericVector<T>::resize(int size, const T &t) {
506 init_to_size(size, t);
507}
508
509template <typename T>
510T &GenericVector<T>::operator[](int index) const {
511 assert(index >= 0 && index < size_used_);
512 return data_[index];
513}
514
515template <typename T>
517 assert(size_used_ > 0);
518 return data_[size_used_ - 1];
519}
520// Returns the last object and removes it.
521template <typename T>
523 assert(size_used_ > 0);
524 return data_[--size_used_];
525}
526
527// Return the object from an index.
528template <typename T>
529void GenericVector<T>::set(const T &t, int index) {
530 assert(index >= 0 && index < size_used_);
531 data_[index] = t;
532}
533
534// Shifts the rest of the elements to the right to make
535// space for the new elements and inserts the given element
536// at the specified index.
537template <typename T>
538void GenericVector<T>::insert(const T &t, int index) {
539 assert(index >= 0 && index <= size_used_);
540 if (size_reserved_ == size_used_) {
541 double_the_size();
542 }
543 for (int i = size_used_; i > index; --i) {
544 data_[i] = data_[i - 1];
545 }
546 data_[index] = t;
547 size_used_++;
548}
549
550// Removes an element at the given index and
551// shifts the remaining elements to the left.
552template <typename T>
554 assert(index >= 0 && index < size_used_);
555 for (int i = index; i < size_used_ - 1; ++i) {
556 data_[i] = data_[i + 1];
557 }
558 size_used_--;
559}
560
561// Return the index of the T object.
562template <typename T>
563int GenericVector<T>::get_index(const T &object) const {
564 for (int i = 0; i < size_used_; ++i) {
565 if (object == data_[i]) {
566 return i;
567 }
568 }
569 return -1;
570}
571
572// Add an element in the array
573template <typename T>
575 int index = 0;
576 if (size_used_ == size_reserved_) {
577 double_the_size();
578 }
579 index = size_used_++;
580 data_[index] = std::move(object);
581 return index;
582}
583
584template <typename T>
586 push_back(t);
587}
588
589template <typename T>
591 this->reserve(size_used_ + other.size_used_);
592 for (unsigned i = 0; i < other.size(); ++i) {
593 this->operator+=(other.data_[i]);
594 }
595 return *this;
596}
597
598template <typename T>
600 if (&other != this) {
601 this->truncate(0);
602 this->operator+=(other);
603 }
604 return *this;
605}
606
607// Clear the array, calling the callback function if any.
608template <typename T>
610 if (size_reserved_ > 0 && clear_cb_ != nullptr) {
611 for (int i = 0; i < size_used_; ++i) {
612 clear_cb_(data_[i]);
613 }
614 }
615 delete[] data_;
616 data_ = nullptr;
617 size_used_ = 0;
618 size_reserved_ = 0;
619 clear_cb_ = nullptr;
620}
621
622template <typename T>
624 for (int i = 0; i < size_used_; ++i) {
625 delete data_[i];
626 }
627}
628
629template <typename T>
630bool GenericVector<T>::write(FILE *f, const std::function<bool(FILE *, const T &)> &cb) const {
631 if (fwrite(&size_reserved_, sizeof(size_reserved_), 1, f) != 1) {
632 return false;
633 }
634 if (fwrite(&size_used_, sizeof(size_used_), 1, f) != 1) {
635 return false;
636 }
637 if (cb != nullptr) {
638 for (int i = 0; i < size_used_; ++i) {
639 if (!cb(f, data_[i])) {
640 return false;
641 }
642 }
643 } else {
644 if (fwrite(data_, sizeof(T), size_used_, f) != unsigned_size()) {
645 return false;
646 }
647 }
648 return true;
649}
650
651template <typename T>
652bool GenericVector<T>::read(TFile *f, const std::function<bool(TFile *, T *)> &cb) {
653 int32_t reserved;
654 if (f->FReadEndian(&reserved, sizeof(reserved), 1) != 1) {
655 return false;
656 }
657 reserve(reserved);
658 if (f->FReadEndian(&size_used_, sizeof(size_used_), 1) != 1) {
659 return false;
660 }
661 if (cb != nullptr) {
662 for (int i = 0; i < size_used_; ++i) {
663 if (!cb(f, data_ + i)) {
664 return false;
665 }
666 }
667 } else {
668 if (f->FReadEndian(data_, sizeof(T), size_used_) != static_cast<unsigned>(size_used_)) {
669 return false;
670 }
671 }
672 return true;
673}
674
675// Writes a vector of simple types to the given file. Assumes that bitwise
676// read/write of T will work. Returns false in case of error.
677template <typename T>
678bool GenericVector<T>::Serialize(FILE *fp) const {
679 if (fwrite(&size_used_, sizeof(size_used_), 1, fp) != 1) {
680 return false;
681 }
682 if (fwrite(data_, sizeof(*data_), size_used_, fp) != unsigned_size()) {
683 return false;
684 }
685 return true;
686}
687template <typename T>
689 if (fp->FWrite(&size_used_, sizeof(size_used_), 1) != 1) {
690 return false;
691 }
692 if (fp->FWrite(data_, sizeof(*data_), size_used_) != size_used_) {
693 return false;
694 }
695 return true;
696}
697
698// Reads a vector of simple types from the given file. Assumes that bitwise
699// read/write will work with ReverseN according to sizeof(T).
700// Returns false in case of error.
701// If swap is true, assumes a big/little-endian swap is needed.
702template <typename T>
703bool GenericVector<T>::DeSerialize(bool swap, FILE *fp) {
704 uint32_t reserved;
705 if (fread(&reserved, sizeof(reserved), 1, fp) != 1) {
706 return false;
707 }
708 if (swap) {
709 Reverse32(&reserved);
710 }
711 // Arbitrarily limit the number of elements to protect against bad data.
712 assert(reserved <= UINT16_MAX);
713 if (reserved > UINT16_MAX) {
714 return false;
715 }
716 reserve(reserved);
717 size_used_ = reserved;
718 if (fread(data_, sizeof(T), size_used_, fp) != unsigned_size()) {
719 return false;
720 }
721 if (swap) {
722 for (int i = 0; i < size_used_; ++i) {
723 ReverseN(&data_[i], sizeof(data_[i]));
724 }
725 }
726 return true;
727}
728template <typename T>
730 uint32_t reserved;
731 if (fp->FReadEndian(&reserved, sizeof(reserved), 1) != 1) {
732 return false;
733 }
734 // Arbitrarily limit the number of elements to protect against bad data.
735 const uint32_t limit = 50000000;
736 assert(reserved <= limit);
737 if (reserved > limit) {
738 return false;
739 }
740 reserve(reserved);
741 size_used_ = reserved;
742 return fp->FReadEndian(data_, sizeof(T), size_used_) == size_used_;
743}
744
745// Writes a vector of classes to the given file. Assumes the existence of
746// bool T::Serialize(FILE* fp) const that returns false in case of error.
747// Returns false in case of error.
748template <typename T>
750 if (fwrite(&size_used_, sizeof(size_used_), 1, fp) != 1) {
751 return false;
752 }
753 for (int i = 0; i < size_used_; ++i) {
754 if (!data_[i].Serialize(fp)) {
755 return false;
756 }
757 }
758 return true;
759}
760
761// Reads a vector of classes from the given file. Assumes the existence of
762// bool T::Deserialize(bool swap, FILE* fp) that returns false in case of
763// error. Also needs T::T() and T::T(constT&), as init_to_size is used in
764// this function. Returns false in case of error.
765// If swap is true, assumes a big/little-endian swap is needed.
766template <typename T>
768 int32_t reserved;
769 if (fp->FReadEndian(&reserved, sizeof(reserved), 1) != 1) {
770 return false;
771 }
772 T empty;
773 init_to_size(reserved, empty);
774 for (int i = 0; i < reserved; ++i) {
775 if (!data_[i].DeSerialize(fp)) {
776 return false;
777 }
778 }
779 return true;
780}
781
782// This method clear the current object, then, does a shallow copy of
783// its argument, and finally invalidates its argument.
784template <typename T>
786 this->clear();
787 this->data_ = from->data_;
788 this->size_reserved_ = from->size_reserved_;
789 this->size_used_ = from->size_used_;
790 this->clear_cb_ = from->clear_cb_;
791 from->data_ = nullptr;
792 from->clear_cb_ = nullptr;
793 from->size_used_ = 0;
794 from->size_reserved_ = 0;
795}
796
797template <typename T>
799 sort(&sort_cmp<T>);
800}
801
802} // namespace tesseract
803
804#endif // TESSERACT_CCUTIL_GENERICVECTOR_H_
ICOORD & operator+=(ICOORD &op1, const ICOORD &op2)
Definition: points.h:372
void ReverseN(void *ptr, int num_bytes)
Definition: helpers.h:184
bool DeSerialize(bool swap, FILE *fp, std::vector< T > &data)
Definition: helpers.h:205
bool Serialize(FILE *fp, const std::vector< T > &data)
Definition: helpers.h:236
int sort_cmp(const void *t1, const void *t2)
bool SaveDataToFile(const GenericVector< char > &data, const char *filename)
void Reverse32(void *ptr)
Definition: helpers.h:196
int sort_ptr_cmp(const void *t1, const void *t2)
bool LoadDataFromFile(const char *filename, GenericVector< char > *data)
size_t unsigned_size() const
Definition: genericvector.h:74
void resize(int size, const T &t)
void resize_no_init(int size)
Definition: genericvector.h:64
void operator+=(const T &t)
GenericVector(const GenericVector &other)
Definition: genericvector.h:46
void insert(const T &t, int index)
static const int kDefaultVectorSize
int get_index(const T &object) const
bool DeSerializeClasses(TFile *fp)
bool Serialize(TFile *fp) const
T & at(int index) const
Definition: genericvector.h:89
std::function< void(T)> clear_cb_
bool read(TFile *f, const std::function< bool(TFile *, T *)> &cb)
void swap(int index1, int index2)
void set_clear_callback(const std::function< void(T)> &cb)
void sort(int(*comparator)(const void *, const void *))
bool Serialize(FILE *fp) const
void set(const T &t, int index)
unsigned size() const
Definition: genericvector.h:70
bool SerializeClasses(FILE *fp) const
GenericVector< T > & operator=(const GenericVector &other)
bool DeSerialize(TFile *fp)
void remove(int index)
void move(GenericVector< T > *from)
void init_to_size(int size, const T &t)
GenericVector< T > & operator+=(const GenericVector &other)
T & operator[](int index) const
bool write(FILE *f, const std::function< bool(FILE *, const T &)> &cb) const
bool DeSerialize(bool swap, FILE *fp)
bool Serialize(FILE *fp) const
bool DeSerialize(bool swap, FILE *fp)
PointerVector(const PointerVector &other)
bool Serialize(TFile *fp) const
void remove(int index)
PointerVector< T > & operator+=(const PointerVector &other)
PointerVector< T > & operator=(const PointerVector &other)
size_t FWrite(const void *buffer, size_t size, size_t count)
Definition: serialis.cpp:272
size_t FReadEndian(void *buffer, size_t size, size_t count)
Definition: serialis.cpp:210