LCOV - code coverage report
Current view: top level - json/impl - string.ipp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 173 173
Test Date: 2026-07-08 12:13:06 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             175 : string::
      41                 : string(
      42                 :     char const* s,
      43             175 :     storage_ptr sp)
      44             175 :     : sp_(std::move(sp))
      45                 : {
      46             175 :     assign(s);
      47             175 : }
      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             145 : string::
      67                 : string(
      68                 :     string const& other,
      69             145 :     storage_ptr sp)
      70             145 :     : sp_(std::move(sp))
      71                 : {
      72             145 :     assign(other);
      73             145 : }
      74                 : 
      75             351 : string::
      76                 : string(
      77                 :     string&& other,
      78             351 :     storage_ptr sp)
      79             351 :     : sp_(std::move(sp))
      80                 : {
      81             351 :     assign(std::move(other));
      82             351 : }
      83                 : 
      84           17890 : string::
      85                 : string(
      86                 :     string_view s,
      87           17890 :     storage_ptr sp)
      88           17890 :     : sp_(std::move(sp))
      89                 : {
      90           17890 :     assign(s);
      91           17890 : }
      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             193 : string::
     144                 : assign(
     145                 :     string const& other)
     146                 : {
     147             193 :     if(this == &other)
     148               1 :         return *this;
     149             192 :     return assign(
     150                 :         other.data(),
     151             165 :         other.size());
     152                 : }
     153                 : 
     154                 : string&
     155             375 : string::
     156                 : assign(string&& other)
     157                 : {
     158             375 :     if( &other == this )
     159               1 :         return *this;
     160                 : 
     161             374 :     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              34 :     return assign(other);
     171                 : }
     172                 : 
     173                 : string&
     174           18367 : string::
     175                 : assign(
     176                 :     char const* s,
     177                 :     size_type count)
     178                 : {
     179           18244 :     std::char_traits<char>::copy(
     180           18367 :         impl_.assign(count, sp_),
     181                 :         s, count);
     182           18244 :     return *this;
     183                 : }
     184                 : 
     185                 : string&
     186             189 : string::
     187                 : assign(
     188                 :     char const* s)
     189                 : {
     190             189 :     return assign(s, std::char_traits<
     191             186 :         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              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              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              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             148 : string::
     258                 : push_back(char ch)
     259                 : {
     260             148 :     *impl_.append(1, sp_) = ch;
     261             146 : }
     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              55 : string::
     285                 : append(string_view sv)
     286                 : {
     287              55 :     auto const p = impl_.data();
     288              55 :     if(detail::ptr_in_range(p, p + impl_.size(), sv.data()))
     289                 :     {
     290                 :         // sv aliases our own storage; appending may reallocate and free the
     291                 :         // buffer sv points into, so copy from the relocated offset afterwards
     292              10 :         auto const offset = sv.data() - p;
     293              10 :         auto const dest = impl_.append(sv.size(), sp_);
     294               8 :         std::char_traits<char>::copy(
     295               8 :             dest, impl_.data() + offset, sv.size());
     296                 :     }
     297                 :     else
     298                 :     {
     299              90 :         std::char_traits<char>::copy(
     300              45 :             impl_.append(sv.size(), sp_),
     301                 :             sv.data(), sv.size());
     302                 :     }
     303              40 :     return *this;
     304                 : }
     305                 : 
     306                 : //----------------------------------------------------------
     307                 : 
     308                 : string&
     309              27 : string::
     310                 : insert(
     311                 :     size_type pos,
     312                 :     string_view sv)
     313                 : {
     314              27 :     impl_.insert(pos, sv.data(), sv.size(), sp_);
     315              17 :     return *this;
     316                 : }
     317                 : 
     318                 : string&
     319              11 : string::
     320                 : insert(
     321                 :     std::size_t pos,
     322                 :     std::size_t count,
     323                 :     char ch)
     324                 : {
     325               6 :     std::char_traits<char>::assign(
     326              11 :         impl_.insert_unchecked(pos, count, sp_),
     327                 :         count, ch);
     328               6 :     return *this;
     329                 : }
     330                 : 
     331                 : //----------------------------------------------------------
     332                 : 
     333                 : string&
     334              19 : string::
     335                 : replace(
     336                 :     std::size_t pos,
     337                 :     std::size_t count,
     338                 :     string_view sv)
     339                 : {
     340              19 :     impl_.replace(pos, count, sv.data(), sv.size(), sp_);
     341              15 :     return *this;
     342                 : }
     343                 : 
     344                 : string&
     345              11 : string::
     346                 : replace(
     347                 :     std::size_t pos,
     348                 :     std::size_t count,
     349                 :     std::size_t count2,
     350                 :     char ch)
     351                 : {
     352               7 :     std::char_traits<char>::assign(
     353              11 :         impl_.replace_unchecked(pos, count, count2, sp_),
     354                 :         count2, ch);
     355               7 :     return *this;
     356                 : }
     357                 : 
     358                 : //----------------------------------------------------------
     359                 : 
     360                 : string&
     361              10 : string::
     362                 : erase(
     363                 :     size_type pos,
     364                 :     size_type count)
     365                 : {
     366              10 :     if(pos > impl_.size())
     367                 :     {
     368                 :         BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
     369               1 :         detail::throw_system_error( error::out_of_range, &loc );
     370                 :     }
     371               9 :     if( count > impl_.size() - pos)
     372               4 :         count = impl_.size() - pos;
     373               9 :     std::char_traits<char>::move(
     374               9 :         impl_.data() + pos,
     375               9 :         impl_.data() + pos + count,
     376               9 :         impl_.size() - pos - count + 1);
     377               9 :     impl_.term(impl_.size() - count);
     378               9 :     return *this;
     379                 : }
     380                 : 
     381                 : auto
     382               2 : string::
     383                 : erase(const_iterator pos) ->
     384                 :     iterator
     385                 : {
     386               2 :     return erase(pos, pos+1);
     387                 : }
     388                 : 
     389                 : auto
     390               3 : string::
     391                 : erase(
     392                 :     const_iterator first,
     393                 :     const_iterator last) ->
     394                 :         iterator
     395                 : {
     396               3 :     auto const pos = first - begin();
     397               3 :     auto const count = last - first;
     398               3 :     erase(pos, count);
     399               3 :     return data() + pos;
     400                 : }
     401                 : 
     402                 : //----------------------------------------------------------
     403                 : 
     404                 : void
     405              66 : string::
     406                 : resize(size_type count, char ch)
     407                 : {
     408              66 :     if(count <= impl_.size())
     409                 :     {
     410              25 :         impl_.term(count);
     411              25 :         return;
     412                 :     }
     413                 : 
     414              41 :     reserve(count);
     415              35 :     std::char_traits<char>::assign(
     416                 :         impl_.end(),
     417              35 :         count - impl_.size(),
     418                 :         ch);
     419              35 :     grow(count - size());
     420                 : }
     421                 : 
     422                 : //----------------------------------------------------------
     423                 : 
     424                 : void
     425               4 : string::
     426                 : swap(string& other)
     427                 : {
     428               4 :     if(*sp_ == *other.sp_)
     429                 :     {
     430               3 :         std::swap(impl_, other.impl_);
     431               3 :         return;
     432                 :     }
     433                 :     string temp1(
     434               1 :         std::move(*this), other.sp_);
     435                 :     string temp2(
     436               1 :         std::move(other), sp_);
     437               1 :     this->~string();
     438               1 :     ::new(this) string(pilfer(temp2));
     439               1 :     other.~string();
     440               1 :     ::new(&other) string(pilfer(temp1));
     441               1 : }
     442                 : 
     443                 : //----------------------------------------------------------
     444                 : 
     445                 : void
     446            9686 : string::
     447                 : reserve_impl(size_type new_cap)
     448                 : {
     449            9686 :     BOOST_ASSERT(
     450                 :         new_cap >= impl_.capacity());
     451            9686 :     if(new_cap > impl_.capacity())
     452                 :     {
     453                 :         // grow
     454            9686 :         new_cap = detail::string_impl::growth(
     455                 :             new_cap, impl_.capacity());
     456            9685 :         detail::string_impl tmp(new_cap, sp_);
     457            9675 :         std::char_traits<char>::copy(tmp.data(),
     458            9675 :             impl_.data(), impl_.size() + 1);
     459            9675 :         tmp.size(impl_.size());
     460            9675 :         impl_.destroy(sp_);
     461            9675 :         impl_ = tmp;
     462            9675 :         return;
     463                 :     }
     464                 : }
     465                 : 
     466                 : } // namespace json
     467                 : } // namespace boost
     468                 : 
     469                 : //----------------------------------------------------------
     470                 : 
     471                 : std::size_t
     472               3 : std::hash< ::boost::json::string >::operator()(
     473                 :     ::boost::json::string const& js ) const noexcept
     474                 : {
     475               3 :     return ::boost::hash< ::boost::json::string >()( js );
     476                 : }
     477                 : 
     478                 : #endif
        

Generated by: LCOV version 2.3