2014-04-01 02:33:55 +02:00
|
|
|
#pragma once
|
2015-01-12 19:12:06 +01:00
|
|
|
|
2016-04-25 12:49:12 +02:00
|
|
|
#include <cstdarg>
|
2016-04-27 00:27:24 +02:00
|
|
|
#include <exception>
|
2016-05-13 16:01:48 +02:00
|
|
|
#include <string>
|
2016-02-01 22:55:43 +01:00
|
|
|
|
|
|
|
#include "Platform.h"
|
|
|
|
#include "types.h"
|
2014-04-01 02:33:55 +02:00
|
|
|
|
2016-02-01 22:55:43 +01:00
|
|
|
namespace fmt
|
|
|
|
{
|
2016-04-27 00:27:24 +02:00
|
|
|
std::string unsafe_format(const char* fmt...) noexcept;
|
|
|
|
std::string unsafe_vformat(const char*, va_list) noexcept;
|
2014-06-07 16:15:49 +02:00
|
|
|
|
2016-04-27 00:27:24 +02:00
|
|
|
// Formatting function
|
2016-04-25 12:49:12 +02:00
|
|
|
template<typename... Args>
|
2016-05-13 16:01:48 +02:00
|
|
|
inline std::string format(const char* fmt, const Args&... args)
|
2015-01-18 23:54:56 +01:00
|
|
|
{
|
2016-04-27 00:27:24 +02:00
|
|
|
return unsafe_format(fmt, ::unveil<Args>::get(args)...);
|
2016-04-25 12:49:12 +02:00
|
|
|
}
|
2015-01-18 23:54:56 +01:00
|
|
|
|
2016-04-25 12:49:12 +02:00
|
|
|
// Helper class
|
|
|
|
class exception_base : public std::runtime_error
|
2015-01-18 23:54:56 +01:00
|
|
|
{
|
2016-04-25 12:49:12 +02:00
|
|
|
// Helper (there is no other room)
|
|
|
|
va_list m_args;
|
2015-01-18 23:54:56 +01:00
|
|
|
|
2016-04-25 12:49:12 +02:00
|
|
|
protected:
|
|
|
|
// Internal formatting constructor
|
|
|
|
exception_base(const char* fmt...);
|
2015-01-18 23:54:56 +01:00
|
|
|
};
|
|
|
|
|
2016-04-25 12:49:12 +02:00
|
|
|
// Exception type derived from std::runtime_error with formatting constructor
|
|
|
|
class exception : public exception_base
|
2015-01-18 23:54:56 +01:00
|
|
|
{
|
2016-04-25 12:49:12 +02:00
|
|
|
public:
|
|
|
|
template<typename... Args>
|
|
|
|
exception(const char* fmt, const Args&... args)
|
|
|
|
: exception_base(fmt, ::unveil<Args>::get(args)...)
|
2015-01-18 23:54:56 +01:00
|
|
|
{
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-02-01 22:55:43 +01:00
|
|
|
// Narrow cast (similar to gsl::narrow) with exception message formatting
|
|
|
|
template<typename To, typename From, typename... Args>
|
|
|
|
inline auto narrow(const char* format_str, const From& value, const Args&... args) -> decltype(static_cast<To>(static_cast<From>(std::declval<To>())))
|
|
|
|
{
|
|
|
|
const auto result = static_cast<To>(value);
|
2016-04-25 12:49:12 +02:00
|
|
|
if (static_cast<From>(result) != value) throw fmt::exception(format_str, value, args...);
|
2016-02-01 22:55:43 +01:00
|
|
|
return result;
|
|
|
|
}
|
2014-04-01 02:33:55 +02:00
|
|
|
}
|