SmallBuffer.h 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. #pragma once
  2. #include <array>
  3. #include <cstddef>
  4. #include <cstdint>
  5. #include <type_traits>
  6. /** Helper class for allocating temporary fixed size arrays with SBO.
  7. *
  8. * This is intentionally much simpler than SmallVector, to improve performance
  9. * at the expense of many features:
  10. * - No zero-initialization for numeric types
  11. * - No resizing after construction
  12. * - No copy/move
  13. * - No non-trivial types
  14. */
  15. namespace c10 {
  16. template <typename T, size_t N>
  17. class SmallBuffer {
  18. static_assert(std::is_trivial_v<T>, "SmallBuffer is intended for POD types");
  19. std::array<T, N> storage_;
  20. size_t size_{};
  21. T* data_{};
  22. public:
  23. SmallBuffer(size_t size) : size_(size) {
  24. if (size > N) {
  25. data_ = new T[size];
  26. } else {
  27. data_ = &storage_[0];
  28. }
  29. }
  30. SmallBuffer(const SmallBuffer&) = delete;
  31. SmallBuffer& operator=(const SmallBuffer&) = delete;
  32. // move constructor is needed in function return
  33. SmallBuffer(SmallBuffer&& rhs) noexcept : size_{rhs.size_} {
  34. rhs.size_ = 0;
  35. if (size_ > N) {
  36. data_ = rhs.data_;
  37. rhs.data_ = nullptr;
  38. } else {
  39. storage_ = std::move(rhs.storage_);
  40. data_ = &storage_[0];
  41. }
  42. }
  43. SmallBuffer& operator=(SmallBuffer&&) = delete;
  44. ~SmallBuffer() {
  45. if (size_ > N) {
  46. delete[] data_;
  47. }
  48. }
  49. T& operator[](size_t idx) {
  50. return data()[idx];
  51. }
  52. const T& operator[](size_t idx) const {
  53. return data()[idx];
  54. }
  55. T* data() {
  56. return data_;
  57. }
  58. const T* data() const {
  59. return data_;
  60. }
  61. size_t size() const {
  62. return size_;
  63. }
  64. T* begin() {
  65. return data_;
  66. }
  67. const T* begin() const {
  68. return data_;
  69. }
  70. T* end() {
  71. return data_ + size_;
  72. }
  73. const T* end() const {
  74. return data_ + size_;
  75. }
  76. };
  77. } // namespace c10