forked from intel/cpp-std-extensions
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfunctional.cpp
More file actions
107 lines (89 loc) · 3.42 KB
/
functional.cpp
File metadata and controls
107 lines (89 loc) · 3.42 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
#include "detail/tuple_types.hpp"
#include <stdx/functional.hpp>
#include <catch2/catch_test_macros.hpp>
#include <type_traits>
#include <utility>
namespace {
template <typename T, typename = void>
constexpr auto detect_is_transparent = false;
template <typename T>
constexpr auto
detect_is_transparent<T, std::void_t<typename T::is_transparent>> = true;
struct S {};
constexpr auto operator+(S) { return 17; }
constexpr auto operator*(S) { return 28; }
} // namespace
TEST_CASE("unary_plus", "[functional]") {
STATIC_REQUIRE(stdx::unary_plus<int>{}(17) == 17);
STATIC_REQUIRE(stdx::unary_plus<>{}(17) == 17);
}
TEST_CASE("unary_plus transparency", "[functional]") {
STATIC_REQUIRE(not detect_is_transparent<stdx::unary_plus<int>>);
STATIC_REQUIRE(detect_is_transparent<stdx::unary_plus<>>);
}
TEST_CASE("unary_plus calls operator+", "[functional]") {
STATIC_REQUIRE(stdx::unary_plus<>{}(S{}) == 17);
}
TEST_CASE("safe_identity returns unchanged argument", "[functional]") {
static_assert(stdx::safe_identity(17) == 17);
static_assert(stdx::safe_identity(move_only{17}).value == 17);
}
TEST_CASE("safe_identity (copy)", "[functional]") {
counter::reset();
counter c0{};
[[maybe_unused]] auto c1 = stdx::safe_identity(c0);
CHECK(counter::copies == 1);
}
TEST_CASE("safe_identity (move)", "[functional]") {
counter::reset();
counter c0{};
[[maybe_unused]] auto c1 = stdx::safe_identity(std::move(c0));
CHECK(counter::copies == 0);
CHECK(counter::moves == 1);
}
TEST_CASE("safe_identity transparency", "[functional]") {
STATIC_REQUIRE(detect_is_transparent<stdx::safe_identity_t>);
}
namespace {
template <typename T> auto declval() -> T;
}
TEST_CASE("safe_identity value categories", "[functional]") {
static_assert(
std::is_same_v<decltype(stdx::safe_identity(declval<int>())), int>);
static_assert(
std::is_same_v<decltype(stdx::safe_identity(declval<int &>())), int &>);
static_assert(
std::is_same_v<decltype(stdx::safe_identity(declval<int &&>())), int>);
}
TEST_CASE("safe_identity cvref categories", "[functional]") {
static_assert(
std::is_same_v<decltype(stdx::safe_identity(declval<int const &>())),
int const &>);
static_assert(
std::is_same_v<decltype(stdx::safe_identity(declval<int volatile &>())),
int volatile &>);
static_assert(std::is_same_v<decltype(stdx::safe_identity(
declval<int const volatile &>())),
int const volatile &>);
static_assert(
std::is_same_v<decltype(stdx::safe_identity(declval<int const &&>())),
int>);
static_assert(
std::is_same_v<
decltype(stdx::safe_identity(declval<int volatile &&>())), int>);
static_assert(std::is_same_v<decltype(stdx::safe_identity(
declval<int const volatile &&>())),
int>);
}
TEST_CASE("dereference", "[functional]") {
int x{28};
CHECK(stdx::dereference<int *>{}(&x) == 28);
CHECK(stdx::dereference<>{}(&x) == 28);
}
TEST_CASE("dereference transparency", "[functional]") {
STATIC_REQUIRE(not detect_is_transparent<stdx::dereference<int *>>);
STATIC_REQUIRE(detect_is_transparent<stdx::dereference<>>);
}
TEST_CASE("dereference calls operator*", "[functional]") {
STATIC_REQUIRE(stdx::dereference<>{}(S{}) == 28);
}