From 006d8b541a318665a2c8b6cee92ff8358e521f22 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Fri, 1 Dec 2017 14:59:48 +0000 Subject: [PATCH] Remove unused either class --- src/cpp-utils/either.h | 218 ------------ test/cpp-utils/EitherIncludeTest.cpp | 3 - test/cpp-utils/EitherTest.cpp | 505 --------------------------- 3 files changed, 726 deletions(-) delete mode 100644 src/cpp-utils/either.h delete mode 100644 test/cpp-utils/EitherIncludeTest.cpp delete mode 100644 test/cpp-utils/EitherTest.cpp diff --git a/src/cpp-utils/either.h b/src/cpp-utils/either.h deleted file mode 100644 index 23da49d4..00000000 --- a/src/cpp-utils/either.h +++ /dev/null @@ -1,218 +0,0 @@ -#pragma once -#ifndef MESSMER_CPPUTILS_EITHER_H -#define MESSMER_CPPUTILS_EITHER_H - -#include -#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) { - _construct_left(left); - } - either(Left &&left): _side(Side::left) { - _construct_left(std::move(left)); - } - either(const Right &right): _side(Side::right) { - _construct_right(right); - } - either(Right &&right): _side(Side::right) { - _construct_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) { - _construct_left(rhs._left); - } else { - _construct_right(rhs._right); - } - } - either(either &&rhs): _side(rhs._side) { - if(_side == Side::left) { - _construct_left(std::move(rhs._left)); - } else { - _construct_right(std::move(rhs._right)); - } - } - - ~either() { - _destruct(); - } - - //TODO Try allowing copy-assignment when Left/Right types are std::is_convertible - either &operator=(const either &rhs) { - _destruct(); - _side = rhs._side; - if (_side == Side::left) { - _construct_left(rhs._left); - } else { - _construct_right(rhs._right); - } - return *this; - } - - either &operator=(either &&rhs) { - _destruct(); - _side = rhs._side; - if (_side == Side::left) { - _construct_left(std::move(rhs._left)); - } else { - _construct_right(std::move(rhs._right)); - } - return *this; - } - - //TODO fold, map_left, map_right, left_or_else(val), right_or_else(val), left_or_else(func), right_or_else(func) - - bool is_left() const { - return _side == Side::left; - } - - bool is_right() const { - return _side == Side::right; - } - - const Left &left() const& { - return _left; - } - Left &left() & { - return const_cast(const_cast*>(this)->left()); - } - Left &&left() && { - return std::move(left()); - } - - const Right &right() const& { - return _right; - } - Right &right() & { - return const_cast(const_cast*>(this)->right()); - } - Right &&right() && { - return std::move(right()); - } - - boost::optional left_opt() const& { - if (_side == Side::left) { - return _left; - } else { - return boost::none; - } - } - boost::optional left_opt() & { - if (_side == Side::left) { - return _left; - } else { - return boost::none; - } - } - boost::optional left_opt() && { - if (_side == Side::left) { - return std::move(_left); - } else { - return boost::none; - } - } - - boost::optional right_opt() const& { - if (_side == Side::right) { - return _right; - } else { - return boost::none; - } - } - boost::optional right_opt() & { - if (_side == Side::right) { - return _right; - } else { - return boost::none; - } - } - boost::optional right_opt() && { - if (_side == Side::right) { - return std::move(_right); - } else { - return boost::none; - } - } - - private: - union { - Left _left; - Right _right; - }; - enum class Side : unsigned char {left, right} _side; - - either(Side side): _side(side) {} - - template - void _construct_left(Args&&... args) { - new(&_left)Left(std::forward(args)...); - } - template - void _construct_right(Args&&... args) { - new(&_right)Right(std::forward(args)...); - } - void _destruct() { - if (_side == Side::left) { - _left.~Left(); - } else { - _right.~Right(); - } - } - - template - friend either make_left(Args&&... args); - - template - friend either make_right(Args&&... args); - }; - - 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); - } - - template - std::ostream &operator<<(std::ostream &stream, const either &value) { - if (value.is_left()) { - stream << "Left(" << value.left() << ")"; - } else { - stream << "Right(" << value.right() << ")"; - } - return stream; - } - - template - either make_left(Args&&... args) { - either result(either::Side::left); - result._construct_left(std::forward(args)...); - return result; - } - - template - either make_right(Args&&... args) { - either result(either::Side::right); - result._construct_right(std::forward(args)...); - return result; - } -} - - -#endif diff --git a/test/cpp-utils/EitherIncludeTest.cpp b/test/cpp-utils/EitherIncludeTest.cpp deleted file mode 100644 index 5d3dd7b0..00000000 --- a/test/cpp-utils/EitherIncludeTest.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "cpp-utils/either.h" - -//Test that either can be included without needing additional dependencies diff --git a/test/cpp-utils/EitherTest.cpp b/test/cpp-utils/EitherTest.cpp deleted file mode 100644 index e5555318..00000000 --- a/test/cpp-utils/EitherTest.cpp +++ /dev/null @@ -1,505 +0,0 @@ -#include -#include -#include -#include "cpp-utils/either.h" -#include "cpp-utils/macros.h" -#include - -//TODO Go through all test cases and think about whether it makes sense to add the same test case but with primitive types. - -using std::ostringstream; -using std::string; -using std::vector; -using std::pair; -using std::make_pair; -using namespace cpputils; -using ::testing::Test; - -class OnlyMoveable { -public: - OnlyMoveable(int value_): value(value_) {} - OnlyMoveable(OnlyMoveable &&source): value(source.value) {source.value = -1;} - bool operator==(const OnlyMoveable &rhs) const { - return value == rhs.value; - } - int value; -private: - DISALLOW_COPY_AND_ASSIGN(OnlyMoveable); -}; - -template -struct StoreWith1ByteFlag { - T val; - char flag; -}; - -class EitherTest: public Test { -public: - template - void EXPECT_IS_LEFT(const either &val) { - EXPECT_TRUE(val.is_left()); - EXPECT_FALSE(val.is_right()); - } - template - void EXPECT_IS_RIGHT(const either &val) { - EXPECT_FALSE(val.is_left()); - EXPECT_TRUE(val.is_right()); - } - template - void EXPECT_LEFT_IS(const Expected &expected, either &value) { - EXPECT_IS_LEFT(value); - EXPECT_EQ(expected, value.left()); - EXPECT_EQ(expected, value.left_opt().get()); - EXPECT_EQ(boost::none, value.right_opt()); - const either &const_value = value; - EXPECT_EQ(expected, const_value.left()); - EXPECT_EQ(expected, const_value.left_opt().get()); - EXPECT_EQ(boost::none, const_value.right_opt()); - } - template - void EXPECT_RIGHT_IS(const Expected &expected, either &value) { - EXPECT_IS_RIGHT(value); - EXPECT_EQ(expected, value.right()); - EXPECT_EQ(expected, value.right_opt().get()); - EXPECT_EQ(boost::none, value.left_opt()); - const either &const_value = value; - EXPECT_EQ(expected, const_value.right()); - EXPECT_EQ(expected, const_value.right_opt().get()); - EXPECT_EQ(boost::none, const_value.left_opt()); - } -}; - -template -void TestSpaceUsage() { - EXPECT_EQ(std::max(sizeof(StoreWith1ByteFlag), sizeof(StoreWith1ByteFlag)), sizeof(either)); -} - -TEST_F(EitherTest, SpaceUsage) { - TestSpaceUsage(); - TestSpaceUsage(); - TestSpaceUsage(); - TestSpaceUsage(); - TestSpaceUsage>(); -} - -TEST_F(EitherTest, LeftCanBeConstructed) { - either val = 3; - UNUSED(val); -} - -TEST_F(EitherTest, RightCanBeConstructed) { - either val = string("string"); - UNUSED(val); -} - -TEST_F(EitherTest, IsLeft) { - either val = 3; - EXPECT_IS_LEFT(val); -} - -TEST_F(EitherTest, IsRight) { - either val = string("string"); - EXPECT_IS_RIGHT(val); -} - -TEST_F(EitherTest, LeftIsStored) { - either val = 3; - EXPECT_LEFT_IS(3, val); -} - -TEST_F(EitherTest, RightIsStored) { - either val = string("string"); - EXPECT_RIGHT_IS("string", val); -} - -TEST_F(EitherTest, LeftCanBeMoveContructed) { - either val = OnlyMoveable(1); - UNUSED(val); -} - -TEST_F(EitherTest, RightCanBeMoveContructed) { - either val = OnlyMoveable(1); - UNUSED(val); -} - -TEST_F(EitherTest, IsLeftWhenMoveContructed) { - either val = OnlyMoveable(1); - EXPECT_IS_LEFT(val); -} - -TEST_F(EitherTest, IsRightWhenMoveContructed) { - either val = OnlyMoveable(1); - EXPECT_IS_RIGHT(val); -} - -TEST_F(EitherTest, LeftIsStoredWhenMoveContructed) { - either val = OnlyMoveable(2); - EXPECT_LEFT_IS(OnlyMoveable(2), val); -} - -TEST_F(EitherTest, RightIsStoredWhenMoveContructed) { - either val = OnlyMoveable(3); - EXPECT_RIGHT_IS(OnlyMoveable(3), val); -} - -TEST_F(EitherTest, LeftCanBeCopied) { - either val = string("string"); - either val2 = val; - EXPECT_LEFT_IS("string", val2); -} - -TEST_F(EitherTest, CopyingLeftDoesntChangeSource) { - either val = string("string"); - either val2 = val; - EXPECT_LEFT_IS("string", val); -} - -TEST_F(EitherTest, RightCanBeCopied) { - either val = string("string"); - either val2 = val; - EXPECT_RIGHT_IS("string", val2); -} - -TEST_F(EitherTest, CopyingRightDoesntChangeSource) { - either val = string("string"); - either val2 = val; - EXPECT_RIGHT_IS("string", val); -} - -TEST_F(EitherTest, LeftCanBeMoved) { - either val = OnlyMoveable(5); - either val2 = std::move(val); - EXPECT_LEFT_IS(OnlyMoveable(5), val2); -} - -TEST_F(EitherTest, RightCanBeMoved) { - either val = OnlyMoveable(5); - either val2 = std::move(val); - EXPECT_RIGHT_IS(OnlyMoveable(5), val2); -} - -TEST_F(EitherTest, LeftCanBeAssigned) { - either val = string("string"); - either val2 = string("otherstring"); - val2 = val; - EXPECT_LEFT_IS("string", val2); -} - -TEST_F(EitherTest, RightCanBeAssigned) { - either val = string("string"); - either val2 = string("otherstring"); - val2 = val; - EXPECT_RIGHT_IS("string", val2); -} - -TEST_F(EitherTest, LeftCanBeMoveAssigned) { - either val = OnlyMoveable(3); - either val2 = OnlyMoveable(4); - val2 = std::move(val); - EXPECT_LEFT_IS(OnlyMoveable(3), val2); -} - -TEST_F(EitherTest, RightCanBeMoveAssigned) { - either val = OnlyMoveable(3); - either val2 = OnlyMoveable(4); - val2 = std::move(val); - EXPECT_RIGHT_IS(OnlyMoveable(3), val2); -} - -TEST_F(EitherTest, LeftCanBeDirectlyAssigned) { - either val = string("string"); - val = string("otherstring"); - EXPECT_LEFT_IS("otherstring", val); -} - -TEST_F(EitherTest, RightCanBeDirectlyAssigned) { - either val = string("string"); - val = string("otherstring"); - EXPECT_RIGHT_IS("otherstring", val); -} - -TEST_F(EitherTest, LeftCanBeDirectlyMoveAssigned) { - either val = OnlyMoveable(3); - val = OnlyMoveable(5); - EXPECT_LEFT_IS(OnlyMoveable(5), val); -} - -TEST_F(EitherTest, RightCanBeDirectlyMoveAssigned) { - either val = OnlyMoveable(3); - val = OnlyMoveable(5); - EXPECT_RIGHT_IS(OnlyMoveable(5), val); -} - -TEST_F(EitherTest, ModifyLeft) { - either val = string("mystring1"); - val.left() = "mystring2"; - EXPECT_LEFT_IS("mystring2", val); -} - -TEST_F(EitherTest, ModifyRight) { - either val = string("mystring1"); - val.right() = "mystring2"; - EXPECT_RIGHT_IS("mystring2", val); -} - -TEST_F(EitherTest, ModifyLeftOpt) { - either val = string("mystring1"); - val.left_opt().get() = "mystring2"; - EXPECT_LEFT_IS("mystring2", val); -} - -TEST_F(EitherTest, ModifyRightOpt) { - either val = string("mystring1"); - val.right_opt().get() = "mystring2"; - EXPECT_RIGHT_IS("mystring2", val); -} - -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); -} - -TEST_F(EitherTest, OutputLeft) { - ostringstream str; - str << either("mystring"); - EXPECT_EQ("Left(mystring)", str.str()); -} - -TEST_F(EitherTest, OutputRight) { - ostringstream str; - str << either("mystring"); - EXPECT_EQ("Right(mystring)", str.str()); -} - -TEST_F(EitherTest, MakeLeft) { - either var = make_left("mystring"); - EXPECT_LEFT_IS("mystring", var); -} - -TEST_F(EitherTest, MakeLeft_OnlyMoveable) { - either var = make_left(4); - EXPECT_LEFT_IS(OnlyMoveable(4), var); -} - -TEST_F(EitherTest, MakeLeft_MultiParam) { - either, int> var = make_left, int>(4, 5); - EXPECT_LEFT_IS(make_pair(4,5), var); -} - -TEST_F(EitherTest, MakeRight) { - either var = make_right("mystring"); - EXPECT_RIGHT_IS("mystring", var); -} - -TEST_F(EitherTest, MakeRight_OnlyMoveable) { - either var = make_right(4); - EXPECT_RIGHT_IS(OnlyMoveable(4), var); -} - -TEST_F(EitherTest, MakeRight_MultiParam) { - either> var = make_right>(4, 5); - EXPECT_RIGHT_IS(make_pair(4,5), var); -} - -TEST_F(EitherTest, LeftCanBeQueriedAsRvalue) { - OnlyMoveable val = make_left(3).left(); - EXPECT_EQ(OnlyMoveable(3), val); -} - -TEST_F(EitherTest, RightCanBeQueriedAsRvalue) { - OnlyMoveable val = make_right(3).right(); - EXPECT_EQ(OnlyMoveable(3), val); -} - -TEST_F(EitherTest, LeftOptCanBeQueriedAsRvalue) { - OnlyMoveable val = make_left(3).left_opt().value(); - EXPECT_EQ(OnlyMoveable(3), val); -} - -TEST_F(EitherTest, RightOptCanBeQueriedAsRvalue) { - OnlyMoveable val = make_right(3).right_opt().value(); - EXPECT_EQ(OnlyMoveable(3), val); -} - -class DestructorCallback { -public: - MOCK_CONST_METHOD0(call, void()); - - void EXPECT_CALLED(int times = 1) { - EXPECT_CALL(*this, call()).Times(times); - } -}; -class ClassWithDestructorCallback { -public: - ClassWithDestructorCallback(const DestructorCallback *destructorCallback) : _destructorCallback(destructorCallback) {} - ClassWithDestructorCallback(const ClassWithDestructorCallback &rhs): _destructorCallback(rhs._destructorCallback) {} - - ~ClassWithDestructorCallback() { - _destructorCallback->call(); - } - -private: - const DestructorCallback *_destructorCallback; - - ClassWithDestructorCallback &operator=(const ClassWithDestructorCallback &rhs) = delete; -}; -class OnlyMoveableClassWithDestructorCallback { -public: - OnlyMoveableClassWithDestructorCallback(const DestructorCallback *destructorCallback) : _destructorCallback(destructorCallback) { } - OnlyMoveableClassWithDestructorCallback(OnlyMoveableClassWithDestructorCallback &&source): _destructorCallback(source._destructorCallback) {} - - ~OnlyMoveableClassWithDestructorCallback() { - _destructorCallback->call(); - } - -private: - DISALLOW_COPY_AND_ASSIGN(OnlyMoveableClassWithDestructorCallback); - const DestructorCallback *_destructorCallback; -}; - -class EitherTest_Destructor: public EitherTest { -}; - -TEST_F(EitherTest_Destructor, LeftDestructorIsCalled) { - DestructorCallback destructorCallback; - destructorCallback.EXPECT_CALLED(2); //Once for the temp object, once when the either class destructs - - ClassWithDestructorCallback temp(&destructorCallback); - either var = temp; -} - -TEST_F(EitherTest_Destructor, RightDestructorIsCalled) { - DestructorCallback destructorCallback; - destructorCallback.EXPECT_CALLED(2); //Once for the temp object, once when the either class destructs - - ClassWithDestructorCallback temp(&destructorCallback); - either var = temp; -} - -TEST_F(EitherTest_Destructor, LeftDestructorIsCalledAfterCopying) { - DestructorCallback destructorCallback; - destructorCallback.EXPECT_CALLED(3); //Once for the temp object, once for var1 and once for var2 - - ClassWithDestructorCallback temp(&destructorCallback); - either var1 = temp; - either var2 = var1; -} - -TEST_F(EitherTest_Destructor, RightDestructorIsCalledAfterCopying) { - DestructorCallback destructorCallback; - destructorCallback.EXPECT_CALLED(3); //Once for the temp object, once for var1 and once for var2 - - ClassWithDestructorCallback temp(&destructorCallback); - either var1 = temp; - either var2 = var1; -} - -TEST_F(EitherTest_Destructor, LeftDestructorIsCalledAfterMoving) { - DestructorCallback destructorCallback; - destructorCallback.EXPECT_CALLED(3); //Once for the temp object, once for var1 and once for var2 - - OnlyMoveableClassWithDestructorCallback temp(&destructorCallback); - either var1 = std::move(temp); - either var2 = std::move(var1); -} - -TEST_F(EitherTest_Destructor, RightDestructorIsCalledAfterMoving) { - DestructorCallback destructorCallback; - destructorCallback.EXPECT_CALLED(3); //Once for the temp object, once for var1 and once for var2 - - OnlyMoveableClassWithDestructorCallback temp(&destructorCallback); - either var1 = std::move(temp); - either var2 = std::move(var1); -} - -TEST_F(EitherTest_Destructor, LeftDestructorIsCalledAfterAssignment) { - DestructorCallback destructorCallback1; - DestructorCallback destructorCallback2; - destructorCallback1.EXPECT_CALLED(2); //Once for the temp1 object, once at the assignment - destructorCallback2.EXPECT_CALLED(3); //Once for the temp2 object, once in destructor of var2, once in destructor of var1 - - ClassWithDestructorCallback temp1(&destructorCallback1); - either var1 = temp1; - ClassWithDestructorCallback temp2(&destructorCallback2); - either var2 = temp2; - var1 = var2; -} - -TEST_F(EitherTest_Destructor, RightDestructorIsCalledAfterAssignment) { - DestructorCallback destructorCallback1; - DestructorCallback destructorCallback2; - destructorCallback1.EXPECT_CALLED(2); //Once for the temp1 object, once at the assignment - destructorCallback2.EXPECT_CALLED(3); //Once for the temp2 object, once in destructor of var2, once in destructor of var1 - - ClassWithDestructorCallback temp1(&destructorCallback1); - either var1 = temp1; - ClassWithDestructorCallback temp2(&destructorCallback2); - either var2 = temp2; - var1 = var2; -} - -TEST_F(EitherTest_Destructor, LeftDestructorIsCalledAfterMoveAssignment) { - DestructorCallback destructorCallback1; - DestructorCallback destructorCallback2; - destructorCallback1.EXPECT_CALLED(2); //Once for the temp1 object, once at the assignment - destructorCallback2.EXPECT_CALLED(3); //Once for the temp2 object, once in destructor of var2, once in destructor of var1 - - OnlyMoveableClassWithDestructorCallback temp1(&destructorCallback1); - either var1 = std::move(temp1); - OnlyMoveableClassWithDestructorCallback temp2(&destructorCallback2); - either var2 = std::move(temp2); - var1 = std::move(var2); -} - -TEST_F(EitherTest_Destructor, RightDestructorIsCalledAfterMoveAssignment) { - DestructorCallback destructorCallback1; - DestructorCallback destructorCallback2; - destructorCallback1.EXPECT_CALLED(2); //Once for the temp1 object, once at the assignment - destructorCallback2.EXPECT_CALLED(3); //Once for the temp2 object, once in destructor of var2, once in destructor of var1 - - OnlyMoveableClassWithDestructorCallback temp1(&destructorCallback1); - either var1 = std::move(temp1); - OnlyMoveableClassWithDestructorCallback temp2(&destructorCallback2); - either var2 = std::move(temp2); - var1 = std::move(var2); -}