rippled
Loading...
Searching...
No Matches
aged_ordered_container.h
1#ifndef BEAST_CONTAINER_DETAIL_AGED_ORDERED_CONTAINER_H_INCLUDED
2#define BEAST_CONTAINER_DETAIL_AGED_ORDERED_CONTAINER_H_INCLUDED
3
4#include <xrpl/beast/clock/abstract_clock.h>
5#include <xrpl/beast/container/aged_container.h>
6#include <xrpl/beast/container/detail/aged_associative_container.h>
7#include <xrpl/beast/container/detail/aged_container_iterator.h>
8#include <xrpl/beast/container/detail/empty_base_optimization.h>
9
10#include <boost/intrusive/list.hpp>
11#include <boost/intrusive/set.hpp>
12#include <boost/version.hpp>
13
14#include <algorithm>
15#include <functional>
16#include <initializer_list>
17#include <memory>
18#include <type_traits>
19#include <utility>
20
21namespace beast {
22namespace detail {
23
24// Traits templates used to discern reverse_iterators, which are disallowed
25// for mutating operations.
26template <class It>
31
32template <class It>
33struct is_boost_reverse_iterator<boost::intrusive::reverse_iterator<It>>
35{
36 explicit is_boost_reverse_iterator() = default;
37};
38
55template <
56 bool IsMulti,
57 bool IsMap,
58 class Key,
59 class T,
60 class Clock = std::chrono::steady_clock,
61 class Compare = std::less<Key>,
62 class Allocator = std::allocator<
65{
66public:
70 using key_type = Key;
71 using mapped_type = T;
72 using value_type =
76
77 // Introspection (for unit tests)
81
82private:
83 static Key const&
84 extract(value_type const& value)
85 {
87 }
88
89 // VFALCO TODO hoist to remove template argument dependencies
90 struct element
91 : boost::intrusive::set_base_hook<
92 boost::intrusive::link_mode<boost::intrusive::normal_link>>,
93 boost::intrusive::list_base_hook<
94 boost::intrusive::link_mode<boost::intrusive::normal_link>>
95 {
96 // Stash types here so the iterator doesn't
97 // need to see the container declaration.
98 struct stashed
99 {
100 explicit stashed() = default;
101
104 };
105
106 element(time_point const& when_, value_type const& value_)
107 : value(value_), when(when_)
108 {
109 }
110
111 element(time_point const& when_, value_type&& value_)
112 : value(std::move(value_)), when(when_)
113 {
114 }
115
116 template <
117 class... Args,
118 class = typename std::enable_if<
120 element(time_point const& when_, Args&&... args)
121 : value(std::forward<Args>(args)...), when(when_)
122 {
123 }
124
127 };
128
129 // VFALCO TODO This should only be enabled for maps.
130 class pair_value_compare : public Compare
131 {
132 public:
135 using result_type = bool;
136
137 bool
138 operator()(value_type const& lhs, value_type const& rhs) const
139 {
140 return Compare::operator()(lhs.first, rhs.first);
141 }
142
144 {
145 }
146
147 pair_value_compare(pair_value_compare const& other) : Compare(other)
148 {
149 }
150
151 private:
153
154 pair_value_compare(Compare const& compare) : Compare(compare)
155 {
156 }
157 };
158
159 // Compares value_type against element, used in insert_check
160 // VFALCO TODO hoist to remove template argument dependencies
161 class KeyValueCompare : public Compare
162 {
163 public:
164 using first_argument = Key;
166 using result_type = bool;
167
168 KeyValueCompare() = default;
169
170 KeyValueCompare(Compare const& compare) : Compare(compare)
171 {
172 }
173
174 bool
175 operator()(Key const& k, element const& e) const
176 {
177 return Compare::operator()(k, extract(e.value));
178 }
179
180 bool
181 operator()(element const& e, Key const& k) const
182 {
183 return Compare::operator()(extract(e.value), k);
184 }
185
186 bool
187 operator()(element const& x, element const& y) const
188 {
189 return Compare::operator()(extract(x.value), extract(y.value));
190 }
191
192 Compare&
194 {
195 return *this;
196 }
197
198 Compare const&
199 compare() const
200 {
201 return *this;
202 }
203 };
204
205 using list_type = typename boost::intrusive::
206 make_list<element, boost::intrusive::constant_time_size<false>>::type;
207
208 using cont_type = typename std::conditional<
209 IsMulti,
210 typename boost::intrusive::make_multiset<
211 element,
212 boost::intrusive::constant_time_size<true>,
213 boost::intrusive::compare<KeyValueCompare>>::type,
214 typename boost::intrusive::make_set<
215 element,
216 boost::intrusive::constant_time_size<true>,
217 boost::intrusive::compare<KeyValueCompare>>::type>::type;
218
220 Allocator>::template rebind_alloc<element>;
221
223
225 : private KeyValueCompare,
226 public beast::detail::empty_base_optimization<ElementAllocator>
227 {
228 public:
229 explicit config_t(clock_type& clock_) : clock(clock_)
230 {
231 }
232
233 config_t(clock_type& clock_, Compare const& comp)
234 : KeyValueCompare(comp), clock(clock_)
235 {
236 }
237
238 config_t(clock_type& clock_, Allocator const& alloc_)
240 , clock(clock_)
241 {
242 }
243
245 clock_type& clock_,
246 Compare const& comp,
247 Allocator const& alloc_)
248 : KeyValueCompare(comp)
250 , clock(clock_)
251 {
252 }
253
254 config_t(config_t const& other)
257 ElementAllocatorTraits::select_on_container_copy_construction(
258 other.alloc()))
259 , clock(other.clock)
260 {
261 }
262
263 config_t(config_t const& other, Allocator const& alloc)
266 , clock(other.clock)
267 {
268 }
269
271 : KeyValueCompare(std::move(other.key_compare()))
273 std::move(other))
274 , clock(other.clock)
275 {
276 }
277
278 config_t(config_t&& other, Allocator const& alloc)
279 : KeyValueCompare(std::move(other.key_compare()))
281 , clock(other.clock)
282 {
283 }
284
285 config_t&
286 operator=(config_t const& other)
287 {
288 if (this != &other)
289 {
290 compare() = other.compare();
291 alloc() = other.alloc();
292 clock = other.clock;
293 }
294 return *this;
295 }
296
297 config_t&
299 {
300 compare() = std::move(other.compare());
301 alloc() = std::move(other.alloc());
302 clock = other.clock;
303 return *this;
304 }
305
306 Compare&
308 {
310 }
311
312 Compare const&
313 compare() const
314 {
316 }
317
320 {
321 return *this;
322 }
323
324 KeyValueCompare const&
326 {
327 return *this;
328 }
329
336
337 ElementAllocator const&
343
345 };
346
347 template <class... Args>
348 element*
349 new_element(Args&&... args)
350 {
351 struct Deleter
352 {
354 Deleter(ElementAllocator& a) : a_(a)
355 {
356 }
357
358 void
359 operator()(element* p)
360 {
361 ElementAllocatorTraits::deallocate(a_.get(), p, 1);
362 }
363 };
364
367 Deleter(m_config.alloc()));
369 m_config.alloc(),
370 p.get(),
371 clock().now(),
372 std::forward<Args>(args)...);
373 return p.release();
374 }
375
376 void
383
384 void
386 {
387 chronological.list.erase(chronological.list.iterator_to(*p));
388 m_cont.erase(m_cont.iterator_to(*p));
390 }
391
392public:
393 using key_compare = Compare;
396 using allocator_type = Allocator;
402
403 // A set iterator (IsMap==false) is always const
404 // because the elements of a set are immutable.
405 using iterator = beast::detail::
406 aged_container_iterator<!IsMap, typename cont_type::iterator>;
407 using const_iterator = beast::detail::
408 aged_container_iterator<true, typename cont_type::iterator>;
409 using reverse_iterator = beast::detail::
410 aged_container_iterator<!IsMap, typename cont_type::reverse_iterator>;
411 using const_reverse_iterator = beast::detail::
412 aged_container_iterator<true, typename cont_type::reverse_iterator>;
413
414 //--------------------------------------------------------------------------
415 //
416 // Chronological ordered iterators
417 //
418 // "Memberspace"
419 // http://accu.org/index.php/journals/1527
420 //
421 //--------------------------------------------------------------------------
422
424 {
425 public:
426 // A set iterator (IsMap==false) is always const
427 // because the elements of a set are immutable.
428 using iterator = beast::detail::
429 aged_container_iterator<!IsMap, typename list_type::iterator>;
430 using const_iterator = beast::detail::
431 aged_container_iterator<true, typename list_type::iterator>;
433 !IsMap,
434 typename list_type::reverse_iterator>;
435 using const_reverse_iterator = beast::detail::
436 aged_container_iterator<true, typename list_type::reverse_iterator>;
437
440 {
441 return iterator(list.begin());
442 }
443
445 begin() const
446 {
447 return const_iterator(list.begin());
448 }
449
451 cbegin() const
452 {
453 return const_iterator(list.begin());
454 }
455
458 {
459 return iterator(list.end());
460 }
461
463 end() const
464 {
465 return const_iterator(list.end());
466 }
467
469 cend() const
470 {
471 return const_iterator(list.end());
472 }
473
476 {
477 return reverse_iterator(list.rbegin());
478 }
479
481 rbegin() const
482 {
483 return const_reverse_iterator(list.rbegin());
484 }
485
487 crbegin() const
488 {
489 return const_reverse_iterator(list.rbegin());
490 }
491
494 {
495 return reverse_iterator(list.rend());
496 }
497
499 rend() const
500 {
501 return const_reverse_iterator(list.rend());
502 }
503
505 crend() const
506 {
507 return const_reverse_iterator(list.rend());
508 }
509
512 {
513 static_assert(
515 "must be standard layout");
516 return list.iterator_to(*reinterpret_cast<element*>(
517 reinterpret_cast<uint8_t*>(&value) -
518 ((std::size_t)std::addressof(((element*)0)->member))));
519 }
520
522 iterator_to(value_type const& value) const
523 {
524 static_assert(
526 "must be standard layout");
527 return list.iterator_to(*reinterpret_cast<element const*>(
528 reinterpret_cast<uint8_t const*>(&value) -
529 ((std::size_t)std::addressof(((element*)0)->member))));
530 }
531
532 private:
534 {
535 }
536
539
543
544 //--------------------------------------------------------------------------
545 //
546 // Construction
547 //
548 //--------------------------------------------------------------------------
549
551
553
555
556 aged_ordered_container(clock_type& clock, Allocator const& alloc);
557
560 Compare const& comp,
561 Allocator const& alloc);
562
563 template <class InputIt>
564 aged_ordered_container(InputIt first, InputIt last, clock_type& clock);
565
566 template <class InputIt>
568 InputIt first,
569 InputIt last,
571 Compare const& comp);
572
573 template <class InputIt>
575 InputIt first,
576 InputIt last,
578 Allocator const& alloc);
579
580 template <class InputIt>
582 InputIt first,
583 InputIt last,
585 Compare const& comp,
586 Allocator const& alloc);
587
589
591 aged_ordered_container const& other,
592 Allocator const& alloc);
593
595
598 Allocator const& alloc);
599
603
607 Compare const& comp);
608
612 Allocator const& alloc);
613
617 Compare const& comp,
618 Allocator const& alloc);
619
621
624
627
630
633 {
634 return m_config.alloc();
635 }
636
639 {
640 return m_config.clock;
641 }
642
643 clock_type const&
644 clock() const
645 {
646 return m_config.clock;
647 }
648
649 //--------------------------------------------------------------------------
650 //
651 // Element access (maps)
652 //
653 //--------------------------------------------------------------------------
654
655 template <
656 class K,
657 bool maybe_multi = IsMulti,
658 bool maybe_map = IsMap,
661 at(K const& k);
662
663 template <
664 class K,
665 bool maybe_multi = IsMulti,
666 bool maybe_map = IsMap,
669 at(K const& k) const;
670
671 template <
672 bool maybe_multi = IsMulti,
673 bool maybe_map = IsMap,
676 operator[](Key const& key);
677
678 template <
679 bool maybe_multi = IsMulti,
680 bool maybe_map = IsMap,
683 operator[](Key&& key);
684
685 //--------------------------------------------------------------------------
686 //
687 // Iterators
688 //
689 //--------------------------------------------------------------------------
690
693 {
694 return iterator(m_cont.begin());
695 }
696
698 begin() const
699 {
700 return const_iterator(m_cont.begin());
701 }
702
704 cbegin() const
705 {
706 return const_iterator(m_cont.begin());
707 }
708
711 {
712 return iterator(m_cont.end());
713 }
714
716 end() const
717 {
718 return const_iterator(m_cont.end());
719 }
720
722 cend() const
723 {
724 return const_iterator(m_cont.end());
725 }
726
729 {
730 return reverse_iterator(m_cont.rbegin());
731 }
732
734 rbegin() const
735 {
736 return const_reverse_iterator(m_cont.rbegin());
737 }
738
740 crbegin() const
741 {
742 return const_reverse_iterator(m_cont.rbegin());
743 }
744
747 {
748 return reverse_iterator(m_cont.rend());
749 }
750
752 rend() const
753 {
754 return const_reverse_iterator(m_cont.rend());
755 }
756
758 crend() const
759 {
760 return const_reverse_iterator(m_cont.rend());
761 }
762
765 {
766 static_assert(
767 std::is_standard_layout<element>::value, "must be standard layout");
768 return m_cont.iterator_to(*reinterpret_cast<element*>(
769 reinterpret_cast<uint8_t*>(&value) -
770 ((std::size_t)std::addressof(((element*)0)->member))));
771 }
772
774 iterator_to(value_type const& value) const
775 {
776 static_assert(
777 std::is_standard_layout<element>::value, "must be standard layout");
778 return m_cont.iterator_to(*reinterpret_cast<element const*>(
779 reinterpret_cast<uint8_t const*>(&value) -
780 ((std::size_t)std::addressof(((element*)0)->member))));
781 }
782
783 //--------------------------------------------------------------------------
784 //
785 // Capacity
786 //
787 //--------------------------------------------------------------------------
788
789 bool
790 empty() const noexcept
791 {
792 return m_cont.empty();
793 }
794
796 size() const noexcept
797 {
798 return m_cont.size();
799 }
800
802 max_size() const noexcept
803 {
804 return m_config.max_size();
805 }
806
807 //--------------------------------------------------------------------------
808 //
809 // Modifiers
810 //
811 //--------------------------------------------------------------------------
812
813 void
815
816 // map, set
817 template <bool maybe_multi = IsMulti>
818 auto
819 insert(value_type const& value) ->
821
822 // multimap, multiset
823 template <bool maybe_multi = IsMulti>
824 auto
825 insert(value_type const& value) ->
827
828 // set
829 template <bool maybe_multi = IsMulti, bool maybe_map = IsMap>
830 auto
831 insert(value_type&& value) -> typename std::enable_if<
832 !maybe_multi && !maybe_map,
834
835 // multiset
836 template <bool maybe_multi = IsMulti, bool maybe_map = IsMap>
837 auto
838 insert(value_type&& value) ->
840
841 //---
842
843 // map, set
844 template <bool maybe_multi = IsMulti>
845 auto
846 insert(const_iterator hint, value_type const& value) ->
848
849 // multimap, multiset
850 template <bool maybe_multi = IsMulti>
852 insert(const_iterator /*hint*/, value_type const& value)
853 {
854 // VFALCO TODO Figure out how to utilize 'hint'
855 return insert(value);
856 }
857
858 // map, set
859 template <bool maybe_multi = IsMulti>
860 auto
863
864 // multimap, multiset
865 template <bool maybe_multi = IsMulti>
868 {
869 // VFALCO TODO Figure out how to utilize 'hint'
870 return insert(std::move(value));
871 }
872
873 // map, multimap
874 template <class P, bool maybe_map = IsMap>
875 typename std::enable_if<
877 typename std::
879 type
880 insert(P&& value)
881 {
882 return emplace(std::forward<P>(value));
883 }
884
885 // map, multimap
886 template <class P, bool maybe_map = IsMap>
887 typename std::enable_if<
889 typename std::
891 type
892 insert(const_iterator hint, P&& value)
893 {
894 return emplace_hint(hint, std::forward<P>(value));
895 }
896
897 template <class InputIt>
898 void
899 insert(InputIt first, InputIt last)
900 {
901 for (; first != last; ++first)
902 insert(cend(), *first);
903 }
904
905 void
907 {
908 insert(init.begin(), init.end());
909 }
910
911 // map, set
912 template <bool maybe_multi = IsMulti, class... Args>
913 auto
914 emplace(Args&&... args) ->
916
917 // multiset, multimap
918 template <bool maybe_multi = IsMulti, class... Args>
919 auto
920 emplace(Args&&... args) ->
922
923 // map, set
924 template <bool maybe_multi = IsMulti, class... Args>
925 auto
926 emplace_hint(const_iterator hint, Args&&... args) ->
928
929 // multiset, multimap
930 template <bool maybe_multi = IsMulti, class... Args>
932 emplace_hint(const_iterator /*hint*/, Args&&... args)
933 {
934 // VFALCO TODO Figure out how to utilize 'hint'
935 return emplace<maybe_multi>(std::forward<Args>(args)...);
936 }
937
938 // enable_if prevents erase (reverse_iterator pos) from compiling
939 template <
940 bool is_const,
941 class Iterator,
945
946 // enable_if prevents erase (reverse_iterator first, reverse_iterator last)
947 // from compiling
948 template <
949 bool is_const,
950 class Iterator,
956
957 template <class K>
958 auto
959 erase(K const& k) -> size_type;
960
961 void
962 swap(aged_ordered_container& other) noexcept;
963
964 //--------------------------------------------------------------------------
965
966 // enable_if prevents touch (reverse_iterator pos) from compiling
967 template <
968 bool is_const,
969 class Iterator,
971 void
976
977 template <class K>
979 touch(K const& k);
980
981 //--------------------------------------------------------------------------
982 //
983 // Lookup
984 //
985 //--------------------------------------------------------------------------
986
987 // VFALCO TODO Respect is_transparent (c++14)
988 template <class K>
990 count(K const& k) const
991 {
992 return m_cont.count(k, std::cref(m_config.key_compare()));
993 }
994
995 // VFALCO TODO Respect is_transparent (c++14)
996 template <class K>
998 find(K const& k)
999 {
1000 return iterator(m_cont.find(k, std::cref(m_config.key_compare())));
1001 }
1002
1003 // VFALCO TODO Respect is_transparent (c++14)
1004 template <class K>
1006 find(K const& k) const
1007 {
1008 return const_iterator(
1009 m_cont.find(k, std::cref(m_config.key_compare())));
1010 }
1011
1012 // VFALCO TODO Respect is_transparent (c++14)
1013 template <class K>
1015 equal_range(K const& k)
1016 {
1017 auto const r(m_cont.equal_range(k, std::cref(m_config.key_compare())));
1018 return std::make_pair(iterator(r.first), iterator(r.second));
1019 }
1020
1021 // VFALCO TODO Respect is_transparent (c++14)
1022 template <class K>
1024 equal_range(K const& k) const
1025 {
1026 auto const r(m_cont.equal_range(k, std::cref(m_config.key_compare())));
1027 return std::make_pair(
1028 const_iterator(r.first), const_iterator(r.second));
1029 }
1030
1031 // VFALCO TODO Respect is_transparent (c++14)
1032 template <class K>
1033 iterator
1034 lower_bound(K const& k)
1035 {
1036 return iterator(
1037 m_cont.lower_bound(k, std::cref(m_config.key_compare())));
1038 }
1039
1040 // VFALCO TODO Respect is_transparent (c++14)
1041 template <class K>
1043 lower_bound(K const& k) const
1044 {
1045 return const_iterator(
1046 m_cont.lower_bound(k, std::cref(m_config.key_compare())));
1047 }
1048
1049 // VFALCO TODO Respect is_transparent (c++14)
1050 template <class K>
1051 iterator
1052 upper_bound(K const& k)
1053 {
1054 return iterator(
1055 m_cont.upper_bound(k, std::cref(m_config.key_compare())));
1056 }
1057
1058 // VFALCO TODO Respect is_transparent (c++14)
1059 template <class K>
1061 upper_bound(K const& k) const
1062 {
1063 return const_iterator(
1064 m_cont.upper_bound(k, std::cref(m_config.key_compare())));
1065 }
1066
1067 //--------------------------------------------------------------------------
1068 //
1069 // Observers
1070 //
1071 //--------------------------------------------------------------------------
1072
1074 key_comp() const
1075 {
1076 return m_config.compare();
1077 }
1078
1079 // VFALCO TODO Should this return const reference for set?
1082 {
1083 return value_compare(m_config.compare());
1084 }
1085
1086 //--------------------------------------------------------------------------
1087 //
1088 // Comparison
1089 //
1090 //--------------------------------------------------------------------------
1091
1092 // This differs from the standard in that the comparison
1093 // is only done on the key portion of the value type, ignoring
1094 // the mapped type.
1095 //
1096 template <
1097 bool OtherIsMulti,
1098 bool OtherIsMap,
1099 class OtherT,
1100 class OtherDuration,
1101 class OtherAllocator>
1102 bool
1104 OtherIsMulti,
1105 OtherIsMap,
1106 Key,
1107 OtherT,
1108 OtherDuration,
1109 Compare,
1110 OtherAllocator> const& other) const;
1111
1112 template <
1113 bool OtherIsMulti,
1114 bool OtherIsMap,
1115 class OtherT,
1116 class OtherDuration,
1117 class OtherAllocator>
1118 bool
1120 OtherIsMulti,
1121 OtherIsMap,
1122 Key,
1123 OtherT,
1124 OtherDuration,
1125 Compare,
1126 OtherAllocator> const& other) const
1127 {
1128 return !(this->operator==(other));
1129 }
1130
1131 template <
1132 bool OtherIsMulti,
1133 bool OtherIsMap,
1134 class OtherT,
1135 class OtherDuration,
1136 class OtherAllocator>
1137 bool
1139 OtherIsMulti,
1140 OtherIsMap,
1141 Key,
1142 OtherT,
1143 OtherDuration,
1144 Compare,
1145 OtherAllocator> const& other) const
1146 {
1147 value_compare const comp(value_comp());
1149 cbegin(), cend(), other.cbegin(), other.cend(), comp);
1150 }
1151
1152 template <
1153 bool OtherIsMulti,
1154 bool OtherIsMap,
1155 class OtherT,
1156 class OtherDuration,
1157 class OtherAllocator>
1158 bool
1160 OtherIsMulti,
1161 OtherIsMap,
1162 Key,
1163 OtherT,
1164 OtherDuration,
1165 Compare,
1166 OtherAllocator> const& other) const
1167 {
1168 return !(other < *this);
1169 }
1170
1171 template <
1172 bool OtherIsMulti,
1173 bool OtherIsMap,
1174 class OtherT,
1175 class OtherDuration,
1176 class OtherAllocator>
1177 bool
1179 OtherIsMulti,
1180 OtherIsMap,
1181 Key,
1182 OtherT,
1183 OtherDuration,
1184 Compare,
1185 OtherAllocator> const& other) const
1186 {
1187 return other < *this;
1188 }
1189
1190 template <
1191 bool OtherIsMulti,
1192 bool OtherIsMap,
1193 class OtherT,
1194 class OtherDuration,
1195 class OtherAllocator>
1196 bool
1198 OtherIsMulti,
1199 OtherIsMap,
1200 Key,
1201 OtherT,
1202 OtherDuration,
1203 Compare,
1204 OtherAllocator> const& other) const
1205 {
1206 return !(*this < other);
1207 }
1208
1209private:
1210 // enable_if prevents erase (reverse_iterator pos, now) from compiling
1211 template <
1212 bool is_const,
1213 class Iterator,
1215 void
1218 typename clock_type::time_point const& now);
1219
1220 template <
1221 bool maybe_propagate = std::allocator_traits<
1222 Allocator>::propagate_on_container_swap::value>
1225
1226 template <
1227 bool maybe_propagate = std::allocator_traits<
1228 Allocator>::propagate_on_container_swap::value>
1231
1232private:
1235};
1236
1237//------------------------------------------------------------------------------
1238
1239template <
1240 bool IsMulti,
1241 bool IsMap,
1242 class Key,
1243 class T,
1244 class Clock,
1245 class Compare,
1246 class Allocator>
1252
1253template <
1254 bool IsMulti,
1255 bool IsMap,
1256 class Key,
1257 class T,
1258 class Clock,
1259 class Compare,
1260 class Allocator>
1262 aged_ordered_container(clock_type& clock, Compare const& comp)
1263 : m_config(clock, comp), m_cont(comp)
1264{
1265}
1266
1267template <
1268 bool IsMulti,
1269 bool IsMap,
1270 class Key,
1271 class T,
1272 class Clock,
1273 class Compare,
1274 class Allocator>
1276 aged_ordered_container(clock_type& clock, Allocator const& alloc)
1277 : m_config(clock, alloc)
1278{
1279}
1280
1281template <
1282 bool IsMulti,
1283 bool IsMap,
1284 class Key,
1285 class T,
1286 class Clock,
1287 class Compare,
1288 class Allocator>
1291 clock_type& clock,
1292 Compare const& comp,
1293 Allocator const& alloc)
1294 : m_config(clock, comp, alloc), m_cont(comp)
1295{
1296}
1297
1298template <
1299 bool IsMulti,
1300 bool IsMap,
1301 class Key,
1302 class T,
1303 class Clock,
1304 class Compare,
1305 class Allocator>
1306template <class InputIt>
1308 aged_ordered_container(InputIt first, InputIt last, clock_type& clock)
1309 : m_config(clock)
1310{
1311 insert(first, last);
1312}
1313
1314template <
1315 bool IsMulti,
1316 bool IsMap,
1317 class Key,
1318 class T,
1319 class Clock,
1320 class Compare,
1321 class Allocator>
1322template <class InputIt>
1325 InputIt first,
1326 InputIt last,
1327 clock_type& clock,
1328 Compare const& comp)
1329 : m_config(clock, comp), m_cont(comp)
1330{
1331 insert(first, last);
1332}
1333
1334template <
1335 bool IsMulti,
1336 bool IsMap,
1337 class Key,
1338 class T,
1339 class Clock,
1340 class Compare,
1341 class Allocator>
1342template <class InputIt>
1345 InputIt first,
1346 InputIt last,
1347 clock_type& clock,
1348 Allocator const& alloc)
1349 : m_config(clock, alloc)
1350{
1351 insert(first, last);
1352}
1353
1354template <
1355 bool IsMulti,
1356 bool IsMap,
1357 class Key,
1358 class T,
1359 class Clock,
1360 class Compare,
1361 class Allocator>
1362template <class InputIt>
1365 InputIt first,
1366 InputIt last,
1367 clock_type& clock,
1368 Compare const& comp,
1369 Allocator const& alloc)
1370 : m_config(clock, comp, alloc), m_cont(comp)
1371{
1372 insert(first, last);
1373}
1374
1375template <
1376 bool IsMulti,
1377 bool IsMap,
1378 class Key,
1379 class T,
1380 class Clock,
1381 class Compare,
1382 class Allocator>
1385 : m_config(other.m_config)
1386#if BOOST_VERSION >= 108000
1387 , m_cont(other.m_cont.get_comp())
1388#else
1389 , m_cont(other.m_cont.comp())
1390#endif
1391{
1392 insert(other.cbegin(), other.cend());
1393}
1394
1395template <
1396 bool IsMulti,
1397 bool IsMap,
1398 class Key,
1399 class T,
1400 class Clock,
1401 class Compare,
1402 class Allocator>
1405 aged_ordered_container const& other,
1406 Allocator const& alloc)
1407 : m_config(other.m_config, alloc)
1408#if BOOST_VERSION >= 108000
1409 , m_cont(other.m_cont.get_comp())
1410#else
1411 , m_cont(other.m_cont.comp())
1412#endif
1413{
1414 insert(other.cbegin(), other.cend());
1415}
1416
1417template <
1418 bool IsMulti,
1419 bool IsMap,
1420 class Key,
1421 class T,
1422 class Clock,
1423 class Compare,
1424 class Allocator>
1427 : m_config(std::move(other.m_config)), m_cont(std::move(other.m_cont))
1428{
1429 chronological.list = std::move(other.chronological.list);
1430}
1431
1432template <
1433 bool IsMulti,
1434 bool IsMap,
1435 class Key,
1436 class T,
1437 class Clock,
1438 class Compare,
1439 class Allocator>
1442 aged_ordered_container&& other,
1443 Allocator const& alloc)
1444 : m_config(std::move(other.m_config), alloc)
1445#if BOOST_VERSION >= 108000
1446 , m_cont(std::move(other.m_cont.get_comp()))
1447#else
1448 , m_cont(std::move(other.m_cont.comp()))
1449#endif
1450
1451{
1452 insert(other.cbegin(), other.cend());
1453 other.clear();
1454}
1455
1456template <
1457 bool IsMulti,
1458 bool IsMap,
1459 class Key,
1460 class T,
1461 class Clock,
1462 class Compare,
1463 class Allocator>
1472
1473template <
1474 bool IsMulti,
1475 bool IsMap,
1476 class Key,
1477 class T,
1478 class Clock,
1479 class Compare,
1480 class Allocator>
1484 clock_type& clock,
1485 Compare const& comp)
1486 : m_config(clock, comp), m_cont(comp)
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 Allocator const& alloc)
1504 : m_config(clock, alloc)
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 Compare const& comp,
1522 Allocator const& alloc)
1523 : m_config(clock, comp, alloc), m_cont(comp)
1524{
1525 insert(init.begin(), init.end());
1526}
1527
1528template <
1529 bool IsMulti,
1530 bool IsMap,
1531 class Key,
1532 class T,
1533 class Clock,
1534 class Compare,
1535 class Allocator>
1541
1542template <
1543 bool IsMulti,
1544 bool IsMap,
1545 class Key,
1546 class T,
1547 class Clock,
1548 class Compare,
1549 class Allocator>
1550auto
1553{
1554 if (this != &other)
1555 {
1556 clear();
1557 this->m_config = other.m_config;
1558 insert(other.begin(), other.end());
1559 }
1560 return *this;
1561}
1562
1563template <
1564 bool IsMulti,
1565 bool IsMap,
1566 class Key,
1567 class T,
1568 class Clock,
1569 class Compare,
1570 class Allocator>
1571auto
1574{
1575 clear();
1576 this->m_config = std::move(other.m_config);
1577 insert(other.begin(), other.end());
1578 other.clear();
1579 return *this;
1580}
1581
1582template <
1583 bool IsMulti,
1584 bool IsMap,
1585 class Key,
1586 class T,
1587 class Clock,
1588 class Compare,
1589 class Allocator>
1590auto
1598
1599//------------------------------------------------------------------------------
1600
1601template <
1602 bool IsMulti,
1603 bool IsMap,
1604 class Key,
1605 class T,
1606 class Clock,
1607 class Compare,
1608 class Allocator>
1609template <class K, bool maybe_multi, bool maybe_map, class>
1612 K const& k)
1613{
1614 auto const iter(m_cont.find(k, std::cref(m_config.key_compare())));
1615 if (iter == m_cont.end())
1616 throw std::out_of_range("key not found");
1617 return iter->value.second;
1618}
1619
1620template <
1621 bool IsMulti,
1622 bool IsMap,
1623 class Key,
1624 class T,
1625 class Clock,
1626 class Compare,
1627 class Allocator>
1628template <class K, bool maybe_multi, bool maybe_map, class>
1631 K const& k) const
1632{
1633 auto const iter(m_cont.find(k, std::cref(m_config.key_compare())));
1634 if (iter == m_cont.end())
1635 throw std::out_of_range("key not found");
1636 return iter->value.second;
1637}
1638
1639template <
1640 bool IsMulti,
1641 bool IsMap,
1642 class Key,
1643 class T,
1644 class Clock,
1645 class Compare,
1646 class Allocator>
1647template <bool maybe_multi, bool maybe_map, class>
1650operator[](Key const& key)
1651{
1652 typename cont_type::insert_commit_data d;
1653 auto const result(
1654 m_cont.insert_check(key, std::cref(m_config.key_compare()), d));
1655 if (result.second)
1656 {
1657 element* const p(new_element(
1661 m_cont.insert_commit(*p, d);
1662 chronological.list.push_back(*p);
1663 return p->value.second;
1664 }
1665 return result.first->value.second;
1666}
1667
1668template <
1669 bool IsMulti,
1670 bool IsMap,
1671 class Key,
1672 class T,
1673 class Clock,
1674 class Compare,
1675 class Allocator>
1676template <bool maybe_multi, bool maybe_map, class>
1679operator[](Key&& key)
1680{
1681 typename cont_type::insert_commit_data d;
1682 auto const result(
1683 m_cont.insert_check(key, std::cref(m_config.key_compare()), d));
1684 if (result.second)
1685 {
1686 element* const p(new_element(
1688 std::forward_as_tuple(std::move(key)),
1690 m_cont.insert_commit(*p, d);
1691 chronological.list.push_back(*p);
1692 return p->value.second;
1693 }
1694 return result.first->value.second;
1695}
1696
1697//------------------------------------------------------------------------------
1698
1699template <
1700 bool IsMulti,
1701 bool IsMap,
1702 class Key,
1703 class T,
1704 class Clock,
1705 class Compare,
1706 class Allocator>
1707void
1709 clear()
1710{
1711 for (auto iter(chronological.list.begin());
1712 iter != chronological.list.end();)
1713 delete_element(&*iter++);
1714 chronological.list.clear();
1715 m_cont.clear();
1716}
1717
1718// map, set
1719template <
1720 bool IsMulti,
1721 bool IsMap,
1722 class Key,
1723 class T,
1724 class Clock,
1725 class Compare,
1726 class Allocator>
1727template <bool maybe_multi>
1728auto
1730 insert(value_type const& value) ->
1732{
1733 typename cont_type::insert_commit_data d;
1734 auto const result(m_cont.insert_check(
1735 extract(value), std::cref(m_config.key_compare()), d));
1736 if (result.second)
1737 {
1738 element* const p(new_element(value));
1739 auto const iter(m_cont.insert_commit(*p, d));
1740 chronological.list.push_back(*p);
1741 return std::make_pair(iterator(iter), true);
1742 }
1743 return std::make_pair(iterator(result.first), false);
1744}
1745
1746// multimap, multiset
1747template <
1748 bool IsMulti,
1749 bool IsMap,
1750 class Key,
1751 class T,
1752 class Clock,
1753 class Compare,
1754 class Allocator>
1755template <bool maybe_multi>
1756auto
1758 insert(value_type const& value) ->
1760{
1761 auto const before(
1762 m_cont.upper_bound(extract(value), std::cref(m_config.key_compare())));
1763 element* const p(new_element(value));
1764 chronological.list.push_back(*p);
1765 auto const iter(m_cont.insert_before(before, *p));
1766 return iterator(iter);
1767}
1768
1769// set
1770template <
1771 bool IsMulti,
1772 bool IsMap,
1773 class Key,
1774 class T,
1775 class Clock,
1776 class Compare,
1777 class Allocator>
1778template <bool maybe_multi, bool maybe_map>
1779auto
1781 insert(value_type&& value) ->
1782 typename std::
1784{
1785 typename cont_type::insert_commit_data d;
1786 auto const result(m_cont.insert_check(
1787 extract(value), std::cref(m_config.key_compare()), d));
1788 if (result.second)
1789 {
1790 element* const p(new_element(std::move(value)));
1791 auto const iter(m_cont.insert_commit(*p, d));
1792 chronological.list.push_back(*p);
1793 return std::make_pair(iterator(iter), true);
1794 }
1795 return std::make_pair(iterator(result.first), false);
1796}
1797
1798// multiset
1799template <
1800 bool IsMulti,
1801 bool IsMap,
1802 class Key,
1803 class T,
1804 class Clock,
1805 class Compare,
1806 class Allocator>
1807template <bool maybe_multi, bool maybe_map>
1808auto
1810 insert(value_type&& value) ->
1812{
1813 auto const before(
1814 m_cont.upper_bound(extract(value), std::cref(m_config.key_compare())));
1815 element* const p(new_element(std::move(value)));
1816 chronological.list.push_back(*p);
1817 auto const iter(m_cont.insert_before(before, *p));
1818 return iterator(iter);
1819}
1820
1821//---
1822
1823// map, set
1824template <
1825 bool IsMulti,
1826 bool IsMap,
1827 class Key,
1828 class T,
1829 class Clock,
1830 class Compare,
1831 class Allocator>
1832template <bool maybe_multi>
1833auto
1835 insert(const_iterator hint, value_type const& value) ->
1837{
1838 typename cont_type::insert_commit_data d;
1839 auto const result(m_cont.insert_check(
1840 hint.iterator(), extract(value), std::cref(m_config.key_compare()), d));
1841 if (result.second)
1842 {
1843 element* const p(new_element(value));
1844 auto const iter(m_cont.insert_commit(*p, d));
1845 chronological.list.push_back(*p);
1846 return iterator(iter);
1847 }
1848 return iterator(result.first);
1849}
1850
1851// map, set
1852template <
1853 bool IsMulti,
1854 bool IsMap,
1855 class Key,
1856 class T,
1857 class Clock,
1858 class Compare,
1859 class Allocator>
1860template <bool maybe_multi>
1861auto
1863 insert(const_iterator hint, value_type&& value) ->
1865{
1866 typename cont_type::insert_commit_data d;
1867 auto const result(m_cont.insert_check(
1868 hint.iterator(), extract(value), std::cref(m_config.key_compare()), d));
1869 if (result.second)
1870 {
1871 element* const p(new_element(std::move(value)));
1872 auto const iter(m_cont.insert_commit(*p, d));
1873 chronological.list.push_back(*p);
1874 return iterator(iter);
1875 }
1876 return iterator(result.first);
1877}
1878
1879// map, set
1880template <
1881 bool IsMulti,
1882 bool IsMap,
1883 class Key,
1884 class T,
1885 class Clock,
1886 class Compare,
1887 class Allocator>
1888template <bool maybe_multi, class... Args>
1889auto
1891 emplace(Args&&... args) ->
1893{
1894 // VFALCO NOTE Its unfortunate that we need to
1895 // construct element here
1896 element* const p(new_element(std::forward<Args>(args)...));
1897 typename cont_type::insert_commit_data d;
1898 auto const result(m_cont.insert_check(
1899 extract(p->value), std::cref(m_config.key_compare()), d));
1900 if (result.second)
1901 {
1902 auto const iter(m_cont.insert_commit(*p, d));
1903 chronological.list.push_back(*p);
1904 return std::make_pair(iterator(iter), true);
1905 }
1906 delete_element(p);
1907 return std::make_pair(iterator(result.first), false);
1908}
1909
1910// multiset, multimap
1911template <
1912 bool IsMulti,
1913 bool IsMap,
1914 class Key,
1915 class T,
1916 class Clock,
1917 class Compare,
1918 class Allocator>
1919template <bool maybe_multi, class... Args>
1920auto
1922 emplace(Args&&... args) ->
1924{
1925 element* const p(new_element(std::forward<Args>(args)...));
1926 auto const before(m_cont.upper_bound(
1927 extract(p->value), std::cref(m_config.key_compare())));
1928 chronological.list.push_back(*p);
1929 auto const iter(m_cont.insert_before(before, *p));
1930 return iterator(iter);
1931}
1932
1933// map, set
1934template <
1935 bool IsMulti,
1936 bool IsMap,
1937 class Key,
1938 class T,
1939 class Clock,
1940 class Compare,
1941 class Allocator>
1942template <bool maybe_multi, class... Args>
1943auto
1945 emplace_hint(const_iterator hint, Args&&... args) ->
1947{
1948 // VFALCO NOTE Its unfortunate that we need to
1949 // construct element here
1950 element* const p(new_element(std::forward<Args>(args)...));
1951 typename cont_type::insert_commit_data d;
1952 auto const result(m_cont.insert_check(
1953 hint.iterator(),
1954 extract(p->value),
1955 std::cref(m_config.key_compare()),
1956 d));
1957 if (result.second)
1958 {
1959 auto const iter(m_cont.insert_commit(*p, d));
1960 chronological.list.push_back(*p);
1961 return std::make_pair(iterator(iter), true);
1962 }
1963 delete_element(p);
1964 return std::make_pair(iterator(result.first), false);
1965}
1966
1967template <
1968 bool IsMulti,
1969 bool IsMap,
1970 class Key,
1971 class T,
1972 class Clock,
1973 class Compare,
1974 class Allocator>
1975template <bool is_const, class Iterator, class>
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>
2006
2007template <
2008 bool IsMulti,
2009 bool IsMap,
2010 class Key,
2011 class T,
2012 class Clock,
2013 class Compare,
2014 class Allocator>
2015template <class K>
2016auto
2018 erase(K const& k) -> size_type
2019{
2020 auto iter(m_cont.find(k, std::cref(m_config.key_compare())));
2021 if (iter == m_cont.end())
2022 return 0;
2023 size_type n(0);
2024 for (;;)
2025 {
2026 auto p(&*iter++);
2027 bool const done(m_config(*p, extract(iter->value)));
2028 unlink_and_delete_element(p);
2029 ++n;
2030 if (done)
2031 break;
2032 }
2033 return n;
2034}
2035
2036template <
2037 bool IsMulti,
2038 bool IsMap,
2039 class Key,
2040 class T,
2041 class Clock,
2042 class Compare,
2043 class Allocator>
2044void
2046 aged_ordered_container& other) noexcept
2047{
2048 swap_data(other);
2049 std::swap(chronological, other.chronological);
2050 std::swap(m_cont, other.m_cont);
2051}
2052
2053//------------------------------------------------------------------------------
2054
2055template <
2056 bool IsMulti,
2057 bool IsMap,
2058 class Key,
2059 class T,
2060 class Clock,
2061 class Compare,
2062 class Allocator>
2063template <class K>
2064auto
2066 touch(K const& k) -> size_type
2067{
2068 auto const now(clock().now());
2069 size_type n(0);
2070 auto const range(equal_range(k));
2071 for (auto iter : range)
2072 {
2073 touch(iter, now);
2074 ++n;
2075 }
2076 return n;
2077}
2078
2079//------------------------------------------------------------------------------
2080
2081template <
2082 bool IsMulti,
2083 bool IsMap,
2084 class Key,
2085 class T,
2086 class Clock,
2087 class Compare,
2088 class Allocator>
2089template <
2090 bool OtherIsMulti,
2091 bool OtherIsMap,
2092 class OtherT,
2093 class OtherDuration,
2094 class OtherAllocator>
2095bool
2098 OtherIsMulti,
2099 OtherIsMap,
2100 Key,
2101 OtherT,
2102 OtherDuration,
2103 Compare,
2104 OtherAllocator> const& other) const
2105{
2106 using Other = aged_ordered_container<
2107 OtherIsMulti,
2108 OtherIsMap,
2109 Key,
2110 OtherT,
2111 OtherDuration,
2112 Compare,
2113 OtherAllocator>;
2114 if (size() != other.size())
2115 return false;
2117 return std::equal(
2118 cbegin(),
2119 cend(),
2120 other.cbegin(),
2121 other.cend(),
2122 [&eq, &other](
2123 value_type const& lhs, typename Other::value_type const& rhs) {
2124 return eq(extract(lhs), other.extract(rhs));
2125 });
2126}
2127
2128//------------------------------------------------------------------------------
2129
2130template <
2131 bool IsMulti,
2132 bool IsMap,
2133 class Key,
2134 class T,
2135 class Clock,
2136 class Compare,
2137 class Allocator>
2138template <bool is_const, class Iterator, class>
2139void
2141 touch(
2143 typename clock_type::time_point const& now)
2144{
2145 auto& e(*pos.iterator());
2146 e.when = now;
2147 chronological.list.erase(chronological.list.iterator_to(e));
2148 chronological.list.push_back(e);
2149}
2150
2151template <
2152 bool IsMulti,
2153 bool IsMap,
2154 class Key,
2155 class T,
2156 class Clock,
2157 class Compare,
2158 class Allocator>
2159template <bool maybe_propagate>
2162 swap_data(aged_ordered_container& other) noexcept
2163{
2164 std::swap(m_config.key_compare(), other.m_config.key_compare());
2165 std::swap(m_config.alloc(), other.m_config.alloc());
2166 std::swap(m_config.clock, other.m_config.clock);
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.clock, other.m_config.clock);
2184}
2185
2186} // namespace detail
2187
2188//------------------------------------------------------------------------------
2189
2190template <
2191 bool IsMulti,
2192 bool IsMap,
2193 class Key,
2194 class T,
2195 class Clock,
2196 class Compare,
2197 class Allocator>
2199 IsMulti,
2200 IsMap,
2201 Key,
2202 T,
2203 Clock,
2204 Compare,
2205 Allocator>> : std::true_type
2206{
2207 explicit is_aged_container() = default;
2208};
2209
2210// Free functions
2211
2212template <
2213 bool IsMulti,
2214 bool IsMap,
2215 class Key,
2216 class T,
2217 class Clock,
2218 class Compare,
2219 class Allocator>
2220void
2223 IsMulti,
2224 IsMap,
2225 Key,
2226 T,
2227 Clock,
2228 Compare,
2229 Allocator>& lhs,
2231 IsMulti,
2232 IsMap,
2233 Key,
2234 T,
2235 Clock,
2236 Compare,
2237 Allocator>& rhs) noexcept
2238{
2239 lhs.swap(rhs);
2240}
2241
2243template <
2244 bool IsMulti,
2245 bool IsMap,
2246 class Key,
2247 class T,
2248 class Clock,
2249 class Compare,
2250 class Allocator,
2251 class Rep,
2252 class Period>
2256 IsMulti,
2257 IsMap,
2258 Key,
2259 T,
2260 Clock,
2261 Compare,
2262 Allocator>& c,
2264{
2265 std::size_t n(0);
2266 auto const expired(c.clock().now() - age);
2267 for (auto iter(c.chronological.cbegin());
2268 iter != c.chronological.cend() && iter.when() <= expired;)
2269 {
2270 iter = c.erase(iter);
2271 ++n;
2272 }
2273 return n;
2274}
2275
2276} // namespace beast
2277
2278#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)
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)
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
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
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 is_same_v
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 piecewise_construct
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)