#ifndef STR_HPP_ #define STR_HPP_ #include #include #include #include #include #include #include #include #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__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{}; \ 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_