100.00% Lines (69/69) 100.00% Functions (13/13)
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_HPP 10   #ifndef BOOST_JSON_IMPL_STRING_HPP
11   #define BOOST_JSON_IMPL_STRING_HPP 11   #define BOOST_JSON_IMPL_STRING_HPP
12   12  
13   #include <utility> 13   #include <utility>
14   14  
15   namespace boost { 15   namespace boost {
16   namespace json { 16   namespace json {
17   17  
HITCBC 18   30296 string:: 18   30296 string::
19   string( 19   string(
20   detail::key_t const&, 20   detail::key_t const&,
21   string_view s, 21   string_view s,
HITCBC 22   30296 storage_ptr sp) 22   30296 storage_ptr sp)
HITCBC 23   30296 : sp_(std::move(sp)) 23   30296 : sp_(std::move(sp))
HITCBC 24   30296 , impl_(detail::key_t{}, 24   30296 , impl_(detail::key_t{},
HITCBC 25   30296 s, sp_) 25   30296 s, sp_)
26   { 26   {
HITCBC 27   30296 } 27   30296 }
28   28  
HITCBC 29   8060 string:: 29   8060 string::
30   string( 30   string(
31   detail::key_t const&, 31   detail::key_t const&,
32   string_view s1, 32   string_view s1,
33   string_view s2, 33   string_view s2,
HITCBC 34   8060 storage_ptr sp) 34   8060 storage_ptr sp)
HITCBC 35   8060 : sp_(std::move(sp)) 35   8060 : sp_(std::move(sp))
HITCBC 36   8060 , impl_(detail::key_t{}, 36   8060 , impl_(detail::key_t{},
HITCBC 37   8060 s1, s2, sp_) 37   8060 s1, s2, sp_)
38   { 38   {
HITCBC 39   8060 } 39   8060 }
40   40  
41   template<class InputIt, class> 41   template<class InputIt, class>
HITCBC 42   31 string:: 42   31 string::
43   string( 43   string(
44   InputIt first, 44   InputIt first,
45   InputIt last, 45   InputIt last,
46   storage_ptr sp) 46   storage_ptr sp)
HITCBC 47   31 : sp_(std::move(sp)) 47   31 : sp_(std::move(sp))
HITCBC 48   31 , impl_(first, last, sp_, 48   31 , impl_(first, last, sp_,
HITCBC 49   21 iter_cat<InputIt>{}) 49   21 iter_cat<InputIt>{})
50   { 50   {
HITCBC 51   31 } 51   31 }
52   52  
53   template<class InputIt, class> 53   template<class InputIt, class>
54   string& 54   string&
HITCBC 55   13 string:: 55   13 string::
56   assign( 56   assign(
57   InputIt first, 57   InputIt first,
58   InputIt last) 58   InputIt last)
59   { 59   {
HITCBC 60   13 assign(first, last, 60   13 assign(first, last,
61   iter_cat<InputIt>{}); 61   iter_cat<InputIt>{});
HITCBC 62   10 return *this; 62   10 return *this;
63   } 63   }
64   64  
65   template<class InputIt, class> 65   template<class InputIt, class>
66   string& 66   string&
HITCBC 67   6 string:: 67   6 string::
68   append(InputIt first, InputIt last) 68   append(InputIt first, InputIt last)
69   { 69   {
HITCBC 70   6 append(first, last, 70   6 append(first, last,
71   iter_cat<InputIt>{}); 71   iter_cat<InputIt>{});
HITCBC 72   4 return *this; 72   4 return *this;
73   } 73   }
74   74  
75   // KRYSTIAN TODO: this can be done without copies when 75   // KRYSTIAN TODO: this can be done without copies when
76   // reallocation is not needed, when the iterator is a 76   // reallocation is not needed, when the iterator is a
77   // FowardIterator or better, as we can use std::distance 77   // FowardIterator or better, as we can use std::distance
78   template<class InputIt, class> 78   template<class InputIt, class>
79   auto 79   auto
HITCBC 80   6 string:: 80   6 string::
81   insert( 81   insert(
82   size_type pos, 82   size_type pos,
83   InputIt first, 83   InputIt first,
84   InputIt last) -> 84   InputIt last) ->
85   string& 85   string&
86   { 86   {
87   struct cleanup 87   struct cleanup
88   { 88   {
89   detail::string_impl& s; 89   detail::string_impl& s;
90   storage_ptr const& sp; 90   storage_ptr const& sp;
91   91  
HITCBC 92   6 ~cleanup() 92   6 ~cleanup()
93   { 93   {
HITCBC 94   6 s.destroy(sp); 94   6 s.destroy(sp);
HITCBC 95   6 } 95   6 }
96   }; 96   };
97   97  
98   // We use the default storage because 98   // We use the default storage because
99   // the allocation is immediately freed. 99   // the allocation is immediately freed.
HITCBC 100   6 storage_ptr dsp; 100   6 storage_ptr dsp;
HITCBC 101   6 detail::string_impl tmp( 101   6 detail::string_impl tmp(
102   first, last, dsp, 102   first, last, dsp,
103   iter_cat<InputIt>{}); 103   iter_cat<InputIt>{});
HITCBC 104   6 cleanup c{tmp, dsp}; 104   6 cleanup c{tmp, dsp};
HITCBC 105   6 std::memcpy( 105   6 std::memcpy(
HITCBC 106   6 impl_.insert_unchecked(pos, tmp.size(), sp_), 106   6 impl_.insert_unchecked(pos, tmp.size(), sp_),
HITCBC 107   6 tmp.data(), 107   6 tmp.data(),
108   tmp.size()); 108   tmp.size());
HITCBC 109   4 return *this; 109   4 return *this;
HITCBC 110   8 } 110   8 }
111   111  
112   // KRYSTIAN TODO: this can be done without copies when 112   // KRYSTIAN TODO: this can be done without copies when
113   // reallocation is not needed, when the iterator is a 113   // reallocation is not needed, when the iterator is a
114   // FowardIterator or better, as we can use std::distance 114   // FowardIterator or better, as we can use std::distance
115   template<class InputIt, class> 115   template<class InputIt, class>
116   auto 116   auto
117   string:: 117   string::
118   replace( 118   replace(
119   const_iterator first, 119   const_iterator first,
120   const_iterator last, 120   const_iterator last,
121   InputIt first2, 121   InputIt first2,
122   InputIt last2) -> 122   InputIt last2) ->
123   string& 123   string&
124   { 124   {
125   struct cleanup 125   struct cleanup
126   { 126   {
127   detail::string_impl& s; 127   detail::string_impl& s;
128   storage_ptr const& sp; 128   storage_ptr const& sp;
129   129  
130   ~cleanup() 130   ~cleanup()
131   { 131   {
132   s.destroy(sp); 132   s.destroy(sp);
133   } 133   }
134   }; 134   };
135   135  
136   // We use the default storage because 136   // We use the default storage because
137   // the allocation is immediately freed. 137   // the allocation is immediately freed.
138   storage_ptr dsp; 138   storage_ptr dsp;
139   detail::string_impl tmp( 139   detail::string_impl tmp(
140   first2, last2, dsp, 140   first2, last2, dsp,
141   iter_cat<InputIt>{}); 141   iter_cat<InputIt>{});
142   cleanup c{tmp, dsp}; 142   cleanup c{tmp, dsp};
143   std::memcpy( 143   std::memcpy(
144   impl_.replace_unchecked( 144   impl_.replace_unchecked(
145   first - begin(), 145   first - begin(),
146   last - first, 146   last - first,
147   tmp.size(), 147   tmp.size(),
148   sp_), 148   sp_),
149   tmp.data(), 149   tmp.data(),
150   tmp.size()); 150   tmp.size());
151   return *this; 151   return *this;
152   } 152   }
153   153  
154   //---------------------------------------------------------- 154   //----------------------------------------------------------
155   155  
156   template<class InputIt> 156   template<class InputIt>
157   void 157   void
HITCBC 158   6 string:: 158   6 string::
159   assign( 159   assign(
160   InputIt first, 160   InputIt first,
161   InputIt last, 161   InputIt last,
162   std::random_access_iterator_tag) 162   std::random_access_iterator_tag)
163   { 163   {
HITCBC 164   6 auto dest = impl_.assign(static_cast< 164   6 auto dest = impl_.assign(static_cast<
HITCBC 165   6 size_type>(last - first), sp_); 165   6 size_type>(last - first), sp_);
HITCBC 166   63 while(first != last) 166   63 while(first != last)
HITCBC 167   58 *dest++ = *first++; 167   58 *dest++ = *first++;
HITCBC 168   5 } 168   5 }
169   169  
170   template<class InputIt> 170   template<class InputIt>
171   void 171   void
HITCBC 172   7 string:: 172   7 string::
173   assign( 173   assign(
174   InputIt first, 174   InputIt first,
175   InputIt last, 175   InputIt last,
176   std::input_iterator_tag) 176   std::input_iterator_tag)
177   { 177   {
HITCBC 178   7 if(first == last) 178   7 if(first == last)
179   { 179   {
HITCBC 180   1 impl_.term(0); 180   1 impl_.term(0);
HITCBC 181   1 return; 181   1 return;
182   } 182   }
HITCBC 183   6 detail::string_impl tmp( 183   6 detail::string_impl tmp(
HITCBC 184   6 first, last, sp_, 184   6 first, last, sp_,
185   std::input_iterator_tag{}); 185   std::input_iterator_tag{});
HITCBC 186   4 impl_.destroy(sp_); 186   4 impl_.destroy(sp_);
HITCBC 187   4 impl_ = tmp; 187   4 impl_ = tmp;
188   } 188   }
189   189  
190   template<class InputIt> 190   template<class InputIt>
191   void 191   void
HITCBC 192   3 string:: 192   3 string::
193   append( 193   append(
194   InputIt first, 194   InputIt first,
195   InputIt last, 195   InputIt last,
196   std::random_access_iterator_tag) 196   std::random_access_iterator_tag)
197   { 197   {
198   198  
HITCBC 199   3 auto const n = static_cast< 199   3 auto const n = static_cast<
HITCBC 200   3 size_type>(last - first); 200   3 size_type>(last - first);
HITCBC 201   3 char* out = impl_.append(n, sp_); 201   3 char* out = impl_.append(n, sp_);
202   #if defined(_MSC_VER) && _MSC_VER <= 1900 202   #if defined(_MSC_VER) && _MSC_VER <= 1900
203   while( first != last ) 203   while( first != last )
204   *out++ = *first++; 204   *out++ = *first++;
205   #else 205   #else
HITCBC 206   2 std::copy(first, last, out); 206   2 std::copy(first, last, out);
207   #endif 207   #endif
HITCBC 208   2 } 208   2 }
209   209  
210   template<class InputIt> 210   template<class InputIt>
211   void 211   void
HITCBC 212   3 string:: 212   3 string::
213   append( 213   append(
214   InputIt first, 214   InputIt first,
215   InputIt last, 215   InputIt last,
216   std::input_iterator_tag) 216   std::input_iterator_tag)
217   { 217   {
218   struct cleanup 218   struct cleanup
219   { 219   {
220   detail::string_impl& s; 220   detail::string_impl& s;
221   storage_ptr const& sp; 221   storage_ptr const& sp;
222   222  
HITCBC 223   3 ~cleanup() 223   3 ~cleanup()
224   { 224   {
HITCBC 225   3 s.destroy(sp); 225   3 s.destroy(sp);
HITCBC 226   3 } 226   3 }
227   }; 227   };
228   228  
229   // We use the default storage because 229   // We use the default storage because
230   // the allocation is immediately freed. 230   // the allocation is immediately freed.
HITCBC 231   3 storage_ptr dsp; 231   3 storage_ptr dsp;
HITCBC 232   3 detail::string_impl tmp( 232   3 detail::string_impl tmp(
233   first, last, dsp, 233   first, last, dsp,
234   std::input_iterator_tag{}); 234   std::input_iterator_tag{});
HITCBC 235   3 cleanup c{tmp, dsp}; 235   3 cleanup c{tmp, dsp};
HITCBC 236   3 std::memcpy( 236   3 std::memcpy(
HITCBC 237   3 impl_.append(tmp.size(), sp_), 237   3 impl_.append(tmp.size(), sp_),
HITCBC 238   3 tmp.data(), tmp.size()); 238   3 tmp.data(), tmp.size());
HITCBC 239   4 } 239   4 }
240   240  
241   char& 241   char&
HITCBC 242   15 string::at(std::size_t pos, source_location const& loc) 242   15 string::at(std::size_t pos, source_location const& loc)
243   { 243   {
244   244  
HITCBC 245   15 auto const& self = *this; 245   15 auto const& self = *this;
HITCBC 246   15 return const_cast< char& >( self.at(pos, loc) ); 246   15 return const_cast< char& >( self.at(pos, loc) );
247   } 247   }
248   248  
249   } // namespace json 249   } // namespace json
250   } // namespace boost 250   } // namespace boost
251   251  
252   #endif 252   #endif