100.00% Lines (163/163) 100.00% Functions (46/46)
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_ARRAY_HPP 10   #ifndef BOOST_JSON_IMPL_ARRAY_HPP
11   #define BOOST_JSON_IMPL_ARRAY_HPP 11   #define BOOST_JSON_IMPL_ARRAY_HPP
12   12  
13   #include <boost/core/detail/static_assert.hpp> 13   #include <boost/core/detail/static_assert.hpp>
14   #include <boost/json/value.hpp> 14   #include <boost/json/value.hpp>
15   #include <boost/json/detail/except.hpp> 15   #include <boost/json/detail/except.hpp>
16   #include <algorithm> 16   #include <algorithm>
17   #include <stdexcept> 17   #include <stdexcept>
18   #include <type_traits> 18   #include <type_traits>
19   19  
20   namespace boost { 20   namespace boost {
21   namespace json { 21   namespace json {
22   22  
23   //---------------------------------------------------------- 23   //----------------------------------------------------------
24   24  
25   struct alignas(value) 25   struct alignas(value)
26   array::table 26   array::table
27   { 27   {
28   std::uint32_t size = 0; 28   std::uint32_t size = 0;
29   std::uint32_t capacity = 0; 29   std::uint32_t capacity = 0;
30   30  
31   constexpr table(); 31   constexpr table();
32   32  
33   value& 33   value&
HITCBC 34   37790 operator[](std::size_t pos) noexcept 34   37790 operator[](std::size_t pos) noexcept
35   { 35   {
36   return (reinterpret_cast< 36   return (reinterpret_cast<
HITCBC 37   37790 value*>(this + 1))[pos]; 37   37790 value*>(this + 1))[pos];
38   } 38   }
39   39  
40   BOOST_JSON_DECL 40   BOOST_JSON_DECL
41   static 41   static
42   table* 42   table*
43   allocate( 43   allocate(
44   std::size_t capacity, 44   std::size_t capacity,
45   storage_ptr const& sp); 45   storage_ptr const& sp);
46   46  
47   BOOST_JSON_DECL 47   BOOST_JSON_DECL
48   static 48   static
49   void 49   void
50   deallocate( 50   deallocate(
51   table* p, 51   table* p,
52   storage_ptr const& sp); 52   storage_ptr const& sp);
53   }; 53   };
54   54  
55   //---------------------------------------------------------- 55   //----------------------------------------------------------
56   56  
57   class array::revert_construct 57   class array::revert_construct
58   { 58   {
59   array* arr_; 59   array* arr_;
60   60  
61   public: 61   public:
62   explicit 62   explicit
HITCBC 63   410 revert_construct( 63   410 revert_construct(
64   array& arr) noexcept 64   array& arr) noexcept
HITCBC 65   410 : arr_(&arr) 65   410 : arr_(&arr)
66   { 66   {
HITCBC 67   410 } 67   410 }
68   68  
HITCBC 69   410 ~revert_construct() 69   410 ~revert_construct()
HITCBC 70   64 { 70   64 {
HITCBC 71   410 if(! arr_) 71   410 if(! arr_)
HITCBC 72   346 return; 72   346 return;
HITCBC 73   64 arr_->destroy(); 73   64 arr_->destroy();
HITCBC 74   410 } 74   410 }
75   75  
76   void 76   void
HITCBC 77   346 commit() noexcept 77   346 commit() noexcept
78   { 78   {
HITCBC 79   346 arr_ = nullptr; 79   346 arr_ = nullptr;
HITCBC 80   346 } 80   346 }
81   }; 81   };
82   82  
83   //---------------------------------------------------------- 83   //----------------------------------------------------------
84   84  
85   class array::revert_insert 85   class array::revert_insert
86   { 86   {
87   array* arr_; 87   array* arr_;
88   std::size_t const i_; 88   std::size_t const i_;
89   std::size_t const n_; 89   std::size_t const n_;
90   90  
91   public: 91   public:
92   value* p; 92   value* p;
93   93  
94   BOOST_JSON_DECL 94   BOOST_JSON_DECL
95   revert_insert( 95   revert_insert(
96   const_iterator pos, 96   const_iterator pos,
97   std::size_t n, 97   std::size_t n,
98   array& arr); 98   array& arr);
99   99  
100   BOOST_JSON_DECL 100   BOOST_JSON_DECL
101   ~revert_insert(); 101   ~revert_insert();
102   102  
103   value* 103   value*
HITCBC 104   18 commit() noexcept 104   18 commit() noexcept
105   { 105   {
106   auto it = 106   auto it =
HITCBC 107   18 arr_->data() + i_; 107   18 arr_->data() + i_;
HITCBC 108   18 arr_ = nullptr; 108   18 arr_ = nullptr;
HITCBC 109   18 return it; 109   18 return it;
110   } 110   }
111   }; 111   };
112   112  
113   //---------------------------------------------------------- 113   //----------------------------------------------------------
114   114  
115   void 115   void
HITCBC 116   797 array:: 116   797 array::
117   relocate( 117   relocate(
118   value* dest, 118   value* dest,
119   value* src, 119   value* src,
120   std::size_t n) noexcept 120   std::size_t n) noexcept
121   { 121   {
HITCBC 122   797 if(n == 0) 122   797 if(n == 0)
HITCBC 123   660 return; 123   660 return;
HITCBC 124   137 std::memmove( 124   137 std::memmove(
125   static_cast<void*>(dest), 125   static_cast<void*>(dest),
126   static_cast<void const*>(src), 126   static_cast<void const*>(src),
127   n * sizeof(value)); 127   n * sizeof(value));
128   } 128   }
129   129  
130   //---------------------------------------------------------- 130   //----------------------------------------------------------
131   // 131   //
132   // Construction 132   // Construction
133   // 133   //
134   //---------------------------------------------------------- 134   //----------------------------------------------------------
135   135  
136   template<class InputIt, class> 136   template<class InputIt, class>
HITCBC 137   37 array:: 137   37 array::
138   array( 138   array(
139   InputIt first, InputIt last, 139   InputIt first, InputIt last,
140   storage_ptr sp) 140   storage_ptr sp)
141   : array( 141   : array(
142   first, last, 142   first, last,
HITCBC 143   37 std::move(sp), 143   37 std::move(sp),
HITCBC 144   40 iter_cat<InputIt>{}) 144   40 iter_cat<InputIt>{})
145   { 145   {
146   BOOST_CORE_STATIC_ASSERT(( 146   BOOST_CORE_STATIC_ASSERT((
147   std::is_constructible<value, decltype(*first)>::value)); 147   std::is_constructible<value, decltype(*first)>::value));
HITCBC 148   21 } 148   21 }
149   149  
150   //---------------------------------------------------------- 150   //----------------------------------------------------------
151   // 151   //
152   // Modifiers 152   // Modifiers
153   // 153   //
154   //---------------------------------------------------------- 154   //----------------------------------------------------------
155   155  
156   template<class InputIt, class> 156   template<class InputIt, class>
157   auto 157   auto
HITCBC 158   27 array:: 158   27 array::
159   insert( 159   insert(
160   const_iterator pos, 160   const_iterator pos,
161   InputIt first, InputIt last) -> 161   InputIt first, InputIt last) ->
162   iterator 162   iterator
163   { 163   {
164   BOOST_CORE_STATIC_ASSERT(( 164   BOOST_CORE_STATIC_ASSERT((
165   std::is_constructible<value, decltype(*first)>::value)); 165   std::is_constructible<value, decltype(*first)>::value));
HITCBC 166   37 return insert(pos, first, last, 166   37 return insert(pos, first, last,
HITCBC 167   23 iter_cat<InputIt>{}); 167   23 iter_cat<InputIt>{});
168   } 168   }
169   169  
170   template<class Arg> 170   template<class Arg>
171   auto 171   auto
HITCBC 172   13 array:: 172   13 array::
173   emplace( 173   emplace(
174   const_iterator pos, 174   const_iterator pos,
175   Arg&& arg) -> 175   Arg&& arg) ->
176   iterator 176   iterator
177   { 177   {
HITCBC 178   13 BOOST_ASSERT( 178   13 BOOST_ASSERT(
179   pos >= begin() && 179   pos >= begin() &&
180   pos <= end()); 180   pos <= end());
HITCBC 181   21 value jv( 181   21 value jv(
HITCBC 182   7 std::forward<Arg>(arg), 182   7 std::forward<Arg>(arg),
183   storage()); 183   storage());
HITCBC 184   19 return insert(pos, pilfer(jv)); 184   19 return insert(pos, pilfer(jv));
HITCBC 185   12 } 185   12 }
186   186  
187   template<class Arg> 187   template<class Arg>
188   value& 188   value&
HITCBC 189   7607 array:: 189   7607 array::
190   emplace_back(Arg&& arg) 190   emplace_back(Arg&& arg)
191   { 191   {
HITCBC 192   7641 value jv( 192   7641 value jv(
HITCBC 193   31 std::forward<Arg>(arg), 193   31 std::forward<Arg>(arg),
194   storage()); 194   storage());
HITCBC 195   15203 return push_back(pilfer(jv)); 195   15203 return push_back(pilfer(jv));
HITCBC 196   7604 } 196   7604 }
197   197  
198   //---------------------------------------------------------- 198   //----------------------------------------------------------
199   // 199   //
200   // Element access 200   // Element access
201   // 201   //
202   //---------------------------------------------------------- 202   //----------------------------------------------------------
203   203  
204   value& 204   value&
HITCBC 205   36 array:: 205   36 array::
206   at(std::size_t pos, source_location const& loc) & 206   at(std::size_t pos, source_location const& loc) &
207   { 207   {
HITCBC 208   36 auto const& self = *this; 208   36 auto const& self = *this;
HITCBC 209   36 return const_cast< value& >( self.at(pos, loc) ); 209   36 return const_cast< value& >( self.at(pos, loc) );
210   } 210   }
211   211  
212   value&& 212   value&&
HITCBC 213   16 array:: 213   16 array::
214   at(std::size_t pos, source_location const& loc) && 214   at(std::size_t pos, source_location const& loc) &&
215   { 215   {
HITCBC 216   16 return std::move( at(pos, loc) ); 216   16 return std::move( at(pos, loc) );
217   } 217   }
218   218  
219   value& 219   value&
HITCBC 220   49 array:: 220   49 array::
221   operator[](std::size_t pos) & noexcept 221   operator[](std::size_t pos) & noexcept
222   { 222   {
HITCBC 223   49 BOOST_ASSERT(pos < t_->size); 223   49 BOOST_ASSERT(pos < t_->size);
HITCBC 224   49 return (*t_)[pos]; 224   49 return (*t_)[pos];
225   } 225   }
226   226  
227   value&& 227   value&&
HITCBC 228   4 array:: 228   4 array::
229   operator[](std::size_t pos) && noexcept 229   operator[](std::size_t pos) && noexcept
230   { 230   {
HITCBC 231   4 return std::move( (*this)[pos] ); 231   4 return std::move( (*this)[pos] );
232   } 232   }
233   233  
234   value const& 234   value const&
HITCBC 235   6738 array:: 235   6738 array::
236   operator[](std::size_t pos) const& noexcept 236   operator[](std::size_t pos) const& noexcept
237   { 237   {
HITCBC 238   6738 BOOST_ASSERT(pos < t_->size); 238   6738 BOOST_ASSERT(pos < t_->size);
HITCBC 239   6738 return (*t_)[pos]; 239   6738 return (*t_)[pos];
240   } 240   }
241   241  
242   value& 242   value&
HITCBC 243   5 array:: 243   5 array::
244   front() & noexcept 244   front() & noexcept
245   { 245   {
HITCBC 246   5 BOOST_ASSERT(t_->size > 0); 246   5 BOOST_ASSERT(t_->size > 0);
HITCBC 247   5 return (*t_)[0]; 247   5 return (*t_)[0];
248   } 248   }
249   249  
250   value&& 250   value&&
HITCBC 251   2 array:: 251   2 array::
252   front() && noexcept 252   front() && noexcept
253   { 253   {
HITCBC 254   2 return std::move( front() ); 254   2 return std::move( front() );
255   } 255   }
256   256  
257   value const& 257   value const&
HITCBC 258   1 array:: 258   1 array::
259   front() const& noexcept 259   front() const& noexcept
260   { 260   {
HITCBC 261   1 BOOST_ASSERT(t_->size > 0); 261   1 BOOST_ASSERT(t_->size > 0);
HITCBC 262   1 return (*t_)[0]; 262   1 return (*t_)[0];
263   } 263   }
264   264  
265   value& 265   value&
HITCBC 266   7 array:: 266   7 array::
267   back() & noexcept 267   back() & noexcept
268   { 268   {
HITCBC 269   7 BOOST_ASSERT( 269   7 BOOST_ASSERT(
270   t_->size > 0); 270   t_->size > 0);
HITCBC 271   7 return (*t_)[t_->size - 1]; 271   7 return (*t_)[t_->size - 1];
272   } 272   }
273   273  
274   value&& 274   value&&
HITCBC 275   2 array:: 275   2 array::
276   back() && noexcept 276   back() && noexcept
277   { 277   {
HITCBC 278   2 return std::move( back() ); 278   2 return std::move( back() );
279   } 279   }
280   280  
281   value const& 281   value const&
HITCBC 282   1 array:: 282   1 array::
283   back() const& noexcept 283   back() const& noexcept
284   { 284   {
HITCBC 285   1 BOOST_ASSERT( 285   1 BOOST_ASSERT(
286   t_->size > 0); 286   t_->size > 0);
HITCBC 287   1 return (*t_)[t_->size - 1]; 287   1 return (*t_)[t_->size - 1];
288   } 288   }
289   289  
290   value* 290   value*
HITCBC 291   1775 array:: 291   1775 array::
292   data() noexcept 292   data() noexcept
293   { 293   {
HITCBC 294   1775 return &(*t_)[0]; 294   1775 return &(*t_)[0];
295   } 295   }
296   296  
297   value const* 297   value const*
HITCBC 298   190 array:: 298   190 array::
299   data() const noexcept 299   data() const noexcept
300   { 300   {
HITCBC 301   190 return &(*t_)[0]; 301   190 return &(*t_)[0];
302   } 302   }
303   303  
304   value const* 304   value const*
HITCBC 305   17 array:: 305   17 array::
306   if_contains( 306   if_contains(
307   std::size_t pos) const noexcept 307   std::size_t pos) const noexcept
308   { 308   {
HITCBC 309   17 if( pos < t_->size ) 309   17 if( pos < t_->size )
HITCBC 310   14 return &(*t_)[pos]; 310   14 return &(*t_)[pos];
HITCBC 311   3 return nullptr; 311   3 return nullptr;
312   } 312   }
313   313  
314   value* 314   value*
HITCBC 315   3 array:: 315   3 array::
316   if_contains( 316   if_contains(
317   std::size_t pos) noexcept 317   std::size_t pos) noexcept
318   { 318   {
HITCBC 319   3 if( pos < t_->size ) 319   3 if( pos < t_->size )
HITCBC 320   2 return &(*t_)[pos]; 320   2 return &(*t_)[pos];
HITCBC 321   1 return nullptr; 321   1 return nullptr;
322   } 322   }
323   323  
324   //---------------------------------------------------------- 324   //----------------------------------------------------------
325   // 325   //
326   // Iterators 326   // Iterators
327   // 327   //
328   //---------------------------------------------------------- 328   //----------------------------------------------------------
329   329  
330   auto 330   auto
HITCBC 331   3855 array:: 331   3855 array::
332   begin() noexcept -> 332   begin() noexcept ->
333   iterator 333   iterator
334   { 334   {
HITCBC 335   3855 return &(*t_)[0]; 335   3855 return &(*t_)[0];
336   } 336   }
337   337  
338   auto 338   auto
HITCBC 339   5663 array:: 339   5663 array::
340   begin() const noexcept -> 340   begin() const noexcept ->
341   const_iterator 341   const_iterator
342   { 342   {
HITCBC 343   5663 return &(*t_)[0]; 343   5663 return &(*t_)[0];
344   } 344   }
345   345  
346   auto 346   auto
HITCBC 347   3 array:: 347   3 array::
348   cbegin() const noexcept -> 348   cbegin() const noexcept ->
349   const_iterator 349   const_iterator
350   { 350   {
HITCBC 351   3 return &(*t_)[0]; 351   3 return &(*t_)[0];
352   } 352   }
353   353  
354   auto 354   auto
HITCBC 355   4008 array:: 355   4008 array::
356   end() noexcept -> 356   end() noexcept ->
357   iterator 357   iterator
358   { 358   {
HITCBC 359   4008 return &(*t_)[t_->size]; 359   4008 return &(*t_)[t_->size];
360   } 360   }
361   361  
362   auto 362   auto
HITCBC 363   6186 array:: 363   6186 array::
364   end() const noexcept -> 364   end() const noexcept ->
365   const_iterator 365   const_iterator
366   { 366   {
HITCBC 367   6186 return &(*t_)[t_->size]; 367   6186 return &(*t_)[t_->size];
368   } 368   }
369   369  
370   auto 370   auto
HITCBC 371   3 array:: 371   3 array::
372   cend() const noexcept -> 372   cend() const noexcept ->
373   const_iterator 373   const_iterator
374   { 374   {
HITCBC 375   3 return &(*t_)[t_->size]; 375   3 return &(*t_)[t_->size];
376   } 376   }
377   377  
378   auto 378   auto
HITCBC 379   3 array:: 379   3 array::
380   rbegin() noexcept -> 380   rbegin() noexcept ->
381   reverse_iterator 381   reverse_iterator
382   { 382   {
HITCBC 383   3 return reverse_iterator(end()); 383   3 return reverse_iterator(end());
384   } 384   }
385   385  
386   auto 386   auto
HITCBC 387   3 array:: 387   3 array::
388   rbegin() const noexcept -> 388   rbegin() const noexcept ->
389   const_reverse_iterator 389   const_reverse_iterator
390   { 390   {
HITCBC 391   3 return const_reverse_iterator(end()); 391   3 return const_reverse_iterator(end());
392   } 392   }
393   393  
394   auto 394   auto
HITCBC 395   3 array:: 395   3 array::
396   crbegin() const noexcept -> 396   crbegin() const noexcept ->
397   const_reverse_iterator 397   const_reverse_iterator
398   { 398   {
HITCBC 399   3 return const_reverse_iterator(end()); 399   3 return const_reverse_iterator(end());
400   } 400   }
401   401  
402   auto 402   auto
HITCBC 403   3 array:: 403   3 array::
404   rend() noexcept -> 404   rend() noexcept ->
405   reverse_iterator 405   reverse_iterator
406   { 406   {
HITCBC 407   3 return reverse_iterator(begin()); 407   3 return reverse_iterator(begin());
408   } 408   }
409   409  
410   auto 410   auto
HITCBC 411   3 array:: 411   3 array::
412   rend() const noexcept -> 412   rend() const noexcept ->
413   const_reverse_iterator 413   const_reverse_iterator
414   { 414   {
HITCBC 415   3 return const_reverse_iterator(begin()); 415   3 return const_reverse_iterator(begin());
416   } 416   }
417   417  
418   auto 418   auto
HITCBC 419   3 array:: 419   3 array::
420   crend() const noexcept -> 420   crend() const noexcept ->
421   const_reverse_iterator 421   const_reverse_iterator
422   { 422   {
HITCBC 423   3 return const_reverse_iterator(begin()); 423   3 return const_reverse_iterator(begin());
424   } 424   }
425   425  
426   //---------------------------------------------------------- 426   //----------------------------------------------------------
427   // 427   //
428   // Capacity 428   // Capacity
429   // 429   //
430   //---------------------------------------------------------- 430   //----------------------------------------------------------
431   431  
432   std::size_t 432   std::size_t
HITCBC 433   6538 array:: 433   6538 array::
434   size() const noexcept 434   size() const noexcept
435   { 435   {
HITCBC 436   6538 return t_->size; 436   6538 return t_->size;
437   } 437   }
438   438  
439   constexpr 439   constexpr
440   std::size_t 440   std::size_t
HITCBC 441   4164 array:: 441   4164 array::
442   max_size() noexcept 442   max_size() noexcept
443   { 443   {
444   // max_size depends on the address model 444   // max_size depends on the address model
445   using min = std::integral_constant<std::size_t, 445   using min = std::integral_constant<std::size_t,
446   (std::size_t(-1) - sizeof(table)) / sizeof(value)>; 446   (std::size_t(-1) - sizeof(table)) / sizeof(value)>;
447   return min::value < BOOST_JSON_MAX_STRUCTURED_SIZE ? 447   return min::value < BOOST_JSON_MAX_STRUCTURED_SIZE ?
HITCBC 448   4164 min::value : BOOST_JSON_MAX_STRUCTURED_SIZE; 448   4164 min::value : BOOST_JSON_MAX_STRUCTURED_SIZE;
449   } 449   }
450   450  
451   std::size_t 451   std::size_t
HITCBC 452   858 array:: 452   858 array::
453   capacity() const noexcept 453   capacity() const noexcept
454   { 454   {
HITCBC 455   858 return t_->capacity; 455   858 return t_->capacity;
456   } 456   }
457   457  
458   bool 458   bool
HITCBC 459   195 array:: 459   195 array::
460   empty() const noexcept 460   empty() const noexcept
461   { 461   {
HITCBC 462   195 return t_->size == 0; 462   195 return t_->size == 0;
463   } 463   }
464   464  
465   void 465   void
HITCBC 466   711 array:: 466   711 array::
467   reserve( 467   reserve(
468   std::size_t new_capacity) 468   std::size_t new_capacity)
469   { 469   {
470   // never shrink 470   // never shrink
HITCBC 471   711 if(new_capacity <= t_->capacity) 471   711 if(new_capacity <= t_->capacity)
HITCBC 472   37 return; 472   37 return;
HITCBC 473   674 reserve_impl(new_capacity); 473   674 reserve_impl(new_capacity);
474   } 474   }
475   475  
476   //---------------------------------------------------------- 476   //----------------------------------------------------------
477   // 477   //
478   // private 478   // private
479   // 479   //
480   //---------------------------------------------------------- 480   //----------------------------------------------------------
481   481  
482   template<class InputIt> 482   template<class InputIt>
HITCBC 483   19 array:: 483   19 array::
484   array( 484   array(
485   InputIt first, InputIt last, 485   InputIt first, InputIt last,
486   storage_ptr sp, 486   storage_ptr sp,
487   std::input_iterator_tag) 487   std::input_iterator_tag)
HITCBC 488   19 : sp_(std::move(sp)) 488   19 : sp_(std::move(sp))
HITCBC 489   19 , t_(&empty_) 489   19 , t_(&empty_)
490   { 490   {
HITCBC 491   19 revert_construct r(*this); 491   19 revert_construct r(*this);
HITCBC 492   86 while(first != last) 492   86 while(first != last)
493   { 493   {
HITCBC 494   80 reserve(size() + 1); 494   80 reserve(size() + 1);
HITCBC 495   138 ::new(end()) value( 495   138 ::new(end()) value(
HITCBC 496   136 *first++, sp_); 496   136 *first++, sp_);
HITCBC 497   67 ++t_->size; 497   67 ++t_->size;
498   } 498   }
HITCBC 499   6 r.commit(); 499   6 r.commit();
HITCBC 500   32 } 500   32 }
501   501  
502   template<class InputIt> 502   template<class InputIt>
HITCBC 503   18 array:: 503   18 array::
504   array( 504   array(
505   InputIt first, InputIt last, 505   InputIt first, InputIt last,
506   storage_ptr sp, 506   storage_ptr sp,
507   std::forward_iterator_tag) 507   std::forward_iterator_tag)
HITCBC 508   18 : sp_(std::move(sp)) 508   18 : sp_(std::move(sp))
509   { 509   {
HITCBC 510   18 std::size_t n = 510   18 std::size_t n =
HITCBC 511   18 std::distance(first, last); 511   18 std::distance(first, last);
HITCBC 512   18 if( n == 0 ) 512   18 if( n == 0 )
513   { 513   {
HITCBC 514   3 t_ = &empty_; 514   3 t_ = &empty_;
HITCBC 515   3 return; 515   3 return;
516   } 516   }
517   517  
HITCBC 518   15 t_ = table::allocate(n, sp_); 518   15 t_ = table::allocate(n, sp_);
HITCBC 519   13 t_->size = 0; 519   13 t_->size = 0;
HITCBC 520   13 revert_construct r(*this); 520   13 revert_construct r(*this);
HITCBC 521   53 while(n--) 521   53 while(n--)
522   { 522   {
HITCBC 523   84 ::new(end()) value( 523   84 ::new(end()) value(
HITCBC 524   41 *first++, sp_); 524   41 *first++, sp_);
HITCBC 525   40 ++t_->size; 525   40 ++t_->size;
526   } 526   }
HITCBC 527   12 r.commit(); 527   12 r.commit();
HITCBC 528   16 } 528   16 }
529   529  
530   template<class InputIt> 530   template<class InputIt>
531   auto 531   auto
HITCBC 532   13 array:: 532   13 array::
533   insert( 533   insert(
534   const_iterator pos, 534   const_iterator pos,
535   InputIt first, InputIt last, 535   InputIt first, InputIt last,
536   std::input_iterator_tag) -> 536   std::input_iterator_tag) ->
537   iterator 537   iterator
538   { 538   {
HITCBC 539   13 BOOST_ASSERT( 539   13 BOOST_ASSERT(
540   pos >= begin() && pos <= end()); 540   pos >= begin() && pos <= end());
HITCBC 541   13 if(first == last) 541   13 if(first == last)
HITCBC 542   1 return data() + (pos - data()); 542   1 return data() + (pos - data());
HITCBC 543   20 array temp(first, last, sp_); 543   20 array temp(first, last, sp_);
HITCBC 544   4 revert_insert r( 544   4 revert_insert r(
545   pos, temp.size(), *this); 545   pos, temp.size(), *this);
HITCBC 546   2 relocate( 546   2 relocate(
547   r.p, 547   r.p,
548   temp.data(), 548   temp.data(),
549   temp.size()); 549   temp.size());
HITCBC 550   2 temp.t_->size = 0; 550   2 temp.t_->size = 0;
HITCBC 551   2 return r.commit(); 551   2 return r.commit();
HITCBC 552   4 } 552   4 }
553   553  
554   template<class InputIt> 554   template<class InputIt>
555   auto 555   auto
HITCBC 556   14 array:: 556   14 array::
557   insert( 557   insert(
558   const_iterator pos, 558   const_iterator pos,
559   InputIt first, InputIt last, 559   InputIt first, InputIt last,
560   std::forward_iterator_tag) -> 560   std::forward_iterator_tag) ->
561   iterator 561   iterator
562   { 562   {
HITCBC 563   14 std::size_t n = 563   14 std::size_t n =
HITCBC 564   14 std::distance(first, last); 564   14 std::distance(first, last);
HITCBC 565   14 revert_insert r(pos, n, *this); 565   14 revert_insert r(pos, n, *this);
HITCBC 566   3050 while(n--) 566   3050 while(n--)
567   { 567   {
HITCBC 568   3040 ::new(r.p) value(*first++); 568   3040 ::new(r.p) value(*first++);
HITCBC 569   3040 ++r.p; 569   3040 ++r.p;
570   } 570   }
HITCBC 571   20 return r.commit(); 571   20 return r.commit();
HITCBC 572   10 } 572   10 }
573   573  
574   } // namespace json 574   } // namespace json
575   } // namespace boost 575   } // namespace boost
576   576  
577   #endif 577   #endif