Move storage::Result to utils

Summary:
Utils now contain a BasicResult implementation which supports different
types of error. This will make it useful for other parts of the code as
well as during the transition from old to new storage.

Reviewers: mtomic, msantl, mferencevic

Reviewed By: mferencevic

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D2291
This commit is contained in:
Teon Banek 2019-08-08 10:14:31 +02:00
parent 1a20c557b8
commit 5bae9c6457
2 changed files with 102 additions and 71 deletions

View File

@ -1,85 +1,20 @@
#pragma once #pragma once
#include <optional> #include <type_traits>
#include <glog/logging.h> #include "utils/result.hpp"
namespace storage { namespace storage {
static_assert(std::is_same_v<uint8_t, unsigned char>);
enum class Error : uint8_t { enum class Error : uint8_t {
SERIALIZATION_ERROR, SERIALIZATION_ERROR,
DELETED_OBJECT, DELETED_OBJECT,
VERTEX_HAS_EDGES, VERTEX_HAS_EDGES,
}; };
template <typename TValue> template <class TValue>
class [[nodiscard]] Result final { using Result = utils::BasicResult<Error, TValue>;
public:
explicit Result(const TValue &value) : value_(value) {}
explicit Result(TValue &&value) : value_(std::move(value)) {}
explicit Result(const Error &error) : error_(error) {}
bool HasValue() const { return value_.has_value(); }
bool HasError() const { return error_.has_value(); }
TValue &GetValue() & {
CHECK(value_) << "The storage result is an error!";
return *value_;
}
TValue &&GetValue() && {
CHECK(value_) << "The storage result is an error!";
return std::move(*value_);
}
const TValue &GetValue() const & {
CHECK(value_) << "The storage result is an error!";
return *value_;
}
const TValue &&GetValue() const && {
CHECK(value_) << "The storage result is an error!";
return std::move(*value_);
}
TValue &operator*() & {
CHECK(value_) << "The storage result is an error!";
return *value_;
}
TValue &&operator*() && {
CHECK(value_) << "The storage result is an error!";
return std::move(*value_);
}
const TValue &operator*() const & {
CHECK(value_) << "The storage result is an error!";
return *value_;
}
const TValue &&operator*() const && {
CHECK(value_) << "The storage result is an error!";
return std::move(*value_);
}
TValue *operator->() {
CHECK(value_) << "The storage result is an error!";
return &*value_;
}
const TValue *operator->() const {
CHECK(value_) << "The storage result is an error!";
return &*value_;
}
Error GetError() const {
CHECK(error_) << "The storage result is a value!";
return *error_;
}
private:
std::optional<TValue> value_;
std::optional<Error> error_;
};
} // namespace storage } // namespace storage

96
src/utils/result.hpp Normal file
View File

@ -0,0 +1,96 @@
/// @file
#pragma once
#include <optional>
#include <glog/logging.h>
namespace utils {
template <class TError, class TValue>
class [[nodiscard]] BasicResult final {
public:
explicit BasicResult(const TValue &value) : value_(value) {}
explicit BasicResult(TValue &&value) noexcept : value_(std::move(value)) {}
explicit BasicResult(const TError &error) : error_(error) {}
explicit BasicResult(TError &&error) noexcept : error_(std::move(error)) {}
bool HasValue() const { return value_.has_value(); }
bool HasError() const { return error_.has_value(); }
TValue &GetValue() & {
CHECK(value_) << "The storage result is an error!";
return *value_;
}
TValue &&GetValue() && {
CHECK(value_) << "The storage result is an error!";
return std::move(*value_);
}
const TValue &GetValue() const & {
CHECK(value_) << "The storage result is an error!";
return *value_;
}
const TValue &&GetValue() const && {
CHECK(value_) << "The storage result is an error!";
return std::move(*value_);
}
TValue &operator*() & {
CHECK(value_) << "The storage result is an error!";
return *value_;
}
TValue &&operator*() && {
CHECK(value_) << "The storage result is an error!";
return std::move(*value_);
}
const TValue &operator*() const & {
CHECK(value_) << "The storage result is an error!";
return *value_;
}
const TValue &&operator*() const && {
CHECK(value_) << "The storage result is an error!";
return std::move(*value_);
}
TValue *operator->() {
CHECK(value_) << "The storage result is an error!";
return &*value_;
}
const TValue *operator->() const {
CHECK(value_) << "The storage result is an error!";
return &*value_;
}
TError &GetError() & {
CHECK(error_) << "The storage result is a value!";
return *error_;
}
TError &&GetError() && {
CHECK(error_) << "The storage result is a value!";
return std::move(*error_);
}
const TError &GetError() const & {
CHECK(error_) << "The storage result is a value!";
return *error_;
}
const TError &&GetError() const && {
CHECK(error_) << "The storage result is a value!";
return std::move(*error_);
}
private:
std::optional<TValue> value_;
std::optional<TError> error_;
};
} // namespace utils