diff options
| -rw-r--r-- | game/network/rail.cpp | 7 | ||||
| -rw-r--r-- | game/scenary/foliage.cpp | 10 | ||||
| -rw-r--r-- | game/scenary/illuminator.cpp | 18 | ||||
| -rw-r--r-- | game/vehicles/railVehicleClass.cpp | 10 | ||||
| -rw-r--r-- | gfx/gl/instanceVertices.h | 39 | ||||
| -rw-r--r-- | lib/glAllocator.h | 90 | ||||
| -rw-r--r-- | lib/glContainer.h | 496 | ||||
| -rw-r--r-- | test/Jamfile.jam | 8 | ||||
| -rw-r--r-- | test/test-glAllocator.cpp | 28 | ||||
| -rw-r--r-- | test/test-glContainer.cpp | 453 | ||||
| -rw-r--r-- | test/test-instancing.cpp | 33 |
11 files changed, 187 insertions, 1005 deletions
diff --git a/game/network/rail.cpp b/game/network/rail.cpp index 8d85f35..545620d 100644 --- a/game/network/rail.cpp +++ b/game/network/rail.cpp @@ -140,8 +140,7 @@ template<> NetworkLinkHolder<RailLinkStraight>::NetworkLinkHolder() { vao.configure() .addAttribs<RailLinkStraight::Vertex, &RailLinkStraight::Vertex::a, &RailLinkStraight::Vertex::b, - &RailLinkStraight::Vertex::rotation, &RailLinkStraight::Vertex::textureRepeats>( - 0, vertices.bufferName()); + &RailLinkStraight::Vertex::rotation, &RailLinkStraight::Vertex::textureRepeats>(0); } template<> NetworkLinkHolder<RailLinkCurve>::NetworkLinkHolder() @@ -149,7 +148,7 @@ template<> NetworkLinkHolder<RailLinkCurve>::NetworkLinkHolder() vao.configure() .addAttribs<RailLinkCurve::Vertex, &RailLinkCurve::Vertex::a, &RailLinkCurve::Vertex::b, &RailLinkCurve::Vertex::c, &RailLinkCurve::Vertex::textureRepeats, &RailLinkCurve::Vertex::aangle, - &RailLinkCurve::Vertex::bangle, &RailLinkCurve::Vertex::radius>(0, vertices.bufferName()); + &RailLinkCurve::Vertex::bangle, &RailLinkCurve::Vertex::radius>(0); } namespace { @@ -160,6 +159,8 @@ namespace { if (auto count = networkLinks.vertices.size()) { shader.use(RAIL_CROSS_SECTION, RAIL_TEXTURE_POS); glBindVertexArray(networkLinks.vao); + glVertexArrayVertexBuffer( + networkLinks.vao, 0, networkLinks.vertices.bufferName(), 0, sizeof(typename LinkType::Vertex)); glDrawArrays(mode, 0, static_cast<GLsizei>(count)); } }; diff --git a/game/scenary/foliage.cpp b/game/scenary/foliage.cpp index 49a4831..cf2d82e 100644 --- a/game/scenary/foliage.cpp +++ b/game/scenary/foliage.cpp @@ -38,10 +38,8 @@ Foliage::postLoad() { texture = getTexture(); bodyMesh->configureVAO(instanceVAO, 0) - .addAttribs<LocationVertex, &LocationVertex::rotation, &LocationVertex::position>( - 1, instances.bufferName()); - instancePointVAO.configure().addAttribs<LocationVertex, &LocationVertex::position, &LocationVertex::yaw>( - 0, instances.bufferName()); + .addAttribs<LocationVertex, &LocationVertex::rotation, &LocationVertex::position>(1); + instancePointVAO.configure().addAttribs<LocationVertex, &LocationVertex::position, &LocationVertex::yaw>(0); const auto & size = bodyMesh->getDimensions().size; billboardSize = billboardTextureSizeForObject(size); @@ -104,6 +102,7 @@ Foliage::render(const SceneShader & shader, const Frustum &) const billboard[1].bind(GL_TEXTURE_2D_ARRAY, GL_TEXTURE1); billboard[2].bind(GL_TEXTURE_2D_ARRAY, GL_TEXTURE2); glBindVertexArray(instancePointVAO); + glVertexArrayVertexBuffer(instancePointVAO, 0, instances.bufferName(), 0, sizeof(LocationVertex)); glDrawArrays(GL_POINTS, static_cast<GLint>(instancePartitions.second.first), static_cast<GLsizei>(count)); glBindVertexArray(0); } @@ -113,6 +112,7 @@ Foliage::render(const SceneShader & shader, const Frustum &) const if (texture) { texture->bind(); } + glVertexArrayVertexBuffer(instanceVAO, 1, instances.bufferName(), 0, sizeof(LocationVertex)); bodyMesh->DrawInstanced(instanceVAO, static_cast<GLsizei>(count)); } } @@ -129,6 +129,7 @@ Foliage::shadows(const ShadowMapper & mapper, const Frustum &) const mapper.stencilShadowProgram.use(dimensions.centre, dimensions.size); shadowStencil.bind(GL_TEXTURE_2D_ARRAY, GL_TEXTURE0); glBindVertexArray(instancePointVAO); + glVertexArrayVertexBuffer(instancePointVAO, 0, instances.bufferName(), 0, sizeof(LocationVertex)); glDrawArrays(GL_POINTS, static_cast<GLint>(instancePartitions.second.first), static_cast<GLsizei>(count)); glBindVertexArray(0); } @@ -140,6 +141,7 @@ Foliage::shadows(const ShadowMapper & mapper, const Frustum &) const else { mapper.dynamicPointInst.use(); } + glVertexArrayVertexBuffer(instanceVAO, 1, instances.bufferName(), 0, sizeof(LocationVertex)); bodyMesh->DrawInstanced(instanceVAO, static_cast<GLsizei>(count)); } } diff --git a/game/scenary/illuminator.cpp b/game/scenary/illuminator.cpp index 590062e..7ab17fe 100644 --- a/game/scenary/illuminator.cpp +++ b/game/scenary/illuminator.cpp @@ -41,14 +41,13 @@ Illuminator::postLoad() } texture = getTexture(); bodyMesh->configureVAO(instanceVAO, 0) - .addAttribs<LocationVertex, &LocationVertex::first, &LocationVertex::second>(1, instances.bufferName()); + .addAttribs<LocationVertex, &LocationVertex::first, &LocationVertex::second>(1); if (!spotLight.empty()) { instancesSpotLightVAO.emplace(); instancesSpotLightVAO->configure() .addAttribs<SpotLightVertex, &SpotLightVertex::position, &SpotLightVertex::direction, - &SpotLightVertex::colour, &SpotLightVertex::kq, &SpotLightVertex::arc>( - 0, instancesSpotLight.bufferName()) - .addAttribs<LocationVertex, &LocationVertex::first, &LocationVertex::second>(1, instances.bufferName()); + &SpotLightVertex::colour, &SpotLightVertex::kq, &SpotLightVertex::arc>(0) + .addAttribs<LocationVertex, &LocationVertex::first, &LocationVertex::second>(1); std::transform( spotLight.begin(), spotLight.end(), std::back_inserter(spotLightInstances), [this](const auto & s) { return instancesSpotLight.acquire(*s); @@ -58,8 +57,8 @@ Illuminator::postLoad() instancesPointLightVAO.emplace(); instancesPointLightVAO->configure() .addAttribs<PointLightVertex, &PointLightVertex::position, &PointLightVertex::colour, - &PointLightVertex::kq>(0, instancesPointLight.bufferName()) - .addAttribs<LocationVertex, &LocationVertex::first, &LocationVertex::second>(1, instances.bufferName()); + &PointLightVertex::kq>(0) + .addAttribs<LocationVertex, &LocationVertex::first, &LocationVertex::second>(1); std::transform( pointLight.begin(), pointLight.end(), std::back_inserter(pointLightInstances), [this](const auto & s) { return instancesPointLight.acquire(*s); @@ -75,6 +74,7 @@ Illuminator::render(const SceneShader & shader, const Frustum &) const if (texture) { texture->bind(); } + glVertexArrayVertexBuffer(instanceVAO, 1, instances.bufferName(), 0, sizeof(LocationVertex)); bodyMesh->DrawInstanced(instanceVAO, static_cast<GLsizei>(count)); } } @@ -86,11 +86,17 @@ Illuminator::lights(const SceneShader & shader) const if (const auto scount = instancesSpotLight.size()) { shader.spotLightInst.use(); glBindVertexArray(*instancesSpotLightVAO); + glVertexArrayVertexBuffer( + *instancesSpotLightVAO, 0, instancesSpotLight.bufferName(), 0, sizeof(SpotLightVertex)); + glVertexArrayVertexBuffer(*instancesSpotLightVAO, 1, instances.bufferName(), 0, sizeof(LocationVertex)); glDrawArraysInstanced(GL_POINTS, 0, static_cast<GLsizei>(scount), static_cast<GLsizei>(count)); } if (const auto pcount = instancesPointLight.size()) { shader.pointLightInst.use(); glBindVertexArray(*instancesPointLightVAO); + glVertexArrayVertexBuffer( + *instancesPointLightVAO, 0, instancesPointLight.bufferName(), 0, sizeof(PointLightVertex)); + glVertexArrayVertexBuffer(*instancesPointLightVAO, 1, instances.bufferName(), 0, sizeof(LocationVertex)); glDrawArraysInstanced(GL_POINTS, 0, static_cast<GLsizei>(pcount), static_cast<GLsizei>(count)); } diff --git a/game/vehicles/railVehicleClass.cpp b/game/vehicles/railVehicleClass.cpp index a11b435..100073d 100644 --- a/game/vehicles/railVehicleClass.cpp +++ b/game/vehicles/railVehicleClass.cpp @@ -34,13 +34,13 @@ RailVehicleClass::postLoad() { texture = getTexture(); bodyMesh->configureVAO(instanceVAO, 0) - .addAttribs<LocationVertex, &LocationVertex::body, &LocationVertex::bodyPos>(1, instances.bufferName()); + .addAttribs<LocationVertex, &LocationVertex::body, &LocationVertex::bodyPos>(1); bogies.front() ->configureVAO(instancesBogiesVAO.front(), 0) - .addAttribs<LocationVertex, &LocationVertex::front, &LocationVertex::frontPos>(1, instances.bufferName()); + .addAttribs<LocationVertex, &LocationVertex::front, &LocationVertex::frontPos>(1); bogies.back() ->configureVAO(instancesBogiesVAO.back(), 0) - .addAttribs<LocationVertex, &LocationVertex::back, &LocationVertex::backPos>(1, instances.bufferName()); + .addAttribs<LocationVertex, &LocationVertex::back, &LocationVertex::backPos>(1); static_assert(sizeof(LocationVertex) == 144UL); } @@ -52,6 +52,10 @@ RailVehicleClass::render(const SceneShader & shader, const Frustum &) const texture->bind(); } shader.basicInst.use(); + const auto instancesBuffer = instances.bufferName(); + glVertexArrayVertexBuffer(instanceVAO, 1, instancesBuffer, 0, sizeof(LocationVertex)); + glVertexArrayVertexBuffer(instancesBogiesVAO.front(), 1, instancesBuffer, 0, sizeof(LocationVertex)); + glVertexArrayVertexBuffer(instancesBogiesVAO.back(), 1, instancesBuffer, 0, sizeof(LocationVertex)); bodyMesh->DrawInstanced(instanceVAO, count); bogies.front()->DrawInstanced(instancesBogiesVAO.front(), count); bogies.back()->DrawInstanced(instancesBogiesVAO.back(), count); diff --git a/gfx/gl/instanceVertices.h b/gfx/gl/instanceVertices.h index ecadf8f..f24eaa3 100644 --- a/gfx/gl/instanceVertices.h +++ b/gfx/gl/instanceVertices.h @@ -1,13 +1,13 @@ #pragma once -#include "glContainer.h" +#include "glAllocator.h" #include <cassert> #include <functional> #include <special_members.h> #include <utility> -template<typename T> class InstanceVertices : protected glContainer<T> { - using base = glContainer<T>; +template<typename T> class InstanceVertices : protected glVector<T> { + using base = glVector<T>; public: class [[nodiscard]] InstanceProxy { @@ -120,16 +120,31 @@ public: return InstanceProxy {this, index.size() - 1}; } - using base::bufferName; - using base::reserve; - - [[nodiscard]] auto - size() const + [[nodiscard]] GLuint + bufferName() const { - base::unmap(); - return base::size(); + return base::get_allocator().getNameFor(static_cast<const base &>(*this)); } + using base::at; + using base::begin; + using base::cbegin; + using base::cend; + using base::crbegin; + using base::crend; + using base::end; + using base::rbegin; + using base::rend; + using base::size; + using base::operator[]; + using base::back; + using base::capacity; + using base::data; + using base::empty; + using base::front; + using base::reserve; + using base::shrink_to_fit; + template<typename Pred> base::size_type partition(Pred pred) @@ -195,8 +210,8 @@ protected: } template<typename Pred> - glContainer<T>::iterator - partition(glContainer<T>::iterator first, glContainer<T>::iterator last, Pred pred) + base::iterator + partition(base::iterator first, base::iterator last, Pred pred) { while (first < last) { first = std::find_if_not(first, last, pred); diff --git a/lib/glAllocator.h b/lib/glAllocator.h new file mode 100644 index 0000000..a9015da --- /dev/null +++ b/lib/glAllocator.h @@ -0,0 +1,90 @@ +#include <concepts> +#include <flat_map> +#include <glad/gl.h> +#include <memory> +#include <stream_support.h> +#include <vector> + +namespace Detail { + template<typename T> class glAllocator; + template<typename C, typename T> + concept IsGlBufferAllocated = requires(const C & container) { + { container.get_allocator() } -> std::same_as<glAllocator<T>>; + }; + + template<typename T> class glAllocator { + public: + // NOLINTBEGIN(readability-identifier-naming) - STL like + using pointer = T *; + using const_pointer = const T *; + using value_type = T; + + // NOLINTEND(readability-identifier-naming) + + pointer + allocate(size_t count) + { + constexpr static GLbitfield MAPPING_FLAGS + = GL_MAP_WRITE_BIT | GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT; + constexpr static GLbitfield STORAGE_FLAGS = GL_DYNAMIC_STORAGE_BIT | MAPPING_FLAGS; + GLuint name = 0; + glCreateBuffers(1, &name); + const auto size = static_cast<GLsizeiptr>(count * sizeof(T)); + glNamedBufferStorage(name, size, nullptr, STORAGE_FLAGS); + const auto data = static_cast<pointer>(glMapNamedBufferRange(name, 0, size, MAPPING_FLAGS)); + if (!data) { + glDeleteBuffers(1, &name); + throw std::bad_alloc(); + } + buffers->emplace(data, name); + return data; + } + + void + deallocate(const_pointer ptr, size_t) + { + const auto itr = buffers->find(ptr); + glUnmapNamedBuffer(itr->second); + glDeleteBuffers(1, &itr->second); + buffers->erase(itr); + } + + [[nodiscard]] GLuint + getNameFor(const_pointer ptr) const + { + const auto itr = buffers->find(ptr); + if (itr != buffers->end()) { + return itr->second; + } + return 0; + } + + template<IsGlBufferAllocated<T> C> + [[nodiscard]] + GLuint + getNameFor(const C & container) const + { + return getNameFor(container.data()); + } + + bool operator==(const glAllocator &) const = default; + + private: + using BufferMap = std::flat_map<const_pointer, GLuint>; + std::shared_ptr<BufferMap> buffers = std::make_shared<BufferMap>(); + }; +} + +template<typename T> +// NOLINTNEXTLINE(readability-identifier-naming) - OpenGL like +using glVector = std::vector<T, typename std::allocator_traits<Detail::glAllocator<T>>::allocator_type>; + +template<typename C> +GLuint +operator*(const C & container) + requires Detail::IsGlBufferAllocated<C, typename C::value_type> +{ + return container.get_allocator().getNameFor(container); +} + +static_assert(Detail::IsGlBufferAllocated<glVector<int>, int>); diff --git a/lib/glContainer.h b/lib/glContainer.h deleted file mode 100644 index 45f1030..0000000 --- a/lib/glContainer.h +++ /dev/null @@ -1,496 +0,0 @@ -#pragma once - -#include "gfx/gl/glBuffer.h" -#include <cassert> -#include <span> -#include <stdexcept> -#include <utility> -#include <vector> - -static_assert(GL_READ_ONLY < GL_READ_WRITE); -static_assert(GL_WRITE_ONLY < GL_READ_WRITE); - -template<typename T> class glContainer { -public: - using span = std::span<T>; - using const_span = std::span<const T>; - using value_type = T; - using reference_type = T &; - using const_reference_type = const T &; - using pointer_type = T *; - using const_pointer_type = const T *; - using size_type = std::size_t; - using iterator = span::iterator; - using const_iterator = const_span::iterator; - using reverse_iterator = span::reverse_iterator; - using const_reverse_iterator = const_span::reverse_iterator; - static constexpr bool is_trivial_dest = std::is_trivially_destructible_v<T>; - - explicit glContainer(GLenum target = GL_ARRAY_BUFFER) : target_ {target} - { - allocBuffer(1); - } - - ~glContainer() - requires(is_trivial_dest) - = default; - - ~glContainer() - requires(!is_trivial_dest) - { - clear(); - } - - template<template<typename, typename...> typename C> - explicit glContainer(const C<T> & src, GLenum target = GL_ARRAY_BUFFER) : target_ {target} - { - reserve(src.size()); - std::copy(src.begin(), src.end(), std::back_inserter(*this)); - } - - DEFAULT_MOVE_NO_COPY(glContainer); - - [[nodiscard]] iterator - begin() - { - map(GL_READ_WRITE); - return mkspan().begin(); - } - - [[nodiscard]] iterator - end() - { - map(GL_READ_WRITE); - return mkspan().end(); - } - - [[nodiscard]] const_iterator - begin() const - { - map(GL_READ_ONLY); - return mkcspan().begin(); - } - - [[nodiscard]] const_iterator - end() const - { - map(GL_READ_ONLY); - return mkcspan().end(); - } - - [[nodiscard]] const_iterator - cbegin() const - { - map(GL_READ_ONLY); - return mkcspan().begin(); - } - - [[nodiscard]] const_iterator - cend() const - { - map(GL_READ_ONLY); - return mkcspan().end(); - } - - [[nodiscard]] reverse_iterator - rbegin() - { - map(GL_READ_WRITE); - return mkspan().rbegin(); - } - - [[nodiscard]] reverse_iterator - rend() - { - map(GL_READ_WRITE); - return mkspan().rend(); - } - - [[nodiscard]] const_reverse_iterator - rbegin() const - { - map(GL_READ_ONLY); - return mkcspan().rbegin(); - } - - [[nodiscard]] const_reverse_iterator - rend() const - { - map(GL_READ_ONLY); - return mkcspan().rend(); - } - - [[nodiscard]] const_reverse_iterator - crbegin() const - { - map(GL_READ_ONLY); - return mkcspan().rbegin(); - } - - [[nodiscard]] const_reverse_iterator - crend() const - { - map(GL_READ_ONLY); - return mkcspan().rend(); - } - - [[nodiscard]] const auto & - bufferName() const - { - return buffer_; - } - - [[nodiscard]] size_type - size() const - { - return size_; - } - - void - at(size_type pos, const T & value) - { - if (pos >= size()) { - throw std::out_of_range {__FUNCTION__}; - } - if (data_) { - mkspan()[pos] = value; - } - else { - glBindBuffer(target_, buffer_); - glBufferSubData(target_, static_cast<GLintptr>(pos * sizeof(T)), sizeof(value), &value); - glBindBuffer(target_, 0); - } - } - - [[nodiscard]] reference_type - at(size_type pos) - { - if (pos >= size()) { - throw std::out_of_range {__FUNCTION__}; - } - map(GL_READ_WRITE); - return mkspan()[pos]; - } - - [[nodiscard]] const_reference_type - at(size_type pos) const - { - if (pos >= size()) { - throw std::out_of_range {__FUNCTION__}; - } - map(GL_READ_ONLY); - return mkcspan()[pos]; - } - - [[nodiscard]] reference_type - operator[](size_type pos) - { - map(GL_READ_WRITE); - return mkspan()[pos]; - } - - [[nodiscard]] const_reference_type - operator[](size_type pos) const - { - map(GL_READ_ONLY); - return mkcspan()[pos]; - } - - [[nodiscard]] pointer_type - data() - { - map(GL_READ_WRITE); - return data_; - } - - [[nodiscard]] const_pointer_type - data() const - { - map(GL_READ_ONLY); - return data_; - } - - [[nodiscard]] reference_type - front() - { - map(GL_READ_WRITE); - return mkspan().front(); - } - - [[nodiscard]] reference_type - back() - { - map(GL_READ_WRITE); - return mkspan().back(); - } - - [[nodiscard]] const_reference_type - front() const - { - map(GL_READ_ONLY); - return mkcspan().front(); - } - - [[nodiscard]] const_reference_type - back() const - { - map(GL_READ_ONLY); - return mkcspan().back(); - } - - [[nodiscard]] bool - empty() const - { - return !size(); - } - - [[nodiscard]] size_type - capacity() const - { - return capacity_; - } - - void - unmap() const - { - if (data_) { - glBindBuffer(target_, buffer_); - glUnmapBuffer(target_); - glBindBuffer(target_, 0); - data_ = {}; - access_ = {}; - } - } - - void - reserve(size_type newCapacity) - { - if (newCapacity <= capacity_) { - return; - } - newCapacity = std::max(newCapacity, capacity_ * 2); - - std::vector<T> existing; - existing.reserve(size_); - std::move(begin(), end(), std::back_inserter(existing)); - allocBuffer(newCapacity); - std::move(existing.begin(), existing.end(), begin()); - } - - void - resize(size_type newSize) - requires std::is_default_constructible_v<T> - { - if (newSize == size_) { - return; - } - - if (const auto maintain = std::min(newSize, size_)) { - std::vector<T> existing; - const auto maintaind = static_cast<typename decltype(existing)::difference_type>(maintain); - existing.reserve(maintain); - std::move(begin(), end(), std::back_inserter(existing)); - allocBuffer(newSize); - mapForAdd(); - std::move(existing.begin(), existing.begin() + maintaind, begin()); - } - else { - allocBuffer(newSize); - mapForAdd(); - } - if (const auto prevSize = setSize(newSize); newSize > prevSize) { - for (auto & uninitialised : mkspan().subspan(prevSize, newSize - prevSize)) { - new (&uninitialised) T {}; - } - } - } - - void - shrink_to_fit() - { - if (capacity_ <= size_) { - return; - } - - std::vector<T> existing; - existing.reserve(size_); - map(is_trivial_dest ? GL_READ_ONLY : GL_READ_WRITE); - std::move(begin(), end(), std::back_inserter(existing)); - allocBuffer(size_); - map(GL_READ_WRITE); - std::move(existing.begin(), existing.end(), begin()); - } - - void - clear() noexcept(is_trivial_dest) - { - if constexpr (!is_trivial_dest) { - map(GL_READ_WRITE); - std::for_each(begin(), end(), [](auto && v) { - v.~T(); - }); - } - setSize(0); - } - - template<typename... P> - reference_type - emplace_back(P &&... ps) - requires std::is_constructible_v<T, P...> - { - auto newSize = size_ + 1; - reserve(newSize); - mapForAdd(); - new (&*end()) T {std::forward<P>(ps)...}; - setSize(newSize); - return back(); - } - - template<typename... P> - iterator - emplace(iterator pos, P &&... ps) - requires std::is_nothrow_constructible_v<T, P...> - { - auto newSize = size_ + 1; - const auto idx = pos - begin(); - reserve(newSize); - mapForAdd(); - pos = begin() + idx; - std::move_backward(pos, end(), end() + 1); - pos->~T(); - new (&*pos) T {std::forward<P>(ps)...}; - setSize(newSize); - return pos; - } - - reference_type - push_back(T p) - requires std::is_move_constructible_v<T> - { - auto newSize = size_ + 1; - reserve(newSize); - mapForAdd(); - new (&*end()) T {std::move(p)}; - setSize(newSize); - return back(); - } - - iterator - insert(iterator pos, T p) - requires std::is_nothrow_move_constructible_v<T> - { - auto newSize = size_ + 1; - const auto idx = pos - begin(); - reserve(newSize); - mapForAdd(); - pos = begin() + idx; - std::move_backward(pos, end(), end() + 1); - pos->~T(); - new (&*pos) T {std::move(p)}; - setSize(newSize); - return pos; - } - - void - pop_back() - { - if constexpr (!is_trivial_dest) { - map(GL_READ_WRITE); - back().~T(); - } - --size_; - } - - void - erase(iterator pos) - { - erase(pos, pos + 1); - } - - void - erase(iterator pos, iterator to) - { - const auto eraseSize = to - pos; - map(GL_READ_WRITE); - std::move(to, end(), pos); - if constexpr (!is_trivial_dest) { - std::for_each(end() - eraseSize, end(), [](auto && v) { - v.~T(); - }); - } - setSize(size_ - static_cast<size_type>(eraseSize)); - } - -protected: - size_type - setSize(size_type s) - { - return std::exchange(size_, s); - } - - void - allocBuffer(size_type newCapacity) - { - if (newCapacity == 0) { - return allocBuffer(1); - } - glBindBuffer(target_, buffer_); - glBufferData(target_, static_cast<GLsizeiptr>(sizeof(T) * newCapacity), nullptr, GL_DYNAMIC_DRAW); - glBindBuffer(target_, 0); - capacity_ = newCapacity; - data_ = {}; - access_ = {}; - } - - void - map(GLenum access) const - { - if (size_ > 0) { - mapMode(access); - } - } - - void - mapForAdd() const - { - if (!data_) { - mapMode(GL_READ_WRITE); - } - } - - void - mapMode(GLenum access) const - { - if (data_ && access_ < access) { - unmap(); - } - if (!data_) { - glBindBuffer(target_, buffer_); - data_ = static_cast<T *>(glMapBuffer(target_, access)); - glBindBuffer(target_, 0); - assert(data_); - access_ = access; - } - } - - span - mkspan() const - { - assert(!size_ || data_); - return span {data_, size_}; - } - - const_span - mkcspan() const - { - assert(!size_ || data_); - return const_span {data_, size_}; - } - - glBuffer buffer_; - GLenum target_; - std::size_t capacity_ {}; - std::size_t size_ {}; - mutable T * data_; - mutable GLenum access_ {}; -}; diff --git a/test/Jamfile.jam b/test/Jamfile.jam index a96ca2a..da2a61a 100644 --- a/test/Jamfile.jam +++ b/test/Jamfile.jam @@ -61,9 +61,9 @@ run test-lib.cpp ; run [ glob test-geoData*.cpp ] : -- : [ sequence.insertion-sort [ glob-tree $(fixtures)/geoData : *.json ] fixtures/height/SD19.asc ] : <library>test ; run test-network.cpp : : : <library>test ; run test-persistence.cpp : -- : [ sequence.insertion-sort [ glob-tree $(fixtures)/json : *.json ] ] : <library>test ; -run test-text.cpp : -- : test-glContainer : <library>test ; +run test-text.cpp : -- : test-glAllocator : <library>test ; run test-enumDetails.cpp ; -run test-render.cpp : -- : test-assetFactory : <library>test ; +run test-render.cpp : -- : : <library>test ; run test-glContextBhvr.cpp ; run test-assetFactory.cpp : -- : [ sequence.insertion-sort [ glob-tree $(res) : *.* ] fixtures/rgb.txt test-instancing ] : <library>test ; perfrun perf-assetFactory.cpp : : test-assetFactory ; @@ -71,9 +71,9 @@ perfrun perf-geoData.cpp : : test-geoData ; perfrun perf-terrain.cpp : : test-geoData ; perfrun perf-persistence.cpp : : test-persistence ; run test-worker.cpp ; -run test-instancing.cpp : -- : test-glContainer : <library>test ; +run test-instancing.cpp : -- : test-glAllocator : <library>test ; perfrun perf-instancing.cpp : : test-instancing ; -run test-glContainer.cpp : : : <library>test ; +run test-glAllocator.cpp : : : <library>test ; run test-pack.cpp : : : <library>test ; run test-environment.cpp : : : <library>test ; run test-ui.cpp : : : <library>test ; diff --git a/test/test-glAllocator.cpp b/test/test-glAllocator.cpp new file mode 100644 index 0000000..96457a2 --- /dev/null +++ b/test/test-glAllocator.cpp @@ -0,0 +1,28 @@ +#define BOOST_TEST_MODULE glAllocator + +#include "testMainWindow.h" +#include <boost/test/data/test_case.hpp> +#include <boost/test/unit_test.hpp> + +#include "glAllocator.h" + +BOOST_GLOBAL_FIXTURE(TestMainWindowAppBase); + +namespace { + BOOST_AUTO_TEST_CASE(Simple) + { + GLuint name = 0; + { + glVector<long double> list; + BOOST_REQUIRE_EQUAL(list.get_allocator().getNameFor(list), 0); + list.reserve(5); + name = list.get_allocator().getNameFor(list); + BOOST_REQUIRE_GT(name, 0); + std::ranges::copy(std::views::iota(0, 10), std::back_inserter(list)); + BOOST_REQUIRE_EQUAL(10, list.size()); + BOOST_CHECK_EQUAL(0, list.front()); + BOOST_CHECK_EQUAL(9, list.back()); + } + BOOST_CHECK(!glIsBuffer(name)); + } +} diff --git a/test/test-glContainer.cpp b/test/test-glContainer.cpp deleted file mode 100644 index 7f82e13..0000000 --- a/test/test-glContainer.cpp +++ /dev/null @@ -1,453 +0,0 @@ -#define BOOST_TEST_MODULE glContainer - -#include "testMainWindow.h" -#include <boost/test/data/test_case.hpp> -#include <boost/test/unit_test.hpp> - -#include "glContainer.h" - -// Force generation of all functions -template class glContainer<int>; - -BOOST_TEST_DONT_PRINT_LOG_VALUE(glContainer<int>::iterator); -BOOST_TEST_DONT_PRINT_LOG_VALUE(glContainer<int>::const_iterator); -BOOST_TEST_DONT_PRINT_LOG_VALUE(glContainer<int>::reverse_iterator); -BOOST_TEST_DONT_PRINT_LOG_VALUE(glContainer<int>::const_reverse_iterator); - -BOOST_GLOBAL_FIXTURE(TestMainWindowAppBase); - -BOOST_FIXTURE_TEST_SUITE(i, glContainer<int>) - -BOOST_AUTO_TEST_CASE(CreateDestroy, *boost::unit_test::timeout(1)) -{ - // Unmapped - BOOST_CHECK(!data_); - BOOST_CHECK(!access_); - // Request map, but empty - BOOST_CHECK_NO_THROW(map(GL_READ_ONLY)); - BOOST_REQUIRE(!data_); - BOOST_REQUIRE(!access_); - BOOST_CHECK_NO_THROW(map(GL_READ_WRITE)); - BOOST_REQUIRE(!data_); - BOOST_REQUIRE(!access_); - // Add something - BOOST_CHECK_NO_THROW(emplace_back(0)); - BOOST_REQUIRE(data_); - BOOST_REQUIRE_EQUAL(access_, GL_READ_WRITE); - // Unmap - BOOST_CHECK_NO_THROW(unmap()); - BOOST_REQUIRE(!data_); - BOOST_REQUIRE(!access_); - // Map RO - BOOST_CHECK_NO_THROW(map(GL_READ_ONLY)); - BOOST_REQUIRE(data_); - BOOST_REQUIRE_EQUAL(access_, GL_READ_ONLY); - // Map RW upgradde - BOOST_CHECK_NO_THROW(map(GL_READ_WRITE)); - BOOST_REQUIRE(data_); - BOOST_REQUIRE_EQUAL(access_, GL_READ_WRITE); - // Map RO downgradde, no change - BOOST_CHECK_NO_THROW(map(GL_READ_ONLY)); - BOOST_REQUIRE(data_); - BOOST_REQUIRE_EQUAL(access_, GL_READ_WRITE); - // Unmap - BOOST_CHECK_NO_THROW(unmap()); - BOOST_CHECK(!data_); - BOOST_CHECK(!access_); -} - -BOOST_AUTO_TEST_CASE(MapModes) -{ - BOOST_CHECK_EQUAL(std::accumulate(begin(), end(), 0), 0); - BOOST_CHECK(!data_); - BOOST_CHECK(!access_); - - BOOST_CHECK_NO_THROW(push_back(1)); - BOOST_CHECK_NO_THROW(push_back(2)); - BOOST_CHECK_NO_THROW(push_back(3)); - BOOST_CHECK_NO_THROW(push_back(4)); - BOOST_CHECK_NO_THROW(unmap()); - - BOOST_CHECK_EQUAL(std::accumulate(cbegin(), cend(), 0), 10); - BOOST_CHECK(data_); - BOOST_CHECK_EQUAL(access_, GL_READ_ONLY); - BOOST_CHECK_NO_THROW(unmap()); - - BOOST_CHECK_EQUAL(std::accumulate(begin(), end(), 0), 10); - BOOST_CHECK(data_); - BOOST_CHECK_EQUAL(access_, GL_READ_WRITE); - BOOST_CHECK_NO_THROW(unmap()); - - BOOST_CHECK_EQUAL(std::ranges::fold_left(std::as_const(*this), 0, std::plus {}), 10); - BOOST_CHECK(data_); - BOOST_CHECK_EQUAL(access_, GL_READ_ONLY); - BOOST_CHECK_NO_THROW(unmap()); -} - -BOOST_AUTO_TEST_CASE(PushBackTest, *boost::unit_test::timeout(1)) -{ - BOOST_CHECK_EQUAL(capacity_, 1); - BOOST_CHECK_EQUAL(size_, 0); - BOOST_CHECK_NO_THROW(push_back(1)); - BOOST_CHECK_NO_THROW(push_back(2)); - BOOST_CHECK_NO_THROW(push_back(3)); - BOOST_CHECK_NO_THROW(push_back(4)); - BOOST_CHECK_NO_THROW(push_back(5)); - BOOST_CHECK_EQUAL(capacity_, 8); - BOOST_CHECK_EQUAL(size_, 5); - { - std::array expected1 {1, 2, 3, 4, 5}; - BOOST_CHECK_EQUAL_COLLECTIONS(begin(), end(), expected1.begin(), expected1.end()); - BOOST_CHECK_EQUAL_COLLECTIONS(rbegin(), rend(), expected1.rbegin(), expected1.rend()); - } -} - -BOOST_AUTO_TEST_CASE(EmplaceBackTest, *boost::unit_test::timeout(1)) -{ - BOOST_CHECK_EQUAL(capacity_, 1); - BOOST_CHECK_EQUAL(size_, 0); - - BOOST_CHECK_NO_THROW(emplace_back(1)); - BOOST_CHECK_NO_THROW(emplace_back(2)); - BOOST_CHECK_EQUAL(capacity_, 2); - BOOST_CHECK_EQUAL(size_, 2); - - BOOST_CHECK_NO_THROW(reserve(5)); - BOOST_CHECK_EQUAL(capacity_, 5); - BOOST_CHECK_EQUAL(size_, 2); - - BOOST_CHECK_NO_THROW(emplace_back(3)); - BOOST_CHECK_NO_THROW(emplace_back(4)); - BOOST_CHECK_EQUAL(capacity_, 5); - BOOST_CHECK_EQUAL(size_, 4); - - { - std::array expected1 {1, 2, 3, 4}; - BOOST_CHECK_EQUAL_COLLECTIONS(begin(), end(), expected1.begin(), expected1.end()); - BOOST_CHECK_EQUAL_COLLECTIONS(rbegin(), rend(), expected1.rbegin(), expected1.rend()); - } - - BOOST_CHECK_NO_THROW(emplace_back(5)); - BOOST_CHECK_EQUAL(capacity_, 5); - BOOST_CHECK_EQUAL(size_, 5); - BOOST_CHECK_NO_THROW(emplace_back(6)); - BOOST_CHECK_NO_THROW(emplace_back(7)); - BOOST_CHECK_EQUAL(capacity_, 10); - BOOST_CHECK_EQUAL(size_, 7); - - { - std::array expected2 {1, 2, 3, 4, 5, 6, 7}; - BOOST_CHECK_EQUAL_COLLECTIONS(begin(), end(), expected2.begin(), expected2.end()); - BOOST_CHECK_EQUAL_COLLECTIONS(rbegin(), rend(), expected2.rbegin(), expected2.rend()); - } - - BOOST_CHECK_EQUAL(7, end() - begin()); - BOOST_CHECK_EQUAL(7, rend() - rbegin()); -} - -BOOST_AUTO_TEST_CASE(ResizeTest) -{ - BOOST_CHECK_NO_THROW(push_back(1)); - BOOST_CHECK_NO_THROW(emplace_back(2)); - BOOST_CHECK_NO_THROW(resize(4)); - BOOST_CHECK_EQUAL(capacity_, 4); - BOOST_CHECK_EQUAL(size_, 4); - { - std::array expected1 {1, 2, 0, 0}; - BOOST_CHECK_EQUAL_COLLECTIONS(begin(), end(), expected1.begin(), expected1.end()); - } - - BOOST_CHECK_NO_THROW(resize(1)); - BOOST_CHECK_EQUAL(capacity_, 1); - BOOST_CHECK_EQUAL(size_, 1); - { - std::array expected2 {1}; - BOOST_CHECK_EQUAL_COLLECTIONS(begin(), end(), expected2.begin(), expected2.end()); - } - - BOOST_CHECK_NO_THROW(resize(1)); - BOOST_CHECK_EQUAL(capacity_, 1); - BOOST_CHECK_EQUAL(size_, 1); - - BOOST_CHECK_NO_THROW(resize(0)); - BOOST_CHECK_EQUAL(capacity_, 1); - BOOST_CHECK_EQUAL(size_, 0); - BOOST_CHECK_EQUAL(begin(), end()); - BOOST_CHECK_EQUAL(rbegin(), rend()); -} - -BOOST_AUTO_TEST_CASE(ShrinkToFitTest) -{ - BOOST_CHECK_NO_THROW(reserve(4)); - BOOST_CHECK_NO_THROW(emplace_back(1)); - BOOST_CHECK_NO_THROW(emplace_back(2)); - BOOST_CHECK_EQUAL(capacity_, 4); - BOOST_CHECK_EQUAL(size_, 2); - { - std::array expected1 {1, 2}; - BOOST_CHECK_EQUAL_COLLECTIONS(begin(), end(), expected1.begin(), expected1.end()); - } - BOOST_CHECK_NO_THROW(shrink_to_fit()); - BOOST_CHECK_EQUAL(capacity_, 2); - BOOST_CHECK_EQUAL(size_, 2); - { - std::array expected1 {1, 2}; - BOOST_CHECK_EQUAL_COLLECTIONS(begin(), end(), expected1.begin(), expected1.end()); - } - - BOOST_CHECK_NO_THROW(shrink_to_fit()); - BOOST_CHECK_EQUAL(capacity(), 2); - BOOST_CHECK_EQUAL(size(), 2); - - BOOST_CHECK_NO_THROW(clear()); - BOOST_CHECK_EQUAL(capacity(), 2); - BOOST_CHECK_EQUAL(size(), 0); -} - -BOOST_AUTO_TEST_CASE(Getters) -{ - BOOST_CHECK(empty()); - BOOST_CHECK_NO_THROW(emplace_back(1)); - BOOST_CHECK(!empty()); - BOOST_CHECK_NO_THROW(emplace_back(2)); - BOOST_CHECK_EQUAL(1, front()); - BOOST_CHECK_EQUAL(2, back()); - BOOST_CHECK_EQUAL(1, at(0)); - BOOST_CHECK_EQUAL(2, at(1)); - BOOST_CHECK_EQUAL(1, (*this)[0]); - BOOST_CHECK_EQUAL(2, (*this)[1]); - BOOST_CHECK_EQUAL(data_, data()); - BOOST_CHECK_THROW(std::ignore = at(2), std::out_of_range); - - const auto & constCont {*this}; - BOOST_CHECK_EQUAL(1, constCont.front()); - BOOST_CHECK_EQUAL(2, constCont.back()); - { - std::array expected1 {1, 2}; - BOOST_CHECK_EQUAL_COLLECTIONS(constCont.begin(), constCont.end(), expected1.begin(), expected1.end()); - BOOST_CHECK_EQUAL_COLLECTIONS(constCont.rbegin(), constCont.rend(), expected1.rbegin(), expected1.rend()); - BOOST_CHECK_EQUAL_COLLECTIONS(constCont.cbegin(), constCont.cend(), expected1.cbegin(), expected1.cend()); - BOOST_CHECK_EQUAL_COLLECTIONS(constCont.crbegin(), constCont.crend(), expected1.crbegin(), expected1.crend()); - } - BOOST_CHECK_EQUAL(1, constCont.at(0)); - BOOST_CHECK_EQUAL(2, constCont.at(1)); - BOOST_CHECK_EQUAL(1, constCont[0]); - BOOST_CHECK_EQUAL(2, constCont[1]); - BOOST_CHECK_EQUAL(data_, constCont.data()); - BOOST_CHECK_THROW(std::ignore = constCont.at(2), std::out_of_range); -} - -BOOST_AUTO_TEST_CASE(RandomAccess) -{ - BOOST_CHECK_NO_THROW(emplace_back(1)); - BOOST_CHECK_NO_THROW(emplace_back(2)); - BOOST_CHECK_NO_THROW(emplace_back(3)); - - auto iterator = begin(); - BOOST_CHECK_EQUAL(1, *iterator); - BOOST_CHECK_EQUAL(2, *++iterator); - BOOST_CHECK_EQUAL(2, *iterator++); - BOOST_CHECK_EQUAL(3, *iterator); - BOOST_CHECK_EQUAL(3, *iterator--); - BOOST_CHECK_EQUAL(2, *iterator); - BOOST_CHECK_EQUAL(1, *--iterator); - BOOST_CHECK_EQUAL(1, *iterator); -} - -BOOST_AUTO_TEST_CASE(RandomWrite) -{ - BOOST_CHECK_NO_THROW(resize(3)); - BOOST_CHECK_EQUAL(size(), 3); - BOOST_CHECK_NO_THROW(unmap()); - BOOST_REQUIRE(!data_); - BOOST_CHECK_NO_THROW(at(0, 10)); - BOOST_CHECK_NO_THROW(at(1, 20)); - BOOST_CHECK_NO_THROW(at(2, 30)); - BOOST_CHECK(!data_); - { - std::array expected1 {10, 20, 30}; - BOOST_CHECK_EQUAL_COLLECTIONS(begin(), end(), expected1.begin(), expected1.end()); - } - BOOST_CHECK(data_); - BOOST_CHECK_NO_THROW(at(1, 40)); - { - std::array expected1 {10, 40, 30}; - BOOST_CHECK_EQUAL_COLLECTIONS(begin(), end(), expected1.begin(), expected1.end()); - } - BOOST_CHECK_THROW(at(4, 0), std::out_of_range); -} - -BOOST_AUTO_TEST_CASE(InsertRemoveTest) -{ - BOOST_CHECK_NO_THROW(emplace_back(1)); - BOOST_CHECK_NO_THROW(emplace_back(2)); - BOOST_CHECK_NO_THROW(emplace_back(3)); - BOOST_CHECK_NO_THROW(emplace_back(4)); - BOOST_CHECK_NO_THROW(pop_back()); - BOOST_CHECK_EQUAL(size_, 3); - BOOST_CHECK_EQUAL(capacity_, 4); - - BOOST_CHECK_NO_THROW(emplace(begin(), 5)); - BOOST_CHECK_EQUAL(size_, 4); - BOOST_CHECK_EQUAL(capacity_, 4); - { - std::array expected1 {5, 1, 2, 3}; - BOOST_CHECK_EQUAL_COLLECTIONS(begin(), end(), expected1.begin(), expected1.end()); - } - - { - std::array expected1 {2, 3}; - BOOST_CHECK_EQUAL_COLLECTIONS(begin() + 2, end(), expected1.begin(), expected1.end()); - } - BOOST_CHECK_NO_THROW(insert(begin() + 2, 6)); - BOOST_CHECK_EQUAL(size_, 5); - BOOST_CHECK_EQUAL(capacity_, 8); - { - std::array expected1 {5, 1, 6, 2, 3}; - BOOST_CHECK_EQUAL_COLLECTIONS(begin(), end(), expected1.begin(), expected1.end()); - } - erase(begin() + 1); - BOOST_CHECK_EQUAL(size_, 4); - BOOST_CHECK_EQUAL(capacity_, 8); - { - std::array expected1 {5, 6, 2, 3}; - BOOST_CHECK_EQUAL_COLLECTIONS(begin(), end(), expected1.begin(), expected1.end()); - } - erase(begin() + 1, end() - 1); - BOOST_CHECK_EQUAL(size_, 2); - BOOST_CHECK_EQUAL(capacity_, 8); - { - std::array expected1 {5, 3}; - BOOST_CHECK_EQUAL_COLLECTIONS(begin(), end(), expected1.begin(), expected1.end()); - } -} - -BOOST_AUTO_TEST_CASE(StlCompatilibty) -{ - BOOST_CHECK_NO_THROW(resize(10)); - BOOST_CHECK_NO_THROW(std::generate(begin(), end(), [value = 0]() mutable { - return value++; - })); - BOOST_CHECK_NO_THROW(std::sort(rbegin(), rend())); - { - std::array expected1 {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; - BOOST_CHECK_EQUAL_COLLECTIONS(begin(), end(), expected1.begin(), expected1.end()); - } - const auto newend = std::remove_if(begin(), end(), [](const auto & value) { - return value % 2 == 0; - }); - { - std::array expected1 {9, 7, 5, 3, 1}; - BOOST_CHECK_EQUAL_COLLECTIONS(begin(), newend, expected1.begin(), expected1.end()); - } -} - -BOOST_AUTO_TEST_CASE(IterCompare) -{ - BOOST_CHECK_EQUAL(begin(), end()); - BOOST_CHECK_EQUAL(rbegin(), rend()); - emplace_back(); - BOOST_CHECK_LT(begin(), end()); - BOOST_CHECK_LT(rbegin(), rend()); - BOOST_CHECK_LT(cbegin(), cend()); - BOOST_CHECK_LT(crbegin(), crend()); -} - -BOOST_AUTO_TEST_SUITE_END(); - -BOOST_AUTO_TEST_CASE(CreateCopySource, *boost::unit_test::timeout(1)) -{ - const std::vector src {4, 6, 2, 4, 6, 0}; - glContainer dst {src}; - static_assert(std::is_same_v<decltype(src)::value_type, decltype(dst)::value_type>); - dst.unmap(); - BOOST_CHECK_EQUAL_COLLECTIONS(src.begin(), src.end(), dst.begin(), dst.end()); -} - -namespace { - struct C { - int x; - float y; - }; - - static_assert(std::is_trivially_destructible_v<C>); - - struct CC { - CC() = default; - - CC(int intValue, float floatValue) noexcept : x {intValue}, y {floatValue} { } - - ~CC() - { - ++x; - } - - DEFAULT_MOVE_COPY(CC); - - int x; - float y; - }; - - static_assert(!std::is_trivially_destructible_v<CC>); -} - -BOOST_FIXTURE_TEST_SUITE(c, glContainer<C>) - -BOOST_AUTO_TEST_CASE(Basic) -{ - BOOST_CHECK_NO_THROW(emplace_back(1, 2.F)); - BOOST_CHECK_EQUAL(1, begin()->x); - BOOST_CHECK_EQUAL(2.F, begin()->y); - BOOST_CHECK_NO_THROW(begin()->x = 3); - BOOST_CHECK_EQUAL(3, begin()->x); - - BOOST_CHECK_NO_THROW(push_back(C {4, 5.F})); - BOOST_CHECK_EQUAL(3, begin()->x); - BOOST_CHECK_EQUAL(2.F, begin()->y); - BOOST_CHECK_EQUAL(4, rbegin()->x); - BOOST_CHECK_EQUAL(5.F, rbegin()->y); -} - -BOOST_AUTO_TEST_SUITE_END(); - -BOOST_FIXTURE_TEST_SUITE(cc, glContainer<CC>) - -BOOST_AUTO_TEST_CASE(Basic) -{ - BOOST_CHECK_NO_THROW(emplace_back(1, 2.F)); - BOOST_CHECK_EQUAL(1, begin()->x); - BOOST_CHECK_EQUAL(2.F, begin()->y); - BOOST_CHECK_NO_THROW(begin()->x = 3); - BOOST_CHECK_EQUAL(3, begin()->x); - - BOOST_CHECK_NO_THROW(push_back(CC {4, 5.F})); - BOOST_CHECK_EQUAL(3, begin()->x); - BOOST_CHECK_EQUAL(2.F, begin()->y); - BOOST_CHECK_EQUAL(4, rbegin()->x); - BOOST_CHECK_EQUAL(5.F, rbegin()->y); - BOOST_CHECK_NO_THROW(pop_back()); - BOOST_CHECK_EQUAL(size(), 1); - BOOST_CHECK_EQUAL(capacity(), 2); - BOOST_CHECK_NO_THROW(resize(3)); - BOOST_CHECK_EQUAL(size(), 3); - BOOST_CHECK_EQUAL(capacity(), 3); - BOOST_CHECK_NO_THROW(resize(1)); - BOOST_CHECK_EQUAL(size(), 1); - BOOST_CHECK_EQUAL(capacity(), 1); -} - -BOOST_AUTO_TEST_CASE(InsertRemoveTest) -{ - BOOST_CHECK_NO_THROW(emplace_back(1, 2.F)); - BOOST_CHECK_NO_THROW(emplace_back(3, 4.F)); - BOOST_CHECK_NO_THROW(emplace(begin(), 5, 6.F)); - BOOST_CHECK_NO_THROW(emplace(begin() + 1, 7, 8.F)); - BOOST_CHECK_NO_THROW(emplace(begin() + 2, 9, 10.F)); - BOOST_CHECK_EQUAL(capacity(), 8); - BOOST_CHECK_EQUAL(size(), 5); - BOOST_CHECK_NO_THROW(shrink_to_fit()); - BOOST_CHECK_EQUAL(capacity(), 5); - BOOST_CHECK_EQUAL(size(), 5); -} - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/test/test-instancing.cpp b/test/test-instancing.cpp index 4748f93..399a84c 100644 --- a/test/test-instancing.cpp +++ b/test/test-instancing.cpp @@ -77,19 +77,6 @@ BOOST_AUTO_TEST_CASE(AcquireReleaseMove) BOOST_CHECK(reverseIndex.empty()); } -BOOST_AUTO_TEST_CASE(AutoMapUnmap) -{ - { - auto proxy = acquire(); - BOOST_CHECK(data_); - std::ignore = bufferName(); - BOOST_CHECK(data_); - BOOST_CHECK_EQUAL(1, size()); - BOOST_CHECK(!data_); - } - BOOST_CHECK_EQUAL(0, size()); -} - BOOST_AUTO_TEST_CASE(Initialize) { auto proxy = acquire(5); @@ -246,7 +233,7 @@ BOOST_AUTO_TEST_CASE(PartitionBy, *boost::unit_test::timeout(1)) }; auto matchedEnd = partition(pred); // The underlying data is partitioned... - BOOST_REQUIRE(std::is_partitioned(mkcspan().cbegin(), mkcspan().cend(), pred)); + BOOST_REQUIRE(std::is_partitioned(cbegin(), cend(), pred)); // The external view of the data is unchanged... BOOST_CHECK_EQUAL_COLLECTIONS(values.cbegin(), values.cend(), instances.cbegin(), instances.cend()); // The partition point is right... @@ -281,7 +268,7 @@ BOOST_AUTO_TEST_CASE(PartitionBy2, *boost::unit_test::timeout(1)) auto matchedBoundaries = partition(pred3, pred5); // As PartitionBy... primary partition is normal layout // The underlying data is partitioned... - BOOST_REQUIRE(std::is_partitioned(mkcspan().cbegin(), mkcspan().cend(), pred3)); + BOOST_REQUIRE(std::is_partitioned(cbegin(), cend(), pred3)); // The external view of the data is unchanged... BOOST_CHECK_EQUAL_COLLECTIONS(values.cbegin(), values.cend(), instances.cbegin(), instances.cend()); // The partition point is right... @@ -291,19 +278,17 @@ BOOST_AUTO_TEST_CASE(PartitionBy2, *boost::unit_test::timeout(1)) // Secondary partition lives contiguous in the middle somewhere, with two falsy blocks at each end const auto p2bndry = matchedBoundaries.second; - BOOST_TEST_CONTEXT(mkcspan()) { + BOOST_TEST_CONTEXT(std::span(cbegin(), cend())) { BOOST_TEST_CONTEXT(matchedBoundaries.first) { - BOOST_CHECK(std::all_of( - mkcspan().cbegin(), mkcspan().cbegin() + static_cast<int>(matchedBoundaries.first), pred3)); - BOOST_CHECK(std::none_of( - mkcspan().cbegin() + static_cast<int>(matchedBoundaries.first), mkcspan().cend(), pred3)); + BOOST_CHECK(std::all_of(cbegin(), cbegin() + static_cast<int>(matchedBoundaries.first), pred3)); + BOOST_CHECK(std::none_of(cbegin() + static_cast<int>(matchedBoundaries.first), cend(), pred3)); } BOOST_TEST_CONTEXT(p2bndry) { - BOOST_CHECK(std::all_of(mkcspan().cbegin() + static_cast<int>(p2bndry.first), - mkcspan().begin() + static_cast<int>(p2bndry.second), pred5)); - BOOST_CHECK(std::none_of(mkcspan().cbegin(), mkcspan().cbegin() + static_cast<int>(p2bndry.first), pred5)); - BOOST_CHECK(std::none_of(mkcspan().cbegin() + static_cast<int>(p2bndry.second), mkcspan().cend(), pred5)); + BOOST_CHECK(std::all_of( + cbegin() + static_cast<int>(p2bndry.first), cbegin() + static_cast<int>(p2bndry.second), pred5)); + BOOST_CHECK(std::none_of(cbegin(), cbegin() + static_cast<int>(p2bndry.first), pred5)); + BOOST_CHECK(std::none_of(cbegin() + static_cast<int>(p2bndry.second), cend(), pred5)); } } |
