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