diff options
Diffstat (limited to 'lib/glArrays.h')
| -rw-r--r-- | lib/glArrays.h | 141 |
1 files changed, 79 insertions, 62 deletions
diff --git a/lib/glArrays.h b/lib/glArrays.h index 842a593..7f5a10b 100644 --- a/lib/glArrays.h +++ b/lib/glArrays.h @@ -5,91 +5,108 @@ #include <cstddef> #include <glad/gl.h> #include <special_members.h> +#include <utility> -// NOLINTNEXTLINE(readability-identifier-naming) -template<size_t N> class glArraysBase { - static_assert(N > 0); +namespace Detail { + class glNamed; -public: - ~glArraysBase() = default; - NO_COPY(glArraysBase); - CUSTOM_MOVE(glArraysBase); + template<typename Named> + concept IsglNamed = sizeof(Named) == sizeof(GLuint) && std::is_base_of_v<Detail::glNamed, Named>; +} + +template<Detail::IsglNamed, size_t, auto, auto> struct glManagedArray; + +namespace Detail { + class glNamed { + public: + glNamed() = default; + ~glNamed() = default; + DEFAULT_MOVE_NO_COPY(glNamed); + + GLuint + operator*() const noexcept + { + return name; + } + + // NOLINTNEXTLINE(hicpp-explicit-conversions) + operator GLuint() const noexcept + { + return name; + } - // NOLINTNEXTLINE(hicpp-explicit-conversions) - operator GLuint() const - requires(N == 1) + protected: + GLuint name {}; + template<Detail::IsglNamed, size_t, auto, auto> friend struct ::glManagedArray; + }; +} + +template<Detail::IsglNamed Named, auto Gen, auto Del> struct glManagedSingle : public Named { + glManagedSingle() noexcept { - return ids.front(); + (*Gen)(1, &this->name); } - GLuint - operator*() const - requires(N == 1) + glManagedSingle(glManagedSingle && src) noexcept { - return ids.front(); + this->name = std::exchange(src.name, 0); } - const auto & - operator[](size_t n) const + ~glManagedSingle() noexcept { - return ids[n]; + if (this->name) { + (*Del)(1, &this->name); + } } - constexpr static auto - size() + NO_COPY(glManagedSingle); + + glManagedSingle & + operator=(glManagedSingle && src) noexcept { - return N; + if (this->name) { + (*Del)(1, &this->name); + } + this->name = std::exchange(src.name, 0); + return *this; } - -protected: - glArraysBase() noexcept = default; - std::array<GLuint, N> ids {}; }; -template<size_t N> inline glArraysBase<N>::glArraysBase(glArraysBase<N> && src) noexcept : ids {src.ids} -{ - std::fill(src.ids.begin(), src.ids.end(), 0); -} - -template<size_t N> -inline glArraysBase<N> & -glArraysBase<N>::operator=(glArraysBase<N> && src) noexcept -{ - ids = src.ids; - std::fill(src.ids.begin(), src.ids.end(), 0); - return *this; -} +template<Detail::IsglNamed Named, size_t N, auto Gen, auto Del> struct glManagedArray : public std::array<Named, N> { + using Arr = std::array<Named, N>; -// NOLINTNEXTLINE(readability-identifier-naming) -template<size_t N, auto Gen, auto Del> class glArrays : public glArraysBase<N> { -public: - using glArraysBase<N>::glArraysBase; - using glArraysBase<N>::operator=; + glManagedArray() noexcept + { + (*Gen)(N, &Arr::front().name); + } - DEFAULT_MOVE_COPY(glArrays); + glManagedArray(glManagedArray && src) noexcept + { + Arr::operator=(std::exchange(static_cast<Arr &>(src), {})); + } - glArrays() noexcept + ~glManagedArray() noexcept { - (*Gen)(N, this->ids.data()); + if (Arr::front().name) { + (*Del)(N, &Arr::front().name); + } } - ~glArrays() noexcept + NO_COPY(glManagedArray); + + glManagedArray & + operator=(glManagedArray && src) noexcept { - if (this->ids.front()) { - (*Del)(N, this->ids.data()); + if (Arr::front().name) { + (*Del)(N, &Arr::front().name); } + Arr::operator=(std::exchange(static_cast<Arr &>(src), {})); + return *this; } -}; -// NOLINTBEGIN(readability-identifier-naming) -template<size_t N> using glVertexArrays = glArrays<N, &glGenVertexArrays, &glDeleteVertexArrays>; -using glVertexArray = glVertexArrays<1>; -template<size_t N> using glBuffers = glArrays<N, &glGenBuffers, &glDeleteBuffers>; -using glBuffer = glBuffers<1>; -template<size_t N> using glTextures = glArrays<N, &glGenTextures, &glDeleteTextures>; -using glTexture = glTextures<1>; -template<size_t N> using glFrameBuffers = glArrays<N, &glGenFramebuffers, &glDeleteFramebuffers>; -using glFrameBuffer = glFrameBuffers<1>; -template<size_t N> using glRenderBuffers = glArrays<N, &glGenRenderbuffers, &glDeleteRenderbuffers>; -using glRenderBuffer = glRenderBuffers<1>; -// NOLINTEND(readability-identifier-naming) + [[nodiscard]] static constexpr size_t + size() noexcept + { + return N; + } +}; |
