batteries/exception.hpp
batteries/exception.hpp
Namespaces
Classes
Defines
Macro Documentation
define BATTERIES_EXCEPTION_HPP
| #define BATTERIES_EXCEPTION_HPP()
|
define BATT_THROW_IF_NOT_OK
| #define BATT_THROW_IF_NOT_OK(status_expr)
|
Expands to a statement which throws a batt::StatusException if the passed expression evaluates to a non-ok batt::StatusOr value.
This macro allows additional information to appended to the message of the exception via ostream-style insertion:
| {c++}
int arg = 7;
batt::Status status = something_that_might_fail(arg);
BATT_THROW_IF_NOT_OK(status) << "Turns out it did fail!" << BATT_INSPECT(arg);
|
define BATT_OK_RESULT_OR_THROW
| #define BATT_OK_RESULT_OR_THROW(statusor_expr)
|
Expands to an expression which throws a StatusException if the passed expression evaluates to a non-ok batt::StatusOr value, and otherwise evaluates to the T
value contained within the batt::StatusOr.
Example:
| {c++}
batt::StatusOr<std::string> part1 = get_part1();
batt::StatusOr<std::string> part2 = get_part2();
// This line will throw if either part1 or part2 is not ok; otherwise it concatenates the strings.
//
std::string both_parts = BATT_OK_RESULT_OR_THROW(part1) + BATT_OK_RESULT_OR_THROW(part2);
|
Source code
| //######=###=##=#=#=#=#=#==#==#====#+==#+==============+==+==+==+=+==+=+=+=+=+=+=+
// Copyright 2024 Anthony Paul Astolfi
//
#pragma once
#ifndef BATTERIES_EXCEPTION_HPP
#define BATTERIES_EXCEPTION_HPP
#include <batteries/config.hpp>
//
#include <batteries/hint.hpp>
#include <batteries/status.hpp>
#include <batteries/stream_util.hpp>
#include <sstream>
#include <stdexcept>
#include <string_view>
namespace batt {
class StatusException : public std::runtime_error
{
public:
explicit StatusException(Status status, Optional<std::string_view>&& optional_message = None) noexcept;
//+++++++++++-+-+--+----- --- -- - - - -
Status status() const noexcept;
//+++++++++++-+-+--+----- --- -- - - - -
private:
Status status_;
};
namespace detail {
class ThrowWhenDestroyed
{
public:
explicit ThrowWhenDestroyed() noexcept;
explicit ThrowWhenDestroyed(Status status) noexcept;
ThrowWhenDestroyed(const ThrowWhenDestroyed&) = delete;
ThrowWhenDestroyed& operator=(const ThrowWhenDestroyed&) = delete;
ThrowWhenDestroyed(ThrowWhenDestroyed&& that) noexcept;
ThrowWhenDestroyed& operator=(ThrowWhenDestroyed&& that) noexcept;
~ThrowWhenDestroyed() noexcept(false);
//+++++++++++-+-+--+----- --- -- - - - -
bool has_status() const noexcept;
Status status() const noexcept;
void cancel() noexcept;
std::ostream& message_out() noexcept;
template <typename T>
ThrowWhenDestroyed& operator<<(T&& value) noexcept;
ThrowWhenDestroyed& operator<<(std::ostream& (&fn)(std::ostream&)) noexcept;
//+++++++++++-+-+--+----- --- -- - - - -
private:
Optional<Status> status_;
Optional<std::ostringstream> message_stream_;
};
} //namespace detail
#define BATT_THROW_IF_NOT_OK(status_expr) \
for (auto&& BOOST_PP_CAT(BATTERIES_temp_status_result_, __LINE__) = (status_expr); \
!::batt::is_ok_status(BOOST_PP_CAT(BATTERIES_temp_status_result_, __LINE__));) \
::batt::detail::ThrowWhenDestroyed \
{ \
::batt::to_status(BATT_FORWARD(BOOST_PP_CAT(BATTERIES_temp_status_result_, __LINE__))) \
}
#define BATT_OK_RESULT_OR_THROW(statusor_expr) \
[&](auto&& statusor_value) { \
BATT_THROW_IF_NOT_OK(statusor_value) \
<< "(" << BOOST_PP_STRINGIZE(statusor_expr) << ").ok() == false"; \
return std::move(*BATT_FORWARD(statusor_value)); \
}((statusor_expr))
//#=##=##=#==#=#==#===#+==#+==========+==+=+=+=+=+=++=+++=+++++=-++++=-+++++++++++
namespace detail {
//==#==========+==+=+=++=+++++++++++-+-+--+----- --- -- - - - -
//
template <typename T>
inline ThrowWhenDestroyed& ThrowWhenDestroyed::operator<<(T&& value) noexcept
{
if (this->status_) {
this->message_out() << BATT_FORWARD(value);
}
return *this;
}
} //namespace detail
} //namespace batt
#if BATT_HEADER_ONLY
#include <batteries/exception_impl.hpp>
#endif
#endif // BATTERIES_EXCEPTION_HPP
|
Updated on 31 January 2025 at 21:21:05 UTC