16#if defined( DAW_JSON_HAS_REFLECTION )
17#include <daw/daw_concepts.h>
20#include <daw/daw_move.h>
21#include <daw/traits/daw_traits_remove_cvref.h>
28 namespace json_writer_details {
29 template<
typename JsonClass,
typename Value>
30 using json_write_value_class_t =
typename daw::conditional_t<
31 std::is_same_v<use_default, JsonClass>,
32 json_details::ident_trait<json_details::json_deduced_type, Value>,
33 json_details::ident_trait<json_details::json_deduced_type,
36 enum class json_writer_states : std::uint8_t {
52 template<
typename WritableType,
typename StackType,
auto... PolicyFlags>
55 decltype( json_details::make_output_iterator<PolicyFlags...>(
56 std::declval<WritableType>( ) ) );
59 json_writer_details::json_writer_states m_current_state =
60 json_writer_details::json_writer_states::json_writer_nothing;
61 bool m_is_first =
true;
62 bool m_is_key_written =
false;
66 push_state( json_writer_details::json_writer_states new_state ) {
67 m_stack.push_back( m_current_state );
68 m_current_state = new_state;
73 m_current_state = m_stack.back( );
79 if( not m_is_first ) {
84 m_writer.next_member( );
88 if( m_current_state ==
89 json_writer_details::json_writer_states::json_writer_nothing ) {
93 if( m_current_state ==
94 json_writer_details::json_writer_states::json_writer_object ) {
96 m_is_key_written =
false;
99 if( m_current_state !=
100 json_writer_details::json_writer_states::json_writer_nothing ) {
101 write_item_prefix( );
105 template<
typename JsonClass = use_default,
typename T>
107 using json_class_t =
typename daw::conditional_t<
108 std::is_same_v<use_default, JsonClass>,
109 json_details::ident_trait<json_details::json_deduced_type, T>,
110 json_details::ident_trait<json_details::json_deduced_type,
113 if constexpr( std::is_pointer_v<std::remove_reference_t<T>> ) {
115 m_writer.write(
"null" );
117 if constexpr( std::is_convertible_v<T, char const *> ) {
118 m_writer = json_details::member_to_string<
120 m_writer, daw::string_view( value ) );
123 json_details::member_to_string<json_class_t>( m_writer, value );
128 json_details::member_to_string<json_class_t>( m_writer, value );
136 : m_writer( json_details::make_output_iterator<PolicyFlags...>(
137 DAW_FWD( writer ) ) ) {}
144 if( m_is_key_written ) {
145 write_value(
nullptr );
147 while( m_current_state !=
148 json_writer_details::json_writer_states::json_writer_nothing ) {
149 switch( m_current_state ) {
150 case json_writer_details::json_writer_states::json_writer_object:
153 case json_writer_details::json_writer_states::json_writer_array:
156 case json_writer_details::json_writer_states::json_writer_nothing:
166 json_writer_details::json_writer_states::json_writer_nothing;
168 m_is_key_written =
false;
172 noexcept( m_writer.put( ' ' ) ) ) {
179 json_writer_details::json_writer_states::json_writer_object );
181 m_writer.add_indent( );
188 json_writer_details::json_writer_states::json_writer_object,
189 ErrorReason::OutputError );
190 if( m_is_key_written ) {
191 write_value(
nullptr );
193 m_writer.del_indent( );
194 if( not m_is_first ) {
195 if constexpr( iterator_t::output_trailing_comma ==
196 options::OutputTrailingComma::Yes ) {
199 m_writer.next_member( );
209 json_writer_details::json_writer_states::json_writer_array );
211 m_writer.add_indent( );
218 json_writer_details::json_writer_states::json_writer_array,
219 ErrorReason::OutputError );
220 m_writer.del_indent( );
221 if( not m_is_first ) {
222 if constexpr( iterator_t::output_trailing_comma ==
223 options::OutputTrailingComma::Yes ) {
226 m_writer.next_member( );
237 template<
typename JsonClass = use_default,
typename T>
241 json_writer_details::json_writer_states::json_writer_object or
243 ErrorReason::OutputError );
246 json_writer_details::json_writer_states::json_writer_nothing or
248 ErrorReason::OutputError );
250 do_write_value<JsonClass>( value );
253 template<
typename T,
typename T2,
typename... Ts>
255 Ts
const &...values ) {
258 json_writer_details::json_writer_states::json_writer_object or
260 ErrorReason::OutputError );
263 json_writer_details::json_writer_states::json_writer_nothing or
265 ErrorReason::OutputError );
267 write_array_values( value, value2, values... );
271 template<
typename JsonClass = use_default,
typename T>
272 constexpr void write_value( std::initializer_list<T>
const &values ) {
275 json_writer_details::json_writer_states::json_writer_object or
277 ErrorReason::OutputError );
280 json_writer_details::json_writer_states::json_writer_nothing or
282 ErrorReason::OutputError );
284 write_array_values<JsonClass>( values );
288 template<
typename JsonClass = use_default, std::
size_t N>
292 json_writer_details::json_writer_states::json_writer_object or
294 ErrorReason::OutputError );
297 json_writer_details::json_writer_states::json_writer_nothing or
299 ErrorReason::OutputError );
300 do_write_value<JsonClass>( daw::string_view( str, N - 1 ) );
303 constexpr void add_key( daw::string_view name ) {
304 if( m_is_key_written ) {
305 write_value(
nullptr );
309 json_writer_details::json_writer_states::json_writer_object,
310 ErrorReason::OutputError );
312 write_item_prefix( );
313 m_writer.write(
"\"", name,
"\":", m_writer.space );
314 m_is_key_written =
true;
322 template<
typename JsonClass = use_default,
typename T>
324 std::initializer_list<T>
const &values ) {
327 write_array_values<JsonClass>( values );
331 template<
typename JsonClass = use_default,
typename T>
334 write_value<JsonClass>( value );
337 template<
typename T,
typename T2,
typename... Ts>
339 T2
const &value2, Ts
const &...values ) {
342 write_array_values( value, value2, values... );
346 template<
typename JsonClass = use_default, std::
size_t N>
348 char const ( &str )[N] ) {
350 write_value<JsonClass>( daw::string_view( str, N - 1 ) );
355 typename JsonClass = use_default,
356 typename Range DAW_ENABLEIF( daw::traits::is_container_like_v<Range> )>
358 constexpr
void write_array_values( Range const &values ) {
361 json_writer_details::json_writer_states::json_writer_array,
362 ErrorReason::OutputError );
363 for(
auto const &value : values ) {
364 do_write_value<JsonClass>( value );
368 template<
typename JsonClass = use_default,
typename T>
373 json_writer_details::json_writer_states::json_writer_array,
374 ErrorReason::OutputError );
375 for(
auto const &value : values ) {
376 write_value<JsonClass>( value );
380 template<
typename T,
typename... Ts>
384 json_writer_details::json_writer_states::json_writer_array,
385 ErrorReason::OutputError );
386 write_value( value );
387 (void)( ( write_value( values ),
true ) and ... );
397 json_writer_details::json_writer_states::json_writer_nothing or
399 ErrorReason::OutputError );
401 m_writer.write(
"null" );
405 template<
typename JsonClass = use_default,
typename T>
408 json_writer_details::json_write_value_class_t<JsonClass, T>;
410 JsonMember::underlying_json_type;
412 json_base_type == JsonBaseParseTypes::Number or
413 json_base_type == JsonBaseParseTypes::Bool,
414 "The underlying mapping must be a number or boolean type" );
415 if constexpr( json_base_type == JsonBaseParseTypes::Bool ) {
416 write_value<JsonClass>(
static_cast<bool>( value ) ? 1 : 0 );
419 write_value<JsonClass>( value );
426 using json_class_t = json_details::json_deduced_type<T>;
427 auto tmp = std::string{ };
429 json_details::make_output_iterator<PolicyFlags...>( tmp );
430 tmp_iterator.indentation_level = m_writer.indentation_level;
431 (void)json_details::member_to_string<json_class_t>( tmp_iterator,
433 do_write_value<json_string_no_name<>>( tmp );
437 template<
typename JsonClass = use_default,
typename T>
440 json_writer_details::json_write_value_class_t<JsonClass, T>;
442 JsonMember::underlying_json_type;
443 if constexpr( json_base_type == JsonBaseParseTypes::String ) {
444 write_value<JsonClass>( value );
445 }
else if constexpr( json_base_type == JsonBaseParseTypes::Bool or
446 json_base_type == JsonBaseParseTypes::Number ) {
450 json_details::member_to_string<JsonMember>( m_writer, value );
454 write_string_class( value );
458 template<
typename JsonClass = use_default, std::
size_t N>
460 write_value<JsonClass>( daw::string_view( str, N - 1 ) );
463#if defined( DAW_JSON_HAS_REFLECTION )
464 constexpr void write_enum_string( daw::EnumType
auto e ) {
465 write_string( refl_details::enum_to_string( e ) );
470 template<
auto... PolicyFlags,
typename WriterType>
471 constexpr auto json_writer( WriterType &&writer DAW_LIFETIME_BOUND ) {
473 std::vector<json_writer_details::json_writer_states>,
474 PolicyFlags...>( 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()
DAW_CPP20_CX_ALLOC void write_string_class(T const &value)
constexpr void write_string(T const &value)
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 json_writer_t(W &&writer DAW_LIFETIME_BOUND)
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.
json_base::json_string_raw< T, Options, Constructor > json_string_raw_no_name
constexpr auto json_writer(WriterType &&writer DAW_LIFETIME_BOUND)
Customization point traits.
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.