array_with_size.h 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #pragma once
  2. #include <util/generic/ptr.h>
  3. #include <util/generic/noncopyable.h>
  4. #include <util/generic/utility.h>
  5. #include <util/system/sys_alloc.h>
  6. template <typename T>
  7. class TArrayWithSizeHolder : TNonCopyable {
  8. typedef TArrayWithSizeHolder<T> TThis;
  9. T* Data;
  10. public:
  11. TArrayWithSizeHolder()
  12. : Data(nullptr)
  13. {
  14. }
  15. ~TArrayWithSizeHolder() {
  16. if (!Data)
  17. return;
  18. for (size_t i = 0; i < Size(); ++i) {
  19. try {
  20. Data[i].~T();
  21. } catch (...) {
  22. }
  23. }
  24. y_deallocate(((size_t*)Data) - 1);
  25. }
  26. void Swap(TThis& copy) {
  27. DoSwap(Data, copy.Data);
  28. }
  29. void Resize(size_t newSize) {
  30. if (newSize == Size())
  31. return;
  32. TThis copy;
  33. copy.Data = (T*)(((size_t*)y_allocate(sizeof(size_t) + sizeof(T) * newSize)) + 1);
  34. // does not handle constructor exceptions properly
  35. for (size_t i = 0; i < Min(Size(), newSize); ++i) {
  36. new (copy.Data + i) T(Data[i]);
  37. }
  38. for (size_t i = Min(Size(), newSize); i < newSize; ++i) {
  39. new (copy.Data + i) T;
  40. }
  41. ((size_t*)copy.Data)[-1] = newSize;
  42. Swap(copy);
  43. }
  44. size_t Size() const {
  45. return Data ? ((size_t*)Data)[-1] : 0;
  46. }
  47. bool Empty() const {
  48. return Size() == 0;
  49. }
  50. T* Get() {
  51. return Data;
  52. }
  53. const T* Get() const {
  54. return Data;
  55. }
  56. };