libcruft-util/except.hpp

80 lines
2.2 KiB
C++

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright 2018 Danny Robson <danny@nerdcruft.net>
*/
#pragma once
#include <fmt/core.h>
#include <utility>
#include <iosfwd>
#include <string>
namespace cruft {
/// A base exception class for all cruft libraries.
///
/// There is deliberately no `what` method as it's not always acceptable
/// to store a string that we can return a pointer to. Instead we rely on
/// the `describe` method to output to a std::ostream. The user can wrangle
/// that into a std::string if they need one.
class error {
public:
virtual ~error () = default;
virtual std::ostream& describe (std::ostream&) const = 0;
};
/// A mixin error class that can be used when inheriting from
/// `cruft::error`.
///
/// It accepts a single std::string, saving it so that it can be passed
/// through to a std::ostream later on.
///
/// By setting `BaseT` to a locally useful error class we can still
/// maintain an appropriate exception hierarchy for a given module.
/// eg, pass `foo::error` (which derives eventually from `cruft::error`)
/// in the module `foo`.
///
/// \tparam BaseT The desired base class.
template <typename BaseT>
class string_error : public BaseT {
public:
template <typename... Args>
string_error (std::string const &_message, Args &&...args)
: BaseT (std::forward<Args> (args)...)
, m_message (_message)
{ ; }
std::ostream&
describe (std::ostream &os) const override
{
return os << m_message;
}
private:
std::string m_message;
};
/// Use `error::describe` to render the supplied error object to a
/// std::ostream.
std::ostream&
operator<< (std::ostream &os, error const&);
}
template <>
struct fmt::formatter<cruft::error> {
constexpr format_parse_context::iterator
parse (format_parse_context &ctx)
{
return ctx.begin ();
}
format_context::iterator
format (cruft::error const&, format_context &ctx);
};