Fixing tree and adding unit tests
This commit is contained in:
@@ -29,5 +29,5 @@ float4 fragmentMain(in FragmentParameter params) : SV_Target
|
|||||||
{
|
{
|
||||||
result += pLightEnv.pointLights[i].illuminate(lightingParams, brdf);
|
result += pLightEnv.pointLights[i].illuminate(lightingParams, brdf);
|
||||||
}
|
}
|
||||||
return float4(result, 1.0f);
|
return float4(params.vertexColor, 1.0f);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ void meshMain(
|
|||||||
{
|
{
|
||||||
uint vertexIndex = pScene.vertexIndices[m.vertexOffset + v];
|
uint vertexIndex = pScene.vertexIndices[m.vertexOffset + v];
|
||||||
VertexAttributes attr = pVertexData.getAttributes(md.indicesOffset + vertexIndex);
|
VertexAttributes attr = pVertexData.getAttributes(md.indicesOffset + vertexIndex);
|
||||||
|
attr.vertexColor = m.color;
|
||||||
vertices[v] = attr.getParameter(inst.transformMatrix);
|
vertices[v] = attr.getParameter(inst.transformMatrix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ struct MeshletDescription
|
|||||||
uint32_t primitiveCount;
|
uint32_t primitiveCount;
|
||||||
uint32_t vertexOffset;
|
uint32_t vertexOffset;
|
||||||
uint32_t primitiveOffset;
|
uint32_t primitiveOffset;
|
||||||
|
float3 color;
|
||||||
|
float pad;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MeshData
|
struct MeshData
|
||||||
|
|||||||
@@ -268,11 +268,7 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array<PMaterialIns
|
|||||||
|
|
||||||
Array<Meshlet> meshlets;
|
Array<Meshlet> meshlets;
|
||||||
meshlets.reserve(indices.size() / (3ull * Gfx::numPrimitivesPerMeshlet));
|
meshlets.reserve(indices.size() / (3ull * Gfx::numPrimitivesPerMeshlet));
|
||||||
Meshlet::build(indices, meshlets);
|
Meshlet::build(positions, indices, meshlets);
|
||||||
for (auto& meshlet : meshlets)
|
|
||||||
{
|
|
||||||
meshlet.calcBoundingBox(positions);
|
|
||||||
}
|
|
||||||
vertexData->loadMesh(id, indices, meshlets);
|
vertexData->loadMesh(id, indices, meshlets);
|
||||||
|
|
||||||
collider.physicsMesh.addCollider(positions, indices, Matrix4(1.0f));
|
collider.physicsMesh.addCollider(positions, indices, Matrix4(1.0f));
|
||||||
|
|||||||
@@ -185,7 +185,10 @@ public:
|
|||||||
, _size()
|
, _size()
|
||||||
, comp(other.comp)
|
, comp(other.comp)
|
||||||
{
|
{
|
||||||
std::copy(other.begin(), other.end(), begin());
|
for (const auto& elem : other)
|
||||||
|
{
|
||||||
|
insert(elem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
constexpr Tree(Tree&& other) noexcept
|
constexpr Tree(Tree&& other) noexcept
|
||||||
: alloc(std::move(other.alloc))
|
: alloc(std::move(other.alloc))
|
||||||
@@ -204,11 +207,14 @@ public:
|
|||||||
if (this != &other)
|
if (this != &other)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
alloc = other.alloc;
|
if constexpr (std::allocator_traits<allocator_type>::propagate_on_container_copy_assignment::value)
|
||||||
comp = other.comp;
|
{
|
||||||
root = nullptr;
|
alloc = other.alloc;
|
||||||
_size = 0;
|
}
|
||||||
std::copy(other.begin(), other.end(), begin());
|
for (const auto& elem : other)
|
||||||
|
{
|
||||||
|
insert(elem);
|
||||||
|
}
|
||||||
markIteratorsDirty();
|
markIteratorsDirty();
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
@@ -405,7 +411,7 @@ private:
|
|||||||
Node* newNode = alloc.allocate(1);
|
Node* newNode = alloc.allocate(1);
|
||||||
std::allocator_traits<NodeAlloc>::construct(alloc, newNode, nullptr, nullptr, std::forward<NodeDataType>(data));
|
std::allocator_traits<NodeAlloc>::construct(alloc, newNode, nullptr, nullptr, std::forward<NodeDataType>(data));
|
||||||
|
|
||||||
if (comp(keyFun(r->data), keyFun(newNode->data)))
|
if (comp(keyFun(newNode->data), keyFun(r->data)))
|
||||||
{
|
{
|
||||||
newNode->rightChild = r;
|
newNode->rightChild = r;
|
||||||
newNode->leftChild = r->leftChild;
|
newNode->leftChild = r->leftChild;
|
||||||
@@ -456,12 +462,12 @@ private:
|
|||||||
{
|
{
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
if (comp(keyFun(r->data), key))
|
if (comp(key, keyFun(r->data)))
|
||||||
{
|
{
|
||||||
if (r->leftChild == nullptr)
|
if (r->leftChild == nullptr)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (comp(keyFun(r->leftChild->data), key))
|
if (comp(key, keyFun(r->leftChild->data)))
|
||||||
{
|
{
|
||||||
r->leftChild->leftChild = _splay(r->leftChild->leftChild, key);
|
r->leftChild->leftChild = _splay(r->leftChild->leftChild, key);
|
||||||
|
|
||||||
@@ -483,7 +489,7 @@ private:
|
|||||||
if (r->rightChild == nullptr)
|
if (r->rightChild == nullptr)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (comp(keyFun(r->rightChild->data), key))
|
if (comp(key, keyFun(r->rightChild->data)))
|
||||||
{
|
{
|
||||||
r->rightChild->leftChild = _splay(r->rightChild->leftChild, key);
|
r->rightChild->leftChild = _splay(r->rightChild->leftChild, key);
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ target_sources(Engine
|
|||||||
Initializer.cpp
|
Initializer.cpp
|
||||||
Mesh.h
|
Mesh.h
|
||||||
Mesh.cpp
|
Mesh.cpp
|
||||||
|
Meshlet.h
|
||||||
|
Meshlet.cpp
|
||||||
Pipeline.h
|
Pipeline.h
|
||||||
Pipeline.cpp
|
Pipeline.cpp
|
||||||
RenderTarget.h
|
RenderTarget.h
|
||||||
@@ -43,6 +45,7 @@ target_sources(Engine
|
|||||||
Graphics.h
|
Graphics.h
|
||||||
Initializer.h
|
Initializer.h
|
||||||
Mesh.h
|
Mesh.h
|
||||||
|
Meshlet.h
|
||||||
Pipeline.h
|
Pipeline.h
|
||||||
RenderTarget.h
|
RenderTarget.h
|
||||||
Resources.h
|
Resources.h
|
||||||
|
|||||||
@@ -0,0 +1,203 @@
|
|||||||
|
#include "Meshlet.h"
|
||||||
|
#include "Containers/Map.h"
|
||||||
|
#include "Containers/List.h"
|
||||||
|
#include "Containers/Set.h"
|
||||||
|
|
||||||
|
using namespace Seele;
|
||||||
|
|
||||||
|
// Tipsy algorithm by Sanders 2007
|
||||||
|
struct Triangle
|
||||||
|
{
|
||||||
|
bool emitted = false;
|
||||||
|
StaticArray<uint32, 3> indices;
|
||||||
|
};
|
||||||
|
|
||||||
|
Map<uint32, List<Triangle>> buildAdjacency(const Array<uint32>& indices)
|
||||||
|
{
|
||||||
|
Map<uint32, List<Triangle>> result;
|
||||||
|
for (uint32 i = 0; i < indices.size(); i += 3)
|
||||||
|
{
|
||||||
|
result[indices[i + 0]].add(Triangle{
|
||||||
|
.emitted = false,
|
||||||
|
.indices = {
|
||||||
|
indices[i + 0],
|
||||||
|
indices[i + 1],
|
||||||
|
indices[i + 2],
|
||||||
|
}
|
||||||
|
});
|
||||||
|
result[indices[i + 1]].add(Triangle{
|
||||||
|
.emitted = false,
|
||||||
|
.indices = {
|
||||||
|
indices[i + 0],
|
||||||
|
indices[i + 1],
|
||||||
|
indices[i + 2],
|
||||||
|
}
|
||||||
|
});
|
||||||
|
result[indices[i + 2]].add(Triangle{
|
||||||
|
.emitted = false,
|
||||||
|
.indices = {
|
||||||
|
indices[i + 0],
|
||||||
|
indices[i + 1],
|
||||||
|
indices[i + 2],
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<uint32, uint32> getTriangleCounts(Map<uint32, List<Triangle>>& adjacency)
|
||||||
|
{
|
||||||
|
Map<uint32, uint32> result;
|
||||||
|
for (const auto& [index, list] : adjacency)
|
||||||
|
{
|
||||||
|
result[index] = list.size();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 skipDeadEnd(Map<uint32, uint32>& L, Array<uint32>& D, const Array<uint32>& indices, uint32& i, uint32 vertexCount)
|
||||||
|
{
|
||||||
|
while (!D.empty())
|
||||||
|
{
|
||||||
|
uint32 d = D.back();
|
||||||
|
D.pop();
|
||||||
|
if (L[d] > 0)
|
||||||
|
{
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (i < vertexCount)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
if (L[i] > 0)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 getNextVertex(const Array<uint32>& indices, uint32& i, uint32 cacheSize, Set<uint32> N, const Array<uint32>& C, uint32 s, Map<uint32, uint32>& L, Array<uint32>& D, uint32 vertexCount)
|
||||||
|
{
|
||||||
|
int32 n = -1;
|
||||||
|
int32 p = -1;
|
||||||
|
int32 m = 0;
|
||||||
|
for (uint32 v : N)
|
||||||
|
{
|
||||||
|
if (L[v] > 0)
|
||||||
|
{
|
||||||
|
p = 0;
|
||||||
|
if (s - C[v] + 2 * L[v] <= cacheSize)
|
||||||
|
{
|
||||||
|
p = s - C[v];
|
||||||
|
}
|
||||||
|
if (p > m)
|
||||||
|
{
|
||||||
|
m = p;
|
||||||
|
n = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (n == -1)
|
||||||
|
{
|
||||||
|
n = skipDeadEnd(L, D, indices, i, vertexCount);
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
Array<uint32> tipsify(const Array<Vector>& positions, const Array<uint32>& indices, uint32 cacheSize)
|
||||||
|
{
|
||||||
|
auto A = buildAdjacency(indices);
|
||||||
|
auto L = getTriangleCounts(A);
|
||||||
|
auto C = Array<uint32>(positions.size(), 0);
|
||||||
|
auto D = Array<uint32>();
|
||||||
|
Array<uint32> output;
|
||||||
|
int32 f = 0;
|
||||||
|
uint32 s = cacheSize + 1, i = 1;
|
||||||
|
while (f >= 0)
|
||||||
|
{
|
||||||
|
auto N = Set<uint32>();
|
||||||
|
for (Triangle t : A[f])
|
||||||
|
{
|
||||||
|
if (!t.emitted)
|
||||||
|
{
|
||||||
|
for (uint32 v : t.indices)
|
||||||
|
{
|
||||||
|
output.add(v);
|
||||||
|
D.add(v);
|
||||||
|
N.insert(v);
|
||||||
|
L[v] = L[v] - 1;
|
||||||
|
if (s - C[v] > cacheSize)
|
||||||
|
{
|
||||||
|
C[v] = s;
|
||||||
|
s = s + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t.emitted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f = getNextVertex(indices, i, cacheSize, std::move(N), C, s, L, D, positions.size());
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Meshlet::build(const Array<Vector>& positions, const Array<uint32>& indices, Array<Meshlet>& meshlets)
|
||||||
|
{
|
||||||
|
Meshlet current = {
|
||||||
|
.numVertices = 0,
|
||||||
|
.numPrimitives = 0,
|
||||||
|
};
|
||||||
|
auto findIndex = [¤t](uint32 index) -> int {
|
||||||
|
for (uint32 i = 0; i < current.numVertices; ++i)
|
||||||
|
{
|
||||||
|
if (current.uniqueVertices[i] == index)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (current.numVertices == Gfx::numVerticesPerMeshlet)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
current.uniqueVertices[current.numVertices] = index;
|
||||||
|
return current.numVertices++;
|
||||||
|
};
|
||||||
|
auto completeMeshlet = [&positions, &meshlets, ¤t]() {
|
||||||
|
for (uint32 i = 0; i < current.numVertices; ++i)
|
||||||
|
{
|
||||||
|
current.boundingBox.adjust(positions[current.uniqueVertices[i]]);
|
||||||
|
}
|
||||||
|
meshlets.add(current);
|
||||||
|
current = {
|
||||||
|
.numVertices = 0,
|
||||||
|
.numPrimitives = 0,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
for (size_t faceIndex = 0; faceIndex < indices.size() / 3; ++faceIndex)
|
||||||
|
{
|
||||||
|
int f1 = findIndex(indices[faceIndex * 3 + 0]);
|
||||||
|
int f2 = findIndex(indices[faceIndex * 3 + 1]);
|
||||||
|
int f3 = findIndex(indices[faceIndex * 3 + 2]);
|
||||||
|
|
||||||
|
if (f1 == -1 || f2 == -1 || f1 == -1)
|
||||||
|
{
|
||||||
|
completeMeshlet();
|
||||||
|
f1 = findIndex(indices[faceIndex * 3 + 0]);
|
||||||
|
f2 = findIndex(indices[faceIndex * 3 + 1]);
|
||||||
|
f3 = findIndex(indices[faceIndex * 3 + 2]);
|
||||||
|
}
|
||||||
|
current.primitiveLayout[current.numPrimitives * 3 + 0] = uint8(f1);
|
||||||
|
current.primitiveLayout[current.numPrimitives * 3 + 1] = uint8(f2);
|
||||||
|
current.primitiveLayout[current.numPrimitives * 3 + 2] = uint8(f3);
|
||||||
|
current.numPrimitives++;
|
||||||
|
if (current.numPrimitives == Gfx::numPrimitivesPerMeshlet)
|
||||||
|
{
|
||||||
|
completeMeshlet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (current.numVertices > 0)
|
||||||
|
{
|
||||||
|
completeMeshlet();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Math/AABB.h"
|
||||||
|
#include "Graphics/Enums.h"
|
||||||
|
|
||||||
|
namespace Seele
|
||||||
|
{
|
||||||
|
struct Meshlet
|
||||||
|
{
|
||||||
|
AABB boundingBox;
|
||||||
|
uint32 uniqueVertices[Gfx::numVerticesPerMeshlet]; // unique vertiex indices in the vertex data
|
||||||
|
uint8 primitiveLayout[Gfx::numPrimitivesPerMeshlet * 3]; // indices into the uniqueVertices array, only uint8 needed
|
||||||
|
uint32 numVertices;
|
||||||
|
uint32 numPrimitives;
|
||||||
|
static void build(const Array<Vector>& positions, const Array<uint32>& indices, Array<Meshlet>& meshlets);
|
||||||
|
};
|
||||||
|
} // namespace Seele
|
||||||
@@ -117,6 +117,7 @@ void VertexData::loadMesh(MeshId id, Array<uint32> loadedIndices, Array<Meshlet>
|
|||||||
.primitiveCount = m.numPrimitives,
|
.primitiveCount = m.numPrimitives,
|
||||||
.vertexOffset = vertexOffset,
|
.vertexOffset = vertexOffset,
|
||||||
.primitiveOffset = primitiveOffset,
|
.primitiveOffset = primitiveOffset,
|
||||||
|
.color = Vector((float)rand() / RAND_MAX,(float)rand() / RAND_MAX,(float)rand() / RAND_MAX),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
meshData[id].add(MeshData{
|
meshData[id].add(MeshData{
|
||||||
@@ -245,73 +246,3 @@ VertexData::VertexData()
|
|||||||
, dirty(false)
|
, dirty(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Meshlet::build(const Array<uint32>& indices, Array<Meshlet>& meshlets)
|
|
||||||
{
|
|
||||||
Map<uint32, Set<uint32>> connectivity;
|
|
||||||
for (uint32 i = 0; i < indices.size(); i+=3)
|
|
||||||
{
|
|
||||||
connectivity[indices[i]].insert(indices[i + 1]);
|
|
||||||
connectivity[indices[i]].insert(indices[i + 2]);
|
|
||||||
}
|
|
||||||
Meshlet current = {
|
|
||||||
.numVertices = 0,
|
|
||||||
.numPrimitives = 0,
|
|
||||||
};
|
|
||||||
auto findIndex = [¤t](uint32 index) -> int {
|
|
||||||
for (uint32 i = 0; i < current.numVertices; ++i)
|
|
||||||
{
|
|
||||||
if (current.uniqueVertices[i] == index)
|
|
||||||
{
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (current.numVertices == Gfx::numVerticesPerMeshlet)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
current.uniqueVertices[current.numVertices] = index;
|
|
||||||
return current.numVertices++;
|
|
||||||
};
|
|
||||||
auto completeMeshlet = [&meshlets, ¤t]() {
|
|
||||||
meshlets.add(current);
|
|
||||||
current = {
|
|
||||||
.numVertices = 0,
|
|
||||||
.numPrimitives = 0,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
for (size_t faceIndex = 0; faceIndex < indices.size() / 3; ++faceIndex)
|
|
||||||
{
|
|
||||||
int f1 = findIndex(indices[faceIndex * 3 + 0]);
|
|
||||||
int f2 = findIndex(indices[faceIndex * 3 + 1]);
|
|
||||||
int f3 = findIndex(indices[faceIndex * 3 + 2]);
|
|
||||||
|
|
||||||
if (f1 == -1 || f2 == -1 || f1 == -1)
|
|
||||||
{
|
|
||||||
completeMeshlet();
|
|
||||||
f1 = findIndex(indices[faceIndex * 3 + 0]);
|
|
||||||
f2 = findIndex(indices[faceIndex * 3 + 1]);
|
|
||||||
f3 = findIndex(indices[faceIndex * 3 + 2]);
|
|
||||||
}
|
|
||||||
current.primitiveLayout[current.numPrimitives * 3 + 0] = uint8(f1);
|
|
||||||
current.primitiveLayout[current.numPrimitives * 3 + 1] = uint8(f2);
|
|
||||||
current.primitiveLayout[current.numPrimitives * 3 + 2] = uint8(f3);
|
|
||||||
current.numPrimitives++;
|
|
||||||
if (current.numPrimitives == Gfx::numPrimitivesPerMeshlet)
|
|
||||||
{
|
|
||||||
completeMeshlet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (current.numVertices > 0)
|
|
||||||
{
|
|
||||||
completeMeshlet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Meshlet::calcBoundingBox(const Array<Vector>& positions)
|
|
||||||
{
|
|
||||||
for (uint32 i = 0; i < numVertices; ++i)
|
|
||||||
{
|
|
||||||
boundingBox.adjust(positions[uniqueVertices[i]]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
#include "Graphics/Command.h"
|
#include "Graphics/Command.h"
|
||||||
#include "Graphics/Descriptor.h"
|
#include "Graphics/Descriptor.h"
|
||||||
#include "Graphics/Buffer.h"
|
#include "Graphics/Buffer.h"
|
||||||
#include "Math/AABB.h"
|
#include "Meshlet.h"
|
||||||
|
|
||||||
namespace Seele
|
namespace Seele
|
||||||
{
|
{
|
||||||
@@ -23,16 +23,6 @@ struct MeshId
|
|||||||
return id == other.id;
|
return id == other.id;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
struct Meshlet
|
|
||||||
{
|
|
||||||
AABB boundingBox;
|
|
||||||
uint32 uniqueVertices[Gfx::numVerticesPerMeshlet]; // unique vertiex indices in the vertex data
|
|
||||||
uint8 primitiveLayout[Gfx::numPrimitivesPerMeshlet * 3]; // indices into the uniqueVertices array, only uint8 needed
|
|
||||||
uint32 numVertices;
|
|
||||||
uint32 numPrimitives;
|
|
||||||
static void build(const Array<uint32>& indices, Array<Meshlet>& meshlets);
|
|
||||||
void calcBoundingBox(const Array<Vector>& positions);
|
|
||||||
};
|
|
||||||
class VertexData
|
class VertexData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -99,6 +89,8 @@ protected:
|
|||||||
uint32_t primitiveCount;
|
uint32_t primitiveCount;
|
||||||
uint32_t vertexOffset;
|
uint32_t vertexOffset;
|
||||||
uint32_t primitiveOffset;
|
uint32_t primitiveOffset;
|
||||||
|
Vector color;
|
||||||
|
float pad;
|
||||||
};
|
};
|
||||||
std::mutex materialDataLock;
|
std::mutex materialDataLock;
|
||||||
Map<std::string, MaterialData> materialData;
|
Map<std::string, MaterialData> materialData;
|
||||||
|
|||||||
@@ -82,10 +82,34 @@ TEST(CachedMap, custom_key)
|
|||||||
|
|
||||||
TEST(CachedMap, string_key)
|
TEST(CachedMap, string_key)
|
||||||
{
|
{
|
||||||
std::map<std::string, int> map;
|
Map<std::string, int> map;
|
||||||
map["Test"] = 2;
|
map["Test"] = 2;
|
||||||
map["Test2"] = 3;
|
map["Test2"] = 3;
|
||||||
ASSERT_EQ(map["Test"], 2);
|
ASSERT_EQ(map["Test"], 2);
|
||||||
ASSERT_EQ(map["Test2"], 3);
|
ASSERT_EQ(map["Test2"], 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(CachedMap, copy)
|
||||||
|
{
|
||||||
|
Map<int, int> map;
|
||||||
|
map[54] = 14;
|
||||||
|
map[5123] = 51;
|
||||||
|
map[262] = 14;
|
||||||
|
map[9620] = 91283;
|
||||||
|
map[141] = 415;
|
||||||
|
Map<int, int> map2 = map;
|
||||||
|
Map<int, int> map3;
|
||||||
|
map3 = map;
|
||||||
|
Map<int, int>::iterator i1 = map.begin();
|
||||||
|
Map<int, int>::iterator i2 = map2.begin();
|
||||||
|
Map<int, int>::iterator i3 = map3.begin();
|
||||||
|
while(i1 != map.end())
|
||||||
|
{
|
||||||
|
ASSERT_EQ(i1->key, i2->key);
|
||||||
|
ASSERT_EQ(i1->value, i2->value);
|
||||||
|
ASSERT_EQ(i1->key, i3->key);
|
||||||
|
ASSERT_EQ(i1->value, i3->value);
|
||||||
|
i1++; i2++; i3++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user