#pragma once #include #include #include namespace orange { template struct Span { Span(std::nullptr_t) : data(nullptr), size(0) {} Span(T* data, size_t size) : data(data), size(size) {} Span(T* begin, T* end) : data(begin), size(uintptr_t(end) - uintptr_t(begin)) {} template Span(T (&array)[Count]) : data(array), size(Count) {} template Span(J& x) : data(x.begin()) , size(x.end() - x.begin()) {} T& operator [] (size_t idx) { return data[idx]; } const T& operator [] (size_t idx) const { return data[idx]; } template bool operator == (const Span& other) const { if (other.size != size) return false; for (size_t i = 0; i < size; i++) { if (data[i] != other.data[i]) return false; } return true; } bool IsEmpty() const { return size == 0; } T* begin() { return &data[0]; } const T* begin() const { return &data[0]; } T* end() { return &data[size]; } const T* end() const { return &data[size]; } T& front() { return data[0]; } const T& front() const { return data[0]; } T& back() { return data[size - 1]; } const T& back() const { return data[size - 1]; } void copy(void* dst) { memcpy(dst, data, sizeof(T) * size); } T* data; size_t size; }; struct BufferView : public Span { using Span::Span; }; struct StringView : public Span { using Span::Span; StringView(const std::string& string) : Span(string.data(), string.length()) {} StringView(const char* str) : Span{str, strlen(str)} {} }; struct Buffer : public BufferView { using BufferView::BufferView; ~Buffer() { delete[] data; } }; struct TextBuffer : public Span { using Span::Span; ~TextBuffer() { delete[] data; } }; }