mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-25 22:45:39 +00:00
* Added a class template argument deduction guide (CTAD) to infer the `T` and `N` template arguments. This lets you write `Vector{1,2,3}` instead of `Vector<int, 3>{1,2,3}`. This is important as a mismatch between the number of constructor arguments and the `N` template argument can cause silent heap allocations, which we're trying to avoid. The `T` deduction uses the same smarts as the return-type deduction of `Switch()`, so: * `Vector{1, 2.0}` would construct a `Vector<double, 2>` * `Vector{i32, u32}` would construct a `Vector<const sem::Type*, 2>` * Removed the Vector(size_t) and Vector(size_t, const T&) constructors. This is a move away from the std::vector style API, but these are rarely more efficient than calling Reserve() and Push(), as you remove the redundant initialization. The main reason for doing this is to remove ambiguity between `Vector{1}` and `Vector(1)`. * Added support for covariance conversion (`Vector<Derived*, N>` -> `Vector<Base*, N>`). Only supports pointers to `Castable`, as this can only safely work with single-inheritance. * Added support for conversion of `Vector<T*, N>` -> `Vector<const T*, N>`. This will remove pointless vector copies from the sem package. Bug: tint:1613 Change-Id: I79b9f82d623f90afa14f8ba1613ee49cccceafeb Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/97020 Reviewed-by: Antonio Maiorano <amaiorano@google.com> Commit-Queue: Ben Clayton <bclayton@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com>
1965 lines
64 KiB
C++
1965 lines
64 KiB
C++
// Copyright 2022 The Tint Authors.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "src/tint/utils/vector.h"
|
|
|
|
#include <string>
|
|
#include <tuple>
|
|
|
|
#include "gtest/gtest.h"
|
|
|
|
#include "src/tint/utils/bitcast.h"
|
|
|
|
namespace tint::utils {
|
|
namespace {
|
|
|
|
class C0 : public Castable<C0> {};
|
|
class C1 : public Castable<C1, C0> {};
|
|
class C2a : public Castable<C2a, C1> {};
|
|
class C2b : public Castable<C2b, C1> {};
|
|
|
|
/// @returns true if the address of el is within the memory of the vector vec.
|
|
template <typename T, size_t N, typename E>
|
|
bool IsInternal(Vector<T, N>& vec, E& el) {
|
|
auto ptr = Bitcast<uintptr_t>(&el);
|
|
auto base = Bitcast<uintptr_t>(&vec);
|
|
return ptr >= base && ptr < base + sizeof(vec);
|
|
}
|
|
|
|
/// @returns true if all elements of the vector `vec` are held within the memory of `vec`.
|
|
template <typename T, size_t N>
|
|
bool AllInternallyHeld(Vector<T, N>& vec) {
|
|
for (auto& el : vec) {
|
|
if (!IsInternal(vec, el)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/// @returns true if all elements of the vector `vec` are held outside the memory of `vec`.
|
|
template <typename T, size_t N>
|
|
bool AllExternallyHeld(Vector<T, N>& vec) {
|
|
for (auto& el : vec) {
|
|
if (IsInternal(vec, el)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Static asserts
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
static_assert(std::is_same_v<VectorCommonType<int>, int>);
|
|
static_assert(std::is_same_v<VectorCommonType<int, int>, int>);
|
|
static_assert(std::is_same_v<VectorCommonType<int, float>, float>);
|
|
|
|
static_assert(std::is_same_v<VectorCommonType<C0*>, C0*>);
|
|
static_assert(std::is_same_v<VectorCommonType<const C0*>, const C0*>);
|
|
|
|
static_assert(std::is_same_v<VectorCommonType<C0*, C1*>, C0*>);
|
|
static_assert(std::is_same_v<VectorCommonType<const C0*, C1*>, const C0*>);
|
|
static_assert(std::is_same_v<VectorCommonType<C0*, const C1*>, const C0*>);
|
|
static_assert(std::is_same_v<VectorCommonType<const C0*, const C1*>, const C0*>);
|
|
|
|
static_assert(std::is_same_v<VectorCommonType<C2a*, C2b*>, C1*>);
|
|
static_assert(std::is_same_v<VectorCommonType<const C2a*, C2b*>, const C1*>);
|
|
static_assert(std::is_same_v<VectorCommonType<C2a*, const C2b*>, const C1*>);
|
|
static_assert(std::is_same_v<VectorCommonType<const C2a*, const C2b*>, const C1*>);
|
|
|
|
static_assert(CanReinterpretSlice<const C0*, C0*>, "apply const");
|
|
static_assert(!CanReinterpretSlice<C0*, const C0*>, "remove const");
|
|
static_assert(CanReinterpretSlice<C0*, C1*>, "up cast");
|
|
static_assert(CanReinterpretSlice<const C0*, const C1*>, "up cast");
|
|
static_assert(CanReinterpretSlice<const C0*, C1*>, "up cast, apply const");
|
|
static_assert(!CanReinterpretSlice<C0*, const C1*>, "up cast, remove const");
|
|
static_assert(!CanReinterpretSlice<C1*, C0*>, "down cast");
|
|
static_assert(!CanReinterpretSlice<const C1*, const C0*>, "down cast");
|
|
static_assert(!CanReinterpretSlice<const C1*, C0*>, "down cast, apply const");
|
|
static_assert(!CanReinterpretSlice<C1*, const C0*>, "down cast, remove const");
|
|
static_assert(!CanReinterpretSlice<const C1*, C0*>, "down cast, apply const");
|
|
static_assert(!CanReinterpretSlice<C1*, const C0*>, "down cast, remove const");
|
|
static_assert(!CanReinterpretSlice<C2a*, C2b*>, "sideways cast");
|
|
static_assert(!CanReinterpretSlice<const C2a*, const C2b*>, "sideways cast");
|
|
static_assert(!CanReinterpretSlice<const C2a*, C2b*>, "sideways cast, apply const");
|
|
static_assert(!CanReinterpretSlice<C2a*, const C2b*>, "sideways cast, remove const");
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// TintVectorTest
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
TEST(TintVectorTest, SmallArray_Empty) {
|
|
Vector<int, 2> vec;
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
}
|
|
|
|
TEST(TintVectorTest, Empty_NoSmallArray) {
|
|
Vector<int, 0> vec;
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_EQ(vec.Capacity(), 0u);
|
|
}
|
|
|
|
TEST(TintVectorTest, InitializerList_NoSpill) {
|
|
Vector<std::string, 2> vec{"one", "two"};
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], "one");
|
|
EXPECT_EQ(vec[1], "two");
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, InitializerList_WithSpill) {
|
|
Vector<std::string, 2> vec{"one", "two", "three"};
|
|
EXPECT_EQ(vec.Length(), 3u);
|
|
EXPECT_EQ(vec.Capacity(), 3u);
|
|
EXPECT_EQ(vec[0], "one");
|
|
EXPECT_EQ(vec[1], "two");
|
|
EXPECT_EQ(vec[2], "three");
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, InitializerList_NoSmallArray) {
|
|
Vector<std::string, 0> vec{"one", "two"};
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], "one");
|
|
EXPECT_EQ(vec[1], "two");
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, InferTN_1CString) {
|
|
auto vec = Vector{"one"};
|
|
static_assert(std::is_same_v<decltype(vec)::value_type, const char*>);
|
|
static_assert(decltype(vec)::static_length == 1u);
|
|
EXPECT_EQ(vec.Length(), 1u);
|
|
EXPECT_EQ(vec.Capacity(), 1u);
|
|
EXPECT_STREQ(vec[0], "one");
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, InferTN_2CStrings) {
|
|
auto vec = Vector{"one", "two"};
|
|
static_assert(std::is_same_v<decltype(vec)::value_type, const char*>);
|
|
static_assert(decltype(vec)::static_length == 2u);
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_STREQ(vec[0], "one");
|
|
EXPECT_STREQ(vec[1], "two");
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, InferTN_IntFloat) {
|
|
auto vec = Vector{1, 2.0f};
|
|
static_assert(std::is_same_v<decltype(vec)::value_type, float>);
|
|
static_assert(decltype(vec)::static_length == 2u);
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], 1.0f);
|
|
EXPECT_EQ(vec[1], 2.0f);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, InferTN_IntDoubleIntDouble) {
|
|
auto vec = Vector{1, 2.0, 3, 4.0};
|
|
static_assert(std::is_same_v<decltype(vec)::value_type, double>);
|
|
static_assert(decltype(vec)::static_length == 4u);
|
|
EXPECT_EQ(vec.Length(), 4u);
|
|
EXPECT_EQ(vec.Capacity(), 4u);
|
|
EXPECT_EQ(vec[0], 1.0);
|
|
EXPECT_EQ(vec[1], 2.0);
|
|
EXPECT_EQ(vec[2], 3.0);
|
|
EXPECT_EQ(vec[3], 4.0);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, InferTN_C0) {
|
|
C0 c0;
|
|
auto vec = Vector{&c0};
|
|
static_assert(std::is_same_v<decltype(vec)::value_type, C0*>);
|
|
static_assert(decltype(vec)::static_length == 1u);
|
|
EXPECT_EQ(vec.Length(), 1u);
|
|
EXPECT_EQ(vec.Capacity(), 1u);
|
|
EXPECT_EQ(vec[0], &c0);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, InferTN_ConstC0) {
|
|
const C0 c0;
|
|
auto vec = Vector{&c0};
|
|
static_assert(std::is_same_v<decltype(vec)::value_type, const C0*>);
|
|
static_assert(decltype(vec)::static_length == 1u);
|
|
EXPECT_EQ(vec.Length(), 1u);
|
|
EXPECT_EQ(vec.Capacity(), 1u);
|
|
EXPECT_EQ(vec[0], &c0);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, InferTN_C0C1) {
|
|
C0 c0;
|
|
C1 c1;
|
|
auto vec = Vector{&c0, &c1};
|
|
static_assert(std::is_same_v<decltype(vec)::value_type, C0*>);
|
|
static_assert(decltype(vec)::static_length == 2u);
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], &c0);
|
|
EXPECT_EQ(vec[1], &c1);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, InferTN_ConstC0C1) {
|
|
const C0 c0;
|
|
C1 c1;
|
|
auto vec = Vector{&c0, &c1};
|
|
static_assert(std::is_same_v<decltype(vec)::value_type, const C0*>);
|
|
static_assert(decltype(vec)::static_length == 2u);
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], &c0);
|
|
EXPECT_EQ(vec[1], &c1);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, InferTN_C0ConstC1) {
|
|
C0 c0;
|
|
const C1 c1;
|
|
auto vec = Vector{&c0, &c1};
|
|
static_assert(std::is_same_v<decltype(vec)::value_type, const C0*>);
|
|
static_assert(decltype(vec)::static_length == 2u);
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], &c0);
|
|
EXPECT_EQ(vec[1], &c1);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, InferTN_ConstC0ConstC1) {
|
|
const C0 c0;
|
|
const C1 c1;
|
|
auto vec = Vector{&c0, &c1};
|
|
static_assert(std::is_same_v<decltype(vec)::value_type, const C0*>);
|
|
static_assert(decltype(vec)::static_length == 2u);
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], &c0);
|
|
EXPECT_EQ(vec[1], &c1);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, InferTN_C2aC2b) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
auto vec = Vector{&c2a, &c2b};
|
|
static_assert(std::is_same_v<decltype(vec)::value_type, C1*>);
|
|
static_assert(decltype(vec)::static_length == 2u);
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], &c2a);
|
|
EXPECT_EQ(vec[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, InferTN_ConstC2aC2b) {
|
|
const C2a c2a;
|
|
C2b c2b;
|
|
auto vec = Vector{&c2a, &c2b};
|
|
static_assert(std::is_same_v<decltype(vec)::value_type, const C1*>);
|
|
static_assert(decltype(vec)::static_length == 2u);
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], &c2a);
|
|
EXPECT_EQ(vec[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, InferTN_C2aConstC2b) {
|
|
C2a c2a;
|
|
const C2b c2b;
|
|
auto vec = Vector{&c2a, &c2b};
|
|
static_assert(std::is_same_v<decltype(vec)::value_type, const C1*>);
|
|
static_assert(decltype(vec)::static_length == 2u);
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], &c2a);
|
|
EXPECT_EQ(vec[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, InferTN_ConstC2aConstC2b) {
|
|
const C2a c2a;
|
|
const C2b c2b;
|
|
auto vec = Vector{&c2a, &c2b};
|
|
static_assert(std::is_same_v<decltype(vec)::value_type, const C1*>);
|
|
static_assert(decltype(vec)::static_length == 2u);
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], &c2a);
|
|
EXPECT_EQ(vec[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, CopyVector_NoSpill_N2_to_N2) {
|
|
Vector<std::string, 2> vec_a{"hello", "world"};
|
|
Vector<std::string, 2> vec_b(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 2u);
|
|
EXPECT_EQ(vec_b.Capacity(), 2u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, CopyVector_WithSpill_N2_to_N2) {
|
|
Vector<std::string, 2> vec_a{"hello", "world", "spill"};
|
|
Vector<std::string, 2> vec_b(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 3u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_EQ(vec_b[2], "spill");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, CopyVector_NoSpill_N2_to_N1) {
|
|
Vector<std::string, 2> vec_a{"hello", "world"};
|
|
Vector<std::string, 1> vec_b(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 2u);
|
|
EXPECT_EQ(vec_b.Capacity(), 2u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, CopyVector_WithSpill_N2_to_N1) {
|
|
Vector<std::string, 2> vec_a{"hello", "world", "spill"};
|
|
Vector<std::string, 1> vec_b(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 3u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_EQ(vec_b[2], "spill");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, CopyVector_NoSpill_N2_to_N3) {
|
|
Vector<std::string, 2> vec_a{"hello", "world"};
|
|
Vector<std::string, 3> vec_b(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 2u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, CopyVector_WithSpill_N2_to_N3) {
|
|
Vector<std::string, 2> vec_a{"hello", "world", "spill"};
|
|
Vector<std::string, 3> vec_b(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 3u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_EQ(vec_b[2], "spill");
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, CopyVector_NoMoveUpcast_NoSpill) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 2> vec_a{&c2a, &c2b};
|
|
Vector<C0*, 2> vec_b(vec_a); // No move
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorTest, CopyVector_NoMoveUpcast_WithSpill) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 1> vec_a{&c2a, &c2b};
|
|
Vector<C0*, 2> vec_b(vec_a); // No move
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorTest, CopyVector_NoMoveAddConst_NoSpill) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 2> vec_a{&c2a, &c2b};
|
|
Vector<const C1*, 2> vec_b(vec_a); // No move
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorTest, CopyVector_NoMoveAddConst_WithSpill) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 1> vec_a{&c2a, &c2b};
|
|
Vector<const C1*, 2> vec_b(vec_a); // No move
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorTest, CopyVector_NoMoveUpcastAndAddConst_NoSpill) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 2> vec_a{&c2a, &c2b};
|
|
Vector<const C0*, 2> vec_b(vec_a); // No move
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorTest, CopyVector_NoMoveUpcastAndAddConst_WithSpill) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 1> vec_a{&c2a, &c2b};
|
|
Vector<const C0*, 2> vec_b(vec_a); // No move
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorTest, MoveVector_NoSpill_N2_to_N2) {
|
|
Vector<std::string, 2> vec_a{"hello", "world"};
|
|
Vector<std::string, 2> vec_b(std::move(vec_a));
|
|
EXPECT_EQ(vec_b.Length(), 2u);
|
|
EXPECT_EQ(vec_b.Capacity(), 2u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, MoveVector_WithSpill_N2_to_N2) {
|
|
Vector<std::string, 2> vec_a{"hello", "world", "spill"};
|
|
Vector<std::string, 2> vec_b(std::move(vec_a));
|
|
EXPECT_EQ(vec_b.Length(), 3u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_EQ(vec_b[2], "spill");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, MoveVector_NoSpill_N2_to_N1) {
|
|
Vector<std::string, 2> vec_a{"hello", "world"};
|
|
Vector<std::string, 1> vec_b(std::move(vec_a));
|
|
EXPECT_EQ(vec_b.Length(), 2u);
|
|
EXPECT_EQ(vec_b.Capacity(), 2u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, MoveVector_WithSpill_N2_to_N1) {
|
|
Vector<std::string, 2> vec_a{"hello", "world", "spill"};
|
|
Vector<std::string, 1> vec_b(std::move(vec_a));
|
|
EXPECT_EQ(vec_b.Length(), 3u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_EQ(vec_b[2], "spill");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, MoveVector_NoSpill_N2_to_N3) {
|
|
Vector<std::string, 2> vec_a{"hello", "world"};
|
|
Vector<std::string, 3> vec_b(std::move(vec_a));
|
|
EXPECT_EQ(vec_b.Length(), 2u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, MoveVector_WithSpill_N2_to_N3) {
|
|
Vector<std::string, 2> vec_a{"hello", "world", "spill"};
|
|
Vector<std::string, 3> vec_b(std::move(vec_a));
|
|
EXPECT_EQ(vec_b.Length(), 3u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_EQ(vec_b[2], "spill");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, MoveVector_Upcast_NoSpill) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 2> vec_a{&c2a, &c2b};
|
|
Vector<C0*, 2> vec_b(std::move(vec_a)); // Move
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorTest, MoveVector_Upcast_WithSpill) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 1> vec_a{&c2a, &c2b};
|
|
Vector<C0*, 2> vec_b(std::move(vec_a)); // Move
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b)); // Moved, not copied
|
|
}
|
|
|
|
TEST(TintVectorTest, MoveVector_AddConst_NoSpill) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 2> vec_a{&c2a, &c2b};
|
|
Vector<const C1*, 2> vec_b(std::move(vec_a)); // Move
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorTest, MoveVector_AddConst_WithSpill) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 1> vec_a{&c2a, &c2b};
|
|
Vector<const C1*, 2> vec_b(std::move(vec_a)); // Move
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b)); // Moved, not copied
|
|
}
|
|
|
|
TEST(TintVectorTest, MoveVector_UpcastAndAddConst_NoSpill) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 2> vec_a{&c2a, &c2b};
|
|
Vector<const C0*, 2> vec_b(std::move(vec_a)); // Move
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorTest, MoveVector_UpcastAndAddConst_WithSpill) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 1> vec_a{&c2a, &c2b};
|
|
Vector<const C0*, 2> vec_b(std::move(vec_a)); // Move
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b)); // Moved, not copied
|
|
}
|
|
|
|
TEST(TintVectorTest, CopyAssign_NoSpill_N2_to_N2) {
|
|
Vector<std::string, 2> vec_a{"hello", "world"};
|
|
Vector<std::string, 2> vec_b;
|
|
vec_b = vec_a;
|
|
EXPECT_EQ(vec_b.Length(), 2u);
|
|
EXPECT_EQ(vec_b.Capacity(), 2u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, CopyAssign_WithSpill_N2_to_N2) {
|
|
Vector<std::string, 2> vec_a{"hello", "world", "spill"};
|
|
Vector<std::string, 2> vec_b;
|
|
vec_b = vec_a;
|
|
EXPECT_EQ(vec_b.Length(), 3u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_EQ(vec_b[2], "spill");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, CopyAssign_NoSpill_N2_to_N1) {
|
|
Vector<std::string, 2> vec_a{"hello", "world"};
|
|
Vector<std::string, 1> vec_b;
|
|
vec_b = vec_a;
|
|
EXPECT_EQ(vec_b.Length(), 2u);
|
|
EXPECT_EQ(vec_b.Capacity(), 2u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, CopyAssign_WithSpill_N2_to_N1) {
|
|
Vector<std::string, 2> vec_a{"hello", "world", "spill"};
|
|
Vector<std::string, 1> vec_b;
|
|
vec_b = vec_a;
|
|
EXPECT_EQ(vec_b.Length(), 3u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_EQ(vec_b[2], "spill");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, CopyAssign_NoSpill_N2_to_N3) {
|
|
Vector<std::string, 2> vec_a{"hello", "world"};
|
|
Vector<std::string, 3> vec_b;
|
|
vec_b = vec_a;
|
|
EXPECT_EQ(vec_b.Length(), 2u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, CopyAssign_WithSpill_N2_to_N3) {
|
|
Vector<std::string, 2> vec_a{"hello", "world", "spill"};
|
|
Vector<std::string, 3> vec_b;
|
|
vec_b = vec_a;
|
|
EXPECT_EQ(vec_b.Length(), 3u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_EQ(vec_b[2], "spill");
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, CopyAssign_NoSpill_N2_to_N0) {
|
|
Vector<std::string, 2> vec_a{"hello", "world"};
|
|
Vector<std::string, 0> vec_b;
|
|
vec_b = vec_a;
|
|
EXPECT_EQ(vec_b.Length(), 2u);
|
|
EXPECT_EQ(vec_b.Capacity(), 2u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, CopyAssign_WithSpill_N2_to_N0) {
|
|
Vector<std::string, 2> vec_a{"hello", "world", "spill"};
|
|
Vector<std::string, 0> vec_b;
|
|
vec_b = vec_a;
|
|
EXPECT_EQ(vec_b.Length(), 3u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_EQ(vec_b[2], "spill");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, CopyAssign_Self_NoSpill) {
|
|
Vector<std::string, 2> vec{"hello", "world"};
|
|
auto* vec_ptr = &vec; // Used to avoid -Wself-assign-overloaded
|
|
vec = *vec_ptr;
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], "hello");
|
|
EXPECT_EQ(vec[1], "world");
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, CopyAssign_Self_WithSpill) {
|
|
Vector<std::string, 1> vec{"hello", "world"};
|
|
auto* vec_ptr = &vec; // Used to avoid -Wself-assign-overloaded
|
|
vec = *vec_ptr;
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], "hello");
|
|
EXPECT_EQ(vec[1], "world");
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, MoveAssign_NoSpill_N2_to_N2) {
|
|
Vector<std::string, 2> vec_a{"hello", "world"};
|
|
Vector<std::string, 2> vec_b;
|
|
vec_b = std::move(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 2u);
|
|
EXPECT_EQ(vec_b.Capacity(), 2u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, MoveAssign_WithSpill_N2_to_N2) {
|
|
Vector<std::string, 2> vec_a{"hello", "world", "spill"};
|
|
Vector<std::string, 2> vec_b;
|
|
vec_b = std::move(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 3u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_EQ(vec_b[2], "spill");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, MoveAssign_NoSpill_N2_to_N1) {
|
|
Vector<std::string, 2> vec_a{"hello", "world"};
|
|
Vector<std::string, 1> vec_b;
|
|
vec_b = std::move(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 2u);
|
|
EXPECT_EQ(vec_b.Capacity(), 2u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, MoveAssign_SpillSpill_N2_to_N1) {
|
|
Vector<std::string, 2> vec_a{"hello", "world", "spill"};
|
|
Vector<std::string, 1> vec_b;
|
|
vec_b = std::move(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 3u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_EQ(vec_b[2], "spill");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, MoveAssign_NoSpill_N2_to_N3) {
|
|
Vector<std::string, 2> vec_a{"hello", "world"};
|
|
Vector<std::string, 3> vec_b;
|
|
vec_b = std::move(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 2u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, MoveAssign_WithSpill_N2_to_N3) {
|
|
Vector<std::string, 2> vec_a{"hello", "world", "spill"};
|
|
Vector<std::string, 3> vec_b;
|
|
vec_b = std::move(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 3u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_EQ(vec_b[2], "spill");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, MoveAssign_NoSpill_N2_to_N0) {
|
|
Vector<std::string, 2> vec_a{"hello", "world"};
|
|
Vector<std::string, 0> vec_b;
|
|
vec_b = std::move(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 2u);
|
|
EXPECT_EQ(vec_b.Capacity(), 2u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, MoveAssign_WithSpill_N2_to_N0) {
|
|
Vector<std::string, 2> vec_a{"hello", "world", "spill"};
|
|
Vector<std::string, 0> vec_b;
|
|
vec_b = std::move(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 3u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_EQ(vec_b[2], "spill");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, MoveAssign_Self_NoSpill) {
|
|
Vector<std::string, 2> vec{"hello", "world"};
|
|
auto* vec_ptr = &vec; // Used to avoid -Wself-move
|
|
vec = std::move(*vec_ptr);
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], "hello");
|
|
EXPECT_EQ(vec[1], "world");
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, MoveAssign_Self_WithSpill) {
|
|
Vector<std::string, 1> vec{"hello", "world"};
|
|
auto* vec_ptr = &vec; // Used to avoid -Wself-move
|
|
vec = std::move(*vec_ptr);
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], "hello");
|
|
EXPECT_EQ(vec[1], "world");
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, RepeatMoveAssign_NoSpill) {
|
|
Vector<std::string, 3> vec_a{"hello", "world"};
|
|
Vector<std::string, 3> vec_b{"Ciao", "mondo"};
|
|
Vector<std::string, 3> vec_c{"Bonjour", "le", "monde"};
|
|
Vector<std::string, 3> vec;
|
|
vec = std::move(vec_a);
|
|
vec = std::move(vec_b);
|
|
vec = std::move(vec_c);
|
|
EXPECT_EQ(vec.Length(), 3u);
|
|
EXPECT_EQ(vec.Capacity(), 3u);
|
|
EXPECT_EQ(vec[0], "Bonjour");
|
|
EXPECT_EQ(vec[1], "le");
|
|
EXPECT_EQ(vec[2], "monde");
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, DoubleMoveAssign_WithSpill) {
|
|
Vector<std::string, 1> vec_a{"hello", "world"};
|
|
Vector<std::string, 1> vec_b{"Ciao", "mondo"};
|
|
Vector<std::string, 1> vec_c{"bonjour", "le", "monde"};
|
|
Vector<std::string, 1> vec;
|
|
vec = std::move(vec_a);
|
|
vec = std::move(vec_b);
|
|
vec = std::move(vec_c);
|
|
EXPECT_EQ(vec.Length(), 3u);
|
|
EXPECT_EQ(vec.Capacity(), 3u);
|
|
EXPECT_EQ(vec[0], "bonjour");
|
|
EXPECT_EQ(vec[1], "le");
|
|
EXPECT_EQ(vec[2], "monde");
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, Index) {
|
|
Vector<std::string, 2> vec{"hello", "world"};
|
|
static_assert(!std::is_const_v<std::remove_reference_t<decltype(vec[0])>>);
|
|
EXPECT_EQ(vec[0], "hello");
|
|
EXPECT_EQ(vec[1], "world");
|
|
}
|
|
|
|
TEST(TintVectorTest, ConstIndex) {
|
|
const Vector<std::string, 2> vec{"hello", "world"};
|
|
static_assert(std::is_const_v<std::remove_reference_t<decltype(vec[0])>>);
|
|
EXPECT_EQ(vec[0], "hello");
|
|
EXPECT_EQ(vec[1], "world");
|
|
}
|
|
|
|
TEST(TintVectorTest, Reserve_NoSpill) {
|
|
Vector<std::string, 2> vec;
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
vec.Reserve(1);
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
vec.Reserve(2);
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
vec.Push("hello");
|
|
vec.Push("world");
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
vec.Reserve(1);
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, Reserve_WithSpill) {
|
|
Vector<std::string, 1> vec;
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_EQ(vec.Capacity(), 1u);
|
|
vec.Reserve(1);
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_EQ(vec.Capacity(), 1u);
|
|
vec.Reserve(2);
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
vec.Push("hello");
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
vec.Push("world");
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
vec.Reserve(1);
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, ResizeZero_NoSpill) {
|
|
Vector<std::string, 2> vec;
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
vec.Resize(1);
|
|
EXPECT_EQ(vec.Length(), 1u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], "");
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
vec[0] = "hello";
|
|
vec.Resize(2);
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], "hello");
|
|
EXPECT_EQ(vec[1], "");
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
vec[1] = "world";
|
|
vec.Resize(1);
|
|
EXPECT_EQ(vec.Length(), 1u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], "hello");
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
vec.Resize(2);
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], "hello");
|
|
EXPECT_EQ(vec[1], "");
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, ResizeZero_WithSpill) {
|
|
Vector<std::string, 1> vec;
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_EQ(vec.Capacity(), 1u);
|
|
vec.Resize(1);
|
|
EXPECT_EQ(vec.Length(), 1u);
|
|
EXPECT_EQ(vec.Capacity(), 1u);
|
|
EXPECT_EQ(vec[0], "");
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
vec[0] = "hello";
|
|
vec.Resize(2);
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], "hello");
|
|
EXPECT_EQ(vec[1], "");
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
vec[1] = "world";
|
|
vec.Resize(1);
|
|
EXPECT_EQ(vec.Length(), 1u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], "hello");
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
vec.Resize(2);
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], "hello");
|
|
EXPECT_EQ(vec[1], "");
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, ResizeValue_NoSpill) {
|
|
Vector<std::string, 2> vec;
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
vec.Resize(1, "meow");
|
|
EXPECT_EQ(vec.Length(), 1u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], "meow");
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
vec[0] = "hello";
|
|
vec.Resize(2, "woof");
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], "hello");
|
|
EXPECT_EQ(vec[1], "woof");
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
vec[1] = "world";
|
|
vec.Resize(1, "quack");
|
|
EXPECT_EQ(vec.Length(), 1u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], "hello");
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
vec.Resize(2, "hiss");
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], "hello");
|
|
EXPECT_EQ(vec[1], "hiss");
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, ResizeValue_WithSpill) {
|
|
Vector<std::string, 1> vec;
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_EQ(vec.Capacity(), 1u);
|
|
vec.Resize(1, "meow");
|
|
EXPECT_EQ(vec.Length(), 1u);
|
|
EXPECT_EQ(vec.Capacity(), 1u);
|
|
EXPECT_EQ(vec[0], "meow");
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
vec[0] = "hello";
|
|
vec.Resize(2, "woof");
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], "hello");
|
|
EXPECT_EQ(vec[1], "woof");
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
vec[1] = "world";
|
|
vec.Resize(1, "quack");
|
|
EXPECT_EQ(vec.Length(), 1u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], "hello");
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
vec.Resize(2, "hiss");
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], "hello");
|
|
EXPECT_EQ(vec[1], "hiss");
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, Reserve_NoSmallArray) {
|
|
Vector<std::string, 0> vec;
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_EQ(vec.Capacity(), 0u);
|
|
vec.Reserve(1);
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_EQ(vec.Capacity(), 1u);
|
|
vec.Reserve(2);
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
vec.Push("hello");
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
vec.Push("world");
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
vec.Reserve(1);
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, Resize_NoSmallArray) {
|
|
Vector<std::string, 0> vec;
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_EQ(vec.Capacity(), 0u);
|
|
vec.Resize(1);
|
|
EXPECT_EQ(vec.Length(), 1u);
|
|
EXPECT_EQ(vec.Capacity(), 1u);
|
|
EXPECT_EQ(vec[0], "");
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
vec[0] = "hello";
|
|
vec.Resize(2);
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], "hello");
|
|
EXPECT_EQ(vec[1], "");
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
vec[1] = "world";
|
|
vec.Resize(1);
|
|
EXPECT_EQ(vec.Length(), 1u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], "hello");
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
vec.Resize(2);
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
EXPECT_EQ(vec[0], "hello");
|
|
EXPECT_EQ(vec[1], "");
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, Copy_NoSpill_N2_to_N2_Empty) {
|
|
Vector<std::string, 2> vec_a{"hello", "world"};
|
|
Vector<std::string, 2> vec_b;
|
|
vec_b.Copy(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 2u);
|
|
EXPECT_EQ(vec_b.Capacity(), 2u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, Copy_NoSpill_N2_to_N2_NonEmpty) {
|
|
Vector<std::string, 2> vec_a{"hello", "world"};
|
|
Vector<std::string, 2> vec_b{"hallo", "wereld"};
|
|
vec_b.Copy(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 2u);
|
|
EXPECT_EQ(vec_b.Capacity(), 2u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, Copy_NoSpill_N2_to_N2_Spill) {
|
|
Vector<std::string, 2> vec_a{"hello", "world"};
|
|
Vector<std::string, 2> vec_b{"hallo", "wereld", "spill"};
|
|
vec_b.Copy(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 2u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, Copy_WithSpill_N2_to_N2_Empty) {
|
|
Vector<std::string, 2> vec_a{"hello", "world", "spill"};
|
|
Vector<std::string, 2> vec_b;
|
|
vec_b.Copy(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 3u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_EQ(vec_b[2], "spill");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, Copy_WithSpill_N2_to_N2_NonEmpty) {
|
|
Vector<std::string, 2> vec_a{"hello", "world", "spill"};
|
|
Vector<std::string, 2> vec_b{"hallo", "wereld"};
|
|
vec_b.Copy(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 3u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_EQ(vec_b[2], "spill");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, Copy_WithSpill_N2_to_N2_Spill) {
|
|
Vector<std::string, 2> vec_a{"hello", "world", "spill"};
|
|
Vector<std::string, 2> vec_b{"hallo", "wereld", "morsen"};
|
|
vec_b.Copy(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 3u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_EQ(vec_b[2], "spill");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, Copy_NoSpill_N2_to_N1_Empty) {
|
|
Vector<std::string, 2> vec_a{"hello", "world"};
|
|
Vector<std::string, 1> vec_b;
|
|
vec_b.Copy(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 2u);
|
|
EXPECT_EQ(vec_b.Capacity(), 2u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, Copy_NoSpill_N2_to_N1_NonEmpty) {
|
|
Vector<std::string, 2> vec_a{"hello", "world"};
|
|
Vector<std::string, 1> vec_b{"hallo"};
|
|
vec_b.Copy(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 2u);
|
|
EXPECT_EQ(vec_b.Capacity(), 2u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, Copy_NoSpill_N2_to_N1_Spill) {
|
|
Vector<std::string, 2> vec_a{"hello", "world"};
|
|
Vector<std::string, 1> vec_b{"hallo", "morsen"};
|
|
vec_b.Copy(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 2u);
|
|
EXPECT_EQ(vec_b.Capacity(), 2u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, Copy_WithSpill_N2_to_N1_Empty) {
|
|
Vector<std::string, 2> vec_a{"hello", "world", "spill"};
|
|
Vector<std::string, 1> vec_b;
|
|
vec_b.Copy(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 3u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_EQ(vec_b[2], "spill");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, Copy_WithSpill_N2_to_N1_NonEmpty) {
|
|
Vector<std::string, 2> vec_a{"hello", "world", "spill"};
|
|
Vector<std::string, 1> vec_b{"hallo"};
|
|
vec_b.Copy(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 3u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_EQ(vec_b[2], "spill");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, Copy_WithSpill_N2_to_N1_Spill) {
|
|
Vector<std::string, 2> vec_a{"hello", "world", "spill"};
|
|
Vector<std::string, 1> vec_b{"hallo", "wereld"};
|
|
vec_b.Copy(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 3u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_EQ(vec_b[2], "spill");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, Copy_NoSpill_N2_to_N3_Empty) {
|
|
Vector<std::string, 2> vec_a{"hello", "world"};
|
|
Vector<std::string, 3> vec_b;
|
|
vec_b.Copy(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 2u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, Copy_NoSpill_N2_to_N3_NonEmpty) {
|
|
Vector<std::string, 2> vec_a{"hello", "world"};
|
|
Vector<std::string, 3> vec_b{"hallo", "fijne", "wereld"};
|
|
vec_b.Copy(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 2u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, Copy_NoSpill_N2_to_N3_Spill) {
|
|
Vector<std::string, 2> vec_a{"hello", "world"};
|
|
Vector<std::string, 3> vec_b{"hallo", "fijne", "wereld", "morsen"};
|
|
vec_b.Copy(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 2u);
|
|
EXPECT_EQ(vec_b.Capacity(), 4u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, Copy_WithSpill_N2_to_N3_Empty) {
|
|
Vector<std::string, 2> vec_a{"hello", "world", "spill"};
|
|
Vector<std::string, 3> vec_b;
|
|
vec_b.Copy(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 3u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_EQ(vec_b[2], "spill");
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, Copy_WithSpill_N2_to_N3_NonEmpty) {
|
|
Vector<std::string, 2> vec_a{"hello", "world", "spill"};
|
|
Vector<std::string, 3> vec_b{"hallo", "fijne", "wereld"};
|
|
vec_b.Copy(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 3u);
|
|
EXPECT_EQ(vec_b.Capacity(), 3u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_EQ(vec_b[2], "spill");
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, Copy_WithSpill_N2_to_N3_Spill) {
|
|
Vector<std::string, 2> vec_a{"hello", "world", "spill"};
|
|
Vector<std::string, 3> vec_b{"hallo", "fijne", "wereld", "morsen"};
|
|
vec_b.Copy(vec_a);
|
|
EXPECT_EQ(vec_b.Length(), 3u);
|
|
EXPECT_EQ(vec_b.Capacity(), 4u);
|
|
EXPECT_EQ(vec_b[0], "hello");
|
|
EXPECT_EQ(vec_b[1], "world");
|
|
EXPECT_EQ(vec_b[2], "spill");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b));
|
|
}
|
|
|
|
TEST(TintVectorTest, Clear_Empty) {
|
|
Vector<std::string, 2> vec;
|
|
vec.Clear();
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
}
|
|
|
|
TEST(TintVectorTest, Clear_NoSpill) {
|
|
Vector<std::string, 2> vec{"hello", "world"};
|
|
vec.Clear();
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_EQ(vec.Capacity(), 2u);
|
|
}
|
|
|
|
TEST(TintVectorTest, Clear_WithSpill) {
|
|
Vector<std::string, 2> vec{"hello", "world", "spill"};
|
|
vec.Clear();
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_EQ(vec.Capacity(), 3u);
|
|
}
|
|
|
|
TEST(TintVectorTest, PushPop_StringNoSpill) {
|
|
const std::string hello = "hello";
|
|
const std::string world = "world";
|
|
|
|
Vector<std::string, 2> vec;
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
|
|
vec.Push(hello);
|
|
EXPECT_EQ(vec.Length(), 1u);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
|
|
vec.Push(world);
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
|
|
EXPECT_EQ(vec.Pop(), world);
|
|
EXPECT_EQ(vec.Length(), 1u);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
|
|
EXPECT_EQ(vec.Pop(), hello);
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, PushPop_StringWithSpill) {
|
|
const std::string hello = "hello";
|
|
const std::string world = "world";
|
|
|
|
Vector<std::string, 1> vec;
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
|
|
vec.Push(hello);
|
|
EXPECT_EQ(vec.Length(), 1u);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
|
|
vec.Push(world);
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
|
|
EXPECT_EQ(vec.Pop(), world);
|
|
EXPECT_EQ(vec.Length(), 1u);
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
|
|
EXPECT_EQ(vec.Pop(), hello);
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, PushPop_StringMoveNoSpill) {
|
|
std::string hello = "hello";
|
|
std::string world = "world";
|
|
|
|
Vector<std::string, 2> vec;
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
|
|
vec.Push(std::move(hello));
|
|
EXPECT_EQ(vec.Length(), 1u);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
|
|
vec.Push(std::move(world));
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
|
|
EXPECT_EQ(vec.Pop(), "world");
|
|
EXPECT_EQ(vec.Length(), 1u);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
|
|
EXPECT_EQ(vec.Pop(), "hello");
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, PushPop_StringMoveWithSpill) {
|
|
std::string hello = "hello";
|
|
std::string world = "world";
|
|
|
|
Vector<std::string, 1> vec;
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
|
|
vec.Push(std::move(hello));
|
|
EXPECT_EQ(vec.Length(), 1u);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
|
|
vec.Push(std::move(world));
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
|
|
EXPECT_EQ(vec.Pop(), "world");
|
|
EXPECT_EQ(vec.Length(), 1u);
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
|
|
EXPECT_EQ(vec.Pop(), "hello");
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, EmplacePop_TupleVarArgNoSpill) {
|
|
Vector<std::tuple<int, float, bool>, 2> vec;
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
|
|
vec.Emplace(1, 2.0, false);
|
|
EXPECT_EQ(vec.Length(), 1u);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
|
|
vec.Emplace(3, 4.0, true);
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
|
|
EXPECT_EQ(vec.Pop(), std::make_tuple(3, 4.0, true));
|
|
EXPECT_EQ(vec.Length(), 1u);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
|
|
EXPECT_EQ(vec.Pop(), std::make_tuple(1, 2.0, false));
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, EmplacePop_TupleVarArgWithSpill) {
|
|
Vector<std::tuple<int, float, bool>, 1> vec;
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
|
|
vec.Emplace(1, 2.0, false);
|
|
EXPECT_EQ(vec.Length(), 1u);
|
|
EXPECT_TRUE(AllInternallyHeld(vec));
|
|
|
|
vec.Emplace(3, 4.0, true);
|
|
EXPECT_EQ(vec.Length(), 2u);
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
|
|
EXPECT_EQ(vec.Pop(), std::make_tuple(3, 4.0, true));
|
|
EXPECT_EQ(vec.Length(), 1u);
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
|
|
EXPECT_EQ(vec.Pop(), std::make_tuple(1, 2.0, false));
|
|
EXPECT_EQ(vec.Length(), 0u);
|
|
EXPECT_TRUE(AllExternallyHeld(vec));
|
|
}
|
|
|
|
TEST(TintVectorTest, IsEmpty) {
|
|
Vector<std::string, 1> vec;
|
|
EXPECT_TRUE(vec.IsEmpty());
|
|
vec.Push("one");
|
|
EXPECT_FALSE(vec.IsEmpty());
|
|
vec.Pop();
|
|
EXPECT_TRUE(vec.IsEmpty());
|
|
}
|
|
|
|
TEST(TintVectorTest, FrontBack_NoSpill) {
|
|
Vector<std::string, 3> vec{"front", "mid", "back"};
|
|
static_assert(!std::is_const_v<std::remove_reference_t<decltype(vec.Front())>>);
|
|
static_assert(!std::is_const_v<std::remove_reference_t<decltype(vec.Back())>>);
|
|
EXPECT_EQ(vec.Front(), "front");
|
|
EXPECT_EQ(vec.Back(), "back");
|
|
}
|
|
|
|
TEST(TintVectorTest, FrontBack_WithSpill) {
|
|
Vector<std::string, 2> vec{"front", "mid", "back"};
|
|
static_assert(!std::is_const_v<std::remove_reference_t<decltype(vec.Front())>>);
|
|
static_assert(!std::is_const_v<std::remove_reference_t<decltype(vec.Back())>>);
|
|
EXPECT_EQ(vec.Front(), "front");
|
|
EXPECT_EQ(vec.Back(), "back");
|
|
}
|
|
|
|
TEST(TintVectorTest, ConstFrontBack_NoSpill) {
|
|
const Vector<std::string, 3> vec{"front", "mid", "back"};
|
|
static_assert(std::is_const_v<std::remove_reference_t<decltype(vec.Front())>>);
|
|
static_assert(std::is_const_v<std::remove_reference_t<decltype(vec.Back())>>);
|
|
EXPECT_EQ(vec.Front(), "front");
|
|
EXPECT_EQ(vec.Back(), "back");
|
|
}
|
|
|
|
TEST(TintVectorTest, ConstFrontBack_WithSpill) {
|
|
const Vector<std::string, 2> vec{"front", "mid", "back"};
|
|
static_assert(std::is_const_v<std::remove_reference_t<decltype(vec.Front())>>);
|
|
static_assert(std::is_const_v<std::remove_reference_t<decltype(vec.Back())>>);
|
|
EXPECT_EQ(vec.Front(), "front");
|
|
EXPECT_EQ(vec.Back(), "back");
|
|
}
|
|
|
|
TEST(TintVectorTest, BeginEnd_NoSpill) {
|
|
Vector<std::string, 3> vec{"front", "mid", "back"};
|
|
static_assert(!std::is_const_v<std::remove_reference_t<decltype(*vec.begin())>>);
|
|
static_assert(!std::is_const_v<std::remove_reference_t<decltype(*vec.end())>>);
|
|
EXPECT_EQ(vec.begin(), &vec[0]);
|
|
EXPECT_EQ(vec.end(), &vec[0] + 3);
|
|
}
|
|
|
|
TEST(TintVectorTest, BeginEnd_WithSpill) {
|
|
Vector<std::string, 2> vec{"front", "mid", "back"};
|
|
static_assert(!std::is_const_v<std::remove_reference_t<decltype(*vec.begin())>>);
|
|
static_assert(!std::is_const_v<std::remove_reference_t<decltype(*vec.end())>>);
|
|
EXPECT_EQ(vec.begin(), &vec[0]);
|
|
EXPECT_EQ(vec.end(), &vec[0] + 3);
|
|
}
|
|
|
|
TEST(TintVectorTest, ConstBeginEnd_NoSpill) {
|
|
const Vector<std::string, 3> vec{"front", "mid", "back"};
|
|
static_assert(std::is_const_v<std::remove_reference_t<decltype(*vec.begin())>>);
|
|
static_assert(std::is_const_v<std::remove_reference_t<decltype(*vec.end())>>);
|
|
EXPECT_EQ(vec.begin(), &vec[0]);
|
|
EXPECT_EQ(vec.end(), &vec[0] + 3);
|
|
}
|
|
|
|
TEST(TintVectorTest, ConstBeginEnd_WithSpill) {
|
|
const Vector<std::string, 2> vec{"front", "mid", "back"};
|
|
static_assert(std::is_const_v<std::remove_reference_t<decltype(*vec.begin())>>);
|
|
static_assert(std::is_const_v<std::remove_reference_t<decltype(*vec.end())>>);
|
|
EXPECT_EQ(vec.begin(), &vec[0]);
|
|
EXPECT_EQ(vec.end(), &vec[0] + 3);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// TintVectorRefTest
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
TEST(TintVectorRefTest, CopyVectorRef) {
|
|
Vector<std::string, 1> vec_a{"one", "two"};
|
|
VectorRef<std::string> vec_ref_a(std::move(vec_a));
|
|
VectorRef<std::string> vec_ref_b(vec_ref_a); // No move
|
|
Vector<std::string, 2> vec_b(std::move(vec_ref_b));
|
|
EXPECT_EQ(vec_b[0], "one");
|
|
EXPECT_EQ(vec_b[1], "two");
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorRefTest, CopyVectorRef_Upcast) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 1> vec_a{&c2a, &c2b};
|
|
VectorRef<C1*> vec_ref_a(std::move(vec_a));
|
|
VectorRef<C0*> vec_ref_b(vec_ref_a); // No-move. Up-cast
|
|
Vector<C0*, 2> vec_b(std::move(vec_ref_b));
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorRefTest, CopyVectorRef_AddConst) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 1> vec_a{&c2a, &c2b};
|
|
VectorRef<C1*> vec_ref_a(std::move(vec_a));
|
|
VectorRef<const C1*> vec_ref_b(vec_ref_a); // No-move. Up-cast
|
|
Vector<const C1*, 2> vec_b(std::move(vec_ref_b));
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorRefTest, CopyVectorRef_UpcastAndAddConst) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 1> vec_a{&c2a, &c2b};
|
|
VectorRef<C1*> vec_ref_a(std::move(vec_a));
|
|
VectorRef<const C0*> vec_ref_b(vec_ref_a); // No-move. Up-cast
|
|
Vector<const C0*, 2> vec_b(std::move(vec_ref_b));
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorRefTest, MoveVectorRef) {
|
|
Vector<std::string, 1> vec_a{"one", "two"};
|
|
VectorRef<std::string> vec_ref_a(std::move(vec_a)); // Move
|
|
VectorRef<std::string> vec_ref_b(std::move(vec_ref_a));
|
|
Vector<std::string, 2> vec_b(std::move(vec_ref_b));
|
|
EXPECT_EQ(vec_b[0], "one");
|
|
EXPECT_EQ(vec_b[1], "two");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b)); // Moved, not copied
|
|
}
|
|
|
|
TEST(TintVectorRefTest, MoveVectorRef_Upcast) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 1> vec_a{&c2a, &c2b};
|
|
VectorRef<C1*> vec_ref_a(std::move(vec_a));
|
|
VectorRef<C0*> vec_ref_b(std::move(vec_ref_a)); // Moved. Up-cast
|
|
Vector<C0*, 2> vec_b(std::move(vec_ref_b));
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b)); // Moved, not copied
|
|
}
|
|
|
|
TEST(TintVectorRefTest, MoveVectorRef_AddConst) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 1> vec_a{&c2a, &c2b};
|
|
VectorRef<C1*> vec_ref_a(std::move(vec_a));
|
|
VectorRef<const C1*> vec_ref_b(std::move(vec_ref_a)); // Moved. Up-cast
|
|
Vector<const C1*, 2> vec_b(std::move(vec_ref_b));
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b)); // Moved, not copied
|
|
}
|
|
|
|
TEST(TintVectorRefTest, MoveVectorRef_UpcastAndAddConst) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 1> vec_a{&c2a, &c2b};
|
|
VectorRef<C1*> vec_ref_a(std::move(vec_a));
|
|
VectorRef<const C0*> vec_ref_b(std::move(vec_ref_a)); // Moved. Up-cast
|
|
Vector<const C0*, 2> vec_b(std::move(vec_ref_b));
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b)); // Moved, not copied
|
|
}
|
|
|
|
TEST(TintVectorRefTest, CopyVector) {
|
|
Vector<std::string, 1> vec_a{"one", "two"};
|
|
VectorRef<std::string> vec_ref(vec_a); // No move
|
|
Vector<std::string, 2> vec_b(std::move(vec_ref));
|
|
EXPECT_EQ(vec_b[0], "one");
|
|
EXPECT_EQ(vec_b[1], "two");
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorRefTest, CopyVector_Upcast) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 1> vec_a{&c2a, &c2b};
|
|
VectorRef<C0*> vec_ref(vec_a); // No move
|
|
EXPECT_EQ(vec_ref[0], &c2a);
|
|
EXPECT_EQ(vec_ref[1], &c2b);
|
|
Vector<C0*, 2> vec_b(std::move(vec_ref));
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorRefTest, CopyVector_AddConst) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 1> vec_a{&c2a, &c2b};
|
|
VectorRef<const C1*> vec_ref(vec_a); // No move
|
|
EXPECT_EQ(vec_ref[0], &c2a);
|
|
EXPECT_EQ(vec_ref[1], &c2b);
|
|
Vector<const C1*, 2> vec_b(std::move(vec_ref));
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorRefTest, CopyVector_UpcastAndAddConst) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 1> vec_a{&c2a, &c2b};
|
|
VectorRef<const C0*> vec_ref(vec_a); // No move
|
|
EXPECT_EQ(vec_ref[0], &c2a);
|
|
EXPECT_EQ(vec_ref[1], &c2b);
|
|
Vector<const C0*, 2> vec_b(std::move(vec_ref));
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorRefTest, MoveVector) {
|
|
Vector<std::string, 1> vec_a{"one", "two"};
|
|
VectorRef<std::string> vec_ref(std::move(vec_a)); // Move
|
|
Vector<std::string, 2> vec_b(std::move(vec_ref));
|
|
EXPECT_EQ(vec_b[0], "one");
|
|
EXPECT_EQ(vec_b[1], "two");
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b)); // Moved, not copied
|
|
}
|
|
|
|
TEST(TintVectorRefTest, MoveVector_Upcast) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 1> vec_a{&c2a, &c2b};
|
|
VectorRef<C0*> vec_ref(std::move(vec_a)); // Move
|
|
EXPECT_EQ(vec_ref[0], &c2a);
|
|
EXPECT_EQ(vec_ref[1], &c2b);
|
|
Vector<C0*, 2> vec_b(std::move(vec_ref));
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b)); // Moved, not copied
|
|
}
|
|
|
|
TEST(TintVectorRefTest, MoveVector_AddConst) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 1> vec_a{&c2a, &c2b};
|
|
VectorRef<const C1*> vec_ref(std::move(vec_a)); // Move
|
|
EXPECT_EQ(vec_ref[0], &c2a);
|
|
EXPECT_EQ(vec_ref[1], &c2b);
|
|
Vector<const C1*, 2> vec_b(std::move(vec_ref));
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b)); // Moved, not copied
|
|
}
|
|
|
|
TEST(TintVectorRefTest, MoveVector_UpcastAndAddConst) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 1> vec_a{&c2a, &c2b};
|
|
VectorRef<const C0*> vec_ref(std::move(vec_a)); // Move
|
|
EXPECT_EQ(vec_ref[0], &c2a);
|
|
EXPECT_EQ(vec_ref[1], &c2b);
|
|
Vector<const C0*, 2> vec_b(std::move(vec_ref));
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllExternallyHeld(vec_b)); // Moved, not copied
|
|
}
|
|
|
|
TEST(TintVectorRefTest, Index) {
|
|
Vector<std::string, 2> vec{"one", "two"};
|
|
VectorRef<std::string> vec_ref(vec);
|
|
static_assert(!std::is_const_v<std::remove_reference_t<decltype(vec_ref[0])>>);
|
|
EXPECT_EQ(vec_ref[0], "one");
|
|
EXPECT_EQ(vec_ref[1], "two");
|
|
}
|
|
|
|
TEST(TintVectorRefTest, ConstIndex) {
|
|
Vector<std::string, 2> vec{"one", "two"};
|
|
const VectorRef<std::string> vec_ref(vec);
|
|
static_assert(std::is_const_v<std::remove_reference_t<decltype(vec_ref[0])>>);
|
|
EXPECT_EQ(vec_ref[0], "one");
|
|
EXPECT_EQ(vec_ref[1], "two");
|
|
}
|
|
|
|
TEST(TintVectorRefTest, Length) {
|
|
Vector<std::string, 2> vec{"one", "two", "three"};
|
|
VectorRef<std::string> vec_ref(vec);
|
|
EXPECT_EQ(vec_ref.Length(), 3u);
|
|
}
|
|
|
|
TEST(TintVectorRefTest, Capacity) {
|
|
Vector<std::string, 5> vec{"one", "two", "three"};
|
|
VectorRef<std::string> vec_ref(vec);
|
|
EXPECT_EQ(vec_ref.Capacity(), 5u);
|
|
}
|
|
|
|
TEST(TintVectorRefTest, IsEmpty) {
|
|
Vector<std::string, 1> vec;
|
|
VectorRef<std::string> vec_ref(vec);
|
|
EXPECT_TRUE(vec_ref.IsEmpty());
|
|
vec.Push("one");
|
|
EXPECT_FALSE(vec_ref.IsEmpty());
|
|
vec.Pop();
|
|
EXPECT_TRUE(vec_ref.IsEmpty());
|
|
}
|
|
|
|
TEST(TintVectorRefTest, FrontBack) {
|
|
Vector<std::string, 3> vec{"front", "mid", "back"};
|
|
VectorRef<std::string> vec_ref(vec);
|
|
static_assert(!std::is_const_v<std::remove_reference_t<decltype(vec_ref.Front())>>);
|
|
static_assert(!std::is_const_v<std::remove_reference_t<decltype(vec_ref.Back())>>);
|
|
EXPECT_EQ(vec_ref.Front(), "front");
|
|
EXPECT_EQ(vec_ref.Back(), "back");
|
|
}
|
|
|
|
TEST(TintVectorRefTest, ConstFrontBack) {
|
|
Vector<std::string, 3> vec{"front", "mid", "back"};
|
|
const VectorRef<std::string> vec_ref(vec);
|
|
static_assert(std::is_const_v<std::remove_reference_t<decltype(vec_ref.Front())>>);
|
|
static_assert(std::is_const_v<std::remove_reference_t<decltype(vec_ref.Back())>>);
|
|
EXPECT_EQ(vec_ref.Front(), "front");
|
|
EXPECT_EQ(vec_ref.Back(), "back");
|
|
}
|
|
|
|
TEST(TintVectorRefTest, BeginEnd) {
|
|
Vector<std::string, 3> vec{"front", "mid", "back"};
|
|
VectorRef<std::string> vec_ref(vec);
|
|
static_assert(!std::is_const_v<std::remove_reference_t<decltype(*vec_ref.begin())>>);
|
|
static_assert(!std::is_const_v<std::remove_reference_t<decltype(*vec_ref.end())>>);
|
|
EXPECT_EQ(vec_ref.begin(), &vec[0]);
|
|
EXPECT_EQ(vec_ref.end(), &vec[0] + 3);
|
|
}
|
|
|
|
TEST(TintVectorRefTest, ConstBeginEnd) {
|
|
Vector<std::string, 3> vec{"front", "mid", "back"};
|
|
const VectorRef<std::string> vec_ref(vec);
|
|
static_assert(std::is_const_v<std::remove_reference_t<decltype(*vec_ref.begin())>>);
|
|
static_assert(std::is_const_v<std::remove_reference_t<decltype(*vec_ref.end())>>);
|
|
EXPECT_EQ(vec_ref.begin(), &vec[0]);
|
|
EXPECT_EQ(vec_ref.end(), &vec[0] + 3);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// TintVectorConstRefTest
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
TEST(TintVectorConstRefTest, CopyVectorConstRef) {
|
|
Vector<std::string, 1> vec_a{"one", "two"};
|
|
ConstVectorRef<std::string> vec_ref_a(vec_a);
|
|
ConstVectorRef<std::string> vec_ref_b(vec_ref_a);
|
|
Vector<std::string, 2> vec_b(vec_ref_b);
|
|
EXPECT_EQ(vec_b[0], "one");
|
|
EXPECT_EQ(vec_b[1], "two");
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorConstRefTest, CopyVectorConstRef_Upcast) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 1> vec_a{&c2a, &c2b};
|
|
ConstVectorRef<C1*> vec_ref_a(vec_a);
|
|
ConstVectorRef<C0*> vec_ref_b(vec_ref_a); // Up-cast
|
|
Vector<C0*, 2> vec_b(vec_ref_b);
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorConstRefTest, CopyVectorConstRef_AddConst) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 1> vec_a{&c2a, &c2b};
|
|
ConstVectorRef<C1*> vec_ref_a(vec_a);
|
|
ConstVectorRef<const C1*> vec_ref_b(vec_ref_a); // Up-cast
|
|
Vector<const C1*, 2> vec_b(vec_ref_b);
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorConstRefTest, CopyVectorConstRef_UpcastAndAddConst) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 1> vec_a{&c2a, &c2b};
|
|
ConstVectorRef<C1*> vec_ref_a(vec_a);
|
|
ConstVectorRef<const C0*> vec_ref_b(vec_ref_a); // Up-cast
|
|
Vector<const C0*, 2> vec_b(vec_ref_b);
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorConstRefTest, CopyVector) {
|
|
Vector<std::string, 1> vec_a{"one", "two"};
|
|
ConstVectorRef<std::string> vec_ref(vec_a);
|
|
Vector<std::string, 2> vec_b(vec_ref);
|
|
EXPECT_EQ(vec_b[0], "one");
|
|
EXPECT_EQ(vec_b[1], "two");
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorConstRefTest, CopyVector_Upcast) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 1> vec_a{&c2a, &c2b};
|
|
ConstVectorRef<C0*> vec_ref(vec_a);
|
|
EXPECT_EQ(vec_ref[0], &c2a);
|
|
EXPECT_EQ(vec_ref[1], &c2b);
|
|
Vector<C0*, 2> vec_b(vec_ref);
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorConstRefTest, CopyVector_AddConst) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 1> vec_a{&c2a, &c2b};
|
|
ConstVectorRef<const C1*> vec_ref(vec_a);
|
|
EXPECT_EQ(vec_ref[0], &c2a);
|
|
EXPECT_EQ(vec_ref[1], &c2b);
|
|
Vector<const C1*, 2> vec_b(vec_ref);
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorConstRefTest, CopyVectorRef_Upcast) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 1> vec_a{&c2a, &c2b};
|
|
VectorRef<C1*> vec_ref_a(vec_a);
|
|
ConstVectorRef<C0*> vec_ref_b(vec_ref_a);
|
|
EXPECT_EQ(vec_ref_b[0], &c2a);
|
|
EXPECT_EQ(vec_ref_b[1], &c2b);
|
|
Vector<C0*, 2> vec_b(vec_ref_b);
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorConstRefTest, CopyVectorRef_AddConst) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 1> vec_a{&c2a, &c2b};
|
|
VectorRef<C1*> vec_ref_a(vec_a);
|
|
ConstVectorRef<const C1*> vec_ref_b(vec_ref_a);
|
|
EXPECT_EQ(vec_ref_b[0], &c2a);
|
|
EXPECT_EQ(vec_ref_b[1], &c2b);
|
|
Vector<const C1*, 2> vec_b(vec_ref_b);
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorConstRefTest, CopyVectorRef_UpcastAndAddConst) {
|
|
C2a c2a;
|
|
C2b c2b;
|
|
Vector<C1*, 1> vec_a{&c2a, &c2b};
|
|
VectorRef<C1*> vec_ref_a(vec_a);
|
|
ConstVectorRef<const C0*> vec_ref_b(vec_ref_a);
|
|
EXPECT_EQ(vec_ref_b[0], &c2a);
|
|
EXPECT_EQ(vec_ref_b[1], &c2b);
|
|
Vector<const C0*, 2> vec_b(vec_ref_b);
|
|
EXPECT_EQ(vec_b[0], &c2a);
|
|
EXPECT_EQ(vec_b[1], &c2b);
|
|
EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
|
|
}
|
|
|
|
TEST(TintVectorConstRefTest, Index) {
|
|
Vector<std::string, 2> vec{"one", "two"};
|
|
ConstVectorRef<std::string> vec_ref(vec);
|
|
static_assert(std::is_const_v<std::remove_reference_t<decltype(vec_ref[0])>>);
|
|
EXPECT_EQ(vec_ref[0], "one");
|
|
EXPECT_EQ(vec_ref[1], "two");
|
|
}
|
|
|
|
TEST(TintVectorConstRefTest, ConstIndex) {
|
|
Vector<std::string, 2> vec{"one", "two"};
|
|
const ConstVectorRef<std::string> vec_ref(vec);
|
|
static_assert(std::is_const_v<std::remove_reference_t<decltype(vec_ref[0])>>);
|
|
EXPECT_EQ(vec_ref[0], "one");
|
|
EXPECT_EQ(vec_ref[1], "two");
|
|
}
|
|
|
|
TEST(TintVectorConstRefTest, Length) {
|
|
Vector<std::string, 2> vec{"one", "two", "three"};
|
|
ConstVectorRef<std::string> vec_ref(vec);
|
|
EXPECT_EQ(vec_ref.Length(), 3u);
|
|
}
|
|
|
|
TEST(TintVectorConstRefTest, Capacity) {
|
|
Vector<std::string, 5> vec{"one", "two", "three"};
|
|
ConstVectorRef<std::string> vec_ref(vec);
|
|
EXPECT_EQ(vec_ref.Capacity(), 5u);
|
|
}
|
|
|
|
TEST(TintVectorConstRefTest, IsEmpty) {
|
|
Vector<std::string, 1> vec;
|
|
ConstVectorRef<std::string> vec_ref(vec);
|
|
EXPECT_TRUE(vec_ref.IsEmpty());
|
|
vec.Push("one");
|
|
EXPECT_FALSE(vec_ref.IsEmpty());
|
|
vec.Pop();
|
|
EXPECT_TRUE(vec_ref.IsEmpty());
|
|
}
|
|
|
|
TEST(TintVectorConstRefTest, FrontBack) {
|
|
Vector<std::string, 3> vec{"front", "mid", "back"};
|
|
ConstVectorRef<std::string> vec_ref(vec);
|
|
static_assert(std::is_const_v<std::remove_reference_t<decltype(vec_ref.Front())>>);
|
|
static_assert(std::is_const_v<std::remove_reference_t<decltype(vec_ref.Back())>>);
|
|
EXPECT_EQ(vec_ref.Front(), "front");
|
|
EXPECT_EQ(vec_ref.Back(), "back");
|
|
}
|
|
|
|
TEST(TintVectorConstRefTest, ConstFrontBack) {
|
|
Vector<std::string, 3> vec{"front", "mid", "back"};
|
|
const ConstVectorRef<std::string> vec_ref(vec);
|
|
static_assert(std::is_const_v<std::remove_reference_t<decltype(vec_ref.Front())>>);
|
|
static_assert(std::is_const_v<std::remove_reference_t<decltype(vec_ref.Back())>>);
|
|
EXPECT_EQ(vec_ref.Front(), "front");
|
|
EXPECT_EQ(vec_ref.Back(), "back");
|
|
}
|
|
|
|
TEST(TintVectorConstRefTest, BeginEnd) {
|
|
Vector<std::string, 3> vec{"front", "mid", "back"};
|
|
ConstVectorRef<std::string> vec_ref(vec);
|
|
static_assert(std::is_const_v<std::remove_reference_t<decltype(*vec_ref.begin())>>);
|
|
static_assert(std::is_const_v<std::remove_reference_t<decltype(*vec_ref.end())>>);
|
|
EXPECT_EQ(vec_ref.begin(), &vec[0]);
|
|
EXPECT_EQ(vec_ref.end(), &vec[0] + 3);
|
|
}
|
|
|
|
TEST(TintVectorConstRefTest, ConstBeginEnd) {
|
|
Vector<std::string, 3> vec{"front", "mid", "back"};
|
|
const ConstVectorRef<std::string> vec_ref(vec);
|
|
static_assert(std::is_const_v<std::remove_reference_t<decltype(*vec_ref.begin())>>);
|
|
static_assert(std::is_const_v<std::remove_reference_t<decltype(*vec_ref.end())>>);
|
|
EXPECT_EQ(vec_ref.begin(), &vec[0]);
|
|
EXPECT_EQ(vec_ref.end(), &vec[0] + 3);
|
|
}
|
|
|
|
} // namespace
|
|
} // namespace tint::utils
|
|
|
|
TINT_INSTANTIATE_TYPEINFO(tint::utils::C0);
|
|
TINT_INSTANTIATE_TYPEINFO(tint::utils::C1);
|
|
TINT_INSTANTIATE_TYPEINFO(tint::utils::C2a);
|
|
TINT_INSTANTIATE_TYPEINFO(tint::utils::C2b);
|