LCOV - code coverage report
Current view: top level - json/impl - string.ipp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 167 167
Test Date: 2025-12-23 17:20:51 Functions: 100.0 % 36 36

            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           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          203 : string::
      41              : string(
      42              :     char const* s,
      43          203 :     storage_ptr sp)
      44          203 :     : sp_(std::move(sp))
      45              : {
      46          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            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          151 : string::
      67              : string(
      68              :     string const& other,
      69          151 :     storage_ptr sp)
      70          151 :     : sp_(std::move(sp))
      71              : {
      72          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          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        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          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          493 :     if( &other == this )
     159            1 :         return *this;
     160              : 
     161          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           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           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           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            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           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            4 :     if(*sp_ == *other.sp_)
     416              :     {
     417            3 :         std::swap(impl_, other.impl_);
     418            3 :         return;
     419              :     }
     420              :     string temp1(
     421            1 :         std::move(*this), other.sp_);
     422              :     string temp2(
     423            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         9686 :     BOOST_ASSERT(
     437              :         new_cap >= impl_.capacity());
     438         9686 :     if(new_cap > impl_.capacity())
     439              :     {
     440              :         // grow
     441         9686 :         new_cap = detail::string_impl::growth(
     442              :             new_cap, impl_.capacity());
     443         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
        

Generated by: LCOV version 2.1