File expected.hpp
File List > include > nebula_common > util > expected.hpp
Go to the documentation of this file
// Copyright 2024 TIER IV, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <exception>
#include <string>
#include <variant>
namespace nebula
{
namespace util
{
struct bad_expected_access : public std::exception
{
explicit bad_expected_access(const std::string & msg) : std::exception(), msg_(msg) {}
const char * what() const noexcept override { return msg_.c_str(); }
private:
const std::string msg_;
};
template <typename T, typename E>
struct expected
{
bool has_value() { return std::holds_alternative<T>(value_); }
T value()
{
if (!has_value()) {
throw bad_expected_access("value() called but containing error");
}
return std::get<T>(value_);
}
T value_or(const T & default_)
{
if (has_value()) return value();
return default_;
}
T value_or_throw(const std::string & error_msg)
{
if (has_value()) return value();
throw std::runtime_error(error_msg);
}
E error()
{
if (has_value()) {
throw bad_expected_access("error() called but containing value");
}
return std::get<E>(value_);
}
E error_or(const E & default_)
{
if (!has_value()) return error();
return default_;
}
expected(const T & value) { value_ = value; } // NOLINT(runtime/explicit)
expected(const E & error) { value_ = error; } // NOLINT(runtime/explicit)
private:
std::variant<T, E> value_;
};
} // namespace util
} // namespace nebula