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 <iterator>
37#include <memory>
38#include <type_traits>
39#include <utility>
40
41namespace beast {
42namespace detail {
43
44// Traits templates used to discern reverse_iterators, which are disallowed
45// for mutating operations.
46template <class It>
48{
49 explicit is_boost_reverse_iterator() = default;
50};
51
52template <class It>
53struct is_boost_reverse_iterator<boost::intrusive::reverse_iterator<It>>
55{
56 explicit is_boost_reverse_iterator() = default;
57};
58
75template <
76 bool IsMulti,
77 bool IsMap,
78 class Key,
79 class T,
80 class Clock = std::chrono::steady_clock,
81 class Compare = std::less<Key>,
82 class Allocator = std::allocator<
85{
86public:
90 using key_type = Key;
91 using mapped_type = T;
92 using value_type =
96
97 // Introspection (for unit tests)
101
102private:
103 static Key const&
104 extract(value_type const& value)
105 {
107 }
108
109 // VFALCO TODO hoist to remove template argument dependencies
110 struct element
111 : boost::intrusive::set_base_hook<
112 boost::intrusive::link_mode<boost::intrusive::normal_link>>,
113 boost::intrusive::list_base_hook<
114 boost::intrusive::link_mode<boost::intrusive::normal_link>>
115 {
116 // Stash types here so the iterator doesn't
117 // need to see the container declaration.
118 struct stashed
119 {
120 explicit stashed() = default;
121
124 };
125
126 element(time_point const& when_, value_type const& value_)
127 : value(value_), when(when_)
128 {
129 }
130
131 element(time_point const& when_, value_type&& value_)
132 : value(std::move(value_)), when(when_)
133 {
134 }
135
136 template <
137 class... Args,
138 class = typename std::enable_if<
140 element(time_point const& when_, Args&&... args)
141 : value(std::forward<Args>(args)...), when(when_)
142 {
143 }
144
147 };
148
149 // VFALCO TODO This should only be enabled for maps.
150 class pair_value_compare : public Compare
151 {
152 public:
155 using result_type = bool;
156
157 bool
158 operator()(value_type const& lhs, value_type const& rhs) const
159 {
160 return Compare::operator()(lhs.first, rhs.first);
161 }
162
164 {
165 }
166
167 pair_value_compare(pair_value_compare const& other) : Compare(other)
168 {
169 }
170
171 private:
173
174 pair_value_compare(Compare const& compare) : Compare(compare)
175 {
176 }
177 };
178
179 // Compares value_type against element, used in insert_check
180 // VFALCO TODO hoist to remove template argument dependencies
181 class KeyValueCompare : public Compare
182 {
183 public:
184 using first_argument = Key;
186 using result_type = bool;
187
188 KeyValueCompare() = default;
189
190 KeyValueCompare(Compare const& compare) : Compare(compare)
191 {
192 }
193
194 bool
195 operator()(Key const& k, element const& e) const
196 {
197 return Compare::operator()(k, extract(e.value));
198 }
199
200 bool
201 operator()(element const& e, Key const& k) const
202 {
203 return Compare::operator()(extract(e.value), k);
204 }
205
206 bool
207 operator()(element const& x, element const& y) const
208 {
209 return Compare::operator()(extract(x.value), extract(y.value));
210 }
211
212 Compare&
214 {
215 return *this;
216 }
217
218 Compare const&
219 compare() const
220 {
221 return *this;
222 }
223 };
224
225 using list_type = typename boost::intrusive::
226 make_list<element, boost::intrusive::constant_time_size<false>>::type;
227
228 using cont_type = typename std::conditional<
229 IsMulti,
230 typename boost::intrusive::make_multiset<
231 element,
232 boost::intrusive::constant_time_size<true>,
233 boost::intrusive::compare<KeyValueCompare>>::type,
234 typename boost::intrusive::make_set<
235 element,
236 boost::intrusive::constant_time_size<true>,
237 boost::intrusive::compare<KeyValueCompare>>::type>::type;
238
240 Allocator>::template rebind_alloc<element>;
241
243
245 : private KeyValueCompare,
246 public beast::detail::empty_base_optimization<ElementAllocator>
247 {
248 public:
249 explicit config_t(clock_type& clock_) : clock(clock_)
250 {
251 }
252
253 config_t(clock_type& clock_, Compare const& comp)
254 : KeyValueCompare(comp), clock(clock_)
255 {
256 }
257
258 config_t(clock_type& clock_, Allocator const& alloc_)
260 , clock(clock_)
261 {
262 }
263
265 clock_type& clock_,
266 Compare const& comp,
267 Allocator const& alloc_)
268 : KeyValueCompare(comp)
270 , clock(clock_)
271 {
272 }
273
274 config_t(config_t const& other)
277 ElementAllocatorTraits::select_on_container_copy_construction(
278 other.alloc()))
279 , clock(other.clock)
280 {
281 }
282
283 config_t(config_t const& other, Allocator const& alloc)
286 , clock(other.clock)
287 {
288 }
289
291 : KeyValueCompare(std::move(other.key_compare()))
293 std::move(other))
294 , clock(other.clock)
295 {
296 }
297
298 config_t(config_t&& other, Allocator const& alloc)
299 : KeyValueCompare(std::move(other.key_compare()))
301 , clock(other.clock)
302 {
303 }
304
305 config_t&
306 operator=(config_t const& other)
307 {
308 if (this != &other)
309 {
310 compare() = other.compare();
311 alloc() = other.alloc();
312 clock = other.clock;
313 }
314 return *this;
315 }
316
317 config_t&
319 {
320 compare() = std::move(other.compare());
321 alloc() = std::move(other.alloc());
322 clock = other.clock;
323 return *this;
324 }
325
326 Compare&
328 {
330 }
331
332 Compare const&
333 compare() const
334 {
336 }
337
340 {
341 return *this;
342 }
343
344 KeyValueCompare const&
346 {
347 return *this;
348 }
349
352 {
355 }
356
357 ElementAllocator const&
358 alloc() const
359 {
362 }
363
365 };
366
367 template <class... Args>
368 element*
369 new_element(Args&&... args)
370 {
371 struct Deleter
372 {
374 Deleter(ElementAllocator& a) : a_(a)
375 {
376 }
377
378 void
379 operator()(element* p)
380 {
381 ElementAllocatorTraits::deallocate(a_.get(), p, 1);
382 }
383 };
384
387 Deleter(m_config.alloc()));
389 m_config.alloc(),
390 p.get(),
391 clock().now(),
392 std::forward<Args>(args)...);
393 return p.release();
394 }
395
396 void
398 {
401 m_config.alloc(), const_cast<element*>(p), 1);
402 }
403
404 void
406 {
407 chronological.list.erase(chronological.list.iterator_to(*p));
408 m_cont.erase(m_cont.iterator_to(*p));
410 }
411
412public:
413 using key_compare = Compare;
416 using allocator_type = Allocator;
422
423 // A set iterator (IsMap==false) is always const
424 // because the elements of a set are immutable.
425 using iterator = beast::detail::
426 aged_container_iterator<!IsMap, typename cont_type::iterator>;
427 using const_iterator = beast::detail::
428 aged_container_iterator<true, typename cont_type::iterator>;
429 using reverse_iterator = beast::detail::
430 aged_container_iterator<!IsMap, typename cont_type::reverse_iterator>;
431 using const_reverse_iterator = beast::detail::
432 aged_container_iterator<true, typename cont_type::reverse_iterator>;
433
434 //--------------------------------------------------------------------------
435 //
436 // Chronological ordered iterators
437 //
438 // "Memberspace"
439 // http://accu.org/index.php/journals/1527
440 //
441 //--------------------------------------------------------------------------
442
444 {
445 public:
446 // A set iterator (IsMap==false) is always const
447 // because the elements of a set are immutable.
448 using iterator = beast::detail::
449 aged_container_iterator<!IsMap, typename list_type::iterator>;
450 using const_iterator = beast::detail::
451 aged_container_iterator<true, typename list_type::iterator>;
453 !IsMap,
454 typename list_type::reverse_iterator>;
455 using const_reverse_iterator = beast::detail::
456 aged_container_iterator<true, typename list_type::reverse_iterator>;
457
460 {
461 return iterator(list.begin());
462 }
463
465 begin() const
466 {
467 return const_iterator(list.begin());
468 }
469
471 cbegin() const
472 {
473 return const_iterator(list.begin());
474 }
475
478 {
479 return iterator(list.end());
480 }
481
483 end() const
484 {
485 return const_iterator(list.end());
486 }
487
489 cend() const
490 {
491 return const_iterator(list.end());
492 }
493
496 {
497 return reverse_iterator(list.rbegin());
498 }
499
501 rbegin() const
502 {
503 return const_reverse_iterator(list.rbegin());
504 }
505
507 crbegin() const
508 {
509 return const_reverse_iterator(list.rbegin());
510 }
511
514 {
515 return reverse_iterator(list.rend());
516 }
517
519 rend() const
520 {
521 return const_reverse_iterator(list.rend());
522 }
523
525 crend() const
526 {
527 return const_reverse_iterator(list.rend());
528 }
529
532 {
533 static_assert(
535 "must be standard layout");
536 return list.iterator_to(*reinterpret_cast<element*>(
537 reinterpret_cast<uint8_t*>(&value) -
538 ((std::size_t)std::addressof(((element*)0)->member))));
539 }
540
542 iterator_to(value_type const& value) const
543 {
544 static_assert(
546 "must be standard layout");
547 return list.iterator_to(*reinterpret_cast<element const*>(
548 reinterpret_cast<uint8_t const*>(&value) -
549 ((std::size_t)std::addressof(((element*)0)->member))));
550 }
551
552 private:
554 {
555 }
556
559
563
564 //--------------------------------------------------------------------------
565 //
566 // Construction
567 //
568 //--------------------------------------------------------------------------
569
571
573
575
576 aged_ordered_container(clock_type& clock, Allocator const& alloc);
577
580 Compare const& comp,
581 Allocator const& alloc);
582
583 template <class InputIt>
584 aged_ordered_container(InputIt first, InputIt last, clock_type& clock);
585
586 template <class InputIt>
588 InputIt first,
589 InputIt last,
591 Compare const& comp);
592
593 template <class InputIt>
595 InputIt first,
596 InputIt last,
598 Allocator const& alloc);
599
600 template <class InputIt>
602 InputIt first,
603 InputIt last,
605 Compare const& comp,
606 Allocator const& alloc);
607
609
611 aged_ordered_container const& other,
612 Allocator const& alloc);
613
615
618 Allocator const& alloc);
619
623
627 Compare const& comp);
628
632 Allocator const& alloc);
633
637 Compare const& comp,
638 Allocator const& alloc);
639
641
644
647
650
653 {
654 return m_config.alloc();
655 }
656
659 {
660 return m_config.clock;
661 }
662
663 clock_type const&
664 clock() const
665 {
666 return m_config.clock;
667 }
668
669 //--------------------------------------------------------------------------
670 //
671 // Element access (maps)
672 //
673 //--------------------------------------------------------------------------
674
675 template <
676 class K,
677 bool maybe_multi = IsMulti,
678 bool maybe_map = IsMap,
681 at(K const& k);
682
683 template <
684 class K,
685 bool maybe_multi = IsMulti,
686 bool maybe_map = IsMap,
689 at(K const& k) const;
690
691 template <
692 bool maybe_multi = IsMulti,
693 bool maybe_map = IsMap,
696 operator[](Key const& key);
697
698 template <
699 bool maybe_multi = IsMulti,
700 bool maybe_map = IsMap,
703 operator[](Key&& key);
704
705 //--------------------------------------------------------------------------
706 //
707 // Iterators
708 //
709 //--------------------------------------------------------------------------
710
713 {
714 return iterator(m_cont.begin());
715 }
716
718 begin() const
719 {
720 return const_iterator(m_cont.begin());
721 }
722
724 cbegin() const
725 {
726 return const_iterator(m_cont.begin());
727 }
728
731 {
732 return iterator(m_cont.end());
733 }
734
736 end() const
737 {
738 return const_iterator(m_cont.end());
739 }
740
742 cend() const
743 {
744 return const_iterator(m_cont.end());
745 }
746
749 {
750 return reverse_iterator(m_cont.rbegin());
751 }
752
754 rbegin() const
755 {
756 return const_reverse_iterator(m_cont.rbegin());
757 }
758
760 crbegin() const
761 {
762 return const_reverse_iterator(m_cont.rbegin());
763 }
764
767 {
768 return reverse_iterator(m_cont.rend());
769 }
770
772 rend() const
773 {
774 return const_reverse_iterator(m_cont.rend());
775 }
776
778 crend() const
779 {
780 return const_reverse_iterator(m_cont.rend());
781 }
782
785 {
786 static_assert(
787 std::is_standard_layout<element>::value, "must be standard layout");
788 return m_cont.iterator_to(*reinterpret_cast<element*>(
789 reinterpret_cast<uint8_t*>(&value) -
790 ((std::size_t)std::addressof(((element*)0)->member))));
791 }
792
794 iterator_to(value_type const& value) const
795 {
796 static_assert(
797 std::is_standard_layout<element>::value, "must be standard layout");
798 return m_cont.iterator_to(*reinterpret_cast<element const*>(
799 reinterpret_cast<uint8_t const*>(&value) -
800 ((std::size_t)std::addressof(((element*)0)->member))));
801 }
802
803 //--------------------------------------------------------------------------
804 //
805 // Capacity
806 //
807 //--------------------------------------------------------------------------
808
809 bool
810 empty() const noexcept
811 {
812 return m_cont.empty();
813 }
814
816 size() const noexcept
817 {
818 return m_cont.size();
819 }
820
822 max_size() const noexcept
823 {
824 return m_config.max_size();
825 }
826
827 //--------------------------------------------------------------------------
828 //
829 // Modifiers
830 //
831 //--------------------------------------------------------------------------
832
833 void
835
836 // map, set
837 template <bool maybe_multi = IsMulti>
838 auto
839 insert(value_type const& value) ->
841
842 // multimap, multiset
843 template <bool maybe_multi = IsMulti>
844 auto
845 insert(value_type const& value) ->
847
848 // set
849 template <bool maybe_multi = IsMulti, bool maybe_map = IsMap>
850 auto
851 insert(value_type&& value) -> typename std::enable_if<
852 !maybe_multi && !maybe_map,
854
855 // multiset
856 template <bool maybe_multi = IsMulti, bool maybe_map = IsMap>
857 auto
858 insert(value_type&& value) ->
860
861 //---
862
863 // map, set
864 template <bool maybe_multi = IsMulti>
865 auto
866 insert(const_iterator hint, value_type const& value) ->
868
869 // multimap, multiset
870 template <bool maybe_multi = IsMulti>
872 insert(const_iterator /*hint*/, value_type const& value)
873 {
874 // VFALCO TODO Figure out how to utilize 'hint'
875 return insert(value);
876 }
877
878 // map, set
879 template <bool maybe_multi = IsMulti>
880 auto
883
884 // multimap, multiset
885 template <bool maybe_multi = IsMulti>
888 {
889 // VFALCO TODO Figure out how to utilize 'hint'
890 return insert(std::move(value));
891 }
892
893 // map, multimap
894 template <class P, bool maybe_map = IsMap>
895 typename std::enable_if<
897 typename std::
898 conditional<IsMulti, iterator, std::pair<iterator, bool>>::type>::
899 type
900 insert(P&& value)
901 {
902 return emplace(std::forward<P>(value));
903 }
904
905 // map, multimap
906 template <class P, bool maybe_map = IsMap>
907 typename std::enable_if<
909 typename std::
910 conditional<IsMulti, iterator, std::pair<iterator, bool>>::type>::
911 type
912 insert(const_iterator hint, P&& value)
913 {
914 return emplace_hint(hint, std::forward<P>(value));
915 }
916
917 template <class InputIt>
918 void
919 insert(InputIt first, InputIt last)
920 {
921 for (; first != last; ++first)
922 insert(cend(), *first);
923 }
924
925 void
927 {
928 insert(init.begin(), init.end());
929 }
930
931 // map, set
932 template <bool maybe_multi = IsMulti, class... Args>
933 auto
934 emplace(Args&&... args) ->
936
937 // multiset, multimap
938 template <bool maybe_multi = IsMulti, class... Args>
939 auto
940 emplace(Args&&... args) ->
942
943 // map, set
944 template <bool maybe_multi = IsMulti, class... Args>
945 auto
946 emplace_hint(const_iterator hint, Args&&... args) ->
948
949 // multiset, multimap
950 template <bool maybe_multi = IsMulti, class... Args>
952 emplace_hint(const_iterator /*hint*/, Args&&... args)
953 {
954 // VFALCO TODO Figure out how to utilize 'hint'
955 return emplace<maybe_multi>(std::forward<Args>(args)...);
956 }
957
958 // enable_if prevents erase (reverse_iterator pos) from compiling
959 template <
960 bool is_const,
961 class Iterator,
965
966 // enable_if prevents erase (reverse_iterator first, reverse_iterator last)
967 // from compiling
968 template <
969 bool is_const,
970 class Iterator,
976
977 template <class K>
978 auto
979 erase(K const& k) -> size_type;
980
981 void
982 swap(aged_ordered_container& other) noexcept;
983
984 //--------------------------------------------------------------------------
985
986 // enable_if prevents touch (reverse_iterator pos) from compiling
987 template <
988 bool is_const,
989 class Iterator,
991 void
993 {
994 touch(pos, clock().now());
995 }
996
997 template <class K>
999 touch(K const& k);
1000
1001 //--------------------------------------------------------------------------
1002 //
1003 // Lookup
1004 //
1005 //--------------------------------------------------------------------------
1006
1007 // VFALCO TODO Respect is_transparent (c++14)
1008 template <class K>
1009 size_type
1010 count(K const& k) const
1011 {
1012 return m_cont.count(k, std::cref(m_config.key_compare()));
1013 }
1014
1015 // VFALCO TODO Respect is_transparent (c++14)
1016 template <class K>
1017 iterator
1018 find(K const& k)
1019 {
1020 return iterator(m_cont.find(k, std::cref(m_config.key_compare())));
1021 }
1022
1023 // VFALCO TODO Respect is_transparent (c++14)
1024 template <class K>
1026 find(K const& k) const
1027 {
1028 return const_iterator(
1029 m_cont.find(k, std::cref(m_config.key_compare())));
1030 }
1031
1032 // VFALCO TODO Respect is_transparent (c++14)
1033 template <class K>
1035 equal_range(K const& k)
1036 {
1037 auto const r(m_cont.equal_range(k, std::cref(m_config.key_compare())));
1038 return std::make_pair(iterator(r.first), iterator(r.second));
1039 }
1040
1041 // VFALCO TODO Respect is_transparent (c++14)
1042 template <class K>
1044 equal_range(K const& k) const
1045 {
1046 auto const r(m_cont.equal_range(k, std::cref(m_config.key_compare())));
1047 return std::make_pair(
1048 const_iterator(r.first), const_iterator(r.second));
1049 }
1050
1051 // VFALCO TODO Respect is_transparent (c++14)
1052 template <class K>
1053 iterator
1054 lower_bound(K const& k)
1055 {
1056 return iterator(
1057 m_cont.lower_bound(k, std::cref(m_config.key_compare())));
1058 }
1059
1060 // VFALCO TODO Respect is_transparent (c++14)
1061 template <class K>
1063 lower_bound(K const& k) const
1064 {
1065 return const_iterator(
1066 m_cont.lower_bound(k, std::cref(m_config.key_compare())));
1067 }
1068
1069 // VFALCO TODO Respect is_transparent (c++14)
1070 template <class K>
1071 iterator
1072 upper_bound(K const& k)
1073 {
1074 return iterator(
1075 m_cont.upper_bound(k, std::cref(m_config.key_compare())));
1076 }
1077
1078 // VFALCO TODO Respect is_transparent (c++14)
1079 template <class K>
1081 upper_bound(K const& k) const
1082 {
1083 return const_iterator(
1084 m_cont.upper_bound(k, std::cref(m_config.key_compare())));
1085 }
1086
1087 //--------------------------------------------------------------------------
1088 //
1089 // Observers
1090 //
1091 //--------------------------------------------------------------------------
1092
1094 key_comp() const
1095 {
1096 return m_config.compare();
1097 }
1098
1099 // VFALCO TODO Should this return const reference for set?
1102 {
1103 return value_compare(m_config.compare());
1104 }
1105
1106 //--------------------------------------------------------------------------
1107 //
1108 // Comparison
1109 //
1110 //--------------------------------------------------------------------------
1111
1112 // This differs from the standard in that the comparison
1113 // is only done on the key portion of the value type, ignoring
1114 // the mapped type.
1115 //
1116 template <
1117 bool OtherIsMulti,
1118 bool OtherIsMap,
1119 class OtherT,
1120 class OtherDuration,
1121 class OtherAllocator>
1122 bool
1124 OtherIsMulti,
1125 OtherIsMap,
1126 Key,
1127 OtherT,
1128 OtherDuration,
1129 Compare,
1130 OtherAllocator> const& other) const;
1131
1132 template <
1133 bool OtherIsMulti,
1134 bool OtherIsMap,
1135 class OtherT,
1136 class OtherDuration,
1137 class OtherAllocator>
1138 bool
1140 OtherIsMulti,
1141 OtherIsMap,
1142 Key,
1143 OtherT,
1144 OtherDuration,
1145 Compare,
1146 OtherAllocator> const& other) const
1147 {
1148 return !(this->operator==(other));
1149 }
1150
1151 template <
1152 bool OtherIsMulti,
1153 bool OtherIsMap,
1154 class OtherT,
1155 class OtherDuration,
1156 class OtherAllocator>
1157 bool
1159 OtherIsMulti,
1160 OtherIsMap,
1161 Key,
1162 OtherT,
1163 OtherDuration,
1164 Compare,
1165 OtherAllocator> const& other) const
1166 {
1167 value_compare const comp(value_comp());
1169 cbegin(), cend(), other.cbegin(), other.cend(), comp);
1170 }
1171
1172 template <
1173 bool OtherIsMulti,
1174 bool OtherIsMap,
1175 class OtherT,
1176 class OtherDuration,
1177 class OtherAllocator>
1178 bool
1180 OtherIsMulti,
1181 OtherIsMap,
1182 Key,
1183 OtherT,
1184 OtherDuration,
1185 Compare,
1186 OtherAllocator> const& other) const
1187 {
1188 return !(other < *this);
1189 }
1190
1191 template <
1192 bool OtherIsMulti,
1193 bool OtherIsMap,
1194 class OtherT,
1195 class OtherDuration,
1196 class OtherAllocator>
1197 bool
1199 OtherIsMulti,
1200 OtherIsMap,
1201 Key,
1202 OtherT,
1203 OtherDuration,
1204 Compare,
1205 OtherAllocator> const& other) const
1206 {
1207 return other < *this;
1208 }
1209
1210 template <
1211 bool OtherIsMulti,
1212 bool OtherIsMap,
1213 class OtherT,
1214 class OtherDuration,
1215 class OtherAllocator>
1216 bool
1218 OtherIsMulti,
1219 OtherIsMap,
1220 Key,
1221 OtherT,
1222 OtherDuration,
1223 Compare,
1224 OtherAllocator> const& other) const
1225 {
1226 return !(*this < other);
1227 }
1228
1229private:
1230 // enable_if prevents erase (reverse_iterator pos, now) from compiling
1231 template <
1232 bool is_const,
1233 class Iterator,
1235 void
1238 typename clock_type::time_point const& now);
1239
1240 template <
1241 bool maybe_propagate = std::allocator_traits<
1242 Allocator>::propagate_on_container_swap::value>
1245
1246 template <
1247 bool maybe_propagate = std::allocator_traits<
1248 Allocator>::propagate_on_container_swap::value>
1251
1252private:
1255};
1256
1257//------------------------------------------------------------------------------
1258
1259template <
1260 bool IsMulti,
1261 bool IsMap,
1262 class Key,
1263 class T,
1264 class Clock,
1265 class Compare,
1266 class Allocator>
1269 : m_config(clock)
1270{
1271}
1272
1273template <
1274 bool IsMulti,
1275 bool IsMap,
1276 class Key,
1277 class T,
1278 class Clock,
1279 class Compare,
1280 class Allocator>
1282 aged_ordered_container(clock_type& clock, Compare const& comp)
1283 : m_config(clock, comp), m_cont(comp)
1284{
1285}
1286
1287template <
1288 bool IsMulti,
1289 bool IsMap,
1290 class Key,
1291 class T,
1292 class Clock,
1293 class Compare,
1294 class Allocator>
1296 aged_ordered_container(clock_type& clock, Allocator const& alloc)
1297 : m_config(clock, alloc)
1298{
1299}
1300
1301template <
1302 bool IsMulti,
1303 bool IsMap,
1304 class Key,
1305 class T,
1306 class Clock,
1307 class Compare,
1308 class Allocator>
1311 clock_type& clock,
1312 Compare const& comp,
1313 Allocator const& alloc)
1314 : m_config(clock, comp, alloc), m_cont(comp)
1315{
1316}
1317
1318template <
1319 bool IsMulti,
1320 bool IsMap,
1321 class Key,
1322 class T,
1323 class Clock,
1324 class Compare,
1325 class Allocator>
1326template <class InputIt>
1328 aged_ordered_container(InputIt first, InputIt last, clock_type& clock)
1329 : m_config(clock)
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 Compare const& comp)
1349 : m_config(clock, comp), m_cont(comp)
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 Allocator const& alloc)
1369 : m_config(clock, alloc)
1370{
1371 insert(first, last);
1372}
1373
1374template <
1375 bool IsMulti,
1376 bool IsMap,
1377 class Key,
1378 class T,
1379 class Clock,
1380 class Compare,
1381 class Allocator>
1382template <class InputIt>
1385 InputIt first,
1386 InputIt last,
1387 clock_type& clock,
1388 Compare const& comp,
1389 Allocator const& alloc)
1390 : m_config(clock, comp, alloc), m_cont(comp)
1391{
1392 insert(first, last);
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 : m_config(other.m_config)
1406#if BOOST_VERSION >= 108000
1407 , m_cont(other.m_cont.get_comp())
1408#else
1409 , m_cont(other.m_cont.comp())
1410#endif
1411{
1412 insert(other.cbegin(), other.cend());
1413}
1414
1415template <
1416 bool IsMulti,
1417 bool IsMap,
1418 class Key,
1419 class T,
1420 class Clock,
1421 class Compare,
1422 class Allocator>
1425 aged_ordered_container const& other,
1426 Allocator const& alloc)
1427 : m_config(other.m_config, alloc)
1428#if BOOST_VERSION >= 108000
1429 , m_cont(other.m_cont.get_comp())
1430#else
1431 , m_cont(other.m_cont.comp())
1432#endif
1433{
1434 insert(other.cbegin(), other.cend());
1435}
1436
1437template <
1438 bool IsMulti,
1439 bool IsMap,
1440 class Key,
1441 class T,
1442 class Clock,
1443 class Compare,
1444 class Allocator>
1447 : m_config(std::move(other.m_config)), m_cont(std::move(other.m_cont))
1448{
1449 chronological.list = std::move(other.chronological.list);
1450}
1451
1452template <
1453 bool IsMulti,
1454 bool IsMap,
1455 class Key,
1456 class T,
1457 class Clock,
1458 class Compare,
1459 class Allocator>
1462 aged_ordered_container&& other,
1463 Allocator const& alloc)
1464 : m_config(std::move(other.m_config), alloc)
1465#if BOOST_VERSION >= 108000
1466 , m_cont(std::move(other.m_cont.get_comp()))
1467#else
1468 , m_cont(std::move(other.m_cont.comp()))
1469#endif
1470
1471{
1472 insert(other.cbegin(), other.cend());
1473 other.clear();
1474}
1475
1476template <
1477 bool IsMulti,
1478 bool IsMap,
1479 class Key,
1480 class T,
1481 class Clock,
1482 class Compare,
1483 class Allocator>
1487 clock_type& clock)
1488 : m_config(clock)
1489{
1490 insert(init.begin(), init.end());
1491}
1492
1493template <
1494 bool IsMulti,
1495 bool IsMap,
1496 class Key,
1497 class T,
1498 class Clock,
1499 class Compare,
1500 class Allocator>
1504 clock_type& clock,
1505 Compare const& comp)
1506 : m_config(clock, comp), m_cont(comp)
1507{
1508 insert(init.begin(), init.end());
1509}
1510
1511template <
1512 bool IsMulti,
1513 bool IsMap,
1514 class Key,
1515 class T,
1516 class Clock,
1517 class Compare,
1518 class Allocator>
1522 clock_type& clock,
1523 Allocator const& alloc)
1524 : m_config(clock, alloc)
1525{
1526 insert(init.begin(), init.end());
1527}
1528
1529template <
1530 bool IsMulti,
1531 bool IsMap,
1532 class Key,
1533 class T,
1534 class Clock,
1535 class Compare,
1536 class Allocator>
1540 clock_type& clock,
1541 Compare const& comp,
1542 Allocator const& alloc)
1543 : m_config(clock, comp, alloc), m_cont(comp)
1544{
1545 insert(init.begin(), init.end());
1546}
1547
1548template <
1549 bool IsMulti,
1550 bool IsMap,
1551 class Key,
1552 class T,
1553 class Clock,
1554 class Compare,
1555 class Allocator>
1558{
1559 clear();
1560}
1561
1562template <
1563 bool IsMulti,
1564 bool IsMap,
1565 class Key,
1566 class T,
1567 class Clock,
1568 class Compare,
1569 class Allocator>
1570auto
1573{
1574 if (this != &other)
1575 {
1576 clear();
1577 this->m_config = other.m_config;
1578 insert(other.begin(), other.end());
1579 }
1580 return *this;
1581}
1582
1583template <
1584 bool IsMulti,
1585 bool IsMap,
1586 class Key,
1587 class T,
1588 class Clock,
1589 class Compare,
1590 class Allocator>
1591auto
1594{
1595 clear();
1596 this->m_config = std::move(other.m_config);
1597 insert(other.begin(), other.end());
1598 other.clear();
1599 return *this;
1600}
1601
1602template <
1603 bool IsMulti,
1604 bool IsMap,
1605 class Key,
1606 class T,
1607 class Clock,
1608 class Compare,
1609 class Allocator>
1610auto
1613{
1614 clear();
1615 insert(init);
1616 return *this;
1617}
1618
1619//------------------------------------------------------------------------------
1620
1621template <
1622 bool IsMulti,
1623 bool IsMap,
1624 class Key,
1625 class T,
1626 class Clock,
1627 class Compare,
1628 class Allocator>
1629template <class K, bool maybe_multi, bool maybe_map, class>
1632 K const& k)
1633{
1634 auto const iter(m_cont.find(k, std::cref(m_config.key_compare())));
1635 if (iter == m_cont.end())
1636 throw std::out_of_range("key not found");
1637 return iter->value.second;
1638}
1639
1640template <
1641 bool IsMulti,
1642 bool IsMap,
1643 class Key,
1644 class T,
1645 class Clock,
1646 class Compare,
1647 class Allocator>
1648template <class K, bool maybe_multi, bool maybe_map, class>
1651 K const& k) const
1652{
1653 auto const iter(m_cont.find(k, std::cref(m_config.key_compare())));
1654 if (iter == m_cont.end())
1655 throw std::out_of_range("key not found");
1656 return iter->value.second;
1657}
1658
1659template <
1660 bool IsMulti,
1661 bool IsMap,
1662 class Key,
1663 class T,
1664 class Clock,
1665 class Compare,
1666 class Allocator>
1667template <bool maybe_multi, bool maybe_map, class>
1670operator[](Key const& key)
1671{
1672 typename cont_type::insert_commit_data d;
1673 auto const result(
1674 m_cont.insert_check(key, std::cref(m_config.key_compare()), d));
1675 if (result.second)
1676 {
1677 element* const p(new_element(
1681 m_cont.insert_commit(*p, d);
1682 chronological.list.push_back(*p);
1683 return p->value.second;
1684 }
1685 return result.first->value.second;
1686}
1687
1688template <
1689 bool IsMulti,
1690 bool IsMap,
1691 class Key,
1692 class T,
1693 class Clock,
1694 class Compare,
1695 class Allocator>
1696template <bool maybe_multi, bool maybe_map, class>
1699operator[](Key&& key)
1700{
1701 typename cont_type::insert_commit_data d;
1702 auto const result(
1703 m_cont.insert_check(key, std::cref(m_config.key_compare()), d));
1704 if (result.second)
1705 {
1706 element* const p(new_element(
1708 std::forward_as_tuple(std::move(key)),
1710 m_cont.insert_commit(*p, d);
1711 chronological.list.push_back(*p);
1712 return p->value.second;
1713 }
1714 return result.first->value.second;
1715}
1716
1717//------------------------------------------------------------------------------
1718
1719template <
1720 bool IsMulti,
1721 bool IsMap,
1722 class Key,
1723 class T,
1724 class Clock,
1725 class Compare,
1726 class Allocator>
1727void
1729 clear()
1730{
1731 for (auto iter(chronological.list.begin());
1732 iter != chronological.list.end();)
1733 delete_element(&*iter++);
1734 chronological.list.clear();
1735 m_cont.clear();
1736}
1737
1738// map, set
1739template <
1740 bool IsMulti,
1741 bool IsMap,
1742 class Key,
1743 class T,
1744 class Clock,
1745 class Compare,
1746 class Allocator>
1747template <bool maybe_multi>
1748auto
1750 insert(value_type const& value) ->
1752{
1753 typename cont_type::insert_commit_data d;
1754 auto const result(m_cont.insert_check(
1755 extract(value), std::cref(m_config.key_compare()), d));
1756 if (result.second)
1757 {
1758 element* const p(new_element(value));
1759 auto const iter(m_cont.insert_commit(*p, d));
1760 chronological.list.push_back(*p);
1761 return std::make_pair(iterator(iter), true);
1762 }
1763 return std::make_pair(iterator(result.first), false);
1764}
1765
1766// multimap, multiset
1767template <
1768 bool IsMulti,
1769 bool IsMap,
1770 class Key,
1771 class T,
1772 class Clock,
1773 class Compare,
1774 class Allocator>
1775template <bool maybe_multi>
1776auto
1778 insert(value_type const& value) ->
1780{
1781 auto const before(
1782 m_cont.upper_bound(extract(value), std::cref(m_config.key_compare())));
1783 element* const p(new_element(value));
1784 chronological.list.push_back(*p);
1785 auto const iter(m_cont.insert_before(before, *p));
1786 return iterator(iter);
1787}
1788
1789// set
1790template <
1791 bool IsMulti,
1792 bool IsMap,
1793 class Key,
1794 class T,
1795 class Clock,
1796 class Compare,
1797 class Allocator>
1798template <bool maybe_multi, bool maybe_map>
1799auto
1801 insert(value_type&& value) ->
1802 typename std::
1803 enable_if<!maybe_multi && !maybe_map, std::pair<iterator, bool>>::type
1804{
1805 typename cont_type::insert_commit_data d;
1806 auto const result(m_cont.insert_check(
1807 extract(value), std::cref(m_config.key_compare()), d));
1808 if (result.second)
1809 {
1810 element* const p(new_element(std::move(value)));
1811 auto const iter(m_cont.insert_commit(*p, d));
1812 chronological.list.push_back(*p);
1813 return std::make_pair(iterator(iter), true);
1814 }
1815 return std::make_pair(iterator(result.first), false);
1816}
1817
1818// multiset
1819template <
1820 bool IsMulti,
1821 bool IsMap,
1822 class Key,
1823 class T,
1824 class Clock,
1825 class Compare,
1826 class Allocator>
1827template <bool maybe_multi, bool maybe_map>
1828auto
1830 insert(value_type&& value) ->
1832{
1833 auto const before(
1834 m_cont.upper_bound(extract(value), std::cref(m_config.key_compare())));
1835 element* const p(new_element(std::move(value)));
1836 chronological.list.push_back(*p);
1837 auto const iter(m_cont.insert_before(before, *p));
1838 return iterator(iter);
1839}
1840
1841//---
1842
1843// map, set
1844template <
1845 bool IsMulti,
1846 bool IsMap,
1847 class Key,
1848 class T,
1849 class Clock,
1850 class Compare,
1851 class Allocator>
1852template <bool maybe_multi>
1853auto
1855 insert(const_iterator hint, value_type const& value) ->
1857{
1858 typename cont_type::insert_commit_data d;
1859 auto const result(m_cont.insert_check(
1860 hint.iterator(), extract(value), std::cref(m_config.key_compare()), d));
1861 if (result.second)
1862 {
1863 element* const p(new_element(value));
1864 auto const iter(m_cont.insert_commit(*p, d));
1865 chronological.list.push_back(*p);
1866 return iterator(iter);
1867 }
1868 return iterator(result.first);
1869}
1870
1871// map, set
1872template <
1873 bool IsMulti,
1874 bool IsMap,
1875 class Key,
1876 class T,
1877 class Clock,
1878 class Compare,
1879 class Allocator>
1880template <bool maybe_multi>
1881auto
1883 insert(const_iterator hint, value_type&& value) ->
1885{
1886 typename cont_type::insert_commit_data d;
1887 auto const result(m_cont.insert_check(
1888 hint.iterator(), extract(value), std::cref(m_config.key_compare()), d));
1889 if (result.second)
1890 {
1891 element* const p(new_element(std::move(value)));
1892 auto const iter(m_cont.insert_commit(*p, d));
1893 chronological.list.push_back(*p);
1894 return iterator(iter);
1895 }
1896 return iterator(result.first);
1897}
1898
1899// map, set
1900template <
1901 bool IsMulti,
1902 bool IsMap,
1903 class Key,
1904 class T,
1905 class Clock,
1906 class Compare,
1907 class Allocator>
1908template <bool maybe_multi, class... Args>
1909auto
1911 emplace(Args&&... args) ->
1913{
1914 // VFALCO NOTE Its unfortunate that we need to
1915 // construct element here
1916 element* const p(new_element(std::forward<Args>(args)...));
1917 typename cont_type::insert_commit_data d;
1918 auto const result(m_cont.insert_check(
1919 extract(p->value), std::cref(m_config.key_compare()), d));
1920 if (result.second)
1921 {
1922 auto const iter(m_cont.insert_commit(*p, d));
1923 chronological.list.push_back(*p);
1924 return std::make_pair(iterator(iter), true);
1925 }
1926 delete_element(p);
1927 return std::make_pair(iterator(result.first), false);
1928}
1929
1930// multiset, multimap
1931template <
1932 bool IsMulti,
1933 bool IsMap,
1934 class Key,
1935 class T,
1936 class Clock,
1937 class Compare,
1938 class Allocator>
1939template <bool maybe_multi, class... Args>
1940auto
1942 emplace(Args&&... args) ->
1944{
1945 element* const p(new_element(std::forward<Args>(args)...));
1946 auto const before(m_cont.upper_bound(
1947 extract(p->value), std::cref(m_config.key_compare())));
1948 chronological.list.push_back(*p);
1949 auto const iter(m_cont.insert_before(before, *p));
1950 return iterator(iter);
1951}
1952
1953// map, set
1954template <
1955 bool IsMulti,
1956 bool IsMap,
1957 class Key,
1958 class T,
1959 class Clock,
1960 class Compare,
1961 class Allocator>
1962template <bool maybe_multi, class... Args>
1963auto
1965 emplace_hint(const_iterator hint, Args&&... args) ->
1967{
1968 // VFALCO NOTE Its unfortunate that we need to
1969 // construct element here
1970 element* const p(new_element(std::forward<Args>(args)...));
1971 typename cont_type::insert_commit_data d;
1972 auto const result(m_cont.insert_check(
1973 hint.iterator(),
1974 extract(p->value),
1975 std::cref(m_config.key_compare()),
1976 d));
1977 if (result.second)
1978 {
1979 auto const iter(m_cont.insert_commit(*p, d));
1980 chronological.list.push_back(*p);
1981 return std::make_pair(iterator(iter), true);
1982 }
1983 delete_element(p);
1984 return std::make_pair(iterator(result.first), false);
1985}
1986
1987template <
1988 bool IsMulti,
1989 bool IsMap,
1990 class Key,
1991 class T,
1992 class Clock,
1993 class Compare,
1994 class Allocator>
1995template <bool is_const, class Iterator, class>
1999{
2000 unlink_and_delete_element(&*((pos++).iterator()));
2002 pos.iterator());
2003}
2004
2005template <
2006 bool IsMulti,
2007 bool IsMap,
2008 class Key,
2009 class T,
2010 class Clock,
2011 class Compare,
2012 class Allocator>
2013template <bool is_const, class Iterator, class>
2016 erase(
2019{
2020 for (; first != last;)
2021 unlink_and_delete_element(&*((first++).iterator()));
2022
2024 first.iterator());
2025}
2026
2027template <
2028 bool IsMulti,
2029 bool IsMap,
2030 class Key,
2031 class T,
2032 class Clock,
2033 class Compare,
2034 class Allocator>
2035template <class K>
2036auto
2038 erase(K const& k) -> size_type
2039{
2040 auto iter(m_cont.find(k, std::cref(m_config.key_compare())));
2041 if (iter == m_cont.end())
2042 return 0;
2043 size_type n(0);
2044 for (;;)
2045 {
2046 auto p(&*iter++);
2047 bool const done(m_config(*p, extract(iter->value)));
2048 unlink_and_delete_element(p);
2049 ++n;
2050 if (done)
2051 break;
2052 }
2053 return n;
2054}
2055
2056template <
2057 bool IsMulti,
2058 bool IsMap,
2059 class Key,
2060 class T,
2061 class Clock,
2062 class Compare,
2063 class Allocator>
2064void
2066 aged_ordered_container& other) noexcept
2067{
2068 swap_data(other);
2069 std::swap(chronological, other.chronological);
2070 std::swap(m_cont, other.m_cont);
2071}
2072
2073//------------------------------------------------------------------------------
2074
2075template <
2076 bool IsMulti,
2077 bool IsMap,
2078 class Key,
2079 class T,
2080 class Clock,
2081 class Compare,
2082 class Allocator>
2083template <class K>
2084auto
2086 touch(K const& k) -> size_type
2087{
2088 auto const now(clock().now());
2089 size_type n(0);
2090 auto const range(equal_range(k));
2091 for (auto iter : range)
2092 {
2093 touch(iter, now);
2094 ++n;
2095 }
2096 return n;
2097}
2098
2099//------------------------------------------------------------------------------
2100
2101template <
2102 bool IsMulti,
2103 bool IsMap,
2104 class Key,
2105 class T,
2106 class Clock,
2107 class Compare,
2108 class Allocator>
2109template <
2110 bool OtherIsMulti,
2111 bool OtherIsMap,
2112 class OtherT,
2113 class OtherDuration,
2114 class OtherAllocator>
2115bool
2118 OtherIsMulti,
2119 OtherIsMap,
2120 Key,
2121 OtherT,
2122 OtherDuration,
2123 Compare,
2124 OtherAllocator> const& other) const
2125{
2126 using Other = aged_ordered_container<
2127 OtherIsMulti,
2128 OtherIsMap,
2129 Key,
2130 OtherT,
2131 OtherDuration,
2132 Compare,
2133 OtherAllocator>;
2134 if (size() != other.size())
2135 return false;
2137 return std::equal(
2138 cbegin(),
2139 cend(),
2140 other.cbegin(),
2141 other.cend(),
2142 [&eq, &other](
2143 value_type const& lhs, typename Other::value_type const& rhs) {
2144 return eq(extract(lhs), other.extract(rhs));
2145 });
2146}
2147
2148//------------------------------------------------------------------------------
2149
2150template <
2151 bool IsMulti,
2152 bool IsMap,
2153 class Key,
2154 class T,
2155 class Clock,
2156 class Compare,
2157 class Allocator>
2158template <bool is_const, class Iterator, class>
2159void
2161 touch(
2163 typename clock_type::time_point const& now)
2164{
2165 auto& e(*pos.iterator());
2166 e.when = now;
2167 chronological.list.erase(chronological.list.iterator_to(e));
2168 chronological.list.push_back(e);
2169}
2170
2171template <
2172 bool IsMulti,
2173 bool IsMap,
2174 class Key,
2175 class T,
2176 class Clock,
2177 class Compare,
2178 class Allocator>
2179template <bool maybe_propagate>
2182 swap_data(aged_ordered_container& other) noexcept
2183{
2184 std::swap(m_config.key_compare(), other.m_config.key_compare());
2185 std::swap(m_config.alloc(), other.m_config.alloc());
2186 std::swap(m_config.clock, other.m_config.clock);
2187}
2188
2189template <
2190 bool IsMulti,
2191 bool IsMap,
2192 class Key,
2193 class T,
2194 class Clock,
2195 class Compare,
2196 class Allocator>
2197template <bool maybe_propagate>
2200 swap_data(aged_ordered_container& other) noexcept
2201{
2202 std::swap(m_config.key_compare(), other.m_config.key_compare());
2203 std::swap(m_config.clock, other.m_config.clock);
2204}
2205
2206} // namespace detail
2207
2208//------------------------------------------------------------------------------
2209
2210template <
2211 bool IsMulti,
2212 bool IsMap,
2213 class Key,
2214 class T,
2215 class Clock,
2216 class Compare,
2217 class Allocator>
2219 IsMulti,
2220 IsMap,
2221 Key,
2222 T,
2223 Clock,
2224 Compare,
2225 Allocator>> : std::true_type
2226{
2227 explicit is_aged_container() = default;
2228};
2229
2230// Free functions
2231
2232template <
2233 bool IsMulti,
2234 bool IsMap,
2235 class Key,
2236 class T,
2237 class Clock,
2238 class Compare,
2239 class Allocator>
2240void
2243 IsMulti,
2244 IsMap,
2245 Key,
2246 T,
2247 Clock,
2248 Compare,
2249 Allocator>& lhs,
2251 IsMulti,
2252 IsMap,
2253 Key,
2254 T,
2255 Clock,
2256 Compare,
2257 Allocator>& rhs) noexcept
2258{
2259 lhs.swap(rhs);
2260}
2261
2263template <
2264 bool IsMulti,
2265 bool IsMap,
2266 class Key,
2267 class T,
2268 class Clock,
2269 class Compare,
2270 class Allocator,
2271 class Rep,
2272 class Period>
2276 IsMulti,
2277 IsMap,
2278 Key,
2279 T,
2280 Clock,
2281 Compare,
2282 Allocator>& c,
2284{
2285 std::size_t n(0);
2286 auto const expired(c.clock().now() - age);
2287 for (auto iter(c.chronological.cbegin());
2288 iter != c.chronological.cend() && iter.when() <= expired;)
2289 {
2290 iter = c.erase(iter);
2291 ++n;
2292 }
2293 return n;
2294}
2295
2296} // namespace beast
2297
2298#endif
T addressof(T... args)
T allocate(T... args)
Abstract interface to a clock.
typename Clock::time_point time_point
typename Clock::duration duration
bool operator()(element const &e, Key const &k) const
bool operator()(element const &x, element const &y) const
bool operator()(Key const &k, element const &e) const
const_iterator iterator_to(value_type const &value) const
beast::detail::aged_container_iterator<!IsMap, typename list_type::iterator > iterator
beast::detail::aged_container_iterator< !IsMap, typename list_type::reverse_iterator > reverse_iterator
beast::detail::aged_container_iterator< true, typename list_type::reverse_iterator > const_reverse_iterator
beast::detail::aged_container_iterator< true, typename list_type::iterator > const_iterator
config_t(config_t const &other, Allocator const &alloc)
config_t(clock_type &clock_, Allocator const &alloc_)
config_t(clock_type &clock_, Compare const &comp, Allocator const &alloc_)
config_t(config_t &&other, Allocator const &alloc)
config_t(clock_type &clock_, Compare const &comp)
bool operator()(value_type const &lhs, value_type const &rhs) const
Associative container where each element is also indexed by time.
std::conditional< IsMap, T, void * >::type & operator[](Key const &key)
aged_ordered_container(aged_ordered_container &&other, Allocator const &alloc)
std::enable_if< maybe_multi, iterator >::type emplace_hint(const_iterator, Args &&... args)
typename std::allocator_traits< Allocator >::const_pointer const_pointer
aged_ordered_container(aged_ordered_container &&other)
auto insert(const_iterator hint, value_type const &value) -> typename std::enable_if<!maybe_multi, iterator >::type
std::conditional< IsMap, T, void * >::type & at(K const &k)
typename std::allocator_traits< Allocator >::pointer pointer
aged_ordered_container & operator=(std::initializer_list< value_type > init)
auto insert(value_type const &value) -> typename std::enable_if< maybe_multi, iterator >::type
const_iterator find(K const &k) const
typename std::conditional< IsMap, pair_value_compare, Compare >::type value_compare
void swap(aged_ordered_container &other) noexcept
beast::detail::aged_container_iterator< false, Iterator > erase(beast::detail::aged_container_iterator< is_const, Iterator > pos)
const_reverse_iterator rbegin() const
beast::detail::aged_container_iterator< true, typename cont_type::reverse_iterator > const_reverse_iterator
aged_ordered_container(clock_type &clock, Compare const &comp)
aged_ordered_container(aged_ordered_container const &other, Allocator const &alloc)
aged_ordered_container(std::initializer_list< value_type > init, clock_type &clock, Compare const &comp, Allocator const &alloc)
aged_ordered_container(std::initializer_list< value_type > init, clock_type &clock, Allocator const &alloc)
bool operator<=(aged_ordered_container< OtherIsMulti, OtherIsMap, Key, OtherT, OtherDuration, Compare, OtherAllocator > const &other) const
aged_ordered_container(std::initializer_list< value_type > init, clock_type &clock)
aged_ordered_container & operator=(aged_ordered_container const &other)
aged_ordered_container(InputIt first, InputIt last, clock_type &clock, Allocator const &alloc)
bool operator>(aged_ordered_container< OtherIsMulti, OtherIsMap, Key, OtherT, OtherDuration, Compare, OtherAllocator > const &other) const
auto insert(value_type &&value) -> typename std::enable_if< !maybe_multi &&!maybe_map, std::pair< iterator, bool > >::type
void insert(InputIt first, InputIt last)
const_reverse_iterator crend() const
std::pair< iterator, iterator > equal_range(K const &k)
bool operator==(aged_ordered_container< OtherIsMulti, OtherIsMap, Key, OtherT, OtherDuration, Compare, OtherAllocator > const &other) const
aged_ordered_container(clock_type &clock, Compare const &comp, Allocator const &alloc)
std::enable_if< maybe_map &&std::is_constructible< value_type, P && >::value, typenamestd::conditional< IsMulti, iterator, std::pair< iterator, bool > >::type >::type insert(P &&value)
void insert(std::initializer_list< value_type > init)
aged_ordered_container(aged_ordered_container const &other)
aged_ordered_container(std::initializer_list< value_type > init, clock_type &clock, Compare const &comp)
std::enable_if< maybe_map &&std::is_constructible< value_type, P && >::value, typenamestd::conditional< IsMulti, iterator, std::pair< iterator, bool > >::type >::type insert(const_iterator hint, P &&value)
const_iterator lower_bound(K const &k) const
typename std::conditional< IsMulti, typename boost::intrusive::make_multiset< element, boost::intrusive::constant_time_size< true >, boost::intrusive::compare< KeyValueCompare > >::type, typename boost::intrusive::make_set< element, boost::intrusive::constant_time_size< true >, boost::intrusive::compare< KeyValueCompare > >::type >::type cont_type
const_iterator upper_bound(K const &k) const
bool operator!=(aged_ordered_container< OtherIsMulti, OtherIsMap, Key, OtherT, OtherDuration, Compare, OtherAllocator > const &other) const
const_iterator iterator_to(value_type const &value) const
std::enable_if< maybe_propagate >::type swap_data(aged_ordered_container &other) noexcept
typename std::allocator_traits< Allocator >::template rebind_alloc< element > ElementAllocator
auto insert(value_type &&value) -> typename std::enable_if< maybe_multi &&!maybe_map, iterator >::type
auto insert(value_type const &value) -> typename std::enable_if<!maybe_multi, std::pair< iterator, bool > >::type
beast::detail::aged_container_iterator< false, Iterator > erase(beast::detail::aged_container_iterator< is_const, Iterator > first, beast::detail::aged_container_iterator< is_const, Iterator > last)
std::enable_if< maybe_multi, iterator >::type insert(const_iterator, value_type const &value)
auto emplace(Args &&... args) -> typename std::enable_if< maybe_multi, iterator >::type
bool operator<(aged_ordered_container< OtherIsMulti, OtherIsMap, Key, OtherT, OtherDuration, Compare, OtherAllocator > const &other) const
typename clock_type::duration duration
auto insert(const_iterator hint, value_type &&value) -> typename std::enable_if<!maybe_multi, iterator >::type
void touch(beast::detail::aged_container_iterator< is_const, Iterator > pos, typename clock_type::time_point const &now)
beast::detail::aged_container_iterator<!IsMap, typename cont_type::iterator > iterator
beast::detail::aged_container_iterator< true, typename cont_type::iterator > const_iterator
void touch(beast::detail::aged_container_iterator< is_const, Iterator > pos)
class beast::detail::aged_ordered_container::chronological_t chronological
aged_ordered_container(clock_type &clock, Allocator const &alloc)
aged_ordered_container(InputIt first, InputIt last, clock_type &clock, Compare const &comp)
aged_ordered_container(InputIt first, InputIt last, clock_type &clock, Compare const &comp, Allocator const &alloc)
aged_ordered_container & operator=(aged_ordered_container &&other)
std::enable_if< maybe_multi, iterator >::type insert(const_iterator, value_type &&value)
bool operator>=(aged_ordered_container< OtherIsMulti, OtherIsMap, Key, OtherT, OtherDuration, Compare, OtherAllocator > const &other) const
typename boost::intrusive::make_list< element, boost::intrusive::constant_time_size< false > >::type list_type
const_reverse_iterator crbegin() const
auto emplace_hint(const_iterator hint, Args &&... args) -> typename std::enable_if<!maybe_multi, std::pair< iterator, bool > >::type
std::conditional< IsMap, T, void * >::type const & at(K const &k) const
aged_ordered_container(InputIt first, InputIt last, clock_type &clock)
typename std::conditional< IsMap, std::pair< Key const, T >, Key >::type value_type
auto emplace(Args &&... args) -> typename std::enable_if<!maybe_multi, std::pair< iterator, bool > >::type
std::conditional< IsMap, T, void * >::type & operator[](Key &&key)
beast::detail::aged_container_iterator<!IsMap, typename cont_type::reverse_iterator > reverse_iterator
static Key const & extract(value_type const &value)
std::pair< const_iterator, const_iterator > equal_range(K const &k) const
typename clock_type::time_point time_point
T construct(T... args)
T deallocate(T... args)
T destroy(T... args)
T equal(T... args)
T forward_as_tuple(T... args)
T lexicographical_compare(T... args)
T make_pair(T... args)
int compare(SemanticVersion const &lhs, SemanticVersion const &rhs)
Compare two SemanticVersions against each other.
std::enable_if< is_aged_container< AgedContainer >::value, std::size_t >::type expire(AgedContainer &c, std::chrono::duration< Rep, Period > const &age)
Expire aged container items past the specified age.
void swap(beast::detail::aged_ordered_container< IsMulti, IsMap, Key, T, Clock, Compare, Allocator > &lhs, beast::detail::aged_ordered_container< IsMulti, IsMap, Key, T, Clock, Compare, Allocator > &rhs) noexcept
STL namespace.
T 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)