-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathcached.cpp
More file actions
105 lines (89 loc) · 2.62 KB
/
cached.cpp
File metadata and controls
105 lines (89 loc) · 2.62 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
#include <stdx/cached.hpp>
#include <catch2/catch_test_macros.hpp>
TEST_CASE("construction", "[cached]") {
auto c = stdx::cached{[] { return 42; }};
CHECK(not c);
CHECK(not c.has_value());
}
TEST_CASE("exposed value_type", "[cached]") {
auto c = stdx::cached{[] { return 42; }};
STATIC_REQUIRE(std::is_same_v<typename decltype(c)::value_type, int>);
}
TEST_CASE("cached_value_t", "[cached]") {
auto const c = stdx::cached{[] { return 42; }};
STATIC_REQUIRE(std::is_same_v<stdx::cached_value_t<decltype(c)>, int>);
}
TEST_CASE("automatic population", "[cached]") {
auto c = stdx::cached{[] { return 42; }};
CHECK(c.value() == 42);
CHECK(c.has_value());
}
TEST_CASE("operator*", "[cached]") {
auto c = stdx::cached{[] { return 42; }};
CHECK(*c == 42);
CHECK(c.has_value());
}
namespace {
struct S {
int x{};
};
} // namespace
TEST_CASE("operator->", "[cached]") {
auto c = stdx::cached{[] { return S{42}; }};
CHECK(c->x == 42);
CHECK(c.has_value());
}
TEST_CASE("reset clears value", "[cached]") {
auto c = stdx::cached{[] { return 42; }};
CHECK(*c == 42);
c.reset();
CHECK(not c.has_value());
}
TEST_CASE("refresh immediately repopulates value", "[cached]") {
int count{};
auto c = stdx::cached{[&] {
++count;
return 42;
}};
CHECK(*c == 42);
CHECK(count == 1);
c.refresh();
CHECK(count == 2);
}
TEST_CASE("refresh returns a reference to value", "[cached]") {
auto c = stdx::cached{[] { return 42; }};
STATIC_REQUIRE(std::is_same_v<decltype(c.refresh()), int &>);
CHECK(c.refresh() == 42);
}
namespace {
struct move_only {
constexpr move_only(int i) : value{i} {}
constexpr move_only(move_only &&) = default;
int value{};
};
struct non_movable {
constexpr non_movable(int i) : value{i} {}
constexpr non_movable(non_movable &&) = delete;
int value{};
};
} // namespace
TEST_CASE("move-only value", "[cached]") {
auto c = stdx::cached{[] { return move_only{42}; }};
CHECK(c->value == 42);
}
TEST_CASE("non-movable value", "[cached]") {
auto c = stdx::cached{[] { return non_movable{42}; }};
CHECK(c->value == 42);
}
TEST_CASE("preserving value categories", "[cached]") {
{
auto c = stdx::cached{[] { return 42; }};
STATIC_REQUIRE(std::is_same_v<int const &, decltype(*c)>);
STATIC_REQUIRE(std::is_same_v<int const &&, decltype(*std::move(c))>);
}
{
auto const c = stdx::cached{[] { return 42; }};
STATIC_REQUIRE(std::is_same_v<int const &, decltype(*c)>);
STATIC_REQUIRE(std::is_same_v<int const &&, decltype(*std::move(c))>);
}
}