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