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