| Line | Branch | Exec | Source |
|---|---|---|---|
| 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_IPP | ||
| 11 | #define BOOST_JSON_IMPL_STRING_IPP | ||
| 12 | |||
| 13 | #include <boost/json/detail/except.hpp> | ||
| 14 | #include <algorithm> | ||
| 15 | #include <new> | ||
| 16 | #include <ostream> | ||
| 17 | #include <stdexcept> | ||
| 18 | #include <string> | ||
| 19 | #include <utility> | ||
| 20 | |||
| 21 | namespace boost { | ||
| 22 | namespace json { | ||
| 23 | |||
| 24 | //---------------------------------------------------------- | ||
| 25 | // | ||
| 26 | // Construction | ||
| 27 | // | ||
| 28 | //---------------------------------------------------------- | ||
| 29 | |||
| 30 | 78 | string:: | |
| 31 | string( | ||
| 32 | std::size_t count, | ||
| 33 | char ch, | ||
| 34 | 78 | storage_ptr sp) | |
| 35 | 78 | : sp_(std::move(sp)) | |
| 36 | { | ||
| 37 |
1/1✓ Branch 1 taken 60 times.
|
78 | assign(count, ch); |
| 38 | 78 | } | |
| 39 | |||
| 40 | 203 | string:: | |
| 41 | string( | ||
| 42 | char const* s, | ||
| 43 | 203 | storage_ptr sp) | |
| 44 | 203 | : sp_(std::move(sp)) | |
| 45 | { | ||
| 46 |
1/1✓ Branch 1 taken 202 times.
|
203 | assign(s); |
| 47 | 203 | } | |
| 48 | |||
| 49 | 4 | string:: | |
| 50 | string( | ||
| 51 | char const* s, | ||
| 52 | std::size_t count, | ||
| 53 | 4 | storage_ptr sp) | |
| 54 | 4 | : sp_(std::move(sp)) | |
| 55 | { | ||
| 56 |
1/1✓ Branch 1 taken 4 times.
|
4 | assign(s, count); |
| 57 | 4 | } | |
| 58 | |||
| 59 | 8 | string:: | |
| 60 | 8 | string(string const& other) | |
| 61 | 8 | : sp_(other.sp_) | |
| 62 | { | ||
| 63 |
1/1✓ Branch 1 taken 8 times.
|
8 | assign(other); |
| 64 | 8 | } | |
| 65 | |||
| 66 | 151 | string:: | |
| 67 | string( | ||
| 68 | string const& other, | ||
| 69 | 151 | storage_ptr sp) | |
| 70 | 151 | : sp_(std::move(sp)) | |
| 71 | { | ||
| 72 |
1/1✓ Branch 1 taken 133 times.
|
151 | assign(other); |
| 73 | 151 | } | |
| 74 | |||
| 75 | 469 | string:: | |
| 76 | string( | ||
| 77 | string&& other, | ||
| 78 | 469 | storage_ptr sp) | |
| 79 | 469 | : sp_(std::move(sp)) | |
| 80 | { | ||
| 81 |
1/1✓ Branch 2 taken 464 times.
|
469 | assign(std::move(other)); |
| 82 | 469 | } | |
| 83 | |||
| 84 | 17954 | string:: | |
| 85 | string( | ||
| 86 | string_view s, | ||
| 87 | 17954 | storage_ptr sp) | |
| 88 | 17954 | : sp_(std::move(sp)) | |
| 89 | { | ||
| 90 |
1/1✓ Branch 1 taken 17865 times.
|
17954 | assign(s); |
| 91 | 17954 | } | |
| 92 | |||
| 93 | //---------------------------------------------------------- | ||
| 94 | // | ||
| 95 | // Assignment | ||
| 96 | // | ||
| 97 | //---------------------------------------------------------- | ||
| 98 | |||
| 99 | string& | ||
| 100 | 6 | string:: | |
| 101 | operator=(string const& other) | ||
| 102 | { | ||
| 103 | 6 | return assign(other); | |
| 104 | } | ||
| 105 | |||
| 106 | string& | ||
| 107 | 10 | string:: | |
| 108 | operator=(string&& other) | ||
| 109 | { | ||
| 110 | 10 | return assign(std::move(other)); | |
| 111 | } | ||
| 112 | |||
| 113 | string& | ||
| 114 | 9 | string:: | |
| 115 | operator=(char const* s) | ||
| 116 | { | ||
| 117 | 9 | return assign(s); | |
| 118 | } | ||
| 119 | |||
| 120 | string& | ||
| 121 | 8 | string:: | |
| 122 | operator=(string_view s) | ||
| 123 | { | ||
| 124 | 8 | return assign(s); | |
| 125 | } | ||
| 126 | |||
| 127 | |||
| 128 | |||
| 129 | string& | ||
| 130 | 83 | string:: | |
| 131 | assign( | ||
| 132 | size_type count, | ||
| 133 | char ch) | ||
| 134 | { | ||
| 135 | 64 | std::char_traits<char>::assign( | |
| 136 | 83 | impl_.assign(count, sp_), | |
| 137 | count, | ||
| 138 | ch); | ||
| 139 | 64 | return *this; | |
| 140 | } | ||
| 141 | |||
| 142 | string& | ||
| 143 | 199 | string:: | |
| 144 | assign( | ||
| 145 | string const& other) | ||
| 146 | { | ||
| 147 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 198 times.
|
199 | if(this == &other) |
| 148 | 1 | return *this; | |
| 149 | 198 | return assign( | |
| 150 | other.data(), | ||
| 151 | 171 | other.size()); | |
| 152 | } | ||
| 153 | |||
| 154 | string& | ||
| 155 | 493 | string:: | |
| 156 | assign(string&& other) | ||
| 157 | { | ||
| 158 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 492 times.
|
493 | if( &other == this ) |
| 159 | 1 | return *this; | |
| 160 | |||
| 161 |
2/2✓ Branch 3 taken 458 times.
✓ Branch 4 taken 34 times.
|
492 | if(*sp_ == *other.sp_) |
| 162 | { | ||
| 163 | 458 | impl_.destroy(sp_); | |
| 164 | 458 | impl_ = other.impl_; | |
| 165 | 458 | ::new(&other.impl_) detail::string_impl(); | |
| 166 | 458 | return *this; | |
| 167 | } | ||
| 168 | |||
| 169 | // copy | ||
| 170 | 34 | return assign(other); | |
| 171 | } | ||
| 172 | |||
| 173 | string& | ||
| 174 | 18525 | string:: | |
| 175 | assign( | ||
| 176 | char const* s, | ||
| 177 | size_type count) | ||
| 178 | { | ||
| 179 | 18404 | std::char_traits<char>::copy( | |
| 180 | 18525 | impl_.assign(count, sp_), | |
| 181 | s, count); | ||
| 182 | 18404 | return *this; | |
| 183 | } | ||
| 184 | |||
| 185 | string& | ||
| 186 | 217 | string:: | |
| 187 | assign( | ||
| 188 | char const* s) | ||
| 189 | { | ||
| 190 | 217 | return assign(s, std::char_traits< | |
| 191 | 214 | char>::length(s)); | |
| 192 | } | ||
| 193 | |||
| 194 | //---------------------------------------------------------- | ||
| 195 | // | ||
| 196 | // Capacity | ||
| 197 | // | ||
| 198 | //---------------------------------------------------------- | ||
| 199 | |||
| 200 | void | ||
| 201 | 7 | string:: | |
| 202 | shrink_to_fit() | ||
| 203 | { | ||
| 204 | 7 | impl_.shrink_to_fit(sp_); | |
| 205 | 7 | } | |
| 206 | |||
| 207 | //---------------------------------------------------------- | ||
| 208 | // | ||
| 209 | // Access | ||
| 210 | // | ||
| 211 | //---------------------------------------------------------- | ||
| 212 | |||
| 213 | system::result<char&> | ||
| 214 | 12 | string::try_at(std::size_t pos) noexcept | |
| 215 | { | ||
| 216 |
2/2✓ Branch 1 taken 10 times.
✓ Branch 2 taken 2 times.
|
12 | if( pos < size() ) |
| 217 | 10 | return impl_.data()[pos]; | |
| 218 | |||
| 219 | 2 | system::error_code ec; | |
| 220 | 2 | BOOST_JSON_FAIL(ec, error::out_of_range); | |
| 221 | 2 | return ec; | |
| 222 | } | ||
| 223 | |||
| 224 | system::result<char const&> | ||
| 225 | 20 | string::try_at(std::size_t pos) const noexcept | |
| 226 | { | ||
| 227 |
2/2✓ Branch 1 taken 18 times.
✓ Branch 2 taken 2 times.
|
20 | if( pos < size() ) |
| 228 | 18 | return impl_.data()[pos]; | |
| 229 | |||
| 230 | 2 | system::error_code ec; | |
| 231 | 2 | BOOST_JSON_FAIL(ec, error::out_of_range); | |
| 232 | 2 | return ec; | |
| 233 | } | ||
| 234 | |||
| 235 | char const& | ||
| 236 | 18 | string::at(std::size_t pos, source_location const& loc) const | |
| 237 | { | ||
| 238 |
1/1✓ Branch 2 taken 16 times.
|
18 | return try_at(pos).value(loc); |
| 239 | } | ||
| 240 | |||
| 241 | //---------------------------------------------------------- | ||
| 242 | // | ||
| 243 | // Operations | ||
| 244 | // | ||
| 245 | //---------------------------------------------------------- | ||
| 246 | |||
| 247 | void | ||
| 248 | 2 | string:: | |
| 249 | clear() noexcept | ||
| 250 | { | ||
| 251 | 2 | impl_.term(0); | |
| 252 | 2 | } | |
| 253 | |||
| 254 | //---------------------------------------------------------- | ||
| 255 | |||
| 256 | void | ||
| 257 | 88 | string:: | |
| 258 | push_back(char ch) | ||
| 259 | { | ||
| 260 | 88 | *impl_.append(1, sp_) = ch; | |
| 261 | 86 | } | |
| 262 | |||
| 263 | void | ||
| 264 | 29 | string:: | |
| 265 | pop_back() | ||
| 266 | { | ||
| 267 | 29 | back() = 0; | |
| 268 | 29 | impl_.size(impl_.size() - 1); | |
| 269 | 29 | } | |
| 270 | |||
| 271 | //---------------------------------------------------------- | ||
| 272 | |||
| 273 | string& | ||
| 274 | 4 | string:: | |
| 275 | append(size_type count, char ch) | ||
| 276 | { | ||
| 277 | 2 | std::char_traits<char>::assign( | |
| 278 | 4 | impl_.append(count, sp_), | |
| 279 | count, ch); | ||
| 280 | 2 | return *this; | |
| 281 | } | ||
| 282 | |||
| 283 | string& | ||
| 284 | 45 | string:: | |
| 285 | append(string_view sv) | ||
| 286 | { | ||
| 287 | 90 | std::char_traits<char>::copy( | |
| 288 | 45 | impl_.append(sv.size(), sp_), | |
| 289 | sv.data(), sv.size()); | ||
| 290 | 34 | return *this; | |
| 291 | } | ||
| 292 | |||
| 293 | //---------------------------------------------------------- | ||
| 294 | |||
| 295 | string& | ||
| 296 | 27 | string:: | |
| 297 | insert( | ||
| 298 | size_type pos, | ||
| 299 | string_view sv) | ||
| 300 | { | ||
| 301 | 27 | impl_.insert(pos, sv.data(), sv.size(), sp_); | |
| 302 | 17 | return *this; | |
| 303 | } | ||
| 304 | |||
| 305 | string& | ||
| 306 | 11 | string:: | |
| 307 | insert( | ||
| 308 | std::size_t pos, | ||
| 309 | std::size_t count, | ||
| 310 | char ch) | ||
| 311 | { | ||
| 312 | 6 | std::char_traits<char>::assign( | |
| 313 | 11 | impl_.insert_unchecked(pos, count, sp_), | |
| 314 | count, ch); | ||
| 315 | 6 | return *this; | |
| 316 | } | ||
| 317 | |||
| 318 | //---------------------------------------------------------- | ||
| 319 | |||
| 320 | string& | ||
| 321 | 19 | string:: | |
| 322 | replace( | ||
| 323 | std::size_t pos, | ||
| 324 | std::size_t count, | ||
| 325 | string_view sv) | ||
| 326 | { | ||
| 327 | 19 | impl_.replace(pos, count, sv.data(), sv.size(), sp_); | |
| 328 | 15 | return *this; | |
| 329 | } | ||
| 330 | |||
| 331 | string& | ||
| 332 | 7 | string:: | |
| 333 | replace( | ||
| 334 | std::size_t pos, | ||
| 335 | std::size_t count, | ||
| 336 | std::size_t count2, | ||
| 337 | char ch) | ||
| 338 | { | ||
| 339 | 4 | std::char_traits<char>::assign( | |
| 340 | 7 | impl_.replace_unchecked(pos, count, count2, sp_), | |
| 341 | count2, ch); | ||
| 342 | 4 | return *this; | |
| 343 | } | ||
| 344 | |||
| 345 | //---------------------------------------------------------- | ||
| 346 | |||
| 347 | string& | ||
| 348 | 10 | string:: | |
| 349 | erase( | ||
| 350 | size_type pos, | ||
| 351 | size_type count) | ||
| 352 | { | ||
| 353 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 9 times.
|
10 | if(pos > impl_.size()) |
| 354 | { | ||
| 355 | BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; | ||
| 356 | 1 | detail::throw_system_error( error::out_of_range, &loc ); | |
| 357 | } | ||
| 358 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 5 times.
|
9 | if( count > impl_.size() - pos) |
| 359 | 4 | count = impl_.size() - pos; | |
| 360 | 9 | std::char_traits<char>::move( | |
| 361 | 9 | impl_.data() + pos, | |
| 362 | 9 | impl_.data() + pos + count, | |
| 363 | 9 | impl_.size() - pos - count + 1); | |
| 364 | 9 | impl_.term(impl_.size() - count); | |
| 365 | 9 | return *this; | |
| 366 | } | ||
| 367 | |||
| 368 | auto | ||
| 369 | 2 | string:: | |
| 370 | erase(const_iterator pos) -> | ||
| 371 | iterator | ||
| 372 | { | ||
| 373 | 2 | return erase(pos, pos+1); | |
| 374 | } | ||
| 375 | |||
| 376 | auto | ||
| 377 | 3 | string:: | |
| 378 | erase( | ||
| 379 | const_iterator first, | ||
| 380 | const_iterator last) -> | ||
| 381 | iterator | ||
| 382 | { | ||
| 383 | 3 | auto const pos = first - begin(); | |
| 384 | 3 | auto const count = last - first; | |
| 385 | 3 | erase(pos, count); | |
| 386 | 3 | return data() + pos; | |
| 387 | } | ||
| 388 | |||
| 389 | //---------------------------------------------------------- | ||
| 390 | |||
| 391 | void | ||
| 392 | 66 | string:: | |
| 393 | resize(size_type count, char ch) | ||
| 394 | { | ||
| 395 |
2/2✓ Branch 1 taken 25 times.
✓ Branch 2 taken 41 times.
|
66 | if(count <= impl_.size()) |
| 396 | { | ||
| 397 | 25 | impl_.term(count); | |
| 398 | 25 | return; | |
| 399 | } | ||
| 400 | |||
| 401 | 41 | reserve(count); | |
| 402 | 35 | std::char_traits<char>::assign( | |
| 403 | impl_.end(), | ||
| 404 | 35 | count - impl_.size(), | |
| 405 | ch); | ||
| 406 | 35 | grow(count - size()); | |
| 407 | } | ||
| 408 | |||
| 409 | //---------------------------------------------------------- | ||
| 410 | |||
| 411 | void | ||
| 412 | 4 | string:: | |
| 413 | swap(string& other) | ||
| 414 | { | ||
| 415 |
2/2✓ Branch 3 taken 3 times.
✓ Branch 4 taken 1 times.
|
4 | if(*sp_ == *other.sp_) |
| 416 | { | ||
| 417 | 3 | std::swap(impl_, other.impl_); | |
| 418 | 3 | return; | |
| 419 | } | ||
| 420 | string temp1( | ||
| 421 |
1/1✓ Branch 3 taken 1 times.
|
1 | std::move(*this), other.sp_); |
| 422 | string temp2( | ||
| 423 |
1/1✓ Branch 3 taken 1 times.
|
1 | std::move(other), sp_); |
| 424 | 1 | this->~string(); | |
| 425 | 1 | ::new(this) string(pilfer(temp2)); | |
| 426 | 1 | other.~string(); | |
| 427 | 1 | ::new(&other) string(pilfer(temp1)); | |
| 428 | 1 | } | |
| 429 | |||
| 430 | //---------------------------------------------------------- | ||
| 431 | |||
| 432 | void | ||
| 433 | 9686 | string:: | |
| 434 | reserve_impl(size_type new_cap) | ||
| 435 | { | ||
| 436 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 9686 times.
|
9686 | BOOST_ASSERT( |
| 437 | new_cap >= impl_.capacity()); | ||
| 438 |
1/2✓ Branch 1 taken 9686 times.
✗ Branch 2 not taken.
|
9686 | if(new_cap > impl_.capacity()) |
| 439 | { | ||
| 440 | // grow | ||
| 441 |
1/1✓ Branch 2 taken 9685 times.
|
9686 | new_cap = detail::string_impl::growth( |
| 442 | new_cap, impl_.capacity()); | ||
| 443 |
1/1✓ Branch 1 taken 9675 times.
|
9685 | detail::string_impl tmp(new_cap, sp_); |
| 444 | 9675 | std::char_traits<char>::copy(tmp.data(), | |
| 445 | 9675 | impl_.data(), impl_.size() + 1); | |
| 446 | 9675 | tmp.size(impl_.size()); | |
| 447 | 9675 | impl_.destroy(sp_); | |
| 448 | 9675 | impl_ = tmp; | |
| 449 | 9675 | return; | |
| 450 | } | ||
| 451 | } | ||
| 452 | |||
| 453 | } // namespace json | ||
| 454 | } // namespace boost | ||
| 455 | |||
| 456 | //---------------------------------------------------------- | ||
| 457 | |||
| 458 | std::size_t | ||
| 459 | 3 | std::hash< ::boost::json::string >::operator()( | |
| 460 | ::boost::json::string const& js ) const noexcept | ||
| 461 | { | ||
| 462 | 3 | return ::boost::hash< ::boost::json::string >()( js ); | |
| 463 | } | ||
| 464 | |||
| 465 | #endif | ||
| 466 |