rippled
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 <ripple/beast/clock/abstract_clock.h>
24 #include <ripple/beast/container/aged_container.h>
25 #include <ripple/beast/container/detail/aged_associative_container.h>
26 #include <ripple/beast/container/detail/aged_container_iterator.h>
27 #include <ripple/beast/container/detail/empty_base_optimization.h>
28 #include <boost/intrusive/list.hpp>
29 #include <boost/intrusive/set.hpp>
30 #include <boost/version.hpp>
31 #include <algorithm>
32 #include <functional>
33 #include <initializer_list>
34 #include <iterator>
35 #include <memory>
36 #include <type_traits>
37 #include <utility>
38 
39 namespace beast {
40 namespace detail {
41 
42 // Traits templates used to discern reverse_iterators, which are disallowed
43 // for mutating operations.
44 template <class It>
46 {
47  explicit is_boost_reverse_iterator() = default;
48 };
49 
50 template <class It>
51 struct is_boost_reverse_iterator<boost::intrusive::reverse_iterator<It>>
53 {
54  explicit is_boost_reverse_iterator() = default;
55 };
56 
73 template <
74  bool IsMulti,
75  bool IsMap,
76  class Key,
77  class T,
78  class Clock = std::chrono::steady_clock,
79  class Compare = std::less<Key>,
80  class Allocator = std::allocator<
83 {
84 public:
87  using duration = typename clock_type::duration;
88  using key_type = Key;
89  using mapped_type = T;
90  using value_type =
94 
95  // Introspection (for unit tests)
99 
100 private:
101  static Key const&
102  extract(value_type const& value)
103  {
105  }
106 
107  // VFALCO TODO hoist to remove template argument dependencies
108  struct element
109  : boost::intrusive::set_base_hook<
110  boost::intrusive::link_mode<boost::intrusive::normal_link>>,
111  boost::intrusive::list_base_hook<
112  boost::intrusive::link_mode<boost::intrusive::normal_link>>
113  {
114  // Stash types here so the iterator doesn't
115  // need to see the container declaration.
116  struct stashed
117  {
118  explicit stashed() = default;
119 
122  };
123 
124  element(time_point const& when_, value_type const& value_)
125  : value(value_), when(when_)
126  {
127  }
128 
129  element(time_point const& when_, value_type&& value_)
130  : value(std::move(value_)), when(when_)
131  {
132  }
133 
134  template <
135  class... Args,
136  class = typename std::enable_if<
137  std::is_constructible<value_type, Args...>::value>::type>
138  element(time_point const& when_, Args&&... args)
139  : value(std::forward<Args>(args)...), when(when_)
140  {
141  }
142 
145  };
146 
147  // VFALCO TODO This should only be enabled for maps.
150 #ifdef _LIBCPP_VERSION
151  ,
153 #endif
154  {
155  public:
156 #ifndef _LIBCPP_VERSION
159  using result_type = bool;
160 #endif
161 
162  bool
163  operator()(value_type const& lhs, value_type const& rhs) const
164  {
165  return this->member()(lhs.first, rhs.first);
166  }
167 
169  {
170  }
171 
173  : beast::detail::empty_base_optimization<Compare>(other)
174  {
175  }
176 
177  private:
179 
180  pair_value_compare(Compare const& compare)
181  : beast::detail::empty_base_optimization<Compare>(compare)
182  {
183  }
184  };
185 
186  // Compares value_type against element, used in insert_check
187  // VFALCO TODO hoist to remove template argument dependencies
190 #ifdef _LIBCPP_VERSION
191  ,
193 #endif
194  {
195  public:
196 #ifndef _LIBCPP_VERSION
197  using first_argument = Key;
199  using result_type = bool;
200 #endif
201 
202  KeyValueCompare() = default;
203 
204  KeyValueCompare(Compare const& compare)
205  : beast::detail::empty_base_optimization<Compare>(compare)
206  {
207  }
208 
209  // VFALCO NOTE WE might want only to enable these overloads
210  // if Compare has is_transparent
211 #if 0
212  template <class K>
213  bool operator() (K const& k, element const& e) const
214  {
215  return this->member() (k, extract (e.value));
216  }
217 
218  template <class K>
219  bool operator() (element const& e, K const& k) const
220  {
221  return this->member() (extract (e.value), k);
222  }
223 #endif
224 
225  bool
226  operator()(Key const& k, element const& e) const
227  {
228  return this->member()(k, extract(e.value));
229  }
230 
231  bool
232  operator()(element const& e, Key const& k) const
233  {
234  return this->member()(extract(e.value), k);
235  }
236 
237  bool
238  operator()(element const& x, element const& y) const
239  {
240  return this->member()(extract(x.value), extract(y.value));
241  }
242 
243  Compare&
245  {
247  }
248 
249  Compare const&
250  compare() const
251  {
253  }
254  };
255 
256  using list_type = typename boost::intrusive::
257  make_list<element, boost::intrusive::constant_time_size<false>>::type;
258 
259  using cont_type = typename std::conditional<
260  IsMulti,
261  typename boost::intrusive::make_multiset<
262  element,
263  boost::intrusive::constant_time_size<true>,
264  boost::intrusive::compare<KeyValueCompare>>::type,
265  typename boost::intrusive::make_set<
266  element,
267  boost::intrusive::constant_time_size<true>,
268  boost::intrusive::compare<KeyValueCompare>>::type>::type;
269 
270  using ElementAllocator = typename std::allocator_traits<
271  Allocator>::template rebind_alloc<element>;
272 
274 
275  class config_t
276  : private KeyValueCompare,
277  public beast::detail::empty_base_optimization<ElementAllocator>
278  {
279  public:
280  explicit config_t(clock_type& clock_) : clock(clock_)
281  {
282  }
283 
284  config_t(clock_type& clock_, Compare const& comp)
285  : KeyValueCompare(comp), clock(clock_)
286  {
287  }
288 
289  config_t(clock_type& clock_, Allocator const& alloc_)
291  , clock(clock_)
292  {
293  }
294 
296  clock_type& clock_,
297  Compare const& comp,
298  Allocator const& alloc_)
299  : KeyValueCompare(comp)
301  , clock(clock_)
302  {
303  }
304 
305  config_t(config_t const& other)
306  : KeyValueCompare(other.key_compare())
308  ElementAllocatorTraits::select_on_container_copy_construction(
309  other.alloc()))
310  , clock(other.clock)
311  {
312  }
313 
314  config_t(config_t const& other, Allocator const& alloc)
315  : KeyValueCompare(other.key_compare())
317  , clock(other.clock)
318  {
319  }
320 
322  : KeyValueCompare(std::move(other.key_compare()))
324  std::move(other))
325  , clock(other.clock)
326  {
327  }
328 
329  config_t(config_t&& other, Allocator const& alloc)
330  : KeyValueCompare(std::move(other.key_compare()))
332  , clock(other.clock)
333  {
334  }
335 
336  config_t&
337  operator=(config_t const& other)
338  {
339  if (this != &other)
340  {
341  compare() = other.compare();
342  alloc() = other.alloc();
343  clock = other.clock;
344  }
345  return *this;
346  }
347 
348  config_t&
350  {
351  compare() = std::move(other.compare());
352  alloc() = std::move(other.alloc());
353  clock = other.clock;
354  return *this;
355  }
356 
357  Compare&
359  {
360  return KeyValueCompare::compare();
361  }
362 
363  Compare const&
364  compare() const
365  {
366  return KeyValueCompare::compare();
367  }
368 
371  {
372  return *this;
373  }
374 
375  KeyValueCompare const&
376  key_compare() const
377  {
378  return *this;
379  }
380 
383  {
386  }
387 
388  ElementAllocator const&
389  alloc() const
390  {
393  }
394 
396  };
397 
398  template <class... Args>
399  element*
400  new_element(Args&&... args)
401  {
402  struct Deleter
403  {
405  Deleter(ElementAllocator& a) : a_(a)
406  {
407  }
408 
409  void
410  operator()(element* p)
411  {
413  }
414  };
415 
418  Deleter(m_config.alloc()));
420  m_config.alloc(),
421  p.get(),
422  clock().now(),
423  std::forward<Args>(args)...);
424  return p.release();
425  }
426 
427  void
428  delete_element(element const* p)
429  {
432  m_config.alloc(), const_cast<element*>(p), 1);
433  }
434 
435  void
436  unlink_and_delete_element(element const* p)
437  {
438  chronological.list.erase(chronological.list.iterator_to(*p));
439  m_cont.erase(m_cont.iterator_to(*p));
440  delete_element(p);
441  }
442 
443 public:
444  using key_compare = Compare;
445  using value_compare =
447  using allocator_type = Allocator;
449  using const_reference = value_type const&;
451  using const_pointer =
453 
454  // A set iterator (IsMap==false) is always const
455  // because the elements of a set are immutable.
456  using iterator = beast::detail::
457  aged_container_iterator<!IsMap, typename cont_type::iterator>;
458  using const_iterator = beast::detail::
459  aged_container_iterator<true, typename cont_type::iterator>;
460  using reverse_iterator = beast::detail::
461  aged_container_iterator<!IsMap, typename cont_type::reverse_iterator>;
462  using const_reverse_iterator = beast::detail::
463  aged_container_iterator<true, typename cont_type::reverse_iterator>;
464 
465  //--------------------------------------------------------------------------
466  //
467  // Chronological ordered iterators
468  //
469  // "Memberspace"
470  // http://accu.org/index.php/journals/1527
471  //
472  //--------------------------------------------------------------------------
473 
475  {
476  public:
477  // A set iterator (IsMap==false) is always const
478  // because the elements of a set are immutable.
479  using iterator = beast::detail::
480  aged_container_iterator<!IsMap, typename list_type::iterator>;
481  using const_iterator = beast::detail::
482  aged_container_iterator<true, typename list_type::iterator>;
484  !IsMap,
485  typename list_type::reverse_iterator>;
486  using const_reverse_iterator = beast::detail::
487  aged_container_iterator<true, typename list_type::reverse_iterator>;
488 
489  iterator
491  {
492  return iterator(list.begin());
493  }
494 
496  begin() const
497  {
498  return const_iterator(list.begin());
499  }
500 
502  cbegin() const
503  {
504  return const_iterator(list.begin());
505  }
506 
507  iterator
508  end()
509  {
510  return iterator(list.end());
511  }
512 
514  end() const
515  {
516  return const_iterator(list.end());
517  }
518 
520  cend() const
521  {
522  return const_iterator(list.end());
523  }
524 
527  {
528  return reverse_iterator(list.rbegin());
529  }
530 
532  rbegin() const
533  {
534  return const_reverse_iterator(list.rbegin());
535  }
536 
538  crbegin() const
539  {
540  return const_reverse_iterator(list.rbegin());
541  }
542 
545  {
546  return reverse_iterator(list.rend());
547  }
548 
550  rend() const
551  {
552  return const_reverse_iterator(list.rend());
553  }
554 
556  crend() const
557  {
558  return const_reverse_iterator(list.rend());
559  }
560 
561  iterator
563  {
564  static_assert(
566  "must be standard layout");
567  return list.iterator_to(*reinterpret_cast<element*>(
568  reinterpret_cast<uint8_t*>(&value) -
569  ((std::size_t)std::addressof(((element*)0)->member))));
570  }
571 
573  iterator_to(value_type const& value) const
574  {
575  static_assert(
577  "must be standard layout");
578  return list.iterator_to(*reinterpret_cast<element const*>(
579  reinterpret_cast<uint8_t const*>(&value) -
580  ((std::size_t)std::addressof(((element*)0)->member))));
581  }
582 
583  private:
585  {
586  }
587 
588  chronological_t(chronological_t const&) = delete;
589  chronological_t(chronological_t&&) = delete;
590 
592  list_type mutable list;
593  } chronological;
594 
595  //--------------------------------------------------------------------------
596  //
597  // Construction
598  //
599  //--------------------------------------------------------------------------
600 
601  aged_ordered_container() = delete;
602 
604 
605  aged_ordered_container(clock_type& clock, Compare const& comp);
606 
607  aged_ordered_container(clock_type& clock, Allocator const& alloc);
608 
610  clock_type& clock,
611  Compare const& comp,
612  Allocator const& alloc);
613 
614  template <class InputIt>
615  aged_ordered_container(InputIt first, InputIt last, clock_type& clock);
616 
617  template <class InputIt>
619  InputIt first,
620  InputIt last,
621  clock_type& clock,
622  Compare const& comp);
623 
624  template <class InputIt>
626  InputIt first,
627  InputIt last,
628  clock_type& clock,
629  Allocator const& alloc);
630 
631  template <class InputIt>
633  InputIt first,
634  InputIt last,
635  clock_type& clock,
636  Compare const& comp,
637  Allocator const& alloc);
638 
640 
642  aged_ordered_container const& other,
643  Allocator const& alloc);
644 
646 
648  aged_ordered_container&& other,
649  Allocator const& alloc);
650 
653  clock_type& clock);
654 
657  clock_type& clock,
658  Compare const& comp);
659 
662  clock_type& clock,
663  Allocator const& alloc);
664 
667  clock_type& clock,
668  Compare const& comp,
669  Allocator const& alloc);
670 
672 
674  operator=(aged_ordered_container const& other);
675 
678 
681 
684  {
685  return m_config.alloc();
686  }
687 
688  clock_type&
690  {
691  return m_config.clock;
692  }
693 
694  clock_type const&
695  clock() const
696  {
697  return m_config.clock;
698  }
699 
700  //--------------------------------------------------------------------------
701  //
702  // Element access (maps)
703  //
704  //--------------------------------------------------------------------------
705 
706  template <
707  class K,
708  bool maybe_multi = IsMulti,
709  bool maybe_map = IsMap,
712  at(K const& k);
713 
714  template <
715  class K,
716  bool maybe_multi = IsMulti,
717  bool maybe_map = IsMap,
720  at(K const& k) const;
721 
722  template <
723  bool maybe_multi = IsMulti,
724  bool maybe_map = IsMap,
727  operator[](Key const& key);
728 
729  template <
730  bool maybe_multi = IsMulti,
731  bool maybe_map = IsMap,
734  operator[](Key&& key);
735 
736  //--------------------------------------------------------------------------
737  //
738  // Iterators
739  //
740  //--------------------------------------------------------------------------
741 
742  iterator
744  {
745  return iterator(m_cont.begin());
746  }
747 
749  begin() const
750  {
751  return const_iterator(m_cont.begin());
752  }
753 
755  cbegin() const
756  {
757  return const_iterator(m_cont.begin());
758  }
759 
760  iterator
761  end()
762  {
763  return iterator(m_cont.end());
764  }
765 
767  end() const
768  {
769  return const_iterator(m_cont.end());
770  }
771 
773  cend() const
774  {
775  return const_iterator(m_cont.end());
776  }
777 
780  {
781  return reverse_iterator(m_cont.rbegin());
782  }
783 
785  rbegin() const
786  {
787  return const_reverse_iterator(m_cont.rbegin());
788  }
789 
791  crbegin() const
792  {
793  return const_reverse_iterator(m_cont.rbegin());
794  }
795 
798  {
799  return reverse_iterator(m_cont.rend());
800  }
801 
803  rend() const
804  {
805  return const_reverse_iterator(m_cont.rend());
806  }
807 
809  crend() const
810  {
811  return const_reverse_iterator(m_cont.rend());
812  }
813 
814  iterator
816  {
817  static_assert(
818  std::is_standard_layout<element>::value, "must be standard layout");
819  return m_cont.iterator_to(*reinterpret_cast<element*>(
820  reinterpret_cast<uint8_t*>(&value) -
821  ((std::size_t)std::addressof(((element*)0)->member))));
822  }
823 
825  iterator_to(value_type const& value) const
826  {
827  static_assert(
828  std::is_standard_layout<element>::value, "must be standard layout");
829  return m_cont.iterator_to(*reinterpret_cast<element const*>(
830  reinterpret_cast<uint8_t const*>(&value) -
831  ((std::size_t)std::addressof(((element*)0)->member))));
832  }
833 
834  //--------------------------------------------------------------------------
835  //
836  // Capacity
837  //
838  //--------------------------------------------------------------------------
839 
840  bool
841  empty() const noexcept
842  {
843  return m_cont.empty();
844  }
845 
846  size_type
847  size() const noexcept
848  {
849  return m_cont.size();
850  }
851 
852  size_type
853  max_size() const noexcept
854  {
855  return m_config.max_size();
856  }
857 
858  //--------------------------------------------------------------------------
859  //
860  // Modifiers
861  //
862  //--------------------------------------------------------------------------
863 
864  void
865  clear();
866 
867  // map, set
868  template <bool maybe_multi = IsMulti>
869  auto
870  insert(value_type const& value) ->
872 
873  // multimap, multiset
874  template <bool maybe_multi = IsMulti>
875  auto
876  insert(value_type const& value) ->
878 
879  // set
880  template <bool maybe_multi = IsMulti, bool maybe_map = IsMap>
881  auto
882  insert(value_type&& value) -> typename std::
883  enable_if<!maybe_multi && !maybe_map, std::pair<iterator, bool>>::type;
884 
885  // multiset
886  template <bool maybe_multi = IsMulti, bool maybe_map = IsMap>
887  auto
888  insert(value_type&& value) ->
890 
891  //---
892 
893  // map, set
894  template <bool maybe_multi = IsMulti>
895  auto
896  insert(const_iterator hint, value_type const& value) ->
898 
899  // multimap, multiset
900  template <bool maybe_multi = IsMulti>
902  insert(const_iterator /*hint*/, value_type const& value)
903  {
904  // VFALCO TODO Figure out how to utilize 'hint'
905  return insert(value);
906  }
907 
908  // map, set
909  template <bool maybe_multi = IsMulti>
910  auto
911  insert(const_iterator hint, value_type&& value) ->
913 
914  // multimap, multiset
915  template <bool maybe_multi = IsMulti>
917  insert(const_iterator /*hint*/, value_type&& value)
918  {
919  // VFALCO TODO Figure out how to utilize 'hint'
920  return insert(std::move(value));
921  }
922 
923  // map, multimap
924  template <class P, bool maybe_map = IsMap>
925  typename std::enable_if<
927  typename std::
928  conditional<IsMulti, iterator, std::pair<iterator, bool>>::type>::
929  type
930  insert(P&& value)
931  {
932  return emplace(std::forward<P>(value));
933  }
934 
935  // map, multimap
936  template <class P, bool maybe_map = IsMap>
937  typename std::enable_if<
939  typename std::
940  conditional<IsMulti, iterator, std::pair<iterator, bool>>::type>::
941  type
942  insert(const_iterator hint, P&& value)
943  {
944  return emplace_hint(hint, std::forward<P>(value));
945  }
946 
947  template <class InputIt>
948  void
949  insert(InputIt first, InputIt last)
950  {
951  for (; first != last; ++first)
952  insert(cend(), *first);
953  }
954 
955  void
957  {
958  insert(init.begin(), init.end());
959  }
960 
961  // map, set
962  template <bool maybe_multi = IsMulti, class... Args>
963  auto
964  emplace(Args&&... args) ->
966 
967  // multiset, multimap
968  template <bool maybe_multi = IsMulti, class... Args>
969  auto
970  emplace(Args&&... args) ->
972 
973  // map, set
974  template <bool maybe_multi = IsMulti, class... Args>
975  auto
976  emplace_hint(const_iterator hint, Args&&... args) ->
978 
979  // multiset, multimap
980  template <bool maybe_multi = IsMulti, class... Args>
982  emplace_hint(const_iterator /*hint*/, Args&&... args)
983  {
984  // VFALCO TODO Figure out how to utilize 'hint'
985  return emplace<maybe_multi>(std::forward<Args>(args)...);
986  }
987 
988  // enable_if prevents erase (reverse_iterator pos) from compiling
989  template <
990  bool is_const,
991  class Iterator,
995 
996  // enable_if prevents erase (reverse_iterator first, reverse_iterator last)
997  // from compiling
998  template <
999  bool is_const,
1000  class Iterator,
1003  erase(
1006 
1007  template <class K>
1008  auto
1009  erase(K const& k) -> size_type;
1010 
1011  void
1012  swap(aged_ordered_container& other) noexcept;
1013 
1014  //--------------------------------------------------------------------------
1015 
1016  // enable_if prevents touch (reverse_iterator pos) from compiling
1017  template <
1018  bool is_const,
1019  class Iterator,
1021  void
1023  {
1024  touch(pos, clock().now());
1025  }
1026 
1027  template <class K>
1028  size_type
1029  touch(K const& k);
1030 
1031  //--------------------------------------------------------------------------
1032  //
1033  // Lookup
1034  //
1035  //--------------------------------------------------------------------------
1036 
1037  // VFALCO TODO Respect is_transparent (c++14)
1038  template <class K>
1039  size_type
1040  count(K const& k) const
1041  {
1042  return m_cont.count(k, std::cref(m_config.key_compare()));
1043  }
1044 
1045  // VFALCO TODO Respect is_transparent (c++14)
1046  template <class K>
1047  iterator
1048  find(K const& k)
1049  {
1050  return iterator(m_cont.find(k, std::cref(m_config.key_compare())));
1051  }
1052 
1053  // VFALCO TODO Respect is_transparent (c++14)
1054  template <class K>
1056  find(K const& k) const
1057  {
1058  return const_iterator(
1059  m_cont.find(k, std::cref(m_config.key_compare())));
1060  }
1061 
1062  // VFALCO TODO Respect is_transparent (c++14)
1063  template <class K>
1065  equal_range(K const& k)
1066  {
1067  auto const r(m_cont.equal_range(k, std::cref(m_config.key_compare())));
1068  return std::make_pair(iterator(r.first), iterator(r.second));
1069  }
1070 
1071  // VFALCO TODO Respect is_transparent (c++14)
1072  template <class K>
1074  equal_range(K const& k) const
1075  {
1076  auto const r(m_cont.equal_range(k, std::cref(m_config.key_compare())));
1077  return std::make_pair(
1078  const_iterator(r.first), const_iterator(r.second));
1079  }
1080 
1081  // VFALCO TODO Respect is_transparent (c++14)
1082  template <class K>
1083  iterator
1084  lower_bound(K const& k)
1085  {
1086  return iterator(
1087  m_cont.lower_bound(k, std::cref(m_config.key_compare())));
1088  }
1089 
1090  // VFALCO TODO Respect is_transparent (c++14)
1091  template <class K>
1093  lower_bound(K const& k) const
1094  {
1095  return const_iterator(
1096  m_cont.lower_bound(k, std::cref(m_config.key_compare())));
1097  }
1098 
1099  // VFALCO TODO Respect is_transparent (c++14)
1100  template <class K>
1101  iterator
1102  upper_bound(K const& k)
1103  {
1104  return iterator(
1105  m_cont.upper_bound(k, std::cref(m_config.key_compare())));
1106  }
1107 
1108  // VFALCO TODO Respect is_transparent (c++14)
1109  template <class K>
1111  upper_bound(K const& k) const
1112  {
1113  return const_iterator(
1114  m_cont.upper_bound(k, std::cref(m_config.key_compare())));
1115  }
1116 
1117  //--------------------------------------------------------------------------
1118  //
1119  // Observers
1120  //
1121  //--------------------------------------------------------------------------
1122 
1123  key_compare
1124  key_comp() const
1125  {
1126  return m_config.compare();
1127  }
1128 
1129  // VFALCO TODO Should this return const reference for set?
1131  value_comp() const
1132  {
1133  return value_compare(m_config.compare());
1134  }
1135 
1136  //--------------------------------------------------------------------------
1137  //
1138  // Comparison
1139  //
1140  //--------------------------------------------------------------------------
1141 
1142  // This differs from the standard in that the comparison
1143  // is only done on the key portion of the value type, ignoring
1144  // the mapped type.
1145  //
1146  template <
1147  bool OtherIsMulti,
1148  bool OtherIsMap,
1149  class OtherT,
1150  class OtherDuration,
1151  class OtherAllocator>
1152  bool
1154  OtherIsMulti,
1155  OtherIsMap,
1156  Key,
1157  OtherT,
1158  OtherDuration,
1159  Compare,
1160  OtherAllocator> const& other) const;
1161 
1162  template <
1163  bool OtherIsMulti,
1164  bool OtherIsMap,
1165  class OtherT,
1166  class OtherDuration,
1167  class OtherAllocator>
1168  bool
1170  OtherIsMulti,
1171  OtherIsMap,
1172  Key,
1173  OtherT,
1174  OtherDuration,
1175  Compare,
1176  OtherAllocator> const& other) const
1177  {
1178  return !(this->operator==(other));
1179  }
1180 
1181  template <
1182  bool OtherIsMulti,
1183  bool OtherIsMap,
1184  class OtherT,
1185  class OtherDuration,
1186  class OtherAllocator>
1187  bool
1189  OtherIsMulti,
1190  OtherIsMap,
1191  Key,
1192  OtherT,
1193  OtherDuration,
1194  Compare,
1195  OtherAllocator> const& other) const
1196  {
1197  value_compare const comp(value_comp());
1199  cbegin(), cend(), other.cbegin(), other.cend(), comp);
1200  }
1201 
1202  template <
1203  bool OtherIsMulti,
1204  bool OtherIsMap,
1205  class OtherT,
1206  class OtherDuration,
1207  class OtherAllocator>
1208  bool
1210  OtherIsMulti,
1211  OtherIsMap,
1212  Key,
1213  OtherT,
1214  OtherDuration,
1215  Compare,
1216  OtherAllocator> const& other) const
1217  {
1218  return !(other < *this);
1219  }
1220 
1221  template <
1222  bool OtherIsMulti,
1223  bool OtherIsMap,
1224  class OtherT,
1225  class OtherDuration,
1226  class OtherAllocator>
1227  bool
1229  OtherIsMulti,
1230  OtherIsMap,
1231  Key,
1232  OtherT,
1233  OtherDuration,
1234  Compare,
1235  OtherAllocator> const& other) const
1236  {
1237  return other < *this;
1238  }
1239 
1240  template <
1241  bool OtherIsMulti,
1242  bool OtherIsMap,
1243  class OtherT,
1244  class OtherDuration,
1245  class OtherAllocator>
1246  bool
1248  OtherIsMulti,
1249  OtherIsMap,
1250  Key,
1251  OtherT,
1252  OtherDuration,
1253  Compare,
1254  OtherAllocator> const& other) const
1255  {
1256  return !(*this < other);
1257  }
1258 
1259 private:
1260  // enable_if prevents erase (reverse_iterator pos, now) from compiling
1261  template <
1262  bool is_const,
1263  class Iterator,
1265  void
1266  touch(
1268  typename clock_type::time_point const& now);
1269 
1270  template <
1271  bool maybe_propagate = std::allocator_traits<
1272  Allocator>::propagate_on_container_swap::value>
1274  swap_data(aged_ordered_container& other) noexcept;
1275 
1276  template <
1277  bool maybe_propagate = std::allocator_traits<
1278  Allocator>::propagate_on_container_swap::value>
1280  swap_data(aged_ordered_container& other) noexcept;
1281 
1282 private:
1283  config_t m_config;
1285 };
1286 
1287 //------------------------------------------------------------------------------
1288 
1289 template <
1290  bool IsMulti,
1291  bool IsMap,
1292  class Key,
1293  class T,
1294  class Clock,
1295  class Compare,
1296  class Allocator>
1299  : m_config(clock)
1300 {
1301 }
1302 
1303 template <
1304  bool IsMulti,
1305  bool IsMap,
1306  class Key,
1307  class T,
1308  class Clock,
1309  class Compare,
1310  class Allocator>
1312  aged_ordered_container(clock_type& clock, Compare const& comp)
1313  : m_config(clock, comp), m_cont(comp)
1314 {
1315 }
1316 
1317 template <
1318  bool IsMulti,
1319  bool IsMap,
1320  class Key,
1321  class T,
1322  class Clock,
1323  class Compare,
1324  class Allocator>
1326  aged_ordered_container(clock_type& clock, Allocator const& alloc)
1327  : m_config(clock, alloc)
1328 {
1329 }
1330 
1331 template <
1332  bool IsMulti,
1333  bool IsMap,
1334  class Key,
1335  class T,
1336  class Clock,
1337  class Compare,
1338  class Allocator>
1341  clock_type& clock,
1342  Compare const& comp,
1343  Allocator const& alloc)
1344  : m_config(clock, comp, alloc), m_cont(comp)
1345 {
1346 }
1347 
1348 template <
1349  bool IsMulti,
1350  bool IsMap,
1351  class Key,
1352  class T,
1353  class Clock,
1354  class Compare,
1355  class Allocator>
1356 template <class InputIt>
1358  aged_ordered_container(InputIt first, InputIt last, clock_type& clock)
1359  : m_config(clock)
1360 {
1361  insert(first, last);
1362 }
1363 
1364 template <
1365  bool IsMulti,
1366  bool IsMap,
1367  class Key,
1368  class T,
1369  class Clock,
1370  class Compare,
1371  class Allocator>
1372 template <class InputIt>
1375  InputIt first,
1376  InputIt last,
1377  clock_type& clock,
1378  Compare const& comp)
1379  : m_config(clock, comp), m_cont(comp)
1380 {
1381  insert(first, last);
1382 }
1383 
1384 template <
1385  bool IsMulti,
1386  bool IsMap,
1387  class Key,
1388  class T,
1389  class Clock,
1390  class Compare,
1391  class Allocator>
1392 template <class InputIt>
1395  InputIt first,
1396  InputIt last,
1397  clock_type& clock,
1398  Allocator const& alloc)
1399  : m_config(clock, alloc)
1400 {
1401  insert(first, last);
1402 }
1403 
1404 template <
1405  bool IsMulti,
1406  bool IsMap,
1407  class Key,
1408  class T,
1409  class Clock,
1410  class Compare,
1411  class Allocator>
1412 template <class InputIt>
1415  InputIt first,
1416  InputIt last,
1417  clock_type& clock,
1418  Compare const& comp,
1419  Allocator const& alloc)
1420  : m_config(clock, comp, alloc), m_cont(comp)
1421 {
1422  insert(first, last);
1423 }
1424 
1425 template <
1426  bool IsMulti,
1427  bool IsMap,
1428  class Key,
1429  class T,
1430  class Clock,
1431  class Compare,
1432  class Allocator>
1435  : m_config(other.m_config)
1436 #if BOOST_VERSION >= 108000
1437  , m_cont(other.m_cont.get_comp())
1438 #else
1439  , m_cont(other.m_cont.comp())
1440 #endif
1441 {
1442  insert(other.cbegin(), other.cend());
1443 }
1444 
1445 template <
1446  bool IsMulti,
1447  bool IsMap,
1448  class Key,
1449  class T,
1450  class Clock,
1451  class Compare,
1452  class Allocator>
1455  aged_ordered_container const& other,
1456  Allocator const& alloc)
1457  : m_config(other.m_config, alloc)
1458 #if BOOST_VERSION >= 108000
1459  , m_cont(other.m_cont.get_comp())
1460 #else
1461  , m_cont(other.m_cont.comp())
1462 #endif
1463 {
1464  insert(other.cbegin(), other.cend());
1465 }
1466 
1467 template <
1468  bool IsMulti,
1469  bool IsMap,
1470  class Key,
1471  class T,
1472  class Clock,
1473  class Compare,
1474  class Allocator>
1477  : m_config(std::move(other.m_config)), m_cont(std::move(other.m_cont))
1478 {
1479  chronological.list = std::move(other.chronological.list);
1480 }
1481 
1482 template <
1483  bool IsMulti,
1484  bool IsMap,
1485  class Key,
1486  class T,
1487  class Clock,
1488  class Compare,
1489  class Allocator>
1492  aged_ordered_container&& other,
1493  Allocator const& alloc)
1494  : m_config(std::move(other.m_config), alloc)
1495 #if BOOST_VERSION >= 108000
1496  , m_cont(std::move(other.m_cont.get_comp()))
1497 #else
1498  , m_cont(std::move(other.m_cont.comp()))
1499 #endif
1500 
1501 {
1502  insert(other.cbegin(), other.cend());
1503  other.clear();
1504 }
1505 
1506 template <
1507  bool IsMulti,
1508  bool IsMap,
1509  class Key,
1510  class T,
1511  class Clock,
1512  class Compare,
1513  class Allocator>
1517  clock_type& clock)
1518  : m_config(clock)
1519 {
1520  insert(init.begin(), init.end());
1521 }
1522 
1523 template <
1524  bool IsMulti,
1525  bool IsMap,
1526  class Key,
1527  class T,
1528  class Clock,
1529  class Compare,
1530  class Allocator>
1534  clock_type& clock,
1535  Compare const& comp)
1536  : m_config(clock, comp), m_cont(comp)
1537 {
1538  insert(init.begin(), init.end());
1539 }
1540 
1541 template <
1542  bool IsMulti,
1543  bool IsMap,
1544  class Key,
1545  class T,
1546  class Clock,
1547  class Compare,
1548  class Allocator>
1552  clock_type& clock,
1553  Allocator const& alloc)
1554  : m_config(clock, alloc)
1555 {
1556  insert(init.begin(), init.end());
1557 }
1558 
1559 template <
1560  bool IsMulti,
1561  bool IsMap,
1562  class Key,
1563  class T,
1564  class Clock,
1565  class Compare,
1566  class Allocator>
1570  clock_type& clock,
1571  Compare const& comp,
1572  Allocator const& alloc)
1573  : m_config(clock, comp, alloc), m_cont(comp)
1574 {
1575  insert(init.begin(), init.end());
1576 }
1577 
1578 template <
1579  bool IsMulti,
1580  bool IsMap,
1581  class Key,
1582  class T,
1583  class Clock,
1584  class Compare,
1585  class Allocator>
1588 {
1589  clear();
1590 }
1591 
1592 template <
1593  bool IsMulti,
1594  bool IsMap,
1595  class Key,
1596  class T,
1597  class Clock,
1598  class Compare,
1599  class Allocator>
1600 auto
1603 {
1604  if (this != &other)
1605  {
1606  clear();
1607  this->m_config = other.m_config;
1608  insert(other.begin(), other.end());
1609  }
1610  return *this;
1611 }
1612 
1613 template <
1614  bool IsMulti,
1615  bool IsMap,
1616  class Key,
1617  class T,
1618  class Clock,
1619  class Compare,
1620  class Allocator>
1621 auto
1624 {
1625  clear();
1626  this->m_config = std::move(other.m_config);
1627  insert(other.begin(), other.end());
1628  other.clear();
1629  return *this;
1630 }
1631 
1632 template <
1633  bool IsMulti,
1634  bool IsMap,
1635  class Key,
1636  class T,
1637  class Clock,
1638  class Compare,
1639  class Allocator>
1640 auto
1643 {
1644  clear();
1645  insert(init);
1646  return *this;
1647 }
1648 
1649 //------------------------------------------------------------------------------
1650 
1651 template <
1652  bool IsMulti,
1653  bool IsMap,
1654  class Key,
1655  class T,
1656  class Clock,
1657  class Compare,
1658  class Allocator>
1659 template <class K, bool maybe_multi, bool maybe_map, class>
1662  K const& k)
1663 {
1664  auto const iter(m_cont.find(k, std::cref(m_config.key_compare())));
1665  if (iter == m_cont.end())
1666  throw std::out_of_range("key not found");
1667  return iter->value.second;
1668 }
1669 
1670 template <
1671  bool IsMulti,
1672  bool IsMap,
1673  class Key,
1674  class T,
1675  class Clock,
1676  class Compare,
1677  class Allocator>
1678 template <class K, bool maybe_multi, bool maybe_map, class>
1681  K const& k) const
1682 {
1683  auto const iter(m_cont.find(k, std::cref(m_config.key_compare())));
1684  if (iter == m_cont.end())
1685  throw std::out_of_range("key not found");
1686  return iter->value.second;
1687 }
1688 
1689 template <
1690  bool IsMulti,
1691  bool IsMap,
1692  class Key,
1693  class T,
1694  class Clock,
1695  class Compare,
1696  class Allocator>
1697 template <bool maybe_multi, bool maybe_map, class>
1700 operator[](Key const& key)
1701 {
1702  typename cont_type::insert_commit_data d;
1703  auto const result(
1704  m_cont.insert_check(key, std::cref(m_config.key_compare()), d));
1705  if (result.second)
1706  {
1707  element* const p(new_element(
1708  std::piecewise_construct,
1709  std::forward_as_tuple(key),
1711  m_cont.insert_commit(*p, d);
1712  chronological.list.push_back(*p);
1713  return p->value.second;
1714  }
1715  return result.first->value.second;
1716 }
1717 
1718 template <
1719  bool IsMulti,
1720  bool IsMap,
1721  class Key,
1722  class T,
1723  class Clock,
1724  class Compare,
1725  class Allocator>
1726 template <bool maybe_multi, bool maybe_map, class>
1729 operator[](Key&& key)
1730 {
1731  typename cont_type::insert_commit_data d;
1732  auto const result(
1733  m_cont.insert_check(key, std::cref(m_config.key_compare()), d));
1734  if (result.second)
1735  {
1736  element* const p(new_element(
1737  std::piecewise_construct,
1738  std::forward_as_tuple(std::move(key)),
1740  m_cont.insert_commit(*p, d);
1741  chronological.list.push_back(*p);
1742  return p->value.second;
1743  }
1744  return result.first->value.second;
1745 }
1746 
1747 //------------------------------------------------------------------------------
1748 
1749 template <
1750  bool IsMulti,
1751  bool IsMap,
1752  class Key,
1753  class T,
1754  class Clock,
1755  class Compare,
1756  class Allocator>
1757 void
1760 {
1761  for (auto iter(chronological.list.begin());
1762  iter != chronological.list.end();)
1763  delete_element(&*iter++);
1764  chronological.list.clear();
1765  m_cont.clear();
1766 }
1767 
1768 // map, set
1769 template <
1770  bool IsMulti,
1771  bool IsMap,
1772  class Key,
1773  class T,
1774  class Clock,
1775  class Compare,
1776  class Allocator>
1777 template <bool maybe_multi>
1778 auto
1780  insert(value_type const& value) ->
1782 {
1783  typename cont_type::insert_commit_data d;
1784  auto const result(m_cont.insert_check(
1785  extract(value), std::cref(m_config.key_compare()), d));
1786  if (result.second)
1787  {
1788  element* const p(new_element(value));
1789  auto const iter(m_cont.insert_commit(*p, d));
1790  chronological.list.push_back(*p);
1791  return std::make_pair(iterator(iter), true);
1792  }
1793  return std::make_pair(iterator(result.first), false);
1794 }
1795 
1796 // multimap, multiset
1797 template <
1798  bool IsMulti,
1799  bool IsMap,
1800  class Key,
1801  class T,
1802  class Clock,
1803  class Compare,
1804  class Allocator>
1805 template <bool maybe_multi>
1806 auto
1808  insert(value_type const& value) ->
1810 {
1811  auto const before(
1812  m_cont.upper_bound(extract(value), std::cref(m_config.key_compare())));
1813  element* const p(new_element(value));
1814  chronological.list.push_back(*p);
1815  auto const iter(m_cont.insert_before(before, *p));
1816  return iterator(iter);
1817 }
1818 
1819 // set
1820 template <
1821  bool IsMulti,
1822  bool IsMap,
1823  class Key,
1824  class T,
1825  class Clock,
1826  class Compare,
1827  class Allocator>
1828 template <bool maybe_multi, bool maybe_map>
1829 auto
1831  insert(value_type&& value) -> typename std::
1832  enable_if<!maybe_multi && !maybe_map, std::pair<iterator, bool>>::type
1833 {
1834  typename cont_type::insert_commit_data d;
1835  auto const result(m_cont.insert_check(
1836  extract(value), std::cref(m_config.key_compare()), d));
1837  if (result.second)
1838  {
1839  element* const p(new_element(std::move(value)));
1840  auto const iter(m_cont.insert_commit(*p, d));
1841  chronological.list.push_back(*p);
1842  return std::make_pair(iterator(iter), true);
1843  }
1844  return std::make_pair(iterator(result.first), false);
1845 }
1846 
1847 // multiset
1848 template <
1849  bool IsMulti,
1850  bool IsMap,
1851  class Key,
1852  class T,
1853  class Clock,
1854  class Compare,
1855  class Allocator>
1856 template <bool maybe_multi, bool maybe_map>
1857 auto
1859  insert(value_type&& value) ->
1861 {
1862  auto const before(
1863  m_cont.upper_bound(extract(value), std::cref(m_config.key_compare())));
1864  element* const p(new_element(std::move(value)));
1865  chronological.list.push_back(*p);
1866  auto const iter(m_cont.insert_before(before, *p));
1867  return iterator(iter);
1868 }
1869 
1870 //---
1871 
1872 // map, set
1873 template <
1874  bool IsMulti,
1875  bool IsMap,
1876  class Key,
1877  class T,
1878  class Clock,
1879  class Compare,
1880  class Allocator>
1881 template <bool maybe_multi>
1882 auto
1884  insert(const_iterator hint, value_type const& value) ->
1886 {
1887  typename cont_type::insert_commit_data d;
1888  auto const result(m_cont.insert_check(
1889  hint.iterator(), extract(value), std::cref(m_config.key_compare()), d));
1890  if (result.second)
1891  {
1892  element* const p(new_element(value));
1893  auto const iter(m_cont.insert_commit(*p, d));
1894  chronological.list.push_back(*p);
1895  return iterator(iter);
1896  }
1897  return iterator(result.first);
1898 }
1899 
1900 // map, set
1901 template <
1902  bool IsMulti,
1903  bool IsMap,
1904  class Key,
1905  class T,
1906  class Clock,
1907  class Compare,
1908  class Allocator>
1909 template <bool maybe_multi>
1910 auto
1914 {
1915  typename cont_type::insert_commit_data d;
1916  auto const result(m_cont.insert_check(
1917  hint.iterator(), extract(value), std::cref(m_config.key_compare()), d));
1918  if (result.second)
1919  {
1920  element* const p(new_element(std::move(value)));
1921  auto const iter(m_cont.insert_commit(*p, d));
1922  chronological.list.push_back(*p);
1923  return iterator(iter);
1924  }
1925  return iterator(result.first);
1926 }
1927 
1928 // map, set
1929 template <
1930  bool IsMulti,
1931  bool IsMap,
1932  class Key,
1933  class T,
1934  class Clock,
1935  class Compare,
1936  class Allocator>
1937 template <bool maybe_multi, class... Args>
1938 auto
1940  emplace(Args&&... args) ->
1942 {
1943  // VFALCO NOTE Its unfortunate that we need to
1944  // construct element here
1945  element* const p(new_element(std::forward<Args>(args)...));
1946  typename cont_type::insert_commit_data d;
1947  auto const result(m_cont.insert_check(
1948  extract(p->value), std::cref(m_config.key_compare()), d));
1949  if (result.second)
1950  {
1951  auto const iter(m_cont.insert_commit(*p, d));
1952  chronological.list.push_back(*p);
1953  return std::make_pair(iterator(iter), true);
1954  }
1955  delete_element(p);
1956  return std::make_pair(iterator(result.first), false);
1957 }
1958 
1959 // multiset, multimap
1960 template <
1961  bool IsMulti,
1962  bool IsMap,
1963  class Key,
1964  class T,
1965  class Clock,
1966  class Compare,
1967  class Allocator>
1968 template <bool maybe_multi, class... Args>
1969 auto
1971  emplace(Args&&... args) ->
1973 {
1974  element* const p(new_element(std::forward<Args>(args)...));
1975  auto const before(m_cont.upper_bound(
1976  extract(p->value), std::cref(m_config.key_compare())));
1977  chronological.list.push_back(*p);
1978  auto const iter(m_cont.insert_before(before, *p));
1979  return iterator(iter);
1980 }
1981 
1982 // map, set
1983 template <
1984  bool IsMulti,
1985  bool IsMap,
1986  class Key,
1987  class T,
1988  class Clock,
1989  class Compare,
1990  class Allocator>
1991 template <bool maybe_multi, class... Args>
1992 auto
1994  emplace_hint(const_iterator hint, Args&&... args) ->
1996 {
1997  // VFALCO NOTE Its unfortunate that we need to
1998  // construct element here
1999  element* const p(new_element(std::forward<Args>(args)...));
2000  typename cont_type::insert_commit_data d;
2001  auto const result(m_cont.insert_check(
2002  hint.iterator(),
2003  extract(p->value),
2004  std::cref(m_config.key_compare()),
2005  d));
2006  if (result.second)
2007  {
2008  auto const iter(m_cont.insert_commit(*p, d));
2009  chronological.list.push_back(*p);
2010  return std::make_pair(iterator(iter), true);
2011  }
2012  delete_element(p);
2013  return std::make_pair(iterator(result.first), false);
2014 }
2015 
2016 template <
2017  bool IsMulti,
2018  bool IsMap,
2019  class Key,
2020  class T,
2021  class Clock,
2022  class Compare,
2023  class Allocator>
2024 template <bool is_const, class Iterator, class>
2028 {
2029  unlink_and_delete_element(&*((pos++).iterator()));
2031  pos.iterator());
2032 }
2033 
2034 template <
2035  bool IsMulti,
2036  bool IsMap,
2037  class Key,
2038  class T,
2039  class Clock,
2040  class Compare,
2041  class Allocator>
2042 template <bool is_const, class Iterator, class>
2048 {
2049  for (; first != last;)
2050  unlink_and_delete_element(&*((first++).iterator()));
2051 
2053  first.iterator());
2054 }
2055 
2056 template <
2057  bool IsMulti,
2058  bool IsMap,
2059  class Key,
2060  class T,
2061  class Clock,
2062  class Compare,
2063  class Allocator>
2064 template <class K>
2065 auto
2067  erase(K const& k) -> size_type
2068 {
2069  auto iter(m_cont.find(k, std::cref(m_config.key_compare())));
2070  if (iter == m_cont.end())
2071  return 0;
2072  size_type n(0);
2073  for (;;)
2074  {
2075  auto p(&*iter++);
2076  bool const done(m_config(*p, extract(iter->value)));
2077  unlink_and_delete_element(p);
2078  ++n;
2079  if (done)
2080  break;
2081  }
2082  return n;
2083 }
2084 
2085 template <
2086  bool IsMulti,
2087  bool IsMap,
2088  class Key,
2089  class T,
2090  class Clock,
2091  class Compare,
2092  class Allocator>
2093 void
2095  aged_ordered_container& other) noexcept
2096 {
2097  swap_data(other);
2098  std::swap(chronological, other.chronological);
2099  std::swap(m_cont, other.m_cont);
2100 }
2101 
2102 //------------------------------------------------------------------------------
2103 
2104 template <
2105  bool IsMulti,
2106  bool IsMap,
2107  class Key,
2108  class T,
2109  class Clock,
2110  class Compare,
2111  class Allocator>
2112 template <class K>
2113 auto
2115  touch(K const& k) -> size_type
2116 {
2117  auto const now(clock().now());
2118  size_type n(0);
2119  auto const range(equal_range(k));
2120  for (auto iter : range)
2121  {
2122  touch(iter, now);
2123  ++n;
2124  }
2125  return n;
2126 }
2127 
2128 //------------------------------------------------------------------------------
2129 
2130 template <
2131  bool IsMulti,
2132  bool IsMap,
2133  class Key,
2134  class T,
2135  class Clock,
2136  class Compare,
2137  class Allocator>
2138 template <
2139  bool OtherIsMulti,
2140  bool OtherIsMap,
2141  class OtherT,
2142  class OtherDuration,
2143  class OtherAllocator>
2144 bool
2147  OtherIsMulti,
2148  OtherIsMap,
2149  Key,
2150  OtherT,
2151  OtherDuration,
2152  Compare,
2153  OtherAllocator> const& other) const
2154 {
2155  using Other = aged_ordered_container<
2156  OtherIsMulti,
2157  OtherIsMap,
2158  Key,
2159  OtherT,
2160  OtherDuration,
2161  Compare,
2162  OtherAllocator>;
2163  if (size() != other.size())
2164  return false;
2166  return std::equal(
2167  cbegin(),
2168  cend(),
2169  other.cbegin(),
2170  other.cend(),
2171  [&eq, &other](
2172  value_type const& lhs, typename Other::value_type const& rhs) {
2173  return eq(extract(lhs), other.extract(rhs));
2174  });
2175 }
2176 
2177 //------------------------------------------------------------------------------
2178 
2179 template <
2180  bool IsMulti,
2181  bool IsMap,
2182  class Key,
2183  class T,
2184  class Clock,
2185  class Compare,
2186  class Allocator>
2187 template <bool is_const, class Iterator, class>
2188 void
2192  typename clock_type::time_point const& now)
2193 {
2194  auto& e(*pos.iterator());
2195  e.when = now;
2196  chronological.list.erase(chronological.list.iterator_to(e));
2197  chronological.list.push_back(e);
2198 }
2199 
2200 template <
2201  bool IsMulti,
2202  bool IsMap,
2203  class Key,
2204  class T,
2205  class Clock,
2206  class Compare,
2207  class Allocator>
2208 template <bool maybe_propagate>
2212 {
2213  std::swap(m_config.key_compare(), other.m_config.key_compare());
2214  std::swap(m_config.alloc(), other.m_config.alloc());
2215  std::swap(m_config.clock, other.m_config.clock);
2216 }
2217 
2218 template <
2219  bool IsMulti,
2220  bool IsMap,
2221  class Key,
2222  class T,
2223  class Clock,
2224  class Compare,
2225  class Allocator>
2226 template <bool maybe_propagate>
2229  swap_data(aged_ordered_container& other) noexcept
2230 {
2231  std::swap(m_config.key_compare(), other.m_config.key_compare());
2232  std::swap(m_config.clock, other.m_config.clock);
2233 }
2234 
2235 } // namespace detail
2236 
2237 //------------------------------------------------------------------------------
2238 
2239 template <
2240  bool IsMulti,
2241  bool IsMap,
2242  class Key,
2243  class T,
2244  class Clock,
2245  class Compare,
2246  class Allocator>
2248  IsMulti,
2249  IsMap,
2250  Key,
2251  T,
2252  Clock,
2253  Compare,
2254  Allocator>> : std::true_type
2255 {
2256  explicit is_aged_container() = default;
2257 };
2258 
2259 // Free functions
2260 
2261 template <
2262  bool IsMulti,
2263  bool IsMap,
2264  class Key,
2265  class T,
2266  class Clock,
2267  class Compare,
2268  class Allocator>
2269 void
2270 swap(
2272  IsMulti,
2273  IsMap,
2274  Key,
2275  T,
2276  Clock,
2277  Compare,
2278  Allocator>& lhs,
2280  IsMulti,
2281  IsMap,
2282  Key,
2283  T,
2284  Clock,
2285  Compare,
2286  Allocator>& rhs) noexcept
2287 {
2288  lhs.swap(rhs);
2289 }
2290 
2292 template <
2293  bool IsMulti,
2294  bool IsMap,
2295  class Key,
2296  class T,
2297  class Clock,
2298  class Compare,
2299  class Allocator,
2300  class Rep,
2301  class Period>
2305  IsMulti,
2306  IsMap,
2307  Key,
2308  T,
2309  Clock,
2310  Compare,
2311  Allocator>& c,
2313 {
2314  std::size_t n(0);
2315  auto const expired(c.clock().now() - age);
2316  for (auto iter(c.chronological.cbegin());
2317  iter != c.chronological.cend() && iter.when() <= expired;)
2318  {
2319  iter = c.erase(iter);
2320  ++n;
2321  }
2322  return n;
2323 }
2324 
2325 } // namespace beast
2326 
2327 #endif
std::is_standard_layout
beast::detail::aged_ordered_container::config_t::alloc
ElementAllocator const & alloc() const
Definition: aged_ordered_container.h:389
beast::detail::aged_ordered_container::new_element
element * new_element(Args &&... args)
Definition: aged_ordered_container.h:400
beast::detail::aged_ordered_container::chronological_t::rbegin
reverse_iterator rbegin()
Definition: aged_ordered_container.h:526
beast::detail::aged_ordered_container::empty
bool empty() const noexcept
Definition: aged_ordered_container.h:841
beast::detail::aged_ordered_container::operator==
bool operator==(aged_ordered_container< OtherIsMulti, OtherIsMap, Key, OtherT, OtherDuration, Compare, OtherAllocator > const &other) const
Definition: aged_ordered_container.h:2146
beast::detail::aged_ordered_container::pair_value_compare::second_argument
value_type second_argument
Definition: aged_ordered_container.h:158
beast::detail::aged_ordered_container::chronological_t::begin
const_iterator begin() const
Definition: aged_ordered_container.h:496
beast::detail::aged_ordered_container::clear
void clear()
Definition: aged_ordered_container.h:1759
beast::detail::aged_ordered_container::element::stashed::time_point
typename aged_ordered_container::time_point time_point
Definition: aged_ordered_container.h:121
std::chrono::steady_clock
beast::detail::aged_ordered_container::config_t::key_compare
KeyValueCompare const & key_compare() const
Definition: aged_ordered_container.h:376
beast::detail::aged_ordered_container::config_t::config_t
config_t(clock_type &clock_, Compare const &comp, Allocator const &alloc_)
Definition: aged_ordered_container.h:295
beast::detail::aged_ordered_container::extract
static Key const & extract(value_type const &value)
Definition: aged_ordered_container.h:102
std::binary_function
beast::detail::aged_ordered_container::chronological_t::cend
const_iterator cend() const
Definition: aged_ordered_container.h:520
beast::detail::aged_ordered_container::operator>
bool operator>(aged_ordered_container< OtherIsMulti, OtherIsMap, Key, OtherT, OtherDuration, Compare, OtherAllocator > const &other) const
Definition: aged_ordered_container.h:1228
std::false_type
beast::detail::aged_ordered_container::lower_bound
iterator lower_bound(K const &k)
Definition: aged_ordered_container.h:1084
beast::detail::aged_ordered_container::chronological_t::list
list_type list
Definition: aged_ordered_container.h:592
beast::detail::aged_ordered_container::begin
const_iterator begin() const
Definition: aged_ordered_container.h:749
std::equal
T equal(T... args)
beast::detail::aged_ordered_container< beast::IP::Address >::mapped_type
T mapped_type
Definition: aged_ordered_container.h:89
utility
beast::detail::aged_ordered_container::config_t::operator=
config_t & operator=(config_t const &other)
Definition: aged_ordered_container.h:337
beast::detail::aged_ordered_container::config_t::config_t
config_t(clock_type &clock_)
Definition: aged_ordered_container.h:280
beast::detail::aged_ordered_container::value_comp
value_compare value_comp() const
Definition: aged_ordered_container.h:1131
beast::detail::aged_ordered_container::rend
reverse_iterator rend()
Definition: aged_ordered_container.h:797
beast::detail::aged_ordered_container::chronological_t::crend
const_reverse_iterator crend() const
Definition: aged_ordered_container.h:556
beast::detail::aged_ordered_container::chronological_t::const_iterator
beast::detail::aged_container_iterator< true, typename list_type::iterator > const_iterator
Definition: aged_ordered_container.h:482
functional
beast::detail::aged_ordered_container::max_size
size_type max_size() const noexcept
Definition: aged_ordered_container.h:853
std::pair
beast::detail::aged_ordered_container::at
std::conditional< IsMap, T, void * >::type & at(K const &k)
Definition: aged_ordered_container.h:1661
beast::detail::is_boost_reverse_iterator::is_boost_reverse_iterator
is_boost_reverse_iterator()=default
beast::detail::aged_ordered_container::element::stashed::stashed
stashed()=default
beast::detail::aged_ordered_container::KeyValueCompare
Definition: aged_ordered_container.h:188
beast::is_aged_container
Definition: aged_container.h:28
beast::detail::aged_ordered_container< beast::IP::Address >::const_reference
value_type const & const_reference
Definition: aged_ordered_container.h:449
beast::detail::aged_ordered_container::config_t::config_t
config_t(clock_type &clock_, Compare const &comp)
Definition: aged_ordered_container.h:284
std::chrono::duration
beast::detail::aged_ordered_container::KeyValueCompare::compare
Compare const & compare() const
Definition: aged_ordered_container.h:250
beast::detail::aged_ordered_container::lower_bound
const_iterator lower_bound(K const &k) const
Definition: aged_ordered_container.h:1093
iterator
beast::detail::aged_ordered_container< beast::IP::Address >::value_type
typename std::conditional< IsMap, std::pair< Key const, T >, Key >::type value_type
Definition: aged_ordered_container.h:91
beast::detail::aged_ordered_container::list_type
typename boost::intrusive::make_list< element, boost::intrusive::constant_time_size< false > >::type list_type
Definition: aged_ordered_container.h:257
beast::detail::aged_ordered_container::insert
auto insert(value_type const &value) -> typename std::enable_if<!maybe_multi, std::pair< iterator, bool >>::type
Definition: aged_ordered_container.h:1780
beast::detail::aged_ordered_container::config_t::config_t
config_t(config_t &&other, Allocator const &alloc)
Definition: aged_ordered_container.h:329
beast::detail::aged_ordered_container::config_t::key_compare
KeyValueCompare & key_compare()
Definition: aged_ordered_container.h:370
beast::detail::aged_ordered_container::chronological_t::cbegin
const_iterator cbegin() const
Definition: aged_ordered_container.h:502
std::reference_wrapper::get
T get(T... args)
beast::compare
int compare(SemanticVersion const &lhs, SemanticVersion const &rhs)
Compare two SemanticVersions against each other.
Definition: SemanticVersion.cpp:259
std::unique_ptr::release
T release(T... args)
beast::detail::aged_ordered_container::equal_range
std::pair< const_iterator, const_iterator > equal_range(K const &k) const
Definition: aged_ordered_container.h:1074
beast::detail::aged_ordered_container::element::stashed
Definition: aged_ordered_container.h:116
beast::detail::aged_ordered_container::chronological_t::crbegin
const_reverse_iterator crbegin() const
Definition: aged_ordered_container.h:538
beast::detail::aged_ordered_container::end
const_iterator end() const
Definition: aged_ordered_container.h:767
beast::detail::aged_ordered_container::m_cont
cont_type m_cont
Definition: aged_ordered_container.h:1284
beast::detail::aged_ordered_container::KeyValueCompare::operator()
bool operator()(Key const &k, element const &e) const
Definition: aged_ordered_container.h:226
beast::detail::aged_ordered_container::iterator_to
iterator iterator_to(value_type &value)
Definition: aged_ordered_container.h:815
beast::detail::aged_ordered_container::config_t::config_t
config_t(config_t const &other)
Definition: aged_ordered_container.h:305
boost
Definition: IPAddress.h:103
beast::detail::aged_ordered_container::KeyValueCompare::operator()
bool operator()(element const &x, element const &y) const
Definition: aged_ordered_container.h:238
beast::detail::empty_base_optimization< Compare >
beast::detail::aged_ordered_container::operator>=
bool operator>=(aged_ordered_container< OtherIsMulti, OtherIsMap, Key, OtherT, OtherDuration, Compare, OtherAllocator > const &other) const
Definition: aged_ordered_container.h:1247
beast::detail::aged_ordered_container::unlink_and_delete_element
void unlink_and_delete_element(element const *p)
Definition: aged_ordered_container.h:436
beast::detail::aged_ordered_container::element::element
element(time_point const &when_, Args &&... args)
Definition: aged_ordered_container.h:138
beast::detail::aged_ordered_container::chronological_t::rend
reverse_iterator rend()
Definition: aged_ordered_container.h:544
std::less
beast::detail::aged_ordered_container::config_t::config_t
config_t(config_t &&other)
Definition: aged_ordered_container.h:321
beast::detail::empty_base_optimization::member
T & member() noexcept
Definition: empty_base_optimization.h:50
std::allocator_traits
algorithm
beast::detail::aged_ordered_container< beast::IP::Address >::time_point
typename clock_type::time_point time_point
Definition: aged_ordered_container.h:86
beast::detail::aged_ordered_container::swap_data
std::enable_if< maybe_propagate >::type swap_data(aged_ordered_container &other) noexcept
Definition: aged_ordered_container.h:2211
beast::detail::aged_ordered_container::pair_value_compare::operator()
bool operator()(value_type const &lhs, value_type const &rhs) const
Definition: aged_ordered_container.h:163
beast::detail::aged_ordered_container::chronological_t::iterator_to
iterator iterator_to(value_type &value)
Definition: aged_ordered_container.h:562
beast::detail::aged_ordered_container::count
size_type count(K const &k) const
Definition: aged_ordered_container.h:1040
beast::detail::aged_ordered_container::config_t::clock
std::reference_wrapper< clock_type > clock
Definition: aged_ordered_container.h:395
beast::detail::aged_ordered_container::operator<=
bool operator<=(aged_ordered_container< OtherIsMulti, OtherIsMap, Key, OtherT, OtherDuration, Compare, OtherAllocator > const &other) const
Definition: aged_ordered_container.h:1209
beast::detail::aged_ordered_container::emplace_hint
std::enable_if< maybe_multi, iterator >::type emplace_hint(const_iterator, Args &&... args)
Definition: aged_ordered_container.h:982
beast::detail::aged_associative_container_extract_t
Definition: aged_associative_container.h:30
beast::detail::aged_ordered_container::insert
std::enable_if< maybe_multi, iterator >::type insert(const_iterator, value_type const &value)
Definition: aged_ordered_container.h:902
beast::detail::aged_ordered_container::chronological_t::iterator_to
const_iterator iterator_to(value_type const &value) const
Definition: aged_ordered_container.h:573
beast::detail::aged_ordered_container< beast::IP::Address >::ElementAllocator
typename std::allocator_traits< std::allocator< typename std::conditional< IsMap, std::pair< Key const, T >, Key >::type > >::template rebind_alloc< element > ElementAllocator
Definition: aged_ordered_container.h:271
beast::detail::aged_ordered_container::chronological_t::end
const_iterator end() const
Definition: aged_ordered_container.h:514
beast::detail::aged_ordered_container::key_comp
key_compare key_comp() const
Definition: aged_ordered_container.h:1124
beast::detail::aged_ordered_container::element::element
element(time_point const &when_, value_type const &value_)
Definition: aged_ordered_container.h:124
std::addressof
T addressof(T... args)
beast::detail::aged_ordered_container< beast::IP::Address >::pointer
typename std::allocator_traits< std::allocator< typename std::conditional< IsMap, std::pair< Key const, T >, Key >::type > >::pointer pointer
Definition: aged_ordered_container.h:450
beast::detail::aged_ordered_container::KeyValueCompare::operator()
bool operator()(element const &e, Key const &k) const
Definition: aged_ordered_container.h:232
std::reference_wrapper
beast::detail::aged_ordered_container::~aged_ordered_container
~aged_ordered_container()
Definition: aged_ordered_container.h:1587
beast::detail::aged_ordered_container::pair_value_compare::pair_value_compare
pair_value_compare(Compare const &compare)
Definition: aged_ordered_container.h:180
beast::detail::aged_ordered_container::chronological_t::end
iterator end()
Definition: aged_ordered_container.h:508
beast::detail::aged_ordered_container::swap
void swap(aged_ordered_container &other) noexcept
Definition: aged_ordered_container.h:2094
beast::detail::aged_ordered_container::find
iterator find(K const &k)
Definition: aged_ordered_container.h:1048
beast::detail::aged_ordered_container::cend
const_iterator cend() const
Definition: aged_ordered_container.h:773
std::enable_if
beast::detail::aged_ordered_container::clock
clock_type & clock()
Definition: aged_ordered_container.h:689
beast::detail::aged_ordered_container::pair_value_compare::first_argument
value_type first_argument
Definition: aged_ordered_container.h:157
beast::detail::aged_ordered_container::chronological_t::begin
iterator begin()
Definition: aged_ordered_container.h:490
beast::detail::aged_ordered_container::element::element
element(time_point const &when_, value_type &&value_)
Definition: aged_ordered_container.h:129
beast::detail::aged_ordered_container::chronological_t::rend
const_reverse_iterator rend() const
Definition: aged_ordered_container.h:550
std::lexicographical_compare
T lexicographical_compare(T... args)
beast::detail::aged_ordered_container::chronological_t
Definition: aged_ordered_container.h:474
std::allocator_traits::allocate
T allocate(T... args)
beast::detail::aged_ordered_container::emplace
auto emplace(Args &&... args) -> typename std::enable_if<!maybe_multi, std::pair< iterator, bool >>::type
Definition: aged_ordered_container.h:1940
beast::detail::aged_ordered_container::chronological_t::iterator
beast::detail::aged_container_iterator<!IsMap, typename list_type::iterator > iterator
Definition: aged_ordered_container.h:480
beast::detail::aged_ordered_container< beast::IP::Address >::reference
value_type & reference
Definition: aged_ordered_container.h:448
std::allocator_traits::deallocate
T deallocate(T... args)
beast::detail::aged_ordered_container::emplace_hint
auto emplace_hint(const_iterator hint, Args &&... args) -> typename std::enable_if<!maybe_multi, std::pair< iterator, bool >>::type
Definition: aged_ordered_container.h:1994
beast::detail::aged_ordered_container::operator!=
bool operator!=(aged_ordered_container< OtherIsMulti, OtherIsMap, Key, OtherT, OtherDuration, Compare, OtherAllocator > const &other) const
Definition: aged_ordered_container.h:1169
beast::detail::aged_ordered_container::config_t::compare
Compare & compare()
Definition: aged_ordered_container.h:358
std::allocator_traits::destroy
T destroy(T... args)
beast::detail::aged_ordered_container< beast::IP::Address >::cont_type
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
Definition: aged_ordered_container.h:268
beast::detail::aged_ordered_container::insert
std::enable_if< maybe_map &&std::is_constructible< value_type, P && >::value, typename std::conditional< IsMulti, iterator, std::pair< iterator, bool > >::type >::type insert(P &&value)
Definition: aged_ordered_container.h:930
beast::detail::aged_ordered_container::element
Definition: aged_ordered_container.h:108
beast::detail::aged_ordered_container::iterator_to
const_iterator iterator_to(value_type const &value) const
Definition: aged_ordered_container.h:825
beast::aged_ordered_container
Definition: aged_container_iterator.h:29
beast::detail::aged_ordered_container::clock
clock_type const & clock() const
Definition: aged_ordered_container.h:695
beast::detail::aged_ordered_container::erase
beast::detail::aged_container_iterator< false, Iterator > erase(beast::detail::aged_container_iterator< is_const, Iterator > pos)
Definition: aged_ordered_container.h:2027
beast::detail::aged_ordered_container::config_t::config_t
config_t(config_t const &other, Allocator const &alloc)
Definition: aged_ordered_container.h:314
beast::expire
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.
Definition: aged_container_utility.h:33
beast::detail::aged_ordered_container::clock_type
abstract_clock< Clock > clock_type
Definition: aged_ordered_container.h:85
std::forward_as_tuple
T forward_as_tuple(T... args)
beast::detail::aged_ordered_container::crbegin
const_reverse_iterator crbegin() const
Definition: aged_ordered_container.h:791
beast::detail::aged_container_iterator::iterator
Iterator const & iterator() const
Definition: aged_container_iterator.h:170
beast::detail::aged_ordered_container::upper_bound
iterator upper_bound(K const &k)
Definition: aged_ordered_container.h:1102
beast::detail::aged_ordered_container::chronological_t::const_reverse_iterator
beast::detail::aged_container_iterator< true, typename list_type::reverse_iterator > const_reverse_iterator
Definition: aged_ordered_container.h:487
beast::detail::aged_ordered_container::insert
std::enable_if< maybe_map &&std::is_constructible< value_type, P && >::value, typename std::conditional< IsMulti, iterator, std::pair< iterator, bool > >::type >::type insert(const_iterator hint, P &&value)
Definition: aged_ordered_container.h:942
beast::detail::aged_ordered_container::crend
const_reverse_iterator crend() const
Definition: aged_ordered_container.h:809
beast::abstract_clock< std::chrono::steady_clock >
memory
beast::detail::aged_ordered_container::operator[]
std::conditional< IsMap, T, void * >::type & operator[](Key const &key)
Definition: aged_ordered_container.h:1700
beast::detail::aged_ordered_container::aged_ordered_container
aged_ordered_container()=delete
std::swap
T swap(T... args)
beast::detail::aged_ordered_container::pair_value_compare::pair_value_compare
pair_value_compare()
Definition: aged_ordered_container.h:168
std::equal_to
beast::detail::aged_ordered_container::element::value
value_type value
Definition: aged_ordered_container.h:143
beast::detail::aged_ordered_container::iterator
beast::detail::aged_container_iterator<!IsMap, typename cont_type::iterator > iterator
Definition: aged_ordered_container.h:457
beast::detail::aged_ordered_container::get_allocator
allocator_type get_allocator() const
Definition: aged_ordered_container.h:683
beast::detail::aged_ordered_container::const_iterator
beast::detail::aged_container_iterator< true, typename cont_type::iterator > const_iterator
Definition: aged_ordered_container.h:459
beast::detail::aged_ordered_container::chronological_t::rbegin
const_reverse_iterator rbegin() const
Definition: aged_ordered_container.h:532
beast::detail::aged_ordered_container::reverse_iterator
beast::detail::aged_container_iterator<!IsMap, typename cont_type::reverse_iterator > reverse_iterator
Definition: aged_ordered_container.h:461
beast::detail::aged_ordered_container::size
size_type size() const noexcept
Definition: aged_ordered_container.h:847
beast::detail::aged_ordered_container::end
iterator end()
Definition: aged_ordered_container.h:761
beast::detail::aged_ordered_container::operator=
aged_ordered_container & operator=(aged_ordered_container const &other)
Definition: aged_ordered_container.h:1602
beast::detail::aged_ordered_container::element::stashed::value_type
typename aged_ordered_container::value_type value_type
Definition: aged_ordered_container.h:120
beast::detail::aged_ordered_container
Associative container where each element is also indexed by time.
Definition: aged_ordered_container.h:82
beast::detail::aged_ordered_container::rbegin
const_reverse_iterator rbegin() const
Definition: aged_ordered_container.h:785
beast::detail::aged_ordered_container< beast::IP::Address >::const_pointer
typename std::allocator_traits< std::allocator< typename std::conditional< IsMap, std::pair< Key const, T >, Key >::type > >::const_pointer const_pointer
Definition: aged_ordered_container.h:452
beast::detail::aged_ordered_container::upper_bound
const_iterator upper_bound(K const &k) const
Definition: aged_ordered_container.h:1111
beast::detail::aged_ordered_container::operator<
bool operator<(aged_ordered_container< OtherIsMulti, OtherIsMap, Key, OtherT, OtherDuration, Compare, OtherAllocator > const &other) const
Definition: aged_ordered_container.h:1188
beast::detail::aged_ordered_container::chronological
class beast::detail::aged_ordered_container::chronological_t chronological
beast::detail::aged_ordered_container::config_t::compare
Compare const & compare() const
Definition: aged_ordered_container.h:364
std::initializer_list::begin
T begin(T... args)
beast::detail::aged_ordered_container::insert
void insert(std::initializer_list< value_type > init)
Definition: aged_ordered_container.h:956
std
STL namespace.
beast::detail::aged_ordered_container::chronological_t::reverse_iterator
beast::detail::aged_container_iterator< !IsMap, typename list_type::reverse_iterator > reverse_iterator
Definition: aged_ordered_container.h:485
beast::detail::aged_ordered_container::KeyValueCompare::compare
Compare & compare()
Definition: aged_ordered_container.h:244
beast::detail::aged_ordered_container::begin
iterator begin()
Definition: aged_ordered_container.h:743
beast::detail::aged_ordered_container::touch
void touch(beast::detail::aged_container_iterator< is_const, Iterator > pos)
Definition: aged_ordered_container.h:1022
std::ptrdiff_t
beast::detail::aged_ordered_container::key_compare
Compare key_compare
Definition: aged_ordered_container.h:444
std::out_of_range
STL class.
std::allocator
STL class.
std::is_constructible
std::size_t
beast::detail::aged_ordered_container::KeyValueCompare::first_argument
Key first_argument
Definition: aged_ordered_container.h:197
beast::detail::aged_ordered_container::pair_value_compare::result_type
bool result_type
Definition: aged_ordered_container.h:159
std::make_pair
T make_pair(T... args)
beast::detail::aged_ordered_container::config_t::alloc
ElementAllocator & alloc()
Definition: aged_ordered_container.h:382
beast::detail::aged_ordered_container::config_t
Definition: aged_ordered_container.h:275
std::initializer_list::end
T end(T... args)
beast::detail::aged_ordered_container::const_reverse_iterator
beast::detail::aged_container_iterator< true, typename cont_type::reverse_iterator > const_reverse_iterator
Definition: aged_ordered_container.h:463
beast::detail::aged_ordered_container::insert
void insert(InputIt first, InputIt last)
Definition: aged_ordered_container.h:949
std::conditional
beast::detail::aged_ordered_container::config_t::config_t
config_t(clock_type &clock_, Allocator const &alloc_)
Definition: aged_ordered_container.h:289
beast::detail::aged_ordered_container::rbegin
reverse_iterator rbegin()
Definition: aged_ordered_container.h:779
beast::detail::aged_ordered_container::equal_range
std::pair< iterator, iterator > equal_range(K const &k)
Definition: aged_ordered_container.h:1065
beast::detail::aged_ordered_container::cbegin
const_iterator cbegin() const
Definition: aged_ordered_container.h:755
beast::detail::aged_ordered_container::rend
const_reverse_iterator rend() const
Definition: aged_ordered_container.h:803
beast::detail::aged_ordered_container< beast::IP::Address >::value_compare
typename std::conditional< IsMap, pair_value_compare, std::less< Key > >::type value_compare
Definition: aged_ordered_container.h:446
beast::detail::aged_ordered_container::config_t::operator=
config_t & operator=(config_t &&other)
Definition: aged_ordered_container.h:349
beast::detail::is_boost_reverse_iterator
Definition: aged_ordered_container.h:45
std::unique_ptr
STL class.
beast::detail::aged_ordered_container::pair_value_compare::pair_value_compare
pair_value_compare(pair_value_compare const &other)
Definition: aged_ordered_container.h:172
beast::detail::aged_ordered_container::m_config
config_t m_config
Definition: aged_ordered_container.h:1283
beast::detail::aged_ordered_container::chronological_t::chronological_t
chronological_t()
Definition: aged_ordered_container.h:584
beast::abstract_clock::time_point
typename Clock::time_point time_point
Definition: abstract_clock.h:63
beast::detail::aged_ordered_container::delete_element
void delete_element(element const *p)
Definition: aged_ordered_container.h:428
beast::detail::aged_ordered_container::find
const_iterator find(K const &k) const
Definition: aged_ordered_container.h:1056
type_traits
beast::detail::aged_container_iterator
Definition: aged_container_iterator.h:35
beast::detail::aged_ordered_container< beast::IP::Address >::duration
typename clock_type::duration duration
Definition: aged_ordered_container.h:87
beast::detail::aged_ordered_container::insert
std::enable_if< maybe_multi, iterator >::type insert(const_iterator, value_type &&value)
Definition: aged_ordered_container.h:917
beast::abstract_clock::duration
typename Clock::duration duration
Definition: abstract_clock.h:62
std::allocator_traits::construct
T construct(T... args)
beast::detail::aged_ordered_container::pair_value_compare::aged_ordered_container
friend aged_ordered_container
Definition: aged_ordered_container.h:178
std::cref
T cref(T... args)
beast::detail::aged_ordered_container::KeyValueCompare::KeyValueCompare
KeyValueCompare(Compare const &compare)
Definition: aged_ordered_container.h:204
beast::detail::aged_ordered_container::element::when
time_point when
Definition: aged_ordered_container.h:144
beast::detail::aged_ordered_container::size_type
std::size_t size_type
Definition: aged_ordered_container.h:92
beast::detail::aged_ordered_container::pair_value_compare
Definition: aged_ordered_container.h:148
beast::detail::aged_ordered_container::KeyValueCompare::result_type
bool result_type
Definition: aged_ordered_container.h:199
beast::detail::aged_ordered_container< beast::IP::Address >::key_type
Key key_type
Definition: aged_ordered_container.h:88
initializer_list
beast::detail::aged_ordered_container::allocator_type
Allocator allocator_type
Definition: aged_ordered_container.h:447
beast
Definition: base_uint.h:677