Skip to content

Commit

Permalink
Merge branch 'feature/polymorphic_result' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
nickaleks authored and lebdron committed Feb 12, 2018
2 parents 431793e + a302b14 commit ec11bf5
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 5 deletions.
19 changes: 19 additions & 0 deletions libs/common/result.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,25 @@ namespace iroha {
[&f](const Value<T> &v) { return f(v.value); },
[](const Error<E> &e) { return return_type(makeError(e.error)); });
}

/**
* Polymorphic Result is simple alias for result type, which can be used to
* work with polymorphic objects. It is achieved by wrapping V and E in a
* polymorphic container (std::shared_ptr is used by default). This
* simplifies declaration of polymorphic result.
*
* Note: ordinary result itself stores both V and E directly inside itself
* (on the stack), polymorphic result stores objects wherever VContainer and
* EContainer store them, but since you need polymorphic behavior, it will
* probably be on the heap. That is why polymorphic result is generally
* slower, and should be used ONLY when polymorphic behaviour is required,
* hence the name. For all other use cases, stick to basic Result
*/
template <typename V,
typename E,
typename VContainer = std::shared_ptr<V>,
typename EContainer = std::shared_ptr<E>>
using PolymorphicResult = Result<VContainer, EContainer>;
} // namespace expected
} // namespace iroha
#endif // IROHA_RESULT_HPP
53 changes: 48 additions & 5 deletions test/module/libs/common/result_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,7 @@
#include "common/result.hpp"
#include <gtest/gtest.h>

using iroha::expected::Error;
using iroha::expected::Result;
using iroha::expected::Value;
using iroha::expected::makeError;
using iroha::expected::makeValue;
using namespace iroha::expected;

constexpr auto kErrorCaseMessage = "Unexpected error case";
constexpr auto kValueCaseMessage = "Unexpected value case";
Expand Down Expand Up @@ -161,3 +157,50 @@ TEST(ResultTest, ResultVoidError) {
result.match([](Value<int> v) { ASSERT_EQ(5, v.value); },
makeFailCase<Error<void>>(kErrorCaseMessage));
}

/// Polymorphic result tests

/// Base and Derived are classes, which can be used to test polymorphic behavior
class Base {
public:
virtual int getNumber() {
return 0;
}
};

class Derived : public Base {
public:
virtual int getNumber() override {
return 1;
}
};

/**
* @given Polymorphic Result of Base class type with value of derived class
* @when match function is invoked
* @then Value case is invoked, and polymorphic behavior persists
*/
TEST(PolyMorphicResultTest, PolymorphicValueConstruction) {
PolymorphicResult<Base, std::string> result =
makeValue(std::make_shared<Derived>());
result.match(
[](Value<std::shared_ptr<Base>> &v) {
ASSERT_EQ(1, v.value->getNumber());
},
makeFailCase<Error<std::shared_ptr<std::string>>>(kErrorCaseMessage));
}

/**
* @given Polymorphic Result of Base class type with error
* @when match function is invoked
* @then Error case is invoked
*/
TEST(PolyMorphicResultTest, PolymorphicErrorConstruction) {
PolymorphicResult<Base, std::string> result =
makeError(std::make_shared<std::string>(kErrorMessage));
result.match(
makeFailCase<Value<std::shared_ptr<Base>>>(kValueCaseMessage),
[](Error<std::shared_ptr<std::string>> &e) {
ASSERT_EQ(kErrorMessage, *e.error);
});
}

0 comments on commit ec11bf5

Please sign in to comment.