annotate foosdk/sdk/pfc/chain_list_v2.h @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 #pragma once
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2 #include "iterators.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4 namespace pfc {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6 template<typename t_item>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7 class __chain_list_elem : public _list_node<t_item> {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 typedef _list_node<t_item> t_node;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10 template<typename ... arg_t > __chain_list_elem( arg_t && ... args ) : t_node( std::forward<arg_t>(args) ... ) {m_prev = m_next = NULL;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12 typedef __chain_list_elem<t_item> t_self;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 t_self * m_prev, * m_next;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 t_node * prev() throw() {return m_prev;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 t_node * next() throw() {return m_next;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 //helper wrappers
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 void add_ref() throw() {this->refcount_add_ref();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 void release() throw() {this->refcount_release();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 //workaround for cross-list-relinking case - never actually deletes p_elem
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23 void __release_temporary() throw() {this->_refcount_release_temporary();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 //! Differences between chain_list_v2_t<> and old chain_list_t<>: \n
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27 //! Iterators pointing to removed items as well as to items belonging to no longer existing list objects remain valid but they're no longer walkable - as if the referenced item was the only item in the list. The old class invalidated iterators on deletion instead.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28 template<typename _t_item>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 class chain_list_v2_t {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31 typedef _t_item t_item;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32 typedef chain_list_v2_t<t_item> t_self;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33 typedef ::pfc::iterator<t_item> iterator;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34 typedef ::pfc::const_iterator<t_item> const_iterator;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35 typedef ::pfc::forward_iterator<t_item> forward_iterator;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 typedef ::pfc::forward_const_iterator<t_item> forward_const_iterator;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 typedef __chain_list_elem<t_item> t_elem;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 chain_list_v2_t() {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 chain_list_v2_t(const t_self & p_source) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42 *this = p_source;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43 } catch(...) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44 remove_all();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45 throw;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49 chain_list_v2_t(t_self && p_source) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 append_move_from( p_source );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 template<typename t_in> void _set(const t_in & in) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54 remove_all(); _add(in);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 template<typename t_in> void _add(const t_in & in) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57 for(typename t_in::const_iterator iter = in.first(); iter.is_valid(); ++in) add_item(*iter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 template<typename t_in> t_self & operator=(const t_in & in) {_set(in); return *this;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 t_self & operator=(const t_self & p_other) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 remove_all();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 for(t_elem * walk = p_other.m_first; walk != NULL; walk = walk->m_next) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 add_item(walk->m_content);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66 return *this;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 t_self & operator=(t_self && p_other) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69 move_from(p_other); return *this;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72 // templated constructors = spawn of satan
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73 // template<typename t_other> chain_list_v2_t(const t_other & in) { try {_add(in);} catch(...) {remove_all(); throw;} }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75 t_size get_count() const {return m_count;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 iterator first() {return iterator(m_first);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78 iterator last() {return iterator(m_last);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79 const_iterator first() const {return const_iterator(m_first);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80 const_iterator last() const {return const_iterator(m_last);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81 const_iterator cfirst() const {return const_iterator(m_first);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 const_iterator clast() const {return const_iterator(m_last);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 forward_iterator begin() { return first(); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 forward_const_iterator begin() const { return first(); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86 forward_iterator end() {return forward_iterator(); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87 forward_const_iterator end() const { return forward_const_iterator(); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89 void remove_single(const_iterator const & p_iter) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 PFC_ASSERT(p_iter.is_valid());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91 __unlink(_elem(p_iter));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94 void remove(const_iterator const & p_iter) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 PFC_ASSERT(p_iter.is_valid());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 __unlink(_elem(p_iter));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 void remove_all() throw() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100 while(m_first != NULL) __unlink(m_first);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101 PFC_ASSERT(m_count == 0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 void remove_range(const_iterator const & p_from,const_iterator const & p_to) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 for(t_elem * walk = _elem(p_from);;) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 if (walk == NULL) {PFC_ASSERT(!"Should not get here"); break;}//should not happen unless there is a bug in calling code
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106 t_elem * next = walk->m_next;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 __unlink(walk);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108 if (walk == _elem(p_to)) break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 walk = next;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113 template<typename t_callback> void enumerate(t_callback & p_callback) const {__enumerate_chain<const t_elem>(m_first,p_callback);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114 template<typename t_callback> void enumerate(t_callback & p_callback) {__enumerate_chain<t_elem>(m_first,p_callback);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 template<typename t_source> bool remove_item(const t_source & p_item) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117 t_elem * elem;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118 if (__find(elem,p_item)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119 __unlink(elem);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126 ~chain_list_v2_t() {remove_all();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128 template<typename ... arg_t>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129 inline void add_item(arg_t && ... arg) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130 __link_last(new t_elem(std::forward<arg_t>(arg) ... ));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132 template<typename t_source>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133 inline t_self & operator+=(t_source && p_source) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134 add_item(std::forward<t_source>(p_source)); return *this;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
136 iterator insert_last() {return __link_last(new t_elem);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137 iterator insert_first() {return __link_first(new t_elem);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
138 iterator insert_after(const_iterator const & p_iter) {return __link_next(_elem(p_iter),new t_elem);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
139 iterator insert_before(const_iterator const & p_iter) {return __link_prev(_elem(p_iter),new t_elem);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140 template<typename ... arg_t> iterator insert_last(arg_t && ... arg) {return __link_last(new t_elem(std::forward<arg_t>(arg) ...));}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141 template<typename ... arg_t> iterator insert_first(arg_t && ... arg) {return __link_first(new t_elem(std::forward<arg_t>(arg) ...));}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142 template<typename ... arg_t> iterator insert_after(const_iterator const & p_iter,arg_t && ... arg) {return __link_next(_elem(p_iter),new t_elem(std::forward<arg_t>(arg) ... ));}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
143 template<typename ... arg_t> iterator insert_before(const_iterator const & p_iter,arg_t && ... arg) {return __link_prev(_elem(p_iter),new t_elem(std::forward<arg_t>(arg) ... ));}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
144
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
145 template<typename t_source> const_iterator find_item(const t_source & p_item) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
146 t_elem * elem;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
147 if (!__find(elem,p_item)) return const_iterator();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
148 return const_iterator(elem);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
149 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151 template<typename t_source> iterator find_item(const t_source & p_item) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152 t_elem * elem;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
153 if (!__find(elem,p_item)) return iterator();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
154 return iterator(elem);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
156
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
157 template<typename t_source> bool have_item(const t_source & p_item) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158 t_elem * dummy;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159 return __find(dummy,p_item);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
161 template<typename t_source> void set_single(const t_source & p_item) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
162 remove_all(); add_item(p_item);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
163 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
164
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
165 //! Slow!
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
166 const_iterator by_index(t_size p_index) const {return __by_index(p_index);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
167 //! Slow!
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
168 iterator by_index(t_size p_index) {return __by_index(p_index);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
169
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
170 t_self & operator<<(t_self & p_other) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
171 while(p_other.m_first != NULL) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
172 __link_last( p_other.__unlink_temporary(p_other.m_first) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
173 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
174 return *this;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
175 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
176 t_self & operator>>(t_self & p_other) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
177 while(m_last != NULL) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
178 p_other.__link_first(__unlink_temporary(m_last));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
179 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
180 return p_other;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
181 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
182 //! Links an object that has been unlinked from another list. Unsafe.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
183 void _link_last(const_iterator const& iter) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
184 PFC_ASSERT(iter.is_valid());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
185 PFC_ASSERT( _elem(iter)->m_prev == NULL && _elem(iter)->m_next == NULL );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
186 __link_last(_elem(iter));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
187 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
188 //! Links an object that has been unlinked from another list. Unsafe.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
189 void _link_first(const_iterator const& iter) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
190 PFC_ASSERT(iter.is_valid());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
191 PFC_ASSERT( _elem(iter)->m_prev == NULL && _elem(iter)->m_next == NULL );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
192 __link_first(_elem(iter));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
193 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
194 void append_move_from( t_self & p_other ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
195 while (p_other.m_first != NULL) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
196 __link_last(p_other.__unlink_temporary(p_other.m_first));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
197 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
198 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
199 void move_from( t_self & p_other ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
200 remove_all();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
201 append_move_from( p_other );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
202 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
203 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
204 static t_elem * _elem(const_iterator const & iter) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
205 return static_cast<t_elem*>(iter._node());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
206 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
207 t_elem * __by_index(t_size p_index) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
208 t_elem * walk = m_first;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
209 while(p_index > 0 && walk != NULL) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
210 p_index--;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
211 walk = walk->m_next;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
212 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
213 return walk;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
214 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
215 template<typename t_elemwalk,typename t_callback>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
216 static void __enumerate_chain(t_elemwalk * p_elem,t_callback & p_callback) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
217 t_elemwalk * walk = p_elem;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
218 while(walk != NULL) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
219 p_callback(walk->m_content);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
220 walk = walk->m_next;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
221 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
222 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
223
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
224 template<typename t_source> bool __find(t_elem * & p_elem,const t_source & p_item) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
225 for(t_elem * walk = m_first; walk != NULL; walk = walk->m_next) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
226 if (walk->m_content == p_item) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
227 p_elem = walk; return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
228 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
229 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
230 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
231 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
232
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
233 void __unlink_helper(t_elem * p_elem) throw() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
234 (p_elem->m_prev == NULL ? m_first : p_elem->m_prev->m_next) = p_elem->m_next;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
235 (p_elem->m_next == NULL ? m_last : p_elem->m_next->m_prev) = p_elem->m_prev;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
236 p_elem->m_next = p_elem->m_prev = NULL;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
237 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
238
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
239 //workaround for cross-list-relinking case - never actually deletes p_elem
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
240 t_elem * __unlink_temporary(t_elem * p_elem) throw() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
241 __unlink_helper(p_elem);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
242 --m_count; p_elem->__release_temporary();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
243 return p_elem;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
244 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
245
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
246 t_elem * __unlink(t_elem * p_elem) throw() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
247 __unlink_helper(p_elem);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
248 --m_count; p_elem->release();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
249 return p_elem;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
250 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
251 void __on_link(t_elem * p_elem) throw() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
252 p_elem->add_ref(); ++m_count;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
253 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
254 t_elem * __link_first(t_elem * p_elem) throw() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
255 __on_link(p_elem);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
256 p_elem->m_next = m_first;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
257 p_elem->m_prev = NULL;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
258 (m_first == NULL ? m_last : m_first->m_prev) = p_elem;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
259 m_first = p_elem;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
260 return p_elem;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
261 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
262 t_elem * __link_last(t_elem * p_elem) throw() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
263 __on_link(p_elem);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
264 p_elem->m_prev = m_last;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
265 p_elem->m_next = NULL;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
266 (m_last == NULL ? m_first : m_last->m_next) = p_elem;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
267 m_last = p_elem;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
268 return p_elem;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
269 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
270 t_elem * __link_next(t_elem * p_prev,t_elem * p_elem) throw() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
271 __on_link(p_elem);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
272 p_elem->m_prev = p_prev;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
273 p_elem->m_next = p_prev->m_next;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
274 (p_prev->m_next != NULL ? p_prev->m_next->m_prev : m_last) = p_elem;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
275 p_prev->m_next = p_elem;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
276 return p_elem;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
277 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
278 t_elem * __link_prev(t_elem * p_next,t_elem * p_elem) throw() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
279 __on_link(p_elem);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
280 p_elem->m_next = p_next;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
281 p_elem->m_prev = p_next->m_prev;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
282 (p_next->m_prev != NULL ? p_next->m_prev->m_next : m_first) = p_elem;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
283 p_next->m_prev = p_elem;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
284 return p_elem;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
285 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
286 t_elem * m_first = nullptr, * m_last = nullptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
287 t_size m_count = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
288 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
289
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
290
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
291 template<typename t_item> class traits_t<chain_list_v2_t<t_item> > : public traits_default_movable {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
292
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
293 class __chain_list_iterator_traits : public traits_default_movable {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
294 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
295 enum {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
296 constructor_may_fail = false
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
297 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
298 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
299
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
300 template<typename t_item> class traits_t<const_iterator<t_item> > : public traits_t<refcounted_object_ptr_t<_list_node<t_item> > > {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
301
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
302 template<typename t_item> class traits_t<iterator<t_item> > : public traits_t<const_iterator<t_item> > {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
303
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
304 }//namespace pfc