LCOV - code coverage report
Current view: top level - json/impl - string.ipp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 177 177
Test Date: 2026-07-19 14:13:53 Functions: 100.0 % 36 36

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

Generated by: LCOV version 2.3