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
29#include <boost/intrusive/list.hpp>
30#include <boost/intrusive/set.hpp>
31#include <boost/version.hpp>
32
33#include <algorithm>
34#include <functional>
35#include <initializer_list>
36#include <memory>
37#include <type_traits>
38#include <utility>
39
40namespace beast {
41namespace detail {
42
43// Traits templates used to discern reverse_iterators, which are disallowed
44// for mutating operations.
45template <class It>
50
51template <class It>
52struct is_boost_reverse_iterator<boost::intrusive::reverse_iterator<It>>
54{
55 explicit is_boost_reverse_iterator() = default;
56};
57
74template <
75 bool IsMulti,
76 bool IsMap,
77 class Key,
78 class T,
79 class Clock = std::chrono::steady_clock,
80 class Compare = std::less<Key>,
81 class Allocator = std::allocator<
84{
85public:
89 using key_type = Key;
90 using mapped_type = T;
91 using value_type =
95
96 // Introspection (for unit tests)
100
101private:
102 static Key const&
103 extract(value_type const& value)
104 {
106 }
107
108 // VFALCO TODO hoist to remove template argument dependencies
109 struct element
110 : boost::intrusive::set_base_hook<
111 boost::intrusive::link_mode<boost::intrusive::normal_link>>,
112 boost::intrusive::list_base_hook<
113 boost::intrusive::link_mode<boost::intrusive::normal_link>>
114 {
115 // Stash types here so the iterator doesn't
116 // need to see the container declaration.
117 struct stashed
118 {
119 explicit stashed() = default;
120
123 };
124
125 element(time_point const& when_, value_type const& value_)
126 : value(value_), when(when_)
127 {
128 }
129
130 element(time_point const& when_, value_type&& value_)
131 : value(std::move(value_)), when(when_)
132 {
133 }
134
135 template <
136 class... Args,
137 class = typename std::enable_if<
139 element(time_point const& when_, Args&&... args)
140 : value(std::forward<Args>(args)...), when(when_)
141 {
142 }
143
146 };
147
148 // VFALCO TODO This should only be enabled for maps.
149 class pair_value_compare : public Compare
150 {
151 public:
154 using result_type = bool;
155
156 bool
157 operator()(value_type const& lhs, value_type const& rhs) const
158 {
159 return Compare::operator()(lhs.first, rhs.first);
160 }
161
163 {
164 }
165
166 pair_value_compare(pair_value_compare const& other) : Compare(other)
167 {
168 }
169
170 private:
172
173 pair_value_compare(Compare const& compare) : Compare(compare)
174 {
175 }
176 };
177
178 // Compares value_type against element, used in insert_check
179 // VFALCO TODO hoist to remove template argument dependencies
180 class KeyValueCompare : public Compare
181 {
182 public:
183 using first_argument = Key;
185 using result_type = bool;
186
187 KeyValueCompare() = default;
188
189 KeyValueCompare(Compare const& compare) : Compare(compare)
190 {
191 }
192
193 bool
194 operator()(Key const& k, element const& e) const
195 {
196 return Compare::operator()(k, extract(e.value));
197 }
198
199 bool
200 operator()(element const& e, Key const& k) const
201 {
202 return Compare::operator()(extract(e.value), k);
203 }
204
205 bool
206 operator()(element const& x, element const& y) const
207 {
208 return Compare::operator()(extract(x.value), extract(y.value));
209 }
210
211 Compare&
213 {
214 return *this;
215 }
216
217 Compare const&
218 compare() const
219 {
220 return *this;
221 }
222 };
223
224 using list_type = typename boost::intrusive::
225 make_list<element, boost::intrusive::constant_time_size<false>>::type;
226
227 using cont_type = typename std::conditional<
228 IsMulti,
229 typename boost::intrusive::make_multiset<
230 element,
231 boost::intrusive::constant_time_size<true>,
232 boost::intrusive::compare<KeyValueCompare>>::type,
233 typename boost::intrusive::make_set<
234 element,
235 boost::intrusive::constant_time_size<true>,
236 boost::intrusive::compare<KeyValueCompare>>::type>::type;
237
239 Allocator>::template rebind_alloc<element>;
240
242
244 : private KeyValueCompare,
245 public beast::detail::empty_base_optimization<ElementAllocator>
246 {
247 public:
248 explicit config_t(clock_type& clock_) : clock(clock_)
249 {
250 }
251
252 config_t(clock_type& clock_, Compare const& comp)
253 : KeyValueCompare(comp), clock(clock_)
254 {
255 }
256
257 config_t(clock_type& clock_, Allocator const& alloc_)
259 , clock(clock_)
260 {
261 }
262
264 clock_type& clock_,
265 Compare const& comp,
266 Allocator const& alloc_)
267 : KeyValueCompare(comp)
269 , clock(clock_)
270 {
271 }
272
273 config_t(config_t const& other)
276 ElementAllocatorTraits::select_on_container_copy_construction(
277 other.alloc()))
278 , clock(other.clock)
279 {
280 }
281
282 config_t(config_t const& other, Allocator const& alloc)
285 , clock(other.clock)
286 {
287 }
288
290 : KeyValueCompare(std::move(other.key_compare()))
292 std::move(other))
293 , clock(other.clock)
294 {
295 }
296
297 config_t(config_t&& other, Allocator const& alloc)
298 : KeyValueCompare(std::move(other.key_compare()))
300 , clock(other.clock)
301 {
302 }
303
304 config_t&
305 operator=(config_t const& other)
306 {
307 if (this != &other)
308 {
309 compare() = other.compare();
310 alloc() = other.alloc();
311 clock = other.clock;
312 }
313 return *this;
314 }
315
316 config_t&
318 {
319 compare() = std::move(other.compare());
320 alloc() = std::move(other.alloc());
321 clock = other.clock;
322 return *this;
323 }
324
325 Compare&
327 {
329 }
330
331 Compare const&
332 compare() const
333 {
335 }
336
339 {
340 return *this;
341 }
342
343 KeyValueCompare const&
345 {
346 return *this;
347 }
348
355
356 ElementAllocator const&
362
364 };
365
366 template <class... Args>
367 element*
368 new_element(Args&&... args)
369 {
370 struct Deleter
371 {
373 Deleter(ElementAllocator& a) : a_(a)
374 {
375 }
376
377 void
378 operator()(element* p)
379 {
380 ElementAllocatorTraits::deallocate(a_.get(), p, 1);
381 }
382 };
383
386 Deleter(m_config.alloc()));
388 m_config.alloc(),
389 p.get(),
390 clock().now(),
391 std::forward<Args>(args)...);
392 return p.release();
393 }
394
395 void
402
403 void
405 {
406 chronological.list.erase(chronological.list.iterator_to(*p));
407 m_cont.erase(m_cont.iterator_to(*p));
409 }
410
411public:
412 using key_compare = Compare;
415 using allocator_type = Allocator;
421
422 // A set iterator (IsMap==false) is always const
423 // because the elements of a set are immutable.
424 using iterator = beast::detail::
425 aged_container_iterator<!IsMap, typename cont_type::iterator>;
426 using const_iterator = beast::detail::
427 aged_container_iterator<true, typename cont_type::iterator>;
428 using reverse_iterator = beast::detail::
429 aged_container_iterator<!IsMap, typename cont_type::reverse_iterator>;
430 using const_reverse_iterator = beast::detail::
431 aged_container_iterator<true, typename cont_type::reverse_iterator>;
432
433 //--------------------------------------------------------------------------
434 //
435 // Chronological ordered iterators
436 //
437 // "Memberspace"
438 // http://accu.org/index.php/journals/1527
439 //
440 //--------------------------------------------------------------------------
441
443 {
444 public:
445 // A set iterator (IsMap==false) is always const
446 // because the elements of a set are immutable.
447 using iterator = beast::detail::
448 aged_container_iterator<!IsMap, typename list_type::iterator>;
449 using const_iterator = beast::detail::
450 aged_container_iterator<true, typename list_type::iterator>;
452 !IsMap,
453 typename list_type::reverse_iterator>;
454 using const_reverse_iterator = beast::detail::
455 aged_container_iterator<true, typename list_type::reverse_iterator>;
456
459 {
460 return iterator(list.begin());
461 }
462
464 begin() const
465 {
466 return const_iterator(list.begin());
467 }
468
470 cbegin() const
471 {
472 return const_iterator(list.begin());
473 }
474
477 {
478 return iterator(list.end());
479 }
480
482 end() const
483 {
484 return const_iterator(list.end());
485 }
486
488 cend() const
489 {
490 return const_iterator(list.end());
491 }
492
495 {
496 return reverse_iterator(list.rbegin());
497 }
498
500 rbegin() const
501 {
502 return const_reverse_iterator(list.rbegin());
503 }
504
506 crbegin() const
507 {
508 return const_reverse_iterator(list.rbegin());
509 }
510
513 {
514 return reverse_iterator(list.rend());
515 }
516
518 rend() const
519 {
520 return const_reverse_iterator(list.rend());
521 }
522
524 crend() const
525 {
526 return const_reverse_iterator(list.rend());
527 }
528
531 {
532 static_assert(
534 "must be standard layout");
535 return list.iterator_to(*reinterpret_cast<element*>(
536 reinterpret_cast<uint8_t*>(&value) -
537 ((std::size_t)std::addressof(((element*)0)->member))));
538 }
539
541 iterator_to(value_type const& value) const
542 {
543 static_assert(
545 "must be standard layout");
546 return list.iterator_to(*reinterpret_cast<element const*>(
547 reinterpret_cast<uint8_t const*>(&value) -
548 ((std::size_t)std::addressof(((element*)0)->member))));
549 }
550
551 private:
553 {
554 }
555
558
562
563 //--------------------------------------------------------------------------
564 //
565 // Construction
566 //
567 //--------------------------------------------------------------------------
568
570
572
574
575 aged_ordered_container(clock_type& clock, Allocator const& alloc);
576
579 Compare const& comp,
580 Allocator const& alloc);
581
582 template <class InputIt>
583 aged_ordered_container(InputIt first, InputIt last, clock_type& clock);
584
585 template <class InputIt>
587 InputIt first,
588 InputIt last,
590 Compare const& comp);
591
592 template <class InputIt>
594 InputIt first,
595 InputIt last,
597 Allocator const& alloc);
598
599 template <class InputIt>
601 InputIt first,
602 InputIt last,
604 Compare const& comp,
605 Allocator const& alloc);
606
608
610 aged_ordered_container const& other,
611 Allocator const& alloc);
612
614
617 Allocator const& alloc);
618
622
626 Compare const& comp);
627
631 Allocator const& alloc);
632
636 Compare const& comp,
637 Allocator const& alloc);
638
640
643
646
649
652 {
653 return m_config.alloc();
654 }
655
658 {
659 return m_config.clock;
660 }
661
662 clock_type const&
663 clock() const
664 {
665 return m_config.clock;
666 }
667
668 //--------------------------------------------------------------------------
669 //
670 // Element access (maps)
671 //
672 //--------------------------------------------------------------------------
673
674 template <
675 class K,
676 bool maybe_multi = IsMulti,
677 bool maybe_map = IsMap,
680 at(K const& k);
681
682 template <
683 class K,
684 bool maybe_multi = IsMulti,
685 bool maybe_map = IsMap,
688 at(K const& k) const;
689
690 template <
691 bool maybe_multi = IsMulti,
692 bool maybe_map = IsMap,
695 operator[](Key const& key);
696
697 template <
698 bool maybe_multi = IsMulti,
699 bool maybe_map = IsMap,
702 operator[](Key&& key);
703
704 //--------------------------------------------------------------------------
705 //
706 // Iterators
707 //
708 //--------------------------------------------------------------------------
709
712 {
713 return iterator(m_cont.begin());
714 }
715
717 begin() const
718 {
719 return const_iterator(m_cont.begin());
720 }
721
723 cbegin() const
724 {
725 return const_iterator(m_cont.begin());
726 }
727
730 {
731 return iterator(m_cont.end());
732 }
733
735 end() const
736 {
737 return const_iterator(m_cont.end());
738 }
739
741 cend() const
742 {
743 return const_iterator(m_cont.end());
744 }
745
748 {
749 return reverse_iterator(m_cont.rbegin());
750 }
751
753 rbegin() const
754 {
755 return const_reverse_iterator(m_cont.rbegin());
756 }
757
759 crbegin() const
760 {
761 return const_reverse_iterator(m_cont.rbegin());
762 }
763
766 {
767 return reverse_iterator(m_cont.rend());
768 }
769
771 rend() const
772 {
773 return const_reverse_iterator(m_cont.rend());
774 }
775
777 crend() const
778 {
779 return const_reverse_iterator(m_cont.rend());
780 }
781
784 {
785 static_assert(
786 std::is_standard_layout<element>::value, "must be standard layout");
787 return m_cont.iterator_to(*reinterpret_cast<element*>(
788 reinterpret_cast<uint8_t*>(&value) -
789 ((std::size_t)std::addressof(((element*)0)->member))));
790 }
791
793 iterator_to(value_type const& value) const
794 {
795 static_assert(
796 std::is_standard_layout<element>::value, "must be standard layout");
797 return m_cont.iterator_to(*reinterpret_cast<element const*>(
798 reinterpret_cast<uint8_t const*>(&value) -
799 ((std::size_t)std::addressof(((element*)0)->member))));
800 }
801
802 //--------------------------------------------------------------------------
803 //
804 // Capacity
805 //
806 //--------------------------------------------------------------------------
807
808 bool
809 empty() const noexcept
810 {
811 return m_cont.empty();
812 }
813
815 size() const noexcept
816 {
817 return m_cont.size();
818 }
819
821 max_size() const noexcept
822 {
823 return m_config.max_size();
824 }
825
826 //--------------------------------------------------------------------------
827 //
828 // Modifiers
829 //
830 //--------------------------------------------------------------------------
831
832 void
834
835 // map, set
836 template <bool maybe_multi = IsMulti>
837 auto
838 insert(value_type const& value) ->
840
841 // multimap, multiset
842 template <bool maybe_multi = IsMulti>
843 auto
844 insert(value_type const& value) ->
846
847 // set
848 template <bool maybe_multi = IsMulti, bool maybe_map = IsMap>
849 auto
850 insert(value_type&& value) -> typename std::enable_if<
851 !maybe_multi && !maybe_map,
853
854 // multiset
855 template <bool maybe_multi = IsMulti, bool maybe_map = IsMap>
856 auto
857 insert(value_type&& value) ->
859
860 //---
861
862 // map, set
863 template <bool maybe_multi = IsMulti>
864 auto
865 insert(const_iterator hint, value_type const& value) ->
867
868 // multimap, multiset
869 template <bool maybe_multi = IsMulti>
871 insert(const_iterator /*hint*/, value_type const& value)
872 {
873 // VFALCO TODO Figure out how to utilize 'hint'
874 return insert(value);
875 }
876
877 // map, set
878 template <bool maybe_multi = IsMulti>
879 auto
882
883 // multimap, multiset
884 template <bool maybe_multi = IsMulti>
887 {
888 // VFALCO TODO Figure out how to utilize 'hint'
889 return insert(std::move(value));
890 }
891
892 // map, multimap
893 template <class P, bool maybe_map = IsMap>
894 typename std::enable_if<
896 typename std::
898 type
899 insert(P&& value)
900 {
901 return emplace(std::forward<P>(value));
902 }
903
904 // map, multimap
905 template <class P, bool maybe_map = IsMap>
906 typename std::enable_if<
908 typename std::
910 type
911 insert(const_iterator hint, P&& value)
912 {
913 return emplace_hint(hint, std::forward<P>(value));
914 }
915
916 template <class InputIt>
917 void
918 insert(InputIt first, InputIt last)
919 {
920 for (; first != last; ++first)
921 insert(cend(), *first);
922 }
923
924 void
926 {
927 insert(init.begin(), init.end());
928 }
929
930 // map, set
931 template <bool maybe_multi = IsMulti, class... Args>
932 auto
933 emplace(Args&&... args) ->
935
936 // multiset, multimap
937 template <bool maybe_multi = IsMulti, class... Args>
938 auto
939 emplace(Args&&... args) ->
941
942 // map, set
943 template <bool maybe_multi = IsMulti, class... Args>
944 auto
945 emplace_hint(const_iterator hint, Args&&... args) ->
947
948 // multiset, multimap
949 template <bool maybe_multi = IsMulti, class... Args>
951 emplace_hint(const_iterator /*hint*/, Args&&... args)
952 {
953 // VFALCO TODO Figure out how to utilize 'hint'
954 return emplace<maybe_multi>(std::forward<Args>(args)...);
955 }
956
957 // enable_if prevents erase (reverse_iterator pos) from compiling
958 template <
959 bool is_const,
960 class Iterator,
964
965 // enable_if prevents erase (reverse_iterator first, reverse_iterator last)
966 // from compiling
967 template <
968 bool is_const,
969 class Iterator,
975
976 template <class K>
977 auto
978 erase(K const& k) -> size_type;
979
980 void
981 swap(aged_ordered_container& other) noexcept;
982
983 //--------------------------------------------------------------------------
984
985 // enable_if prevents touch (reverse_iterator pos) from compiling
986 template <
987 bool is_const,
988 class Iterator,
990 void
995
996 template <class K>
998 touch(K const& k);
999
1000 //--------------------------------------------------------------------------
1001 //
1002 // Lookup
1003 //
1004 //--------------------------------------------------------------------------
1005
1006 // VFALCO TODO Respect is_transparent (c++14)
1007 template <class K>
1008 size_type
1009 count(K const& k) const
1010 {
1011 return m_cont.count(k, std::cref(m_config.key_compare()));
1012 }
1013
1014 // VFALCO TODO Respect is_transparent (c++14)
1015 template <class K>
1016 iterator
1017 find(K const& k)
1018 {
1019 return iterator(m_cont.find(k, std::cref(m_config.key_compare())));
1020 }
1021
1022 // VFALCO TODO Respect is_transparent (c++14)
1023 template <class K>
1025 find(K const& k) const
1026 {
1027 return const_iterator(
1028 m_cont.find(k, std::cref(m_config.key_compare())));
1029 }
1030
1031 // VFALCO TODO Respect is_transparent (c++14)
1032 template <class K>
1034 equal_range(K const& k)
1035 {
1036 auto const r(m_cont.equal_range(k, std::cref(m_config.key_compare())));
1037 return std::make_pair(iterator(r.first), iterator(r.second));
1038 }
1039
1040 // VFALCO TODO Respect is_transparent (c++14)
1041 template <class K>
1043 equal_range(K const& k) const
1044 {
1045 auto const r(m_cont.equal_range(k, std::cref(m_config.key_compare())));
1046 return std::make_pair(
1047 const_iterator(r.first), const_iterator(r.second));
1048 }
1049
1050 // VFALCO TODO Respect is_transparent (c++14)
1051 template <class K>
1052 iterator
1053 lower_bound(K const& k)
1054 {
1055 return iterator(
1056 m_cont.lower_bound(k, std::cref(m_config.key_compare())));
1057 }
1058
1059 // VFALCO TODO Respect is_transparent (c++14)
1060 template <class K>
1062 lower_bound(K const& k) const
1063 {
1064 return const_iterator(
1065 m_cont.lower_bound(k, std::cref(m_config.key_compare())));
1066 }
1067
1068 // VFALCO TODO Respect is_transparent (c++14)
1069 template <class K>
1070 iterator
1071 upper_bound(K const& k)
1072 {
1073 return iterator(
1074 m_cont.upper_bound(k, std::cref(m_config.key_compare())));
1075 }
1076
1077 // VFALCO TODO Respect is_transparent (c++14)
1078 template <class K>
1080 upper_bound(K const& k) const
1081 {
1082 return const_iterator(
1083 m_cont.upper_bound(k, std::cref(m_config.key_compare())));
1084 }
1085
1086 //--------------------------------------------------------------------------
1087 //
1088 // Observers
1089 //
1090 //--------------------------------------------------------------------------
1091
1093 key_comp() const
1094 {
1095 return m_config.compare();
1096 }
1097
1098 // VFALCO TODO Should this return const reference for set?
1101 {
1102 return value_compare(m_config.compare());
1103 }
1104
1105 //--------------------------------------------------------------------------
1106 //
1107 // Comparison
1108 //
1109 //--------------------------------------------------------------------------
1110
1111 // This differs from the standard in that the comparison
1112 // is only done on the key portion of the value type, ignoring
1113 // the mapped type.
1114 //
1115 template <
1116 bool OtherIsMulti,
1117 bool OtherIsMap,
1118 class OtherT,
1119 class OtherDuration,
1120 class OtherAllocator>
1121 bool
1123 OtherIsMulti,
1124 OtherIsMap,
1125 Key,
1126 OtherT,
1127 OtherDuration,
1128 Compare,
1129 OtherAllocator> const& other) const;
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 return !(this->operator==(other));
1148 }
1149
1150 template <
1151 bool OtherIsMulti,
1152 bool OtherIsMap,
1153 class OtherT,
1154 class OtherDuration,
1155 class OtherAllocator>
1156 bool
1158 OtherIsMulti,
1159 OtherIsMap,
1160 Key,
1161 OtherT,
1162 OtherDuration,
1163 Compare,
1164 OtherAllocator> const& other) const
1165 {
1166 value_compare const comp(value_comp());
1168 cbegin(), cend(), other.cbegin(), other.cend(), comp);
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 other < *this;
1207 }
1208
1209 template <
1210 bool OtherIsMulti,
1211 bool OtherIsMap,
1212 class OtherT,
1213 class OtherDuration,
1214 class OtherAllocator>
1215 bool
1217 OtherIsMulti,
1218 OtherIsMap,
1219 Key,
1220 OtherT,
1221 OtherDuration,
1222 Compare,
1223 OtherAllocator> const& other) const
1224 {
1225 return !(*this < other);
1226 }
1227
1228private:
1229 // enable_if prevents erase (reverse_iterator pos, now) from compiling
1230 template <
1231 bool is_const,
1232 class Iterator,
1234 void
1237 typename clock_type::time_point const& now);
1238
1239 template <
1240 bool maybe_propagate = std::allocator_traits<
1241 Allocator>::propagate_on_container_swap::value>
1244
1245 template <
1246 bool maybe_propagate = std::allocator_traits<
1247 Allocator>::propagate_on_container_swap::value>
1250
1251private:
1254};
1255
1256//------------------------------------------------------------------------------
1257
1258template <
1259 bool IsMulti,
1260 bool IsMap,
1261 class Key,
1262 class T,
1263 class Clock,
1264 class Compare,
1265 class Allocator>
1271
1272template <
1273 bool IsMulti,
1274 bool IsMap,
1275 class Key,
1276 class T,
1277 class Clock,
1278 class Compare,
1279 class Allocator>
1281 aged_ordered_container(clock_type& clock, Compare const& comp)
1282 : m_config(clock, comp), m_cont(comp)
1283{
1284}
1285
1286template <
1287 bool IsMulti,
1288 bool IsMap,
1289 class Key,
1290 class T,
1291 class Clock,
1292 class Compare,
1293 class Allocator>
1295 aged_ordered_container(clock_type& clock, Allocator const& alloc)
1296 : m_config(clock, alloc)
1297{
1298}
1299
1300template <
1301 bool IsMulti,
1302 bool IsMap,
1303 class Key,
1304 class T,
1305 class Clock,
1306 class Compare,
1307 class Allocator>
1310 clock_type& clock,
1311 Compare const& comp,
1312 Allocator const& alloc)
1313 : m_config(clock, comp, alloc), m_cont(comp)
1314{
1315}
1316
1317template <
1318 bool IsMulti,
1319 bool IsMap,
1320 class Key,
1321 class T,
1322 class Clock,
1323 class Compare,
1324 class Allocator>
1325template <class InputIt>
1327 aged_ordered_container(InputIt first, InputIt last, clock_type& clock)
1328 : m_config(clock)
1329{
1330 insert(first, last);
1331}
1332
1333template <
1334 bool IsMulti,
1335 bool IsMap,
1336 class Key,
1337 class T,
1338 class Clock,
1339 class Compare,
1340 class Allocator>
1341template <class InputIt>
1344 InputIt first,
1345 InputIt last,
1346 clock_type& clock,
1347 Compare const& comp)
1348 : m_config(clock, comp), m_cont(comp)
1349{
1350 insert(first, last);
1351}
1352
1353template <
1354 bool IsMulti,
1355 bool IsMap,
1356 class Key,
1357 class T,
1358 class Clock,
1359 class Compare,
1360 class Allocator>
1361template <class InputIt>
1364 InputIt first,
1365 InputIt last,
1366 clock_type& clock,
1367 Allocator const& alloc)
1368 : m_config(clock, alloc)
1369{
1370 insert(first, last);
1371}
1372
1373template <
1374 bool IsMulti,
1375 bool IsMap,
1376 class Key,
1377 class T,
1378 class Clock,
1379 class Compare,
1380 class Allocator>
1381template <class InputIt>
1384 InputIt first,
1385 InputIt last,
1386 clock_type& clock,
1387 Compare const& comp,
1388 Allocator const& alloc)
1389 : m_config(clock, comp, alloc), m_cont(comp)
1390{
1391 insert(first, last);
1392}
1393
1394template <
1395 bool IsMulti,
1396 bool IsMap,
1397 class Key,
1398 class T,
1399 class Clock,
1400 class Compare,
1401 class Allocator>
1404 : m_config(other.m_config)
1405#if BOOST_VERSION >= 108000
1406 , m_cont(other.m_cont.get_comp())
1407#else
1408 , m_cont(other.m_cont.comp())
1409#endif
1410{
1411 insert(other.cbegin(), other.cend());
1412}
1413
1414template <
1415 bool IsMulti,
1416 bool IsMap,
1417 class Key,
1418 class T,
1419 class Clock,
1420 class Compare,
1421 class Allocator>
1424 aged_ordered_container const& other,
1425 Allocator const& alloc)
1426 : m_config(other.m_config, alloc)
1427#if BOOST_VERSION >= 108000
1428 , m_cont(other.m_cont.get_comp())
1429#else
1430 , m_cont(other.m_cont.comp())
1431#endif
1432{
1433 insert(other.cbegin(), other.cend());
1434}
1435
1436template <
1437 bool IsMulti,
1438 bool IsMap,
1439 class Key,
1440 class T,
1441 class Clock,
1442 class Compare,
1443 class Allocator>
1446 : m_config(std::move(other.m_config)), m_cont(std::move(other.m_cont))
1447{
1448 chronological.list = std::move(other.chronological.list);
1449}
1450
1451template <
1452 bool IsMulti,
1453 bool IsMap,
1454 class Key,
1455 class T,
1456 class Clock,
1457 class Compare,
1458 class Allocator>
1461 aged_ordered_container&& other,
1462 Allocator const& alloc)
1463 : m_config(std::move(other.m_config), alloc)
1464#if BOOST_VERSION >= 108000
1465 , m_cont(std::move(other.m_cont.get_comp()))
1466#else
1467 , m_cont(std::move(other.m_cont.comp()))
1468#endif
1469
1470{
1471 insert(other.cbegin(), other.cend());
1472 other.clear();
1473}
1474
1475template <
1476 bool IsMulti,
1477 bool IsMap,
1478 class Key,
1479 class T,
1480 class Clock,
1481 class Compare,
1482 class Allocator>
1491
1492template <
1493 bool IsMulti,
1494 bool IsMap,
1495 class Key,
1496 class T,
1497 class Clock,
1498 class Compare,
1499 class Allocator>
1503 clock_type& clock,
1504 Compare const& comp)
1505 : m_config(clock, comp), m_cont(comp)
1506{
1507 insert(init.begin(), init.end());
1508}
1509
1510template <
1511 bool IsMulti,
1512 bool IsMap,
1513 class Key,
1514 class T,
1515 class Clock,
1516 class Compare,
1517 class Allocator>
1521 clock_type& clock,
1522 Allocator const& alloc)
1523 : m_config(clock, alloc)
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>
1539 clock_type& clock,
1540 Compare const& comp,
1541 Allocator const& alloc)
1542 : m_config(clock, comp, alloc), m_cont(comp)
1543{
1544 insert(init.begin(), init.end());
1545}
1546
1547template <
1548 bool IsMulti,
1549 bool IsMap,
1550 class Key,
1551 class T,
1552 class Clock,
1553 class Compare,
1554 class Allocator>
1560
1561template <
1562 bool IsMulti,
1563 bool IsMap,
1564 class Key,
1565 class T,
1566 class Clock,
1567 class Compare,
1568 class Allocator>
1569auto
1572{
1573 if (this != &other)
1574 {
1575 clear();
1576 this->m_config = other.m_config;
1577 insert(other.begin(), other.end());
1578 }
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
1593{
1594 clear();
1595 this->m_config = std::move(other.m_config);
1596 insert(other.begin(), other.end());
1597 other.clear();
1598 return *this;
1599}
1600
1601template <
1602 bool IsMulti,
1603 bool IsMap,
1604 class Key,
1605 class T,
1606 class Clock,
1607 class Compare,
1608 class Allocator>
1609auto
1617
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)
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 <class K, bool maybe_multi, bool maybe_map, class>
1650 K const& k) const
1651{
1652 auto const iter(m_cont.find(k, std::cref(m_config.key_compare())));
1653 if (iter == m_cont.end())
1654 throw std::out_of_range("key not found");
1655 return iter->value.second;
1656}
1657
1658template <
1659 bool IsMulti,
1660 bool IsMap,
1661 class Key,
1662 class T,
1663 class Clock,
1664 class Compare,
1665 class Allocator>
1666template <bool maybe_multi, bool maybe_map, class>
1669operator[](Key const& key)
1670{
1671 typename cont_type::insert_commit_data d;
1672 auto const result(
1673 m_cont.insert_check(key, std::cref(m_config.key_compare()), d));
1674 if (result.second)
1675 {
1676 element* const p(new_element(
1680 m_cont.insert_commit(*p, d);
1681 chronological.list.push_back(*p);
1682 return p->value.second;
1683 }
1684 return result.first->value.second;
1685}
1686
1687template <
1688 bool IsMulti,
1689 bool IsMap,
1690 class Key,
1691 class T,
1692 class Clock,
1693 class Compare,
1694 class Allocator>
1695template <bool maybe_multi, bool maybe_map, class>
1698operator[](Key&& key)
1699{
1700 typename cont_type::insert_commit_data d;
1701 auto const result(
1702 m_cont.insert_check(key, std::cref(m_config.key_compare()), d));
1703 if (result.second)
1704 {
1705 element* const p(new_element(
1707 std::forward_as_tuple(std::move(key)),
1709 m_cont.insert_commit(*p, d);
1710 chronological.list.push_back(*p);
1711 return p->value.second;
1712 }
1713 return result.first->value.second;
1714}
1715
1716//------------------------------------------------------------------------------
1717
1718template <
1719 bool IsMulti,
1720 bool IsMap,
1721 class Key,
1722 class T,
1723 class Clock,
1724 class Compare,
1725 class Allocator>
1726void
1728 clear()
1729{
1730 for (auto iter(chronological.list.begin());
1731 iter != chronological.list.end();)
1732 delete_element(&*iter++);
1733 chronological.list.clear();
1734 m_cont.clear();
1735}
1736
1737// map, set
1738template <
1739 bool IsMulti,
1740 bool IsMap,
1741 class Key,
1742 class T,
1743 class Clock,
1744 class Compare,
1745 class Allocator>
1746template <bool maybe_multi>
1747auto
1749 insert(value_type const& value) ->
1751{
1752 typename cont_type::insert_commit_data d;
1753 auto const result(m_cont.insert_check(
1754 extract(value), std::cref(m_config.key_compare()), d));
1755 if (result.second)
1756 {
1757 element* const p(new_element(value));
1758 auto const iter(m_cont.insert_commit(*p, d));
1759 chronological.list.push_back(*p);
1760 return std::make_pair(iterator(iter), true);
1761 }
1762 return std::make_pair(iterator(result.first), false);
1763}
1764
1765// multimap, multiset
1766template <
1767 bool IsMulti,
1768 bool IsMap,
1769 class Key,
1770 class T,
1771 class Clock,
1772 class Compare,
1773 class Allocator>
1774template <bool maybe_multi>
1775auto
1777 insert(value_type const& value) ->
1779{
1780 auto const before(
1781 m_cont.upper_bound(extract(value), std::cref(m_config.key_compare())));
1782 element* const p(new_element(value));
1783 chronological.list.push_back(*p);
1784 auto const iter(m_cont.insert_before(before, *p));
1785 return iterator(iter);
1786}
1787
1788// set
1789template <
1790 bool IsMulti,
1791 bool IsMap,
1792 class Key,
1793 class T,
1794 class Clock,
1795 class Compare,
1796 class Allocator>
1797template <bool maybe_multi, bool maybe_map>
1798auto
1800 insert(value_type&& value) ->
1801 typename std::
1803{
1804 typename cont_type::insert_commit_data d;
1805 auto const result(m_cont.insert_check(
1806 extract(value), std::cref(m_config.key_compare()), d));
1807 if (result.second)
1808 {
1809 element* const p(new_element(std::move(value)));
1810 auto const iter(m_cont.insert_commit(*p, d));
1811 chronological.list.push_back(*p);
1812 return std::make_pair(iterator(iter), true);
1813 }
1814 return std::make_pair(iterator(result.first), false);
1815}
1816
1817// multiset
1818template <
1819 bool IsMulti,
1820 bool IsMap,
1821 class Key,
1822 class T,
1823 class Clock,
1824 class Compare,
1825 class Allocator>
1826template <bool maybe_multi, bool maybe_map>
1827auto
1829 insert(value_type&& value) ->
1831{
1832 auto const before(
1833 m_cont.upper_bound(extract(value), std::cref(m_config.key_compare())));
1834 element* const p(new_element(std::move(value)));
1835 chronological.list.push_back(*p);
1836 auto const iter(m_cont.insert_before(before, *p));
1837 return iterator(iter);
1838}
1839
1840//---
1841
1842// map, set
1843template <
1844 bool IsMulti,
1845 bool IsMap,
1846 class Key,
1847 class T,
1848 class Clock,
1849 class Compare,
1850 class Allocator>
1851template <bool maybe_multi>
1852auto
1854 insert(const_iterator hint, value_type const& value) ->
1856{
1857 typename cont_type::insert_commit_data d;
1858 auto const result(m_cont.insert_check(
1859 hint.iterator(), extract(value), std::cref(m_config.key_compare()), d));
1860 if (result.second)
1861 {
1862 element* const p(new_element(value));
1863 auto const iter(m_cont.insert_commit(*p, d));
1864 chronological.list.push_back(*p);
1865 return iterator(iter);
1866 }
1867 return iterator(result.first);
1868}
1869
1870// map, set
1871template <
1872 bool IsMulti,
1873 bool IsMap,
1874 class Key,
1875 class T,
1876 class Clock,
1877 class Compare,
1878 class Allocator>
1879template <bool maybe_multi>
1880auto
1882 insert(const_iterator hint, value_type&& value) ->
1884{
1885 typename cont_type::insert_commit_data d;
1886 auto const result(m_cont.insert_check(
1887 hint.iterator(), extract(value), std::cref(m_config.key_compare()), d));
1888 if (result.second)
1889 {
1890 element* const p(new_element(std::move(value)));
1891 auto const iter(m_cont.insert_commit(*p, d));
1892 chronological.list.push_back(*p);
1893 return iterator(iter);
1894 }
1895 return iterator(result.first);
1896}
1897
1898// map, set
1899template <
1900 bool IsMulti,
1901 bool IsMap,
1902 class Key,
1903 class T,
1904 class Clock,
1905 class Compare,
1906 class Allocator>
1907template <bool maybe_multi, class... Args>
1908auto
1910 emplace(Args&&... args) ->
1912{
1913 // VFALCO NOTE Its unfortunate that we need to
1914 // construct element here
1915 element* const p(new_element(std::forward<Args>(args)...));
1916 typename cont_type::insert_commit_data d;
1917 auto const result(m_cont.insert_check(
1918 extract(p->value), std::cref(m_config.key_compare()), d));
1919 if (result.second)
1920 {
1921 auto const iter(m_cont.insert_commit(*p, d));
1922 chronological.list.push_back(*p);
1923 return std::make_pair(iterator(iter), true);
1924 }
1925 delete_element(p);
1926 return std::make_pair(iterator(result.first), false);
1927}
1928
1929// multiset, multimap
1930template <
1931 bool IsMulti,
1932 bool IsMap,
1933 class Key,
1934 class T,
1935 class Clock,
1936 class Compare,
1937 class Allocator>
1938template <bool maybe_multi, class... Args>
1939auto
1941 emplace(Args&&... args) ->
1943{
1944 element* const p(new_element(std::forward<Args>(args)...));
1945 auto const before(m_cont.upper_bound(
1946 extract(p->value), std::cref(m_config.key_compare())));
1947 chronological.list.push_back(*p);
1948 auto const iter(m_cont.insert_before(before, *p));
1949 return iterator(iter);
1950}
1951
1952// map, set
1953template <
1954 bool IsMulti,
1955 bool IsMap,
1956 class Key,
1957 class T,
1958 class Clock,
1959 class Compare,
1960 class Allocator>
1961template <bool maybe_multi, class... Args>
1962auto
1964 emplace_hint(const_iterator hint, Args&&... args) ->
1966{
1967 // VFALCO NOTE Its unfortunate that we need to
1968 // construct element here
1969 element* const p(new_element(std::forward<Args>(args)...));
1970 typename cont_type::insert_commit_data d;
1971 auto const result(m_cont.insert_check(
1972 hint.iterator(),
1973 extract(p->value),
1974 std::cref(m_config.key_compare()),
1975 d));
1976 if (result.second)
1977 {
1978 auto const iter(m_cont.insert_commit(*p, d));
1979 chronological.list.push_back(*p);
1980 return std::make_pair(iterator(iter), true);
1981 }
1982 delete_element(p);
1983 return std::make_pair(iterator(result.first), false);
1984}
1985
1986template <
1987 bool IsMulti,
1988 bool IsMap,
1989 class Key,
1990 class T,
1991 class Clock,
1992 class Compare,
1993 class Allocator>
1994template <bool is_const, class Iterator, class>
2003
2004template <
2005 bool IsMulti,
2006 bool IsMap,
2007 class Key,
2008 class T,
2009 class Clock,
2010 class Compare,
2011 class Allocator>
2012template <bool is_const, class Iterator, class>
2025
2026template <
2027 bool IsMulti,
2028 bool IsMap,
2029 class Key,
2030 class T,
2031 class Clock,
2032 class Compare,
2033 class Allocator>
2034template <class K>
2035auto
2037 erase(K const& k) -> size_type
2038{
2039 auto iter(m_cont.find(k, std::cref(m_config.key_compare())));
2040 if (iter == m_cont.end())
2041 return 0;
2042 size_type n(0);
2043 for (;;)
2044 {
2045 auto p(&*iter++);
2046 bool const done(m_config(*p, extract(iter->value)));
2047 unlink_and_delete_element(p);
2048 ++n;
2049 if (done)
2050 break;
2051 }
2052 return n;
2053}
2054
2055template <
2056 bool IsMulti,
2057 bool IsMap,
2058 class Key,
2059 class T,
2060 class Clock,
2061 class Compare,
2062 class Allocator>
2063void
2065 aged_ordered_container& other) noexcept
2066{
2067 swap_data(other);
2068 std::swap(chronological, other.chronological);
2069 std::swap(m_cont, other.m_cont);
2070}
2071
2072//------------------------------------------------------------------------------
2073
2074template <
2075 bool IsMulti,
2076 bool IsMap,
2077 class Key,
2078 class T,
2079 class Clock,
2080 class Compare,
2081 class Allocator>
2082template <class K>
2083auto
2085 touch(K const& k) -> size_type
2086{
2087 auto const now(clock().now());
2088 size_type n(0);
2089 auto const range(equal_range(k));
2090 for (auto iter : range)
2091 {
2092 touch(iter, now);
2093 ++n;
2094 }
2095 return n;
2096}
2097
2098//------------------------------------------------------------------------------
2099
2100template <
2101 bool IsMulti,
2102 bool IsMap,
2103 class Key,
2104 class T,
2105 class Clock,
2106 class Compare,
2107 class Allocator>
2108template <
2109 bool OtherIsMulti,
2110 bool OtherIsMap,
2111 class OtherT,
2112 class OtherDuration,
2113 class OtherAllocator>
2114bool
2117 OtherIsMulti,
2118 OtherIsMap,
2119 Key,
2120 OtherT,
2121 OtherDuration,
2122 Compare,
2123 OtherAllocator> const& other) const
2124{
2125 using Other = aged_ordered_container<
2126 OtherIsMulti,
2127 OtherIsMap,
2128 Key,
2129 OtherT,
2130 OtherDuration,
2131 Compare,
2132 OtherAllocator>;
2133 if (size() != other.size())
2134 return false;
2136 return std::equal(
2137 cbegin(),
2138 cend(),
2139 other.cbegin(),
2140 other.cend(),
2141 [&eq, &other](
2142 value_type const& lhs, typename Other::value_type const& rhs) {
2143 return eq(extract(lhs), other.extract(rhs));
2144 });
2145}
2146
2147//------------------------------------------------------------------------------
2148
2149template <
2150 bool IsMulti,
2151 bool IsMap,
2152 class Key,
2153 class T,
2154 class Clock,
2155 class Compare,
2156 class Allocator>
2157template <bool is_const, class Iterator, class>
2158void
2160 touch(
2162 typename clock_type::time_point const& now)
2163{
2164 auto& e(*pos.iterator());
2165 e.when = now;
2166 chronological.list.erase(chronological.list.iterator_to(e));
2167 chronological.list.push_back(e);
2168}
2169
2170template <
2171 bool IsMulti,
2172 bool IsMap,
2173 class Key,
2174 class T,
2175 class Clock,
2176 class Compare,
2177 class Allocator>
2178template <bool maybe_propagate>
2181 swap_data(aged_ordered_container& other) noexcept
2182{
2183 std::swap(m_config.key_compare(), other.m_config.key_compare());
2184 std::swap(m_config.alloc(), other.m_config.alloc());
2185 std::swap(m_config.clock, other.m_config.clock);
2186}
2187
2188template <
2189 bool IsMulti,
2190 bool IsMap,
2191 class Key,
2192 class T,
2193 class Clock,
2194 class Compare,
2195 class Allocator>
2196template <bool maybe_propagate>
2199 swap_data(aged_ordered_container& other) noexcept
2200{
2201 std::swap(m_config.key_compare(), other.m_config.key_compare());
2202 std::swap(m_config.clock, other.m_config.clock);
2203}
2204
2205} // namespace detail
2206
2207//------------------------------------------------------------------------------
2208
2209template <
2210 bool IsMulti,
2211 bool IsMap,
2212 class Key,
2213 class T,
2214 class Clock,
2215 class Compare,
2216 class Allocator>
2218 IsMulti,
2219 IsMap,
2220 Key,
2221 T,
2222 Clock,
2223 Compare,
2224 Allocator>> : std::true_type
2225{
2226 explicit is_aged_container() = default;
2227};
2228
2229// Free functions
2230
2231template <
2232 bool IsMulti,
2233 bool IsMap,
2234 class Key,
2235 class T,
2236 class Clock,
2237 class Compare,
2238 class Allocator>
2239void
2242 IsMulti,
2243 IsMap,
2244 Key,
2245 T,
2246 Clock,
2247 Compare,
2248 Allocator>& lhs,
2250 IsMulti,
2251 IsMap,
2252 Key,
2253 T,
2254 Clock,
2255 Compare,
2256 Allocator>& rhs) noexcept
2257{
2258 lhs.swap(rhs);
2259}
2260
2262template <
2263 bool IsMulti,
2264 bool IsMap,
2265 class Key,
2266 class T,
2267 class Clock,
2268 class Compare,
2269 class Allocator,
2270 class Rep,
2271 class Period>
2275 IsMulti,
2276 IsMap,
2277 Key,
2278 T,
2279 Clock,
2280 Compare,
2281 Allocator>& c,
2283{
2284 std::size_t n(0);
2285 auto const expired(c.clock().now() - age);
2286 for (auto iter(c.chronological.cbegin());
2287 iter != c.chronological.cend() && iter.when() <= expired;)
2288 {
2289 iter = c.erase(iter);
2290 ++n;
2291 }
2292 return n;
2293}
2294
2295} // namespace beast
2296
2297#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)