78 lines
2.2 KiB
C++
78 lines
2.2 KiB
C++
//
|
|
// Created by jedi on 06.02.21.
|
|
//
|
|
|
|
#pragma once
|
|
|
|
#if __has_include(<source_location>)
|
|
#include <source_location>
|
|
using std::source_location;
|
|
#elif __has_include(<experimental/source_location>)
|
|
|
|
#include <experimental/source_location>
|
|
|
|
using std::experimental::source_location;
|
|
#else
|
|
#error "<source_location> not found"
|
|
#endif
|
|
|
|
/*
|
|
template<typename ERROR = std::runtime_error>
|
|
inline void
|
|
throw_with_pos(const std::string &message = "", const source_location &location = source_location::current()) {
|
|
std::stringstream ss;
|
|
ss << location.function_name() << " in "
|
|
<< location.file_name() << ':'
|
|
<< location.line() << ' '
|
|
<< message;
|
|
throw ERROR(ss.str());
|
|
}*/
|
|
|
|
#include <type_traits>
|
|
|
|
template<typename...>
|
|
struct is_empty : std::false_type {
|
|
};
|
|
|
|
template<typename T, template<T...> class Z, T... Is>
|
|
struct is_empty<T, Z<Is...>> : std::true_type {
|
|
};
|
|
|
|
template<typename T, template<T...> class Z, T First, T... Rest>
|
|
struct is_empty<T, Z<First, Rest...>> : std::false_type {
|
|
};
|
|
|
|
template<typename...>
|
|
struct Z;
|
|
|
|
|
|
template<typename ERROR = std::runtime_error, typename... T>
|
|
struct throw_with_pos {
|
|
explicit throw_with_pos(std::string_view message = "", T &&... pack,
|
|
source_location loc = source_location::current()) {
|
|
std::stringstream ss;
|
|
ss << loc.function_name() << " in "
|
|
<< loc.file_name() << ':'
|
|
<< loc.line() << ' '
|
|
<< message;
|
|
if(!is_empty<Z<T...>>::value)
|
|
((ss << std::forward<T>(pack)), ...);
|
|
throw ERROR(ss.str());
|
|
}
|
|
explicit throw_with_pos(const source_location& loc, T &&... pack) {
|
|
std::stringstream ss;
|
|
ss << loc.function_name() << " in "
|
|
<< loc.file_name() << ':'
|
|
<< loc.line() << ' ';
|
|
if(!is_empty<Z<T...>>::value)
|
|
((ss << std::forward<T>(pack)), ...);
|
|
throw ERROR(ss.str());
|
|
}
|
|
};
|
|
|
|
template<typename ERROR = std::runtime_error, typename... T>
|
|
throw_with_pos(std::string_view, T &&...m) -> throw_with_pos<ERROR, T...>;
|
|
|
|
template<typename ERROR = std::runtime_error, typename... T>
|
|
throw_with_pos(const source_location&, T &&...m) -> throw_with_pos<ERROR, T...>;
|
|
|