holder_vector.h 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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. TBase::clear();
  22. }
  23. size_t Size() const {
  24. return TBase::size();
  25. }
  26. // TVector takes ownership of T
  27. void PushBack(T* t) {
  28. try {
  29. TBase::push_back(t);
  30. } catch (...) {
  31. if (t)
  32. D::Destroy(t);
  33. throw;
  34. }
  35. }
  36. void PushBack(std::unique_ptr<T> t) {
  37. PushBack(t.release());
  38. }
  39. void PushBack(THolder<T> t) {
  40. PushBack(t.Release());
  41. }
  42. void Reset(size_t i, THolder<T> t) {
  43. T* current = (*this)[i];
  44. if (current) {
  45. Y_ASSERT(current != t.Get());
  46. D::Destroy(current);
  47. }
  48. (*this)[i] = t.Release();
  49. }
  50. void PopBack() {
  51. if (size()) {
  52. D::Destroy(back());
  53. TBase::pop_back();
  54. }
  55. }
  56. T* Release(size_t i) {
  57. T* t = (*this)[i];
  58. (*this)[i] = nullptr;
  59. return t;
  60. }
  61. void Resize(size_t newSize) {
  62. for (size_t i = newSize; i < size(); ++i) {
  63. D::Destroy((*this)[i]);
  64. }
  65. TBase::resize(newSize);
  66. }
  67. void Swap(THolderVector& other) {
  68. TBase::swap(other);
  69. }
  70. using TBase::operator[];
  71. using TBase::operator bool;
  72. using TBase::at;
  73. using TBase::back;
  74. using TBase::begin;
  75. using TBase::capacity;
  76. using TBase::empty;
  77. using TBase::end;
  78. using TBase::front;
  79. using TBase::reserve;
  80. using TBase::size;
  81. using typename TBase::const_iterator;
  82. using typename TBase::const_reverse_iterator;
  83. using typename TBase::iterator;
  84. using typename TBase::reverse_iterator;
  85. using typename TBase::value_type;
  86. };