summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--game/network/rail.cpp7
-rw-r--r--game/scenary/foliage.cpp10
-rw-r--r--game/scenary/illuminator.cpp18
-rw-r--r--game/vehicles/railVehicleClass.cpp10
-rw-r--r--gfx/gl/instanceVertices.h39
-rw-r--r--lib/glAllocator.h90
-rw-r--r--lib/glContainer.h496
-rw-r--r--test/Jamfile.jam8
-rw-r--r--test/test-glAllocator.cpp28
-rw-r--r--test/test-glContainer.cpp453
-rw-r--r--test/test-instancing.cpp33
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));
}
}