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,
992  class Base,
996 
997  // enable_if prevents erase (reverse_iterator first, reverse_iterator last)
998  // from compiling
999  template <
1000  bool is_const,
1001  class Iterator,
1002  class Base,
1005  erase(
1008 
1009  template <class K>
1010  auto
1011  erase(K const& k) -> size_type;
1012 
1013  void
1014  swap(aged_ordered_container& other) noexcept;
1015 
1016  //--------------------------------------------------------------------------
1017 
1018  // enable_if prevents touch (reverse_iterator pos) from compiling
1019  template <
1020  bool is_const,
1021  class Iterator,
1022  class Base,
1024  void
1026  {
1027  touch(pos, clock().now());
1028  }
1029 
1030  template <class K>
1031  size_type
1032  touch(K const& k);
1033 
1034  //--------------------------------------------------------------------------
1035  //
1036  // Lookup
1037  //
1038  //--------------------------------------------------------------------------
1039 
1040  // VFALCO TODO Respect is_transparent (c++14)
1041  template <class K>
1042  size_type
1043  count(K const& k) const
1044  {
1045  return m_cont.count(k, std::cref(m_config.key_compare()));
1046  }
1047 
1048  // VFALCO TODO Respect is_transparent (c++14)
1049  template <class K>
1050  iterator
1051  find(K const& k)
1052  {
1053  return iterator(m_cont.find(k, std::cref(m_config.key_compare())));
1054  }
1055 
1056  // VFALCO TODO Respect is_transparent (c++14)
1057  template <class K>
1059  find(K const& k) const
1060  {
1061  return const_iterator(
1062  m_cont.find(k, std::cref(m_config.key_compare())));
1063  }
1064 
1065  // VFALCO TODO Respect is_transparent (c++14)
1066  template <class K>
1068  equal_range(K const& k)
1069  {
1070  auto const r(m_cont.equal_range(k, std::cref(m_config.key_compare())));
1071  return std::make_pair(iterator(r.first), iterator(r.second));
1072  }
1073 
1074  // VFALCO TODO Respect is_transparent (c++14)
1075  template <class K>
1077  equal_range(K const& k) const
1078  {
1079  auto const r(m_cont.equal_range(k, std::cref(m_config.key_compare())));
1080  return std::make_pair(
1081  const_iterator(r.first), const_iterator(r.second));
1082  }
1083 
1084  // VFALCO TODO Respect is_transparent (c++14)
1085  template <class K>
1086  iterator
1087  lower_bound(K const& k)
1088  {
1089  return iterator(
1090  m_cont.lower_bound(k, std::cref(m_config.key_compare())));
1091  }
1092 
1093  // VFALCO TODO Respect is_transparent (c++14)
1094  template <class K>
1096  lower_bound(K const& k) const
1097  {
1098  return const_iterator(
1099  m_cont.lower_bound(k, std::cref(m_config.key_compare())));
1100  }
1101 
1102  // VFALCO TODO Respect is_transparent (c++14)
1103  template <class K>
1104  iterator
1105  upper_bound(K const& k)
1106  {
1107  return iterator(
1108  m_cont.upper_bound(k, std::cref(m_config.key_compare())));
1109  }
1110 
1111  // VFALCO TODO Respect is_transparent (c++14)
1112  template <class K>
1114  upper_bound(K const& k) const
1115  {
1116  return const_iterator(
1117  m_cont.upper_bound(k, std::cref(m_config.key_compare())));
1118  }
1119 
1120  //--------------------------------------------------------------------------
1121  //
1122  // Observers
1123  //
1124  //--------------------------------------------------------------------------
1125 
1126  key_compare
1127  key_comp() const
1128  {
1129  return m_config.compare();
1130  }
1131 
1132  // VFALCO TODO Should this return const reference for set?
1134  value_comp() const
1135  {
1136  return value_compare(m_config.compare());
1137  }
1138 
1139  //--------------------------------------------------------------------------
1140  //
1141  // Comparison
1142  //
1143  //--------------------------------------------------------------------------
1144 
1145  // This differs from the standard in that the comparison
1146  // is only done on the key portion of the value type, ignoring
1147  // the mapped type.
1148  //
1149  template <
1150  bool OtherIsMulti,
1151  bool OtherIsMap,
1152  class OtherT,
1153  class OtherDuration,
1154  class OtherAllocator>
1155  bool
1157  OtherIsMulti,
1158  OtherIsMap,
1159  Key,
1160  OtherT,
1161  OtherDuration,
1162  Compare,
1163  OtherAllocator> const& other) const;
1164 
1165  template <
1166  bool OtherIsMulti,
1167  bool OtherIsMap,
1168  class OtherT,
1169  class OtherDuration,
1170  class OtherAllocator>
1171  bool
1173  OtherIsMulti,
1174  OtherIsMap,
1175  Key,
1176  OtherT,
1177  OtherDuration,
1178  Compare,
1179  OtherAllocator> const& other) const
1180  {
1181  return !(this->operator==(other));
1182  }
1183 
1184  template <
1185  bool OtherIsMulti,
1186  bool OtherIsMap,
1187  class OtherT,
1188  class OtherDuration,
1189  class OtherAllocator>
1190  bool
1192  OtherIsMulti,
1193  OtherIsMap,
1194  Key,
1195  OtherT,
1196  OtherDuration,
1197  Compare,
1198  OtherAllocator> const& other) const
1199  {
1200  value_compare const comp(value_comp());
1202  cbegin(), cend(), other.cbegin(), other.cend(), comp);
1203  }
1204 
1205  template <
1206  bool OtherIsMulti,
1207  bool OtherIsMap,
1208  class OtherT,
1209  class OtherDuration,
1210  class OtherAllocator>
1211  bool
1213  OtherIsMulti,
1214  OtherIsMap,
1215  Key,
1216  OtherT,
1217  OtherDuration,
1218  Compare,
1219  OtherAllocator> const& other) const
1220  {
1221  return !(other < *this);
1222  }
1223 
1224  template <
1225  bool OtherIsMulti,
1226  bool OtherIsMap,
1227  class OtherT,
1228  class OtherDuration,
1229  class OtherAllocator>
1230  bool
1232  OtherIsMulti,
1233  OtherIsMap,
1234  Key,
1235  OtherT,
1236  OtherDuration,
1237  Compare,
1238  OtherAllocator> const& other) const
1239  {
1240  return other < *this;
1241  }
1242 
1243  template <
1244  bool OtherIsMulti,
1245  bool OtherIsMap,
1246  class OtherT,
1247  class OtherDuration,
1248  class OtherAllocator>
1249  bool
1251  OtherIsMulti,
1252  OtherIsMap,
1253  Key,
1254  OtherT,
1255  OtherDuration,
1256  Compare,
1257  OtherAllocator> const& other) const
1258  {
1259  return !(*this < other);
1260  }
1261 
1262 private:
1263  // enable_if prevents erase (reverse_iterator pos, now) from compiling
1264  template <
1265  bool is_const,
1266  class Iterator,
1267  class Base,
1269  void
1270  touch(
1272  typename clock_type::time_point const& now);
1273 
1274  template <
1275  bool maybe_propagate = std::allocator_traits<
1276  Allocator>::propagate_on_container_swap::value>
1278  swap_data(aged_ordered_container& other) noexcept;
1279 
1280  template <
1281  bool maybe_propagate = std::allocator_traits<
1282  Allocator>::propagate_on_container_swap::value>
1284  swap_data(aged_ordered_container& other) noexcept;
1285 
1286 private:
1287  config_t m_config;
1289 };
1290 
1291 //------------------------------------------------------------------------------
1292 
1293 template <
1294  bool IsMulti,
1295  bool IsMap,
1296  class Key,
1297  class T,
1298  class Clock,
1299  class Compare,
1300  class Allocator>
1303  : m_config(clock)
1304 {
1305 }
1306 
1307 template <
1308  bool IsMulti,
1309  bool IsMap,
1310  class Key,
1311  class T,
1312  class Clock,
1313  class Compare,
1314  class Allocator>
1316  aged_ordered_container(clock_type& clock, Compare const& comp)
1317  : m_config(clock, comp), m_cont(comp)
1318 {
1319 }
1320 
1321 template <
1322  bool IsMulti,
1323  bool IsMap,
1324  class Key,
1325  class T,
1326  class Clock,
1327  class Compare,
1328  class Allocator>
1330  aged_ordered_container(clock_type& clock, Allocator const& alloc)
1331  : m_config(clock, alloc)
1332 {
1333 }
1334 
1335 template <
1336  bool IsMulti,
1337  bool IsMap,
1338  class Key,
1339  class T,
1340  class Clock,
1341  class Compare,
1342  class Allocator>
1345  clock_type& clock,
1346  Compare const& comp,
1347  Allocator const& alloc)
1348  : m_config(clock, comp, alloc), m_cont(comp)
1349 {
1350 }
1351 
1352 template <
1353  bool IsMulti,
1354  bool IsMap,
1355  class Key,
1356  class T,
1357  class Clock,
1358  class Compare,
1359  class Allocator>
1360 template <class InputIt>
1362  aged_ordered_container(InputIt first, InputIt last, clock_type& clock)
1363  : m_config(clock)
1364 {
1365  insert(first, last);
1366 }
1367 
1368 template <
1369  bool IsMulti,
1370  bool IsMap,
1371  class Key,
1372  class T,
1373  class Clock,
1374  class Compare,
1375  class Allocator>
1376 template <class InputIt>
1379  InputIt first,
1380  InputIt last,
1381  clock_type& clock,
1382  Compare const& comp)
1383  : m_config(clock, comp), m_cont(comp)
1384 {
1385  insert(first, last);
1386 }
1387 
1388 template <
1389  bool IsMulti,
1390  bool IsMap,
1391  class Key,
1392  class T,
1393  class Clock,
1394  class Compare,
1395  class Allocator>
1396 template <class InputIt>
1399  InputIt first,
1400  InputIt last,
1401  clock_type& clock,
1402  Allocator const& alloc)
1403  : m_config(clock, alloc)
1404 {
1405  insert(first, last);
1406 }
1407 
1408 template <
1409  bool IsMulti,
1410  bool IsMap,
1411  class Key,
1412  class T,
1413  class Clock,
1414  class Compare,
1415  class Allocator>
1416 template <class InputIt>
1419  InputIt first,
1420  InputIt last,
1421  clock_type& clock,
1422  Compare const& comp,
1423  Allocator const& alloc)
1424  : m_config(clock, comp, alloc), m_cont(comp)
1425 {
1426  insert(first, last);
1427 }
1428 
1429 template <
1430  bool IsMulti,
1431  bool IsMap,
1432  class Key,
1433  class T,
1434  class Clock,
1435  class Compare,
1436  class Allocator>
1439  : m_config(other.m_config), m_cont(other.m_cont.comp())
1440 {
1441  insert(other.cbegin(), other.cend());
1442 }
1443 
1444 template <
1445  bool IsMulti,
1446  bool IsMap,
1447  class Key,
1448  class T,
1449  class Clock,
1450  class Compare,
1451  class Allocator>
1454  aged_ordered_container const& other,
1455  Allocator const& alloc)
1456  : m_config(other.m_config, alloc), m_cont(other.m_cont.comp())
1457 {
1458  insert(other.cbegin(), other.cend());
1459 }
1460 
1461 template <
1462  bool IsMulti,
1463  bool IsMap,
1464  class Key,
1465  class T,
1466  class Clock,
1467  class Compare,
1468  class Allocator>
1471  : m_config(std::move(other.m_config)), m_cont(std::move(other.m_cont))
1472 {
1473  chronological.list = std::move(other.chronological.list);
1474 }
1475 
1476 template <
1477  bool IsMulti,
1478  bool IsMap,
1479  class Key,
1480  class T,
1481  class Clock,
1482  class Compare,
1483  class Allocator>
1486  aged_ordered_container&& other,
1487  Allocator const& alloc)
1488  : m_config(std::move(other.m_config), alloc)
1489  , m_cont(std::move(other.m_cont.comp()))
1490 {
1491  insert(other.cbegin(), other.cend());
1492  other.clear();
1493 }
1494 
1495 template <
1496  bool IsMulti,
1497  bool IsMap,
1498  class Key,
1499  class T,
1500  class Clock,
1501  class Compare,
1502  class Allocator>
1506  clock_type& clock)
1507  : m_config(clock)
1508 {
1509  insert(init.begin(), init.end());
1510 }
1511 
1512 template <
1513  bool IsMulti,
1514  bool IsMap,
1515  class Key,
1516  class T,
1517  class Clock,
1518  class Compare,
1519  class Allocator>
1523  clock_type& clock,
1524  Compare const& comp)
1525  : m_config(clock, comp), m_cont(comp)
1526 {
1527  insert(init.begin(), init.end());
1528 }
1529 
1530 template <
1531  bool IsMulti,
1532  bool IsMap,
1533  class Key,
1534  class T,
1535  class Clock,
1536  class Compare,
1537  class Allocator>
1541  clock_type& clock,
1542  Allocator const& alloc)
1543  : m_config(clock, alloc)
1544 {
1545  insert(init.begin(), init.end());
1546 }
1547 
1548 template <
1549  bool IsMulti,
1550  bool IsMap,
1551  class Key,
1552  class T,
1553  class Clock,
1554  class Compare,
1555  class Allocator>
1559  clock_type& clock,
1560  Compare const& comp,
1561  Allocator const& alloc)
1562  : m_config(clock, comp, alloc), m_cont(comp)
1563 {
1564  insert(init.begin(), init.end());
1565 }
1566 
1567 template <
1568  bool IsMulti,
1569  bool IsMap,
1570  class Key,
1571  class T,
1572  class Clock,
1573  class Compare,
1574  class Allocator>
1577 {
1578  clear();
1579 }
1580 
1581 template <
1582  bool IsMulti,
1583  bool IsMap,
1584  class Key,
1585  class T,
1586  class Clock,
1587  class Compare,
1588  class Allocator>
1589 auto
1592 {
1593  if (this != &other)
1594  {
1595  clear();
1596  this->m_config = other.m_config;
1597  insert(other.begin(), other.end());
1598  }
1599  return *this;
1600 }
1601 
1602 template <
1603  bool IsMulti,
1604  bool IsMap,
1605  class Key,
1606  class T,
1607  class Clock,
1608  class Compare,
1609  class Allocator>
1610 auto
1613 {
1614  clear();
1615  this->m_config = std::move(other.m_config);
1616  insert(other.begin(), other.end());
1617  other.clear();
1618  return *this;
1619 }
1620 
1621 template <
1622  bool IsMulti,
1623  bool IsMap,
1624  class Key,
1625  class T,
1626  class Clock,
1627  class Compare,
1628  class Allocator>
1629 auto
1632 {
1633  clear();
1634  insert(init);
1635  return *this;
1636 }
1637 
1638 //------------------------------------------------------------------------------
1639 
1640 template <
1641  bool IsMulti,
1642  bool IsMap,
1643  class Key,
1644  class T,
1645  class Clock,
1646  class Compare,
1647  class Allocator>
1648 template <class K, bool maybe_multi, bool maybe_map, class>
1651  K const& k)
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 
1659 template <
1660  bool IsMulti,
1661  bool IsMap,
1662  class Key,
1663  class T,
1664  class Clock,
1665  class Compare,
1666  class Allocator>
1667 template <class K, bool maybe_multi, bool maybe_map, class>
1670  K const& k) const
1671 {
1672  auto const iter(m_cont.find(k, std::cref(m_config.key_compare())));
1673  if (iter == m_cont.end())
1674  throw std::out_of_range("key not found");
1675  return iter->value.second;
1676 }
1677 
1678 template <
1679  bool IsMulti,
1680  bool IsMap,
1681  class Key,
1682  class T,
1683  class Clock,
1684  class Compare,
1685  class Allocator>
1686 template <bool maybe_multi, bool maybe_map, class>
1689 operator[](Key const& key)
1690 {
1691  typename cont_type::insert_commit_data d;
1692  auto const result(
1693  m_cont.insert_check(key, std::cref(m_config.key_compare()), d));
1694  if (result.second)
1695  {
1696  element* const p(new_element(
1697  std::piecewise_construct,
1698  std::forward_as_tuple(key),
1700  m_cont.insert_commit(*p, d);
1701  chronological.list.push_back(*p);
1702  return p->value.second;
1703  }
1704  return result.first->value.second;
1705 }
1706 
1707 template <
1708  bool IsMulti,
1709  bool IsMap,
1710  class Key,
1711  class T,
1712  class Clock,
1713  class Compare,
1714  class Allocator>
1715 template <bool maybe_multi, bool maybe_map, class>
1718 operator[](Key&& key)
1719 {
1720  typename cont_type::insert_commit_data d;
1721  auto const result(
1722  m_cont.insert_check(key, std::cref(m_config.key_compare()), d));
1723  if (result.second)
1724  {
1725  element* const p(new_element(
1726  std::piecewise_construct,
1727  std::forward_as_tuple(std::move(key)),
1729  m_cont.insert_commit(*p, d);
1730  chronological.list.push_back(*p);
1731  return p->value.second;
1732  }
1733  return result.first->value.second;
1734 }
1735 
1736 //------------------------------------------------------------------------------
1737 
1738 template <
1739  bool IsMulti,
1740  bool IsMap,
1741  class Key,
1742  class T,
1743  class Clock,
1744  class Compare,
1745  class Allocator>
1746 void
1749 {
1750  for (auto iter(chronological.list.begin());
1751  iter != chronological.list.end();)
1752  delete_element(&*iter++);
1753  chronological.list.clear();
1754  m_cont.clear();
1755 }
1756 
1757 // map, set
1758 template <
1759  bool IsMulti,
1760  bool IsMap,
1761  class Key,
1762  class T,
1763  class Clock,
1764  class Compare,
1765  class Allocator>
1766 template <bool maybe_multi>
1767 auto
1769  insert(value_type const& value) ->
1771 {
1772  typename cont_type::insert_commit_data d;
1773  auto const result(m_cont.insert_check(
1774  extract(value), std::cref(m_config.key_compare()), d));
1775  if (result.second)
1776  {
1777  element* const p(new_element(value));
1778  auto const iter(m_cont.insert_commit(*p, d));
1779  chronological.list.push_back(*p);
1780  return std::make_pair(iterator(iter), true);
1781  }
1782  return std::make_pair(iterator(result.first), false);
1783 }
1784 
1785 // multimap, multiset
1786 template <
1787  bool IsMulti,
1788  bool IsMap,
1789  class Key,
1790  class T,
1791  class Clock,
1792  class Compare,
1793  class Allocator>
1794 template <bool maybe_multi>
1795 auto
1797  insert(value_type const& value) ->
1799 {
1800  auto const before(
1801  m_cont.upper_bound(extract(value), std::cref(m_config.key_compare())));
1802  element* const p(new_element(value));
1803  chronological.list.push_back(*p);
1804  auto const iter(m_cont.insert_before(before, *p));
1805  return iterator(iter);
1806 }
1807 
1808 // set
1809 template <
1810  bool IsMulti,
1811  bool IsMap,
1812  class Key,
1813  class T,
1814  class Clock,
1815  class Compare,
1816  class Allocator>
1817 template <bool maybe_multi, bool maybe_map>
1818 auto
1820  insert(value_type&& value) -> typename std::
1821  enable_if<!maybe_multi && !maybe_map, std::pair<iterator, bool>>::type
1822 {
1823  typename cont_type::insert_commit_data d;
1824  auto const result(m_cont.insert_check(
1825  extract(value), std::cref(m_config.key_compare()), d));
1826  if (result.second)
1827  {
1828  element* const p(new_element(std::move(value)));
1829  auto const iter(m_cont.insert_commit(*p, d));
1830  chronological.list.push_back(*p);
1831  return std::make_pair(iterator(iter), true);
1832  }
1833  return std::make_pair(iterator(result.first), false);
1834 }
1835 
1836 // multiset
1837 template <
1838  bool IsMulti,
1839  bool IsMap,
1840  class Key,
1841  class T,
1842  class Clock,
1843  class Compare,
1844  class Allocator>
1845 template <bool maybe_multi, bool maybe_map>
1846 auto
1848  insert(value_type&& value) ->
1850 {
1851  auto const before(
1852  m_cont.upper_bound(extract(value), std::cref(m_config.key_compare())));
1853  element* const p(new_element(std::move(value)));
1854  chronological.list.push_back(*p);
1855  auto const iter(m_cont.insert_before(before, *p));
1856  return iterator(iter);
1857 }
1858 
1859 //---
1860 
1861 // map, set
1862 template <
1863  bool IsMulti,
1864  bool IsMap,
1865  class Key,
1866  class T,
1867  class Clock,
1868  class Compare,
1869  class Allocator>
1870 template <bool maybe_multi>
1871 auto
1873  insert(const_iterator hint, value_type const& value) ->
1875 {
1876  typename cont_type::insert_commit_data d;
1877  auto const result(m_cont.insert_check(
1878  hint.iterator(), extract(value), std::cref(m_config.key_compare()), d));
1879  if (result.second)
1880  {
1881  element* const p(new_element(value));
1882  auto const iter(m_cont.insert_commit(*p, d));
1883  chronological.list.push_back(*p);
1884  return iterator(iter);
1885  }
1886  return iterator(result.first);
1887 }
1888 
1889 // map, set
1890 template <
1891  bool IsMulti,
1892  bool IsMap,
1893  class Key,
1894  class T,
1895  class Clock,
1896  class Compare,
1897  class Allocator>
1898 template <bool maybe_multi>
1899 auto
1903 {
1904  typename cont_type::insert_commit_data d;
1905  auto const result(m_cont.insert_check(
1906  hint.iterator(), extract(value), std::cref(m_config.key_compare()), d));
1907  if (result.second)
1908  {
1909  element* const p(new_element(std::move(value)));
1910  auto const iter(m_cont.insert_commit(*p, d));
1911  chronological.list.push_back(*p);
1912  return iterator(iter);
1913  }
1914  return iterator(result.first);
1915 }
1916 
1917 // map, set
1918 template <
1919  bool IsMulti,
1920  bool IsMap,
1921  class Key,
1922  class T,
1923  class Clock,
1924  class Compare,
1925  class Allocator>
1926 template <bool maybe_multi, class... Args>
1927 auto
1929  emplace(Args&&... args) ->
1931 {
1932  // VFALCO NOTE Its unfortunate that we need to
1933  // construct element here
1934  element* const p(new_element(std::forward<Args>(args)...));
1935  typename cont_type::insert_commit_data d;
1936  auto const result(m_cont.insert_check(
1937  extract(p->value), std::cref(m_config.key_compare()), d));
1938  if (result.second)
1939  {
1940  auto const iter(m_cont.insert_commit(*p, d));
1941  chronological.list.push_back(*p);
1942  return std::make_pair(iterator(iter), true);
1943  }
1944  delete_element(p);
1945  return std::make_pair(iterator(result.first), false);
1946 }
1947 
1948 // multiset, multimap
1949 template <
1950  bool IsMulti,
1951  bool IsMap,
1952  class Key,
1953  class T,
1954  class Clock,
1955  class Compare,
1956  class Allocator>
1957 template <bool maybe_multi, class... Args>
1958 auto
1960  emplace(Args&&... args) ->
1962 {
1963  element* const p(new_element(std::forward<Args>(args)...));
1964  auto const before(m_cont.upper_bound(
1965  extract(p->value), std::cref(m_config.key_compare())));
1966  chronological.list.push_back(*p);
1967  auto const iter(m_cont.insert_before(before, *p));
1968  return iterator(iter);
1969 }
1970 
1971 // map, set
1972 template <
1973  bool IsMulti,
1974  bool IsMap,
1975  class Key,
1976  class T,
1977  class Clock,
1978  class Compare,
1979  class Allocator>
1980 template <bool maybe_multi, class... Args>
1981 auto
1983  emplace_hint(const_iterator hint, Args&&... args) ->
1985 {
1986  // VFALCO NOTE Its unfortunate that we need to
1987  // construct element here
1988  element* const p(new_element(std::forward<Args>(args)...));
1989  typename cont_type::insert_commit_data d;
1990  auto const result(m_cont.insert_check(
1991  hint.iterator(),
1992  extract(p->value),
1993  std::cref(m_config.key_compare()),
1994  d));
1995  if (result.second)
1996  {
1997  auto const iter(m_cont.insert_commit(*p, d));
1998  chronological.list.push_back(*p);
1999  return std::make_pair(iterator(iter), true);
2000  }
2001  delete_element(p);
2002  return std::make_pair(iterator(result.first), false);
2003 }
2004 
2005 template <
2006  bool IsMulti,
2007  bool IsMap,
2008  class Key,
2009  class T,
2010  class Clock,
2011  class Compare,
2012  class Allocator>
2013 template <bool is_const, class Iterator, class Base, class>
2017 {
2018  unlink_and_delete_element(&*((pos++).iterator()));
2020  pos.iterator());
2021 }
2022 
2023 template <
2024  bool IsMulti,
2025  bool IsMap,
2026  class Key,
2027  class T,
2028  class Clock,
2029  class Compare,
2030  class Allocator>
2031 template <bool is_const, class Iterator, class Base, class>
2037 {
2038  for (; first != last;)
2039  unlink_and_delete_element(&*((first++).iterator()));
2040 
2042  first.iterator());
2043 }
2044 
2045 template <
2046  bool IsMulti,
2047  bool IsMap,
2048  class Key,
2049  class T,
2050  class Clock,
2051  class Compare,
2052  class Allocator>
2053 template <class K>
2054 auto
2056  erase(K const& k) -> size_type
2057 {
2058  auto iter(m_cont.find(k, std::cref(m_config.key_compare())));
2059  if (iter == m_cont.end())
2060  return 0;
2061  size_type n(0);
2062  for (;;)
2063  {
2064  auto p(&*iter++);
2065  bool const done(m_config(*p, extract(iter->value)));
2066  unlink_and_delete_element(p);
2067  ++n;
2068  if (done)
2069  break;
2070  }
2071  return n;
2072 }
2073 
2074 template <
2075  bool IsMulti,
2076  bool IsMap,
2077  class Key,
2078  class T,
2079  class Clock,
2080  class Compare,
2081  class Allocator>
2082 void
2084  aged_ordered_container& other) noexcept
2085 {
2086  swap_data(other);
2087  std::swap(chronological, other.chronological);
2088  std::swap(m_cont, other.m_cont);
2089 }
2090 
2091 //------------------------------------------------------------------------------
2092 
2093 template <
2094  bool IsMulti,
2095  bool IsMap,
2096  class Key,
2097  class T,
2098  class Clock,
2099  class Compare,
2100  class Allocator>
2101 template <class K>
2102 auto
2104  touch(K const& k) -> size_type
2105 {
2106  auto const now(clock().now());
2107  size_type n(0);
2108  auto const range(equal_range(k));
2109  for (auto iter : range)
2110  {
2111  touch(iter, now);
2112  ++n;
2113  }
2114  return n;
2115 }
2116 
2117 //------------------------------------------------------------------------------
2118 
2119 template <
2120  bool IsMulti,
2121  bool IsMap,
2122  class Key,
2123  class T,
2124  class Clock,
2125  class Compare,
2126  class Allocator>
2127 template <
2128  bool OtherIsMulti,
2129  bool OtherIsMap,
2130  class OtherT,
2131  class OtherDuration,
2132  class OtherAllocator>
2133 bool
2136  OtherIsMulti,
2137  OtherIsMap,
2138  Key,
2139  OtherT,
2140  OtherDuration,
2141  Compare,
2142  OtherAllocator> const& other) const
2143 {
2144  using Other = aged_ordered_container<
2145  OtherIsMulti,
2146  OtherIsMap,
2147  Key,
2148  OtherT,
2149  OtherDuration,
2150  Compare,
2151  OtherAllocator>;
2152  if (size() != other.size())
2153  return false;
2155  return std::equal(
2156  cbegin(),
2157  cend(),
2158  other.cbegin(),
2159  other.cend(),
2160  [&eq, &other](
2161  value_type const& lhs, typename Other::value_type const& rhs) {
2162  return eq(extract(lhs), other.extract(rhs));
2163  });
2164 }
2165 
2166 //------------------------------------------------------------------------------
2167 
2168 template <
2169  bool IsMulti,
2170  bool IsMap,
2171  class Key,
2172  class T,
2173  class Clock,
2174  class Compare,
2175  class Allocator>
2176 template <bool is_const, class Iterator, class Base, class>
2177 void
2181  typename clock_type::time_point const& now)
2182 {
2183  auto& e(*pos.iterator());
2184  e.when = now;
2185  chronological.list.erase(chronological.list.iterator_to(e));
2186  chronological.list.push_back(e);
2187 }
2188 
2189 template <
2190  bool IsMulti,
2191  bool IsMap,
2192  class Key,
2193  class T,
2194  class Clock,
2195  class Compare,
2196  class Allocator>
2197 template <bool maybe_propagate>
2201 {
2202  std::swap(m_config.key_compare(), other.m_config.key_compare());
2203  std::swap(m_config.alloc(), other.m_config.alloc());
2204  std::swap(m_config.clock, other.m_config.clock);
2205 }
2206 
2207 template <
2208  bool IsMulti,
2209  bool IsMap,
2210  class Key,
2211  class T,
2212  class Clock,
2213  class Compare,
2214  class Allocator>
2215 template <bool maybe_propagate>
2218  swap_data(aged_ordered_container& other) noexcept
2219 {
2220  std::swap(m_config.key_compare(), other.m_config.key_compare());
2221  std::swap(m_config.clock, other.m_config.clock);
2222 }
2223 
2224 } // namespace detail
2225 
2226 //------------------------------------------------------------------------------
2227 
2228 template <
2229  bool IsMulti,
2230  bool IsMap,
2231  class Key,
2232  class T,
2233  class Clock,
2234  class Compare,
2235  class Allocator>
2237  IsMulti,
2238  IsMap,
2239  Key,
2240  T,
2241  Clock,
2242  Compare,
2243  Allocator>> : std::true_type
2244 {
2245  explicit is_aged_container() = default;
2246 };
2247 
2248 // Free functions
2249 
2250 template <
2251  bool IsMulti,
2252  bool IsMap,
2253  class Key,
2254  class T,
2255  class Clock,
2256  class Compare,
2257  class Allocator>
2258 void
2259 swap(
2261  IsMulti,
2262  IsMap,
2263  Key,
2264  T,
2265  Clock,
2266  Compare,
2267  Allocator>& lhs,
2269  IsMulti,
2270  IsMap,
2271  Key,
2272  T,
2273  Clock,
2274  Compare,
2275  Allocator>& rhs) noexcept
2276 {
2277  lhs.swap(rhs);
2278 }
2279 
2281 template <
2282  bool IsMulti,
2283  bool IsMap,
2284  class Key,
2285  class T,
2286  class Clock,
2287  class Compare,
2288  class Allocator,
2289  class Rep,
2290  class Period>
2294  IsMulti,
2295  IsMap,
2296  Key,
2297  T,
2298  Clock,
2299  Compare,
2300  Allocator>& c,
2302 {
2303  std::size_t n(0);
2304  auto const expired(c.clock().now() - age);
2305  for (auto iter(c.chronological.cbegin());
2306  iter != c.chronological.cend() && iter.when() <= expired;)
2307  {
2308  iter = c.erase(iter);
2309  ++n;
2310  }
2311  return n;
2312 }
2313 
2314 } // namespace beast
2315 
2316 #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::erase
beast::detail::aged_container_iterator< false, Iterator, Base > erase(beast::detail::aged_container_iterator< is_const, Iterator, Base > pos)
Definition: aged_ordered_container.h:2016
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:2135
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:1748
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:1231
std::false_type
beast::detail::aged_ordered_container::lower_bound
iterator lower_bound(K const &k)
Definition: aged_ordered_container.h:1087
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:1134
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:1650
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:1096
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:1769
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:1077
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:1288
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:117
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:1250
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:2200
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:1043
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:1212
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:1127
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:1576
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:2083
beast::detail::aged_ordered_container::find
iterator find(K const &k)
Definition: aged_ordered_container.h:1051
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:1929
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:1983
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:1172
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::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_ordered_container::upper_bound
iterator upper_bound(K const &k)
Definition: aged_ordered_container.h:1105
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:1689
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:1591
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:1114
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:1191
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
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
beast::detail::aged_container_iterator::iterator
Iterator const & iterator() const
Definition: aged_container_iterator.h:179
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:1068
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:1287
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:1059
type_traits
beast::detail::aged_container_iterator
Definition: aged_container_iterator.h:47
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::touch
void touch(beast::detail::aged_container_iterator< is_const, Iterator, Base > pos)
Definition: aged_ordered_container.h:1025
beast::detail::aged_ordered_container::allocator_type
Allocator allocator_type
Definition: aged_ordered_container.h:447
beast
Definition: base_uint.h:585