#ifndef TOML11_UTILITY_HPP #define TOML11_UTILITY_HPP #include "result.hpp" #include "traits.hpp" #include "version.hpp" #include #include #include #include #include namespace toml { inline namespace TOML11_INLINE_VERSION_NAMESPACE { namespace detail { // to output character in an error message. inline std::string show_char(const int c) { using char_type = unsigned char; if(std::isgraph(c)) { return std::string(1, static_cast(c)); } else { std::array buf; buf.fill('\0'); const auto r = std::snprintf(buf.data(), buf.size(), "0x%02x", c & 0xFF); assert(r == static_cast(buf.size()) - 1); (void) r; // Unused variable warning auto in_hex = std::string(buf.data()); switch(c) { case char_type('\0'): {in_hex += "(NUL)"; break;} case char_type(' ') : {in_hex += "(SPACE)"; break;} case char_type('\n'): {in_hex += "(LINE FEED)"; break;} case char_type('\r'): {in_hex += "(CARRIAGE RETURN)"; break;} case char_type('\t'): {in_hex += "(TAB)"; break;} case char_type('\v'): {in_hex += "(VERTICAL TAB)"; break;} case char_type('\f'): {in_hex += "(FORM FEED)"; break;} case char_type('\x1B'): {in_hex += "(ESCAPE)"; break;} default: break; } return in_hex; } } // --------------------------------------------------------------------------- template void try_reserve_impl(Container& container, std::size_t N, std::true_type) { container.reserve(N); return; } template void try_reserve_impl(Container&, std::size_t, std::false_type) noexcept { return; } template void try_reserve(Container& container, std::size_t N) { try_reserve_impl(container, N, has_reserve_method{}); return; } // --------------------------------------------------------------------------- template result from_string(const std::string& str) { T v; std::istringstream iss(str); iss >> v; if(iss.fail()) { return err(); } return ok(v); } // --------------------------------------------------------------------------- // helper function to avoid std::string(0, 'c') or std::string(iter, iter) template std::string make_string(Iterator first, Iterator last) { if(first == last) {return "";} return std::string(first, last); } inline std::string make_string(std::size_t len, char c) { if(len == 0) {return "";} return std::string(len, c); } // --------------------------------------------------------------------------- template struct string_conv_impl { static_assert(sizeof(Char) == sizeof(char), ""); static_assert(sizeof(Char2) == sizeof(char), ""); static std::basic_string invoke(std::basic_string s) { std::basic_string retval; std::transform(s.begin(), s.end(), std::back_inserter(retval), [](const Char2 c) {return static_cast(c);}); return retval; } template static std::basic_string invoke(const Char2 (&s)[N]) { std::basic_string retval; // "string literal" has null-char at the end. to skip it, we use prev. std::transform(std::begin(s), std::prev(std::end(s)), std::back_inserter(retval), [](const Char2 c) {return static_cast(c);}); return retval; } }; template struct string_conv_impl { static_assert(sizeof(Char) == sizeof(char), ""); static std::basic_string invoke(std::basic_string s) { return s; } template static std::basic_string invoke(const Char (&s)[N]) { return std::basic_string(s); } }; template cxx::enable_if_t::value, S> string_conv(std::basic_string s) { using C = typename S::value_type; using T = typename S::traits_type; using A = typename S::allocator_type; return string_conv_impl::invoke(std::move(s)); } template cxx::enable_if_t::value, S> string_conv(const char (&s)[N]) { using C = typename S::value_type; using T = typename S::traits_type; using A = typename S::allocator_type; using C2 = char; using T2 = std::char_traits; using A2 = std::allocator; return string_conv_impl::template invoke(s); } } // namespace detail } // TOML11_INLINE_VERSION_NAMESPACE } // namespace toml #endif // TOML11_UTILITY_HPP