neoGFX
Cross-platform C++ app/game engine
Loading...
Searching...
No Matches
jar.hpp
Go to the documentation of this file.
1// jar.hpp
2/*
3 * Copyright (c) 2018, 2020 Leigh Johnston.
4 *
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * * Neither the name of Leigh Johnston nor the names of any
19 * other contributors to this software may be used to endorse or
20 * promote products derived from this software without specific prior
21 * written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*/
35
36#pragma once
37
38#include <neolib/neolib.hpp>
39#include <optional>
40#include <vector>
41#include <set>
42#include <mutex>
43#include <atomic>
45#include <neolib/core/mutex.hpp>
47#include <neolib/core/i_jar.hpp>
48
49namespace neolib
50{
51 template <typename CookieType>
53 {
54 public:
55 typedef CookieType cookie_type;
56 static constexpr cookie_type no_cookie = cookie_type{};
57 public:
59 iConsumer{ nullptr },
60 iCookie{ no_cookie }
61 {
62 }
64 iConsumer{ &aConsumer },
65 iCookie{ aCookie }
66 {
67 add_ref();
68 }
70 {
71 release();
72 }
74 iConsumer{ aOther.iConsumer },
75 iCookie{ aOther.iCookie }
76 {
77 add_ref();
78 }
80 iConsumer{ aOther.iConsumer },
81 iCookie{ aOther.iCookie }
82 {
83 add_ref();
84 aOther.release();
85 }
86 public:
88 {
89 if (&aOther == this)
90 return *this;
91 basic_cookie_ref_ptr temp{ std::move(*this) };
92 iConsumer = aOther.iConsumer;
93 iCookie = aOther.iCookie;
94 add_ref();
95 return *this;
96 }
98 {
99 if (&aOther == this)
100 return *this;
101 basic_cookie_ref_ptr temp{ std::move(*this) };
102 iConsumer = aOther.iConsumer;
103 iCookie = aOther.iCookie;
104 add_ref();
105 aOther.release();
106 return *this;
107 }
108 public:
109 bool operator==(basic_cookie_ref_ptr const& aRhs) const
110 {
111 return iConsumer == aRhs.iConsumer && iCookie == aRhs.iCookie;
112 }
113 bool operator!=(basic_cookie_ref_ptr const& aRhs) const
114 {
115 return !(*this == aRhs);
116 }
117 bool operator<(basic_cookie_ref_ptr const& aRhs) const
118 {
119 return std::forward_as_tuple(iConsumer, iCookie) < std::forward_as_tuple(aRhs.iConsumer, aRhs.iCookie);
120 }
121 public:
122 bool valid() const
123 {
124 return have_consumer() && have_cookie();
125 }
126 bool expired() const
127 {
128 return !valid();
129 }
131 {
132 return iCookie;
133 }
134 void reset() const
135 {
136 iConsumer = nullptr;
137 iCookie = no_cookie;
138 }
139 private:
140 void add_ref() const
141 {
142 if (!valid())
143 return;
144 consumer().add_ref(cookie());
145 }
146 void release() const
147 {
148 if (!valid())
149 return;
150 consumer().release(cookie());
151 reset();
152 }
153 bool have_consumer() const
154 {
155 return iConsumer != nullptr;
156 }
157 i_basic_cookie_consumer<cookie_type>& consumer() const
158 {
159 return *iConsumer;
160 }
161 bool have_cookie() const
162 {
163 return iCookie != no_cookie;
164 }
165 private:
166 mutable i_basic_cookie_consumer<cookie_type>* iConsumer;
167 mutable cookie_type iCookie;
168 };
169
170 namespace detail
171 {
172 template<typename T> struct is_smart_ptr : std::false_type {};
173 template<typename T> struct is_smart_ptr<std::shared_ptr<T>> : std::true_type {};
174 template<typename T> struct is_smart_ptr<std::unique_ptr<T>> : std::true_type {};
175 template<typename T> struct is_smart_ptr<ref_ptr<T>> : std::true_type {};
176 template<typename T>
177 inline constexpr bool is_smart_ptr_v = is_smart_ptr<T>::value;
178 }
179
180 template <typename T, typename Container = vector<T>, typename CookieType = cookie, typename MutexType = null_mutex>
181 class basic_jar : public reference_counted<i_basic_jar<abstract_t<T>, abstract_t<Container>, CookieType>>
182 {
183 public:
184 typedef CookieType cookie_type;
185 public:
186 typedef T value_type;
187 typedef Container container_type;
188 typedef typename container_type::const_iterator const_iterator;
189 typedef typename container_type::iterator iterator;
190 typedef MutexType mutex_type;
191 private:
192 typedef typename container_type::size_type reverse_index_t;
193 typedef std::vector<reverse_index_t> reverse_indices_t;
194 typedef std::vector<cookie_type> cookies_t;
195 private:
196 static constexpr cookie_type INVALID_COOKIE = invalid_cookie<cookie_type>;
197 static constexpr reverse_index_t INVALID_REVERSE_INDEX = static_cast<reverse_index_t>(~reverse_index_t{});
198 public:
199 basic_jar() : iNextAvailableCookie{}
200 {
201 }
202 public:
203 bool empty() const final
204 {
205 return items().empty();
206 }
207 std::size_t size() const final
208 {
209 return items().size();
210 }
211 bool contains(cookie_type aCookie) const final
212 {
213 std::scoped_lock<mutex_type> lock{ mutex() };
214 return aCookie < reverse_indices().size() && reverse_indices()[aCookie] != INVALID_REVERSE_INDEX;
215 }
216 const_iterator find(cookie_type aCookie) const final
217 {
218 std::scoped_lock<mutex_type> lock{ mutex() };
219 if (contains(aCookie))
220 return std::next(begin(), reverse_indices()[aCookie]);
221 return end();
222 }
223 iterator find(cookie_type aCookie) final
224 {
225 std::scoped_lock<mutex_type> lock{ mutex() };
226 if (contains(aCookie))
227 return std::next(begin(), reverse_indices()[aCookie]);
228 return end();
229 }
230 const value_type& operator[](cookie_type aCookie) const final
231 {
232 std::scoped_lock<mutex_type> lock{ mutex() };
233 if (aCookie >= reverse_indices().size())
234 throw cookie_invalid();
235 auto reverseIndex = reverse_indices()[aCookie];
236 if (reverseIndex == INVALID_REVERSE_INDEX)
237 throw cookie_invalid();
238 return items()[reverseIndex];
239 }
241 {
242 return const_cast<value_type&>(to_const(*this)[aCookie]);
243 }
244 const value_type& at_index(std::size_t aIndex) const final
245 {
246 return items().at(aIndex);
247 }
248 value_type& at_index(std::size_t aIndex) final
249 {
250 return items().at(aIndex);
251 }
253 {
254 auto cookie = next_cookie();
255 try
256 {
257 add(cookie, aItem);
258 }
259 catch (...)
260 {
262 throw;
263 }
264 return cookie;
265 }
266 template <typename... Args>
267 cookie_type emplace(Args&&... aArgs)
268 {
269 auto cookie = next_cookie();
270 try
271 {
272 add(cookie, std::forward<Args>(aArgs)...);
273 }
274 catch (...)
275 {
277 throw;
278 }
279 return cookie;
280 }
281 iterator add(cookie_type aCookie, abstract_t<value_type> const& aItem) final
282 {
283 return add<const abstract_t<value_type>&>(aCookie, aItem);
284 }
286 {
287 return remove(*aItem);
288 }
289 template <typename... Args>
290 iterator add(cookie_type aCookie, Args&&... aArgs)
291 {
292 std::scoped_lock<mutex_type> lock{ mutex() };
293 assert(std::find(free_cookies().begin(), free_cookies().end(), aCookie) == free_cookies().end());
294 if (reverse_indices().size() <= aCookie)
295 reverse_indices().insert(reverse_indices().end(), (aCookie + 1) - reverse_indices().size(), INVALID_REVERSE_INDEX);
296 if (reverse_indices()[aCookie] != INVALID_REVERSE_INDEX)
297 throw cookie_already_added();
298 std::optional<iterator> result;
299 if constexpr (!detail::is_smart_ptr_v<value_type>)
300 result = items().emplace(items().end(), std::forward<Args>(aArgs)...);
301 else if constexpr (detail::is_smart_ptr_v<value_type> && std::is_abstract_v<typename value_type::element_type>)
302 result = items().emplace(items().end(), std::forward<Args>(aArgs)...);
303 else if constexpr (detail::is_smart_ptr_v<value_type> && !std::is_abstract_v<typename value_type::element_type>)
304 result = items().insert(items().end(), value_type{ new typename value_type::element_type{std::forward<Args>(aArgs)...} });
305 try
306 {
307 allocated_cookies().insert(allocated_cookies().end(), aCookie);
308 }
309 catch (...)
310 {
311 items().pop_back();
312 throw;
313 }
314 reverse_indices()[aCookie] = items().size() - 1;
315 return *result;
316 }
318 {
319 std::scoped_lock<mutex_type> lock{ mutex() };
320 return remove(item_cookie(aItem));
321 }
323 {
324 std::scoped_lock<mutex_type> lock{ mutex() };
325 assert(std::find(free_cookies().begin(), free_cookies().end(), aCookie) == free_cookies().end());
326 if (aCookie >= reverse_indices().size())
327 throw cookie_invalid();
328 auto& reverseIndex = reverse_indices()[aCookie];
329 if (reverseIndex == INVALID_REVERSE_INDEX)
330 throw cookie_invalid();
331 if (reverseIndex < items().size() - 1)
332 {
333 auto& item = items()[reverseIndex];
334 std::swap(item, items().back());
335 auto& cookie = allocated_cookies()[reverseIndex];
336 std::swap(cookie, allocated_cookies().back());
337 reverse_indices()[cookie] = reverseIndex;
338 }
339 auto resultIndex = reverseIndex;
340 reverseIndex = INVALID_REVERSE_INDEX;
341 allocated_cookies().pop_back();
342 return_cookie(aCookie);
343 items().pop_back();
344 return resultIndex < items().size() ? std::next(items().begin(), resultIndex) : items().end();
345 }
346 public:
348 {
349 if constexpr (!std::is_pointer_v<value_type>)
350 return allocated_cookies()[&static_cast<value_type const&>(aItem) - &items()[0]];
351 else
353 }
355 {
356 std::scoped_lock<mutex_type> lock{ mutex() };
357 if (!free_cookies().empty())
358 {
359 auto nextCookie = free_cookies().back();
360 free_cookies().pop_back();
361 return nextCookie;
362 }
363 auto nextCookie = ++iNextAvailableCookie;
364 if (nextCookie == INVALID_COOKIE)
365 throw cookies_exhausted();
366 assert(std::find(free_cookies().begin(), free_cookies().end(), nextCookie) == free_cookies().end());
367 return nextCookie;
368 }
369 void return_cookie(cookie_type aCookie) final
370 {
371 std::scoped_lock<mutex_type> lock{ mutex() };
372 assert(std::find(free_cookies().begin(), free_cookies().end(), aCookie) == free_cookies().end());
373 free_cookies().push_back(aCookie);
374 }
375 public:
377 {
378 return iMutex;
379 }
380 const_iterator cbegin() const final
381 {
382 return items().begin();
383 }
384 const_iterator begin() const final
385 {
386 return cbegin();
387 }
389 {
390 return items().begin();
391 }
392 const_iterator cend() const final
393 {
394 return items().end();
395 }
396 const_iterator end() const final
397 {
398 return cend();
399 }
400 iterator end() final
401 {
402 return items().end();
403 }
404 public:
405 void clear() final
406 {
407 std::scoped_lock<mutex_type> lock{ mutex() };
408 iNextAvailableCookie = 0ul;
409 allocated_cookies().clear();
410 free_cookies().clear();
411 items().clear();
412 reverse_indices().clear();
413 }
414 const container_type& items() const final
415 {
416 return iItems;
417 }
419 {
420 return iItems;
421 }
422 private:
423 const cookies_t& allocated_cookies() const
424 {
425 return iAllocatedCookies;
426 }
427 cookies_t& allocated_cookies()
428 {
429 return iAllocatedCookies;
430 }
431 const cookies_t& free_cookies() const
432 {
433 return iFreeCookies;
434 }
435 cookies_t& free_cookies()
436 {
437 return iFreeCookies;
438 }
439 const reverse_indices_t& reverse_indices() const
440 {
441 return iReverseIndices;
442 }
443 reverse_indices_t& reverse_indices()
444 {
445 return iReverseIndices;
446 }
447 private:
448 mutable mutex_type iMutex;
449 mutable std::atomic<cookie_type> iNextAvailableCookie;
450 cookies_t iAllocatedCookies;
451 container_type iItems;
452 mutable cookies_t iFreeCookies;
453 reverse_indices_t iReverseIndices;
454 };
455
456 template <typename T, typename CookieType = cookie, typename MutexType = null_mutex>
458 {
459 public:
460 typedef CookieType cookie_type;
461 public:
462 typedef T value_type;
463 typedef std::vector<value_type> container_type;
464 typedef typename container_type::const_iterator const_iterator;
465 typedef typename container_type::iterator iterator;
466 typedef MutexType mutex_type;
467 private:
468 typedef typename container_type::size_type reverse_index_t;
469 typedef std::vector<reverse_index_t> reverse_indices_t;
470 typedef std::vector<cookie_type> cookies_t;
471 private:
472 static constexpr cookie_type INVALID_COOKIE = invalid_cookie<cookie_type>;
473 static constexpr reverse_index_t INVALID_REVERSE_INDEX = static_cast<reverse_index_t>(~reverse_index_t{});
474 public:
475 basic_vector_jar() : iNextAvailableCookie{}
476 {
477 }
478 public:
479 bool empty() const
480 {
481 return items().empty();
482 }
483 std::size_t size() const
484 {
485 return items().size();
486 }
487 bool contains(cookie_type aCookie) const
488 {
489 std::scoped_lock<mutex_type> lock{ mutex() };
490 return aCookie < reverse_indices().size() && reverse_indices()[aCookie] != INVALID_REVERSE_INDEX;
491 }
493 {
494 std::scoped_lock<mutex_type> lock{ mutex() };
495 if (contains(aCookie))
496 return std::next(begin(), reverse_indices()[aCookie]);
497 return end();
498 }
500 {
501 std::scoped_lock<mutex_type> lock{ mutex() };
502 if (contains(aCookie))
503 return std::next(begin(), reverse_indices()[aCookie]);
504 return end();
505 }
506 const value_type& operator[](cookie_type aCookie) const
507 {
508 std::scoped_lock<mutex_type> lock{ mutex() };
509 if (aCookie >= reverse_indices().size())
510 throw cookie_invalid();
511 auto reverseIndex = reverse_indices()[aCookie];
512 if (reverseIndex == INVALID_REVERSE_INDEX)
513 throw cookie_invalid();
514 return items()[reverseIndex];
515 }
517 {
518 return const_cast<value_type&>(to_const(*this)[aCookie]);
519 }
520 const value_type& at_index(std::size_t aIndex) const
521 {
522 return items().at(aIndex);
523 }
524 value_type& at_index(std::size_t aIndex)
525 {
526 return items().at(aIndex);
527 }
529 {
530 auto cookie = next_cookie();
531 try
532 {
533 add(cookie, aItem);
534 }
535 catch (...)
536 {
538 throw;
539 }
540 return cookie;
541 }
542 template <typename... Args>
543 cookie_type emplace(Args&&... aArgs)
544 {
545 auto cookie = next_cookie();
546 try
547 {
548 add(cookie, std::forward<Args>(aArgs)...);
549 }
550 catch (...)
551 {
553 throw;
554 }
555 return cookie;
556 }
558 {
559 return add<const abstract_t<value_type>&>(aCookie, aItem);
560 }
562 {
563 return remove(*aItem);
564 }
565 template <typename... Args>
566 iterator add(cookie_type aCookie, Args&&... aArgs)
567 {
568 std::scoped_lock<mutex_type> lock{ mutex() };
569 assert(std::find(free_cookies().begin(), free_cookies().end(), aCookie) == free_cookies().end());
570 if (reverse_indices().size() <= aCookie)
571 reverse_indices().insert(reverse_indices().end(), (aCookie + 1) - reverse_indices().size(), INVALID_REVERSE_INDEX);
572 if (reverse_indices()[aCookie] != INVALID_REVERSE_INDEX)
573 throw cookie_already_added();
574 std::optional<iterator> result;
575 if constexpr (!detail::is_smart_ptr_v<value_type>)
576 result = items().emplace(items().end(), std::forward<Args>(aArgs)...);
577 else if constexpr (detail::is_smart_ptr_v<value_type> && std::is_abstract_v<typename value_type::element_type>)
578 result = items().emplace(items().end(), std::forward<Args>(aArgs)...);
579 else if constexpr (detail::is_smart_ptr_v<value_type> && !std::is_abstract_v<typename value_type::element_type>)
580 result = items().insert(items().end(), value_type{ new typename value_type::element_type{std::forward<Args>(aArgs)...} });
581 try
582 {
583 allocated_cookies().insert(allocated_cookies().end(), aCookie);
584 }
585 catch (...)
586 {
587 items().pop_back();
588 throw;
589 }
590 reverse_indices()[aCookie] = items().size() - 1;
591 return *result;
592 }
594 {
595 std::scoped_lock<mutex_type> lock{ mutex() };
596 return remove(item_cookie(aItem));
597 }
599 {
600 std::scoped_lock<mutex_type> lock{ mutex() };
601 assert(std::find(free_cookies().begin(), free_cookies().end(), aCookie) == free_cookies().end());
602 if (aCookie >= reverse_indices().size())
603 throw cookie_invalid();
604 auto& reverseIndex = reverse_indices()[aCookie];
605 if (reverseIndex == INVALID_REVERSE_INDEX)
606 throw cookie_invalid();
607 if (reverseIndex < items().size() - 1)
608 {
609 auto& item = items()[reverseIndex];
610 swap(item, items().back());
611 auto& cookie = allocated_cookies()[reverseIndex];
612 std::swap(cookie, allocated_cookies().back());
613 reverse_indices()[cookie] = reverseIndex;
614 }
615 auto resultIndex = reverseIndex;
616 reverseIndex = INVALID_REVERSE_INDEX;
617 allocated_cookies().pop_back();
618 return_cookie(aCookie);
619 items().pop_back();
620 return resultIndex < items().size() ? std::next(items().begin(), resultIndex) : items().end();
621 }
622 public:
624 {
625 if constexpr (!std::is_pointer_v<value_type>)
626 return allocated_cookies()[&static_cast<value_type const&>(aItem) - &items()[0]];
627 else
629 }
631 {
632 std::scoped_lock<mutex_type> lock{ mutex() };
633 if (!free_cookies().empty())
634 {
635 auto nextCookie = free_cookies().back();
636 free_cookies().pop_back();
637 return nextCookie;
638 }
639 auto nextCookie = ++iNextAvailableCookie;
640 if (nextCookie == INVALID_COOKIE)
641 throw cookies_exhausted();
642 assert(std::find(free_cookies().begin(), free_cookies().end(), nextCookie) == free_cookies().end());
643 return nextCookie;
644 }
646 {
647 std::scoped_lock<mutex_type> lock{ mutex() };
648 assert(std::find(free_cookies().begin(), free_cookies().end(), aCookie) == free_cookies().end());
649 free_cookies().push_back(aCookie);
650 }
651 public:
653 {
654 return iMutex;
655 }
657 {
658 return items().begin();
659 }
661 {
662 return cbegin();
663 }
665 {
666 return items().begin();
667 }
669 {
670 return items().end();
671 }
673 {
674 return cend();
675 }
677 {
678 return items().end();
679 }
680 public:
681 void clear()
682 {
683 std::scoped_lock<mutex_type> lock{ mutex() };
684 iNextAvailableCookie = 0ul;
685 allocated_cookies().clear();
686 free_cookies().clear();
687 items().clear();
688 reverse_indices().clear();
689 }
690 const container_type& items() const
691 {
692 return iItems;
693 }
695 {
696 return iItems;
697 }
698 private:
699 const cookies_t& allocated_cookies() const
700 {
701 return iAllocatedCookies;
702 }
703 cookies_t& allocated_cookies()
704 {
705 return iAllocatedCookies;
706 }
707 const cookies_t& free_cookies() const
708 {
709 return iFreeCookies;
710 }
711 cookies_t& free_cookies()
712 {
713 return iFreeCookies;
714 }
715 const reverse_indices_t& reverse_indices() const
716 {
717 return iReverseIndices;
718 }
719 reverse_indices_t& reverse_indices()
720 {
721 return iReverseIndices;
722 }
723 private:
724 mutable mutex_type iMutex;
725 mutable std::atomic<cookie_type> iNextAvailableCookie;
726 cookies_t iAllocatedCookies;
727 container_type iItems;
728 mutable cookies_t iFreeCookies;
729 reverse_indices_t iReverseIndices;
730 };
731
734
735 template <typename T, typename MutexType = null_mutex>
736 using jar = basic_jar<T, vector<T>, cookie, MutexType>;
737 template <typename T, typename MutexType = null_mutex>
739
740 template <typename T, typename MutexType = null_mutex>
742 template <typename T, typename MutexType = null_mutex>
744}
void return_cookie(cookie_type aCookie) final
Definition jar.hpp:369
iterator end() final
Definition jar.hpp:400
value_type & operator[](cookie_type aCookie) final
Definition jar.hpp:240
cookie_type next_cookie() final
Definition jar.hpp:354
void clear() final
Definition jar.hpp:405
iterator add(cookie_type aCookie, abstract_t< value_type > const &aItem) final
Definition jar.hpp:281
iterator add(cookie_type aCookie, Args &&... aArgs)
Definition jar.hpp:290
CookieType cookie_type
Definition jar.hpp:184
const container_type & items() const final
Definition jar.hpp:414
iterator remove(abstract_t< value_type > const &aItem) final
Definition jar.hpp:317
mutex_type & mutex() const
Definition jar.hpp:376
iterator find(cookie_type aCookie) final
Definition jar.hpp:223
const_iterator end() const final
Definition jar.hpp:396
iterator erase(const_iterator aItem) final
Definition jar.hpp:285
MutexType mutex_type
Definition jar.hpp:190
bool empty() const final
Definition jar.hpp:203
bool contains(cookie_type aCookie) const final
Definition jar.hpp:211
const_iterator find(cookie_type aCookie) const final
Definition jar.hpp:216
cookie_type insert(abstract_t< value_type > const &aItem) final
Definition jar.hpp:252
Container container_type
Definition jar.hpp:187
cookie_type emplace(Args &&... aArgs)
Definition jar.hpp:267
const value_type & at_index(std::size_t aIndex) const final
Definition jar.hpp:244
iterator begin() final
Definition jar.hpp:388
std::size_t size() const final
Definition jar.hpp:207
const value_type & operator[](cookie_type aCookie) const final
Definition jar.hpp:230
value_type & at_index(std::size_t aIndex) final
Definition jar.hpp:248
const_iterator begin() const final
Definition jar.hpp:384
container_type::iterator iterator
Definition jar.hpp:189
const_iterator cend() const final
Definition jar.hpp:392
cookie_type item_cookie(abstract_t< value_type > const &aItem) const final
Definition jar.hpp:347
const_iterator cbegin() const final
Definition jar.hpp:380
container_type::const_iterator const_iterator
Definition jar.hpp:188
container_type & items() final
Definition jar.hpp:418
iterator remove(cookie_type aCookie) final
Definition jar.hpp:322
const_iterator cend() const
Definition jar.hpp:668
bool empty() const
Definition jar.hpp:479
iterator add(cookie_type aCookie, abstract_t< value_type > const &aItem)
Definition jar.hpp:557
const_iterator find(cookie_type aCookie) const
Definition jar.hpp:492
cookie_type item_cookie(abstract_t< value_type > const &aItem) const
Definition jar.hpp:623
value_type & at_index(std::size_t aIndex)
Definition jar.hpp:524
container_type & items()
Definition jar.hpp:694
iterator add(cookie_type aCookie, Args &&... aArgs)
Definition jar.hpp:566
const_iterator end() const
Definition jar.hpp:672
bool contains(cookie_type aCookie) const
Definition jar.hpp:487
iterator remove(cookie_type aCookie)
Definition jar.hpp:598
const_iterator cbegin() const
Definition jar.hpp:656
const container_type & items() const
Definition jar.hpp:690
std::vector< value_type > container_type
Definition jar.hpp:463
value_type & operator[](cookie_type aCookie)
Definition jar.hpp:516
const_iterator begin() const
Definition jar.hpp:660
container_type::const_iterator const_iterator
Definition jar.hpp:464
mutex_type & mutex() const
Definition jar.hpp:652
cookie_type insert(abstract_t< value_type > const &aItem)
Definition jar.hpp:528
CookieType cookie_type
Definition jar.hpp:460
iterator find(cookie_type aCookie)
Definition jar.hpp:499
const value_type & at_index(std::size_t aIndex) const
Definition jar.hpp:520
const value_type & operator[](cookie_type aCookie) const
Definition jar.hpp:506
cookie_type next_cookie()
Definition jar.hpp:630
std::size_t size() const
Definition jar.hpp:483
void return_cookie(cookie_type aCookie)
Definition jar.hpp:645
iterator erase(const_iterator aItem)
Definition jar.hpp:561
container_type::iterator iterator
Definition jar.hpp:465
iterator remove(abstract_t< value_type > const &aItem)
Definition jar.hpp:593
cookie_type emplace(Args &&... aArgs)
Definition jar.hpp:543
typename detail::abstract_type< T >::type abstract_t
Definition neolib.hpp:178
basic_vector_jar< T, cookie, MutexType > vector_jar
Definition jar.hpp:741
void swap(any &aLhs, any &aRhs)
Definition any.hpp:261
basic_cookie_ref_ptr< small_cookie > small_cookie_ref_ptr
Definition jar.hpp:733
uint32_t cookie
Definition i_jar.hpp:44
basic_jar< T, vector< T >, cookie, MutexType > jar
Definition jar.hpp:736
basic_cookie_ref_ptr< cookie > cookie_ref_ptr
Definition jar.hpp:732
to_const_reference_t< T > to_const(T &&object)
Definition neolib.hpp:113
uint16_t small_cookie
Definition i_jar.hpp:45
basic_jar< T, vector< T >, small_cookie, MutexType > small_jar
Definition jar.hpp:738
basic_vector_jar< T, small_cookie, MutexType > small_vector_jar
Definition jar.hpp:743
Definition plf_hive.h:79
void swap(plf::hive< element_type, allocator_type > &a, plf::hive< element_type, allocator_type > &b) noexcept(std::allocator_traits< allocator_type >::propagate_on_container_swap::value||std::allocator_traits< allocator_type >::is_always_equal::value)
Definition plf_hive.h:4776
it_type next(it_type it, const typename iterator_traits< it_type >::difference_type distance=1)
Definition plf_hive.h:89