11#include "../microfmt.hpp"
14#include <reloco/allocator.hpp>
15#include <reloco/error.hpp>
28template <
typename Container>
30 Container, std::void_t<decltype(std::declval<Container &>().data()), decltype(std::declval<Container &>().size())>>
31 : std::integral_constant<
32 bool, std::is_convertible<decltype(std::declval<Container &>().data()), const char *>::value &&
33 std::is_convertible<decltype(std::declval<Container &>().size()), std::size_t>::value> {};
35template <
typename Container,
typename =
void>
struct has_std_push_back : std::false_type {};
37template <
typename Container>
38struct has_std_push_back<Container, std::void_t<decltype(std::declval<Container &>().push_back(char{}))>>
42template <
typename Container,
typename =
void>
struct has_try_push_back : std::false_type {};
44template <
typename Container>
46 std::void_t<decltype(static_cast<bool>(std::declval<Container &>().try_push_back(char{})))>>
49template <
typename Container,
typename =
void>
struct has_try_append : std::false_type {};
51template <
typename Container>
52struct has_try_append<Container, std::void_t<decltype(static_cast<bool>(std::declval<Container &>().try_append(
53 microfmt::string_view{})))>> : std::true_type {};
55template <
typename Container>
57 : std::integral_constant<bool, has_data_size_impl<Container>::value &&
58 (has_std_push_back<Container>::value || has_try_push_back<Container>::value)> {};
60template <
typename Container,
typename =
void>
struct has_append : std::false_type {};
62template <
typename Container>
63struct has_append<Container, std::void_t<decltype(std::declval<Container &>().append(
64 std::declval<const char *>(), std::declval<std::size_t>()))>> : std::true_type {};
66template <
typename Container,
typename =
void>
struct has_range_insert : std::false_type {};
68template <
typename Container>
70 Container, std::void_t<decltype(std::declval<Container &>().insert(
71 std::declval<Container &>().end(), std::declval<const char *>(), std::declval<const char *>()))>>
76template <
typename Container>
83template <
typename Container,
typename std::enable_if<is_growable_
char_container<Container>,
int>::type = 0>
86 explicit constexpr container_sink(Container &target RELOCO_LIFETIMEBOUND RELOCO_LIFETIME_CAPTURE_BY_THIS) noexcept
94 [[nodiscard]]
sink as_sink() noexcept RELOCO_LIFETIMEBOUND {
96 [](
void *ctx, microfmt::string_view sv)
noexcept {
static_cast<container_sink *
>(ctx)->
write(sv); }};
99 void put(
char c)
noexcept {
write(microfmt::string_view(&c, 1)); }
103 [[nodiscard]]
bool failed() const noexcept {
return failed_; }
107 RELOCO_BEGIN_UNSAFE_CODE
108 void write(microfmt::string_view sv)
noexcept {
115#if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
129 void write_fallible(microfmt::string_view sv)
noexcept {
131 if (!target_->try_append(sv)) {
136 if (!target_->try_push_back(c)) {
145 void write_std(microfmt::string_view sv) {
146 if constexpr (detail::has_append<Container>::value) {
147 target_->append(sv.data(), sv.size());
148 }
else if constexpr (detail::has_range_insert<Container>::value) {
149 target_->insert(target_->end(), sv.begin(), sv.end());
152 target_->push_back(c);
157 value_ptr<Container> target_;
158 bool failed_ =
false;
162template <
typename Container,
typename std::enable_if<is_growable_
char_container<Container>,
int>::type = 0>
173RELOCO_BEGIN_UNSAFE_CODE
174template <
typename Container,
typename... Args>
175typename std::enable_if<is_growable_char_container<Container>,
void>::type
179 auto out = cs.as_sink();
181#if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
183 throw std::bad_alloc();
190template <
typename Container = std::string,
typename... Args>
191[[nodiscard]]
typename std::enable_if<is_growable_char_container<Container>, Container>::type
202template <
typename Container,
typename... Args>
203[[nodiscard]]
typename std::enable_if<is_growable_char_container<Container> &&
204 std::is_constructible<Container, reloco::allocator_ref>::value,
205 reloco::result<Container>>::type
208 Container result(alloc);
210 format_to(cs.as_sink(), fmt_str, args...);
212 return reloco::unexpected(reloco::error::allocation_failed);
218template <
typename Container,
typename... Args>
219[[nodiscard]]
typename std::enable_if<is_growable_char_container<Container>, reloco::result<void>>::type
223 format_to(cs.as_sink(), fmt_str, args...);
225 return reloco::unexpected(reloco::error::allocation_failed);
Definition container_sink.hpp:84
constexpr container_sink(Container &target RELOCO_LIFETIMEBOUND RELOCO_LIFETIME_CAPTURE_BY_THIS) noexcept
Definition container_sink.hpp:86
void put(char c) noexcept
Definition container_sink.hpp:99
container_sink & operator=(const container_sink &)=delete
bool failed() const noexcept
Definition container_sink.hpp:103
RELOCO_BEGIN_UNSAFE_CODE void write(microfmt::string_view sv) noexcept
Definition container_sink.hpp:108
container_sink(container_sink &&) noexcept=default
container_sink(const container_sink &)=delete
std::enable_if< is_growable_char_container< Container > &&std::is_constructible< Container, reloco::allocator_ref >::value, reloco::result< Container > >::type try_format_as_container(reloco::allocator_ref alloc, microfmt::string_view fmt_str, const Args &...args)
Definition container_sink.hpp:207
constexpr auto make_container_sink(Container &c RELOCO_LIFETIMEBOUND) noexcept
Definition container_sink.hpp:163
reloco::sink sink
Type-erased, zero-allocation output sink.
Definition microfmt.hpp:46
RELOCO_CONSTEXPR20 void format_to(const sink &out, microfmt::string_view fmt, const Args &...args) noexcept
Definition microfmt.hpp:1766
std::enable_if< is_growable_char_container< Container >, reloco::result< void > >::type try_format_to_container(Container &dest, microfmt::string_view fmt_str, const Args &...args)
Definition container_sink.hpp:221
constexpr bool is_growable_char_container
Definition container_sink.hpp:77
RELOCO_END_UNSAFE_CODE std::enable_if< is_growable_char_container< Container >, Container >::type format_as_container(microfmt::string_view fmt_str, const Args &...args)
Definition container_sink.hpp:193
RELOCO_END_UNSAFE_CODE
Definition remote_object.hpp:132
RELOCO_BEGIN_UNSAFE_CODE std::enable_if< is_growable_char_container< Container >, void >::type format_to_container(Container &dest, microfmt::string_view fmt_str, const Args &...args)
Definition container_sink.hpp:177
Definition container_sink.hpp:60
Definition container_sink.hpp:26
Definition container_sink.hpp:66
Definition container_sink.hpp:35
Definition container_sink.hpp:49
Definition container_sink.hpp:42
Definition container_sink.hpp:58