LiteFX 0.3.1.2022
Computer Graphics Engine
exceptions.hpp
1#pragma once
2
3#include <stdexcept>
4#include <string>
5#include <optional>
6#include <string>
7#include <type_traits>
8#include <fmt/format.h>
9
10namespace LiteFX {
11
12 using Exception = std::exception;
13
14 template <typename TBase, typename TException>
15 class ExceptionBase : public TBase {
16 private:
17 std::optional<Exception> m_inner;
18
19 public:
20 ExceptionBase(const ExceptionBase&) = delete;
22 virtual ~ExceptionBase() noexcept = default;
23
24 explicit ExceptionBase() noexcept :
25 TBase(fmt::format("{0}", typeid(TException).name())) { }
26 explicit ExceptionBase(Exception&& inner) noexcept :
27 TBase(fmt::format("{0}\r\n\t{1}", typeid(TException).name(), inner.what())), m_inner(std::move(inner)) { }
28 explicit ExceptionBase(std::string_view message) noexcept :
29 TBase(fmt::format("{0}: {1}", typeid(TException).name(), message)) { }
30 explicit ExceptionBase(Exception&& inner, std::string_view message) noexcept :
31 TBase(fmt::format("{0}: {1}\r\n\t{2}", typeid(TException).name(), message, inner.what())), m_inner(std::move(inner)) { }
32
33 template <typename ...TArgs>
34 explicit ExceptionBase(std::string_view format, TArgs&&... args) noexcept :
35 TBase(fmt::format("{0}: {1}", typeid(TException).name(), fmt::format(fmt::runtime(format), std::forward<TArgs>(args)...))) { }
36
37 template <typename ...TArgs>
38 explicit ExceptionBase(Exception&& inner, std::string_view format, TArgs&&... args) noexcept :
39 TBase(fmt::format("{0}: {1}\r\n\t{2}", typeid(TException).name(), fmt::format(fmt::runtime(format), std::forward<TArgs>(args)...), inner.what())) { }
40
41 public:
42 [[nodiscard]]
43 virtual const Exception* innerException() const noexcept {
44 // NOTE: For some reason, initializing an std::optional by moving the exception into it results in a copy that drops the inherited exception. Be aware, that
45 // you only get an std::exception instance here.
46 return m_inner.has_value() ? &m_inner.value() : nullptr;
47 }
48 };
49
50#define DEFINE_EXCEPTION(name, base) class name : public ExceptionBase<base, name> { \
51 public: \
52 using ExceptionBase<base, name>::ExceptionBase; \
53 }
54
55 DEFINE_EXCEPTION(InvalidArgumentException, std::invalid_argument);
56 DEFINE_EXCEPTION(ArgumentOutOfRangeException, std::out_of_range);
57 DEFINE_EXCEPTION(ArgumentNotInitializedException, std::logic_error);
58 DEFINE_EXCEPTION(RuntimeException, std::runtime_error);
59
60};
Definition: exceptions.hpp:15
ExceptionBase(const ExceptionBase &)=delete
ExceptionBase(ExceptionBase &&)=delete
virtual ~ExceptionBase() noexcept=default
Definition: app.hpp:6
std::exception Exception
Definition: exceptions.hpp:12
Definition: app_formatters.hpp:6