Some improvements to the nullable interface
This commit is contained in:
parent
248ad447b1
commit
85be7c32a4
@ -95,37 +95,42 @@ namespace cpptrace {
|
|||||||
// use.
|
// use.
|
||||||
template<typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
|
template<typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
|
||||||
struct nullable {
|
struct nullable {
|
||||||
T raw_value;
|
T raw_value = null_value();
|
||||||
nullable& operator=(T value) {
|
constexpr nullable() noexcept = default;
|
||||||
|
constexpr nullable(T value) noexcept : raw_value(value) {}
|
||||||
|
constexpr nullable& operator=(T value) noexcept {
|
||||||
raw_value = value;
|
raw_value = value;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
bool has_value() const noexcept {
|
constexpr bool has_value() const noexcept {
|
||||||
return raw_value != (std::numeric_limits<T>::max)();
|
return raw_value != null_value();
|
||||||
}
|
}
|
||||||
T& value() noexcept {
|
constexpr T& value() noexcept {
|
||||||
return raw_value;
|
return raw_value;
|
||||||
}
|
}
|
||||||
const T& value() const noexcept {
|
constexpr const T& value() const noexcept {
|
||||||
return raw_value;
|
return raw_value;
|
||||||
}
|
}
|
||||||
T value_or(T alternative) const noexcept {
|
constexpr T value_or(T alternative) const noexcept {
|
||||||
return has_value() ? raw_value : alternative;
|
return has_value() ? raw_value : alternative;
|
||||||
}
|
}
|
||||||
void swap(nullable& other) noexcept {
|
constexpr void swap(nullable& other) noexcept {
|
||||||
std::swap(raw_value, other.raw_value);
|
std::swap(raw_value, other.raw_value);
|
||||||
}
|
}
|
||||||
void reset() noexcept {
|
constexpr void reset() noexcept {
|
||||||
raw_value = (std::numeric_limits<T>::max)();
|
raw_value = (std::numeric_limits<T>::max)();
|
||||||
}
|
}
|
||||||
bool operator==(const nullable& other) const noexcept {
|
constexpr bool operator==(const nullable& other) const noexcept {
|
||||||
return raw_value == other.raw_value;
|
return raw_value == other.raw_value;
|
||||||
}
|
}
|
||||||
bool operator!=(const nullable& other) const noexcept {
|
constexpr bool operator!=(const nullable& other) const noexcept {
|
||||||
return raw_value != other.raw_value;
|
return raw_value != other.raw_value;
|
||||||
}
|
}
|
||||||
|
constexpr static T null_value() noexcept {
|
||||||
|
return (std::numeric_limits<T>::max)();
|
||||||
|
}
|
||||||
constexpr static nullable null() noexcept {
|
constexpr static nullable null() noexcept {
|
||||||
return { (std::numeric_limits<T>::max)() };
|
return { null_value() };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -13,20 +13,26 @@ TEST(NullableTest, Basic) {
|
|||||||
nullable<std::uint32_t> a{12};
|
nullable<std::uint32_t> a{12};
|
||||||
EXPECT_EQ(a.value(), 12);
|
EXPECT_EQ(a.value(), 12);
|
||||||
EXPECT_EQ(a.raw_value, 12);
|
EXPECT_EQ(a.raw_value, 12);
|
||||||
// TODO: =
|
nullable<std::uint32_t> b = 20;
|
||||||
|
EXPECT_EQ(b.value(), 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(NullableTest, Null) {
|
TEST(NullableTest, Null) {
|
||||||
auto a = nullable<std::uint32_t>::null();
|
auto a = nullable<std::uint32_t>::null();
|
||||||
EXPECT_FALSE(a.has_value());
|
EXPECT_FALSE(a.has_value());
|
||||||
EXPECT_EQ(a.raw_value, (std::numeric_limits<std::uint32_t>::max)());
|
EXPECT_EQ(a.raw_value, (std::numeric_limits<std::uint32_t>::max)());
|
||||||
// TODO: default construct
|
nullable<std::uint32_t> b;
|
||||||
|
EXPECT_FALSE(b.has_value());
|
||||||
|
EXPECT_EQ(b.raw_value, nullable<std::uint32_t>::null_value());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(NullableTest, Assignment) {
|
TEST(NullableTest, Assignment) {
|
||||||
nullable<std::uint32_t> a;
|
nullable<std::uint32_t> a;
|
||||||
a = 12;
|
a = 12;
|
||||||
EXPECT_EQ(a.value(), 12);
|
EXPECT_EQ(a.value(), 12);
|
||||||
|
nullable<std::uint32_t> b = 20;
|
||||||
|
a = b;
|
||||||
|
EXPECT_EQ(a.value(), 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(NullableTest, Reset) {
|
TEST(NullableTest, Reset) {
|
||||||
@ -49,7 +55,7 @@ TEST(NullableTest, Comparison) {
|
|||||||
|
|
||||||
TEST(NullableTest, Swap) {
|
TEST(NullableTest, Swap) {
|
||||||
auto a = nullable<std::uint32_t>::null();
|
auto a = nullable<std::uint32_t>::null();
|
||||||
nullable<std::uint32_t> b{12};
|
nullable<std::uint32_t> b = 12;
|
||||||
EXPECT_FALSE(a.has_value());
|
EXPECT_FALSE(a.has_value());
|
||||||
EXPECT_EQ(b.value(), 12);
|
EXPECT_EQ(b.value(), 12);
|
||||||
a.swap(b);
|
a.swap(b);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user