c3e0ef8c |
#ifndef STR_HPP_
#define STR_HPP_
#include <cerrno>
#include <exception>
#include <functional>
#include <initializer_list>
#include <sstream>
#include <stdexcept>
#include <string>
#include <system_error>
#define STR(VALUE) \
(((std::ostringstream &)(std::ostringstream{} << VALUE)).str())
#define STR_FUNC(VALUE) \
([=]() { return STR(VALUE); })
#define STR_JOIN(JOIN, ITERATOR, VALUE, ...) \
([&]() \
{ \
auto const & str_join_ = JOIN; \
auto str_oss_ = std::ostringstream{}; \
auto str_first_ = true; \
for (auto const & ITERATOR : __VA_ARGS__) \
{ \
auto str_value_ = STR(VALUE); \
if (str_value_.empty()) \
continue; \
if (!str_first_) \
str_oss_ << str_join_; \
str_first_ = false; \
str_oss_ << str_value_; \
} \
return str_oss_.str(); \
}())
#define STR_JOIN_INIT(JOIN, ITERATOR, VALUE, TYPE, ...) \
STR_JOIN(JOIN, ITERATOR, VALUE, std::initializer_list<TYPE>__VA_ARGS__)
#define STR_JOIN_INITSTR(JOIN, ITERATOR, VALUE, ...) \
STR_JOIN_INIT(JOIN, ITERATOR, VALUE, std::string, __VA_ARGS__)
#define STR_CASE(CASE) \
case (CASE): return (#CASE);
#define STR_COND(VALUE, CASE) \
((VALUE) == (CASE)) ? (#CASE) :
#define STR_INIT(CASE) \
{(CASE), (#CASE)},
#define STR_ARGS(ARG) \
ARG, #ARG
#define STR_ARGS_PREFIX(PREFIX, ARG) \
PREFIX##ARG, #ARG
#define STR_HERE(VALUE) \
STR(__FILE__ << ":" << __LINE__ << ":" << __func__ << ": " << VALUE)
#ifndef STR_EXCEPTION
#define STR_EXCEPTION std::runtime_error
#endif
#define STR_THROW(VALUE) \
(throw STR_EXCEPTION{STR(VALUE)})
#define STR_THROW_ERRNO() \
STR_THROW(std::generic_category().message(errno) << ".")
#define STR_RETHROW(VALUE) \
try \
{ \
throw; \
} \
catch (std::exception const & str_exception_) \
{ \
STR_THROW(VALUE << str_exception_.what()); \
}
#define STR_NESTED_THROW(VALUE) \
(std::throw_with_nested(STR_EXCEPTION{STR(VALUE)}))
#define STR_NESTED_THROW_ERRNO() \
STR_NESTED_THROW(std::generic_category().message(errno) << ".")
#define STR_NESTED_WHAT(JOIN, EXCEPTION) \
([&]() \
{ \
auto const & str_join_ = JOIN; \
auto str_oss_ = std::ostringstream{}; \
auto str_first_ = true; \
auto str_what_ = std::function<void(std::exception const &)>{}; \
str_what_ = [&](std::exception const & str_exception_) \
{ \
if (!str_first_) \
str_oss_ << str_join_; \
str_first_ = false; \
str_oss_ << str_exception_.what(); \
try \
{ \
std::rethrow_if_nested(str_exception_); \
} \
catch (std::exception const & str_exception_nested_) \
{ \
str_what_(str_exception_nested_); \
} \
}; \
str_what_(EXCEPTION); \
return str_oss_.str(); \
}())
#endif // STR_HPP_
|