-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathTuple.test.cpp
More file actions
120 lines (97 loc) · 3.05 KB
/
Copy pathTuple.test.cpp
File metadata and controls
120 lines (97 loc) · 3.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include "Tuple.h"
#include "Tuple.ostream.h"
#include "meta19/Index.h"
#include <gtest/gtest.h>
#include <stddef.h> // size_t
#include <utility>
using namespace tuple19;
namespace {
template<typename Type> constexpr size_t alignment(size_t offset = 0, size_t current = 0) {
return current >= offset ? current : alignment<Type>(offset, current + alignof(Type));
}
} // namespace
TEST(Tuple, basic) {
using T = Tuple<char, int, double>;
static_assert(T::has_type<char>);
static_assert(T::has_type<int>);
static_assert(T::has_type<double>);
static_assert(!T::has_type<float>);
static_assert(!T::has_type<bool>);
static_assert(!T::has_type<unsigned int>);
static_assert(T::index_of<char> == 0);
static_assert(T::index_of<int> == 1);
static_assert(T::index_of<double> == 2);
using meta19::_index;
static_assert(std::is_same_v<const char&, decltype(std::declval<T>().at(_index<0>))>);
}
TEST(Tuple, access) {
using meta19::_index;
using meta19::type;
using T = Tuple<char, int, double>;
auto t = T{};
t.amendAt(_index<1>) = 23;
t.amendOf<double>() = 4.2;
EXPECT_EQ((t.of(type<int>)), 23);
EXPECT_EQ((t.at(_index<2>)), 4.2);
}
TEST(Tuple, copy_move) {
using MultiArg = Tuple<char, int, double>;
auto m0 = MultiArg{};
auto m1 = m0; // copy
auto m2 = std::move(m1); // move copy
(void)m2;
// EXPECT_EQ(m0, m2); // uninitialized!
}
TEST(Tuple, construct_empty) {
using T = Tuple<>;
auto t = T{};
t.visitAll([]() {});
}
TEST(Tuple, construct_single) {
using SingleArg = Tuple<int>;
auto s0 = SingleArg{23};
SingleArg s1(s0); // Test that it won't use the argument forward constructor
EXPECT_EQ(s0.at<0>(), s1.at<0>());
EXPECT_EQ(s0, s1);
}
TEST(Tuple, construct_two) {
using TwoArgs = Tuple<int, float>;
auto s0 = TwoArgs{1, 2.3f};
auto s1 = TwoArgs{s0};
EXPECT_EQ(s0.at<0>(), s1.at<0>());
EXPECT_EQ(s0.at<1>(), s1.at<1>());
}
TEST(Tuple, construct_copy) {
using SingleArg = Tuple<int>;
auto v = 23;
auto s0 = SingleArg{v};
SingleArg s1(s0); // Test that it won't use the argument forward constructor
EXPECT_EQ(s0.at<0>(), s1.at<0>());
}
TEST(Tuple, ambigious) {
using Ambiguous = Tuple<char, int, int>;
auto a0 = Ambiguous{};
auto a1 = Ambiguous::fromArgs('c');
// auto a1b = Ambiguous::fromArgs('c', 23, 32); // not allowed! - arguments are treated out of order!
auto a2 = Ambiguous{'c', 23, 32};
(void)(a0);
(void)(a1);
EXPECT_EQ((a2.at<1>()), 23);
EXPECT_EQ((a2.at<2>()), 32);
}
TEST(Tuple, fromTuple) {
using Small = Tuple<char, int, double>;
using Large = Tuple<int, double, char, float>;
auto s = Small{'c', 23, 4.2};
auto l = Large::fromTuple(s);
EXPECT_EQ((l.of<char>()), 'c');
EXPECT_EQ((l.of<double>()), 4.2);
EXPECT_EQ((l.of<int>()), 23);
EXPECT_EQ((l.of<float>()), 0);
}
TEST(Tuple, ostream) {
auto out = std::stringstream{};
using T = Tuple<char, int, double>;
out << T{'c', 23, 4.2};
EXPECT_EQ(out.str(), "[c; 23; 4.2]");
}