| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // | ||
| 2 | // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) | ||
| 3 | // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com) | ||
| 4 | // | ||
| 5 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | ||
| 6 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
| 7 | // | ||
| 8 | // Official repository: https://github.com/boostorg/json | ||
| 9 | // | ||
| 10 | |||
| 11 | #ifndef BOOST_JSON_DETAIL_IMPL_STRING_IMPL_IPP | ||
| 12 | #define BOOST_JSON_DETAIL_IMPL_STRING_IMPL_IPP | ||
| 13 | |||
| 14 | #include <boost/json/detail/string_impl.hpp> | ||
| 15 | #include <boost/json/detail/except.hpp> | ||
| 16 | #include <cstring> | ||
| 17 | #include <functional> | ||
| 18 | |||
| 19 | namespace boost { | ||
| 20 | namespace json { | ||
| 21 | namespace detail { | ||
| 22 | |||
| 23 | inline | ||
| 24 | bool | ||
| 25 | 23 | ptr_in_range( | |
| 26 | const char* first, | ||
| 27 | const char* last, | ||
| 28 | const char* ptr) noexcept | ||
| 29 | { | ||
| 30 |
4/4✓ Branch 1 taken 14 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 10 times.
✓ Branch 4 taken 4 times.
|
37 | return std::less<const char*>()(ptr, last) && |
| 31 | 37 | std::greater_equal<const char*>()(ptr, first); | |
| 32 | } | ||
| 33 | |||
| 34 | 31403 | string_impl:: | |
| 35 | 31403 | string_impl() noexcept | |
| 36 | { | ||
| 37 | 31403 | s_.k = short_string_; | |
| 38 | 31403 | s_.buf[sbo_chars_] = | |
| 39 | static_cast<char>( | ||
| 40 | sbo_chars_); | ||
| 41 | 31403 | s_.buf[0] = 0; | |
| 42 | 31403 | } | |
| 43 | |||
| 44 | 26901 | string_impl:: | |
| 45 | string_impl( | ||
| 46 | std::size_t size, | ||
| 47 | 26901 | storage_ptr const& sp) | |
| 48 | { | ||
| 49 |
2/2✓ Branch 0 taken 41 times.
✓ Branch 1 taken 26860 times.
|
26901 | if(size <= sbo_chars_) |
| 50 | { | ||
| 51 | 41 | s_.k = short_string_; | |
| 52 | 41 | s_.buf[sbo_chars_] = | |
| 53 | static_cast<char>( | ||
| 54 | 41 | sbo_chars_ - size); | |
| 55 | 41 | s_.buf[size] = 0; | |
| 56 | } | ||
| 57 | else | ||
| 58 | { | ||
| 59 | 26860 | s_.k = kind::string; | |
| 60 | 26860 | auto const n = growth( | |
| 61 | size, sbo_chars_ + 1); | ||
| 62 | 26860 | p_.t = ::new(sp->allocate( | |
| 63 | sizeof(table) + | ||
| 64 | 26860 | n + 1, | |
| 65 | alignof(table))) table{ | ||
| 66 | static_cast< | ||
| 67 | std::uint32_t>(size), | ||
| 68 | static_cast< | ||
| 69 | 26673 | std::uint32_t>(n)}; | |
| 70 | 26673 | data()[n] = 0; | |
| 71 | } | ||
| 72 | 26714 | } | |
| 73 | |||
| 74 | // construct a key, unchecked | ||
| 75 | 30296 | string_impl:: | |
| 76 | string_impl( | ||
| 77 | key_t, | ||
| 78 | string_view s, | ||
| 79 | 30296 | storage_ptr const& sp) | |
| 80 | { | ||
| 81 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 30296 times.
|
30296 | BOOST_ASSERT( |
| 82 | s.size() <= max_size()); | ||
| 83 | 30296 | k_.k = key_string_; | |
| 84 | 30296 | k_.n = static_cast< | |
| 85 | 30296 | std::uint32_t>(s.size()); | |
| 86 | 30236 | k_.s = reinterpret_cast<char*>( | |
| 87 | 30296 | sp->allocate(s.size() + 1, | |
| 88 | alignof(char))); | ||
| 89 | 30236 | k_.s[s.size()] = 0; // null term | |
| 90 | 30236 | std::memcpy(&k_.s[0], | |
| 91 | 30236 | s.data(), s.size()); | |
| 92 | 30236 | } | |
| 93 | |||
| 94 | // construct a key, unchecked | ||
| 95 | 8060 | string_impl:: | |
| 96 | string_impl( | ||
| 97 | key_t, | ||
| 98 | string_view s1, | ||
| 99 | string_view s2, | ||
| 100 | 8060 | storage_ptr const& sp) | |
| 101 | { | ||
| 102 | 8060 | auto len = s1.size() + s2.size(); | |
| 103 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8060 times.
|
8060 | BOOST_ASSERT(len <= max_size()); |
| 104 | 8060 | k_.k = key_string_; | |
| 105 | 8060 | k_.n = static_cast< | |
| 106 | std::uint32_t>(len); | ||
| 107 | 8060 | k_.s = reinterpret_cast<char*>( | |
| 108 | 8060 | sp->allocate(len + 1, | |
| 109 | alignof(char))); | ||
| 110 | 8060 | k_.s[len] = 0; // null term | |
| 111 | 8060 | std::memcpy(&k_.s[0], | |
| 112 | 8060 | s1.data(), s1.size()); | |
| 113 | 16120 | std::memcpy(&k_.s[s1.size()], | |
| 114 | 8060 | s2.data(), s2.size()); | |
| 115 | 8060 | } | |
| 116 | |||
| 117 | std::uint32_t | ||
| 118 | 53714 | string_impl:: | |
| 119 | growth( | ||
| 120 | std::size_t new_size, | ||
| 121 | std::size_t capacity) | ||
| 122 | { | ||
| 123 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 53713 times.
|
53714 | if(new_size > max_size()) |
| 124 | { | ||
| 125 | BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; | ||
| 126 | 1 | detail::throw_system_error( error::string_too_large, &loc ); | |
| 127 | } | ||
| 128 | // growth factor 2 | ||
| 129 | 53713 | if( capacity > | |
| 130 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 53713 times.
|
53713 | max_size() - capacity) |
| 131 | return static_cast< | ||
| 132 | ✗ | std::uint32_t>(max_size()); // overflow | |
| 133 | return static_cast<std::uint32_t>( | ||
| 134 | 53713 | (std::max)(capacity * 2, new_size)); | |
| 135 | } | ||
| 136 | |||
| 137 | char* | ||
| 138 | 18614 | string_impl:: | |
| 139 | assign( | ||
| 140 | std::size_t new_size, | ||
| 141 | storage_ptr const& sp) | ||
| 142 | { | ||
| 143 |
2/2✓ Branch 1 taken 17092 times.
✓ Branch 2 taken 1522 times.
|
18614 | if(new_size > capacity()) |
| 144 | { | ||
| 145 |
1/1✓ Branch 2 taken 17092 times.
|
17092 | string_impl tmp(growth( |
| 146 | new_size, | ||
| 147 |
1/1✓ Branch 1 taken 16951 times.
|
17092 | capacity()), sp); |
| 148 | 16951 | destroy(sp); | |
| 149 | 16951 | *this = tmp; | |
| 150 | } | ||
| 151 | 18473 | term(new_size); | |
| 152 | 18473 | return data(); | |
| 153 | } | ||
| 154 | |||
| 155 | char* | ||
| 156 | 154 | string_impl:: | |
| 157 | append( | ||
| 158 | std::size_t n, | ||
| 159 | storage_ptr const& sp) | ||
| 160 | { | ||
| 161 |
2/2✓ Branch 2 taken 1 times.
✓ Branch 3 taken 153 times.
|
154 | if(n > max_size() - size()) |
| 162 | { | ||
| 163 | BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; | ||
| 164 | 1 | detail::throw_system_error( error::string_too_large, &loc ); | |
| 165 | } | ||
| 166 |
2/2✓ Branch 2 taken 107 times.
✓ Branch 3 taken 46 times.
|
153 | if(n <= capacity() - size()) |
| 167 | { | ||
| 168 | 107 | term(size() + n); | |
| 169 | 107 | return end() - n; | |
| 170 | } | ||
| 171 |
1/1✓ Branch 2 taken 46 times.
|
92 | string_impl tmp(growth( |
| 172 |
1/1✓ Branch 2 taken 27 times.
|
92 | size() + n, capacity()), sp); |
| 173 | 27 | std::memcpy( | |
| 174 | 27 | tmp.data(), data(), size()); | |
| 175 | 27 | tmp.term(size() + n); | |
| 176 | 27 | destroy(sp); | |
| 177 | 27 | *this = tmp; | |
| 178 | 27 | return end() - n; | |
| 179 | } | ||
| 180 | |||
| 181 | void | ||
| 182 | 27 | string_impl:: | |
| 183 | insert( | ||
| 184 | std::size_t pos, | ||
| 185 | const char* s, | ||
| 186 | std::size_t n, | ||
| 187 | storage_ptr const& sp) | ||
| 188 | { | ||
| 189 | 27 | const auto curr_size = size(); | |
| 190 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 25 times.
|
27 | if(pos > curr_size) |
| 191 | { | ||
| 192 | BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; | ||
| 193 | 2 | detail::throw_system_error( error::out_of_range, &loc ); | |
| 194 | } | ||
| 195 | 25 | const auto curr_data = data(); | |
| 196 |
2/2✓ Branch 1 taken 10 times.
✓ Branch 2 taken 15 times.
|
25 | if(n <= capacity() - curr_size) |
| 197 | { | ||
| 198 | 10 | const bool inside = detail::ptr_in_range(curr_data, curr_data + curr_size, s); | |
| 199 |
5/6✓ Branch 0 taken 3 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 2 times.
|
10 | if (!inside || (inside && ((s - curr_data) + n <= pos))) |
| 200 | { | ||
| 201 | 8 | std::memmove(&curr_data[pos + n], &curr_data[pos], curr_size - pos + 1); | |
| 202 | 8 | std::memcpy(&curr_data[pos], s, n); | |
| 203 | } | ||
| 204 | else | ||
| 205 | { | ||
| 206 | 2 | const std::size_t offset = s - curr_data; | |
| 207 | 2 | std::memmove(&curr_data[pos + n], &curr_data[pos], curr_size - pos + 1); | |
| 208 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
2 | if (offset < pos) |
| 209 | { | ||
| 210 | 1 | const std::size_t diff = pos - offset; | |
| 211 | 1 | std::memcpy(&curr_data[pos], &curr_data[offset], diff); | |
| 212 | 1 | std::memcpy(&curr_data[pos + diff], &curr_data[pos + n], n - diff); | |
| 213 | } | ||
| 214 | else | ||
| 215 | { | ||
| 216 | 1 | std::memcpy(&curr_data[pos], &curr_data[offset + n], n); | |
| 217 | } | ||
| 218 | } | ||
| 219 | 10 | size(curr_size + n); | |
| 220 | } | ||
| 221 | else | ||
| 222 | { | ||
| 223 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 14 times.
|
15 | if(n > max_size() - curr_size) |
| 224 | { | ||
| 225 | BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; | ||
| 226 | 1 | detail::throw_system_error( error::string_too_large, &loc ); | |
| 227 | } | ||
| 228 |
1/1✓ Branch 2 taken 14 times.
|
14 | string_impl tmp(growth( |
| 229 |
1/1✓ Branch 1 taken 7 times.
|
14 | curr_size + n, capacity()), sp); |
| 230 | 7 | tmp.size(curr_size + n); | |
| 231 | 7 | std::memcpy( | |
| 232 | 7 | tmp.data(), | |
| 233 | curr_data, | ||
| 234 | pos); | ||
| 235 | 14 | std::memcpy( | |
| 236 | 14 | tmp.data() + pos + n, | |
| 237 | curr_data + pos, | ||
| 238 | 7 | curr_size + 1 - pos); | |
| 239 | 7 | std::memcpy( | |
| 240 | 7 | tmp.data() + pos, | |
| 241 | s, | ||
| 242 | n); | ||
| 243 | 7 | destroy(sp); | |
| 244 | 7 | *this = tmp; | |
| 245 | } | ||
| 246 | 17 | } | |
| 247 | |||
| 248 | char* | ||
| 249 | 17 | string_impl:: | |
| 250 | insert_unchecked( | ||
| 251 | std::size_t pos, | ||
| 252 | std::size_t n, | ||
| 253 | storage_ptr const& sp) | ||
| 254 | { | ||
| 255 | 17 | const auto curr_size = size(); | |
| 256 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 16 times.
|
17 | if(pos > curr_size) |
| 257 | { | ||
| 258 | BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; | ||
| 259 | 1 | detail::throw_system_error( error::out_of_range, &loc ); | |
| 260 | } | ||
| 261 | 16 | const auto curr_data = data(); | |
| 262 |
2/2✓ Branch 2 taken 5 times.
✓ Branch 3 taken 11 times.
|
16 | if(n <= capacity() - size()) |
| 263 | { | ||
| 264 | 5 | auto const dest = | |
| 265 | curr_data + pos; | ||
| 266 | 5 | std::memmove( | |
| 267 | dest + n, | ||
| 268 | dest, | ||
| 269 | 5 | curr_size + 1 - pos); | |
| 270 | 5 | size(curr_size + n); | |
| 271 | 5 | return dest; | |
| 272 | } | ||
| 273 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 10 times.
|
11 | if(n > max_size() - curr_size) |
| 274 | { | ||
| 275 | BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; | ||
| 276 | 1 | detail::throw_system_error( error::string_too_large, &loc ); | |
| 277 | } | ||
| 278 |
1/1✓ Branch 2 taken 10 times.
|
10 | string_impl tmp(growth( |
| 279 |
1/1✓ Branch 1 taken 5 times.
|
10 | curr_size + n, capacity()), sp); |
| 280 | 5 | tmp.size(curr_size + n); | |
| 281 | 5 | std::memcpy( | |
| 282 | 5 | tmp.data(), | |
| 283 | curr_data, | ||
| 284 | pos); | ||
| 285 | 10 | std::memcpy( | |
| 286 | 10 | tmp.data() + pos + n, | |
| 287 | curr_data + pos, | ||
| 288 | 5 | curr_size + 1 - pos); | |
| 289 | 5 | destroy(sp); | |
| 290 | 5 | *this = tmp; | |
| 291 | 5 | return data() + pos; | |
| 292 | } | ||
| 293 | |||
| 294 | void | ||
| 295 | 19 | string_impl:: | |
| 296 | replace( | ||
| 297 | std::size_t pos, | ||
| 298 | std::size_t n1, | ||
| 299 | const char* s, | ||
| 300 | std::size_t n2, | ||
| 301 | storage_ptr const& sp) | ||
| 302 | { | ||
| 303 | 19 | const auto curr_size = size(); | |
| 304 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 18 times.
|
19 | if (pos > curr_size) |
| 305 | { | ||
| 306 | BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; | ||
| 307 | 1 | detail::throw_system_error( error::out_of_range, &loc ); | |
| 308 | } | ||
| 309 | 18 | const auto curr_data = data(); | |
| 310 | 18 | n1 = (std::min)(n1, curr_size - pos); | |
| 311 | 18 | const auto delta = (std::max)(n1, n2) - | |
| 312 | 18 | (std::min)(n1, n2); | |
| 313 | // if we are shrinking in size or we have enough | ||
| 314 | // capacity, dont reallocate | ||
| 315 |
6/6✓ Branch 0 taken 14 times.
✓ Branch 1 taken 4 times.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 13 times.
✓ Branch 6 taken 5 times.
|
18 | if (n1 > n2 || delta <= capacity() - curr_size) |
| 316 | { | ||
| 317 | 13 | const bool inside = detail::ptr_in_range(curr_data, curr_data + curr_size, s); | |
| 318 | // there is nothing to replace; return | ||
| 319 |
5/6✓ Branch 0 taken 7 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
13 | if (inside && s == curr_data + pos && n1 == n2) |
| 320 | 1 | return; | |
| 321 |
4/6✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
|
12 | if (!inside || (inside && ((s - curr_data) + n2 <= pos))) |
| 322 | { | ||
| 323 | // source outside | ||
| 324 | 6 | std::memmove(&curr_data[pos + n2], &curr_data[pos + n1], curr_size - pos - n1 + 1); | |
| 325 | 6 | std::memcpy(&curr_data[pos], s, n2); | |
| 326 | } | ||
| 327 | else | ||
| 328 | { | ||
| 329 | // source inside | ||
| 330 | 6 | const std::size_t offset = s - curr_data; | |
| 331 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
|
6 | if (n2 >= n1) |
| 332 | { | ||
| 333 | // grow/unchanged | ||
| 334 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | const std::size_t diff = offset <= pos + n1 ? (std::min)((pos + n1) - offset, n2) : 0; |
| 335 | // shift all right of splice point by n2 - n1 to the right | ||
| 336 | 4 | std::memmove(&curr_data[pos + n2], &curr_data[pos + n1], curr_size - pos - n1 + 1); | |
| 337 | // copy all before splice point | ||
| 338 | 4 | std::memmove(&curr_data[pos], &curr_data[offset], diff); | |
| 339 | // copy all after splice point | ||
| 340 | 4 | std::memmove(&curr_data[pos + diff], &curr_data[(offset - n1) + n2 + diff], n2 - diff); | |
| 341 | } | ||
| 342 | else | ||
| 343 | { | ||
| 344 | // shrink | ||
| 345 | // copy all elements into place | ||
| 346 | 2 | std::memmove(&curr_data[pos], &curr_data[offset], n2); | |
| 347 | // shift all elements after splice point left | ||
| 348 | 2 | std::memmove(&curr_data[pos + n2], &curr_data[pos + n1], curr_size - pos - n1 + 1); | |
| 349 | } | ||
| 350 | } | ||
| 351 | 12 | size((curr_size - n1) + n2); | |
| 352 | } | ||
| 353 | else | ||
| 354 | { | ||
| 355 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 4 times.
|
5 | if (delta > max_size() - curr_size) |
| 356 | { | ||
| 357 | BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; | ||
| 358 | 1 | detail::throw_system_error( error::string_too_large, &loc ); | |
| 359 | } | ||
| 360 | // would exceed capacity, reallocate | ||
| 361 |
1/1✓ Branch 2 taken 4 times.
|
4 | string_impl tmp(growth( |
| 362 |
1/1✓ Branch 1 taken 2 times.
|
4 | curr_size + delta, capacity()), sp); |
| 363 | 2 | tmp.size(curr_size + delta); | |
| 364 | 2 | std::memcpy( | |
| 365 | 2 | tmp.data(), | |
| 366 | curr_data, | ||
| 367 | pos); | ||
| 368 | 4 | std::memcpy( | |
| 369 | 4 | tmp.data() + pos + n2, | |
| 370 | 2 | curr_data + pos + n1, | |
| 371 | 2 | curr_size - pos - n1 + 1); | |
| 372 | 4 | std::memcpy( | |
| 373 | 2 | tmp.data() + pos, | |
| 374 | s, | ||
| 375 | n2); | ||
| 376 | 2 | destroy(sp); | |
| 377 | 2 | *this = tmp; | |
| 378 | } | ||
| 379 | } | ||
| 380 | |||
| 381 | // unlike the replace overload, this function does | ||
| 382 | // not move any characters | ||
| 383 | char* | ||
| 384 | 7 | string_impl:: | |
| 385 | replace_unchecked( | ||
| 386 | std::size_t pos, | ||
| 387 | std::size_t n1, | ||
| 388 | std::size_t n2, | ||
| 389 | storage_ptr const& sp) | ||
| 390 | { | ||
| 391 | 7 | const auto curr_size = size(); | |
| 392 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
|
7 | if(pos > curr_size) |
| 393 | { | ||
| 394 | BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; | ||
| 395 | 1 | detail::throw_system_error( error::out_of_range, &loc ); | |
| 396 | } | ||
| 397 | 6 | const auto curr_data = data(); | |
| 398 | 6 | const auto delta = (std::max)(n1, n2) - | |
| 399 | 6 | (std::min)(n1, n2); | |
| 400 | // if the size doesn't change, we don't need to | ||
| 401 | // do anything | ||
| 402 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
|
6 | if (!delta) |
| 403 | 1 | return curr_data + pos; | |
| 404 | // if we are shrinking in size or we have enough | ||
| 405 | // capacity, dont reallocate | ||
| 406 |
5/6✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 3 times.
|
5 | if(n1 > n2 || delta <= capacity() - curr_size) |
| 407 | { | ||
| 408 | 2 | auto const replace_pos = curr_data + pos; | |
| 409 | 2 | std::memmove( | |
| 410 | 2 | replace_pos + n2, | |
| 411 | 2 | replace_pos + n1, | |
| 412 | 2 | curr_size - pos - n1 + 1); | |
| 413 | 2 | size((curr_size - n1) + n2); | |
| 414 | 2 | return replace_pos; | |
| 415 | } | ||
| 416 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
|
3 | if(delta > max_size() - curr_size) |
| 417 | { | ||
| 418 | BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; | ||
| 419 | 1 | detail::throw_system_error( error::string_too_large, &loc ); | |
| 420 | } | ||
| 421 | // would exceed capacity, reallocate | ||
| 422 |
1/1✓ Branch 2 taken 2 times.
|
2 | string_impl tmp(growth( |
| 423 |
1/1✓ Branch 1 taken 1 times.
|
2 | curr_size + delta, capacity()), sp); |
| 424 | 1 | tmp.size(curr_size + delta); | |
| 425 | 1 | std::memcpy( | |
| 426 | 1 | tmp.data(), | |
| 427 | curr_data, | ||
| 428 | pos); | ||
| 429 | 2 | std::memcpy( | |
| 430 | 2 | tmp.data() + pos + n2, | |
| 431 | 1 | curr_data + pos + n1, | |
| 432 | 1 | curr_size - pos - n1 + 1); | |
| 433 | 1 | destroy(sp); | |
| 434 | 1 | *this = tmp; | |
| 435 | 1 | return data() + pos; | |
| 436 | } | ||
| 437 | |||
| 438 | void | ||
| 439 | 7 | string_impl:: | |
| 440 | shrink_to_fit( | ||
| 441 | storage_ptr const& sp) noexcept | ||
| 442 | { | ||
| 443 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 4 times.
|
7 | if(s_.k == short_string_) |
| 444 | 3 | return; | |
| 445 | 4 | auto const t = p_.t; | |
| 446 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | if(t->size <= sbo_chars_) |
| 447 | { | ||
| 448 | 2 | s_.k = short_string_; | |
| 449 | 4 | std::memcpy( | |
| 450 | 2 | s_.buf, data(), t->size); | |
| 451 | 2 | s_.buf[sbo_chars_] = | |
| 452 | static_cast<char>( | ||
| 453 | 2 | sbo_chars_ - t->size); | |
| 454 | 2 | s_.buf[t->size] = 0; | |
| 455 | 2 | sp->deallocate(t, | |
| 456 | sizeof(table) + | ||
| 457 | 2 | t->capacity + 1, | |
| 458 | alignof(table)); | ||
| 459 | 2 | return; | |
| 460 | } | ||
| 461 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if(t->size >= t->capacity) |
| 462 | ✗ | return; | |
| 463 | #ifndef BOOST_NO_EXCEPTIONS | ||
| 464 | try | ||
| 465 | { | ||
| 466 | #endif | ||
| 467 |
1/1✓ Branch 1 taken 1 times.
|
2 | string_impl tmp(t->size, sp); |
| 468 | 1 | std::memcpy( | |
| 469 | 1 | tmp.data(), | |
| 470 | 1 | data(), | |
| 471 | size()); | ||
| 472 | 1 | destroy(sp); | |
| 473 | 1 | *this = tmp; | |
| 474 | #ifndef BOOST_NO_EXCEPTIONS | ||
| 475 | } | ||
| 476 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | catch(std::exception const&) |
| 477 | { | ||
| 478 | // eat the exception | ||
| 479 | 1 | } | |
| 480 | #endif | ||
| 481 | } | ||
| 482 | |||
| 483 | } // detail | ||
| 484 | } // namespace json | ||
| 485 | } // namespace boost | ||
| 486 | |||
| 487 | #endif | ||
| 488 |