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