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
#include <optional>
#include <type_traits>
#include <glog/logging.h>
#include "utils/result.hpp"
namespace storage {
static_assert(std::is_same_v<uint8_t, unsigned char>);
enum class Error : uint8_t {
SERIALIZATION_ERROR,
DELETED_OBJECT,
VERTEX_HAS_EDGES,
};
template <typename TValue>
class [[nodiscard]] Result final {
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_;
};
template <class TValue>
using Result = utils::BasicResult<Error, TValue>;
} // 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