SmallBuffer.h 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #pragma once
  2. #include <array>
  3. #include <type_traits>
  4. /** Helper class for allocating temporary fixed size arrays with SBO.
  5. *
  6. * This is intentionally much simpler than SmallVector, to improve performace at
  7. * the expense of many features:
  8. * - No zero-initialization for numeric types
  9. * - No resizing after construction
  10. * - No copy/move
  11. * - No non-trivial types
  12. */
  13. namespace c10 {
  14. template <typename T, size_t N>
  15. class SmallBuffer {
  16. static_assert(
  17. std::is_trivial<T>::value,
  18. "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[](int64_t idx) {
  50. return data()[idx];
  51. }
  52. const T& operator[](int64_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