STLdoc
STLdocumentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
concurrent_vector.h
Go to the documentation of this file.
1 /***
2 * ==++==
3 *
4 * Copyright (c) Microsoft Corporation. All rights reserved.
5 * Microsoft would like to acknowledge that this concurrency data structure implementation
6 * is based on the Intel implementation of its Threading Building Blocks ("Intel Material").
7 *
8 * ==--==
9 * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
10 *
11 * concurrent_vector.h
12 *
13 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
14 ****/
15 
16 /*
17  Intel Material Copyright 2005-2008 Intel Corporation. All Rights Reserved.
18 */
19 
20 #pragma once
21 
22 #include <crtdefs.h>
23 #include <memory>
24 #include <iterator>
25 #include <limits>
26 #include <algorithm>
27 #include <cstring>
28 #include <crtdbg.h>
29 #include <concrt.h>
30 
31 #define _PPL_CONTAINER
32 
33 #if !(defined (_M_X64) || defined (_M_IX86) || defined (_M_ARM))
34  #error ERROR: Concurrency Runtime is supported only on X64, X86 and ARM architectures.
35 #endif /* !(defined (_M_X64) || defined (_M_IX86) || defined (_M_ARM)) */
36 
37 #if defined (_M_CEE)
38  #error ERROR: Concurrency Runtime is not supported when compiling /clr.
39 #endif /* defined (_M_CEE) */
40 
41 #pragma pack(push,_CRT_PACKING)
42 #pragma warning (push)
43 #pragma warning (disable: 4510 4512 4610) // disable warnings for compiler unable to generate constructor
44 
49 
50 namespace Concurrency
51 {
52 
53 template<typename _Ty, class _Ax = std::allocator<_Ty> >
55 
56 namespace details
57 {
58 
59  // Bad allocation marker.
60  #define _BAD_ALLOC_MARKER reinterpret_cast<void*>(63)
61 
62  // Base class of concurrent vector implementation.
64  {
65  protected:
66 
67  // Basic types declarations.
68  typedef size_t _Segment_index_t;
69  typedef size_t _Size_type;
70 
71  // Size constants
72  static const _Segment_index_t _Default_initial_segments = 1; // 2 initial items
73 
74  // Number of slots for segment's pointers inside the class
75  static const _Segment_index_t _Pointers_per_short_table = 3; // to fit into 8 words of entire structure
76  static const _Segment_index_t _Pointers_per_long_table = sizeof(_Segment_index_t) * 8; // one segment per bit
77 
78  // Segment pointer. Can be zero-initialized.
79  struct _Segment_t
80  {
81  void* _My_array;
82  };
83 
84  // Data fields
85 
86  // allocator function pointer
87  void* (__cdecl *_My_vector_allocator_ptr)(_Concurrent_vector_base_v4 &, size_t);
88 
89  // embedded storage of segment pointers
91 
92  // Methods
93 
95  {
96  _My_early_size = 0;
97  _My_first_block = 0; // here is not _Default_initial_segments
98  for( _Segment_index_t _I = 0; _I < _Pointers_per_short_table; _I++)
99  _My_storage[_I]._My_array = NULL;
101  }
103 
104  _CRTIMP2 static _Segment_index_t __cdecl _Segment_index_of( _Size_type _Index );
105 
106  static _Segment_index_t _Segment_base( _Segment_index_t _K )
107  {
108  return (_Segment_index_t(1)<<_K & ~_Segment_index_t(1));
109  }
110 
111  static _Segment_index_t _Segment_base_index_of( _Segment_index_t &_Index )
112  {
113  _Segment_index_t _K = _Segment_index_of( _Index );
114  _Index -= _Segment_base(_K);
115  return _K;
116  }
117 
118  static _Size_type _Segment_size( _Segment_index_t _K )
119  {
120  return _Segment_index_t(1)<<_K; // fake value for _K==0
121  }
122 
123  // An operation on an n-element array starting at begin.
124  typedef void (__cdecl *_My_internal_array_op1)(void* _Begin, _Size_type _N );
125 
126  // An operation on n-element destination array and n-element source array.
127  typedef void (__cdecl *_My_internal_array_op2)(void* _Dst, const void* _Src, _Size_type _N );
128 
129  // Internal structure for shrink_to_fit().
131  {
132  _Segment_index_t _First_block;
134  };
135 
136  _CRTIMP2 void _Internal_reserve( _Size_type _N, _Size_type _Element_size, _Size_type _Max_size );
137  _CRTIMP2 _Size_type _Internal_capacity() const;
138  void _Internal_grow( _Size_type _Start, _Size_type _Finish, _Size_type _Element_size, _My_internal_array_op2 _Init, const void *_Src );
139  _Size_type _Internal_grow_segment( const _Size_type _Start, _Size_type _Finish, _Size_type _Element_size, _Segment_t** _PPSegment, _Size_type* _PSegStart, _Size_type* _PSegFinish );
140  _CRTIMP2 _Size_type _Internal_grow_by( _Size_type _Delta, _Size_type _Element_size, _My_internal_array_op2 _Init, const void *_Src );
141  _CRTIMP2 void* _Internal_push_back( _Size_type _Element_size, _Size_type& _Index );
143  void _Internal_truncate( _Size_type _Old_size, _Size_type _New_size, _Size_type _Element_size, _My_internal_array_op1 _Destroy);
144  _CRTIMP2 void* _Internal_compact( _Size_type _Element_size, void *_Table, _My_internal_array_op1 _Destroy, _My_internal_array_op2 _Copy );
145  _CRTIMP2 void _Internal_copy( const _Concurrent_vector_base_v4& _Src, _Size_type _Element_size, _My_internal_array_op2 _Copy );
146  _CRTIMP2 void _Internal_assign( const _Concurrent_vector_base_v4& _Src, _Size_type _Element_size,
148  _CRTIMP2 void _Internal_throw_exception(_Size_type) const;
150 
151  _CRTIMP2 void _Internal_resize( _Size_type _New_size, _Size_type _Element_size, _Size_type _Max_size, _My_internal_array_op1 _Destroy, _My_internal_array_op2 _Init, const void* _Src);
152  _CRTIMP2 _Size_type _Internal_grow_to_at_least_with_result( _Size_type _New_size, _Size_type _Element_size, _My_internal_array_op2 _Init, const void *_Src );
153 
154  // Count of segments in the first block.
156 
157  // Requested size of vector.
159 
160  // Pointer to the segments table.
162 
163 
164  private:
165  // Private functionality.
166  class _Helper;
167  friend class _Helper;
168  };
169 
171 
172  // Meets requirements of a forward iterator for STL.*/
174  template<typename _Container, typename _Value>
176  {
177  // concurrent_vector over which we are iterating.
178  _Container* _My_vector;
179 
180  // Index into the vector.
181  size_t _My_index;
182 
183  // Caches _My_vector-&gt;_Internal_subscript(_My_index)
185  mutable _Value* _My_item;
186 
187  template<typename _C, typename _Ty>
189 
190  template<typename _C, typename _Ty, typename _U>
191  friend bool operator==( const _Vector_iterator<_C,_Ty>&, const _Vector_iterator<_C,_U>& );
192 
193  template<typename _C, typename _Ty, typename _U>
194  friend bool operator<( const _Vector_iterator<_C,_Ty>&, const _Vector_iterator<_C,_U>& );
195 
196  template<typename _C, typename _Ty, typename _U>
198 
199  template<typename _C, typename _U>
200  friend class ::Concurrency::details::_Vector_iterator;
201 
202  template<typename _Ty, class _Ax>
203  friend class ::Concurrency::concurrent_vector;
204 
205  _Vector_iterator( const _Container& _Vec, size_t _Index, void* _Ptr = NULL )
206  : _My_vector(const_cast<_Container*>(&_Vec)),
207  _My_index(_Index),
208  _My_item(static_cast<_Value*>(_Ptr))
209  {
210  }
211 
212  public:
213  // Default constructor
215  : _My_vector(NULL), _My_index(~size_t(0)), _My_item(NULL)
216  {
217  }
218 
220  : _My_vector(_Other._My_vector),
221  _My_index(_Other._My_index),
222  _My_item(_Other._My_item)
223  {
224  }
225 
227  {
228  return _Vector_iterator( *_My_vector, _My_index+_Offset );
229  }
231  {
232  _My_index+=_Offset;
233  _My_item = NULL;
234  return *this;
235  }
237  {
238  return _Vector_iterator( *_My_vector, _My_index-_Offset );
239  }
241  {
242  _My_index-=_Offset;
243  _My_item = NULL;
244  return *this;
245  }
246  _Value& operator*() const
247  {
248  _Value* _Item = _My_item;
249  if( !_Item )
250  _Item = _My_item = &_My_vector->_Internal_subscript(_My_index);
251  _CONCRT_ASSERT( _Item==&_My_vector->_Internal_subscript(_My_index)); // corrupt cache
252  return *_Item;
253  }
255  {
256  return _My_vector->_Internal_subscript(_My_index+_K);
257  }
259  {
260  return &operator*();
261  }
262 
263  // Pre increment
265  {
266  size_t _K = ++_My_index;
267  if( _My_item )
268  {
269  // Following test uses 2's-complement wizardry.
270  if( (_K& (_K-2))==0 )
271  {
272  // _K is a power of two that is at least _K-2.
273  _My_item= NULL;
274  }
275  else
276  {
277  ++_My_item;
278  }
279  }
280  return *this;
281  }
282 
283  // Pre decrement
285  {
286  _CONCRT_ASSERT( _My_index>0 ); // operator--() applied to iterator already at beginning of concurrent_vector.
287  size_t _K = _My_index--;
288  if( _My_item )
289  {
290  // Following test uses 2's-complement wizardry.
291  if( (_K& (_K-2))==0 )
292  {
293  // k is a power of two that is at least k-2.
294  _My_item= NULL;
295  }
296  else
297  {
298  --_My_item;
299  }
300  }
301  return *this;
302  }
303 
304  // Post increment
306  {
307  _Vector_iterator _Result = *this;
308  operator++();
309  return _Result;
310  }
311 
312  // Post decrement
314  {
315  _Vector_iterator _Result = *this;
316  operator--();
317  return _Result;
318  }
319 
320  // STL support
321 
324  typedef _Value* pointer;
325  typedef _Value& reference;
326  typedef std::random_access_iterator_tag iterator_category;
327  };
328 
329  template<typename _Container, typename _Value>
330  struct std::_Is_checked_helper<_Vector_iterator<_Container, _Value> >
331  : public true_type
332  { // mark _Vector_iterator as checked. This supresses warning C4996
333  };
334 
335  template<typename _Container, typename _Ty>
337  {
339  }
340 
341  template<typename _Container, typename _Ty, typename _U>
343  {
344  return _I._My_index==_J._My_index && _I._My_vector == _J._My_vector;
345  }
346 
347  template<typename _Container, typename _Ty, typename _U>
349  {
350  return !(_I==_J);
351  }
352 
353  template<typename _Container, typename _Ty, typename _U>
354  bool operator<( const _Vector_iterator<_Container,_Ty>& _I, const _Vector_iterator<_Container,_U>& _J )
355  {
356  return _I._My_index<_J._My_index && _I._My_vector == _J._My_vector;
357  }
358 
359  template<typename _Container, typename _Ty, typename _U>
361  {
362  return _J<_I;
363  }
364 
365  template<typename _Container, typename _Ty, typename _U>
367  {
368  return !(_I<_J);
369  }
370 
371  template<typename _Container, typename _Ty, typename _U>
372  bool operator<=( const _Vector_iterator<_Container,_Ty>& _I, const _Vector_iterator<_Container,_U>& _J )
373  {
374  return !(_J<_I);
375  }
376 
377  template<typename _Container, typename _Ty, typename _U>
379  {
380  return ptrdiff_t(_I._My_index)-ptrdiff_t(_J._My_index);
381  }
382 
383  template<typename _Ty, class _Ax>
385  {
386  public:
387  typedef typename _Ax::template
388  rebind<_Ty>::other _Allocator_type;
389  _Allocator_type _My_allocator;
390 
391  _Allocator_base(const _Allocator_type &_Al = _Allocator_type() )
392  : _My_allocator(_Al)
393  {
394  }
395  };
396 
397 } // namespace details
398 
415 
416 template<typename _Ty, class _Ax>
417 class concurrent_vector: protected details::_Allocator_base<_Ty, _Ax>,
418  private details::_Concurrent_vector_base_v4
419 {
420 private:
422 
423  template<typename _C, typename _U>
425 
426 public:
427 
431 
433 
437 
439 
443 
444  typedef _Ty value_type;
445 
449 
451 
455 
456  typedef _Ty& reference;
457 
462 
463  typedef const _Ty& const_reference;
464 
468 
469  typedef _Ty *pointer;
470 
474 
475  typedef const _Ty *const_pointer;
476 
481 
483 
487 
489 
494 
495  typedef std::reverse_iterator<iterator> reverse_iterator;
496 
500 
501  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
502 
520 
521  explicit concurrent_vector(const allocator_type &_Al = allocator_type())
522  : details::_Allocator_base<_Ty, _Ax>(_Al)
523  {
525  }
526 
544 
546  : details::_Allocator_base<_Ty, _Ax>(_Vector.get_allocator())
547  {
549  _Internal_copy(_Vector, sizeof(_Ty), &_Copy_array);
550  }
551 
575 
576  template<class M>
577  concurrent_vector( const concurrent_vector<_Ty, M>& _Vector, const allocator_type& _Al = allocator_type() )
578  : details::_Allocator_base<_Ty, _Ax>(_Al)
579  {
581  _Internal_copy(_Vector._Internal_vector_base(), sizeof(_Ty), &_Copy_array);
582  }
583 
584 
602 
604  : details::_Allocator_base<_Ty, _Ax>(_Vector.get_allocator())
605  {
607  _Concurrent_vector_base_v4::_Internal_swap(_Vector._Internal_vector_base());
608  }
609 
627 
628  explicit concurrent_vector(size_type _N)
629  {
631  if ( !_N ) return;
632  _Internal_reserve(_N, sizeof(_Ty), max_size()); _My_early_size = _N;
634  _Initialize_array(static_cast<_Ty*>(_My_segment[0]._My_array), NULL, _N);
635  }
636 
660 
661  concurrent_vector(size_type _N, const_reference _Item, const allocator_type& _Al = allocator_type())
662  : details::_Allocator_base<_Ty, _Ax>(_Al)
663  {
665  _Internal_assign( _N, _Item );
666  }
667 
694 
695  template<class _InputIterator>
696  concurrent_vector(_InputIterator _Begin, _InputIterator _End, const allocator_type &_Al = allocator_type())
697  : details::_Allocator_base<_Ty, _Ax>(_Al)
698  {
701  }
702 
712 
714  {
715  if( this != &_Vector )
716  _Concurrent_vector_base_v4::_Internal_assign(_Vector, sizeof(_Ty), &_Destroy_array, &_Assign_array, &_Copy_array);
717  return *this;
718  }
719 
732 
733  template<class M>
735  {
736  if( static_cast<void*>( this ) != static_cast<const void*>( &_Vector ) )
737  {
738  _Concurrent_vector_base_v4::_Internal_assign(_Vector._Internal_vector_base(),
739  sizeof(_Ty), &_Destroy_array, &_Assign_array, &_Copy_array);
740  }
741  return *this;
742  }
743 
753 
755  {
756  if( static_cast<void*>( this ) != static_cast<const void*>( &_Vector ) )
757  {
758  _Concurrent_vector_base_v4::_Internal_swap(_Vector._Internal_vector_base());
759  _Vector.clear();
760  }
761  return *this;
762  }
763 
776 
777  iterator grow_by( size_type _Delta )
778  {
779  return iterator(*this, _Delta ? _Internal_grow_by( _Delta, sizeof(_Ty), &_Initialize_array, NULL ) : _My_early_size);
780  }
781 
797 
798  iterator grow_by( size_type _Delta, const_reference _Item )
799  {
800  return iterator(*this, _Delta ? _Internal_grow_by( _Delta, sizeof(_Ty), &_Initialize_array_by, static_cast<const void*>(&_Item) ) : _My_early_size);
801  }
802 
813 
814  iterator grow_to_at_least( size_type _N )
815  {
816  size_type _M = 0;
817  if( _N )
818  {
820  if( _M > _N )
821  _M = _N;
822  }
823  return iterator(*this, _M);
824  };
825 
835 
836  iterator push_back( const_reference _Item )
837  {
838  size_type _K;
839  void *_Ptr = _Internal_push_back(sizeof(_Ty), _K);
840  _Internal_loop_guide _Loop(1, _Ptr);
841  _Loop._Init(&_Item);
842  return iterator(*this, _K, _Ptr);
843  }
844 
854 
855  iterator push_back( _Ty &&_Item )
856  {
857  size_type _K;
858  void *_Ptr = _Internal_push_back(sizeof(_Ty), _K);
859  new (_Ptr) _Ty( std::move(_Item));
860  return iterator(*this, _K, _Ptr);
861  }
862 
880 
881  reference operator[]( size_type _Index )
882  {
883  return _Internal_subscript(_Index);
884  }
885 
903 
904  const_reference operator[]( size_type _Index ) const
905  {
906  return _Internal_subscript(_Index);
907  }
908 
928 
929  reference at( size_type _Index )
930  {
932  }
933 
953 
954  const_reference at( size_type _Index ) const
955  {
957  }
958 
970 
971  size_type size() const
972  {
973  size_type _Sz = _My_early_size;
974  size_type _Cp = _Internal_capacity();
975  return _Cp < _Sz ? _Cp : _Sz;
976  }
977 
984 
985  bool empty() const
986  {
987  return !_My_early_size;
988  }
989 
1000 
1001  size_type capacity() const
1002  {
1003  return _Internal_capacity();
1004  }
1005 
1018 
1019  void reserve( size_type _N )
1020  {
1021  if( _N )
1022  _Internal_reserve(_N, sizeof(_Ty), max_size());
1023  }
1024 
1034 
1035  void shrink_to_fit();
1036 
1052 
1053  void resize(size_type _N)
1054  {
1056  }
1057 
1077 
1078  void resize(size_type _N, const _Ty& _Val)
1079  {
1080  _Internal_resize( _N, sizeof(_Ty), max_size(), _Destroy_array, _Initialize_array_by, static_cast<const void*>(&_Val) );
1081  }
1082 
1089 
1090  size_type max_size() const
1091  {
1092  return (~size_type(0))/sizeof(_Ty);
1093  }
1094 
1103 
1104  iterator begin()
1105  {
1106  return iterator(*this,0);
1107  }
1108 
1117 
1118  iterator end()
1119  {
1120  return iterator(*this,size());
1121  }
1122 
1131 
1132  const_iterator begin() const
1133  {
1134  return const_iterator(*this,0);
1135  }
1136 
1145 
1146  const_iterator end() const
1147  {
1148  return const_iterator(*this,size());
1149  }
1150 
1159 
1160  reverse_iterator rbegin()
1161  {
1162  return reverse_iterator(end());
1163  }
1164 
1173 
1174  reverse_iterator rend()
1175  {
1176  return reverse_iterator(begin());
1177  }
1178 
1187 
1188  const_reverse_iterator rbegin() const
1189  {
1190  return const_reverse_iterator(end());
1191  }
1192 
1201 
1202  const_reverse_iterator rend() const
1203  {
1204  return const_reverse_iterator(begin());
1205  }
1206 
1214 
1215  const_iterator cbegin() const
1216  {
1217  return (((const _Myt *)this)->begin());
1218  }
1219 
1227 
1228  const_iterator cend() const
1229  {
1230  return (((const _Myt *)this)->end());
1231  }
1232 
1240 
1241  const_reverse_iterator crbegin() const
1242  {
1243  return (((const _Myt *)this)->rbegin());
1244  }
1245 
1253 
1254  const_reverse_iterator crend() const
1255  {
1256  return (((const _Myt *)this)->rend());
1257  }
1258 
1266 
1267  reference front()
1268  {
1269  _CONCRT_ASSERT( size()>0 );
1270  return static_cast<_Ty*>(_My_segment[0]._My_array)[0];
1271  }
1272 
1280 
1281  const_reference front() const
1282  {
1283  _CONCRT_ASSERT( size()>0 );
1284  return static_cast<_Ty*>(_My_segment[0]._My_array)[0];
1285  }
1286 
1294 
1295  reference back()
1296  {
1297  _Size_type sz = size();
1298  _CONCRT_ASSERT( sz > 0 );
1299  return _Internal_subscript( sz-1 );
1300  }
1301 
1309 
1310  const_reference back() const
1311  {
1312  _Size_type sz = size();
1313  _CONCRT_ASSERT( sz > 0 );
1314  return _Internal_subscript( sz-1 );
1315  }
1316 
1323 
1324  allocator_type get_allocator() const
1325  {
1326  return this->_My_allocator;
1327  }
1328 
1344 
1345  void assign(size_type _N, const_reference _Item)
1346  {
1347  clear();
1348  _Internal_assign( _N, _Item );
1349  }
1350 
1369 
1370  template<class _InputIterator>
1371  void assign(_InputIterator _Begin, _InputIterator _End)
1372  {
1373  clear();
1375  }
1376 
1383 
1384  void swap(concurrent_vector &_Vector)
1385  {
1386  if( this != &_Vector )
1387  {
1388  _Concurrent_vector_base_v4::_Internal_swap(static_cast<_Concurrent_vector_base_v4&>(_Vector));
1389  std::swap(this->_My_allocator, _Vector._My_allocator);
1390  }
1391  }
1392 
1401 
1402  void clear()
1403  {
1405  }
1406 
1410 
1412  {
1413  _Segment_t *_Table = _My_segment;
1414  _Internal_free_segments( reinterpret_cast<void**>(_Table), _Internal_clear(&_Destroy_array), _My_first_block );
1415  // base class destructor call
1416  }
1417 
1418  const ::Concurrency::details::_Concurrent_vector_base_v4 &_Internal_vector_base() const { return *this; }
1420 private:
1421 
1422  // Allocate _K items
1424  {
1425  return static_cast<concurrent_vector<_Ty, _Ax>&>(_Vb)._My_allocator.allocate(_K);
1426  }
1427  // Free _K segments from table
1428  void _Internal_free_segments(void *_Table[], _Segment_index_t _K, _Segment_index_t _First_block);
1429 
1430  // Get reference to element at given _Index.
1431  _Ty& _Internal_subscript( size_type _Index ) const;
1432 
1433  // Get reference to element at given _Index with errors checks
1434  _Ty& _Internal_subscript_with_exceptions( size_type _Index ) const;
1435 
1436  // assign _N items by copying _Item
1437  void _Internal_assign(size_type _N, const_reference _Item);
1438 
1439  // helper class
1440  template<bool B> class _Is_integer_tag;
1441 
1442  // assign integer items by copying when arguments are treated as iterators. See C++ Standard 2003 23.1.1 p9
1443  template<class _I>
1445  {
1446  _Internal_assign(static_cast<size_type>(_First), static_cast<_Ty>(_Last));
1447  }
1448  // inline proxy assign by iterators
1449  template<class _I>
1451  internal_assign_iterators(_First, _Last);
1452  }
1453  // assign by iterators
1454  template<class _I>
1455  void internal_assign_iterators(_I _First, _I _Last);
1456 
1457  // Construct _N instances of _Ty, starting at "begin".
1458  static void __cdecl _Initialize_array( void* _Begin, const void*, size_type _N );
1459 
1460  // Construct _N instances of _Ty, starting at "begin".
1461  static void __cdecl _Initialize_array_by( void* _Begin, const void* _Src, size_type _N );
1462 
1463  // Construct _N instances of _Ty, starting at "begin".
1464  static void __cdecl _Copy_array( void* _Dst, const void* _Src, size_type _N );
1465 
1466  // Assign _N instances of _Ty, starting at "begin".
1467  static void __cdecl _Assign_array( void* _Dst, const void* _Src, size_type _N );
1468 
1469  // Destroy _N instances of _Ty, starting at "begin".
1470  static void __cdecl _Destroy_array( void* _Begin, size_type _N );
1471 
1472  // Exception-aware helper class for filling a segment by exception-danger operators of user class
1474  {
1475  public:
1476  const pointer _My_array;
1477  const size_type _N;
1478  size_type _I;
1479  _Internal_loop_guide(size_type _NTrials, void *_Ptr)
1480  : _My_array(static_cast<pointer>(_Ptr)), _N(_NTrials), _I(0)
1481  {
1482  }
1483 
1484  void _Init()
1485  {
1486  for(; _I < _N; ++_I)
1487  new( &_My_array[_I] ) _Ty();
1488  }
1489  void _Init(const void *_Src)
1490  {
1491  for(; _I < _N; ++_I)
1492  new( &_My_array[_I] ) _Ty(*static_cast<const _Ty*>(_Src));
1493  }
1494  void _Copy(const void *_Src)
1495  {
1496  for(; _I < _N; ++_I)
1497  new( &_My_array[_I] ) _Ty(static_cast<const _Ty*>(_Src)[_I]);
1498  }
1499  void _Assign(const void *_Src)
1500  {
1501  for(; _I < _N; ++_I)
1502  _My_array[_I] = static_cast<const _Ty*>(_Src)[_I];
1503  }
1504  template<class _It> void _Iterate(_It &_Src)
1505  {
1506  for(; _I < _N; ++_I, ++_Src)
1507  new( &_My_array[_I] ) _Ty( *_Src );
1508  }
1510  {
1511  if(_I < _N) // if exception raised, do zeroing on the rest of items
1512  std::memset(_My_array+_I, 0, (_N-_I)*sizeof(value_type));
1513  }
1514  private:
1515  void operator=(const _Internal_loop_guide&); // prevent warning: assign operator can't be generated
1516  };
1517 };
1518 
1527 
1528 template<typename _Ty, class _Ax>
1530 {
1531  _Internal_segments_table _Old = { 0, nullptr };
1532  try
1533  {
1534  if( _Internal_compact( sizeof(_Ty), &_Old, &_Destroy_array, &_Copy_array ) )
1535  _Internal_free_segments( _Old._Table, _Pointers_per_long_table, _Old._First_block ); // Free joined and unnecessary segments
1536  }
1537  catch(...)
1538  {
1539  if( _Old._First_block ) // Free segment allocated for compacting. Only for support of exceptions in ctor of user _Ty[pe]
1540  _Internal_free_segments( _Old._Table, 1, _Old._First_block );
1541  throw;
1542  }
1543 }
1544 
1545 template<typename _Ty, class _Ax>
1547 {
1548  // Free the arrays
1549  while( _K > _First_block )
1550  {
1551  --_K;
1552  _Ty* _Array = static_cast<_Ty*>(_Table[_K]);
1553  _Table[_K] = NULL;
1554  if( _Array > _BAD_ALLOC_MARKER ) // check for correct segment pointer
1555  this->_My_allocator.deallocate( _Array, _Segment_size(_K) );
1556  }
1557  _Ty* _Array = static_cast<_Ty*>(_Table[0]);
1558  if( _Array > _BAD_ALLOC_MARKER )
1559  {
1560  _CONCRT_ASSERT( _First_block > 0 );
1561  while(_K > 0)
1562  _Table[--_K] = NULL;
1563  this->_My_allocator.deallocate( _Array, _Segment_size(_First_block) );
1564  }
1565 }
1566 
1567 template<typename _Ty, class _Ax>
1569 {
1570  _CONCRT_ASSERT( _Index<_My_early_size ); // index out of bounds
1571  size_type _J = _Index;
1572  _Segment_index_t _K = _Segment_base_index_of( _J );
1573  _CONCRT_ASSERT( _My_segment != (_Segment_t*)_My_storage || _K < _Pointers_per_short_table ); // index is under construction
1574  // no need in load_with_acquire because the thread works in its own space or gets
1575  _Ty* _Array = static_cast<_Ty*>(_My_segment[_K]._My_array);
1576  _CONCRT_ASSERT( _Array != _BAD_ALLOC_MARKER ); // instance may be broken by bad allocation; use at() instead
1577  _CONCRT_ASSERT( _Array != NULL ); // index is being allocated
1578  return _Array[_J];
1579 }
1580 
1581 template<typename _Ty, class _Ax>
1583 {
1584  if( _Index >= _My_early_size )
1585  _Internal_throw_exception(0); // throw std::out_of_range
1586  size_type _J = _Index;
1587  _Segment_index_t _K = _Segment_base_index_of( _J );
1588  if( _My_segment == (_Segment_t*)_My_storage && _K >= _Pointers_per_short_table )
1589  _Internal_throw_exception(1); // throw std::out_of_range
1590  void *_Array = _My_segment[_K]._My_array; // no need in load_with_acquire
1591  if( _Array <= _BAD_ALLOC_MARKER ) // check for correct segment pointer
1592  _Internal_throw_exception(2); // throw std::range_error
1593  return static_cast<_Ty*>(_Array)[_J];
1594 }
1595 
1596 template<typename _Ty, class _Ax>
1597 void concurrent_vector<_Ty, _Ax>::_Internal_assign(size_type _N, const_reference _Item)
1598 {
1599  _CONCRT_ASSERT( _My_early_size == 0 );
1600  if( !_N )
1601  return;
1602  _Internal_reserve(_N, sizeof(_Ty), max_size());
1603  _My_early_size = _N;
1604  _Segment_index_t _K = 0;
1605  _Size_type _Sz = _Segment_size( _My_first_block );
1606  while (_Sz < _N)
1607  {
1608  _Initialize_array_by(static_cast<_Ty*>(_My_segment[_K]._My_array), static_cast<const void*>(&_Item), _Sz);
1609  _N -= _Sz;
1610  if (!_K)
1611  {
1612  _K = _My_first_block;
1613  }
1614  else {
1615  ++_K;
1616  _Sz <<= 1;
1617  }
1618  }
1619  _Initialize_array_by(static_cast<_Ty*>(_My_segment[_K]._My_array), static_cast<const void*>(&_Item), _N);
1620 }
1621 
1622 template<typename _Ty, class _Ax> template<class _I>
1624 {
1625  _CONCRT_ASSERT(_My_early_size == 0);
1626  size_type _N = std::distance(_First, _Last);
1627  if( !_N ) return;
1628  _Internal_reserve(_N, sizeof(_Ty), max_size());
1629  _My_early_size = _N;
1630  _Segment_index_t _K = 0;
1631  _Size_type _Sz = _Segment_size( _My_first_block );
1632  while (_Sz < _N)
1633  {
1634  _Internal_loop_guide _Loop(_Sz, _My_segment[_K]._My_array);
1635  _Loop._Iterate(_First);
1636  _N -= _Sz;
1637  if (!_K)
1638  {
1639  _K = _My_first_block;
1640  }
1641  else {
1642  ++_K;
1643  _Sz <<= 1;
1644  }
1645  }
1646 
1647  _Internal_loop_guide _Loop(_N, _My_segment[_K]._My_array);
1648  _Loop._Iterate(_First);
1649 }
1650 
1651 template<typename _Ty, class _Ax>
1652 void __cdecl concurrent_vector<_Ty, _Ax>::_Initialize_array( void* _Begin, const void *, size_type _N )
1653 {
1654  _Internal_loop_guide _Loop(_N, _Begin); _Loop._Init();
1655 }
1656 
1657 template<typename _Ty, class _Ax>
1658 void __cdecl concurrent_vector<_Ty, _Ax>::_Initialize_array_by( void* _Begin, const void *_Src, size_type _N )
1659 {
1660  _Internal_loop_guide _Loop(_N, _Begin); _Loop._Init(_Src);
1661 }
1662 
1663 template<typename _Ty, class _Ax>
1664 void __cdecl concurrent_vector<_Ty, _Ax>::_Copy_array( void* _Dst, const void* _Src, size_type _N ) {
1665  _Internal_loop_guide _Loop(_N, _Dst); _Loop._Copy(_Src);
1666 }
1667 
1668 template<typename _Ty, class _Ax>
1669 void __cdecl concurrent_vector<_Ty, _Ax>::_Assign_array( void* _Dst, const void* _Src, size_type _N )
1670 {
1671  _Internal_loop_guide _Loop(_N, _Dst); _Loop._Assign(_Src);
1672 }
1673 
1674 #pragma warning(push)
1675 #pragma warning(disable: 4189) /* local variable _Array is initialized but not used - the compiler optimizes away calls to the destructor */
1676 
1677 template<typename _Ty, class _Ax>
1678 void __cdecl concurrent_vector<_Ty, _Ax>::_Destroy_array( void* _Begin, size_type _N )
1679 {
1680  _Ty* _Array = static_cast<_Ty*>(_Begin);
1681  for( size_type _J=_N; _J>0; --_J )
1682  _Array[_J-1].~_Ty(); // destructors are supposed to not throw any exceptions
1683 }
1684 
1685 #pragma warning(pop)
1686 
1718 
1719 template<typename _Ty, class A1, class A2>
1721 {
1722  // Simply: return _A.size() == _B.size() && std::equal(_A.begin(), _A.end(), _B.begin());
1723  if(_A.size() != _B.size())
1724  return false;
1725  typename concurrent_vector<_Ty, A1>::const_iterator _I(_A.begin());
1726  typename concurrent_vector<_Ty, A2>::const_iterator _J(_B.begin());
1727  for(; _I != _A.end(); ++_I, ++_J)
1728  {
1729  if( !(*_I == *_J) )
1730  return false;
1731  }
1732  return true;
1733 }
1734 
1765 
1766 template<typename _Ty, class A1, class A2>
1768 {
1769  return !(_A == _B);
1770 }
1771 
1803 
1804 template<typename _Ty, class A1, class A2>
1805 inline bool operator<(const concurrent_vector<_Ty, A1> &_A, const concurrent_vector<_Ty, A2> &_B)
1806 {
1807  return (std::lexicographical_compare(_A.begin(), _A.end(), _B.begin(), _B.end()));
1808 }
1809 
1841 
1842 template<typename _Ty, class A1, class A2>
1844 {
1845  return _B < _A;
1846 }
1847 
1879 
1880 template<typename _Ty, class A1, class A2>
1881 inline bool operator<=(const concurrent_vector<_Ty, A1> &_A, const concurrent_vector<_Ty, A2> &_B)
1882 {
1883  return !(_B < _A);
1884 }
1885 
1917 
1918 template<typename _Ty, class A1, class A2>
1920 {
1921  return !(_A < _B);
1922 }
1923 
1953 
1954 template<typename _Ty, class _Ax>
1956 {
1957  _A.swap( _B );
1958 }
1959 
1960 } // namespace Concurrency
1961 
1962 namespace concurrency = Concurrency;
1963 
1964 #pragma warning (pop)
1965 #pragma pack(pop)
_CRTIMP2 _Size_type _Internal_capacity() const
void _Internal_grow(_Size_type _Start, _Size_type _Finish, _Size_type _Element_size, _My_internal_array_op2 _Init, const void *_Src)
reference operator[](size_type _Index)
Provides access to the element at the given index in the concurrent vector. This method is concurrenc...
Definition: concurrent_vector.h:881
const_reverse_iterator rend() const
Returns an iterator of type reverse_iterator or const_reverse_iterator to the end of the concurrent...
Definition: concurrent_vector.h:1202
void(__cdecl * _My_internal_array_op2)(void *_Dst, const void *_Src, _Size_type _N)
Definition: concurrent_vector.h:127
Definition: xtr1common:34
_Vector_iterator operator++(int)
Definition: concurrent_vector.h:305
_Check_return_opt_ _In_ long _Offset
Definition: io.h:334
void *__cdecl * _My_vector_allocator_ptr(_Concurrent_vector_base_v4 &, size_t)
concurrent_vector(const concurrent_vector &_Vector)
Constructs a concurrent vector.
Definition: concurrent_vector.h:545
_Vector_iterator operator+(ptrdiff_t _Offset) const
Definition: concurrent_vector.h:226
const ::Concurrency::details::_Concurrent_vector_base_v4 & _Internal_vector_base() const
Definition: concurrent_vector.h:1418
size_t _Size_type
Definition: concurrent_vector.h:69
_CRTIMP2 void _Internal_copy(const _Concurrent_vector_base_v4 &_Src, _Size_type _Element_size, _My_internal_array_op2 _Copy)
iterator push_back(_Ty &&_Item)
Appends the given item to the end of the concurrent vector. This method is concurrency-safe.
Definition: concurrent_vector.h:855
_CRTIMP2 void _Internal_throw_exception(_Size_type) const
const_reference front() const
Returns a reference or a const reference to the first element in the concurrent vector. If the concurrent vector is empty, the return value is undefined. This method is concurrency-safe.
Definition: concurrent_vector.h:1281
_Vector_iterator(const _Vector_iterator< _Container, typename _Container::value_type > &_Other)
Definition: concurrent_vector.h:219
~_Internal_loop_guide()
Definition: concurrent_vector.h:1509
_Value & operator*() const
Definition: concurrent_vector.h:246
_Vector_iterator & operator-=(ptrdiff_t _Offset)
Definition: concurrent_vector.h:240
concurrent_vector(const allocator_type &_Al=allocator_type())
Constructs a concurrent vector.
Definition: concurrent_vector.h:521
_CRTIMP _In_ int _Value
Definition: setjmp.h:190
_Value * operator->() const
Definition: concurrent_vector.h:258
_Value value_type
Definition: concurrent_vector.h:323
void _Internal_truncate(_Size_type _Old_size, _Size_type _New_size, _Size_type _Element_size, _My_internal_array_op1 _Destroy)
_Vector_iterator()
Definition: concurrent_vector.h:214
void _Assign(const void *_Src)
Definition: concurrent_vector.h:1499
~concurrent_vector()
Erases all elements and destroys this concurrent vector.
Definition: concurrent_vector.h:1411
Definition: concurrent_vector.h:63
_Value * pointer
Definition: concurrent_vector.h:324
reverse_iterator rend()
Returns an iterator of type reverse_iterator or const_reverse_iterator to the end of the concurrent...
Definition: concurrent_vector.h:1174
const _Ty * const_pointer
A type that provides a pointer to a const element in a concurrent vector.
Definition: concurrent_vector.h:475
void _Init()
Definition: concurrent_vector.h:1484
#define _CONCRT_ASSERT(x)
Definition: concrt.h:137
bool operator==(const _Concurrent_queue_iterator< _C, _Ty > &_I, const _Concurrent_queue_iterator< _C, _U > &_J)
Definition: concurrent_queue.h:317
_W64 unsigned int size_t
Definition: crtdefs.h:496
concurrent_vector(size_type _N, const_reference _Item, const allocator_type &_Al=allocator_type())
Constructs a concurrent vector.
Definition: concurrent_vector.h:661
_Vector_iterator(const _Container &_Vec, size_t _Index, void *_Ptr=NULL)
Definition: concurrent_vector.h:205
iterator grow_to_at_least(size_type _N)
Grows this concurrent vector until it has at least _N elements. This method is concurrency-safe.
Definition: concurrent_vector.h:814
size_type capacity() const
Returns the maximum size to which the concurrent vector can grow without having to allocate more memo...
Definition: concurrent_vector.h:1001
ptrdiff_t difference_type
A type that provides the signed distance between two elements in a concurrent vector.
Definition: concurrent_vector.h:450
reference at(size_type _Index)
Provides access to the element at the given index in the concurrent vector. This method is concurrenc...
Definition: concurrent_vector.h:929
void swap(concurrent_vector< _Ty, _Ax > &_A, concurrent_vector< _Ty, _Ax > &_B)
Exchanges the elements of two concurrent_vector objects.
Definition: concurrent_vector.h:1955
_N
Definition: wchar.h:1269
static _Size_type _Segment_size(_Segment_index_t _K)
Definition: concurrent_vector.h:118
_OutIt move(_InIt _First, _InIt _Last, _OutIt _Dest)
Definition: xutility:2447
size_type _I
Definition: concurrent_vector.h:1478
typedef void(__cdecl *_se_translator_function)(unsigned int
details::_Vector_iterator< concurrent_vector, _Ty > iterator
A type that provides a random-access iterator that can read any element in a concurrent vector...
Definition: concurrent_vector.h:482
The Concurrency namespace provides classes and functions that provide access to the Concurrency Runti...
Definition: agents.h:42
bool operator!=(const _Tuple_type< _Rank > &_Lhs, const _Tuple_type< _Rank > &_Rhs) __GPU
Definition: amp.h:816
static _Segment_index_t _Segment_base_index_of(_Segment_index_t &_Index)
Definition: concurrent_vector.h:111
Definition: concurrent_vector.h:1440
void swap(concurrent_vector &_Vector)
Swaps the contents of two concurrent vectors. This method is not concurrency-safe.
Definition: concurrent_vector.h:1384
void _Internal_assign(_I _First, _I _Last, _Is_integer_tag< true > *)
Definition: concurrent_vector.h:1444
Definition: concurrent_vector.h:175
friend ptrdiff_t operator-(const _Vector_iterator< _C, _Ty > &, const _Vector_iterator< _C, _U > &)
_Ty & reference
A type that provides a reference to an element stored in a concurrent vector.
Definition: concurrent_vector.h:456
_Internal_loop_guide(size_type _NTrials, void *_Ptr)
Definition: concurrent_vector.h:1479
void * _My_array
Definition: concurrent_vector.h:81
const pointer _My_array
Definition: concurrent_vector.h:1476
iterator grow_by(size_type _Delta)
Grows this concurrent vector by _Delta elements. This method is concurrency-safe.
Definition: concurrent_vector.h:777
_CRTIMP2 _Segment_index_t _Internal_clear(_My_internal_array_op1 _Destroy)
static void __cdecl _Initialize_array(void *_Begin, const void *, size_type _N)
Definition: concurrent_vector.h:1652
#define NULL
Definition: crtdbg.h:30
static const _Segment_index_t _Pointers_per_long_table
Definition: concurrent_vector.h:76
void assign(size_type _N, const_reference _Item)
Erases the elements of the concurrent vector and assigns to it either _N copies of _Item ...
Definition: concurrent_vector.h:1345
details::_Allocator_base< _Ty, _Ax >::_Allocator_type allocator_type
A type that represents the allocator class for the concurrent vector.
Definition: concurrent_vector.h:438
void _Copy(const void *_Src)
Definition: concurrent_vector.h:1494
iterator_traits< _InIt >::difference_type distance(_InIt _First, _InIt _Last)
Definition: xutility:755
_Container * _My_vector
Definition: concurrent_vector.h:178
_Vector_iterator & operator--()
Definition: concurrent_vector.h:284
_CRTIMP2 _Size_type _Internal_grow_to_at_least_with_result(_Size_type _New_size, _Size_type _Element_size, _My_internal_array_op2 _Init, const void *_Src)
concurrent_vector(concurrent_vector &&_Vector)
Constructs a concurrent vector.
Definition: concurrent_vector.h:603
void _Init(const void *_Src)
Definition: concurrent_vector.h:1489
const _Ty & const_reference
A type that provides a reference to a const element stored in a concurrent vector for reading and per...
Definition: concurrent_vector.h:463
concurrent_vector(size_type _N)
Constructs a concurrent vector.
Definition: concurrent_vector.h:628
_CRTIMP2 void _Internal_resize(_Size_type _New_size, _Size_type _Element_size, _Size_type _Max_size, _My_internal_array_op1 _Destroy, _My_internal_array_op2 _Init, const void *_Src)
static void __cdecl _Initialize_array_by(void *_Begin, const void *_Src, size_type _N)
Definition: concurrent_vector.h:1658
size_type max_size() const
Returns the maximum number of elements the concurrent vector can hold. This method is concurrency-saf...
Definition: concurrent_vector.h:1090
void shrink_to_fit()
Compacts the internal representation of the concurrent vector to reduce fragmentation and optimize me...
Definition: concurrent_vector.h:1529
reference back()
Returns a reference or a const reference to the last element in the concurrent vector. If the concurrent vector is empty, the return value is undefined. This method is concurrency-safe.
Definition: concurrent_vector.h:1295
reverse_iterator rbegin()
Returns an iterator of type reverse_iterator or const_reverse_iterator to the beginning of the conc...
Definition: concurrent_vector.h:1160
concurrent_vector< _Ty, _Ax > _Myt
Definition: concurrent_vector.h:421
size_t _Segment_index_t
Definition: concurrent_vector.h:68
void _Destroy(_Ty *_Ptr)
Definition: xmemory0:53
_In_ size_t _In_z_ const unsigned char * _Src
Definition: mbstring.h:95
_Allocator_base(const _Allocator_type &_Al=_Allocator_type())
Definition: concurrent_vector.h:391
_Vector_iterator & operator++()
Definition: concurrent_vector.h:264
_Value & operator[](ptrdiff_t _K) const
Definition: concurrent_vector.h:254
concurrent_vector & operator=(const concurrent_vector &_Vector)
Assigns the contents of another concurrent_vector object to this one. This method is not concurrency-...
Definition: concurrent_vector.h:713
_W64 int ptrdiff_t
Definition: crtdefs.h:530
void resize(size_type _N, const _Ty &_Val)
Changes the size of the concurrent vector to the requested size, deleting or adding elements as neces...
Definition: concurrent_vector.h:1078
_Ty & _Internal_subscript_with_exceptions(size_type _Index) const
Definition: concurrent_vector.h:1582
void internal_assign_iterators(_I _First, _I _Last)
Definition: concurrent_vector.h:1623
const_reference at(size_type _Index) const
Provides access to the element at the given index in the concurrent vector. This method is concurrenc...
Definition: concurrent_vector.h:954
_Size_type _Internal_grow_segment(const _Size_type _Start, _Size_type _Finish, _Size_type _Element_size, _Segment_t **_PPSegment, _Size_type *_PSegStart, _Size_type *_PSegFinish)
_Subatomic< _Size_type > _My_early_size
Definition: concurrent_vector.h:158
void * _Table[_Pointers_per_long_table]
Definition: concurrent_vector.h:133
iterator begin()
Returns an iterator of type iterator or const_iterator to the beginning of the concurrent vector...
Definition: concurrent_vector.h:1104
_CRTIMP2 void * _Internal_push_back(_Size_type _Element_size, _Size_type &_Index)
const_iterator cend() const
Returns an iterator of type const_iterator to the end of the concurrent vector. This method is concu...
Definition: concurrent_vector.h:1228
std::reverse_iterator< const_iterator > const_reverse_iterator
A type that provides a random-access iterator that can read any const element in the concurrent vecto...
Definition: concurrent_vector.h:501
_Value * _My_item
Definition: concurrent_vector.h:185
static void __cdecl _Assign_array(void *_Dst, const void *_Src, size_type _N)
Definition: concurrent_vector.h:1669
_Concurrent_vector_base_v4 _Concurrent_vector_base
Definition: concurrent_vector.h:170
::Concurrency::details::_Concurrent_vector_base_v4 & _Internal_vector_base()
Definition: concurrent_vector.h:1419
The concurrent_vector class is a sequence container class that allows random access to any element...
Definition: concurrent_vector.h:54
_Vector_iterator operator--(int)
Definition: concurrent_vector.h:313
void assign(_InputIterator _Begin, _InputIterator _End)
Erases the elements of the concurrent vector and assigns to it either _N copies of _Item ...
Definition: concurrent_vector.h:1371
_Concurrent_vector_base_v4()
Definition: concurrent_vector.h:94
_CRTIMP2 void * _Internal_compact(_Size_type _Element_size, void *_Table, _My_internal_array_op1 _Destroy, _My_internal_array_op2 _Copy)
void resize(size_type _N)
Changes the size of the concurrent vector to the requested size, deleting or adding elements as neces...
Definition: concurrent_vector.h:1053
_Vector_iterator< _Container, _Ty > operator+(ptrdiff_t _Offset, const _Vector_iterator< _Container, _Ty > &_Vec)
Definition: concurrent_vector.h:336
void(__cdecl * _My_internal_array_op1)(void *_Begin, _Size_type _N)
Definition: concurrent_vector.h:124
static void __cdecl _Copy_array(void *_Dst, const void *_Src, size_type _N)
Definition: concurrent_vector.h:1664
static void *__cdecl _Internal_allocator(::Concurrency::details::_Concurrent_vector_base_v4 &_Vb, size_t _K)
Definition: concurrent_vector.h:1423
iterator push_back(const_reference _Item)
Appends the given item to the end of the concurrent vector. This method is concurrency-safe.
Definition: concurrent_vector.h:836
static _Segment_index_t _Segment_base(_Segment_index_t _K)
Definition: concurrent_vector.h:106
_Vector_iterator & operator+=(ptrdiff_t _Offset)
Definition: concurrent_vector.h:230
const_reverse_iterator rbegin() const
Returns an iterator of type reverse_iterator or const_reverse_iterator to the beginning the concurr...
Definition: concurrent_vector.h:1188
static const _Segment_index_t _Default_initial_segments
Definition: concurrent_vector.h:72
Definition: concurrent_vector.h:1473
static const _Segment_index_t _Pointers_per_short_table
Definition: concurrent_vector.h:75
_Subatomic< _Size_type > _My_first_block
Definition: concurrent_vector.h:155
_Ty value_type
A type that represents the data type stored in a concurrent vector.
Definition: concurrent_vector.h:444
_CRTIMP2 void _Internal_assign(const _Concurrent_vector_base_v4 &_Src, _Size_type _Element_size, _My_internal_array_op1 _Destroy, _My_internal_array_op2 _Assign, _My_internal_array_op2 _Copy)
details::_Vector_iterator< concurrent_vector, const _Ty > const_iterator
A type that provides a random-access iterator that can read a const element in a concurrent vector...
Definition: concurrent_vector.h:488
const_iterator end() const
Returns an iterator of type iterator or const_iterator to the end of the concurrent vector...
Definition: concurrent_vector.h:1146
_Segment_t _My_storage[_Pointers_per_short_table]
Definition: concurrent_vector.h:90
size_t _My_index
Definition: concurrent_vector.h:181
void _Iterate(_It &_Src)
Definition: concurrent_vector.h:1504
void _Internal_free_segments(void *_Table[], _Segment_index_t _K, _Segment_index_t _First_block)
Definition: concurrent_vector.h:1546
void _Internal_assign(_I _First, _I _Last, _Is_integer_tag< false > *)
Definition: concurrent_vector.h:1450
friend _Vector_iterator< _C, _Ty > operator+(ptrdiff_t _Offset, const _Vector_iterator< _C, _Ty > &_Vec)
_Vector_iterator operator-(ptrdiff_t _Offset) const
Definition: concurrent_vector.h:236
#define _CRTIMP2
Definition: crtdefs.h:126
const_iterator cbegin() const
Returns an iterator of type const_iterator to the beginning of the concurrent vector. This method is concurrency-safe.
Definition: concurrent_vector.h:1215
const size_type _N
Definition: concurrent_vector.h:1477
const_reverse_iterator crbegin() const
Returns an iterator of type const_reverse_iterator to the beginning of the concurrent vector...
Definition: concurrent_vector.h:1241
const_reference back() const
Returns a reference or a const reference to the last element in the concurrent_vector. If the concurrent vector is empty, the return value is undefined. This method is concurrency-safe.
Definition: concurrent_vector.h:1310
bool operator>=(const concurrent_vector< _Ty, A1 > &_A, const concurrent_vector< _Ty, A2 > &_B)
Tests if the concurrent_vector object on the left side of the operator is greater than or equal to th...
Definition: concurrent_vector.h:1919
const_iterator begin() const
Returns an iterator of type iterator or const_iterator to the beginning of the concurrent vector...
Definition: concurrent_vector.h:1132
void reserve(size_type _N)
Allocates enough space to grow the concurrent vector to size _N without having to allocate more memo...
Definition: concurrent_vector.h:1019
Definition: concurrent_vector.h:384
const_reverse_iterator crend() const
Returns an iterator of type const_reverse_iterator to the end of the concurrent vector. This method is concurrency-safe.
Definition: concurrent_vector.h:1254
_Ty & _Internal_subscript(size_type _Index) const
Definition: concurrent_vector.h:1568
#define _BAD_ALLOC_MARKER
Definition: concurrent_vector.h:60
void operator=(const _Internal_loop_guide &)
ptrdiff_t difference_type
Definition: concurrent_vector.h:322
_Value & reference
Definition: concurrent_vector.h:325
details::_Concurrent_vector_base_v4::_Size_type size_type
A type that counts the number of elements in a concurrent vector.
Definition: concurrent_vector.h:432
bool operator>=(const _Vector_iterator< _Container, _Ty > &_I, const _Vector_iterator< _Container, _U > &_J)
Definition: concurrent_vector.h:366
bool operator>(const _Vector_iterator< _Container, _Ty > &_I, const _Vector_iterator< _Container, _U > &_J)
Definition: concurrent_vector.h:360
concurrent_vector & operator=(concurrent_vector &&_Vector)
Assigns the contents of another concurrent_vector object to this one. This method is not concurrency-...
Definition: concurrent_vector.h:754
concurrent_vector(const concurrent_vector< _Ty, M > &_Vector, const allocator_type &_Al=allocator_type())
Constructs a concurrent vector.
Definition: concurrent_vector.h:577
concurrent_vector & operator=(const concurrent_vector< _Ty, M > &_Vector)
Assigns the contents of another concurrent_vector object to this one. This method is not concurrency-...
Definition: concurrent_vector.h:734
friend bool operator==(const _Vector_iterator< _C, _Ty > &, const _Vector_iterator< _C, _U > &)
bool operator!=(const _Concurrent_queue_iterator< _C, _Ty > &_I, const _Concurrent_queue_iterator< _C, _U > &_J)
Definition: concurrent_queue.h:323
_CRTIMP2 _Size_type _Internal_grow_by(_Size_type _Delta, _Size_type _Element_size, _My_internal_array_op2 _Init, const void *_Src)
allocator_type get_allocator() const
Returns a copy of the allocator used to construct the concurrent vector. This method is concurrency-s...
Definition: concurrent_vector.h:1324
bool empty() const
Tests if the concurrent vector is empty at the time this method is called. This method is concurrency...
Definition: concurrent_vector.h:985
iterator grow_by(size_type _Delta, const_reference _Item)
Grows this concurrent vector by _Delta elements. This method is concurrency-safe.
Definition: concurrent_vector.h:798
static _CRTIMP2 _Segment_index_t __cdecl _Segment_index_of(_Size_type _Index)
_FwdIt const _Ty _Val
Definition: algorithm:1938
_Subatomic< _Segment_t * > _My_segment
Definition: concurrent_vector.h:161
bool operator>(const concurrent_vector< _Ty, A1 > &_A, const concurrent_vector< _Ty, A2 > &_B)
Tests if the concurrent_vector object on the left side of the operator is greater than the concurrent...
Definition: concurrent_vector.h:1843
static void __cdecl _Destroy_array(void *_Begin, size_type _N)
Definition: concurrent_vector.h:1678
bool lexicographical_compare(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2)
Definition: memory:830
_CRTIMP2 void _Internal_swap(_Concurrent_vector_base_v4 &)
_CRTIMP2 void _Internal_reserve(_Size_type _N, _Size_type _Element_size, _Size_type _Max_size)
ptrdiff_t operator-(const _Vector_iterator< _Container, _Ty > &_I, const _Vector_iterator< _Container, _U > &_J)
Definition: concurrent_vector.h:378
const_reference operator[](size_type _Index) const
Provides read access to element at the given index in the concurrent vector. This method is concurren...
Definition: concurrent_vector.h:904
friend class _Helper
Definition: concurrent_vector.h:166
std::reverse_iterator< iterator > reverse_iterator
A type that provides a random-access iterator that can read any element in a reversed concurrent vect...
Definition: concurrent_vector.h:495
_FwdIt _Last
Definition: algorithm:1936
Definition: xmemory0:493
void clear()
Erases all elements in the concurrent vector. This method is not concurrency-safe.
Definition: concurrent_vector.h:1402
size_type size() const
Returns the number of elements in the concurrent vector. This method is concurrency-safe.
Definition: concurrent_vector.h:971
_Ax::template rebind< _Ty >::other _Allocator_type
Definition: concurrent_vector.h:388
bool operator==(const _Tuple_type< _Rank > &_Lhs, const _Tuple_type< _Rank > &_Rhs) __GPU
Definition: amp.h:810
void _Internal_assign(size_type _N, const_reference _Item)
Definition: concurrent_vector.h:1597
std::random_access_iterator_tag iterator_category
Definition: concurrent_vector.h:326
iterator end()
Returns an iterator of type iterator or const_iterator to the end of the concurrent vector...
Definition: concurrent_vector.h:1118
reference front()
Returns a reference or a const reference to the first element in the concurrent vector. If the concurrent vector is empty, the return value is undefined. This method is concurrency-safe.
Definition: concurrent_vector.h:1267
concurrent_vector(_InputIterator _Begin, _InputIterator _End, const allocator_type &_Al=allocator_type())
Constructs a concurrent vector.
Definition: concurrent_vector.h:696
_Ty * pointer
A type that provides a pointer to an element in a concurrent vector.
Definition: concurrent_vector.h:469
_Allocator_type _My_allocator
Definition: concurrent_vector.h:389
_Segment_index_t _First_block
Definition: concurrent_vector.h:132