libcruft-util/except.hpp
Danny Robson 72bd68e60b except: error::describe shouldn't be noexcept
We can't guarantee noexcept because std::ostream& can be pretty liberal
with exceptions.
2019-02-02 15:35:44 +11:00

65 lines
2.0 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 <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&);
}