DAW JSON Link
Loading...
Searching...
No Matches
daw_writable_output_basics.h
Go to the documentation of this file.
1// Copyright (c) Darrell Wright
2//
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
5//
6// Official repository: https://github.com/beached/daw_json_link
7//
8
9#pragma once
10
12
17
18#include <daw/daw_algorithm.h>
19#include <daw/daw_character_traits.h>
20#include <daw/daw_enable_requires.h>
21#include <daw/daw_string_view.h>
22
23#include <cstdio>
24
25namespace daw::json {
26 inline namespace DAW_JSON_VER {
27 namespace concepts {
29 template<typename T>
30 DAW_REQUIRES( writeable_output_details::is_char_sized_character_v<T> or
31 writeable_output_details::is_byte_type_v<T> )
32 struct writable_output_trait<
33 T * DAW_ENABLEIF_S(
34 writeable_output_details::is_char_sized_character_v<T> or
35 writeable_output_details::is_byte_type_v<T> )> : std::true_type {
36
37 template<typename... StringViews>
38 static constexpr void write( T *&ptr, StringViews const &...svs ) {
39 static_assert( sizeof...( StringViews ) > 0 );
40 daw_json_ensure( ptr, daw::json::ErrorReason::OutputError );
41 DAW_CPP23_STATIC_LOCAL constexpr auto writer =
42 []( T *&p, auto sv ) DAW_JSON_CPP23_STATIC_CALL_OP {
43 if( sv.empty( ) ) {
44 return 0;
45 }
46 p = writeable_output_details::copy_to_buffer( p, sv );
47 return 1;
48 };
49 ( (void)writer( ptr, svs ), ... );
50 }
51
52 static constexpr void put( T *&ptr, char c ) {
53 daw_json_ensure( ptr, daw::json::ErrorReason::OutputError );
54 *ptr = static_cast<T>( c );
55 ++ptr;
56 }
57 };
58
60 template<typename T>
61 DAW_REQUIRES( writeable_output_details::is_span_like_range_v<
62 T, typename T::value_type> )
63 struct writable_output_trait<
64 T DAW_ENABLEIF_S( writeable_output_details::is_span_like_range_v<
65 T, typename T::value_type> )> : std::true_type {
66 using CharT = typename T::value_type;
67
68 template<typename... StringViews>
69 static constexpr void write( T &out, StringViews const &...svs ) {
70 static_assert( sizeof...( StringViews ) > 0 );
71 daw_json_ensure( out.size( ) >= ( std::size( svs ) + ... ),
72 daw::json::ErrorReason::OutputError );
73 DAW_CPP23_STATIC_LOCAL constexpr auto writer =
74 []( T &s, auto sv ) DAW_JSON_CPP23_STATIC_CALL_OP {
75 if( sv.empty( ) ) {
76 return 0;
77 }
78 (void)writeable_output_details::copy_to_buffer( s.data( ), sv );
79 s = s.subspan( sv.size( ) );
80 return 1;
81 };
82 ( (void)writer( out, svs ), ... );
83 }
84
85 static constexpr void put( T &out, char c ) {
86 daw_json_ensure( not out.empty( ),
87 daw::json::ErrorReason::OutputError );
88 *out.data( ) = static_cast<CharT>( c );
89 if constexpr( writeable_output_details::has_remove_prefix_v<T> ) {
90 out.remove_prefix( 1 );
91 } else {
92 out = out.subspan( 1 );
93 }
94 }
95 };
96
98 template<typename Container>
99 DAW_REQUIRES( writeable_output_details::is_string_like_writable_output_v<
100 Container, typename Container::value_type> )
101 struct writable_output_trait<Container DAW_ENABLEIF_S(
102 writeable_output_details::is_string_like_writable_output_v<
103 Container, typename Container::value_type> )> : std::true_type {
104 using CharT = typename Container::value_type;
105
106 template<typename... StringViews>
107 static constexpr void write( Container &out,
108 StringViews const &...svs ) {
109 static_assert( sizeof...( StringViews ) > 0 );
110 auto const start_pos = out.size( );
111 auto const total_size = ( std::size( svs ) + ... );
112 out.resize( start_pos + total_size );
113
114 DAW_CPP23_STATIC_LOCAL constexpr auto writer =
115 []( CharT *&p, auto sv ) DAW_JSON_CPP23_STATIC_CALL_OP {
116 if( sv.empty( ) ) {
117 return 0;
118 }
119 p = writeable_output_details::copy_to_buffer( p, sv );
120 return 1;
121 };
122 auto *ptr = out.data( ) + start_pos;
123 ( (void)writer( ptr, svs ), ... );
124 }
125
126 static constexpr void put( Container &out, char c ) {
127 out.push_back( static_cast<CharT>( c ) );
128 }
129
132 static constexpr void reserve( Container &out, std::size_t n ) {
133 if constexpr( writeable_output_details::has_capacity_reserve_v<
134 Container> ) {
135 auto const needed = out.size( ) + n;
136 if( out.capacity( ) < needed ) {
137 auto const doubled = out.capacity( ) * 2;
138 out.reserve( needed < doubled ? doubled : needed );
139 }
140 }
141 }
142 };
143
145 template<typename T>
146 DAW_REQUIRES( writeable_output_details::is_writable_output_iterator_v<T> )
147 struct writable_output_trait<T DAW_ENABLEIF_S(
148 writeable_output_details::is_writable_output_iterator_v<T> )>
149 : std::true_type {
150
151 template<typename... StringViews>
152 static constexpr void write( T &it, StringViews const &...svs ) {
153 static_assert( sizeof...( StringViews ) > 0 );
154
155 DAW_CPP23_STATIC_LOCAL constexpr auto writer =
156 []( T &i, auto sv ) DAW_JSON_CPP23_STATIC_CALL_OP {
157 for( char c : daw::string_view( sv ) ) {
158 *i = c;
159 ++i;
160 }
161 return 0;
162 };
163 ( (void)writer( it, svs ), ... );
164 }
165
166 static constexpr void put( T &it, char c ) {
167 *it = c;
168 ++it;
169 }
170 };
171 } // namespace concepts
172 } // namespace DAW_JSON_VER
173} // namespace daw::json
#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.
#define DAW_JSON_CPP23_STATIC_CALL_OP
string_writer grows its string with resize_and_overwrite, leaving the new bytes uninitialized,...
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition version.h:20