diff --git a/either.h b/either.h index c1672111..84f82977 100644 --- a/either.h +++ b/either.h @@ -2,11 +2,14 @@ #ifndef MESSMER_CPP_UTILS_EITHER_H #define MESSMER_CPP_UTILS_EITHER_H +#include + namespace cpputils { template class Either final { public: + //TODO Try allowing construction with any type that std::is_convertible to Left or Right. Either(const Left &left): _side(Side::left) { new(&_left)Left(left); } @@ -19,6 +22,7 @@ namespace cpputils { Either(Right &&right): _side(Side::right) { new(&_right)Right(std::move(right)); } + //TODO Try allowing copy-construction when Left/Right types are std::is_convertible Either(const Either &rhs): _side(rhs._side) { if(_side == Side::left) { new(&_left)Left(rhs._left); @@ -33,19 +37,6 @@ namespace cpputils { new(&_right)Right(std::move(rhs._right)); } } - //TODO Test copy assignment operator - //TODO Copy assignment operator - //TODO Test destruction after copy assignment - - //TODO Test move assignment operator - //TODO Move assignment operator - //TODO Test destruction after move assignment - - //TODO Test operator==/operator!= - //TODO operator==/operator!= - - //TODO Test operator<< - //TODO operator<<(ostream) ~Either() { if (_side == Side::left) { @@ -55,6 +46,17 @@ namespace cpputils { } } + //TODO Test copy assignment operator + //TODO Copy assignment operator + //TODO Test destruction after copy assignment + + //TODO Test move assignment operator + //TODO Move assignment operator + //TODO Test destruction after move assignment + + //TODO Test operator<< + //TODO operator<<(ostream) + bool is_left() const { return _side == Side::left; } @@ -72,7 +74,6 @@ namespace cpputils { return _right; } - //TODO Test const and non-const left()/right() Left &left() { return const_cast(const_cast*>(this)->left()); } @@ -87,6 +88,23 @@ namespace cpputils { enum class Side : unsigned char {left, right} _side; }; + template + bool operator==(const Either &lhs, const Either &rhs) { + if (lhs.is_left() != rhs.is_left()) { + return false; + } + if (lhs.is_left()) { + return lhs.left() == rhs.left(); + } else { + return lhs.right() == rhs.right(); + } + } + + template + bool operator!=(const Either &lhs, const Either &rhs) { + return !operator==(lhs, rhs); + } + //TODO Test make_either<> //TODO make_either<> } diff --git a/test/EitherTest.cpp b/test/EitherTest.cpp index fc4ab7c4..f14ed66d 100644 --- a/test/EitherTest.cpp +++ b/test/EitherTest.cpp @@ -142,6 +142,51 @@ TEST_F(EitherTest, RightCanBeMoved) { EXPECT_EQ(5, val2.right().value); } +TEST_F(EitherTest, LeftEquals) { + Either val1 = string("mystring"); + Either val2 = string("mystring"); + EXPECT_TRUE(val1 == val2); + EXPECT_TRUE(val2 == val1); + EXPECT_FALSE(val1 != val2); + EXPECT_FALSE(val2 != val1); +} + +TEST_F(EitherTest, LeftNotEquals) { + Either val1 = string("mystring"); + Either val2 = string("mystring2"); + EXPECT_TRUE(val1 != val2); + EXPECT_TRUE(val2 != val1); + EXPECT_FALSE(val1 == val2); + EXPECT_FALSE(val2 == val1); +} + +TEST_F(EitherTest, RightEquals) { + Either val1 = string("mystring"); + Either val2 = string("mystring"); + EXPECT_TRUE(val1 == val2); + EXPECT_TRUE(val2 == val1); + EXPECT_FALSE(val1 != val2); + EXPECT_FALSE(val2 != val1); +} + +TEST_F(EitherTest, RightNotEquals) { + Either val1 = string("mystring"); + Either val2 = string("mystring2"); + EXPECT_TRUE(val1 != val2); + EXPECT_TRUE(val2 != val1); + EXPECT_FALSE(val1 == val2); + EXPECT_FALSE(val2 == val1); +} + +TEST_F(EitherTest, LeftNotEqualsRight) { + Either val1 = string("mystring"); + Either val2 = 3; + EXPECT_TRUE(val1 != val2); + EXPECT_TRUE(val2 != val1); + EXPECT_FALSE(val1 == val2); + EXPECT_FALSE(val2 == val1); +} + class DestructorCallback { public: MOCK_CONST_METHOD0(call, void());