DAW JSON Link
Loading...
Searching...
No Matches
daw_writable_output_string_writer.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
16
17#include <daw/cpp_20.h>
18#include <daw/daw_attributes.h>
19#include <daw/daw_cpp_feature_check.h>
20#include <daw/daw_is_constant_evaluated.h>
21#include <daw/daw_likely.h>
22#include <daw/daw_string_view.h>
23
24#include <algorithm>
25#include <cstddef>
26#include <string>
27#include <type_traits>
28#include <utility>
29
36#if defined( DAW_HAS_CPP23_STR_RESIZE_OVERWRITE ) and \
37 not defined( DAW_JSON_NO_LESS_SAFE_STRING_WRITER )
38#define DAW_JSON_STRING_WRITER_SKIPS_ZERO_FILL
39#endif
40
41namespace daw::json {
42 inline namespace DAW_JSON_VER {
48 std::string m_str{ };
49 std::size_t m_size = 0;
50
54 DAW_ATTRIB_NOINLINE DAW_CPP20_CX_ALLOC2 void grow( std::size_t needed ) {
55 auto const n = ( std::max )(
56 { m_str.size( ) * 2, m_str.capacity( ), needed } );
57#if defined( DAW_JSON_STRING_WRITER_SKIPS_ZERO_FILL )
58 if( not DAW_IS_CONSTANT_EVALUATED_COMPAT( ) ) {
59 m_str.resize_and_overwrite(
60 n, []( char *, std::size_t sz ) DAW_JSON_CPP23_STATIC_CALL_OP {
61 return sz;
62 } );
63 return;
64 }
65#endif
66 m_str.resize( n );
67 }
68
69 public:
70 explicit string_writer( ) = default;
71
73 explicit DAW_CPP20_CX_ALLOC string_writer( std::size_t initial ) {
74 grow( initial );
75 }
76
78 [[nodiscard]] DAW_ATTRIB_INLINE DAW_CPP20_CX_ALLOC2 char *
79 reserve( std::size_t n ) {
80 if( DAW_UNLIKELY( m_str.size( ) - m_size < n ) ) {
81 grow( m_size + n );
82 }
83 return m_str.data( ) + m_size;
84 }
85
86 DAW_ATTRIB_INLINE DAW_CPP20_CX_ALLOC2 void commit( std::size_t n ) {
87 m_size += n;
88 }
89
90 DAW_ATTRIB_INLINE DAW_CPP20_CX_ALLOC2 void write( daw::string_view text ) {
91 (void)concepts::writeable_output_details::copy_to_buffer(
92 reserve( text.size( ) ), text );
93 commit( text.size( ) );
94 }
95
96 DAW_ATTRIB_INLINE DAW_CPP20_CX_ALLOC2 void put( char c ) {
97 *reserve( 1 ) = c;
98 commit( 1 );
99 }
100
102 [[nodiscard]] constexpr std::size_t size( ) const {
103 return m_size;
104 }
105
108 [[nodiscard]] DAW_CPP20_CX_ALLOC std::string finish( ) && {
109 m_str.resize( m_size );
110 m_size = 0;
111 return std::move( m_str );
112 }
113 };
114
115 namespace concepts {
117 template<>
118 struct writable_output_trait<string_writer> : std::true_type {
119 using CharT = char;
120
121 template<typename... StringViews>
122 static DAW_CPP20_CX_ALLOC void write( string_writer &out,
123 StringViews const &...svs ) {
124 static_assert( sizeof...( StringViews ) > 0 );
125 auto const total_size = ( std::size( svs ) + ... );
126 DAW_CPP23_STATIC_LOCAL constexpr auto writer =
127 []( char *&p, auto sv ) DAW_JSON_CPP23_STATIC_CALL_OP {
128 if( sv.empty( ) ) {
129 return 0;
130 }
131 p = writeable_output_details::copy_to_buffer( p, sv );
132 return 1;
133 };
134 auto *ptr = out.reserve( total_size );
135 ( (void)writer( ptr, svs ), ... );
136 out.commit( total_size );
137 }
138
139 static DAW_CPP20_CX_ALLOC void put( string_writer &out, char c ) {
140 out.put( c );
141 }
142
144 static DAW_CPP20_CX_ALLOC void reserve( string_writer &out,
145 std::size_t n ) {
146 (void)out.reserve( n );
147 }
148 };
149 } // namespace concepts
150 } // namespace DAW_JSON_VER
151} // namespace daw::json
A writable output that serializes into a std::string. The string's own output trait resizes it on eve...
DAW_ATTRIB_INLINE DAW_CPP20_CX_ALLOC2 char * reserve(std::size_t n)
Room for n more bytes; commit( ) them once written.
DAW_ATTRIB_NOINLINE DAW_CPP20_CX_ALLOC2 void grow(std::size_t needed)
Out of line so the room check in reserve( ) stays small enough to inline into every put and write....
DAW_CPP20_CX_ALLOC std::string finish() &&
The text written. Shrinking the string neither fills nor reallocates it.
#define DAW_JSON_CPP23_STATIC_CALL_OP
string_writer grows its string with resize_and_overwrite, leaving the new bytes uninitialized,...
static DAW_CPP20_CX_ALLOC void reserve(string_writer &out, std::size_t n)
Room for at least n more bytes.
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition version.h:20