mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-12-16 03:08:52 +08:00
add stream manipulators
This commit is contained in:
116
toml/format.hpp
116
toml/format.hpp
@@ -1,16 +1,40 @@
|
|||||||
#ifndef TOML11_FORMAT
|
#ifndef TOML11_FORMAT
|
||||||
#define TOML11_FORMAT
|
#define TOML11_FORMAT
|
||||||
#include "value.hpp"
|
#include "value.hpp"
|
||||||
|
#include <type_traits>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
namespace toml
|
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 traits = std::char_traits<toml::charactor>,
|
template<typename traits = std::char_traits<toml::charactor>,
|
||||||
typename alloc = std::allocator<toml::charactor>>
|
typename alloc = std::allocator<toml::charactor>>
|
||||||
std::basic_string<toml::charactor, traits, alloc>
|
std::basic_string<toml::charactor, traits, alloc>
|
||||||
format(const value& v);
|
format(const value& v);
|
||||||
|
|
||||||
|
template<typename traits = std::char_traits<toml::charactor>,
|
||||||
|
typename alloc = std::allocator<toml::charactor>>
|
||||||
|
std::basic_string<toml::charactor, traits, alloc>
|
||||||
|
format(const value& v, std::size_t mk);
|
||||||
|
|
||||||
|
template<typename traits = std::char_traits<toml::charactor>,
|
||||||
|
typename alloc = std::allocator<toml::charactor>>
|
||||||
|
std::basic_string<toml::charactor, traits, alloc>
|
||||||
|
format(const toml::key& k, const value& v);
|
||||||
|
|
||||||
|
template<typename traits = std::char_traits<toml::charactor>,
|
||||||
|
typename alloc = std::allocator<toml::charactor>>
|
||||||
|
std::basic_string<toml::charactor, traits, alloc>
|
||||||
|
format(const toml::key& k, const value& v, std::size_t mk);
|
||||||
|
|
||||||
template<value_t Type>
|
template<value_t Type>
|
||||||
struct format_impl;
|
struct format_impl;
|
||||||
|
|
||||||
@@ -115,7 +139,6 @@ template<> struct format_impl<value_t::Table>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template<typename traits, typename alloc>
|
template<typename traits, typename alloc>
|
||||||
std::basic_string<toml::charactor, traits, alloc>
|
std::basic_string<toml::charactor, traits, alloc>
|
||||||
format(const value& v)
|
format(const value& v)
|
||||||
@@ -135,10 +158,9 @@ format(const value& v)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename charT = charactor, typename traits = std::char_traits<charT>,
|
template<typename traits, typename alloc>
|
||||||
typename alloc = std::allocator<charT>>
|
std::basic_string<toml::charactor, traits, alloc>
|
||||||
std::basic_string<charT, traits, alloc>
|
format(std::basic_string<toml::charactor, traits, alloc>&& key, const value& val)
|
||||||
format(std::basic_string<charT, traits, alloc>&& key, const value& val)
|
|
||||||
{
|
{
|
||||||
std::basic_string<charT, traits, alloc> retval(
|
std::basic_string<charT, traits, alloc> retval(
|
||||||
std::forward<std::basic_string<charT, traits, alloc>>(key));
|
std::forward<std::basic_string<charT, traits, alloc>>(key));
|
||||||
@@ -147,5 +169,89 @@ format(std::basic_string<charT, traits, alloc>&& key, const value& val)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------- stream operators -----------------------------
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename T = std::size_t>
|
||||||
|
struct inline_limit
|
||||||
|
{
|
||||||
|
static_assert(std::is_same<T, std::size_t>::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<std::size_t*>(info);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case std::ios_base::copyfmt_event:
|
||||||
|
{
|
||||||
|
info = new std::size_t(*static_cast<std::size_t*>(info));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case std::ios_base::imbue_event:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
const int inline_limit<T>::index = std::ios_base::xalloc();
|
||||||
|
|
||||||
|
} //detail
|
||||||
|
|
||||||
|
template<typename sizeT, typename traits = std::char_traits<toml::charactor>>
|
||||||
|
std::basic_ostream<toml::charactor, traits>&
|
||||||
|
operator<<(std::basic_ostream<toml::charactor, traits>& os,
|
||||||
|
const detail::inline_limit<sizeT>& inl)
|
||||||
|
{
|
||||||
|
void*& info = os.pword(detail::inline_limit<sizeT>::index);
|
||||||
|
if(!os.bad())
|
||||||
|
{
|
||||||
|
if(info == nullptr)
|
||||||
|
{
|
||||||
|
os.register_callback(detail::inline_limit<sizeT>::callback,
|
||||||
|
detail::inline_limit<sizeT>::index);
|
||||||
|
info = new std::size_t(inl.limit);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*static_cast<std::size_t*>(info) = inl.limit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr static detail::inline_limit<std::size_t> forceinline =
|
||||||
|
detail::inline_limit(std::numeric_limits<std::size_t>::max());
|
||||||
|
|
||||||
|
inline detail::inline_limit<std::size_t> make_inline(std::size_t sz)
|
||||||
|
{
|
||||||
|
return detail::inline_limit<std::size_t>(sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename traits = std::char_traits>
|
||||||
|
std::basic_ostream<toml::charactor, traits>&
|
||||||
|
operator<<(std::basic_ostream<toml::charactor, traits>& os,
|
||||||
|
const toml::value& v)
|
||||||
|
{
|
||||||
|
std::size_t* info =
|
||||||
|
static_cast<std::size_t*>(os.pword(inline_limit<std::size_t>::index));
|
||||||
|
return os << (info == nullptr ? toml::format(v) : toml::format(v, *info));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif // TOML11_FORMAT
|
#endif // TOML11_FORMAT
|
||||||
|
|||||||
Reference in New Issue
Block a user