This source file includes following definitions.
- to_string
- to_string
- real_node
- real_node
- real_node
- real_node
- real_node
- end
1 #ifndef libjmmcg_core_intrusive_hpp
2 #define libjmmcg_core_intrusive_hpp
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #include "shared_ptr.hpp"
25
26 #include <algorithm>
27 #include <iterator>
28
29 namespace jmmcg { namespace intrusive {
30
31 namespace private_ {
32 template<class, class> class slist_iterator_internal;
33 }
34
35 template<class, class> class stack;
36 template<class, class> class slist;
37
38
39
40
41
42 template<
43 class LkT
44 >
45 class node_details_itf : virtual public sp_counter_itf_type<long> {
46 public:
47 using base_t=sp_counter_itf_type<long>;
48 using lock_traits=LkT;
49 using atomic_ctr_t=base_t;
50 using atomic_ptr_t=typename lock_traits::template atomic<node_details_itf *>;
51
52 atomic_ptr_t next;
53
54 virtual ~node_details_itf() noexcept(true) FORCE_INLINE {}
55
56 virtual tstring
57 to_string() const noexcept(false) FORCE_INLINE {
58 return "";
59 }
60
61 protected:
62 node_details_itf() noexcept(true) FORCE_INLINE
63 : next() {}
64 };
65
66 namespace private_ {
67
68
69 template<
70 class LkT
71 >
72 class node_details : public node_details_itf<LkT>, public sp_counter_type<typename node_details_itf<LkT>::atomic_ctr_t::value_type, typename node_details_itf<LkT>::lock_traits> {
73 public:
74 using base_t=node_details_itf<LkT>;
75 using base2_t=sp_counter_type<typename base_t::atomic_ctr_t::value_type, typename base_t::lock_traits>;
76 using atomic_ctr_t=typename base2_t::atomic_ctr_t;
77 using lock_traits=typename base_t::lock_traits;
78
79 constexpr node_details() noexcept(true) FORCE_INLINE
80 : base_t() {}
81 ~node_details() noexcept(true)=default;
82 void operator=(node_details const &)=delete;
83 void operator=(node_details &&)=delete;
84
85 tstring
86 to_string() const noexcept(false) FORCE_INLINE {
87 return base2_t::sp_to_string();
88 }
89 };
90
91 template<class V, class LkT> struct end;
92
93
94
95
96 template<class V, class LkT>
97 class slist_iterator_internal {
98 public:
99 using lock_traits=LkT;
100 typedef std::forward_iterator_tag iterator_category;
101 typedef std::ptrdiff_t difference_type;
102 typedef shared_ptr<V, lock_traits> value_type;
103 typedef shared_ptr<V, lock_traits> pointer;
104 typedef const shared_ptr<V, lock_traits> const_pointer;
105 typedef pointer & reference;
106 typedef const_pointer & const_reference;
107
108 typedef typename value_type::deleter_t deleter_t;
109 typedef typename value_type::ctr_type ctr_type;
110 typedef typename value_type::exception_type exception_type;
111
112 private:
113 using node_ptr_t=shared_ptr<node_details_itf<lock_traits>, lock_traits>;
114
115 BOOST_MPL_ASSERT((std::is_base_of<typename node_ptr_t::value_type, typename value_type::value_type>));
116
117 public:
118 explicit __stdcall slist_iterator_internal(const_reference n) noexcept(true) FORCE_INLINE
119 : node(n),
120 real_node(node.get().get() ? node->next : node.get()) {
121 assert(node.get().get() ? node->next==real_node.get() : true);
122 }
123 __stdcall slist_iterator_internal(slist_iterator_internal const &n) noexcept(true) FORCE_INLINE
124 : node(n.node),
125 real_node(node.get().get() ? node->next : node.get()) {
126 }
127
128 bool __fastcall operator==(slist_iterator_internal const &n) const noexcept(true) FORCE_INLINE {
129 if (node.get().get() && n.node.get().get()) {
130 return node->next==n.node->next;
131 } else if (!node.get() && !n.node.get()) {
132 return true;
133 } else if (node.get().get() && !n.node.get()) {
134 return node->next==n.node.get();
135 } else {
136 return false;
137 }
138 }
139 bool __fastcall operator!=(slist_iterator_internal const &n) const noexcept(true) FORCE_INLINE {
140 return !operator==(n);
141 }
142 bool __fastcall operator==(end<V, LkT> const &n) const noexcept(true) FORCE_INLINE;
143
144 slist_iterator_internal &__fastcall operator++() noexcept(true) FORCE_INLINE {
145 const typename node_ptr_t::atomic_ptr_t next_real_node(real_node.get().get() ? real_node->next : typename node_ptr_t::atomic_ptr_t());
146 node=real_node;
147 real_node=node_ptr_t(next_real_node);
148 assert(node.get().get() ? node->next==real_node.get() : true);
149 return *this;
150 }
151 slist_iterator_internal __fastcall operator++(int) noexcept(true) FORCE_INLINE {
152 const slist_iterator_internal tmp(*this);
153 ++*this;
154 return tmp;
155 }
156 pointer __fastcall operator*() noexcept(true) FORCE_INLINE {
157 return pointer(real_node);
158 }
159 const_pointer __fastcall operator*() const noexcept(true) FORCE_INLINE {
160 return const_pointer(real_node);
161 }
162 pointer __fastcall operator->() noexcept(true) FORCE_INLINE {
163 return pointer(real_node);
164 }
165 const_pointer __fastcall operator->() const noexcept(true) FORCE_INLINE {
166 return const_pointer(real_node);
167 }
168
169 friend tostream &
170 operator<<(tostream &os, slist_iterator_internal const &i) {
171 os<<"node="<<i.node
172 <<", real_node="<<i.real_node;
173 return os;
174 }
175
176 private:
177 friend class stack<V, LkT>;
178 friend class slist<V, LkT>;
179
180
181
182
183 node_ptr_t node;
184 node_ptr_t real_node;
185 };
186 template<class V, class LkT>
187 class slist_iterator_internal<V const, LkT> {
188 public:
189 using lock_traits=LkT;
190 typedef std::forward_iterator_tag iterator_category;
191 typedef std::ptrdiff_t difference_type;
192 typedef shared_ptr<V, lock_traits> value_type;
193 typedef shared_ptr<V, lock_traits> pointer;
194 typedef const shared_ptr<V, lock_traits> const_pointer;
195 typedef pointer & reference;
196 typedef const_pointer & const_reference;
197
198 typedef typename value_type::deleter_t deleter_t;
199 typedef typename value_type::ctr_type ctr_type;
200 typedef typename value_type::exception_type exception_type;
201
202 private:
203 using node_ptr_t=shared_ptr<node_details_itf<lock_traits>, lock_traits>;
204
205 BOOST_MPL_ASSERT((std::is_base_of<typename node_ptr_t::value_type, typename value_type::value_type>));
206
207 public:
208 explicit __stdcall slist_iterator_internal(const_reference n) noexcept(true) FORCE_INLINE
209 : node(n), real_node(node.get().get() ? node->next : node.get()) {
210 assert(node.get().get() ? node->next==real_node.get().get() : true);
211 }
212 explicit __stdcall slist_iterator_internal(node_ptr_t n) noexcept(true) FORCE_INLINE
213 : node(n), real_node(node.get().get() ? node->next : node.get()) {
214 assert(node.get().get() ? node->next==real_node.get() : true);
215 }
216 __stdcall slist_iterator_internal(slist_iterator_internal const &n) noexcept(true) FORCE_INLINE
217 : node(n.node), real_node(node.get().get() ? node->next : node.get()) {
218 }
219
220 bool __fastcall operator==(slist_iterator_internal const &n) const noexcept(true) FORCE_INLINE {
221 if (node.get().get() && n.node.get().get()) {
222 return node->next==n.node->next;
223 } else if (!node.get() && !n.node.get()) {
224 return true;
225 } else if (node.get().get() && !n.node.get()) {
226 return node->next==n.node.get();
227 } else {
228 return false;
229 }
230 }
231 bool __fastcall operator!=(slist_iterator_internal const &n) const noexcept(true) FORCE_INLINE {
232 return !operator==(n);
233 }
234
235 slist_iterator_internal &__fastcall operator++() noexcept(true) FORCE_INLINE {
236 const typename node_ptr_t::atomic_ptr_t next_real_node(real_node.get().get() ? real_node->next : typename node_ptr_t::atomic_ptr_t());
237 node=real_node;
238 real_node=node_ptr_t(next_real_node);
239 assert(node.get().get() ? node->next==real_node.get() : true);
240 return *this;
241 }
242 slist_iterator_internal __fastcall operator++(int) noexcept(true) FORCE_INLINE {
243 const slist_iterator_internal tmp(*this);
244 ++*this;
245 return tmp;
246 }
247 const_pointer __fastcall operator*() const noexcept(true) FORCE_INLINE {
248 return const_pointer(real_node);
249 }
250 const_pointer __fastcall operator->() const noexcept(true) FORCE_INLINE {
251 return const_pointer(real_node);
252 }
253
254 friend tostream &
255 operator<<(tostream &os, slist_iterator_internal const &i) {
256 os<<"node="<<i.node
257 <<", real_node="<<i.real_node;
258 return os;
259 }
260
261 private:
262 friend class stack<V, LkT>;
263 friend class slist<V, LkT>;
264
265
266
267
268 node_ptr_t node;
269 node_ptr_t real_node;
270 };
271
272 template<class V, class LkT>
273 struct end : public slist_iterator_internal<V, LkT> {
274 typedef slist_iterator_internal<V, LkT> base_t;
275 typedef typename base_t::value_type value_type;
276
277 constexpr __stdcall end() FORCE_INLINE
278 : base_t(value_type()) {
279 }
280 constexpr bool __fastcall operator==(end const &) const noexcept(true) FORCE_INLINE {
281 return true;
282 }
283 constexpr bool __fastcall operator!=(end const &n) const noexcept(true) FORCE_INLINE {
284 return !operator==(n);
285 }
286 };
287
288 template<class V, class LkT> inline bool FORCE_INLINE
289 slist_iterator_internal<V, LkT>::operator==(end<V, LkT> const &n) const noexcept(true) {
290 return node.get().get() ? node->next==n.node.get().get() : !node.get();
291 }
292
293 }
294
295
296
297
298
299
300
301
302 template<
303 class V,
304 class LkT
305 >
306 class stack : protected non_copyable {
307 protected:
308 using node_details_t=private_::node_details<LkT>;
309 using atomic_ptr_t=typename node_details_t::base_t::atomic_ptr_t;
310
311 public:
312 using lock_traits=typename node_details_t::lock_traits;
313 typedef std::size_t size_type;
314 typedef shared_ptr<V, LkT> value_type;
315 typedef typename lock_traits::template atomic_counter_type<unsigned long> size_ctr_t;
316 typedef private_::slist_iterator_internal<V, LkT> iterator;
317 typedef private_::slist_iterator_internal<V const, LkT> const_iterator;
318 typedef typename iterator::difference_type difference_type;
319 typedef typename iterator::pointer pointer;
320 typedef typename iterator::reference reference;
321 typedef typename const_iterator::const_pointer const_pointer;
322 typedef typename const_iterator::const_reference const_reference;
323
324 typedef typename value_type::deleter_t deleter_t;
325 typedef typename value_type::ctr_type ctr_type;
326 typedef typename value_type::exception_type exception_type;
327
328
329
330 static constexpr ppd::generic_traits::memory_access_modes memory_access_mode=(
331 atomic_ptr_t::memory_access_mode==ppd::generic_traits::memory_access_modes::crew_memory_access
332 && size_ctr_t::memory_access_mode==ppd::generic_traits::memory_access_modes::crew_memory_access
333 ? ppd::generic_traits::memory_access_modes::crew_memory_access
334 : ppd::generic_traits::memory_access_modes::erew_memory_access
335 );
336
337 BOOST_MPL_ASSERT((std::is_base_of<typename node_details_t::base_t, typename value_type::value_type>));
338
339 __stdcall stack() noexcept(true) FORCE_INLINE;
340 stack(stack &&) noexcept(true) FORCE_INLINE;
341
342
343
344 virtual __stdcall ~stack() noexcept(true) FORCE_INLINE;
345
346
347
348
349 iterator __fastcall begin() noexcept(true) FORCE_INLINE;
350
351
352
353 const_iterator __fastcall begin() const noexcept(true) FORCE_INLINE;
354
355
356
357 iterator __fastcall end() noexcept(true) FORCE_INLINE;
358
359
360
361 const_iterator __fastcall end() const noexcept(true) FORCE_INLINE;
362
363
364
365
366
367
368 bool __fastcall empty() const noexcept(true) FORCE_INLINE;
369
370
371
372
373
374
375 size_type __fastcall size() const noexcept(true) FORCE_INLINE;
376
377
378
379
380
381
382
383 size_type __fastcall size_n() const noexcept(true) FORCE_INLINE;
384
385
386
387
388
389
390 void __fastcall erase(iterator v) noexcept(true) FORCE_INLINE;
391
392
393
394
395
396
397
398 size_type __fastcall erase(const_reference v) noexcept(true) FORCE_INLINE;
399
400
401
402
403
404 void __fastcall clear() noexcept(true) FORCE_INLINE;
405
406
407
408
409
410 value_type __fastcall top() noexcept(true) FORCE_INLINE;
411
412
413
414
415
416 value_type __fastcall top() const noexcept(true) FORCE_INLINE;
417
418
419
420
421
422 void __fastcall push(value_type const &v) noexcept(true) FORCE_INLINE;
423
424
425
426
427
428 void __fastcall push(value_type &&v) noexcept(true) FORCE_INLINE;
429
430
431
432
433
434 void __fastcall push_front(value_type const &v) noexcept(true) FORCE_INLINE;
435
436
437
438
439
440 void __fastcall push_front(value_type &&v) noexcept(true) FORCE_INLINE;
441
442
443
444 void __fastcall pop() noexcept(true) FORCE_INLINE;
445
446
447
448 void __fastcall pop_front() noexcept(true) FORCE_INLINE;
449
450
451
452
453 value_type __fastcall pop_top_nochk() noexcept(true) FORCE_INLINE;
454
455 protected:
456 mutable node_details_t prefront_;
457 size_ctr_t size_ctr;
458
459 typename node_details_t::base_t::atomic_ptr_t
460 unlink_node(typename node_details_t::base_t::atomic_ptr_t &node) noexcept(true) FORCE_INLINE;
461
462
463
464
465
466
467
468
469
470 static void insert(typename node_details_t::base_t::atomic_ptr_t i, value_type v) noexcept(true) FORCE_INLINE;
471 void insert(value_type v) noexcept(true) FORCE_INLINE;
472 };
473
474
475
476
477
478
479
480
481 template<
482 class V,
483 class LkT
484 >
485 class slist : public stack<V, LkT> {
486 public:
487 typedef stack<V, LkT> base_t;
488 typedef typename base_t::value_type value_type;
489 typedef typename base_t::lock_traits lock_traits;
490 typedef typename base_t::size_ctr_t size_ctr_t;
491 typedef typename base_t::size_type size_type;
492 typedef typename base_t::iterator iterator;
493 typedef typename base_t::const_iterator const_iterator;
494 typedef typename base_t::difference_type difference_type;
495 typedef typename base_t::pointer pointer;
496 typedef typename base_t::reference reference;
497 typedef typename base_t::const_pointer const_pointer;
498 typedef typename base_t::const_reference const_reference;
499
500 typedef typename base_t::deleter_t deleter_t;
501 typedef typename base_t::ctr_type ctr_type;
502 typedef typename base_t::exception_type exception_type;
503
504 using base_t::erase;
505
506 __stdcall slist() noexcept(true) FORCE_INLINE;
507 slist(slist &&) noexcept(true) FORCE_INLINE;
508
509
510
511 __stdcall ~slist() noexcept(true) FORCE_INLINE;
512
513
514
515
516
517
518
519
520 iterator __fastcall find(const_reference v) noexcept(true) FORCE_INLINE;
521
522
523
524
525
526
527
528 const_iterator __fastcall find(const_reference v) const noexcept(true) FORCE_INLINE;
529
530
531
532
533
534
535
536 size_type __fastcall erase(const_reference v) noexcept(true) FORCE_INLINE;
537
538
539
540 value_type __fastcall front() noexcept(true) FORCE_INLINE;
541
542
543
544
545
546 value_type __fastcall front() const noexcept(true) FORCE_INLINE;
547
548
549
550 value_type __fastcall back() noexcept(true) FORCE_INLINE;
551
552
553
554 value_type __fastcall back() const noexcept(true) FORCE_INLINE;
555
556
557
558
559
560 void __fastcall push_front(value_type const &v) noexcept(true) FORCE_INLINE;
561
562
563
564
565
566 void __fastcall push_front(value_type &&v) noexcept(true) FORCE_INLINE;
567
568
569
570 void __fastcall pop_front() noexcept(true) FORCE_INLINE;
571
572
573
574
575
576
577 void __fastcall push_back(value_type const &v) noexcept(true) FORCE_INLINE;
578
579
580
581
582
583
584 void __fastcall push_back(value_type &&v) noexcept(true) FORCE_INLINE;
585
586
587
588
589
590
591 bool penultimate_reachable_from_prefront() const noexcept(true) FORCE_INLINE;
592
593 private:
594 typedef typename base_t::node_details_t node_details_t;
595
596
597
598
599
600 typename node_details_t::base_t::atomic_ptr_t penultimate_;
601
602 static void move_penultimate(typename node_details_t::base_t::atomic_ptr_t &ptr) noexcept(true) FORCE_INLINE;
603 };
604
605 } }
606
607 #include "intrusive_impl.hpp"
608
609 #endif