Unverified Commit daecadce authored by Dennis Jenkins's avatar Dennis Jenkins Committed by GitHub

Merge pull request #589 from muttleyxd/fix-optional

Fix optional
parents 4dc9e3ef 002ec8de
...@@ -106,6 +106,7 @@ public: ...@@ -106,6 +106,7 @@ public:
{ {
if (!other.isEmpty()) { if (!other.isEmpty()) {
::new (data()) T(*other.data()); ::new (data()) T(*other.data());
none_flag = ValueMarker;
} }
else { else {
none_flag = NoneMarker; none_flag = NoneMarker;
...@@ -153,6 +154,7 @@ public: ...@@ -153,6 +154,7 @@ public:
data()->~T(); data()->~T();
} }
::new (data()) T(*other.data()); ::new (data()) T(*other.data());
none_flag = ValueMarker;
} }
else { else {
if (none_flag != NoneMarker) { if (none_flag != NoneMarker) {
...@@ -237,33 +239,36 @@ private: ...@@ -237,33 +239,36 @@ private:
void move_helper(Optional<T> &&other, std::true_type) { void move_helper(Optional<T> &&other, std::true_type) {
::new (data()) T(std::move(*other.data())); ::new (data()) T(std::move(*other.data()));
none_flag = ValueMarker;
} }
void move_helper(Optional<T> &&other, std::false_type) { void move_helper(Optional<T> &&other, std::false_type) {
::new (data()) T(*other.data()); ::new (data()) T(*other.data());
none_flag = ValueMarker;
} }
template<typename U> template<typename U>
void from_some_helper(types::Some<U> some, std::true_type) { void from_some_helper(types::Some<U> some, std::true_type) {
::new (data()) T(std::move(some.val_)); ::new (data()) T(std::move(some.val_));
none_flag = ValueMarker;
} }
template<typename U> template<typename U>
void from_some_helper(types::Some<U> some, std::false_type) { void from_some_helper(types::Some<U> some, std::false_type) {
::new (data()) T(some.val_); ::new (data()) T(some.val_);
none_flag = ValueMarker;
} }
typedef uint8_t none_flag_t; typedef uint8_t none_flag_t;
static constexpr none_flag_t NoneMarker = 1; static constexpr none_flag_t NoneMarker = 1;
static constexpr none_flag_t ValueMarker = 0;
union { uint8_t bytes[sizeof(T)];
uint8_t bytes[sizeof(T)]; none_flag_t none_flag;
none_flag_t none_flag;
};
}; };
#define PistacheCheckSize(Type) \ #define PistacheCheckSize(Type) \
static_assert(sizeof(Optional<Type>) == sizeof(Type), "Size differs") static_assert(sizeof(Optional<Type>) == sizeof(Type) + sizeof(uint8_t), "Size differs")
PistacheCheckSize(uint8_t); PistacheCheckSize(uint8_t);
PistacheCheckSize(uint16_t); PistacheCheckSize(uint16_t);
......
...@@ -33,6 +33,7 @@ pistache_test(mailbox_test) ...@@ -33,6 +33,7 @@ pistache_test(mailbox_test)
pistache_test(stream_test) pistache_test(stream_test)
pistache_test(reactor_test) pistache_test(reactor_test)
pistache_test(threadname_test) pistache_test(threadname_test)
pistache_test(optional_test)
if (PISTACHE_USE_SSL) if (PISTACHE_USE_SSL)
......
#include "gtest/gtest.h"
#include <pistache/optional.h>
using Pistache::Optional;
TEST(optional, constructor) {
Optional<bool> value(Pistache::Some(true));
ASSERT_FALSE(value.isEmpty());
EXPECT_TRUE(value.get());
}
TEST(optional, copy_constructor) {
Optional<bool> value(Pistache::Some(true));
ASSERT_FALSE(value.isEmpty());
EXPECT_TRUE(value.get());
Optional<bool> copy_constructed(value);
ASSERT_FALSE(copy_constructed.isEmpty());
EXPECT_TRUE(copy_constructed.get());
}
TEST(optional, assignment_operator) {
Optional<bool> value;
EXPECT_TRUE(value.isEmpty());
value = Pistache::Some(true);
ASSERT_FALSE(value.isEmpty());
EXPECT_TRUE(value.get());
}
TEST(optional, copy_assignment_operator) {
Optional<bool> value(Pistache::Some(true));
ASSERT_FALSE(value.isEmpty());
Optional<bool> other;
EXPECT_TRUE(other.isEmpty());
other = value;
ASSERT_FALSE(other.isEmpty());
EXPECT_TRUE(other.get());
}
TEST(optional, move_constructor) {
Optional<bool> value(Pistache::Some(true));
ASSERT_FALSE(value.isEmpty());
EXPECT_TRUE(value.get());
Optional<bool> value_from_move(std::move(value));
ASSERT_FALSE(value_from_move.isEmpty());
EXPECT_TRUE(value_from_move.get());
}
TEST(optional, move_assignment_operator) {
Optional<bool> value(Pistache::Some(true));
ASSERT_FALSE(value.isEmpty());
EXPECT_TRUE(value.get());
Optional<bool> move_assigned = std::move(value);
ASSERT_FALSE(move_assigned.isEmpty());
EXPECT_TRUE(move_assigned.get());
}
TEST(optional, constructor_none) {
Optional<bool> value(Pistache::None());
EXPECT_TRUE(value.isEmpty());
}
TEST(optional, copy_constructor_none) {
Optional<bool> value(Pistache::None());
EXPECT_TRUE(value.isEmpty());
Optional<bool> copy_constructed(value);
EXPECT_TRUE(value.isEmpty());
}
TEST(optional, assignment_operator_none) {
Optional<bool> value(Pistache::None());
EXPECT_TRUE(value.isEmpty());
Optional<bool> assigned = Pistache::None();
EXPECT_TRUE(assigned.isEmpty());
}
TEST(optional, move_constructor_none) {
Optional<bool> value(Pistache::None());
EXPECT_TRUE(value.isEmpty());
Optional<bool> move_constructed(std::move(value));
EXPECT_TRUE(move_constructed.isEmpty());
}
TEST(optional, move_assignment_operator_none) {
Optional<bool> value(Pistache::None());
EXPECT_TRUE(value.isEmpty());
Optional<bool> move_assigned(std::move(value));
EXPECT_TRUE(move_assigned.isEmpty());
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment