STLdoc
STLdocumentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
internal_split_ordered_list.h
Go to the documentation of this file.
1 /***
2 * ==++==
3 *
4 * Copyright (c) Microsoft Corporation. All rights reserved.
5 *
6 * ==--==
7 * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
8 *
9 * internal_split_ordered_list.h
10 *
11 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
12 ****/
13 #pragma once
14 
15 // Needed for forward iterators
16 #include <forward_list>
17 #include <concrt.h>
18 
19 #pragma pack(push,_CRT_PACKING)
20 
21 #pragma warning (push)
22 #pragma warning (disable: 4510 4512 4610) // disable warnings for compiler unable to generate constructor
23 
24 namespace Concurrency
25 {
26 namespace details
27 {
28 // Split-order list iterators, needed to skip dummy elements
29 template<class _Mylist>
30 class _Solist_const_iterator : public std::_Flist_const_iterator<_Mylist>
31 {
32 public:
34  typedef std::_Flist_const_iterator<_Mylist> _Mybase;
35  typedef std::forward_iterator_tag iterator_category;
36 
37  typedef typename _Mylist::_Nodeptr _Nodeptr;
38  typedef typename _Mylist::value_type value_type;
39  typedef typename _Mylist::difference_type difference_type;
40  typedef typename _Mylist::const_pointer pointer;
41  typedef typename _Mylist::const_reference reference;
42 
44  {
45  }
46 
47  _Solist_const_iterator(_Nodeptr _Pnode, const _Mylist * _Plist) : _Mybase(_Pnode, _Plist)
48  {
49  }
50 
52 
53  _Myiter& _Rechecked(_Unchecked_type _Right)
54  {
55  _Ptr = _Right._Ptr;
56  return (*this);
57  }
58 
59  _Unchecked_type _Unchecked() const
60  {
61  return (_Unchecked_type(_Ptr, (_Mylist *)_Getcont()));
62  }
63 
64  reference operator*() const
65  {
66  return ((reference)**(_Mybase *)this);
67  }
68 
69  pointer operator->() const
70  {
71  return (&**this);
72  }
73 
74  _Myiter& operator++()
75  {
76  do
77  {
78  ++(*(_Mybase *)this);
79  }
80  while (_Mynode() != NULL && _Mynode()->_Is_dummy());
81 
82  return (*this);
83  }
84 
85  _Myiter operator++(int)
86  {
87  _Myiter _Tmp = *this;
88  do
89  {
90  ++*this;
91  }
92  while (_Mynode() != NULL && _Mynode()->_Is_dummy());
93 
94  return (_Tmp);
95  }
96 };
97 
98 template<class _Mylist> inline
100 {
101  return (_Iterator._Unchecked());
102 }
103 
104 template<class _Mylist> inline
107 {
108  return (_Iterator._Rechecked(_Right));
109 }
110 
111 template<class _Mylist>
113 {
114 public:
117  typedef std::forward_iterator_tag iterator_category;
118 
119  typedef typename _Mylist::_Nodeptr _Nodeptr;
120  typedef typename _Mylist::value_type value_type;
121  typedef typename _Mylist::difference_type difference_type;
122  typedef typename _Mylist::pointer pointer;
123  typedef typename _Mylist::reference reference;
124 
126  {
127  }
128 
129  _Solist_iterator(_Nodeptr _Pnode, const _Mylist *_Plist) : _Mybase(_Pnode, _Plist)
130  {
131  }
132 
134 
135  _Myiter& _Rechecked(_Unchecked_type _Right)
136  {
137  _Ptr = _Right._Ptr;
138  return (*this);
139  }
140 
141  _Unchecked_type _Unchecked() const
142  {
143  return (_Unchecked_type(_Ptr, (_Mylist *)_Getcont()));
144  }
145 
146  reference operator*() const
147  {
148  return ((reference)**(_Mybase *)this);
149  }
150 
151  pointer operator->() const
152  {
153  return (&**this);
154  }
155 
156  _Myiter& operator++()
157  {
158  do
159  {
160  ++(*(_Mybase *)this);
161  }
162  while (_Mynode() != NULL && _Mynode()->_Is_dummy());
163 
164  return (*this);
165  }
166 
167  _Myiter operator++(int)
168  {
169  _Myiter _Tmp = *this;
170  do
171  {
172  ++*this;
173  }
174  while (_Mynode() != NULL && _Mynode()->_Is_dummy());
175 
176  return (_Tmp);
177  }
178 };
179 
180 template<class _Mylist> inline
182 {
183  return (_Iterator._Unchecked());
184 }
185 
186 template<class _Mylist> inline
189 {
190  return (_Iterator._Rechecked(_Right));
191 }
192 
193 // Forward type and class definitions
194 typedef size_t _Map_key;
195 typedef _Map_key _Split_order_key;
196 
197 template<typename _Element_type, typename _Allocator_type>
199 {
200 public:
201  typedef typename _Allocator_type::template rebind<_Element_type>::other _Allocator_type;
202  typedef typename _Allocator_type::size_type size_type;
203  typedef typename _Element_type value_type;
204 
205  struct _Node;
206  typedef _Node * _Nodeptr;
207  typedef _Nodeptr& _Nodepref;
208 
209  // Node that holds the element in a split-ordered list
210  struct _Node
211  {
212  // Initialize the node with the given order key
213  void _Init(_Split_order_key _Order_key)
214  {
215  _M_order_key = _Order_key;
216  _M_next = NULL;
217  }
218 
219  // Return the order key (needed for hashing)
220  _Split_order_key _Get_order_key() const
221  {
222  return _M_order_key;
223  }
224 
225  // Inserts the new element in the list in an atomic fashion
226  _Nodeptr _Atomic_set_next(_Nodeptr _New_node, _Nodeptr _Current_node)
227  {
228  // Try to change the next pointer on the current element to a new element, only if it still points to the cached next
229  _Nodeptr _Exchange_node = (_Nodeptr) _InterlockedCompareExchangePointer((void * volatile *) &_M_next, _New_node, _Current_node);
230 
231  if (_Exchange_node == _Current_node)
232  {
233  // Operation succeeded, return the new node
234  return _New_node;
235  }
236  else
237  {
238  // Operation failed, return the "interfering" node
239  return _Exchange_node;
240  }
241  }
242 
243  // Checks if this element in the list is a dummy, order-enforcing node. Dummy nodes are used by buckets
244  // in the hash table to quickly index into the right subsection of the split-ordered list.
245  bool _Is_dummy() const
246  {
247  return (_M_order_key & 0x1) == 0;
248  }
249 
250  // dummy default constructor - never used but for suppress warning
251  _Node();
252 
253  _Nodeptr _M_next; // Next element in the list
254  value_type _M_element; // Element storage
255  _Split_order_key _M_order_key; // Order key for this element
256  };
257 
258 #if _ITERATOR_DEBUG_LEVEL == 0
259  _Split_order_list_node(_Allocator_type _Allocator) : _M_node_allocator(_Allocator), _M_value_allocator(_Allocator)
260  {
261  }
262 #else /* _ITERATOR_DEBUG_LEVEL == 0 */
263  _Split_order_list_node(_Allocator_type _Allocator) : _M_node_allocator(_Allocator), _M_value_allocator(_Allocator)
264  {
265  typename _Allocator_type::template rebind<std::_Container_proxy>::other _Alproxy(_M_node_allocator);
266  _Myproxy = _Alproxy.allocate(1);
267  _Alproxy.construct(_Myproxy, std::_Container_proxy());
268  _Myproxy->_Mycont = this;
269  }
270 
272  {
273  typename _Allocator_type::template rebind<std::_Container_proxy>::other _Alproxy(_M_node_allocator);
274  _Orphan_all();
275  _Alproxy.destroy(_Myproxy);
276  _Alproxy.deallocate(_Myproxy, 1);
277  _Myproxy = 0;
278  }
279 #endif /* _ITERATOR_DEBUG_LEVEL == 0 */
280 
281  _Nodeptr _Myhead; // pointer to head node
282  typename _Allocator_type::template rebind<_Node>::other _M_node_allocator; // allocator object for nodes
283  _Allocator_type _M_value_allocator; // allocator object for element values
284 };
285 
286 template<typename _Element_type, typename _Allocator_type>
287 class _Split_order_list_value : public _Split_order_list_node<_Element_type, _Allocator_type>
288 {
289 public:
291  typedef typename _Mybase::_Nodeptr _Nodeptr;
292  typedef typename _Mybase::_Nodepref _Nodepref;
293  typedef typename _Allocator_type::template rebind<_Element_type>::other _Allocator_type;
294 
295  typedef typename _Allocator_type::size_type size_type;
296  typedef typename _Allocator_type::difference_type difference_type;
297  typedef typename _Allocator_type::pointer pointer;
298  typedef typename _Allocator_type::const_pointer const_pointer;
299  typedef typename _Allocator_type::reference reference;
300  typedef typename _Allocator_type::const_reference const_reference;
301  typedef typename _Allocator_type::value_type value_type;
302 
303  _Split_order_list_value(_Allocator_type _Allocator = _Allocator_type()) : _Mybase(_Allocator)
304  {
305  // Immediately allocate a dummy node with order key of 0. This node
306  // will always be the head of the list.
307  _Myhead = _Buynode(0);
308  }
309 
311  {
312  }
313 
314  // Allocate a new node with the given order key and value
315  template<typename _ValTy>
316  _Nodeptr _Buynode(_Split_order_key _Order_key, _ValTy&& _Value)
317  {
318  _Nodeptr _Pnode = _M_node_allocator.allocate(1);
319 
320  try
321  {
322  _M_value_allocator.construct(std::addressof(_Myval(_Pnode)), std::forward<_ValTy>(_Value));
323  _Pnode->_Init(_Order_key);
324  }
325  catch(...)
326  {
327  _M_node_allocator.deallocate(_Pnode, 1);
328  throw;
329  }
330 
331  return (_Pnode);
332  }
333 
334  // Allocate a new node with the given order key; used to allocate dummy nodes
335  _Nodeptr _Buynode(_Split_order_key _Order_key)
336  {
337  _Nodeptr _Pnode = _M_node_allocator.allocate(1);
338  _Pnode->_Init(_Order_key);
339 
340  return (_Pnode);
341  }
342 
343  // Get the next node
344  static _Nodepref _Nextnode(_Nodeptr _Pnode)
345  {
346  return ((_Nodepref)(*_Pnode)._M_next);
347  }
348 
349  // Get the stored value
350  static reference _Myval(_Nodeptr _Pnode)
351  {
352  return ((reference)(*_Pnode)._M_element);
353  }
354 };
355 
356 // Forward list in which elements are sorted in a split-order
357 template <typename _Element_type, typename _Element_allocator_type = std::allocator<_Element_type> >
358 class _Split_ordered_list : _Split_order_list_value<_Element_type, _Element_allocator_type>
359 {
360 public:
364  typedef typename _Mybase::_Nodeptr _Nodeptr;
365 
366  typedef _Allocator_type allocator_type;
367  typedef typename _Allocator_type::size_type size_type;
368  typedef typename _Allocator_type::difference_type difference_type;
369  typedef typename _Allocator_type::pointer pointer;
370  typedef typename _Allocator_type::const_pointer const_pointer;
371  typedef typename _Allocator_type::reference reference;
372  typedef typename _Allocator_type::const_reference const_reference;
373  typedef typename _Allocator_type::value_type value_type;
374 
377  typedef std::_Flist_const_iterator<_Mybase> _Full_const_iterator;
378  typedef std::_Flist_iterator<_Mybase> _Full_iterator;
379  typedef std::pair<iterator, bool> _Pairib;
381  _Split_ordered_list(_Allocator_type _Allocator = allocator_type()) : _Mybase(_Allocator), _M_element_count(0)
382  {
383  }
384 
386  {
387  // Clear the list
388  clear();
389 
390  // Remove the head element which is not cleared by clear()
391  _Nodeptr _Pnode = _Myhead;
392  _Myhead = NULL;
393 
394  _ASSERT_EXPR(_Pnode != NULL && _Nextnode(_Pnode) == NULL, L"Invalid head list node");
395 
396  _Erase(_Pnode);
397  }
398 
399  // Common forward list functions
400 
401  allocator_type get_allocator() const
402  {
403  return (_M_value_allocator);
404  }
405 
406  void clear()
407  {
408 #if _ITERATOR_DEBUG_LEVEL == 2
409  _Orphan_ptr(*this, 0);
410 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
411 
412  _Nodeptr _Pnext;
413  _Nodeptr _Pnode = _Myhead;
414 
415  _ASSERT_EXPR(_Myhead != NULL, L"Invalid head list node");
416  _Pnext = _Nextnode(_Pnode);
417  _Pnode->_M_next = NULL;
418  _Pnode = _Pnext;
419 
420  while (_Pnode != NULL)
421  {
422  _Pnext = _Nextnode(_Pnode);
423  _Erase(_Pnode);
424  _Pnode = _Pnext;
425  }
426 
427  _M_element_count = 0;
428  }
429 
430  // Returns a first non-dummy element in the SOL
431  iterator begin()
432  {
433  _Full_iterator _Iterator = _Begin();
434  return _Get_first_real_iterator(_Iterator);
435  }
436 
437  // Returns a first non-dummy element in the SOL
438  const_iterator begin() const
439  {
440  _Full_const_iterator _Iterator = _Begin();
441  return _Get_first_real_iterator(_Iterator);
442  }
443 
444  iterator end()
445  {
446  return (iterator(0, this));
447  }
448 
449  const_iterator end() const
450  {
451  return (const_iterator(0, this));
452  }
453 
454  const_iterator cbegin() const
455  {
456  return (((const _Mytype *)this)->begin());
457  }
458 
459  const_iterator cend() const
460  {
461  return (((const _Mytype *)this)->end());
462  }
463 
464  // Checks if the number of elements (non-dummy) is 0
465  bool empty() const
466  {
467  return (_M_element_count == 0);
468  }
469 
470  // Returns the number of non-dummy elements in the list
471  size_type size() const
472  {
473  return _M_element_count;
474  }
475 
476  // Returns the maximum size of the list, determined by the allocator
477  size_type max_size() const
478  {
479  return _M_value_allocator.max_size();
480  }
481 
482  // Swaps 'this' list with the passed in one
483  void swap(_Mytype& _Right)
484  {
485  if (this == &_Right)
486  {
487  // Nothing to do
488  return;
489  }
490 
492  {
493  _Swap_all(_Right);
494  std::swap(_Myhead, _Right._Myhead);
496  }
497  else
498  {
499  _Mytype _Temp_list(this->get_allocator());
500  _Temp_list._Move_all(_Right);
501  _Right._Move_all(*this);
502  _Move_all(_Temp_list);
503  }
504  }
505 
506  // Split-order list functions
507 
508  // Returns a first element in the SOL, which is always a dummy
509  _Full_iterator _Begin()
510  {
511  return _Full_iterator(_Myhead, this);
512  }
513 
514  // Returns a first element in the SOL, which is always a dummy
515  _Full_const_iterator _Begin() const
516  {
517  return _Full_const_iterator(_Myhead, this);
518  }
519 
520  _Full_iterator _End()
521  {
522  return _Full_iterator(0, this);
523  }
524 
525  _Full_const_iterator _End() const
526  {
527  return _Full_const_iterator(0, this);
528  }
529 
530  static _Split_order_key _Get_key(const _Full_const_iterator& _Iterator)
531  {
532  return _Iterator._Mynode()->_Get_order_key();
533  }
534 
535  // Returns a public iterator version of the internal iterator. Public iterator must not
536  // be a dummy private iterator.
537  iterator _Get_iterator(_Full_iterator _Iterator)
538  {
539  _ASSERT_EXPR(_Iterator._Mynode() != NULL && !_Iterator._Mynode()->_Is_dummy(), L"Invalid user node (dummy)");
540  return iterator(_Iterator._Mynode(), this);
541  }
542 
543  // Returns a public iterator version of the internal iterator. Public iterator must not
544  // be a dummy private iterator.
545  const_iterator _Get_iterator(_Full_const_iterator _Iterator) const
546  {
547  _ASSERT_EXPR(_Iterator._Mynode() != NULL && !_Iterator._Mynode()->_Is_dummy(), L"Invalid user node (dummy)");
548  return const_iterator(_Iterator._Mynode(), this);
549  }
550 
551  // Returns a non-const version of the _Full_iterator
552  _Full_iterator _Get_iterator(_Full_const_iterator _Iterator)
553  {
554  return _Full_iterator(_Iterator._Mynode(), this);
555  }
556 
557  // Returns a non-const version of the iterator
558  iterator _Get_iterator(const_iterator _Iterator)
559  {
560  return iterator(_Iterator._Mynode(), this);
561  }
562 
563  // Returns a public iterator version of a first non-dummy internal iterator at or after
564  // the passed in internal iterator.
565  iterator _Get_first_real_iterator(_Full_iterator _Iterator)
566  {
567  // Skip all dummy, internal only iterators
568  while (_Iterator != _End() && _Iterator._Mynode()->_Is_dummy())
569  {
570  _Iterator++;
571  }
572 
573  return iterator(_Iterator._Mynode(), this);
574  }
575 
576  // Returns a public iterator version of a first non-dummy internal iterator at or after
577  // the passed in internal iterator.
578  const_iterator _Get_first_real_iterator(_Full_const_iterator _Iterator) const
579  {
580  // Skip all dummy, internal only iterators
581  while (_Iterator != _End() && _Iterator._Mynode()->_Is_dummy())
582  {
583  _Iterator++;
584  }
585 
586  return const_iterator(_Iterator._Mynode(), this);
587  }
588 
589  // Erase an element using the allocator
590  void _Erase(_Nodeptr _Delete_node)
591  {
592  if (!_Delete_node->_Is_dummy())
593  {
594  // Dummy nodes have nothing constructed, thus should not be destroyed.
595  _M_node_allocator.destroy(_Delete_node);
596  }
597  _M_node_allocator.deallocate(_Delete_node, 1);
598  }
599 
600  // Try to insert a new element in the list. If insert fails, return the node that
601  // was inserted instead.
602  _Nodeptr _Insert(_Nodeptr _Previous, _Nodeptr _New_node, _Nodeptr _Current_node)
603  {
604  _New_node->_M_next = _Current_node;
605  return _Previous->_Atomic_set_next(_New_node, _Current_node);
606  }
607 
608  // Insert a new element between passed in iterators
609  _Pairib _Insert(_Full_iterator _Iterator, _Full_iterator _Next, _Nodeptr _List_node, long * _New_count)
610  {
611  _Nodeptr _Inserted_node = _Insert(_Iterator._Mynode(), _List_node, _Next._Mynode());
612 
613  if (_Inserted_node == _List_node)
614  {
615  // If the insert succeeded, check that the order is correct and increment the element count
616  _Check_range();
617  *_New_count = _InterlockedIncrement(&_M_element_count);
618  return _Pairib(iterator(_List_node, this), true);
619  }
620  else
621  {
622  return _Pairib(end(), false);
623  }
624  }
625 
626  // Insert a new dummy element, starting search at a parent dummy element
627  _Full_iterator _Insert_dummy(_Full_iterator _Iterator, _Split_order_key _Order_key)
628  {
629  _Full_iterator _Last = _End();
630  _Full_iterator _Where = _Iterator;
631 
632  _ASSERT_EXPR(_Where != _Last, L"Invalid head node");
633 
634  _Where++;
635 
636  // Create a dummy element up front, even though it may be discarded (due to concurrent insertion)
637  _Nodeptr _Dummy_node = _Buynode(_Order_key);
638 
639  for (;;)
640  {
641  _ASSERT_EXPR(_Iterator != _Last, L"Invalid head list node");
642 
643  // If the head iterator is at the end of the list, or past the point where this dummy
644  // node needs to be inserted, then try to insert it.
645  if (_Where == _Last || _Get_key(_Where) > _Order_key)
646  {
647  _ASSERT_EXPR(_Get_key(_Iterator) < _Order_key, L"Invalid node order in the list");
648 
649  // Try to insert it in the right place
650  _Nodeptr _Inserted_node = _Insert(_Iterator._Mynode(), _Dummy_node, _Where._Mynode());
651 
652  if (_Inserted_node == _Dummy_node)
653  {
654  // Insertion succeeded, check the list for order violations
655  _Check_range();
656  return _Full_iterator(_Dummy_node, this);
657  }
658  else
659  {
660  // Insertion failed: either dummy node was inserted by another thread, or
661  // a real element was inserted at exactly the same place as dummy node.
662  // Proceed with the search from the previous location where order key was
663  // known to be larger (note: this is legal only because there is no safe
664  // concurrent erase operation supported).
665  _Where = _Iterator;
666  _Where++;
667  continue;
668  }
669  }
670  else if (_Get_key(_Where) == _Order_key)
671  {
672  // Another dummy node with the same value found, discard the new one.
673  _Erase(_Dummy_node);
674  return _Where;
675  }
676 
677  // Move the iterator forward
678  _Iterator = _Where;
679  _Where++;
680  }
681 
682  }
683 
684  // This erase function can handle both real and dummy nodes
685  void _Erase(_Full_iterator _Previous, _Full_const_iterator& _Where)
686  {
687 #if _ITERATOR_DEBUG_LEVEL == 2
688  if (_Where._Getcont() != this || _Where._Ptr == _Myhead)
689  {
690  std::_DEBUG_ERROR("list erase iterator outside range");
691  }
692  _Nodeptr _Pnode = (_Where++)._Mynode();
693  _Orphan_ptr(*this, _Pnode);
694 #else /* _ITERATOR_DEBUG_LEVEL == 2 */
695  _Nodeptr _Pnode = (_Where++)._Mynode();
696 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
697 
698  _Nodeptr _Prevnode = _Previous._Mynode();
699  _ASSERT_EXPR(_Prevnode->_M_next == _Pnode, L"Erase must take consecutive iterators");
700  _Prevnode->_M_next = _Pnode->_M_next;
701 
702  _Erase(_Pnode);
703  }
704 
705  // Erase the element (previous node needs to be passed because this is a forward only list)
706  iterator _Erase(_Full_iterator _Previous, const_iterator _Where)
707  {
708  _Full_const_iterator _Iterator = _Where;
709  _Erase(_Previous, _Iterator);
711 
712  return _Get_iterator(_Get_first_real_iterator(_Iterator));
713  }
714 
715  // Move all elements from the passed in split-ordered list to this one
716  void _Move_all(_Mytype& _Source_list)
717  {
718  _Full_const_iterator _First = _Source_list._Begin();
719  _Full_const_iterator _Last = _Source_list._End();
720 
721  if (_First == _Last)
722  {
723  return;
724  }
725 
726  _Nodeptr _Previous_node = _Myhead;
727  _Full_const_iterator _Begin_iterator = _First++;
728 
729  // Move all elements one by one, including dummy ones
730  for (_Full_const_iterator _Iterator = _First; _Iterator != _Last;)
731  {
732  _Nodeptr _Node = _Iterator._Mynode();
733 
734  _Nodeptr _Dummy_node = _Node->_Is_dummy() ? _Buynode(_Node->_Get_order_key()) : _Buynode(_Node->_Get_order_key(), _Myval(_Node));
735  _Previous_node = _Insert(_Previous_node, _Dummy_node, NULL);
736  _ASSERT_EXPR(_Previous_node != NULL, L"Insertion must succeed");
737  _Full_const_iterator _Where = _Iterator++;
738  _Source_list._Erase(_Get_iterator(_Begin_iterator), _Where);
739  }
740  }
741 
742 private:
743 
744  // Check the list for order violations
746  {
747 #if defined (_DEBUG)
748  for (_Full_iterator _Iterator = _Begin(); _Iterator != _End(); _Iterator++)
749  {
750  _Full_iterator _Next_iterator = _Iterator;
751  _Next_iterator++;
752 
753  _ASSERT_EXPR(_Next_iterator == end() || _Next_iterator._Mynode()->_Get_order_key() >= _Iterator._Mynode()->_Get_order_key(), L"!!! List order inconsistency !!!");
754  }
755 #endif /* defined (_DEBUG) */
756  }
757 
758 #if _ITERATOR_DEBUG_LEVEL == 2
759  void _Orphan_ptr(_Mytype& _Cont, _Nodeptr _Ptr) const
760  {
761  std::_Lockit _Lock(_LOCK_DEBUG);
762  const_iterator **_Pnext = (const_iterator **)_Cont._Getpfirst();
763  if (_Pnext != 0)
764  {
765  while (*_Pnext != 0)
766  {
767  if ((*_Pnext)->_Ptr == (_Nodeptr)&_Myhead || _Ptr != 0 && (*_Pnext)->_Ptr != _Ptr)
768  {
769  _Pnext = (const_iterator **)(*_Pnext)->_Getpnext();
770  }
771  else
772  {
773  (*_Pnext)->_Clrcont();
774  *_Pnext = *(const_iterator **)(*_Pnext)->_Getpnext();
775  }
776  }
777  }
778  }
779 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
780 
781  volatile long _M_element_count; // Total item count, not counting dummy nodes
782 };
783 
784 } // namespace details;
785 } // namespace Concurrency
786 
787 namespace concurrency = Concurrency;
788 
789 #pragma warning (push)
790 #pragma pack(pop)
std::pair< iterator, bool > _Pairib
Definition: internal_split_ordered_list.h:379
_Split_order_list_value< _Element_type, _Element_allocator_type > _Mybase
Definition: internal_split_ordered_list.h:362
Definition: internal_split_ordered_list.h:287
_Allocator_type::reference reference
Definition: internal_split_ordered_list.h:371
_Solist_const_iterator< _Mylist > _Unchecked_type
Definition: internal_split_ordered_list.h:51
_Solist_const_iterator< _Mylist > & _Rechecked(_Solist_const_iterator< _Mylist > &_Iterator, typename _Solist_const_iterator< _Mylist >::_Unchecked_type _Right)
Definition: internal_split_ordered_list.h:105
_Full_iterator _Begin()
Definition: internal_split_ordered_list.h:509
iterator _Get_iterator(const_iterator _Iterator)
Definition: internal_split_ordered_list.h:558
_Mylist::pointer pointer
Definition: internal_split_ordered_list.h:122
_Mybase::_Nodeptr _Nodeptr
Definition: internal_split_ordered_list.h:291
_CRTIMP _In_ int _Value
Definition: setjmp.h:190
static _Split_order_key _Get_key(const _Full_const_iterator &_Iterator)
Definition: internal_split_ordered_list.h:530
_Allocator_type::size_type size_type
Definition: internal_split_ordered_list.h:295
const_iterator cend() const
Definition: internal_split_ordered_list.h:459
_Solist_iterator< _Mylist > _Unchecked_type
Definition: internal_split_ordered_list.h:133
size_t _Map_key
Definition: internal_split_ordered_list.h:194
_Element_type value_type
Definition: internal_split_ordered_list.h:203
_Full_iterator _Insert_dummy(_Full_iterator _Iterator, _Split_order_key _Order_key)
Definition: internal_split_ordered_list.h:627
_Solist_const_iterator< _Mylist >::_Unchecked_type _Unchecked(_Solist_const_iterator< _Mylist > _Iterator)
Definition: internal_split_ordered_list.h:99
_Full_const_iterator _End() const
Definition: internal_split_ordered_list.h:525
_Allocator_type::reference reference
Definition: internal_split_ordered_list.h:299
_Unchecked_type _Unchecked() const
Definition: internal_split_ordered_list.h:59
Definition: internal_split_ordered_list.h:112
_Allocator_type allocator_type
Definition: internal_split_ordered_list.h:366
_Full_const_iterator _Begin() const
Definition: internal_split_ordered_list.h:515
_Split_ordered_list(_Allocator_type _Allocator=allocator_type())
Definition: internal_split_ordered_list.h:381
allocator_type get_allocator() const
Definition: internal_split_ordered_list.h:401
_Solist_const_iterator(_Nodeptr _Pnode, const _Mylist *_Plist)
Definition: internal_split_ordered_list.h:47
_Nodeptr & _Nodepref
Definition: internal_split_ordered_list.h:207
_Mybase::_Nodepref _Nodepref
Definition: internal_split_ordered_list.h:292
_Split_ordered_list< _Element_type, _Element_allocator_type > _Mytype
Definition: internal_split_ordered_list.h:361
_Mylist::difference_type difference_type
Definition: internal_split_ordered_list.h:121
std::_Flist_iterator< _Mybase > _Full_iterator
Definition: internal_split_ordered_list.h:378
_Allocator_type::value_type value_type
Definition: internal_split_ordered_list.h:373
_Mylist::_Nodeptr _Nodeptr
Definition: internal_split_ordered_list.h:119
_Solist_const_iterator< _Mylist > _Myiter
Definition: internal_split_ordered_list.h:33
const_iterator _Get_first_real_iterator(_Full_const_iterator _Iterator) const
Definition: internal_split_ordered_list.h:578
pointer operator->() const
Definition: internal_split_ordered_list.h:69
_Split_order_key _M_order_key
Definition: internal_split_ordered_list.h:255
pointer operator->() const
Definition: internal_split_ordered_list.h:151
_Mylist::reference reference
Definition: internal_split_ordered_list.h:123
The Concurrency namespace provides classes and functions that provide access to the Concurrency Runti...
Definition: agents.h:42
_Full_iterator _End()
Definition: internal_split_ordered_list.h:520
_Allocator_type::size_type size_type
Definition: internal_split_ordered_list.h:202
_Allocator_type::const_pointer const_pointer
Definition: internal_split_ordered_list.h:298
_Solist_iterator()
Definition: internal_split_ordered_list.h:125
#define NULL
Definition: crtdbg.h:30
Definition: list:437
std::forward_iterator_tag iterator_category
Definition: internal_split_ordered_list.h:35
std::_Flist_const_iterator< _Mylist > _Mybase
Definition: internal_split_ordered_list.h:34
_Mylist::_Nodeptr _Nodeptr
Definition: internal_split_ordered_list.h:37
_Container_base0 _Container_base
Definition: xutility:245
bool empty() const
Definition: internal_split_ordered_list.h:465
volatile long _M_element_count
Definition: internal_split_ordered_list.h:781
_Allocator_type::const_reference const_reference
Definition: internal_split_ordered_list.h:372
void _Erase(_Nodeptr _Delete_node)
Definition: internal_split_ordered_list.h:590
_Allocator_type::template rebind< _Element_type >::other _Allocator_type
Definition: internal_split_ordered_list.h:293
_Allocator_type::size_type size_type
Definition: internal_split_ordered_list.h:367
const_iterator end() const
Definition: internal_split_ordered_list.h:449
_Split_order_key _Get_order_key() const
Definition: internal_split_ordered_list.h:220
_Mylist::const_pointer pointer
Definition: internal_split_ordered_list.h:40
reference operator*() const
Definition: internal_split_ordered_list.h:64
#define _ASSERT_EXPR(expr, expr_str)
Definition: crtdbg.h:220
iterator end()
Definition: internal_split_ordered_list.h:444
_Unchecked_type _Unchecked() const
Definition: internal_split_ordered_list.h:141
Definition: internal_split_ordered_list.h:30
void _Move_all(_Mytype &_Source_list)
Definition: internal_split_ordered_list.h:716
#define _LOCK_DEBUG
Definition: yvals.h:615
_Nodeptr _Insert(_Nodeptr _Previous, _Nodeptr _New_node, _Nodeptr _Current_node)
Definition: internal_split_ordered_list.h:602
size_type size() const
Definition: internal_split_ordered_list.h:471
_Myiter & _Rechecked(_Unchecked_type _Right)
Definition: internal_split_ordered_list.h:135
std::forward_iterator_tag iterator_category
Definition: internal_split_ordered_list.h:117
Definition: internal_split_ordered_list.h:198
_Full_iterator _Get_iterator(_Full_const_iterator _Iterator)
Definition: internal_split_ordered_list.h:552
~_Split_ordered_list()
Definition: internal_split_ordered_list.h:385
_Allocator_type::difference_type difference_type
Definition: internal_split_ordered_list.h:296
_Mylist::value_type value_type
Definition: internal_split_ordered_list.h:38
_Nodeptr _Myhead
Definition: internal_split_ordered_list.h:281
void _Init(_Split_order_key _Order_key)
Definition: internal_split_ordered_list.h:213
_Mylist::const_reference reference
Definition: internal_split_ordered_list.h:41
iterator _Get_first_real_iterator(_Full_iterator _Iterator)
Definition: internal_split_ordered_list.h:565
size_type max_size() const
Definition: internal_split_ordered_list.h:477
_Nodeptr _Buynode(_Split_order_key _Order_key)
Definition: internal_split_ordered_list.h:335
_Myiter operator++(int)
Definition: internal_split_ordered_list.h:85
void * _InterlockedCompareExchangePointer(void *volatile *, void *, void *)
_Nodeptr _Buynode(_Split_order_key _Order_key, _ValTy &&_Value)
Definition: internal_split_ordered_list.h:316
_Mylist::difference_type difference_type
Definition: internal_split_ordered_list.h:39
void swap(_Mytype &_Right)
Definition: internal_split_ordered_list.h:483
_Solist_iterator< _Mybase > iterator
Definition: internal_split_ordered_list.h:376
_Allocator_type::value_type value_type
Definition: internal_split_ordered_list.h:301
_Node * _Nodeptr
Definition: internal_split_ordered_list.h:205
_Allocator_type::difference_type difference_type
Definition: internal_split_ordered_list.h:368
_Split_order_list_value(_Allocator_type _Allocator=_Allocator_type())
Definition: internal_split_ordered_list.h:303
_Allocator_type::const_reference const_reference
Definition: internal_split_ordered_list.h:300
static reference _Myval(_Nodeptr _Pnode)
Definition: internal_split_ordered_list.h:350
_Ty * addressof(_Ty &_Val) _NOEXCEPT
Definition: xstddef:91
_Myiter & operator++()
Definition: internal_split_ordered_list.h:74
_Nodeptr _Atomic_set_next(_Nodeptr _New_node, _Nodeptr _Current_node)
Definition: internal_split_ordered_list.h:226
_Mybase::_Allocator_type _Allocator_type
Definition: internal_split_ordered_list.h:363
_Map_key _Split_order_key
Definition: internal_split_ordered_list.h:195
_Allocator_type::pointer pointer
Definition: internal_split_ordered_list.h:297
iterator _Erase(_Full_iterator _Previous, const_iterator _Where)
Definition: internal_split_ordered_list.h:706
_Split_order_list_node< _Element_type, _Allocator_type > _Mybase
Definition: internal_split_ordered_list.h:290
void swap(array< _Ty, _Size > &_Left, array< _Ty, _Size > &_Right) _NOEXCEPT_OP(_NOEXCEPT_OP(_Left.swap(_Right)))
Definition: array:429
_Myiter & _Rechecked(_Unchecked_type _Right)
Definition: internal_split_ordered_list.h:53
reference operator*() const
Definition: internal_split_ordered_list.h:146
_Allocator_type::template rebind< _Node >::other _M_node_allocator
Definition: internal_split_ordered_list.h:282
_Myiter operator++(int)
Definition: internal_split_ordered_list.h:167
const_iterator begin() const
Definition: internal_split_ordered_list.h:438
iterator begin()
Definition: internal_split_ordered_list.h:431
value_type _M_element
Definition: internal_split_ordered_list.h:254
_Allocator_type _M_value_allocator
Definition: internal_split_ordered_list.h:283
~_Split_order_list_value()
Definition: internal_split_ordered_list.h:310
void _Erase(_Full_iterator _Previous, _Full_const_iterator &_Where)
Definition: internal_split_ordered_list.h:685
void _Check_range()
Definition: internal_split_ordered_list.h:745
_Solist_const_iterator()
Definition: internal_split_ordered_list.h:43
_Split_order_list_node(_Allocator_type _Allocator)
Definition: internal_split_ordered_list.h:259
#define _DEBUG_ERROR(mesg)
Definition: xutility:32
_Mybase::_Nodeptr _Nodeptr
Definition: internal_split_ordered_list.h:364
static _Nodepref _Nextnode(_Nodeptr _Pnode)
Definition: internal_split_ordered_list.h:344
iterator _Get_iterator(_Full_iterator _Iterator)
Definition: internal_split_ordered_list.h:537
std::_Flist_const_iterator< _Mybase > _Full_const_iterator
Definition: internal_split_ordered_list.h:377
_Myiter & operator++()
Definition: internal_split_ordered_list.h:156
long __cdecl _InterlockedIncrement(long volatile *)
_Solist_iterator< _Mylist > _Myiter
Definition: internal_split_ordered_list.h:115
_Solist_const_iterator< _Mybase > const_iterator
Definition: internal_split_ordered_list.h:375
const_iterator cbegin() const
Definition: internal_split_ordered_list.h:454
Definition: internal_split_ordered_list.h:210
_Pairib _Insert(_Full_iterator _Iterator, _Full_iterator _Next, _Nodeptr _List_node, long *_New_count)
Definition: internal_split_ordered_list.h:609
_Allocator_type::pointer pointer
Definition: internal_split_ordered_list.h:369
Definition: internal_split_ordered_list.h:358
_Nodeptr _M_next
Definition: internal_split_ordered_list.h:253
void clear()
Definition: internal_split_ordered_list.h:406
_Solist_const_iterator< _Mylist > _Mybase
Definition: internal_split_ordered_list.h:116
_FwdIt _Last
Definition: algorithm:1936
const_iterator _Get_iterator(_Full_const_iterator _Iterator) const
Definition: internal_split_ordered_list.h:545
_Allocator_type::const_pointer const_pointer
Definition: internal_split_ordered_list.h:370
const _Ty & _Right
Definition: algorithm:4087
_Allocator_type::template rebind< _Element_type >::other _Allocator_type
Definition: internal_split_ordered_list.h:201
_Solist_iterator(_Nodeptr _Pnode, const _Mylist *_Plist)
Definition: internal_split_ordered_list.h:129
bool _Is_dummy() const
Definition: internal_split_ordered_list.h:245
_Mylist::value_type value_type
Definition: internal_split_ordered_list.h:120