18#if defined( DAW_JSON_HAS_REFLECTION )
19#include <daw/daw_concepts.h>
22#include <daw/daw_move.h>
23#include <daw/traits/daw_traits_remove_cvref.h>
30 namespace json_writer_details {
31 template<
typename JsonClass,
typename Value>
32 using json_write_value_class_t =
typename daw::conditional_t<
33 std::is_same_v<use_default, JsonClass>,
34 json_details::ident_trait<json_details::json_deduced_type, Value>,
35 json_details::ident_trait<json_details::json_deduced_type,
38 enum class json_writer_states : std::uint8_t {
54 template<
typename WritableType,
typename StackType,
auto... PolicyFlags>
57 decltype( json_details::make_output_iterator<PolicyFlags...>(
58 std::declval<WritableType>( ) ) );
61 json_writer_details::json_writer_states m_current_state =
62 json_writer_details::json_writer_states::json_writer_nothing;
63 bool m_is_first =
true;
64 bool m_is_key_written =
false;
68 push_state( json_writer_details::json_writer_states new_state ) {
69 m_stack.push_back( m_current_state );
70 m_current_state = new_state;
75 m_current_state = m_stack.back( );
81 if( not m_is_first ) {
86 m_writer.next_member( );
90 if( m_current_state ==
91 json_writer_details::json_writer_states::json_writer_nothing ) {
95 if( m_current_state ==
96 json_writer_details::json_writer_states::json_writer_object ) {
98 m_is_key_written =
false;
101 if( m_current_state !=
102 json_writer_details::json_writer_states::json_writer_nothing ) {
103 write_item_prefix( );
107 template<
typename JsonClass = use_default,
typename T>
110 to_json<JsonClass>( value, m_writer.get( ) );
117 : m_writer( json_details::make_output_iterator<PolicyFlags...>(
118 DAW_FWD( writer ) ) ) {}
125 if( m_is_key_written ) {
126 write_value(
nullptr );
128 while( m_current_state !=
129 json_writer_details::json_writer_states::json_writer_nothing ) {
130 switch( m_current_state ) {
131 case json_writer_details::json_writer_states::json_writer_object:
134 case json_writer_details::json_writer_states::json_writer_array:
137 case json_writer_details::json_writer_states::json_writer_nothing:
147 json_writer_details::json_writer_states::json_writer_nothing;
149 m_is_key_written =
false;
153 noexcept( m_writer.put( ' ' ) ) ) {
160 json_writer_details::json_writer_states::json_writer_object );
162 m_writer.add_indent( );
169 json_writer_details::json_writer_states::json_writer_object,
170 ErrorReason::OutputError );
171 if( m_is_key_written ) {
172 write_value(
nullptr );
174 m_writer.del_indent( );
175 if( not m_is_first ) {
176 m_writer.next_member( );
186 json_writer_details::json_writer_states::json_writer_array );
188 m_writer.add_indent( );
195 json_writer_details::json_writer_states::json_writer_array,
196 ErrorReason::OutputError );
197 m_writer.del_indent( );
198 if( not m_is_first ) {
199 m_writer.next_member( );
210 template<
typename JsonClass = use_default,
typename T>
214 json_writer_details::json_writer_states::json_writer_object or
216 ErrorReason::OutputError );
219 json_writer_details::json_writer_states::json_writer_nothing or
221 ErrorReason::OutputError );
222 do_write_value<JsonClass>( value );
225 template<
typename T,
typename T2,
typename... Ts>
227 Ts
const &...values ) {
230 json_writer_details::json_writer_states::json_writer_object or
232 ErrorReason::OutputError );
235 json_writer_details::json_writer_states::json_writer_nothing or
237 ErrorReason::OutputError );
239 write_array_values( value, value2, values... );
243 template<
typename JsonClass = use_default,
typename T>
244 constexpr void write_value( std::initializer_list<T>
const &values ) {
247 json_writer_details::json_writer_states::json_writer_object or
249 ErrorReason::OutputError );
252 json_writer_details::json_writer_states::json_writer_nothing or
254 ErrorReason::OutputError );
256 write_array_values<JsonClass>( values );
260 template<
typename JsonClass = use_default, std::
size_t N>
264 json_writer_details::json_writer_states::json_writer_object or
266 ErrorReason::OutputError );
269 json_writer_details::json_writer_states::json_writer_nothing or
271 ErrorReason::OutputError );
272 do_write_value<JsonClass>( daw::string_view( str, N - 1 ) );
275 constexpr void add_key( daw::string_view name ) {
276 if( m_is_key_written ) {
277 write_value(
nullptr );
281 json_writer_details::json_writer_states::json_writer_object,
282 ErrorReason::OutputError );
284 write_item_prefix( );
285 m_writer.write(
"\"", name,
"\":", m_writer.space );
286 m_is_key_written =
true;
294 template<
typename JsonClass = use_default,
typename T>
296 std::initializer_list<T>
const &values ) {
299 write_array_values<JsonClass>( values );
303 template<
typename JsonClass = use_default,
typename T>
306 write_value<JsonClass>( value );
309 template<
typename T,
typename T2,
typename... Ts>
311 T2
const &value2, Ts
const &...values ) {
314 write_array_values( value, value2, values... );
318 template<
typename JsonClass = use_default, std::
size_t N>
320 char const ( &str )[N] ) {
322 write_value<JsonClass>( daw::string_view( str, N - 1 ) );
327 typename JsonClass = use_default,
328 typename Range DAW_ENABLEIF( daw::traits::is_container_like_v<Range> )>
330 constexpr
void write_array_values( Range const &values ) {
333 json_writer_details::json_writer_states::json_writer_array,
334 ErrorReason::OutputError );
335 for(
auto const &value : values ) {
336 do_write_value<JsonClass>( value );
340 template<
typename JsonClass = use_default,
typename T>
345 json_writer_details::json_writer_states::json_writer_array,
346 ErrorReason::OutputError );
347 for(
auto const &value : values ) {
348 write_value<JsonClass>( value );
352 template<
typename T,
typename... Ts>
356 json_writer_details::json_writer_states::json_writer_array,
357 ErrorReason::OutputError );
358 write_value( value );
359 (void)( ( write_value( values ),
true ) and ... );
369 json_writer_details::json_writer_states::json_writer_nothing or
371 ErrorReason::OutputError );
373 m_writer.write(
"null" );
377 template<
typename JsonClass = use_default,
typename T>
380 json_writer_details::json_write_value_class_t<JsonClass, T>;
382 JsonMember::underlying_json_type;
384 json_base_type == JsonBaseParseTypes::Number or
385 json_base_type == JsonBaseParseTypes::Bool,
386 "The underlying mapping must be a number or boolean type" );
387 if constexpr( json_base_type == JsonBaseParseTypes::Bool ) {
388 write_value<JsonClass>(
static_cast<bool>( value ) ? 1 : 0 );
391 write_value<JsonClass>( value );
396 template<
typename JsonClass = use_default,
typename T>
399 json_writer_details::json_write_value_class_t<JsonClass, T>;
401 JsonMember::underlying_json_type;
402 if constexpr( json_base_type == JsonBaseParseTypes::String ) {
403 write_value<JsonClass>( value );
404 }
else if constexpr( json_base_type == JsonBaseParseTypes::Bool or
405 json_base_type == JsonBaseParseTypes::Number ) {
408 to_json<JsonClass>( value, m_writer.get( ) );
412 auto const tmp =
to_json( value );
413 do_write_value<json_string_no_name<>>( tmp );
417 template<
typename JsonClass = use_default, std::
size_t N>
419 write_value<JsonClass>( daw::string_view( str, N - 1 ) );
422#if defined( DAW_JSON_HAS_REFLECTION )
423 constexpr void write_enum_string( daw::EnumType
auto e ) {
424 write_string( refl_details::enum_to_string( e ) );
429 template<
auto... PolicyFlags,
typename WriterType>
432 std::vector<json_writer_details::json_writer_states>,
433 PolicyFlags...>( writer );
constexpr json_writer_t(W &&writer)
constexpr void write_boolean(bool b)
constexpr void do_write_value(T const &value)
constexpr void write_null()
DAW_CPP20_CX_DTOR ~json_writer_t() noexcept(noexcept(m_writer.put(' ')))
constexpr void prepare_value()
constexpr void write_number(T const &value)
constexpr void write_array_values(std::initializer_list< T > const &values)
json_writer_t(json_writer_t &&other)=delete
constexpr void write_value(char const (&str)[N])
constexpr void write_key_value(daw::string_view name, std::nullptr_t)
constexpr void close_object()
constexpr void open_array()
constexpr void write_string(T const &value)
When outputting a class, uses default to_json.
json_writer_t & operator=(json_writer_t &&)=delete
constexpr void write_value(T const &value)
json_writer_t & operator=(json_writer_t const &)=delete
constexpr void finalize()
constexpr void write_value(T const &value, T2 const &value2, Ts const &...values)
constexpr void open_object()
constexpr void write_item_prefix()
constexpr void push_state(json_writer_details::json_writer_states new_state)
constexpr void write_key_value(daw::string_view name, std::initializer_list< T > const &values)
constexpr void write_value(std::initializer_list< T > const &values)
constexpr void write_key_value(daw::string_view name, char const (&str)[N])
json_writer_t(json_writer_t const &)=delete
constexpr void write_value(std::nullptr_t)
constexpr void write_array_values(T const &value, Ts const &...values)
decltype(json_details::make_output_iterator< PolicyFlags... >(std::declval< WritableType >())) iterator_t
constexpr void pop_state()
constexpr void close_array()
constexpr void write_key_value(daw::string_view name, T const &value, T2 const &value2, Ts const &...values)
constexpr void write_key_value(daw::string_view name, T const &value)
constexpr void add_key(daw::string_view name)
constexpr void write_string(char const (&str)[N])
#define daw_json_ensure(Bool,...)
Ensure that Bool is true. If false pass rest of args to daw_json_error.
DAW_REQUIRES(daw::json::json_details::is_container_opted_into_json_iostreams_v< Container >) std
An opt in ostream interface for containers of types that have JSON mappings.
JsonBaseParseTypes
The fundamental JSON types.
constexpr auto json_writer(WriterType &&writer)
DAW_CPP20_CX_ALLOC std::string to_json(Value const &value, options::output_flags_t< PolicyFlags... > flgs)
Customization point traits.
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.