22#define C4_DUMP_HPP_
33
44#include < c4/substr.hpp>
5+ #include < utility> // for std::forward
6+
57
68/* * @file dump.hpp This file provides functions to dump several
79 * arguments as strings to a user-provided function sink, for example
@@ -52,29 +54,24 @@ C4_SUPPRESS_WARNING_GCC_CLANG_WITH_PUSH("-Wold-style-cast")
5254using SinkPfn = void (*)(csubstr str);
5355
5456
55- /* * a traits class to use in SFINAE with @ref c4::dump() to select if
56- * a type is treated as string type (which is dumped directly to the
57- * sink, using to_csubstr()), or if the type is treated as a value,
58- * which is first serialized to a buffer using to_chars(), and then
59- * the serialization serialized as */
60- template <class T > struct dump_directly : public std ::false_type {};
61- template <> struct dump_directly <csubstr> : public std::true_type {};
62- template <> struct dump_directly < substr> : public std::true_type {};
63- template <> struct dump_directly <const char *> : public std::true_type {};
64- template <> struct dump_directly < char *> : public std::true_type {};
65- template <size_t N> struct dump_directly <const char (&)[N]> : public std::true_type {};
66- template <size_t N> struct dump_directly < char (&)[N]> : public std::true_type {};
67- template <size_t N> struct dump_directly <const char [N]> : public std::true_type {};
68- template <size_t N> struct dump_directly < char [N]> : public std::true_type {};
57+ template <class T > struct is_string ; // fwd-decl
58+
59+ /* * a traits class used by @ref c4::dump() to decide whether a type is
60+ * treated as a string type (which is dumped directly to the sink via
61+ * to_csubstr()), or if the type is treated as a value, which is first
62+ * serialized to the dump buffer using to_chars() prior to dumping it
63+ * to the sink. This type defaults to @ref c4::is_string, but can be
64+ * overriden independently. */
65+ template <class T > struct dump_directly : public is_string <T> {};
6966
7067
7168#if (C4_CPP >= 17) || defined(__DOXYGEN__)
7269/* * Dump a serializable object to the (statically dispatched)
7370 * sink. Before dumping, the object may be serialized to a string if
7471 * @ref c4::dump_directly<Arg> is a false type (the default if
7572 * dump_directly does not have a specialization). Otherwise the object
76- * is considered a string object is dumped directly, without any
77- * intermediate serialization.
73+ * is considered a string object and is therefore dumped directly,
74+ * without any intermediate serialization.
7875 *
7976 * @return the number of bytes needed to serialize the string-type
8077 * object, which may be 0 when there is no serialization
@@ -97,10 +94,11 @@ size_t dump(substr buf, Arg const& a)
9794{
9895 if constexpr (dump_directly<Arg>::value)
9996 {
100- C4_ASSERT (!buf.overlaps (a));
10197 C4_UNUSED (buf);
98+ csubstr sa = to_csubstr (a);
99+ C4_ASSERT (!buf.overlaps (sa));
102100 // dump directly, no need to serialize to the buffer
103- sinkfn (to_csubstr (a) );
101+ sinkfn (sa );
104102 return 0 ; // no space was used in the buffer
105103 }
106104 else
@@ -151,9 +149,10 @@ size_t dump(SinkFn &&sinkfn, substr buf, Arg const& a)
151149 if constexpr (dump_directly<Arg>::value)
152150 {
153151 C4_UNUSED (buf);
154- C4_ASSERT (!buf.overlaps (a));
152+ csubstr sa = to_csubstr (a);
153+ C4_ASSERT (!buf.overlaps (sa));
155154 // dump directly, no need to serialize to the buffer
156- std::forward<SinkFn>(sinkfn)(to_csubstr (a) );
155+ std::forward<SinkFn>(sinkfn)(sa );
157156 return 0 ; // no space was used in the buffer
158157 }
159158 else
@@ -181,20 +180,22 @@ template<SinkPfn sinkfn, class Arg>
181180inline auto dump (substr buf, Arg const & a)
182181 -> typename std::enable_if<dump_directly<Arg>::value, size_t>::type
183182{
184- C4_ASSERT (!buf.overlaps (a));
185183 C4_UNUSED (buf);
184+ csubstr sa = to_csubstr (a);
185+ C4_ASSERT (!buf.overlaps (sa));
186186 // dump directly, no need to serialize to the buffer
187- sinkfn (to_csubstr (a) );
187+ sinkfn (sa );
188188 return 0 ; // no space was used in the buffer
189189}
190190template <class SinkFn , class Arg >
191191inline auto dump (SinkFn &&sinkfn, substr buf, Arg const & a)
192192 -> typename std::enable_if<dump_directly<Arg>::value, size_t>::type
193193{
194194 C4_UNUSED (buf);
195- C4_ASSERT (!buf.overlaps (a));
195+ csubstr sa = to_csubstr (a);
196+ C4_ASSERT (!buf.overlaps (sa));
196197 // dump directly, no need to serialize to the buffer
197- std::forward<SinkFn>(sinkfn)(to_csubstr (a) );
198+ std::forward<SinkFn>(sinkfn)(sa );
198199 return 0 ; // no space was used in the buffer
199200}
200201
0 commit comments