rippled
Loading...
Searching...
No Matches
aged_ordered_container.h
1//------------------------------------------------------------------------------
2/*
3 This file is part of Beast: https://github.com/vinniefalco/Beast
4 Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#ifndef BEAST_CONTAINER_DETAIL_AGED_ORDERED_CONTAINER_H_INCLUDED
21#define BEAST_CONTAINER_DETAIL_AGED_ORDERED_CONTAINER_H_INCLUDED
22
23#include <xrpl/beast/clock/abstract_clock.h>
24#include <xrpl/beast/container/aged_container.h>
25#include <xrpl/beast/container/detail/aged_associative_container.h>
26#include <xrpl/beast/container/detail/aged_container_iterator.h>
27#include <xrpl/beast/container/detail/empty_base_optimization.h>
28#include <boost/intrusive/list.hpp>
29#include <boost/intrusive/set.hpp>
30#include <boost/version.hpp>
31#include <algorithm>
32#include <functional>
33#include <initializer_list>
34#include <iterator>
35#include <memory>
36#include <type_traits>
37#include <utility>
38
39namespace beast {
40namespace detail {
41
42// Traits templates used to discern reverse_iterators, which are disallowed
43// for mutating operations.
44template <class It>
46{
47 explicit is_boost_reverse_iterator() = default;
48};
49
50template <class It>
51struct is_boost_reverse_iterator<boost::intrusive::reverse_iterator<It>>
53{
54 explicit is_boost_reverse_iterator() = default;
55};
56
73template <
74 bool IsMulti,
75 bool IsMap,
76 class Key,
77 class T,
78 class Clock = std::chrono::steady_clock,
79 class Compare = std::less<Key>,
80 class Allocator = std::allocator<
83{
84public:
88 using key_type = Key;
89 using mapped_type = T;
90 using value_type =
94
95 // Introspection (for unit tests)
99
100private:
101 static Key const&
102 extract(value_type const& value)
103 {
105 }
106
107 // VFALCO TODO hoist to remove template argument dependencies
108 struct element
109 : boost::intrusive::set_base_hook<
110 boost::intrusive::link_mode<boost::intrusive::normal_link>>,
111 boost::intrusive::list_base_hook<
112 boost::intrusive::link_mode<boost::intrusive::normal_link>>
113 {
114 // Stash types here so the iterator doesn't
115 // need to see the container declaration.
116 struct stashed
117 {
118 explicit stashed() = default;
119
122 };
123
124 element(time_point const& when_, value_type const& value_)
125 : value(value_), when(when_)
126 {
127 }
128
129 element(time_point const& when_, value_type&& value_)
130 : value(std::move(value_)), when(when_)
131 {
132 }
133
134 template <
135 class... Args,
136 class = typename std::enable_if<
138 element(time_point const& when_, Args&&... args)
139 : value(std::forward<Args>(args)...), when(when_)
140 {
141 }
142
145 };
146
147 // VFALCO TODO This should only be enabled for maps.
148 class pair_value_compare : public Compare
149 {
150 public:
153 using result_type = bool;
154
155 bool
156 operator()(value_type const& lhs, value_type const& rhs) const
157 {
158 return Compare::operator()(lhs.first, rhs.first);
159 }
160
162 {
163 }
164
165 pair_value_compare(pair_value_compare const& other) : Compare(other)
166 {
167 }
168
169 private:
171
172 pair_value_compare(Compare const& compare) : Compare(compare)
173 {
174 }
175 };
176
177 // Compares value_type against element, used in insert_check
178 // VFALCO TODO hoist to remove template argument dependencies
179 class KeyValueCompare : public Compare
180 {
181 public:
182 using first_argument = Key;
184 using result_type = bool;
185
186 KeyValueCompare() = default;
187
188 KeyValueCompare(Compare const& compare) : Compare(compare)
189 {
190 }
191
192 bool
193 operator()(Key const& k, element const& e) const
194 {
195 return Compare::operator()(k, extract(e.value));
196 }
197
198 bool
199 operator()(element const& e, Key const& k) const
200 {
201 return Compare::operator()(extract(e.value), k);
202 }
203
204 bool
205 operator()(element const& x, element const& y) const
206 {
207 return Compare::operator()(extract(x.value), extract(y.value));
208 }
209
210 Compare&
212 {
213 return *this;
214 }
215
216 Compare const&
217 compare() const
218 {
219 return *this;
220 }
221 };
222
223 using list_type = typename boost::intrusive::
224 make_list<element, boost::intrusive::constant_time_size<false>>::type;
225
226 using cont_type = typename std::conditional<
227 IsMulti,
228 typename boost::intrusive::make_multiset<
229 element,
230 boost::intrusive::constant_time_size<true>,
231 boost::intrusive::compare<KeyValueCompare>>::type,
232 typename boost::intrusive::make_set<
233 element,
234 boost::intrusive::constant_time_size<true>,
235 boost::intrusive::compare<KeyValueCompare>>::type>::type;
236
238 Allocator>::template rebind_alloc<element>;
239
241
243 : private KeyValueCompare,
244 public beast::detail::empty_base_optimization<ElementAllocator>
245 {
246 public:
247 explicit config_t(clock_type& clock_) : clock(clock_)
248 {
249 }
250
251 config_t(clock_type& clock_, Compare const& comp)
252 : KeyValueCompare(comp), clock(clock_)
253 {
254 }
255
256 config_t(clock_type& clock_, Allocator const& alloc_)
258 , clock(clock_)
259 {
260 }
261
263 clock_type& clock_,
264 Compare const& comp,
265 Allocator const& alloc_)
266 : KeyValueCompare(comp)
268 , clock(clock_)
269 {
270 }
271
272 config_t(config_t const& other)
275 ElementAllocatorTraits::select_on_container_copy_construction(
276 other.alloc()))
277 , clock(other.clock)
278 {
279 }
280
281 config_t(config_t const& other, Allocator const& alloc)
284 , clock(other.clock)
285 {
286 }
287
289 : KeyValueCompare(std::move(other.key_compare()))
291 std::move(other))
292 , clock(other.clock)
293 {
294 }
295
296 config_t(config_t&& other, Allocator const& alloc)
297 : KeyValueCompare(std::move(other.key_compare()))
299 , clock(other.clock)
300 {
301 }
302
303 config_t&
304 operator=(config_t const& other)
305 {
306 if (this != &other)
307 {
308 compare() = other.compare();
309 alloc() = other.alloc();
310 clock = other.clock;
311 }
312 return *this;
313 }
314
315 config_t&
317 {
318 compare() = std::move(other.compare());
319 alloc() = std::move(other.alloc());
320 clock = other.clock;
321 return *this;
322 }
323
324 Compare&
326 {
328 }
329
330 Compare const&
331 compare() const
332 {
334 }
335
338 {
339 return *this;
340 }
341
342 KeyValueCompare const&
344 {
345 return *this;
346 }
347
350 {
353 }
354
355 ElementAllocator const&
356 alloc() const
357 {
360 }
361
363 };
364
365 template <class... Args>
366 element*
367 new_element(Args&&... args)
368 {
369 struct Deleter
370 {
372 Deleter(ElementAllocator& a) : a_(a)
373 {
374 }
375
376 void
377 operator()(element* p)
378 {
379 ElementAllocatorTraits::deallocate(a_.get(), p, 1);
380 }
381 };
382
385 Deleter(m_config.alloc()));
387 m_config.alloc(),
388 p.get(),
389 clock().now(),
390 std::forward<Args>(args)...);
391 return p.release();
392 }
393
394 void
396 {
399 m_config.alloc(), const_cast<element*>(p), 1);
400 }
401
402 void
404 {
405 chronological.list.erase(chronological.list.iterator_to(*p));
406 m_cont.erase(m_cont.iterator_to(*p));
408 }
409
410public:
411 using key_compare = Compare;
414 using allocator_type = Allocator;
420
421 // A set iterator (IsMap==false) is always const
422 // because the elements of a set are immutable.
423 using iterator = beast::detail::
424 aged_container_iterator<!IsMap, typename cont_type::iterator>;
425 using const_iterator = beast::detail::
426 aged_container_iterator<true, typename cont_type::iterator>;
427 using reverse_iterator = beast::detail::
428 aged_container_iterator<!IsMap, typename cont_type::reverse_iterator>;
429 using const_reverse_iterator = beast::detail::
430 aged_container_iterator<true, typename cont_type::reverse_iterator>;
431
432 //--------------------------------------------------------------------------
433 //
434 // Chronological ordered iterators
435 //
436 // "Memberspace"
437 // http://accu.org/index.php/journals/1527
438 //
439 //--------------------------------------------------------------------------
440
442 {
443 public:
444 // A set iterator (IsMap==false) is always const
445 // because the elements of a set are immutable.
446 using iterator = beast::detail::
447 aged_container_iterator<!IsMap, typename list_type::iterator>;
448 using const_iterator = beast::detail::
449 aged_container_iterator<true, typename list_type::iterator>;
451 !IsMap,
452 typename list_type::reverse_iterator>;
453 using const_reverse_iterator = beast::detail::
454 aged_container_iterator<true, typename list_type::reverse_iterator>;
455
458 {
459 return iterator(list.begin());
460 }
461
463 begin() const
464 {
465 return const_iterator(list.begin());
466 }
467
469 cbegin() const
470 {
471 return const_iterator(list.begin());
472 }
473
476 {
477 return iterator(list.end());
478 }
479
481 end() const
482 {
483 return const_iterator(list.end());
484 }
485
487 cend() const
488 {
489 return const_iterator(list.end());
490 }
491
494 {
495 return reverse_iterator(list.rbegin());
496 }
497
499 rbegin() const
500 {
501 return const_reverse_iterator(list.rbegin());
502 }
503
505 crbegin() const
506 {
507 return const_reverse_iterator(list.rbegin());
508 }
509
512 {
513 return reverse_iterator(list.rend());
514 }
515
517 rend() const
518 {
519 return const_reverse_iterator(list.rend());
520 }
521
523 crend() const
524 {
525 return const_reverse_iterator(list.rend());
526 }
527
530 {
531 static_assert(
533 "must be standard layout");
534 return list.iterator_to(*reinterpret_cast<element*>(
535 reinterpret_cast<uint8_t*>(&value) -
536 ((std::size_t)std::addressof(((element*)0)->member))));
537 }
538
540 iterator_to(value_type const& value) const
541 {
542 static_assert(
544 "must be standard layout");
545 return list.iterator_to(*reinterpret_cast<element const*>(
546 reinterpret_cast<uint8_t const*>(&value) -
547 ((std::size_t)std::addressof(((element*)0)->member))));
548 }
549
550 private:
552 {
553 }
554
557
561
562 //--------------------------------------------------------------------------
563 //
564 // Construction
565 //
566 //--------------------------------------------------------------------------
567
569
571
573
574 aged_ordered_container(clock_type& clock, Allocator const& alloc);
575
578 Compare const& comp,
579 Allocator const& alloc);
580
581 template <class InputIt>
582 aged_ordered_container(InputIt first, InputIt last, clock_type& clock);
583
584 template <class InputIt>
586 InputIt first,
587 InputIt last,
589 Compare const& comp);
590
591 template <class InputIt>
593 InputIt first,
594 InputIt last,
596 Allocator const& alloc);
597
598 template <class InputIt>
600 InputIt first,
601 InputIt last,
603 Compare const& comp,
604 Allocator const& alloc);
605
607
609 aged_ordered_container const& other,
610 Allocator const& alloc);
611
613
616 Allocator const& alloc);
617
621
625 Compare const& comp);
626
630 Allocator const& alloc);
631
635 Compare const& comp,
636 Allocator const& alloc);
637
639
642
645
648
651 {
652 return m_config.alloc();
653 }
654
657 {
658 return m_config.clock;
659 }
660
661 clock_type const&
662 clock() const
663 {
664 return m_config.clock;
665 }
666
667 //--------------------------------------------------------------------------
668 //
669 // Element access (maps)
670 //
671 //--------------------------------------------------------------------------
672
673 template <
674 class K,
675 bool maybe_multi = IsMulti,
676 bool maybe_map = IsMap,
679 at(K const& k);
680
681 template <
682 class K,
683 bool maybe_multi = IsMulti,
684 bool maybe_map = IsMap,
687 at(K const& k) const;
688
689 template <
690 bool maybe_multi = IsMulti,
691 bool maybe_map = IsMap,
694 operator[](Key const& key);
695
696 template <
697 bool maybe_multi = IsMulti,
698 bool maybe_map = IsMap,
701 operator[](Key&& key);
702
703 //--------------------------------------------------------------------------
704 //
705 // Iterators
706 //
707 //--------------------------------------------------------------------------
708
711 {
712 return iterator(m_cont.begin());
713 }
714
716 begin() const
717 {
718 return const_iterator(m_cont.begin());
719 }
720
722 cbegin() const
723 {
724 return const_iterator(m_cont.begin());
725 }
726
729 {
730 return iterator(m_cont.end());
731 }
732
734 end() const
735 {
736 return const_iterator(m_cont.end());
737 }
738
740 cend() const
741 {
742 return const_iterator(m_cont.end());
743 }
744
747 {
748 return reverse_iterator(m_cont.rbegin());
749 }
750
752 rbegin() const
753 {
754 return const_reverse_iterator(m_cont.rbegin());
755 }
756
758 crbegin() const
759 {
760 return const_reverse_iterator(m_cont.rbegin());
761 }
762
765 {
766 return reverse_iterator(m_cont.rend());
767 }
768
770 rend() const
771 {
772 return const_reverse_iterator(m_cont.rend());
773 }
774
776 crend() const
777 {
778 return const_reverse_iterator(m_cont.rend());
779 }
780
783 {
784 static_assert(
785 std::is_standard_layout<element>::value, "must be standard layout");
786 return m_cont.iterator_to(*reinterpret_cast<element*>(
787 reinterpret_cast<uint8_t*>(&value) -
788 ((std::size_t)std::addressof(((element*)0)->member))));
789 }
790
792 iterator_to(value_type const& value) const
793 {
794 static_assert(
795 std::is_standard_layout<element>::value, "must be standard layout");
796 return m_cont.iterator_to(*reinterpret_cast<element const*>(
797 reinterpret_cast<uint8_t const*>(&value) -
798 ((std::size_t)std::addressof(((element*)0)->member))));
799 }
800
801 //--------------------------------------------------------------------------
802 //
803 // Capacity
804 //
805 //--------------------------------------------------------------------------
806
807 bool
808 empty() const noexcept
809 {
810 return m_cont.empty();
811 }
812
814 size() const noexcept
815 {
816 return m_cont.size();
817 }
818
820 max_size() const noexcept
821 {
822 return m_config.max_size();
823 }
824
825 //--------------------------------------------------------------------------
826 //
827 // Modifiers
828 //
829 //--------------------------------------------------------------------------
830
831 void
833
834 // map, set
835 template <bool maybe_multi = IsMulti>
836 auto
837 insert(value_type const& value) ->
839
840 // multimap, multiset
841 template <bool maybe_multi = IsMulti>
842 auto
843 insert(value_type const& value) ->
845
846 // set
847 template <bool maybe_multi = IsMulti, bool maybe_map = IsMap>
848 auto
849 insert(value_type&& value) -> typename std::enable_if<
850 !maybe_multi && !maybe_map,
852
853 // multiset
854 template <bool maybe_multi = IsMulti, bool maybe_map = IsMap>
855 auto
856 insert(value_type&& value) ->
858
859 //---
860
861 // map, set
862 template <bool maybe_multi = IsMulti>
863 auto
864 insert(const_iterator hint, value_type const& value) ->
866
867 // multimap, multiset
868 template <bool maybe_multi = IsMulti>
870 insert(const_iterator /*hint*/, value_type const& value)
871 {
872 // VFALCO TODO Figure out how to utilize 'hint'
873 return insert(value);
874 }
875
876 // map, set
877 template <bool maybe_multi = IsMulti>
878 auto
881
882 // multimap, multiset
883 template <bool maybe_multi = IsMulti>
886 {
887 // VFALCO TODO Figure out how to utilize 'hint'
888 return insert(std::move(value));
889 }
890
891 // map, multimap
892 template <class P, bool maybe_map = IsMap>
893 typename std::enable_if<
895 typename std::
896 conditional<IsMulti, iterator, std::pair<iterator, bool>>::type>::
897 type
898 insert(P&& value)
899 {
900 return emplace(std::forward<P>(value));
901 }
902
903 // map, multimap
904 template <class P, bool maybe_map = IsMap>
905 typename std::enable_if<
907 typename std::
908 conditional<IsMulti, iterator, std::pair<iterator, bool>>::type>::
909 type
910 insert(const_iterator hint, P&& value)
911 {
912 return emplace_hint(hint, std::forward<P>(value));
913 }
914
915 template <class InputIt>
916 void
917 insert(InputIt first, InputIt last)
918 {
919 for (; first != last; ++first)
920 insert(cend(), *first);
921 }
922
923 void
925 {
926 insert(init.begin(), init.end());
927 }
928
929 // map, set
930 template <bool maybe_multi = IsMulti, class... Args>
931 auto
932 emplace(Args&&... args) ->
934
935 // multiset, multimap
936 template <bool maybe_multi = IsMulti, class... Args>
937 auto
938 emplace(Args&&... args) ->
940
941 // map, set
942 template <bool maybe_multi = IsMulti, class... Args>
943 auto
944 emplace_hint(const_iterator hint, Args&&... args) ->
946
947 // multiset, multimap
948 template <bool maybe_multi = IsMulti, class... Args>
950 emplace_hint(const_iterator /*hint*/, Args&&... args)
951 {
952 // VFALCO TODO Figure out how to utilize 'hint'
953 return emplace<maybe_multi>(std::forward<Args>(args)...);
954 }
955
956 // enable_if prevents erase (reverse_iterator pos) from compiling
957 template <
958 bool is_const,
959 class Iterator,
963
964 // enable_if prevents erase (reverse_iterator first, reverse_iterator last)
965 // from compiling
966 template <
967 bool is_const,
968 class Iterator,
974
975 template <class K>
976 auto
977 erase(K const& k) -> size_type;
978
979 void
980 swap(aged_ordered_container& other) noexcept;
981
982 //--------------------------------------------------------------------------
983
984 // enable_if prevents touch (reverse_iterator pos) from compiling
985 template <
986 bool is_const,
987 class Iterator,
989 void
991 {
992 touch(pos, clock().now());
993 }
994
995 template <class K>
997 touch(K const& k);
998
999 //--------------------------------------------------------------------------
1000 //
1001 // Lookup
1002 //
1003 //--------------------------------------------------------------------------
1004
1005 // VFALCO TODO Respect is_transparent (c++14)
1006 template <class K>
1007 size_type
1008 count(K const& k) const
1009 {
1010 return m_cont.count(k, std::cref(m_config.key_compare()));
1011 }
1012
1013 // VFALCO TODO Respect is_transparent (c++14)
1014 template <class K>
1015 iterator
1016 find(K const& k)
1017 {
1018 return iterator(m_cont.find(k, std::cref(m_config.key_compare())));
1019 }
1020
1021 // VFALCO TODO Respect is_transparent (c++14)
1022 template <class K>
1024 find(K const& k) const
1025 {
1026 return const_iterator(
1027 m_cont.find(k, std::cref(m_config.key_compare())));
1028 }
1029
1030 // VFALCO TODO Respect is_transparent (c++14)
1031 template <class K>
1033 equal_range(K const& k)
1034 {
1035 auto const r(m_cont.equal_range(k, std::cref(m_config.key_compare())));
1036 return std::make_pair(iterator(r.first), iterator(r.second));
1037 }
1038
1039 // VFALCO TODO Respect is_transparent (c++14)
1040 template <class K>
1042 equal_range(K const& k) const
1043 {
1044 auto const r(m_cont.equal_range(k, std::cref(m_config.key_compare())));
1045 return std::make_pair(
1046 const_iterator(r.first), const_iterator(r.second));
1047 }
1048
1049 // VFALCO TODO Respect is_transparent (c++14)
1050 template <class K>
1051 iterator
1052 lower_bound(K const& k)
1053 {
1054 return iterator(
1055 m_cont.lower_bound(k, std::cref(m_config.key_compare())));
1056 }
1057
1058 // VFALCO TODO Respect is_transparent (c++14)
1059 template <class K>
1061 lower_bound(K const& k) const
1062 {
1063 return const_iterator(
1064 m_cont.lower_bound(k, std::cref(m_config.key_compare())));
1065 }
1066
1067 // VFALCO TODO Respect is_transparent (c++14)
1068 template <class K>
1069 iterator
1070 upper_bound(K const& k)
1071 {
1072 return iterator(
1073 m_cont.upper_bound(k, std::cref(m_config.key_compare())));
1074 }
1075
1076 // VFALCO TODO Respect is_transparent (c++14)
1077 template <class K>
1079 upper_bound(K const& k) const
1080 {
1081 return const_iterator(
1082 m_cont.upper_bound(k, std::cref(m_config.key_compare())));
1083 }
1084
1085 //--------------------------------------------------------------------------
1086 //
1087 // Observers
1088 //
1089 //--------------------------------------------------------------------------
1090
1092 key_comp() const
1093 {
1094 return m_config.compare();
1095 }
1096
1097 // VFALCO TODO Should this return const reference for set?
1100 {
1101 return value_compare(m_config.compare());
1102 }
1103
1104 //--------------------------------------------------------------------------
1105 //
1106 // Comparison
1107 //
1108 //--------------------------------------------------------------------------
1109
1110 // This differs from the standard in that the comparison
1111 // is only done on the key portion of the value type, ignoring
1112 // the mapped type.
1113 //
1114 template <
1115 bool OtherIsMulti,
1116 bool OtherIsMap,
1117 class OtherT,
1118 class OtherDuration,
1119 class OtherAllocator>
1120 bool
1122 OtherIsMulti,
1123 OtherIsMap,
1124 Key,
1125 OtherT,
1126 OtherDuration,
1127 Compare,
1128 OtherAllocator> const& other) const;
1129
1130 template <
1131 bool OtherIsMulti,
1132 bool OtherIsMap,
1133 class OtherT,
1134 class OtherDuration,
1135 class OtherAllocator>
1136 bool
1138 OtherIsMulti,
1139 OtherIsMap,
1140 Key,
1141 OtherT,
1142 OtherDuration,
1143 Compare,
1144 OtherAllocator> const& other) const
1145 {
1146 return !(this->operator==(other));
1147 }
1148
1149 template <
1150 bool OtherIsMulti,
1151 bool OtherIsMap,
1152 class OtherT,
1153 class OtherDuration,
1154 class OtherAllocator>
1155 bool
1157 OtherIsMulti,
1158 OtherIsMap,
1159 Key,
1160 OtherT,
1161 OtherDuration,
1162 Compare,
1163 OtherAllocator> const& other) const
1164 {
1165 value_compare const comp(value_comp());
1167 cbegin(), cend(), other.cbegin(), other.cend(), comp);
1168 }
1169
1170 template <
1171 bool OtherIsMulti,
1172 bool OtherIsMap,
1173 class OtherT,
1174 class OtherDuration,
1175 class OtherAllocator>
1176 bool
1178 OtherIsMulti,
1179 OtherIsMap,
1180 Key,
1181 OtherT,
1182 OtherDuration,
1183 Compare,
1184 OtherAllocator> const& other) const
1185 {
1186 return !(other < *this);
1187 }
1188
1189 template <
1190 bool OtherIsMulti,
1191 bool OtherIsMap,
1192 class OtherT,
1193 class OtherDuration,
1194 class OtherAllocator>
1195 bool
1197 OtherIsMulti,
1198 OtherIsMap,
1199 Key,
1200 OtherT,
1201 OtherDuration,
1202 Compare,
1203 OtherAllocator> const& other) const
1204 {
1205 return other < *this;
1206 }
1207
1208 template <
1209 bool OtherIsMulti,
1210 bool OtherIsMap,
1211 class OtherT,
1212 class OtherDuration,
1213 class OtherAllocator>
1214 bool
1216 OtherIsMulti,
1217 OtherIsMap,
1218 Key,
1219 OtherT,
1220 OtherDuration,
1221 Compare,
1222 OtherAllocator> const& other) const
1223 {
1224 return !(*this < other);
1225 }
1226
1227private:
1228 // enable_if prevents erase (reverse_iterator pos, now) from compiling
1229 template <
1230 bool is_const,
1231 class Iterator,
1233 void
1236 typename clock_type::time_point const& now);
1237
1238 template <
1239 bool maybe_propagate = std::allocator_traits<
1240 Allocator>::propagate_on_container_swap::value>
1243
1244 template <
1245 bool maybe_propagate = std::allocator_traits<
1246 Allocator>::propagate_on_container_swap::value>
1249
1250private:
1253};
1254
1255//------------------------------------------------------------------------------
1256
1257template <
1258 bool IsMulti,
1259 bool IsMap,
1260 class Key,
1261 class T,
1262 class Clock,
1263 class Compare,
1264 class Allocator>
1267 : m_config(clock)
1268{
1269}
1270
1271template <
1272 bool IsMulti,
1273 bool IsMap,
1274 class Key,
1275 class T,
1276 class Clock,
1277 class Compare,
1278 class Allocator>
1280 aged_ordered_container(clock_type& clock, Compare const& comp)
1281 : m_config(clock, comp), m_cont(comp)
1282{
1283}
1284
1285template <
1286 bool IsMulti,
1287 bool IsMap,
1288 class Key,
1289 class T,
1290 class Clock,
1291 class Compare,
1292 class Allocator>
1294 aged_ordered_container(clock_type& clock, Allocator const& alloc)
1295 : m_config(clock, alloc)
1296{
1297}
1298
1299template <
1300 bool IsMulti,
1301 bool IsMap,
1302 class Key,
1303 class T,
1304 class Clock,
1305 class Compare,
1306 class Allocator>
1309 clock_type& clock,
1310 Compare const& comp,
1311 Allocator const& alloc)
1312 : m_config(clock, comp, alloc), m_cont(comp)
1313{
1314}
1315
1316template <
1317 bool IsMulti,
1318 bool IsMap,
1319 class Key,
1320 class T,
1321 class Clock,
1322 class Compare,
1323 class Allocator>
1324template <class InputIt>
1326 aged_ordered_container(InputIt first, InputIt last, clock_type& clock)
1327 : m_config(clock)
1328{
1329 insert(first, last);
1330}
1331
1332template <
1333 bool IsMulti,
1334 bool IsMap,
1335 class Key,
1336 class T,
1337 class Clock,
1338 class Compare,
1339 class Allocator>
1340template <class InputIt>
1343 InputIt first,
1344 InputIt last,
1345 clock_type& clock,
1346 Compare const& comp)
1347 : m_config(clock, comp), m_cont(comp)
1348{
1349 insert(first, last);
1350}
1351
1352template <
1353 bool IsMulti,
1354 bool IsMap,
1355 class Key,
1356 class T,
1357 class Clock,
1358 class Compare,
1359 class Allocator>
1360template <class InputIt>
1363 InputIt first,
1364 InputIt last,
1365 clock_type& clock,
1366 Allocator const& alloc)
1367 : m_config(clock, alloc)
1368{
1369 insert(first, last);
1370}
1371
1372template <
1373 bool IsMulti,
1374 bool IsMap,
1375 class Key,
1376 class T,
1377 class Clock,
1378 class Compare,
1379 class Allocator>
1380template <class InputIt>
1383 InputIt first,
1384 InputIt last,
1385 clock_type& clock,
1386 Compare const& comp,
1387 Allocator const& alloc)
1388 : m_config(clock, comp, alloc), m_cont(comp)
1389{
1390 insert(first, last);
1391}
1392
1393template <
1394 bool IsMulti,
1395 bool IsMap,
1396 class Key,
1397 class T,
1398 class Clock,
1399 class Compare,
1400 class Allocator>
1403 : m_config(other.m_config)
1404#if BOOST_VERSION >= 108000
1405 , m_cont(other.m_cont.get_comp())
1406#else
1407 , m_cont(other.m_cont.comp())
1408#endif
1409{
1410 insert(other.cbegin(), other.cend());
1411}
1412
1413template <
1414 bool IsMulti,
1415 bool IsMap,
1416 class Key,
1417 class T,
1418 class Clock,
1419 class Compare,
1420 class Allocator>
1423 aged_ordered_container const& other,
1424 Allocator const& alloc)
1425 : m_config(other.m_config, alloc)
1426#if BOOST_VERSION >= 108000
1427 , m_cont(other.m_cont.get_comp())
1428#else
1429 , m_cont(other.m_cont.comp())
1430#endif
1431{
1432 insert(other.cbegin(), other.cend());
1433}
1434
1435template <
1436 bool IsMulti,
1437 bool IsMap,
1438 class Key,
1439 class T,
1440 class Clock,
1441 class Compare,
1442 class Allocator>
1445 : m_config(std::move(other.m_config)), m_cont(std::move(other.m_cont))
1446{
1447 chronological.list = std::move(other.chronological.list);
1448}
1449
1450template <
1451 bool IsMulti,
1452 bool IsMap,
1453 class Key,
1454 class T,
1455 class Clock,
1456 class Compare,
1457 class Allocator>
1460 aged_ordered_container&& other,
1461 Allocator const& alloc)
1462 : m_config(std::move(other.m_config), alloc)
1463#if BOOST_VERSION >= 108000
1464 , m_cont(std::move(other.m_cont.get_comp()))
1465#else
1466 , m_cont(std::move(other.m_cont.comp()))
1467#endif
1468
1469{
1470 insert(other.cbegin(), other.cend());
1471 other.clear();
1472}
1473
1474template <
1475 bool IsMulti,
1476 bool IsMap,
1477 class Key,
1478 class T,
1479 class Clock,
1480 class Compare,
1481 class Allocator>
1485 clock_type& clock)
1486 : m_config(clock)
1487{
1488 insert(init.begin(), init.end());
1489}
1490
1491template <
1492 bool IsMulti,
1493 bool IsMap,
1494 class Key,
1495 class T,
1496 class Clock,
1497 class Compare,
1498 class Allocator>
1502 clock_type& clock,
1503 Compare const& comp)
1504 : m_config(clock, comp), m_cont(comp)
1505{
1506 insert(init.begin(), init.end());
1507}
1508
1509template <
1510 bool IsMulti,
1511 bool IsMap,
1512 class Key,
1513 class T,
1514 class Clock,
1515 class Compare,
1516 class Allocator>
1520 clock_type& clock,
1521 Allocator const& alloc)
1522 : m_config(clock, alloc)
1523{
1524 insert(init.begin(), init.end());
1525}
1526
1527template <
1528 bool IsMulti,
1529 bool IsMap,
1530 class Key,
1531 class T,
1532 class Clock,
1533 class Compare,
1534 class Allocator>
1538 clock_type& clock,
1539 Compare const& comp,
1540 Allocator const& alloc)
1541 : m_config(clock, comp, alloc), m_cont(comp)
1542{
1543 insert(init.begin(), init.end());
1544}
1545
1546template <
1547 bool IsMulti,
1548 bool IsMap,
1549 class Key,
1550 class T,
1551 class Clock,
1552 class Compare,
1553 class Allocator>
1556{
1557 clear();
1558}
1559
1560template <
1561 bool IsMulti,
1562 bool IsMap,
1563 class Key,
1564 class T,
1565 class Clock,
1566 class Compare,
1567 class Allocator>
1568auto
1571{
1572 if (this != &other)
1573 {
1574 clear();
1575 this->m_config = other.m_config;
1576 insert(other.begin(), other.end());
1577 }
1578 return *this;
1579}
1580
1581template <
1582 bool IsMulti,
1583 bool IsMap,
1584 class Key,
1585 class T,
1586 class Clock,
1587 class Compare,
1588 class Allocator>
1589auto
1592{
1593 clear();
1594 this->m_config = std::move(other.m_config);
1595 insert(other.begin(), other.end());
1596 other.clear();
1597 return *this;
1598}
1599
1600template <
1601 bool IsMulti,
1602 bool IsMap,
1603 class Key,
1604 class T,
1605 class Clock,
1606 class Compare,
1607 class Allocator>
1608auto
1611{
1612 clear();
1613 insert(init);
1614 return *this;
1615}
1616
1617//------------------------------------------------------------------------------
1618
1619template <
1620 bool IsMulti,
1621 bool IsMap,
1622 class Key,
1623 class T,
1624 class Clock,
1625 class Compare,
1626 class Allocator>
1627template <class K, bool maybe_multi, bool maybe_map, class>
1630 K const& k)
1631{
1632 auto const iter(m_cont.find(k, std::cref(m_config.key_compare())));
1633 if (iter == m_cont.end())
1634 throw std::out_of_range("key not found");
1635 return iter->value.second;
1636}
1637
1638template <
1639 bool IsMulti,
1640 bool IsMap,
1641 class Key,
1642 class T,
1643 class Clock,
1644 class Compare,
1645 class Allocator>
1646template <class K, bool maybe_multi, bool maybe_map, class>
1649 K const& k) const
1650{
1651 auto const iter(m_cont.find(k, std::cref(m_config.key_compare())));
1652 if (iter == m_cont.end())
1653 throw std::out_of_range("key not found");
1654 return iter->value.second;
1655}
1656
1657template <
1658 bool IsMulti,
1659 bool IsMap,
1660 class Key,
1661 class T,
1662 class Clock,
1663 class Compare,
1664 class Allocator>
1665template <bool maybe_multi, bool maybe_map, class>
1668operator[](Key const& key)
1669{
1670 typename cont_type::insert_commit_data d;
1671 auto const result(
1672 m_cont.insert_check(key, std::cref(m_config.key_compare()), d));
1673 if (result.second)
1674 {
1675 element* const p(new_element(
1676 std::piecewise_construct,
1679 m_cont.insert_commit(*p, d);
1680 chronological.list.push_back(*p);
1681 return p->value.second;
1682 }
1683 return result.first->value.second;
1684}
1685
1686template <
1687 bool IsMulti,
1688 bool IsMap,
1689 class Key,
1690 class T,
1691 class Clock,
1692 class Compare,
1693 class Allocator>
1694template <bool maybe_multi, bool maybe_map, class>
1697operator[](Key&& key)
1698{
1699 typename cont_type::insert_commit_data d;
1700 auto const result(
1701 m_cont.insert_check(key, std::cref(m_config.key_compare()), d));
1702 if (result.second)
1703 {
1704 element* const p(new_element(
1705 std::piecewise_construct,
1706 std::forward_as_tuple(std::move(key)),
1708 m_cont.insert_commit(*p, d);
1709 chronological.list.push_back(*p);
1710 return p->value.second;
1711 }
1712 return result.first->value.second;
1713}
1714
1715//------------------------------------------------------------------------------
1716
1717template <
1718 bool IsMulti,
1719 bool IsMap,
1720 class Key,
1721 class T,
1722 class Clock,
1723 class Compare,
1724 class Allocator>
1725void
1727 clear()
1728{
1729 for (auto iter(chronological.list.begin());
1730 iter != chronological.list.end();)
1731 delete_element(&*iter++);
1732 chronological.list.clear();
1733 m_cont.clear();
1734}
1735
1736// map, set
1737template <
1738 bool IsMulti,
1739 bool IsMap,
1740 class Key,
1741 class T,
1742 class Clock,
1743 class Compare,
1744 class Allocator>
1745template <bool maybe_multi>
1746auto
1748 insert(value_type const& value) ->
1750{
1751 typename cont_type::insert_commit_data d;
1752 auto const result(m_cont.insert_check(
1753 extract(value), std::cref(m_config.key_compare()), d));
1754 if (result.second)
1755 {
1756 element* const p(new_element(value));
1757 auto const iter(m_cont.insert_commit(*p, d));
1758 chronological.list.push_back(*p);
1759 return std::make_pair(iterator(iter), true);
1760 }
1761 return std::make_pair(iterator(result.first), false);
1762}
1763
1764// multimap, multiset
1765template <
1766 bool IsMulti,
1767 bool IsMap,
1768 class Key,
1769 class T,
1770 class Clock,
1771 class Compare,
1772 class Allocator>
1773template <bool maybe_multi>
1774auto
1776 insert(value_type const& value) ->
1778{
1779 auto const before(
1780 m_cont.upper_bound(extract(value), std::cref(m_config.key_compare())));
1781 element* const p(new_element(value));
1782 chronological.list.push_back(*p);
1783 auto const iter(m_cont.insert_before(before, *p));
1784 return iterator(iter);
1785}
1786
1787// set
1788template <
1789 bool IsMulti,
1790 bool IsMap,
1791 class Key,
1792 class T,
1793 class Clock,
1794 class Compare,
1795 class Allocator>
1796template <bool maybe_multi, bool maybe_map>
1797auto
1799 insert(value_type&& value) ->
1800 typename std::
1801 enable_if<!maybe_multi && !maybe_map, std::pair<iterator, bool>>::type
1802{
1803 typename cont_type::insert_commit_data d;
1804 auto const result(m_cont.insert_check(
1805 extract(value), std::cref(m_config.key_compare()), d));
1806 if (result.second)
1807 {
1808 element* const p(new_element(std::move(value)));
1809 auto const iter(m_cont.insert_commit(*p, d));
1810 chronological.list.push_back(*p);
1811 return std::make_pair(iterator(iter), true);
1812 }
1813 return std::make_pair(iterator(result.first), false);
1814}
1815
1816// multiset
1817template <
1818 bool IsMulti,
1819 bool IsMap,
1820 class Key,
1821 class T,
1822 class Clock,
1823 class Compare,
1824 class Allocator>
1825template <bool maybe_multi, bool maybe_map>
1826auto
1828 insert(value_type&& value) ->
1830{
1831 auto const before(
1832 m_cont.upper_bound(extract(value), std::cref(m_config.key_compare())));
1833 element* const p(new_element(std::move(value)));
1834 chronological.list.push_back(*p);
1835 auto const iter(m_cont.insert_before(before, *p));
1836 return iterator(iter);
1837}
1838
1839//---
1840
1841// map, set
1842template <
1843 bool IsMulti,
1844 bool IsMap,
1845 class Key,
1846 class T,
1847 class Clock,
1848 class Compare,
1849 class Allocator>
1850template <bool maybe_multi>
1851auto
1853 insert(const_iterator hint, value_type const& value) ->
1855{
1856 typename cont_type::insert_commit_data d;
1857 auto const result(m_cont.insert_check(
1858 hint.iterator(), extract(value), std::cref(m_config.key_compare()), d));
1859 if (result.second)
1860 {
1861 element* const p(new_element(value));
1862 auto const iter(m_cont.insert_commit(*p, d));
1863 chronological.list.push_back(*p);
1864 return iterator(iter);
1865 }
1866 return iterator(result.first);
1867}
1868
1869// map, set
1870template <
1871 bool IsMulti,
1872 bool IsMap,
1873 class Key,
1874 class T,
1875 class Clock,
1876 class Compare,
1877 class Allocator>
1878template <bool maybe_multi>
1879auto
1881 insert(const_iterator hint, value_type&& value) ->
1883{
1884 typename cont_type::insert_commit_data d;
1885 auto const result(m_cont.insert_check(
1886 hint.iterator(), extract(value), std::cref(m_config.key_compare()), d));
1887 if (result.second)
1888 {
1889 element* const p(new_element(std::move(value)));
1890 auto const iter(m_cont.insert_commit(*p, d));
1891 chronological.list.push_back(*p);
1892 return iterator(iter);
1893 }
1894 return iterator(result.first);
1895}
1896
1897// map, set
1898template <
1899 bool IsMulti,
1900 bool IsMap,
1901 class Key,
1902 class T,
1903 class Clock,
1904 class Compare,
1905 class Allocator>
1906template <bool maybe_multi, class... Args>
1907auto
1909 emplace(Args&&... args) ->
1911{
1912 // VFALCO NOTE Its unfortunate that we need to
1913 // construct element here
1914 element* const p(new_element(std::forward<Args>(args)...));
1915 typename cont_type::insert_commit_data d;
1916 auto const result(m_cont.insert_check(
1917 extract(p->value), std::cref(m_config.key_compare()), d));
1918 if (result.second)
1919 {
1920 auto const iter(m_cont.insert_commit(*p, d));
1921 chronological.list.push_back(*p);
1922 return std::make_pair(iterator(iter), true);
1923 }
1924 delete_element(p);
1925 return std::make_pair(iterator(result.first), false);
1926}
1927
1928// multiset, multimap
1929template <
1930 bool IsMulti,
1931 bool IsMap,
1932 class Key,
1933 class T,
1934 class Clock,
1935 class Compare,
1936 class Allocator>
1937template <bool maybe_multi, class... Args>
1938auto
1940 emplace(Args&&... args) ->
1942{
1943 element* const p(new_element(std::forward<Args>(args)...));
1944 auto const before(m_cont.upper_bound(
1945 extract(p->value), std::cref(m_config.key_compare())));
1946 chronological.list.push_back(*p);
1947 auto const iter(m_cont.insert_before(before, *p));
1948 return iterator(iter);
1949}
1950
1951// map, set
1952template <
1953 bool IsMulti,
1954 bool IsMap,
1955 class Key,
1956 class T,
1957 class Clock,
1958 class Compare,
1959 class Allocator>
1960template <bool maybe_multi, class... Args>
1961auto
1963 emplace_hint(const_iterator hint, Args&&... args) ->
1965{
1966 // VFALCO NOTE Its unfortunate that we need to
1967 // construct element here
1968 element* const p(new_element(std::forward<Args>(args)...));
1969 typename cont_type::insert_commit_data d;
1970 auto const result(m_cont.insert_check(
1971 hint.iterator(),
1972 extract(p->value),
1973 std::cref(m_config.key_compare()),
1974 d));
1975 if (result.second)
1976 {
1977 auto const iter(m_cont.insert_commit(*p, d));
1978 chronological.list.push_back(*p);
1979 return std::make_pair(iterator(iter), true);
1980 }
1981 delete_element(p);
1982 return std::make_pair(iterator(result.first), false);
1983}
1984
1985template <
1986 bool IsMulti,
1987 bool IsMap,
1988 class Key,
1989 class T,
1990 class Clock,
1991 class Compare,
1992 class Allocator>
1993template <bool is_const, class Iterator, class>
1997{
1998 unlink_and_delete_element(&*((pos++).iterator()));
2000 pos.iterator());
2001}
2002
2003template <
2004 bool IsMulti,
2005 bool IsMap,
2006 class Key,
2007 class T,
2008 class Clock,
2009 class Compare,
2010 class Allocator>
2011template <bool is_const, class Iterator, class>
2014 erase(
2017{
2018 for (; first != last;)
2019 unlink_and_delete_element(&*((first++).iterator()));
2020
2022 first.iterator());
2023}
2024
2025template <
2026 bool IsMulti,
2027 bool IsMap,
2028 class Key,
2029 class T,
2030 class Clock,
2031 class Compare,
2032 class Allocator>
2033template <class K>
2034auto
2036 erase(K const& k) -> size_type
2037{
2038 auto iter(m_cont.find(k, std::cref(m_config.key_compare())));
2039 if (iter == m_cont.end())
2040 return 0;
2041 size_type n(0);
2042 for (;;)
2043 {
2044 auto p(&*iter++);
2045 bool const done(m_config(*p, extract(iter->value)));
2046 unlink_and_delete_element(p);
2047 ++n;
2048 if (done)
2049 break;
2050 }
2051 return n;
2052}
2053
2054template <
2055 bool IsMulti,
2056 bool IsMap,
2057 class Key,
2058 class T,
2059 class Clock,
2060 class Compare,
2061 class Allocator>
2062void
2064 aged_ordered_container& other) noexcept
2065{
2066 swap_data(other);
2067 std::swap(chronological, other.chronological);
2068 std::swap(m_cont, other.m_cont);
2069}
2070
2071//------------------------------------------------------------------------------
2072
2073template <
2074 bool IsMulti,
2075 bool IsMap,
2076 class Key,
2077 class T,
2078 class Clock,
2079 class Compare,
2080 class Allocator>
2081template <class K>
2082auto
2084 touch(K const& k) -> size_type
2085{
2086 auto const now(clock().now());
2087 size_type n(0);
2088 auto const range(equal_range(k));
2089 for (auto iter : range)
2090 {
2091 touch(iter, now);
2092 ++n;
2093 }
2094 return n;
2095}
2096
2097//------------------------------------------------------------------------------
2098
2099template <
2100 bool IsMulti,
2101 bool IsMap,
2102 class Key,
2103 class T,
2104 class Clock,
2105 class Compare,
2106 class Allocator>
2107template <
2108 bool OtherIsMulti,
2109 bool OtherIsMap,
2110 class OtherT,
2111 class OtherDuration,
2112 class OtherAllocator>
2113bool
2116 OtherIsMulti,
2117 OtherIsMap,
2118 Key,
2119 OtherT,
2120 OtherDuration,
2121 Compare,
2122 OtherAllocator> const& other) const
2123{
2124 using Other = aged_ordered_container<
2125 OtherIsMulti,
2126 OtherIsMap,
2127 Key,
2128 OtherT,
2129 OtherDuration,
2130 Compare,
2131 OtherAllocator>;
2132 if (size() != other.size())
2133 return false;
2135 return std::equal(
2136 cbegin(),
2137 cend(),
2138 other.cbegin(),
2139 other.cend(),
2140 [&eq, &other](
2141 value_type const& lhs, typename Other::value_type const& rhs) {
2142 return eq(extract(lhs), other.extract(rhs));
2143 });
2144}
2145
2146//------------------------------------------------------------------------------
2147
2148template <
2149 bool IsMulti,
2150 bool IsMap,
2151 class Key,
2152 class T,
2153 class Clock,
2154 class Compare,
2155 class Allocator>
2156template <bool is_const, class Iterator, class>
2157void
2159 touch(
2161 typename clock_type::time_point const& now)
2162{
2163 auto& e(*pos.iterator());
2164 e.when = now;
2165 chronological.list.erase(chronological.list.iterator_to(e));
2166 chronological.list.push_back(e);
2167}
2168
2169template <
2170 bool IsMulti,
2171 bool IsMap,
2172 class Key,
2173 class T,
2174 class Clock,
2175 class Compare,
2176 class Allocator>
2177template <bool maybe_propagate>
2180 swap_data(aged_ordered_container& other) noexcept
2181{
2182 std::swap(m_config.key_compare(), other.m_config.key_compare());
2183 std::swap(m_config.alloc(), other.m_config.alloc());
2184 std::swap(m_config.clock, other.m_config.clock);
2185}
2186
2187template <
2188 bool IsMulti,
2189 bool IsMap,
2190 class Key,
2191 class T,
2192 class Clock,
2193 class Compare,
2194 class Allocator>
2195template <bool maybe_propagate>
2198 swap_data(aged_ordered_container& other) noexcept
2199{
2200 std::swap(m_config.key_compare(), other.m_config.key_compare());
2201 std::swap(m_config.clock, other.m_config.clock);
2202}
2203
2204} // namespace detail
2205
2206//------------------------------------------------------------------------------
2207
2208template <
2209 bool IsMulti,
2210 bool IsMap,
2211 class Key,
2212 class T,
2213 class Clock,
2214 class Compare,
2215 class Allocator>
2217 IsMulti,
2218 IsMap,
2219 Key,
2220 T,
2221 Clock,
2222 Compare,
2223 Allocator>> : std::true_type
2224{
2225 explicit is_aged_container() = default;
2226};
2227
2228// Free functions
2229
2230template <
2231 bool IsMulti,
2232 bool IsMap,
2233 class Key,
2234 class T,
2235 class Clock,
2236 class Compare,
2237 class Allocator>
2238void
2241 IsMulti,
2242 IsMap,
2243 Key,
2244 T,
2245 Clock,
2246 Compare,
2247 Allocator>& lhs,
2249 IsMulti,
2250 IsMap,
2251 Key,
2252 T,
2253 Clock,
2254 Compare,
2255 Allocator>& rhs) noexcept
2256{
2257 lhs.swap(rhs);
2258}
2259
2261template <
2262 bool IsMulti,
2263 bool IsMap,
2264 class Key,
2265 class T,
2266 class Clock,
2267 class Compare,
2268 class Allocator,
2269 class Rep,
2270 class Period>
2274 IsMulti,
2275 IsMap,
2276 Key,
2277 T,
2278 Clock,
2279 Compare,
2280 Allocator>& c,
2282{
2283 std::size_t n(0);
2284 auto const expired(c.clock().now() - age);
2285 for (auto iter(c.chronological.cbegin());
2286 iter != c.chronological.cend() && iter.when() <= expired;)
2287 {
2288 iter = c.erase(iter);
2289 ++n;
2290 }
2291 return n;
2292}
2293
2294} // namespace beast
2295
2296#endif
T addressof(T... args)
T allocate(T... args)
Abstract interface to a clock.
typename Clock::time_point time_point
typename Clock::duration duration
bool operator()(element const &e, Key const &k) const
bool operator()(element const &x, element const &y) const
bool operator()(Key const &k, element const &e) const
const_iterator iterator_to(value_type const &value) const
beast::detail::aged_container_iterator<!IsMap, typename list_type::iterator > iterator
beast::detail::aged_container_iterator< !IsMap, typename list_type::reverse_iterator > reverse_iterator
beast::detail::aged_container_iterator< true, typename list_type::reverse_iterator > const_reverse_iterator
beast::detail::aged_container_iterator< true, typename list_type::iterator > const_iterator
config_t(config_t const &other, Allocator const &alloc)
config_t(clock_type &clock_, Allocator const &alloc_)
config_t(clock_type &clock_, Compare const &comp, Allocator const &alloc_)
config_t(config_t &&other, Allocator const &alloc)
config_t(clock_type &clock_, Compare const &comp)
bool operator()(value_type const &lhs, value_type const &rhs) const
Associative container where each element is also indexed by time.
std::conditional< IsMap, T, void * >::type & operator[](Key const &key)
aged_ordered_container(aged_ordered_container &&other, Allocator const &alloc)
std::enable_if< maybe_multi, iterator >::type emplace_hint(const_iterator, Args &&... args)
typename std::allocator_traits< Allocator >::const_pointer const_pointer
aged_ordered_container(aged_ordered_container &&other)
auto insert(const_iterator hint, value_type const &value) -> typename std::enable_if<!maybe_multi, iterator >::type
std::conditional< IsMap, T, void * >::type & at(K const &k)
typename std::allocator_traits< Allocator >::pointer pointer
aged_ordered_container & operator=(std::initializer_list< value_type > init)
auto insert(value_type const &value) -> typename std::enable_if< maybe_multi, iterator >::type
const_iterator find(K const &k) const
typename std::conditional< IsMap, pair_value_compare, Compare >::type value_compare
void swap(aged_ordered_container &other) noexcept
beast::detail::aged_container_iterator< false, Iterator > erase(beast::detail::aged_container_iterator< is_const, Iterator > pos)
const_reverse_iterator rbegin() const
beast::detail::aged_container_iterator< true, typename cont_type::reverse_iterator > const_reverse_iterator
aged_ordered_container(clock_type &clock, Compare const &comp)
aged_ordered_container(aged_ordered_container const &other, Allocator const &alloc)
aged_ordered_container(std::initializer_list< value_type > init, clock_type &clock, Compare const &comp, Allocator const &alloc)
aged_ordered_container(std::initializer_list< value_type > init, clock_type &clock, Allocator const &alloc)
bool operator<=(aged_ordered_container< OtherIsMulti, OtherIsMap, Key, OtherT, OtherDuration, Compare, OtherAllocator > const &other) const
aged_ordered_container(std::initializer_list< value_type > init, clock_type &clock)
aged_ordered_container & operator=(aged_ordered_container const &other)
aged_ordered_container(InputIt first, InputIt last, clock_type &clock, Allocator const &alloc)
bool operator>(aged_ordered_container< OtherIsMulti, OtherIsMap, Key, OtherT, OtherDuration, Compare, OtherAllocator > const &other) const
auto insert(value_type &&value) -> typename std::enable_if< !maybe_multi &&!maybe_map, std::pair< iterator, bool > >::type
void insert(InputIt first, InputIt last)
const_reverse_iterator crend() const
std::pair< iterator, iterator > equal_range(K const &k)
bool operator==(aged_ordered_container< OtherIsMulti, OtherIsMap, Key, OtherT, OtherDuration, Compare, OtherAllocator > const &other) const
aged_ordered_container(clock_type &clock, Compare const &comp, Allocator const &alloc)
std::enable_if< maybe_map &&std::is_constructible< value_type, P && >::value, typenamestd::conditional< IsMulti, iterator, std::pair< iterator, bool > >::type >::type insert(P &&value)
void insert(std::initializer_list< value_type > init)
aged_ordered_container(aged_ordered_container const &other)
aged_ordered_container(std::initializer_list< value_type > init, clock_type &clock, Compare const &comp)
std::enable_if< maybe_map &&std::is_constructible< value_type, P && >::value, typenamestd::conditional< IsMulti, iterator, std::pair< iterator, bool > >::type >::type insert(const_iterator hint, P &&value)
const_iterator lower_bound(K const &k) const
typename std::conditional< IsMulti, typename boost::intrusive::make_multiset< element, boost::intrusive::constant_time_size< true >, boost::intrusive::compare< KeyValueCompare > >::type, typename boost::intrusive::make_set< element, boost::intrusive::constant_time_size< true >, boost::intrusive::compare< KeyValueCompare > >::type >::type cont_type
const_iterator upper_bound(K const &k) const
bool operator!=(aged_ordered_container< OtherIsMulti, OtherIsMap, Key, OtherT, OtherDuration, Compare, OtherAllocator > const &other) const
const_iterator iterator_to(value_type const &value) const
std::enable_if< maybe_propagate >::type swap_data(aged_ordered_container &other) noexcept
typename std::allocator_traits< Allocator >::template rebind_alloc< element > ElementAllocator
auto insert(value_type &&value) -> typename std::enable_if< maybe_multi &&!maybe_map, iterator >::type
auto insert(value_type const &value) -> typename std::enable_if<!maybe_multi, std::pair< iterator, bool > >::type
beast::detail::aged_container_iterator< false, Iterator > erase(beast::detail::aged_container_iterator< is_const, Iterator > first, beast::detail::aged_container_iterator< is_const, Iterator > last)
std::enable_if< maybe_multi, iterator >::type insert(const_iterator, value_type const &value)
auto emplace(Args &&... args) -> typename std::enable_if< maybe_multi, iterator >::type
bool operator<(aged_ordered_container< OtherIsMulti, OtherIsMap, Key, OtherT, OtherDuration, Compare, OtherAllocator > const &other) const
typename clock_type::duration duration
auto insert(const_iterator hint, value_type &&value) -> typename std::enable_if<!maybe_multi, iterator >::type
void touch(beast::detail::aged_container_iterator< is_const, Iterator > pos, typename clock_type::time_point const &now)
beast::detail::aged_container_iterator<!IsMap, typename cont_type::iterator > iterator
beast::detail::aged_container_iterator< true, typename cont_type::iterator > const_iterator
void touch(beast::detail::aged_container_iterator< is_const, Iterator > pos)
class beast::detail::aged_ordered_container::chronological_t chronological
aged_ordered_container(clock_type &clock, Allocator const &alloc)
aged_ordered_container(InputIt first, InputIt last, clock_type &clock, Compare const &comp)
aged_ordered_container(InputIt first, InputIt last, clock_type &clock, Compare const &comp, Allocator const &alloc)
aged_ordered_container & operator=(aged_ordered_container &&other)
std::enable_if< maybe_multi, iterator >::type insert(const_iterator, value_type &&value)
bool operator>=(aged_ordered_container< OtherIsMulti, OtherIsMap, Key, OtherT, OtherDuration, Compare, OtherAllocator > const &other) const
typename boost::intrusive::make_list< element, boost::intrusive::constant_time_size< false > >::type list_type
const_reverse_iterator crbegin() const
auto emplace_hint(const_iterator hint, Args &&... args) -> typename std::enable_if<!maybe_multi, std::pair< iterator, bool > >::type
std::conditional< IsMap, T, void * >::type const & at(K const &k) const
aged_ordered_container(InputIt first, InputIt last, clock_type &clock)
typename std::conditional< IsMap, std::pair< Key const, T >, Key >::type value_type
auto emplace(Args &&... args) -> typename std::enable_if<!maybe_multi, std::pair< iterator, bool > >::type
std::conditional< IsMap, T, void * >::type & operator[](Key &&key)
beast::detail::aged_container_iterator<!IsMap, typename cont_type::reverse_iterator > reverse_iterator
static Key const & extract(value_type const &value)
std::pair< const_iterator, const_iterator > equal_range(K const &k) const
typename clock_type::time_point time_point
T construct(T... args)
T deallocate(T... args)
T destroy(T... args)
T equal(T... args)
T forward_as_tuple(T... args)
T lexicographical_compare(T... args)
T make_pair(T... args)
int compare(SemanticVersion const &lhs, SemanticVersion const &rhs)
Compare two SemanticVersions against each other.
std::enable_if< is_aged_container< AgedContainer >::value, std::size_t >::type expire(AgedContainer &c, std::chrono::duration< Rep, Period > const &age)
Expire aged container items past the specified age.
void swap(beast::detail::aged_ordered_container< IsMulti, IsMap, Key, T, Clock, Compare, Allocator > &lhs, beast::detail::aged_ordered_container< IsMulti, IsMap, Key, T, Clock, Compare, Allocator > &rhs) noexcept
STL namespace.
T cref(T... args)
T release(T... args)
typename aged_ordered_container::time_point time_point
typename aged_ordered_container::value_type value_type
element(time_point const &when_, value_type const &value_)
element(time_point const &when_, value_type &&value_)
element(time_point const &when_, Args &&... args)
T swap(T... args)