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  this->_Ptr = _Right._Ptr;
56  return (*this);
57  }
58 
59  _Unchecked_type _Unchecked() const
60  {
61  return (_Unchecked_type(this->_Ptr, (_Mylist *)this->_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 (this->_Mynode() != NULL && this->_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 (this->_Mynode() != NULL && this->_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  this->_Ptr = _Right._Ptr;
138  return (*this);
139  }
140 
141  _Unchecked_type _Unchecked() const
142  {
143  return (_Unchecked_type(this->_Ptr, (_Mylist *)this->_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 (this->_Mynode() != NULL && this->_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 (this->_Mynode() != NULL && this->_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 _Before_head() const _NOEXCEPT
282  {
283  // return pointer to the "before begin" pseudo node
284  return &(reinterpret_cast<_Node&>(const_cast<_Nodeptr&>(_Myhead)));
285  }
286 
287  _Nodeptr _Myhead; // pointer to head node
288  typename _Allocator_type::template rebind<_Node>::other _M_node_allocator; // allocator object for nodes
289  _Allocator_type _M_value_allocator; // allocator object for element values
290 };
291 
292 template<typename _Element_type, typename _Allocator_type>
293 class _Split_order_list_value : public _Split_order_list_node<_Element_type, _Allocator_type>
294 {
295 public:
297  typedef typename _Mybase::_Nodeptr _Nodeptr;
298  typedef typename _Mybase::_Nodepref _Nodepref;
299  typedef typename _Allocator_type::template rebind<_Element_type>::other _Allocator_type;
300 
301  typedef typename _Allocator_type::size_type size_type;
302  typedef typename _Allocator_type::difference_type difference_type;
303  typedef typename _Allocator_type::pointer pointer;
304  typedef typename _Allocator_type::const_pointer const_pointer;
305  typedef typename _Allocator_type::reference reference;
306  typedef typename _Allocator_type::const_reference const_reference;
307  typedef typename _Allocator_type::value_type value_type;
308 
309  _Split_order_list_value(_Allocator_type _Allocator = _Allocator_type()) : _Mybase(_Allocator)
310  {
311  // Immediately allocate a dummy node with order key of 0. This node
312  // will always be the head of the list.
313  this->_Myhead = _Buynode(0);
314  }
315 
317  {
318  }
319 
320  // Allocate a new node with the given order key and value
321  template<typename _ValTy>
322  _Nodeptr _Buynode(_Split_order_key _Order_key, _ValTy&& _Value)
323  {
324  _Nodeptr _Pnode = this->_M_node_allocator.allocate(1);
325 
326  try
327  {
328  this->_M_value_allocator.construct(std::addressof(_Myval(_Pnode)), std::forward<_ValTy>(_Value));
329  _Pnode->_Init(_Order_key);
330  }
331  catch(...)
332  {
333  this->_M_node_allocator.deallocate(_Pnode, 1);
334  throw;
335  }
336 
337  return (_Pnode);
338  }
339 
340  // Allocate a new node with the given order key; used to allocate dummy nodes
341  _Nodeptr _Buynode(_Split_order_key _Order_key)
342  {
343  _Nodeptr _Pnode = this->_M_node_allocator.allocate(1);
344  _Pnode->_Init(_Order_key);
345 
346  return (_Pnode);
347  }
348 
349  // Get the next node
350  static _Nodepref _Nextnode(_Nodeptr _Pnode)
351  {
352  return ((_Nodepref)(*_Pnode)._M_next);
353  }
354 
355  // Get the stored value
356  static reference _Myval(_Nodeptr _Pnode)
357  {
358  return ((reference)(*_Pnode)._M_element);
359  }
360 };
361 
362 // Forward list in which elements are sorted in a split-order
363 template <typename _Element_type, typename _Element_allocator_type = std::allocator<_Element_type> >
364 class _Split_ordered_list : _Split_order_list_value<_Element_type, _Element_allocator_type>
365 {
366 public:
370  typedef typename _Mybase::_Nodeptr _Nodeptr;
371 
372  typedef _Allocator_type allocator_type;
373  typedef typename _Allocator_type::size_type size_type;
374  typedef typename _Allocator_type::difference_type difference_type;
375  typedef typename _Allocator_type::pointer pointer;
376  typedef typename _Allocator_type::const_pointer const_pointer;
377  typedef typename _Allocator_type::reference reference;
378  typedef typename _Allocator_type::const_reference const_reference;
379  typedef typename _Allocator_type::value_type value_type;
380 
383  typedef std::_Flist_const_iterator<_Mybase> _Full_const_iterator;
384  typedef std::_Flist_iterator<_Mybase> _Full_iterator;
385  typedef std::pair<iterator, bool> _Pairib;
387  _Split_ordered_list(_Allocator_type _Allocator = allocator_type()) : _Mybase(_Allocator), _M_element_count(0)
388  {
389  }
390 
392  {
393  // Clear the list
394  clear();
395 
396  // Remove the head element which is not cleared by clear()
397  _Nodeptr _Pnode = this->_Myhead;
398  this->_Myhead = NULL;
399 
400  _ASSERT_EXPR(_Pnode != NULL && this->_Nextnode(_Pnode) == NULL, L"Invalid head list node");
401 
402  _Erase(_Pnode);
403  }
404 
405  // Common forward list functions
406 
407  allocator_type get_allocator() const
408  {
409  return (this->_M_value_allocator);
410  }
411 
412  void clear()
413  {
414 #if _ITERATOR_DEBUG_LEVEL == 2
415  _Orphan_ptr(*this, 0);
416 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
417 
418  _Nodeptr _Pnext;
419  _Nodeptr _Pnode = this->_Myhead;
420 
421  _ASSERT_EXPR(this->_Myhead != NULL, L"Invalid head list node");
422  _Pnext = this->_Nextnode(_Pnode);
423  _Pnode->_M_next = NULL;
424  _Pnode = _Pnext;
425 
426  while (_Pnode != NULL)
427  {
428  _Pnext = this->_Nextnode(_Pnode);
429  _Erase(_Pnode);
430  _Pnode = _Pnext;
431  }
432 
433  _M_element_count = 0;
434  }
435 
436  // Returns a first non-dummy element in the SOL
437  iterator begin()
438  {
439  _Full_iterator _Iterator = _Begin();
440  return _Get_first_real_iterator(_Iterator);
441  }
442 
443  // Returns a first non-dummy element in the SOL
444  const_iterator begin() const
445  {
446  _Full_const_iterator _Iterator = _Begin();
447  return _Get_first_real_iterator(_Iterator);
448  }
449 
450  iterator end()
451  {
452  return (iterator(0, this));
453  }
454 
455  const_iterator end() const
456  {
457  return (const_iterator(0, this));
458  }
459 
460  const_iterator cbegin() const
461  {
462  return (((const _Mytype *)this)->begin());
463  }
464 
465  const_iterator cend() const
466  {
467  return (((const _Mytype *)this)->end());
468  }
469 
470  // Checks if the number of elements (non-dummy) is 0
471  bool empty() const
472  {
473  return (_M_element_count == 0);
474  }
475 
476  // Returns the number of non-dummy elements in the list
477  size_type size() const
478  {
479  return _M_element_count;
480  }
481 
482  // Returns the maximum size of the list, determined by the allocator
483  size_type max_size() const
484  {
485  return this->_M_value_allocator.max_size();
486  }
487 
488  // Swaps 'this' list with the passed in one
489  void swap(_Mytype& _Right)
490  {
491  if (this == &_Right)
492  {
493  // Nothing to do
494  return;
495  }
496 
497  if (this->_M_value_allocator == _Right._M_value_allocator)
498  {
499  this->_Swap_all(_Right);
500  std::swap(this->_Myhead, _Right._Myhead);
502  }
503  else
504  {
505  _Mytype _Temp_list(this->get_allocator());
506  _Temp_list._Move_all(_Right);
507  _Right._Move_all(*this);
508  _Move_all(_Temp_list);
509  }
510  }
511 
512  // Split-order list functions
513 
514  // Returns a first element in the SOL, which is always a dummy
515  _Full_iterator _Begin()
516  {
517  return _Full_iterator(this->_Myhead, this);
518  }
519 
520  // Returns a first element in the SOL, which is always a dummy
521  _Full_const_iterator _Begin() const
522  {
523  return _Full_const_iterator(this->_Myhead, this);
524  }
525 
526  _Full_iterator _End()
527  {
528  return _Full_iterator(0, this);
529  }
530 
531  _Full_const_iterator _End() const
532  {
533  return _Full_const_iterator(0, this);
534  }
535 
536  static _Split_order_key _Get_key(const _Full_const_iterator& _Iterator)
537  {
538  return _Iterator._Mynode()->_Get_order_key();
539  }
540 
541  // Returns a public iterator version of the internal iterator. Public iterator must not
542  // be a dummy private iterator.
543  iterator _Get_iterator(_Full_iterator _Iterator)
544  {
545  _ASSERT_EXPR(_Iterator._Mynode() != NULL && !_Iterator._Mynode()->_Is_dummy(), L"Invalid user node (dummy)");
546  return iterator(_Iterator._Mynode(), this);
547  }
548 
549  // Returns a public iterator version of the internal iterator. Public iterator must not
550  // be a dummy private iterator.
551  const_iterator _Get_iterator(_Full_const_iterator _Iterator) const
552  {
553  _ASSERT_EXPR(_Iterator._Mynode() != NULL && !_Iterator._Mynode()->_Is_dummy(), L"Invalid user node (dummy)");
554  return const_iterator(_Iterator._Mynode(), this);
555  }
556 
557  // Returns a non-const version of the _Full_iterator
558  _Full_iterator _Get_iterator(_Full_const_iterator _Iterator)
559  {
560  return _Full_iterator(_Iterator._Mynode(), this);
561  }
562 
563  // Returns a non-const version of the iterator
564  iterator _Get_iterator(const_iterator _Iterator)
565  {
566  return iterator(_Iterator._Mynode(), this);
567  }
568 
569  // Returns a public iterator version of a first non-dummy internal iterator at or after
570  // the passed in internal iterator.
571  iterator _Get_first_real_iterator(_Full_iterator _Iterator)
572  {
573  // Skip all dummy, internal only iterators
574  while (_Iterator != _End() && _Iterator._Mynode()->_Is_dummy())
575  {
576  _Iterator++;
577  }
578 
579  return iterator(_Iterator._Mynode(), this);
580  }
581 
582  // Returns a public iterator version of a first non-dummy internal iterator at or after
583  // the passed in internal iterator.
584  const_iterator _Get_first_real_iterator(_Full_const_iterator _Iterator) const
585  {
586  // Skip all dummy, internal only iterators
587  while (_Iterator != _End() && _Iterator._Mynode()->_Is_dummy())
588  {
589  _Iterator++;
590  }
591 
592  return const_iterator(_Iterator._Mynode(), this);
593  }
594 
595  // Erase an element using the allocator
596  void _Erase(_Nodeptr _Delete_node)
597  {
598  if (!_Delete_node->_Is_dummy())
599  {
600  // Dummy nodes have nothing constructed, thus should not be destroyed.
601  this->_M_node_allocator.destroy(_Delete_node);
602  }
603  this->_M_node_allocator.deallocate(_Delete_node, 1);
604  }
605 
606  // Try to insert a new element in the list. If insert fails, return the node that
607  // was inserted instead.
608  _Nodeptr _Insert(_Nodeptr _Previous, _Nodeptr _New_node, _Nodeptr _Current_node)
609  {
610  _New_node->_M_next = _Current_node;
611  return _Previous->_Atomic_set_next(_New_node, _Current_node);
612  }
613 
614  // Insert a new element between passed in iterators
615  _Pairib _Insert(_Full_iterator _Iterator, _Full_iterator _Next, _Nodeptr _List_node, long * _New_count)
616  {
617  _Nodeptr _Inserted_node = _Insert(_Iterator._Mynode(), _List_node, _Next._Mynode());
618 
619  if (_Inserted_node == _List_node)
620  {
621  // If the insert succeeded, check that the order is correct and increment the element count
622  _Check_range();
623  *_New_count = _InterlockedIncrement(&_M_element_count);
624  return _Pairib(iterator(_List_node, this), true);
625  }
626  else
627  {
628  return _Pairib(end(), false);
629  }
630  }
631 
632  // Insert a new dummy element, starting search at a parent dummy element
633  _Full_iterator _Insert_dummy(_Full_iterator _Iterator, _Split_order_key _Order_key)
634  {
635  _Full_iterator _Last = _End();
636  _Full_iterator _Where = _Iterator;
637 
638  _ASSERT_EXPR(_Where != _Last, L"Invalid head node");
639 
640  _Where++;
641 
642  // Create a dummy element up front, even though it may be discarded (due to concurrent insertion)
643  _Nodeptr _Dummy_node = _Buynode(_Order_key);
644 
645  for (;;)
646  {
647  _ASSERT_EXPR(_Iterator != _Last, L"Invalid head list node");
648 
649  // If the head iterator is at the end of the list, or past the point where this dummy
650  // node needs to be inserted, then try to insert it.
651  if (_Where == _Last || _Get_key(_Where) > _Order_key)
652  {
653  _ASSERT_EXPR(_Get_key(_Iterator) < _Order_key, L"Invalid node order in the list");
654 
655  // Try to insert it in the right place
656  _Nodeptr _Inserted_node = _Insert(_Iterator._Mynode(), _Dummy_node, _Where._Mynode());
657 
658  if (_Inserted_node == _Dummy_node)
659  {
660  // Insertion succeeded, check the list for order violations
661  _Check_range();
662  return _Full_iterator(_Dummy_node, this);
663  }
664  else
665  {
666  // Insertion failed: either dummy node was inserted by another thread, or
667  // a real element was inserted at exactly the same place as dummy node.
668  // Proceed with the search from the previous location where order key was
669  // known to be larger (note: this is legal only because there is no safe
670  // concurrent erase operation supported).
671  _Where = _Iterator;
672  _Where++;
673  continue;
674  }
675  }
676  else if (_Get_key(_Where) == _Order_key)
677  {
678  // Another dummy node with the same value found, discard the new one.
679  _Erase(_Dummy_node);
680  return _Where;
681  }
682 
683  // Move the iterator forward
684  _Iterator = _Where;
685  _Where++;
686  }
687 
688  }
689 
690  // This erase function can handle both real and dummy nodes
691  void _Erase(_Full_iterator _Previous, _Full_const_iterator& _Where)
692  {
693 #if _ITERATOR_DEBUG_LEVEL == 2
694  if (_Where._Getcont() != this || _Where._Ptr == this->_Myhead)
695  {
696  std::_DEBUG_ERROR("list erase iterator outside range");
697  }
698  _Nodeptr _Pnode = (_Where++)._Mynode();
699  _Orphan_ptr(*this, _Pnode);
700 #else /* _ITERATOR_DEBUG_LEVEL == 2 */
701  _Nodeptr _Pnode = (_Where++)._Mynode();
702 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
703 
704  _Nodeptr _Prevnode = _Previous._Mynode();
705  _ASSERT_EXPR(_Prevnode->_M_next == _Pnode, L"Erase must take consecutive iterators");
706  _Prevnode->_M_next = _Pnode->_M_next;
707 
708  _Erase(_Pnode);
709  }
710 
711  // Erase the element (previous node needs to be passed because this is a forward only list)
712  iterator _Erase(_Full_iterator _Previous, const_iterator _Where)
713  {
714  _Full_const_iterator _Iterator = _Where;
715  _Erase(_Previous, _Iterator);
717 
718  return _Get_iterator(_Get_first_real_iterator(_Iterator));
719  }
720 
721  // Move all elements from the passed in split-ordered list to this one
722  void _Move_all(_Mytype& _Source_list)
723  {
724  _Full_const_iterator _First = _Source_list._Begin();
725  _Full_const_iterator _Last = _Source_list._End();
726 
727  if (_First == _Last)
728  {
729  return;
730  }
731 
732  _Nodeptr _Previous_node = this->_Myhead;
733  _Full_const_iterator _Begin_iterator = _First++;
734 
735  // Move all elements one by one, including dummy ones
736  for (_Full_const_iterator _Iterator = _First; _Iterator != _Last;)
737  {
738  _Nodeptr _Node = _Iterator._Mynode();
739 
740  _Nodeptr _Dummy_node = _Node->_Is_dummy() ? _Buynode(_Node->_Get_order_key()) : _Buynode(_Node->_Get_order_key(), this->_Myval(_Node));
741  _Previous_node = _Insert(_Previous_node, _Dummy_node, NULL);
742  _ASSERT_EXPR(_Previous_node != NULL, L"Insertion must succeed");
743  _Full_const_iterator _Where = _Iterator++;
744  _Source_list._Erase(_Get_iterator(_Begin_iterator), _Where);
745  }
746  }
747 
748 private:
749 
750  // Check the list for order violations
752  {
753 #if defined (_DEBUG)
754  for (_Full_iterator _Iterator = _Begin(); _Iterator != _End(); _Iterator++)
755  {
756  _Full_iterator _Next_iterator = _Iterator;
757  _Next_iterator++;
758 
759  _ASSERT_EXPR(_Next_iterator == end() || _Next_iterator._Mynode()->_Get_order_key() >= _Iterator._Mynode()->_Get_order_key(), L"!!! List order inconsistency !!!");
760  }
761 #endif /* defined (_DEBUG) */
762  }
763 
764 #if _ITERATOR_DEBUG_LEVEL == 2
765  void _Orphan_ptr(_Mytype& _Cont, _Nodeptr _Ptr) const
766  {
767  std::_Lockit _Lock(_LOCK_DEBUG);
768  const_iterator **_Pnext = (const_iterator **)_Cont._Getpfirst();
769  if (_Pnext != 0)
770  {
771  while (*_Pnext != 0)
772  {
773  if ((*_Pnext)->_Ptr == (_Nodeptr)&this->_Myhead || _Ptr != 0 && (*_Pnext)->_Ptr != _Ptr)
774  {
775  _Pnext = (const_iterator **)(*_Pnext)->_Getpnext();
776  }
777  else
778  {
779  (*_Pnext)->_Clrcont();
780  *_Pnext = *(const_iterator **)(*_Pnext)->_Getpnext();
781  }
782  }
783  }
784  }
785 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
786 
787  volatile long _M_element_count; // Total item count, not counting dummy nodes
788 };
789 
790 } // namespace details;
791 } // namespace Concurrency
792 
793 namespace concurrency = ::Concurrency;
794 
795 #pragma warning (push)
796 #pragma pack(pop)
std::pair< iterator, bool > _Pairib
Definition: internal_split_ordered_list.h:385
_Split_order_list_value< _Element_type, _Element_allocator_type > _Mybase
Definition: internal_split_ordered_list.h:368
Definition: internal_split_ordered_list.h:293
_Allocator_type::reference reference
Definition: internal_split_ordered_list.h:377
_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:515
iterator _Get_iterator(const_iterator _Iterator)
Definition: internal_split_ordered_list.h:564
_Mylist::pointer pointer
Definition: internal_split_ordered_list.h:122
#define NULL
Definition: vcruntime.h:236
_Mybase::_Nodeptr _Nodeptr
Definition: internal_split_ordered_list.h:297
static _Split_order_key _Get_key(const _Full_const_iterator &_Iterator)
Definition: internal_split_ordered_list.h:536
_Allocator_type::size_type size_type
Definition: internal_split_ordered_list.h:301
const_iterator cend() const
Definition: internal_split_ordered_list.h:465
_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:633
_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:531
_Allocator_type::reference reference
Definition: internal_split_ordered_list.h:305
_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:372
constexpr _Ty * addressof(_Ty &_Val) _NOEXCEPT
Definition: xstddef:723
_Full_const_iterator _Begin() const
Definition: internal_split_ordered_list.h:521
_Split_ordered_list(_Allocator_type _Allocator=allocator_type())
Definition: internal_split_ordered_list.h:387
allocator_type get_allocator() const
Definition: internal_split_ordered_list.h:407
_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:298
_Split_ordered_list< _Element_type, _Element_allocator_type > _Mytype
Definition: internal_split_ordered_list.h:367
_Mylist::difference_type difference_type
Definition: internal_split_ordered_list.h:121
std::_Flist_iterator< _Mybase > _Full_iterator
Definition: internal_split_ordered_list.h:384
_Allocator_type::value_type value_type
Definition: internal_split_ordered_list.h:379
_Mylist::_Nodeptr _Nodeptr
Definition: internal_split_ordered_list.h:119
_Nodeptr _Before_head() const _NOEXCEPT
Definition: internal_split_ordered_list.h:281
_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:584
pointer operator->() const
Definition: internal_split_ordered_list.h:69
#define _NOEXCEPT
Definition: yvals.h:25
_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:43
_Full_iterator _End()
Definition: internal_split_ordered_list.h:526
_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:304
_Solist_iterator()
Definition: internal_split_ordered_list.h:125
Definition: list:440
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:246
bool empty() const
Definition: internal_split_ordered_list.h:471
volatile long _M_element_count
Definition: internal_split_ordered_list.h:787
_Allocator_type::const_reference const_reference
Definition: internal_split_ordered_list.h:378
void _Erase(_Nodeptr _Delete_node)
Definition: internal_split_ordered_list.h:596
_Allocator_type::template rebind< _Element_type >::other _Allocator_type
Definition: internal_split_ordered_list.h:299
_Allocator_type::size_type size_type
Definition: internal_split_ordered_list.h:373
const_iterator end() const
Definition: internal_split_ordered_list.h:455
_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
iterator end()
Definition: internal_split_ordered_list.h:450
_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:722
#define _LOCK_DEBUG
Definition: yvals.h:607
_Nodeptr _Insert(_Nodeptr _Previous, _Nodeptr _New_node, _Nodeptr _Current_node)
Definition: internal_split_ordered_list.h:608
size_type size() const
Definition: internal_split_ordered_list.h:477
_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:558
~_Split_ordered_list()
Definition: internal_split_ordered_list.h:391
void swap(array< _Ty, _Size > &_Left, array< _Ty, _Size > &_Right) _NOEXCEPT_OP(_NOEXCEPT_OP(_Left.swap(_Right)))
Definition: array:433
_Allocator_type::difference_type difference_type
Definition: internal_split_ordered_list.h:302
_Mylist::value_type value_type
Definition: internal_split_ordered_list.h:38
_Nodeptr _Myhead
Definition: internal_split_ordered_list.h:287
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:571
size_type max_size() const
Definition: internal_split_ordered_list.h:483
_Nodeptr _Buynode(_Split_order_key _Order_key)
Definition: internal_split_ordered_list.h:341
_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:322
_Mylist::difference_type difference_type
Definition: internal_split_ordered_list.h:39
void swap(_Mytype &_Right)
Definition: internal_split_ordered_list.h:489
_Solist_iterator< _Mybase > iterator
Definition: internal_split_ordered_list.h:382
_Allocator_type::value_type value_type
Definition: internal_split_ordered_list.h:307
_Node * _Nodeptr
Definition: internal_split_ordered_list.h:205
_Allocator_type::difference_type difference_type
Definition: internal_split_ordered_list.h:374
_Split_order_list_value(_Allocator_type _Allocator=_Allocator_type())
Definition: internal_split_ordered_list.h:309
_Allocator_type::const_reference const_reference
Definition: internal_split_ordered_list.h:306
static reference _Myval(_Nodeptr _Pnode)
Definition: internal_split_ordered_list.h:356
_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:369
_Map_key _Split_order_key
Definition: internal_split_ordered_list.h:195
_Allocator_type::pointer pointer
Definition: internal_split_ordered_list.h:303
iterator _Erase(_Full_iterator _Previous, const_iterator _Where)
Definition: internal_split_ordered_list.h:712
_Split_order_list_node< _Element_type, _Allocator_type > _Mybase
Definition: internal_split_ordered_list.h:296
_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:288
_Myiter operator++(int)
Definition: internal_split_ordered_list.h:167
const_iterator begin() const
Definition: internal_split_ordered_list.h:444
iterator begin()
Definition: internal_split_ordered_list.h:437
value_type _M_element
Definition: internal_split_ordered_list.h:254
_Allocator_type _M_value_allocator
Definition: internal_split_ordered_list.h:289
~_Split_order_list_value()
Definition: internal_split_ordered_list.h:316
void _Erase(_Full_iterator _Previous, _Full_const_iterator &_Where)
Definition: internal_split_ordered_list.h:691
void _Check_range()
Definition: internal_split_ordered_list.h:751
_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:370
static _Nodepref _Nextnode(_Nodeptr _Pnode)
Definition: internal_split_ordered_list.h:350
iterator _Get_iterator(_Full_iterator _Iterator)
Definition: internal_split_ordered_list.h:543
std::_Flist_const_iterator< _Mybase > _Full_const_iterator
Definition: internal_split_ordered_list.h:383
_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:381
const_iterator cbegin() const
Definition: internal_split_ordered_list.h:460
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:615
_Allocator_type::pointer pointer
Definition: internal_split_ordered_list.h:375
Definition: internal_split_ordered_list.h:364
_In_ int _Value
Definition: setjmp.h:173
_Nodeptr _M_next
Definition: internal_split_ordered_list.h:253
void clear()
Definition: internal_split_ordered_list.h:412
_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:551
_Allocator_type::const_pointer const_pointer
Definition: internal_split_ordered_list.h:376
constexpr const _Ty &() _Right
Definition: algorithm:3591
_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