1 #pragma once 2 3 #include <vector> 4 5 // Like a const begin/end pair, just more convenient to use (and can only be used for linear array data). 6 // Inspired by Rust's slices and Google's StringPiece. 7 template <class T> 8 struct Slice { 9 // View some memory as a slice. SliceSlice10 Slice(const T *data, size_t size) : data_(data), size_(size) {} 11 12 // Intentionally non-explicit. 13 // View a const array as a slice. 14 template<size_t N> SliceSlice15 Slice(const T(&data)[N]) : data_(data), size_(N) {} 16 17 // Intentionally non-explicit. 18 // View a const array as a slice. SliceSlice19 Slice(const std::vector<T> &data) : data_(data.data()), size_(data.size()) {} 20 21 const T &operator[](size_t index) const { 22 return data_[index]; 23 } 24 sizeSlice25 size_t size() const { 26 return size_; 27 } 28 29 // "Iterators" beginSlice30 const T *begin() const { 31 return data_; 32 } endSlice33 const T *end() const { 34 return data_ + size_; 35 } 36 emptySlice37 static Slice empty() { 38 return Slice<T>(nullptr, 0); 39 } 40 is_emptySlice41 bool is_empty() const { 42 return size_ == 0; 43 } 44 45 private: 46 const T *data_; 47 size_t size_; 48 }; 49