#pragma once #include // IWYU pragma: keep #include #include #include #include #include namespace Detail { // NOLINTNEXTLINE(readability-identifier-naming) class glNamed; template concept IsglNamed = sizeof(Named) == sizeof(GLuint) && std::is_base_of_v; } template // NOLINTNEXTLINE(readability-identifier-naming) struct glManagedArray; namespace Detail { // NOLINTNEXTLINE(readability-identifier-naming) 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; } protected: GLuint name {}; template friend struct ::glManagedArray; }; } // NOLINTNEXTLINE(readability-identifier-naming) template struct glManagedSingle : public Named { glManagedSingle() noexcept { (*Gen)(1, &this->name); } glManagedSingle(glManagedSingle && src) noexcept { this->name = std::exchange(src.name, 0); } ~glManagedSingle() noexcept { if (this->name) { (*Del)(1, &this->name); } } NO_COPY(glManagedSingle); glManagedSingle & operator=(glManagedSingle && src) noexcept { if (this->name) { (*Del)(1, &this->name); } this->name = std::exchange(src.name, 0); return *this; } }; template // NOLINTNEXTLINE(readability-identifier-naming) struct glManagedArray : public std::array { using Arr = std::array; glManagedArray() noexcept { (*Gen)(N, &Arr::front().name); } glManagedArray(glManagedArray && src) noexcept { Arr::operator=(std::exchange(static_cast(src), {})); } ~glManagedArray() noexcept { if (Arr::front().name) { (*Del)(N, &Arr::front().name); } } NO_COPY(glManagedArray); glManagedArray & operator=(glManagedArray && src) noexcept { if (Arr::front().name) { (*Del)(N, &Arr::front().name); } Arr::operator=(std::exchange(static_cast(src), {})); return *this; } [[nodiscard]] static constexpr size_t size() noexcept { return N; } }; // NOLINTBEGIN(readability-identifier-naming) template using glVertexArrays = glManagedArray; using glVertexArray = glManagedSingle; template using glBuffers = glManagedArray; using glBuffer = glManagedSingle; template using glTextures = glManagedArray; using glTexture = glManagedSingle; template using glFrameBuffers = glManagedArray; using glFrameBuffer = glManagedSingle; template using glRenderBuffers = glManagedArray; using glRenderBuffer = glManagedSingle; // NOLINTEND(readability-identifier-naming)