holder_vector.h 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #pragma once
  2. #include <util/generic/ptr.h>
  3. #include <util/generic/vector.h>
  4. #include <util/generic/noncopyable.h>
  5. template <class T, class D = TDelete>
  6. class THolderVector: public TVector<T*>, public TNonCopyable {
  7. using TBase = TVector<T*>;
  8. public:
  9. explicit THolderVector(size_t n = 0)
  10. : TBase(n)
  11. {
  12. }
  13. ~THolderVector() {
  14. Clear();
  15. }
  16. void Clear() {
  17. for (typename TBase::iterator it = TBase::begin(); it != TBase::end(); ++it) {
  18. if (*it) {
  19. D::Destroy(*it);
  20. }
  21. }
  22. TBase::clear();
  23. }
  24. size_t Size() const {
  25. return TBase::size();
  26. }
  27. // TVector takes ownership of T
  28. void PushBack(T* t) {
  29. try {
  30. TBase::push_back(t);
  31. } catch (...) {
  32. if (t) {
  33. D::Destroy(t);
  34. }
  35. throw;
  36. }
  37. }
  38. void PushBack(std::unique_ptr<T> t) {
  39. PushBack(t.release());
  40. }
  41. void PushBack(THolder<T> t) {
  42. PushBack(t.Release());
  43. }
  44. void Reset(size_t i, THolder<T> t) {
  45. T* current = (*this)[i];
  46. if (current) {
  47. Y_ASSERT(current != t.Get());
  48. D::Destroy(current);
  49. }
  50. (*this)[i] = t.Release();
  51. }
  52. void PopBack() {
  53. if (size()) {
  54. D::Destroy(back());
  55. TBase::pop_back();
  56. }
  57. }
  58. T* Release(size_t i) {
  59. T* t = (*this)[i];
  60. (*this)[i] = nullptr;
  61. return t;
  62. }
  63. void Resize(size_t newSize) {
  64. for (size_t i = newSize; i < size(); ++i) {
  65. D::Destroy((*this)[i]);
  66. }
  67. TBase::resize(newSize);
  68. }
  69. void Swap(THolderVector& other) {
  70. TBase::swap(other);
  71. }
  72. using TBase::operator[];
  73. using TBase::operator bool;
  74. using TBase::at;
  75. using TBase::back;
  76. using TBase::begin;
  77. using TBase::capacity;
  78. using TBase::empty;
  79. using TBase::end;
  80. using TBase::front;
  81. using TBase::reserve;
  82. using TBase::size;
  83. using typename TBase::const_iterator;
  84. using typename TBase::const_reverse_iterator;
  85. using typename TBase::iterator;
  86. using typename TBase::reverse_iterator;
  87. using typename TBase::value_type;
  88. };