/src/boost/boost/json/impl/string.hpp
Line | Count | Source (jump to first uncovered line) |
1 | | // |
2 | | // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) |
3 | | // |
4 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
5 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
6 | | // |
7 | | // Official repository: https://github.com/boostorg/json |
8 | | // |
9 | | |
10 | | #ifndef BOOST_JSON_IMPL_STRING_HPP |
11 | | #define BOOST_JSON_IMPL_STRING_HPP |
12 | | |
13 | | #include <utility> |
14 | | |
15 | | namespace boost { |
16 | | namespace json { |
17 | | |
18 | | string:: |
19 | | string( |
20 | | detail::key_t const&, |
21 | | string_view s, |
22 | | storage_ptr sp) |
23 | 1.88M | : sp_(std::move(sp)) |
24 | 1.88M | , impl_(detail::key_t{}, |
25 | 1.88M | s, sp_) |
26 | 1.88M | { |
27 | 1.88M | } |
28 | | |
29 | | string:: |
30 | | string( |
31 | | detail::key_t const&, |
32 | | string_view s1, |
33 | | string_view s2, |
34 | | storage_ptr sp) |
35 | 3.26k | : sp_(std::move(sp)) |
36 | 3.26k | , impl_(detail::key_t{}, |
37 | 3.26k | s1, s2, sp_) |
38 | 3.26k | { |
39 | 3.26k | } |
40 | | |
41 | | template<class InputIt, class> |
42 | | string:: |
43 | | string( |
44 | | InputIt first, |
45 | | InputIt last, |
46 | | storage_ptr sp) |
47 | 0 | : sp_(std::move(sp)) |
48 | 0 | , impl_(first, last, sp_, |
49 | 0 | iter_cat<InputIt>{}) |
50 | 0 | { |
51 | 0 | } |
52 | | |
53 | | template<class InputIt, class> |
54 | | string& |
55 | | string:: |
56 | | assign( |
57 | | InputIt first, |
58 | | InputIt last) |
59 | | { |
60 | | assign(first, last, |
61 | | iter_cat<InputIt>{}); |
62 | | return *this; |
63 | | } |
64 | | |
65 | | template<class InputIt, class> |
66 | | string& |
67 | | string:: |
68 | | append(InputIt first, InputIt last) |
69 | | { |
70 | | append(first, last, |
71 | | iter_cat<InputIt>{}); |
72 | | return *this; |
73 | | } |
74 | | |
75 | | // KRYSTIAN TODO: this can be done without copies when |
76 | | // reallocation is not needed, when the iterator is a |
77 | | // FowardIterator or better, as we can use std::distance |
78 | | template<class InputIt, class> |
79 | | auto |
80 | | string:: |
81 | | insert( |
82 | | size_type pos, |
83 | | InputIt first, |
84 | | InputIt last) -> |
85 | | string& |
86 | | { |
87 | | struct cleanup |
88 | | { |
89 | | detail::string_impl& s; |
90 | | storage_ptr const& sp; |
91 | | |
92 | | ~cleanup() |
93 | | { |
94 | | s.destroy(sp); |
95 | | } |
96 | | }; |
97 | | |
98 | | // We use the default storage because |
99 | | // the allocation is immediately freed. |
100 | | storage_ptr dsp; |
101 | | detail::string_impl tmp( |
102 | | first, last, dsp, |
103 | | iter_cat<InputIt>{}); |
104 | | cleanup c{tmp, dsp}; |
105 | | std::memcpy( |
106 | | impl_.insert_unchecked(pos, tmp.size(), sp_), |
107 | | tmp.data(), |
108 | | tmp.size()); |
109 | | return *this; |
110 | | } |
111 | | |
112 | | // KRYSTIAN TODO: this can be done without copies when |
113 | | // reallocation is not needed, when the iterator is a |
114 | | // FowardIterator or better, as we can use std::distance |
115 | | template<class InputIt, class> |
116 | | auto |
117 | | string:: |
118 | | replace( |
119 | | const_iterator first, |
120 | | const_iterator last, |
121 | | InputIt first2, |
122 | | InputIt last2) -> |
123 | | string& |
124 | | { |
125 | | struct cleanup |
126 | | { |
127 | | detail::string_impl& s; |
128 | | storage_ptr const& sp; |
129 | | |
130 | | ~cleanup() |
131 | | { |
132 | | s.destroy(sp); |
133 | | } |
134 | | }; |
135 | | |
136 | | // We use the default storage because |
137 | | // the allocation is immediately freed. |
138 | | storage_ptr dsp; |
139 | | detail::string_impl tmp( |
140 | | first2, last2, dsp, |
141 | | iter_cat<InputIt>{}); |
142 | | cleanup c{tmp, dsp}; |
143 | | std::memcpy( |
144 | | impl_.replace_unchecked( |
145 | | first - begin(), |
146 | | last - first, |
147 | | tmp.size(), |
148 | | sp_), |
149 | | tmp.data(), |
150 | | tmp.size()); |
151 | | return *this; |
152 | | } |
153 | | |
154 | | //---------------------------------------------------------- |
155 | | |
156 | | template<class InputIt> |
157 | | void |
158 | | string:: |
159 | | assign( |
160 | | InputIt first, |
161 | | InputIt last, |
162 | | std::random_access_iterator_tag) |
163 | | { |
164 | | auto dest = impl_.assign(static_cast< |
165 | | size_type>(last - first), sp_); |
166 | | while(first != last) |
167 | | *dest++ = *first++; |
168 | | } |
169 | | |
170 | | template<class InputIt> |
171 | | void |
172 | | string:: |
173 | | assign( |
174 | | InputIt first, |
175 | | InputIt last, |
176 | | std::input_iterator_tag) |
177 | | { |
178 | | if(first == last) |
179 | | { |
180 | | impl_.term(0); |
181 | | return; |
182 | | } |
183 | | detail::string_impl tmp( |
184 | | first, last, sp_, |
185 | | std::input_iterator_tag{}); |
186 | | impl_.destroy(sp_); |
187 | | impl_ = tmp; |
188 | | } |
189 | | |
190 | | template<class InputIt> |
191 | | void |
192 | | string:: |
193 | | append( |
194 | | InputIt first, |
195 | | InputIt last, |
196 | | std::random_access_iterator_tag) |
197 | | { |
198 | | |
199 | | auto const n = static_cast< |
200 | | size_type>(last - first); |
201 | | char* out = impl_.append(n, sp_); |
202 | | #if defined(_MSC_VER) && _MSC_VER <= 1900 |
203 | | while( first != last ) |
204 | | *out++ = *first++; |
205 | | #else |
206 | | std::copy(first, last, out); |
207 | | #endif |
208 | | } |
209 | | |
210 | | template<class InputIt> |
211 | | void |
212 | | string:: |
213 | | append( |
214 | | InputIt first, |
215 | | InputIt last, |
216 | | std::input_iterator_tag) |
217 | | { |
218 | | struct cleanup |
219 | | { |
220 | | detail::string_impl& s; |
221 | | storage_ptr const& sp; |
222 | | |
223 | | ~cleanup() |
224 | | { |
225 | | s.destroy(sp); |
226 | | } |
227 | | }; |
228 | | |
229 | | // We use the default storage because |
230 | | // the allocation is immediately freed. |
231 | | storage_ptr dsp; |
232 | | detail::string_impl tmp( |
233 | | first, last, dsp, |
234 | | std::input_iterator_tag{}); |
235 | | cleanup c{tmp, dsp}; |
236 | | std::memcpy( |
237 | | impl_.append(tmp.size(), sp_), |
238 | | tmp.data(), tmp.size()); |
239 | | } |
240 | | |
241 | | char& |
242 | | string::at(std::size_t pos, source_location const& loc) |
243 | 0 | { |
244 | 0 |
|
245 | 0 | auto const& self = *this; |
246 | 0 | return const_cast< char& >( self.at(pos, loc) ); |
247 | 0 | } |
248 | | |
249 | | } // namespace json |
250 | | } // namespace boost |
251 | | |
252 | | #endif |