diff --git a/toml/format.hpp b/toml/format.hpp index 8d131f6..3bc147e 100644 --- a/toml/format.hpp +++ b/toml/format.hpp @@ -1,16 +1,40 @@ #ifndef TOML11_FORMAT #define TOML11_FORMAT #include "value.hpp" +#include #include +#include +#include namespace toml { +// synopsis +// toml::format("key", value, toml::make_inline(80)) +// toml::format("key", value, toml::forceinline) +// std::cout << toml::make_inline(80) << value; +// std::cout << toml::forceinline << value; + template, typename alloc = std::allocator> std::basic_string format(const value& v); +template, + typename alloc = std::allocator> +std::basic_string +format(const value& v, std::size_t mk); + +template, + typename alloc = std::allocator> +std::basic_string +format(const toml::key& k, const value& v); + +template, + typename alloc = std::allocator> +std::basic_string +format(const toml::key& k, const value& v, std::size_t mk); + template struct format_impl; @@ -115,7 +139,6 @@ template<> struct format_impl } }; - template std::basic_string format(const value& v) @@ -135,10 +158,9 @@ format(const value& v) } } -template, - typename alloc = std::allocator> -std::basic_string -format(std::basic_string&& key, const value& val) +template +std::basic_string +format(std::basic_string&& key, const value& val) { std::basic_string retval( std::forward>(key)); @@ -147,5 +169,89 @@ format(std::basic_string&& key, const value& val) return retval; } +// ----------------------------- stream operators ----------------------------- + +namespace detail +{ + +template +struct inline_limit +{ + static_assert(std::is_same::value, "do not instantiate this"); + static const int index; + T limit; + inline_limit() = default; + ~inline_limit() = default; + constexpr make_inline(T i): limit(i){} + constexpr operator T() const {return limit;} + + static void callback(std::ios_base::event ev, std::ios_base& ios, int idx) + { + void*& info = ios.pword(idx); + switch (ev) + { + case std::ios_base::erase_event: + { + delete static_cast(info); + break; + } + case std::ios_base::copyfmt_event: + { + info = new std::size_t(*static_cast(info)); + break; + } + case std::ios_base::imbue_event: + { + break; + } + } + } +}; + +template +const int inline_limit::index = std::ios_base::xalloc(); + +} //detail + +template> +std::basic_ostream& +operator<<(std::basic_ostream& os, + const detail::inline_limit& inl) +{ + void*& info = os.pword(detail::inline_limit::index); + if(!os.bad()) + { + if(info == nullptr) + { + os.register_callback(detail::inline_limit::callback, + detail::inline_limit::index); + info = new std::size_t(inl.limit); + } + else + { + *static_cast(info) = inl.limit; + } + } + return os; +} + +constexpr static detail::inline_limit forceinline = + detail::inline_limit(std::numeric_limits::max()); + +inline detail::inline_limit make_inline(std::size_t sz) +{ + return detail::inline_limit(sz); +} + +template +std::basic_ostream& +operator<<(std::basic_ostream& os, + const toml::value& v) +{ + std::size_t* info = + static_cast(os.pword(inline_limit::index)); + return os << (info == nullptr ? toml::format(v) : toml::format(v, *info)); +} + } #endif // TOML11_FORMAT