rippled
aged_unordered_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_UNORDERED_CONTAINER_H_INCLUDED
21 #define BEAST_CONTAINER_DETAIL_AGED_UNORDERED_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/unordered_set.hpp>
30 #include <algorithm>
31 #include <cmath>
32 #include <functional>
33 #include <initializer_list>
34 #include <iterator>
35 #include <memory>
36 #include <type_traits>
37 #include <utility>
38 
39 /*
40 
41 TODO
42 
43 - Add constructor variations that take a bucket count
44 
45 - Review for noexcept and exception guarantees
46 
47 - Call the safe version of is_permutation that takes 4 iterators
48 
49 */
50 
51 #ifndef BEAST_NO_CXX14_IS_PERMUTATION
52 #define BEAST_NO_CXX14_IS_PERMUTATION 1
53 #endif
54 
55 namespace beast {
56 namespace detail {
57 
75 template <
76  bool IsMulti,
77  bool IsMap,
78  class Key,
79  class T,
80  class Clock = std::chrono::steady_clock,
81  class Hash = std::hash<Key>,
82  class KeyEqual = std::equal_to<Key>,
83  class Allocator = std::allocator<
86 {
87 public:
90  using duration = typename clock_type::duration;
91  using key_type = Key;
92  using mapped_type = T;
93  using value_type =
97 
98  // Introspection (for unit tests)
102 
103 private:
104  static Key const&
105  extract(value_type const& value)
106  {
108  }
109 
110  // VFALCO TODO hoist to remove template argument dependencies
111  struct element
112  : boost::intrusive::unordered_set_base_hook<
113  boost::intrusive::link_mode<boost::intrusive::normal_link>>,
114  boost::intrusive::list_base_hook<
115  boost::intrusive::link_mode<boost::intrusive::normal_link>>
116  {
117  // Stash types here so the iterator doesn't
118  // need to see the container declaration.
119  struct stashed
120  {
121  explicit stashed() = default;
122 
125  };
126 
127  element(time_point const& when_, value_type const& value_)
128  : value(value_), when(when_)
129  {
130  }
131 
132  element(time_point const& when_, value_type&& value_)
133  : value(std::move(value_)), when(when_)
134  {
135  }
136 
137  template <
138  class... Args,
139  class = typename std::enable_if<
140  std::is_constructible<value_type, Args...>::value>::type>
141  element(time_point const& when_, Args&&... args)
142  : value(std::forward<Args>(args)...), when(when_)
143  {
144  }
145 
148  };
149 
150  // VFALCO TODO hoist to remove template argument dependencies
151  class ValueHash : public Hash
152  {
153  public:
155  using result_type = size_t;
156 
158  {
159  }
160 
161  ValueHash(Hash const& h) : Hash(h)
162  {
163  }
164 
166  operator()(element const& e) const
167  {
168  return Hash::operator()(extract(e.value));
169  }
170 
171  Hash&
173  {
174  return *this;
175  }
176 
177  Hash const&
179  {
180  return *this;
181  }
182  };
183 
184  // Compares value_type against element, used in find/insert_check
185  // VFALCO TODO hoist to remove template argument dependencies
186  class KeyValueEqual : public KeyEqual
187  {
188  public:
189  using first_argument_type = Key;
191  using result_type = bool;
192 
194  {
195  }
196 
197  KeyValueEqual(KeyEqual const& keyEqual) : KeyEqual(keyEqual)
198  {
199  }
200 
201  bool
202  operator()(Key const& k, element const& e) const
203  {
204  return KeyEqual::operator()(k, extract(e.value));
205  }
206 
207  bool
208  operator()(element const& e, Key const& k) const
209  {
210  return KeyEqual::operator()(extract(e.value), k);
211  }
212 
213  bool
214  operator()(element const& lhs, element const& rhs) const
215  {
216  return KeyEqual::operator()(extract(lhs.value), extract(rhs.value));
217  }
218 
219  KeyEqual&
221  {
222  return *this;
223  }
224 
225  KeyEqual const&
226  key_eq() const
227  {
228  return *this;
229  }
230  };
231 
232  using list_type = typename boost::intrusive::
233  make_list<element, boost::intrusive::constant_time_size<false>>::type;
234 
235  using cont_type = typename std::conditional<
236  IsMulti,
237  typename boost::intrusive::make_unordered_multiset<
238  element,
239  boost::intrusive::constant_time_size<true>,
240  boost::intrusive::hash<ValueHash>,
241  boost::intrusive::equal<KeyValueEqual>,
242  boost::intrusive::cache_begin<true>>::type,
243  typename boost::intrusive::make_unordered_set<
244  element,
245  boost::intrusive::constant_time_size<true>,
246  boost::intrusive::hash<ValueHash>,
247  boost::intrusive::equal<KeyValueEqual>,
248  boost::intrusive::cache_begin<true>>::type>::type;
249 
250  using bucket_type = typename cont_type::bucket_type;
251  using bucket_traits = typename cont_type::bucket_traits;
252 
253  using ElementAllocator = typename std::allocator_traits<
254  Allocator>::template rebind_alloc<element>;
255 
257 
258  using BucketAllocator = typename std::allocator_traits<
259  Allocator>::template rebind_alloc<element>;
260 
262 
263  class config_t
264  : private ValueHash,
265  private KeyValueEqual,
266  private beast::detail::empty_base_optimization<ElementAllocator>
267  {
268  public:
269  explicit config_t(clock_type& clock_) : clock(clock_)
270  {
271  }
272 
273  config_t(clock_type& clock_, Hash const& hash)
274  : ValueHash(hash), clock(clock_)
275  {
276  }
277 
278  config_t(clock_type& clock_, KeyEqual const& keyEqual)
279  : KeyValueEqual(keyEqual), clock(clock_)
280  {
281  }
282 
283  config_t(clock_type& clock_, Allocator const& alloc_)
285  , clock(clock_)
286  {
287  }
288 
289  config_t(clock_type& clock_, Hash const& hash, KeyEqual const& keyEqual)
290  : ValueHash(hash), KeyValueEqual(keyEqual), clock(clock_)
291  {
292  }
293 
294  config_t(clock_type& clock_, Hash const& hash, Allocator const& alloc_)
295  : ValueHash(hash)
297  , clock(clock_)
298  {
299  }
300 
302  clock_type& clock_,
303  KeyEqual const& keyEqual,
304  Allocator const& alloc_)
305  : KeyValueEqual(keyEqual)
307  , clock(clock_)
308  {
309  }
310 
312  clock_type& clock_,
313  Hash const& hash,
314  KeyEqual const& keyEqual,
315  Allocator const& alloc_)
316  : ValueHash(hash)
317  , KeyValueEqual(keyEqual)
319  , clock(clock_)
320  {
321  }
322 
323  config_t(config_t const& other)
324  : ValueHash(other.hash_function())
325  , KeyValueEqual(other.key_eq())
327  ElementAllocatorTraits::select_on_container_copy_construction(
328  other.alloc()))
329  , clock(other.clock)
330  {
331  }
332 
333  config_t(config_t const& other, Allocator const& alloc)
334  : ValueHash(other.hash_function())
335  , KeyValueEqual(other.key_eq())
337  , clock(other.clock)
338  {
339  }
340 
342  : ValueHash(std::move(other.hash_function()))
343  , KeyValueEqual(std::move(other.key_eq()))
345  std::move(other.alloc()))
346  , clock(other.clock)
347  {
348  }
349 
350  config_t(config_t&& other, Allocator const& alloc)
351  : ValueHash(std::move(other.hash_function()))
352  , KeyValueEqual(std::move(other.key_eq()))
354  , clock(other.clock)
355  {
356  }
357 
358  config_t&
359  operator=(config_t const& other)
360  {
361  hash_function() = other.hash_function();
362  key_eq() = other.key_eq();
363  alloc() = other.alloc();
364  clock = other.clock;
365  return *this;
366  }
367 
368  config_t&
370  {
371  hash_function() = std::move(other.hash_function());
372  key_eq() = std::move(other.key_eq());
373  alloc() = std::move(other.alloc());
374  clock = other.clock;
375  return *this;
376  }
377 
378  ValueHash&
380  {
381  return *this;
382  }
383 
384  ValueHash const&
385  value_hash() const
386  {
387  return *this;
388  }
389 
390  Hash&
392  {
393  return ValueHash::hash_function();
394  }
395 
396  Hash const&
398  {
399  return ValueHash::hash_function();
400  }
401 
404  {
405  return *this;
406  }
407 
408  KeyValueEqual const&
410  {
411  return *this;
412  }
413 
414  KeyEqual&
416  {
417  return key_value_equal().key_eq();
418  }
419 
420  KeyEqual const&
421  key_eq() const
422  {
423  return key_value_equal().key_eq();
424  }
425 
428  {
431  }
432 
433  ElementAllocator const&
434  alloc() const
435  {
438  }
439 
441  };
442 
443  class Buckets
444  {
445  public:
446  using vec_type = std::vector<
447  bucket_type,
448  typename std::allocator_traits<Allocator>::template rebind_alloc<
450 
452  {
453  m_vec.resize(cont_type::suggested_upper_bucket_count(0));
454  }
455 
456  Buckets(Allocator const& alloc) : m_max_load_factor(1.f), m_vec(alloc)
457  {
458  m_vec.resize(cont_type::suggested_upper_bucket_count(0));
459  }
460 
461  operator bucket_traits()
462  {
463  return bucket_traits(&m_vec[0], m_vec.size());
464  }
465 
466  void
468  {
469  m_vec.clear();
470  }
471 
472  size_type
474  {
475  return m_vec.max_size();
476  }
477 
478  float&
480  {
481  return m_max_load_factor;
482  }
483 
484  float const&
486  {
487  return m_max_load_factor;
488  }
489 
490  // count is the number of buckets
491  template <class Container>
492  void
493  rehash(size_type count, Container& c)
494  {
495  size_type const size(m_vec.size());
496  if (count == size)
497  return;
498  if (count > m_vec.capacity())
499  {
500  // Need two vectors otherwise we
501  // will destroy non-empty buckets.
503  std::swap(m_vec, vec);
504  m_vec.resize(count);
505  c.rehash(bucket_traits(&m_vec[0], m_vec.size()));
506  return;
507  }
508  // Rehash in place.
509  if (count > size)
510  {
511  // This should not reallocate since
512  // we checked capacity earlier.
513  m_vec.resize(count);
514  c.rehash(bucket_traits(&m_vec[0], count));
515  return;
516  }
517  // Resize must happen after rehash otherwise
518  // we might destroy non-empty buckets.
519  c.rehash(bucket_traits(&m_vec[0], count));
520  m_vec.resize(count);
521  }
522 
523  // Resize the buckets to accommodate at least n items.
524  template <class Container>
525  void
526  resize(size_type n, Container& c)
527  {
528  size_type const suggested(
529  cont_type::suggested_upper_bucket_count(n));
530  rehash(suggested, c);
531  }
532 
533  private:
536  };
537 
538  template <class... Args>
539  element*
540  new_element(Args&&... args)
541  {
542  struct Deleter
543  {
545  Deleter(ElementAllocator& a) : a_(a)
546  {
547  }
548 
549  void
550  operator()(element* p)
551  {
553  }
554  };
555 
558  Deleter(m_config.alloc()));
560  m_config.alloc(),
561  p.get(),
562  clock().now(),
563  std::forward<Args>(args)...);
564  return p.release();
565  }
566 
567  void
568  delete_element(element const* p)
569  {
572  m_config.alloc(), const_cast<element*>(p), 1);
573  }
574 
575  void
576  unlink_and_delete_element(element const* p)
577  {
578  chronological.list.erase(chronological.list.iterator_to(*p));
579  m_cont.erase(m_cont.iterator_to(*p));
580  delete_element(p);
581  }
582 
583 public:
584  using hasher = Hash;
585  using key_equal = KeyEqual;
586  using allocator_type = Allocator;
588  using const_reference = value_type const&;
590  using const_pointer =
592 
593  // A set iterator (IsMap==false) is always const
594  // because the elements of a set are immutable.
595  using iterator = beast::detail::
596  aged_container_iterator<!IsMap, typename cont_type::iterator>;
597  using const_iterator = beast::detail::
598  aged_container_iterator<true, typename cont_type::iterator>;
599 
600  using local_iterator = beast::detail::
601  aged_container_iterator<!IsMap, typename cont_type::local_iterator>;
602  using const_local_iterator = beast::detail::
603  aged_container_iterator<true, typename cont_type::local_iterator>;
604 
605  //--------------------------------------------------------------------------
606  //
607  // Chronological ordered iterators
608  //
609  // "Memberspace"
610  // http://accu.org/index.php/journals/1527
611  //
612  //--------------------------------------------------------------------------
613 
615  {
616  public:
617  // A set iterator (IsMap==false) is always const
618  // because the elements of a set are immutable.
619  using iterator = beast::detail::
620  aged_container_iterator<!IsMap, typename list_type::iterator>;
621  using const_iterator = beast::detail::
622  aged_container_iterator<true, typename list_type::iterator>;
624  !IsMap,
625  typename list_type::reverse_iterator>;
626  using const_reverse_iterator = beast::detail::
627  aged_container_iterator<true, typename list_type::reverse_iterator>;
628 
629  iterator
631  {
632  return iterator(list.begin());
633  }
634 
636  begin() const
637  {
638  return const_iterator(list.begin());
639  }
640 
642  cbegin() const
643  {
644  return const_iterator(list.begin());
645  }
646 
647  iterator
648  end()
649  {
650  return iterator(list.end());
651  }
652 
654  end() const
655  {
656  return const_iterator(list.end());
657  }
658 
660  cend() const
661  {
662  return const_iterator(list.end());
663  }
664 
667  {
668  return reverse_iterator(list.rbegin());
669  }
670 
672  rbegin() const
673  {
674  return const_reverse_iterator(list.rbegin());
675  }
676 
678  crbegin() const
679  {
680  return const_reverse_iterator(list.rbegin());
681  }
682 
685  {
686  return reverse_iterator(list.rend());
687  }
688 
690  rend() const
691  {
692  return const_reverse_iterator(list.rend());
693  }
694 
696  crend() const
697  {
698  return const_reverse_iterator(list.rend());
699  }
700 
701  iterator
703  {
704  static_assert(
706  "must be standard layout");
707  return list.iterator_to(*reinterpret_cast<element*>(
708  reinterpret_cast<uint8_t*>(&value) -
709  ((std::size_t)std::addressof(((element*)0)->member))));
710  }
711 
713  iterator_to(value_type const& value) const
714  {
715  static_assert(
717  "must be standard layout");
718  return list.iterator_to(*reinterpret_cast<element const*>(
719  reinterpret_cast<uint8_t const*>(&value) -
720  ((std::size_t)std::addressof(((element*)0)->member))));
721  }
722 
723  private:
725  {
726  }
727 
728  chronological_t(chronological_t const&) = delete;
729  chronological_t(chronological_t&&) = delete;
730 
732  list_type mutable list;
733  } chronological;
734 
735  //--------------------------------------------------------------------------
736  //
737  // Construction
738  //
739  //--------------------------------------------------------------------------
740 
741  aged_unordered_container() = delete;
742 
744 
745  aged_unordered_container(clock_type& clock, Hash const& hash);
746 
747  aged_unordered_container(clock_type& clock, KeyEqual const& key_eq);
748 
749  aged_unordered_container(clock_type& clock, Allocator const& alloc);
750 
752  clock_type& clock,
753  Hash const& hash,
754  KeyEqual const& key_eq);
755 
757  clock_type& clock,
758  Hash const& hash,
759  Allocator const& alloc);
760 
762  clock_type& clock,
763  KeyEqual const& key_eq,
764  Allocator const& alloc);
765 
767  clock_type& clock,
768  Hash const& hash,
769  KeyEqual const& key_eq,
770  Allocator const& alloc);
771 
772  template <class InputIt>
773  aged_unordered_container(InputIt first, InputIt last, clock_type& clock);
774 
775  template <class InputIt>
777  InputIt first,
778  InputIt last,
779  clock_type& clock,
780  Hash const& hash);
781 
782  template <class InputIt>
784  InputIt first,
785  InputIt last,
786  clock_type& clock,
787  KeyEqual const& key_eq);
788 
789  template <class InputIt>
791  InputIt first,
792  InputIt last,
793  clock_type& clock,
794  Allocator const& alloc);
795 
796  template <class InputIt>
798  InputIt first,
799  InputIt last,
800  clock_type& clock,
801  Hash const& hash,
802  KeyEqual const& key_eq);
803 
804  template <class InputIt>
806  InputIt first,
807  InputIt last,
808  clock_type& clock,
809  Hash const& hash,
810  Allocator const& alloc);
811 
812  template <class InputIt>
814  InputIt first,
815  InputIt last,
816  clock_type& clock,
817  KeyEqual const& key_eq,
818  Allocator const& alloc);
819 
820  template <class InputIt>
822  InputIt first,
823  InputIt last,
824  clock_type& clock,
825  Hash const& hash,
826  KeyEqual const& key_eq,
827  Allocator const& alloc);
828 
830 
832  aged_unordered_container const& other,
833  Allocator const& alloc);
834 
836 
838  aged_unordered_container&& other,
839  Allocator const& alloc);
840 
843  clock_type& clock);
844 
847  clock_type& clock,
848  Hash const& hash);
849 
852  clock_type& clock,
853  KeyEqual const& key_eq);
854 
857  clock_type& clock,
858  Allocator const& alloc);
859 
862  clock_type& clock,
863  Hash const& hash,
864  KeyEqual const& key_eq);
865 
868  clock_type& clock,
869  Hash const& hash,
870  Allocator const& alloc);
871 
874  clock_type& clock,
875  KeyEqual const& key_eq,
876  Allocator const& alloc);
877 
880  clock_type& clock,
881  Hash const& hash,
882  KeyEqual const& key_eq,
883  Allocator const& alloc);
884 
886 
888  operator=(aged_unordered_container const& other);
889 
892 
895 
898  {
899  return m_config.alloc();
900  }
901 
902  clock_type&
904  {
905  return m_config.clock;
906  }
907 
908  clock_type const&
909  clock() const
910  {
911  return m_config.clock;
912  }
913 
914  //--------------------------------------------------------------------------
915  //
916  // Element access (maps)
917  //
918  //--------------------------------------------------------------------------
919 
920  template <
921  class K,
922  bool maybe_multi = IsMulti,
923  bool maybe_map = IsMap,
926  at(K const& k);
927 
928  template <
929  class K,
930  bool maybe_multi = IsMulti,
931  bool maybe_map = IsMap,
934  at(K const& k) const;
935 
936  template <
937  bool maybe_multi = IsMulti,
938  bool maybe_map = IsMap,
941  operator[](Key const& key);
942 
943  template <
944  bool maybe_multi = IsMulti,
945  bool maybe_map = IsMap,
948  operator[](Key&& key);
949 
950  //--------------------------------------------------------------------------
951  //
952  // Iterators
953  //
954  //--------------------------------------------------------------------------
955 
956  iterator
958  {
959  return iterator(m_cont.begin());
960  }
961 
963  begin() const
964  {
965  return const_iterator(m_cont.begin());
966  }
967 
969  cbegin() const
970  {
971  return const_iterator(m_cont.begin());
972  }
973 
974  iterator
975  end()
976  {
977  return iterator(m_cont.end());
978  }
979 
981  end() const
982  {
983  return const_iterator(m_cont.end());
984  }
985 
987  cend() const
988  {
989  return const_iterator(m_cont.end());
990  }
991 
992  iterator
994  {
995  static_assert(
996  std::is_standard_layout<element>::value, "must be standard layout");
997  return m_cont.iterator_to(*reinterpret_cast<element*>(
998  reinterpret_cast<uint8_t*>(&value) -
999  ((std::size_t)std::addressof(((element*)0)->member))));
1000  }
1001 
1003  iterator_to(value_type const& value) const
1004  {
1005  static_assert(
1006  std::is_standard_layout<element>::value, "must be standard layout");
1007  return m_cont.iterator_to(*reinterpret_cast<element const*>(
1008  reinterpret_cast<uint8_t const*>(&value) -
1009  ((std::size_t)std::addressof(((element*)0)->member))));
1010  }
1011 
1012  //--------------------------------------------------------------------------
1013  //
1014  // Capacity
1015  //
1016  //--------------------------------------------------------------------------
1017 
1018  bool
1019  empty() const noexcept
1020  {
1021  return m_cont.empty();
1022  }
1023 
1024  size_type
1025  size() const noexcept
1026  {
1027  return m_cont.size();
1028  }
1029 
1030  size_type
1031  max_size() const noexcept
1032  {
1033  return m_config.max_size();
1034  }
1035 
1036  //--------------------------------------------------------------------------
1037  //
1038  // Modifiers
1039  //
1040  //--------------------------------------------------------------------------
1041 
1042  void
1043  clear();
1044 
1045  // map, set
1046  template <bool maybe_multi = IsMulti>
1047  auto
1048  insert(value_type const& value) ->
1050 
1051  // multimap, multiset
1052  template <bool maybe_multi = IsMulti>
1053  auto
1054  insert(value_type const& value) ->
1056 
1057  // map, set
1058  template <bool maybe_multi = IsMulti, bool maybe_map = IsMap>
1059  auto
1060  insert(value_type&& value) -> typename std::
1061  enable_if<!maybe_multi && !maybe_map, std::pair<iterator, bool>>::type;
1062 
1063  // multimap, multiset
1064  template <bool maybe_multi = IsMulti, bool maybe_map = IsMap>
1065  auto
1066  insert(value_type&& value) ->
1068 
1069  // map, set
1070  template <bool maybe_multi = IsMulti>
1072  insert(const_iterator /*hint*/, value_type const& value)
1073  {
1074  // Hint is ignored but we provide the interface so
1075  // callers may use ordered and unordered interchangeably.
1076  return insert(value).first;
1077  }
1078 
1079  // multimap, multiset
1080  template <bool maybe_multi = IsMulti>
1082  insert(const_iterator /*hint*/, value_type const& value)
1083  {
1084  // VFALCO TODO The hint could be used to let
1085  // the client order equal ranges
1086  return insert(value);
1087  }
1088 
1089  // map, set
1090  template <bool maybe_multi = IsMulti>
1092  insert(const_iterator /*hint*/, value_type&& value)
1093  {
1094  // Hint is ignored but we provide the interface so
1095  // callers may use ordered and unordered interchangeably.
1096  return insert(std::move(value)).first;
1097  }
1098 
1099  // multimap, multiset
1100  template <bool maybe_multi = IsMulti>
1102  insert(const_iterator /*hint*/, value_type&& value)
1103  {
1104  // VFALCO TODO The hint could be used to let
1105  // the client order equal ranges
1106  return insert(std::move(value));
1107  }
1108 
1109  // map, multimap
1110  template <class P, bool maybe_map = IsMap>
1111  typename std::enable_if<
1113  typename std::
1114  conditional<IsMulti, iterator, std::pair<iterator, bool>>::type>::
1115  type
1116  insert(P&& value)
1117  {
1118  return emplace(std::forward<P>(value));
1119  }
1120 
1121  // map, multimap
1122  template <class P, bool maybe_map = IsMap>
1123  typename std::enable_if<
1125  typename std::
1126  conditional<IsMulti, iterator, std::pair<iterator, bool>>::type>::
1127  type
1128  insert(const_iterator hint, P&& value)
1129  {
1130  return emplace_hint(hint, std::forward<P>(value));
1131  }
1132 
1133  template <class InputIt>
1134  void
1135  insert(InputIt first, InputIt last)
1136  {
1137  insert(
1138  first,
1139  last,
1141  }
1142 
1143  void
1145  {
1146  insert(init.begin(), init.end());
1147  }
1148 
1149  // set, map
1150  template <bool maybe_multi = IsMulti, class... Args>
1151  auto
1152  emplace(Args&&... args) ->
1154 
1155  // multiset, multimap
1156  template <bool maybe_multi = IsMulti, class... Args>
1157  auto
1158  emplace(Args&&... args) ->
1160 
1161  // set, map
1162  template <bool maybe_multi = IsMulti, class... Args>
1163  auto
1164  emplace_hint(const_iterator /*hint*/, Args&&... args) ->
1166 
1167  // multiset, multimap
1168  template <bool maybe_multi = IsMulti, class... Args>
1170  emplace_hint(const_iterator /*hint*/, Args&&... args)
1171  {
1172  // VFALCO TODO The hint could be used for multi, to let
1173  // the client order equal ranges
1174  return emplace<maybe_multi>(std::forward<Args>(args)...);
1175  }
1176 
1177  template <bool is_const, class Iterator>
1180 
1181  template <bool is_const, class Iterator>
1183  erase(
1186 
1187  /*
1188  * This is broken as of at least gcc 11.3.0
1189  template <class K>
1190  auto
1191  erase(K const& k) -> size_type;
1192  */
1193 
1194  void
1195  swap(aged_unordered_container& other) noexcept;
1196 
1197  template <bool is_const, class Iterator>
1198  void
1200  {
1201  touch(pos, clock().now());
1202  }
1203 
1204  template <class K>
1205  auto
1206  touch(K const& k) -> size_type;
1207 
1208  //--------------------------------------------------------------------------
1209  //
1210  // Lookup
1211  //
1212  //--------------------------------------------------------------------------
1213 
1214  // VFALCO TODO Respect is_transparent (c++14)
1215  template <class K>
1216  size_type
1217  count(K const& k) const
1218  {
1219  return m_cont.count(
1220  k,
1223  }
1224 
1225  // VFALCO TODO Respect is_transparent (c++14)
1226  template <class K>
1227  iterator
1228  find(K const& k)
1229  {
1230  return iterator(m_cont.find(
1231  k,
1234  }
1235 
1236  // VFALCO TODO Respect is_transparent (c++14)
1237  template <class K>
1239  find(K const& k) const
1240  {
1241  return const_iterator(m_cont.find(
1242  k,
1245  }
1246 
1247  // VFALCO TODO Respect is_transparent (c++14)
1248  template <class K>
1250  equal_range(K const& k)
1251  {
1252  auto const r(m_cont.equal_range(
1253  k,
1256  return std::make_pair(iterator(r.first), iterator(r.second));
1257  }
1258 
1259  // VFALCO TODO Respect is_transparent (c++14)
1260  template <class K>
1262  equal_range(K const& k) const
1263  {
1264  auto const r(m_cont.equal_range(
1265  k,
1268  return std::make_pair(
1269  const_iterator(r.first), const_iterator(r.second));
1270  }
1271 
1272  //--------------------------------------------------------------------------
1273  //
1274  // Bucket interface
1275  //
1276  //--------------------------------------------------------------------------
1277 
1280  {
1281  return local_iterator(m_cont.begin(n));
1282  }
1283 
1285  begin(size_type n) const
1286  {
1287  return const_local_iterator(m_cont.begin(n));
1288  }
1289 
1292  {
1293  return const_local_iterator(m_cont.begin(n));
1294  }
1295 
1298  {
1299  return local_iterator(m_cont.end(n));
1300  }
1301 
1303  end(size_type n) const
1304  {
1305  return const_local_iterator(m_cont.end(n));
1306  }
1307 
1309  cend(size_type n) const
1310  {
1311  return const_local_iterator(m_cont.end(n));
1312  }
1313 
1314  size_type
1316  {
1317  return m_cont.bucket_count();
1318  }
1319 
1320  size_type
1322  {
1323  return m_buck.max_bucket_count();
1324  }
1325 
1326  size_type
1328  {
1329  return m_cont.bucket_size(n);
1330  }
1331 
1332  size_type
1333  bucket(Key const& k) const
1334  {
1335  assert(bucket_count() != 0);
1336  return m_cont.bucket(k, std::cref(m_config.hash_function()));
1337  }
1338 
1339  //--------------------------------------------------------------------------
1340  //
1341  // Hash policy
1342  //
1343  //--------------------------------------------------------------------------
1344 
1345  float
1346  load_factor() const
1347  {
1348  return size() / static_cast<float>(m_cont.bucket_count());
1349  }
1350 
1351  float
1353  {
1354  return m_buck.max_load_factor();
1355  }
1356 
1357  void
1359  {
1361  }
1362 
1363  void
1365  {
1368  }
1369 
1370  void
1372  {
1374  }
1375 
1376  //--------------------------------------------------------------------------
1377  //
1378  // Observers
1379  //
1380  //--------------------------------------------------------------------------
1381 
1382  hasher const&
1384  {
1385  return m_config.hash_function();
1386  }
1387 
1388  key_equal const&
1389  key_eq() const
1390  {
1391  return m_config.key_eq();
1392  }
1393 
1394  //--------------------------------------------------------------------------
1395  //
1396  // Comparison
1397  //
1398  //--------------------------------------------------------------------------
1399 
1400  // This differs from the standard in that the comparison
1401  // is only done on the key portion of the value type, ignoring
1402  // the mapped type.
1403  //
1404  template <
1405  bool OtherIsMap,
1406  class OtherKey,
1407  class OtherT,
1408  class OtherDuration,
1409  class OtherHash,
1410  class OtherAllocator,
1411  bool maybe_multi = IsMulti>
1414  false,
1415  OtherIsMap,
1416  OtherKey,
1417  OtherT,
1418  OtherDuration,
1419  OtherHash,
1420  KeyEqual,
1421  OtherAllocator> const& other) const;
1422 
1423  template <
1424  bool OtherIsMap,
1425  class OtherKey,
1426  class OtherT,
1427  class OtherDuration,
1428  class OtherHash,
1429  class OtherAllocator,
1430  bool maybe_multi = IsMulti>
1433  true,
1434  OtherIsMap,
1435  OtherKey,
1436  OtherT,
1437  OtherDuration,
1438  OtherHash,
1439  KeyEqual,
1440  OtherAllocator> const& other) const;
1441 
1442  template <
1443  bool OtherIsMulti,
1444  bool OtherIsMap,
1445  class OtherKey,
1446  class OtherT,
1447  class OtherDuration,
1448  class OtherHash,
1449  class OtherAllocator>
1450  bool
1452  OtherIsMulti,
1453  OtherIsMap,
1454  OtherKey,
1455  OtherT,
1456  OtherDuration,
1457  OtherHash,
1458  KeyEqual,
1459  OtherAllocator> const& other) const
1460  {
1461  return !(this->operator==(other));
1462  }
1463 
1464 private:
1465  bool
1466  would_exceed(size_type additional) const
1467  {
1468  return size() + additional > bucket_count() * max_load_factor();
1469  }
1470 
1471  void
1473  {
1474  if (would_exceed(additional))
1475  m_buck.resize(size() + additional, m_cont);
1476  assert(load_factor() <= max_load_factor());
1477  }
1478 
1479  // map, set
1480  template <bool maybe_multi = IsMulti>
1481  auto
1482  insert_unchecked(value_type const& value) ->
1484 
1485  // multimap, multiset
1486  template <bool maybe_multi = IsMulti>
1487  auto
1488  insert_unchecked(value_type const& value) ->
1490 
1491  template <class InputIt>
1492  void
1493  insert_unchecked(InputIt first, InputIt last)
1494  {
1495  for (; first != last; ++first)
1496  insert_unchecked(*first);
1497  }
1498 
1499  template <class InputIt>
1500  void
1501  insert(InputIt first, InputIt last, std::input_iterator_tag)
1502  {
1503  for (; first != last; ++first)
1504  insert(*first);
1505  }
1506 
1507  template <class InputIt>
1508  void
1509  insert(InputIt first, InputIt last, std::random_access_iterator_tag)
1510  {
1511  auto const n(std::distance(first, last));
1512  maybe_rehash(n);
1513  insert_unchecked(first, last);
1514  }
1515 
1516  template <bool is_const, class Iterator>
1517  void
1520  typename clock_type::time_point const& now)
1521  {
1522  auto& e(*pos.iterator());
1523  e.when = now;
1524  chronological.list.erase(chronological.list.iterator_to(e));
1525  chronological.list.push_back(e);
1526  }
1527 
1528  template <
1529  bool maybe_propagate = std::allocator_traits<
1530  Allocator>::propagate_on_container_swap::value>
1533  {
1534  std::swap(m_config.key_compare(), other.m_config.key_compare());
1535  std::swap(m_config.alloc(), other.m_config.alloc());
1536  std::swap(m_config.clock, other.m_config.clock);
1537  }
1538 
1539  template <
1540  bool maybe_propagate = std::allocator_traits<
1541  Allocator>::propagate_on_container_swap::value>
1544  {
1545  std::swap(m_config.key_compare(), other.m_config.key_compare());
1546  std::swap(m_config.clock, other.m_config.clock);
1547  }
1548 
1549 private:
1550  config_t m_config;
1551  Buckets m_buck;
1553 };
1554 
1555 //------------------------------------------------------------------------------
1556 
1557 template <
1558  bool IsMulti,
1559  bool IsMap,
1560  class Key,
1561  class T,
1562  class Clock,
1563  class Hash,
1564  class KeyEqual,
1565  class Allocator>
1567  IsMulti,
1568  IsMap,
1569  Key,
1570  T,
1571  Clock,
1572  Hash,
1573  KeyEqual,
1575  : m_config(clock)
1576  , m_cont(
1577  m_buck,
1578  std::cref(m_config.value_hash()),
1579  std::cref(m_config.key_value_equal()))
1580 {
1581 }
1582 
1583 template <
1584  bool IsMulti,
1585  bool IsMap,
1586  class Key,
1587  class T,
1588  class Clock,
1589  class Hash,
1590  class KeyEqual,
1591  class Allocator>
1593  IsMulti,
1594  IsMap,
1595  Key,
1596  T,
1597  Clock,
1598  Hash,
1599  KeyEqual,
1600  Allocator>::aged_unordered_container(clock_type& clock, Hash const& hash)
1601  : m_config(clock, hash)
1602  , m_cont(
1603  m_buck,
1604  std::cref(m_config.value_hash()),
1605  std::cref(m_config.key_value_equal()))
1606 {
1607 }
1608 
1609 template <
1610  bool IsMulti,
1611  bool IsMap,
1612  class Key,
1613  class T,
1614  class Clock,
1615  class Hash,
1616  class KeyEqual,
1617  class Allocator>
1619  IsMulti,
1620  IsMap,
1621  Key,
1622  T,
1623  Clock,
1624  Hash,
1625  KeyEqual,
1626  Allocator>::
1627  aged_unordered_container(clock_type& clock, KeyEqual const& key_eq)
1628  : m_config(clock, key_eq)
1629  , m_cont(
1630  m_buck,
1631  std::cref(m_config.value_hash()),
1632  std::cref(m_config.key_value_equal()))
1633 {
1634 }
1635 
1636 template <
1637  bool IsMulti,
1638  bool IsMap,
1639  class Key,
1640  class T,
1641  class Clock,
1642  class Hash,
1643  class KeyEqual,
1644  class Allocator>
1646  IsMulti,
1647  IsMap,
1648  Key,
1649  T,
1650  Clock,
1651  Hash,
1652  KeyEqual,
1653  Allocator>::
1654  aged_unordered_container(clock_type& clock, Allocator const& alloc)
1655  : m_config(clock, alloc)
1656  , m_buck(alloc)
1657  , m_cont(
1658  m_buck,
1659  std::cref(m_config.value_hash()),
1660  std::cref(m_config.key_value_equal()))
1661 {
1662 }
1663 
1664 template <
1665  bool IsMulti,
1666  bool IsMap,
1667  class Key,
1668  class T,
1669  class Clock,
1670  class Hash,
1671  class KeyEqual,
1672  class Allocator>
1674  IsMulti,
1675  IsMap,
1676  Key,
1677  T,
1678  Clock,
1679  Hash,
1680  KeyEqual,
1681  Allocator>::
1682  aged_unordered_container(
1683  clock_type& clock,
1684  Hash const& hash,
1685  KeyEqual const& key_eq)
1686  : m_config(clock, hash, key_eq)
1687  , m_cont(
1688  m_buck,
1689  std::cref(m_config.value_hash()),
1690  std::cref(m_config.key_value_equal()))
1691 {
1692 }
1693 
1694 template <
1695  bool IsMulti,
1696  bool IsMap,
1697  class Key,
1698  class T,
1699  class Clock,
1700  class Hash,
1701  class KeyEqual,
1702  class Allocator>
1704  IsMulti,
1705  IsMap,
1706  Key,
1707  T,
1708  Clock,
1709  Hash,
1710  KeyEqual,
1711  Allocator>::
1712  aged_unordered_container(
1713  clock_type& clock,
1714  Hash const& hash,
1715  Allocator const& alloc)
1716  : m_config(clock, hash, alloc)
1717  , m_buck(alloc)
1718  , m_cont(
1719  m_buck,
1720  std::cref(m_config.value_hash()),
1721  std::cref(m_config.key_value_equal()))
1722 {
1723 }
1724 
1725 template <
1726  bool IsMulti,
1727  bool IsMap,
1728  class Key,
1729  class T,
1730  class Clock,
1731  class Hash,
1732  class KeyEqual,
1733  class Allocator>
1735  IsMulti,
1736  IsMap,
1737  Key,
1738  T,
1739  Clock,
1740  Hash,
1741  KeyEqual,
1742  Allocator>::
1743  aged_unordered_container(
1744  clock_type& clock,
1745  KeyEqual const& key_eq,
1746  Allocator const& alloc)
1747  : m_config(clock, key_eq, alloc)
1748  , m_buck(alloc)
1749  , m_cont(
1750  m_buck,
1751  std::cref(m_config.value_hash()),
1752  std::cref(m_config.key_value_equal()))
1753 {
1754 }
1755 
1756 template <
1757  bool IsMulti,
1758  bool IsMap,
1759  class Key,
1760  class T,
1761  class Clock,
1762  class Hash,
1763  class KeyEqual,
1764  class Allocator>
1766  IsMulti,
1767  IsMap,
1768  Key,
1769  T,
1770  Clock,
1771  Hash,
1772  KeyEqual,
1773  Allocator>::
1774  aged_unordered_container(
1775  clock_type& clock,
1776  Hash const& hash,
1777  KeyEqual const& key_eq,
1778  Allocator const& alloc)
1779  : m_config(clock, hash, key_eq, alloc)
1780  , m_buck(alloc)
1781  , m_cont(
1782  m_buck,
1783  std::cref(m_config.value_hash()),
1784  std::cref(m_config.key_value_equal()))
1785 {
1786 }
1787 
1788 template <
1789  bool IsMulti,
1790  bool IsMap,
1791  class Key,
1792  class T,
1793  class Clock,
1794  class Hash,
1795  class KeyEqual,
1796  class Allocator>
1797 template <class InputIt>
1799  IsMulti,
1800  IsMap,
1801  Key,
1802  T,
1803  Clock,
1804  Hash,
1805  KeyEqual,
1806  Allocator>::
1807  aged_unordered_container(InputIt first, InputIt last, clock_type& clock)
1808  : m_config(clock)
1809  , m_cont(
1810  m_buck,
1811  std::cref(m_config.value_hash()),
1812  std::cref(m_config.key_value_equal()))
1813 {
1814  insert(first, last);
1815 }
1816 
1817 template <
1818  bool IsMulti,
1819  bool IsMap,
1820  class Key,
1821  class T,
1822  class Clock,
1823  class Hash,
1824  class KeyEqual,
1825  class Allocator>
1826 template <class InputIt>
1828  IsMulti,
1829  IsMap,
1830  Key,
1831  T,
1832  Clock,
1833  Hash,
1834  KeyEqual,
1835  Allocator>::
1836  aged_unordered_container(
1837  InputIt first,
1838  InputIt last,
1839  clock_type& clock,
1840  Hash const& hash)
1841  : m_config(clock, hash)
1842  , m_cont(
1843  m_buck,
1844  std::cref(m_config.value_hash()),
1845  std::cref(m_config.key_value_equal()))
1846 {
1847  insert(first, last);
1848 }
1849 
1850 template <
1851  bool IsMulti,
1852  bool IsMap,
1853  class Key,
1854  class T,
1855  class Clock,
1856  class Hash,
1857  class KeyEqual,
1858  class Allocator>
1859 template <class InputIt>
1861  IsMulti,
1862  IsMap,
1863  Key,
1864  T,
1865  Clock,
1866  Hash,
1867  KeyEqual,
1868  Allocator>::
1869  aged_unordered_container(
1870  InputIt first,
1871  InputIt last,
1872  clock_type& clock,
1873  KeyEqual const& key_eq)
1874  : m_config(clock, key_eq)
1875  , m_cont(
1876  m_buck,
1877  std::cref(m_config.value_hash()),
1878  std::cref(m_config.key_value_equal()))
1879 {
1880  insert(first, last);
1881 }
1882 
1883 template <
1884  bool IsMulti,
1885  bool IsMap,
1886  class Key,
1887  class T,
1888  class Clock,
1889  class Hash,
1890  class KeyEqual,
1891  class Allocator>
1892 template <class InputIt>
1894  IsMulti,
1895  IsMap,
1896  Key,
1897  T,
1898  Clock,
1899  Hash,
1900  KeyEqual,
1901  Allocator>::
1902  aged_unordered_container(
1903  InputIt first,
1904  InputIt last,
1905  clock_type& clock,
1906  Allocator const& alloc)
1907  : m_config(clock, alloc)
1908  , m_buck(alloc)
1909  , m_cont(
1910  m_buck,
1911  std::cref(m_config.value_hash()),
1912  std::cref(m_config.key_value_equal()))
1913 {
1914  insert(first, last);
1915 }
1916 
1917 template <
1918  bool IsMulti,
1919  bool IsMap,
1920  class Key,
1921  class T,
1922  class Clock,
1923  class Hash,
1924  class KeyEqual,
1925  class Allocator>
1926 template <class InputIt>
1928  IsMulti,
1929  IsMap,
1930  Key,
1931  T,
1932  Clock,
1933  Hash,
1934  KeyEqual,
1935  Allocator>::
1936  aged_unordered_container(
1937  InputIt first,
1938  InputIt last,
1939  clock_type& clock,
1940  Hash const& hash,
1941  KeyEqual const& key_eq)
1942  : m_config(clock, hash, key_eq)
1943  , m_cont(
1944  m_buck,
1945  std::cref(m_config.value_hash()),
1946  std::cref(m_config.key_value_equal()))
1947 {
1948  insert(first, last);
1949 }
1950 
1951 template <
1952  bool IsMulti,
1953  bool IsMap,
1954  class Key,
1955  class T,
1956  class Clock,
1957  class Hash,
1958  class KeyEqual,
1959  class Allocator>
1960 template <class InputIt>
1962  IsMulti,
1963  IsMap,
1964  Key,
1965  T,
1966  Clock,
1967  Hash,
1968  KeyEqual,
1969  Allocator>::
1970  aged_unordered_container(
1971  InputIt first,
1972  InputIt last,
1973  clock_type& clock,
1974  Hash const& hash,
1975  Allocator const& alloc)
1976  : m_config(clock, hash, alloc)
1977  , m_buck(alloc)
1978  , m_cont(
1979  m_buck,
1980  std::cref(m_config.value_hash()),
1981  std::cref(m_config.key_value_equal()))
1982 {
1983  insert(first, last);
1984 }
1985 
1986 template <
1987  bool IsMulti,
1988  bool IsMap,
1989  class Key,
1990  class T,
1991  class Clock,
1992  class Hash,
1993  class KeyEqual,
1994  class Allocator>
1995 template <class InputIt>
1997  IsMulti,
1998  IsMap,
1999  Key,
2000  T,
2001  Clock,
2002  Hash,
2003  KeyEqual,
2004  Allocator>::
2005  aged_unordered_container(
2006  InputIt first,
2007  InputIt last,
2008  clock_type& clock,
2009  KeyEqual const& key_eq,
2010  Allocator const& alloc)
2011  : m_config(clock, key_eq, alloc)
2012  , m_buck(alloc)
2013  , m_cont(
2014  m_buck,
2015  std::cref(m_config.value_hash()),
2016  std::cref(m_config.key_value_equal()))
2017 {
2018  insert(first, last);
2019 }
2020 
2021 template <
2022  bool IsMulti,
2023  bool IsMap,
2024  class Key,
2025  class T,
2026  class Clock,
2027  class Hash,
2028  class KeyEqual,
2029  class Allocator>
2030 template <class InputIt>
2032  IsMulti,
2033  IsMap,
2034  Key,
2035  T,
2036  Clock,
2037  Hash,
2038  KeyEqual,
2039  Allocator>::
2040  aged_unordered_container(
2041  InputIt first,
2042  InputIt last,
2043  clock_type& clock,
2044  Hash const& hash,
2045  KeyEqual const& key_eq,
2046  Allocator const& alloc)
2047  : m_config(clock, hash, key_eq, alloc)
2048  , m_buck(alloc)
2049  , m_cont(
2050  m_buck,
2051  std::cref(m_config.value_hash()),
2052  std::cref(m_config.key_value_equal()))
2053 {
2054  insert(first, last);
2055 }
2056 
2057 template <
2058  bool IsMulti,
2059  bool IsMap,
2060  class Key,
2061  class T,
2062  class Clock,
2063  class Hash,
2064  class KeyEqual,
2065  class Allocator>
2067  IsMulti,
2068  IsMap,
2069  Key,
2070  T,
2071  Clock,
2072  Hash,
2073  KeyEqual,
2075  : m_config(other.m_config)
2076  , m_buck(m_config.alloc())
2077  , m_cont(
2078  m_buck,
2079  std::cref(m_config.value_hash()),
2080  std::cref(m_config.key_value_equal()))
2081 {
2082  insert(other.cbegin(), other.cend());
2083 }
2084 
2085 template <
2086  bool IsMulti,
2087  bool IsMap,
2088  class Key,
2089  class T,
2090  class Clock,
2091  class Hash,
2092  class KeyEqual,
2093  class Allocator>
2095  IsMulti,
2096  IsMap,
2097  Key,
2098  T,
2099  Clock,
2100  Hash,
2101  KeyEqual,
2102  Allocator>::
2103  aged_unordered_container(
2104  aged_unordered_container const& other,
2105  Allocator const& alloc)
2106  : m_config(other.m_config, alloc)
2107  , m_buck(alloc)
2108  , m_cont(
2109  m_buck,
2110  std::cref(m_config.value_hash()),
2111  std::cref(m_config.key_value_equal()))
2112 {
2113  insert(other.cbegin(), other.cend());
2114 }
2115 
2116 template <
2117  bool IsMulti,
2118  bool IsMap,
2119  class Key,
2120  class T,
2121  class Clock,
2122  class Hash,
2123  class KeyEqual,
2124  class Allocator>
2126  IsMulti,
2127  IsMap,
2128  Key,
2129  T,
2130  Clock,
2131  Hash,
2132  KeyEqual,
2134  : m_config(std::move(other.m_config))
2135  , m_buck(std::move(other.m_buck))
2136  , m_cont(std::move(other.m_cont))
2137 {
2138  chronological.list = std::move(other.chronological.list);
2139 }
2140 
2141 template <
2142  bool IsMulti,
2143  bool IsMap,
2144  class Key,
2145  class T,
2146  class Clock,
2147  class Hash,
2148  class KeyEqual,
2149  class Allocator>
2151  IsMulti,
2152  IsMap,
2153  Key,
2154  T,
2155  Clock,
2156  Hash,
2157  KeyEqual,
2158  Allocator>::
2159  aged_unordered_container(
2160  aged_unordered_container&& other,
2161  Allocator const& alloc)
2162  : m_config(std::move(other.m_config), alloc)
2163  , m_buck(alloc)
2164  , m_cont(
2165  m_buck,
2166  std::cref(m_config.value_hash()),
2167  std::cref(m_config.key_value_equal()))
2168 {
2169  insert(other.cbegin(), other.cend());
2170  other.clear();
2171 }
2172 
2173 template <
2174  bool IsMulti,
2175  bool IsMap,
2176  class Key,
2177  class T,
2178  class Clock,
2179  class Hash,
2180  class KeyEqual,
2181  class Allocator>
2183  IsMulti,
2184  IsMap,
2185  Key,
2186  T,
2187  Clock,
2188  Hash,
2189  KeyEqual,
2190  Allocator>::
2191  aged_unordered_container(
2193  clock_type& clock)
2194  : m_config(clock)
2195  , m_cont(
2196  m_buck,
2197  std::cref(m_config.value_hash()),
2198  std::cref(m_config.key_value_equal()))
2199 {
2200  insert(init.begin(), init.end());
2201 }
2202 
2203 template <
2204  bool IsMulti,
2205  bool IsMap,
2206  class Key,
2207  class T,
2208  class Clock,
2209  class Hash,
2210  class KeyEqual,
2211  class Allocator>
2213  IsMulti,
2214  IsMap,
2215  Key,
2216  T,
2217  Clock,
2218  Hash,
2219  KeyEqual,
2220  Allocator>::
2221  aged_unordered_container(
2223  clock_type& clock,
2224  Hash const& hash)
2225  : m_config(clock, hash)
2226  , m_cont(
2227  m_buck,
2228  std::cref(m_config.value_hash()),
2229  std::cref(m_config.key_value_equal()))
2230 {
2231  insert(init.begin(), init.end());
2232 }
2233 
2234 template <
2235  bool IsMulti,
2236  bool IsMap,
2237  class Key,
2238  class T,
2239  class Clock,
2240  class Hash,
2241  class KeyEqual,
2242  class Allocator>
2244  IsMulti,
2245  IsMap,
2246  Key,
2247  T,
2248  Clock,
2249  Hash,
2250  KeyEqual,
2251  Allocator>::
2252  aged_unordered_container(
2254  clock_type& clock,
2255  KeyEqual const& key_eq)
2256  : m_config(clock, key_eq)
2257  , m_cont(
2258  m_buck,
2259  std::cref(m_config.value_hash()),
2260  std::cref(m_config.key_value_equal()))
2261 {
2262  insert(init.begin(), init.end());
2263 }
2264 
2265 template <
2266  bool IsMulti,
2267  bool IsMap,
2268  class Key,
2269  class T,
2270  class Clock,
2271  class Hash,
2272  class KeyEqual,
2273  class Allocator>
2275  IsMulti,
2276  IsMap,
2277  Key,
2278  T,
2279  Clock,
2280  Hash,
2281  KeyEqual,
2282  Allocator>::
2283  aged_unordered_container(
2285  clock_type& clock,
2286  Allocator const& alloc)
2287  : m_config(clock, alloc)
2288  , m_buck(alloc)
2289  , m_cont(
2290  m_buck,
2291  std::cref(m_config.value_hash()),
2292  std::cref(m_config.key_value_equal()))
2293 {
2294  insert(init.begin(), init.end());
2295 }
2296 
2297 template <
2298  bool IsMulti,
2299  bool IsMap,
2300  class Key,
2301  class T,
2302  class Clock,
2303  class Hash,
2304  class KeyEqual,
2305  class Allocator>
2307  IsMulti,
2308  IsMap,
2309  Key,
2310  T,
2311  Clock,
2312  Hash,
2313  KeyEqual,
2314  Allocator>::
2315  aged_unordered_container(
2317  clock_type& clock,
2318  Hash const& hash,
2319  KeyEqual const& key_eq)
2320  : m_config(clock, hash, key_eq)
2321  , m_cont(
2322  m_buck,
2323  std::cref(m_config.value_hash()),
2324  std::cref(m_config.key_value_equal()))
2325 {
2326  insert(init.begin(), init.end());
2327 }
2328 
2329 template <
2330  bool IsMulti,
2331  bool IsMap,
2332  class Key,
2333  class T,
2334  class Clock,
2335  class Hash,
2336  class KeyEqual,
2337  class Allocator>
2339  IsMulti,
2340  IsMap,
2341  Key,
2342  T,
2343  Clock,
2344  Hash,
2345  KeyEqual,
2346  Allocator>::
2347  aged_unordered_container(
2349  clock_type& clock,
2350  Hash const& hash,
2351  Allocator const& alloc)
2352  : m_config(clock, hash, alloc)
2353  , m_buck(alloc)
2354  , m_cont(
2355  m_buck,
2356  std::cref(m_config.value_hash()),
2357  std::cref(m_config.key_value_equal()))
2358 {
2359  insert(init.begin(), init.end());
2360 }
2361 
2362 template <
2363  bool IsMulti,
2364  bool IsMap,
2365  class Key,
2366  class T,
2367  class Clock,
2368  class Hash,
2369  class KeyEqual,
2370  class Allocator>
2372  IsMulti,
2373  IsMap,
2374  Key,
2375  T,
2376  Clock,
2377  Hash,
2378  KeyEqual,
2379  Allocator>::
2380  aged_unordered_container(
2382  clock_type& clock,
2383  KeyEqual const& key_eq,
2384  Allocator const& alloc)
2385  : m_config(clock, key_eq, alloc)
2386  , m_buck(alloc)
2387  , m_cont(
2388  m_buck,
2389  std::cref(m_config.value_hash()),
2390  std::cref(m_config.key_value_equal()))
2391 {
2392  insert(init.begin(), init.end());
2393 }
2394 
2395 template <
2396  bool IsMulti,
2397  bool IsMap,
2398  class Key,
2399  class T,
2400  class Clock,
2401  class Hash,
2402  class KeyEqual,
2403  class Allocator>
2405  IsMulti,
2406  IsMap,
2407  Key,
2408  T,
2409  Clock,
2410  Hash,
2411  KeyEqual,
2412  Allocator>::
2413  aged_unordered_container(
2415  clock_type& clock,
2416  Hash const& hash,
2417  KeyEqual const& key_eq,
2418  Allocator const& alloc)
2419  : m_config(clock, hash, key_eq, alloc)
2420  , m_buck(alloc)
2421  , m_cont(
2422  m_buck,
2423  std::cref(m_config.value_hash()),
2424  std::cref(m_config.key_value_equal()))
2425 {
2426  insert(init.begin(), init.end());
2427 }
2428 
2429 template <
2430  bool IsMulti,
2431  bool IsMap,
2432  class Key,
2433  class T,
2434  class Clock,
2435  class Hash,
2436  class KeyEqual,
2437  class Allocator>
2439  IsMulti,
2440  IsMap,
2441  Key,
2442  T,
2443  Clock,
2444  Hash,
2445  KeyEqual,
2446  Allocator>::~aged_unordered_container()
2447 {
2448  clear();
2449 }
2450 
2451 template <
2452  bool IsMulti,
2453  bool IsMap,
2454  class Key,
2455  class T,
2456  class Clock,
2457  class Hash,
2458  class KeyEqual,
2459  class Allocator>
2460 auto
2462  IsMulti,
2463  IsMap,
2464  Key,
2465  T,
2466  Clock,
2467  Hash,
2468  KeyEqual,
2469  Allocator>::operator=(aged_unordered_container const& other)
2471 {
2472  if (this != &other)
2473  {
2474  size_type const n(other.size());
2475  clear();
2476  m_config = other.m_config;
2477  m_buck = Buckets(m_config.alloc());
2478  maybe_rehash(n);
2479  insert_unchecked(other.begin(), other.end());
2480  }
2481  return *this;
2482 }
2483 
2484 template <
2485  bool IsMulti,
2486  bool IsMap,
2487  class Key,
2488  class T,
2489  class Clock,
2490  class Hash,
2491  class KeyEqual,
2492  class Allocator>
2493 auto
2495  IsMulti,
2496  IsMap,
2497  Key,
2498  T,
2499  Clock,
2500  Hash,
2501  KeyEqual,
2502  Allocator>::operator=(aged_unordered_container&& other)
2504 {
2505  size_type const n(other.size());
2506  clear();
2507  m_config = std::move(other.m_config);
2508  m_buck = Buckets(m_config.alloc());
2509  maybe_rehash(n);
2510  insert_unchecked(other.begin(), other.end());
2511  other.clear();
2512  return *this;
2513 }
2514 
2515 template <
2516  bool IsMulti,
2517  bool IsMap,
2518  class Key,
2519  class T,
2520  class Clock,
2521  class Hash,
2522  class KeyEqual,
2523  class Allocator>
2524 auto
2526  IsMulti,
2527  IsMap,
2528  Key,
2529  T,
2530  Clock,
2531  Hash,
2532  KeyEqual,
2533  Allocator>::operator=(std::initializer_list<value_type> init)
2535 {
2536  clear();
2537  insert(init);
2538  return *this;
2539 }
2540 
2541 //------------------------------------------------------------------------------
2542 
2543 template <
2544  bool IsMulti,
2545  bool IsMap,
2546  class Key,
2547  class T,
2548  class Clock,
2549  class Hash,
2550  class KeyEqual,
2551  class Allocator>
2552 template <class K, bool maybe_multi, bool maybe_map, class>
2555  IsMulti,
2556  IsMap,
2557  Key,
2558  T,
2559  Clock,
2560  Hash,
2561  KeyEqual,
2562  Allocator>::at(K const& k)
2563 {
2564  auto const iter(m_cont.find(
2565  k,
2566  std::cref(m_config.hash_function()),
2567  std::cref(m_config.key_value_equal())));
2568  if (iter == m_cont.end())
2569  throw std::out_of_range("key not found");
2570  return iter->value.second;
2571 }
2572 
2573 template <
2574  bool IsMulti,
2575  bool IsMap,
2576  class Key,
2577  class T,
2578  class Clock,
2579  class Hash,
2580  class KeyEqual,
2581  class Allocator>
2582 template <class K, bool maybe_multi, bool maybe_map, class>
2585  IsMulti,
2586  IsMap,
2587  Key,
2588  T,
2589  Clock,
2590  Hash,
2591  KeyEqual,
2592  Allocator>::at(K const& k) const
2593 {
2594  auto const iter(m_cont.find(
2595  k,
2596  std::cref(m_config.hash_function()),
2597  std::cref(m_config.key_value_equal())));
2598  if (iter == m_cont.end())
2599  throw std::out_of_range("key not found");
2600  return iter->value.second;
2601 }
2602 
2603 template <
2604  bool IsMulti,
2605  bool IsMap,
2606  class Key,
2607  class T,
2608  class Clock,
2609  class Hash,
2610  class KeyEqual,
2611  class Allocator>
2612 template <bool maybe_multi, bool maybe_map, class>
2615  IsMulti,
2616  IsMap,
2617  Key,
2618  T,
2619  Clock,
2620  Hash,
2621  KeyEqual,
2622  Allocator>::operator[](Key const& key)
2623 {
2624  maybe_rehash(1);
2625  typename cont_type::insert_commit_data d;
2626  auto const result(m_cont.insert_check(
2627  key,
2628  std::cref(m_config.hash_function()),
2629  std::cref(m_config.key_value_equal()),
2630  d));
2631  if (result.second)
2632  {
2633  element* const p(new_element(
2634  std::piecewise_construct,
2635  std::forward_as_tuple(key),
2637  m_cont.insert_commit(*p, d);
2638  chronological.list.push_back(*p);
2639  return p->value.second;
2640  }
2641  return result.first->value.second;
2642 }
2643 
2644 template <
2645  bool IsMulti,
2646  bool IsMap,
2647  class Key,
2648  class T,
2649  class Clock,
2650  class Hash,
2651  class KeyEqual,
2652  class Allocator>
2653 template <bool maybe_multi, bool maybe_map, class>
2656  IsMulti,
2657  IsMap,
2658  Key,
2659  T,
2660  Clock,
2661  Hash,
2662  KeyEqual,
2663  Allocator>::operator[](Key&& key)
2664 {
2665  maybe_rehash(1);
2666  typename cont_type::insert_commit_data d;
2667  auto const result(m_cont.insert_check(
2668  key,
2669  std::cref(m_config.hash_function()),
2670  std::cref(m_config.key_value_equal()),
2671  d));
2672  if (result.second)
2673  {
2674  element* const p(new_element(
2675  std::piecewise_construct,
2676  std::forward_as_tuple(std::move(key)),
2678  m_cont.insert_commit(*p, d);
2679  chronological.list.push_back(*p);
2680  return p->value.second;
2681  }
2682  return result.first->value.second;
2683 }
2684 
2685 //------------------------------------------------------------------------------
2686 
2687 template <
2688  bool IsMulti,
2689  bool IsMap,
2690  class Key,
2691  class T,
2692  class Clock,
2693  class Hash,
2694  class KeyEqual,
2695  class Allocator>
2696 void
2698  IsMulti,
2699  IsMap,
2700  Key,
2701  T,
2702  Clock,
2703  Hash,
2704  KeyEqual,
2705  Allocator>::clear()
2706 {
2707  for (auto iter(chronological.list.begin());
2708  iter != chronological.list.end();)
2709  unlink_and_delete_element(&*iter++);
2710  chronological.list.clear();
2711  m_cont.clear();
2712  m_buck.clear();
2713 }
2714 
2715 // map, set
2716 template <
2717  bool IsMulti,
2718  bool IsMap,
2719  class Key,
2720  class T,
2721  class Clock,
2722  class Hash,
2723  class KeyEqual,
2724  class Allocator>
2725 template <bool maybe_multi>
2726 auto
2728  IsMulti,
2729  IsMap,
2730  Key,
2731  T,
2732  Clock,
2733  Hash,
2734  KeyEqual,
2735  Allocator>::insert(value_type const& value) ->
2737 {
2738  maybe_rehash(1);
2739  typename cont_type::insert_commit_data d;
2740  auto const result(m_cont.insert_check(
2741  extract(value),
2742  std::cref(m_config.hash_function()),
2743  std::cref(m_config.key_value_equal()),
2744  d));
2745  if (result.second)
2746  {
2747  element* const p(new_element(value));
2748  auto const iter(m_cont.insert_commit(*p, d));
2749  chronological.list.push_back(*p);
2750  return std::make_pair(iterator(iter), true);
2751  }
2752  return std::make_pair(iterator(result.first), false);
2753 }
2754 
2755 // multimap, multiset
2756 template <
2757  bool IsMulti,
2758  bool IsMap,
2759  class Key,
2760  class T,
2761  class Clock,
2762  class Hash,
2763  class KeyEqual,
2764  class Allocator>
2765 template <bool maybe_multi>
2766 auto
2768  IsMulti,
2769  IsMap,
2770  Key,
2771  T,
2772  Clock,
2773  Hash,
2774  KeyEqual,
2775  Allocator>::insert(value_type const& value) ->
2777 {
2778  maybe_rehash(1);
2779  element* const p(new_element(value));
2780  chronological.list.push_back(*p);
2781  auto const iter(m_cont.insert(*p));
2782  return iterator(iter);
2783 }
2784 
2785 // map, set
2786 template <
2787  bool IsMulti,
2788  bool IsMap,
2789  class Key,
2790  class T,
2791  class Clock,
2792  class Hash,
2793  class KeyEqual,
2794  class Allocator>
2795 template <bool maybe_multi, bool maybe_map>
2796 auto
2797 aged_unordered_container<
2798  IsMulti,
2799  IsMap,
2800  Key,
2801  T,
2802  Clock,
2803  Hash,
2804  KeyEqual,
2805  Allocator>::insert(value_type&& value) -> typename std::
2806  enable_if<!maybe_multi && !maybe_map, std::pair<iterator, bool>>::type
2807 {
2808  maybe_rehash(1);
2809  typename cont_type::insert_commit_data d;
2810  auto const result(m_cont.insert_check(
2811  extract(value),
2812  std::cref(m_config.hash_function()),
2813  std::cref(m_config.key_value_equal()),
2814  d));
2815  if (result.second)
2816  {
2817  element* const p(new_element(std::move(value)));
2818  auto const iter(m_cont.insert_commit(*p, d));
2819  chronological.list.push_back(*p);
2820  return std::make_pair(iterator(iter), true);
2821  }
2822  return std::make_pair(iterator(result.first), false);
2823 }
2824 
2825 // multimap, multiset
2826 template <
2827  bool IsMulti,
2828  bool IsMap,
2829  class Key,
2830  class T,
2831  class Clock,
2832  class Hash,
2833  class KeyEqual,
2834  class Allocator>
2835 template <bool maybe_multi, bool maybe_map>
2836 auto
2838  IsMulti,
2839  IsMap,
2840  Key,
2841  T,
2842  Clock,
2843  Hash,
2844  KeyEqual,
2845  Allocator>::insert(value_type&& value) ->
2847 {
2848  maybe_rehash(1);
2849  element* const p(new_element(std::move(value)));
2850  chronological.list.push_back(*p);
2851  auto const iter(m_cont.insert(*p));
2852  return iterator(iter);
2853 }
2854 
2855 #if 1 // Use insert() instead of insert_check() insert_commit()
2856 // set, map
2857 template <
2858  bool IsMulti,
2859  bool IsMap,
2860  class Key,
2861  class T,
2862  class Clock,
2863  class Hash,
2864  class KeyEqual,
2865  class Allocator>
2866 template <bool maybe_multi, class... Args>
2867 auto
2868 aged_unordered_container<
2869  IsMulti,
2870  IsMap,
2871  Key,
2872  T,
2873  Clock,
2874  Hash,
2875  KeyEqual,
2876  Allocator>::emplace(Args&&... args) ->
2878 {
2879  maybe_rehash(1);
2880  // VFALCO NOTE Its unfortunate that we need to
2881  // construct element here
2882  element* const p(new_element(std::forward<Args>(args)...));
2883  auto const result(m_cont.insert(*p));
2884  if (result.second)
2885  {
2886  chronological.list.push_back(*p);
2887  return std::make_pair(iterator(result.first), true);
2888  }
2889  delete_element(p);
2890  return std::make_pair(iterator(result.first), false);
2891 }
2892 #else // As original, use insert_check() / insert_commit () pair.
2893 // set, map
2894 template <
2895  bool IsMulti,
2896  bool IsMap,
2897  class Key,
2898  class T,
2899  class Clock,
2900  class Hash,
2901  class KeyEqual,
2902  class Allocator>
2903 template <bool maybe_multi, class... Args>
2904 auto
2906  IsMulti,
2907  IsMap,
2908  Key,
2909  T,
2910  Clock,
2911  Hash,
2912  KeyEqual,
2913  Allocator>::emplace(Args&&... args) ->
2915 {
2916  maybe_rehash(1);
2917  // VFALCO NOTE Its unfortunate that we need to
2918  // construct element here
2919  element* const p(new_element(std::forward<Args>(args)...));
2920  typename cont_type::insert_commit_data d;
2921  auto const result(m_cont.insert_check(
2922  extract(p->value),
2923  std::cref(m_config.hash_function()),
2924  std::cref(m_config.key_value_equal()),
2925  d));
2926  if (result.second)
2927  {
2928  auto const iter(m_cont.insert_commit(*p, d));
2929  chronological.list.push_back(*p);
2930  return std::make_pair(iterator(iter), true);
2931  }
2932  delete_element(p);
2933  return std::make_pair(iterator(result.first), false);
2934 }
2935 #endif // 0
2936 
2937 // multiset, multimap
2938 template <
2939  bool IsMulti,
2940  bool IsMap,
2941  class Key,
2942  class T,
2943  class Clock,
2944  class Hash,
2945  class KeyEqual,
2946  class Allocator>
2947 template <bool maybe_multi, class... Args>
2948 auto
2949 aged_unordered_container<
2950  IsMulti,
2951  IsMap,
2952  Key,
2953  T,
2954  Clock,
2955  Hash,
2956  KeyEqual,
2957  Allocator>::emplace(Args&&... args) ->
2959 {
2960  maybe_rehash(1);
2961  element* const p(new_element(std::forward<Args>(args)...));
2962  chronological.list.push_back(*p);
2963  auto const iter(m_cont.insert(*p));
2964  return iterator(iter);
2965 }
2966 
2967 // set, map
2968 template <
2969  bool IsMulti,
2970  bool IsMap,
2971  class Key,
2972  class T,
2973  class Clock,
2974  class Hash,
2975  class KeyEqual,
2976  class Allocator>
2977 template <bool maybe_multi, class... Args>
2978 auto
2979 aged_unordered_container<
2980  IsMulti,
2981  IsMap,
2982  Key,
2983  T,
2984  Clock,
2985  Hash,
2986  KeyEqual,
2987  Allocator>::emplace_hint(const_iterator /*hint*/, Args&&... args) ->
2989 {
2990  maybe_rehash(1);
2991  // VFALCO NOTE Its unfortunate that we need to
2992  // construct element here
2993  element* const p(new_element(std::forward<Args>(args)...));
2994  typename cont_type::insert_commit_data d;
2995  auto const result(m_cont.insert_check(
2996  extract(p->value),
2997  std::cref(m_config.hash_function()),
2998  std::cref(m_config.key_value_equal()),
2999  d));
3000  if (result.second)
3001  {
3002  auto const iter(m_cont.insert_commit(*p, d));
3003  chronological.list.push_back(*p);
3004  return std::make_pair(iterator(iter), true);
3005  }
3006  delete_element(p);
3007  return std::make_pair(iterator(result.first), false);
3008 }
3009 
3010 template <
3011  bool IsMulti,
3012  bool IsMap,
3013  class Key,
3014  class T,
3015  class Clock,
3016  class Hash,
3017  class KeyEqual,
3018  class Allocator>
3019 template <bool is_const, class Iterator>
3022  IsMulti,
3023  IsMap,
3024  Key,
3025  T,
3026  Clock,
3027  Hash,
3028  KeyEqual,
3030  pos)
3031 {
3032  unlink_and_delete_element(&*((pos++).iterator()));
3034  pos.iterator());
3035 }
3036 
3037 template <
3038  bool IsMulti,
3039  bool IsMap,
3040  class Key,
3041  class T,
3042  class Clock,
3043  class Hash,
3044  class KeyEqual,
3045  class Allocator>
3046 template <bool is_const, class Iterator>
3049  IsMulti,
3050  IsMap,
3051  Key,
3052  T,
3053  Clock,
3054  Hash,
3055  KeyEqual,
3056  Allocator>::
3057  erase(
3060 {
3061  for (; first != last;)
3062  unlink_and_delete_element(&*((first++).iterator()));
3063 
3065  first.iterator());
3066 }
3067 
3068 /*
3069 template <
3070  bool IsMulti,
3071  bool IsMap,
3072  class Key,
3073  class T,
3074  class Clock,
3075  class Hash,
3076  class KeyEqual,
3077  class Allocator>
3078 template <class K>
3079 auto
3080 aged_unordered_container<
3081  IsMulti,
3082  IsMap,
3083  Key,
3084  T,
3085  Clock,
3086  Hash,
3087  KeyEqual,
3088  Allocator>::erase(K const& k) -> size_type
3089 {
3090  auto iter(m_cont.find(
3091  k,
3092  std::cref(m_config.hash_function()),
3093  std::cref(m_config.key_value_equal())));
3094  if (iter == m_cont.end())
3095  return 0;
3096  size_type n(0);
3097  for (;;)
3098  {
3099  auto p(&*iter++);
3100  bool const done(m_config(*p, extract(iter->value)));
3101  unlink_and_delete_element(p);
3102  ++n;
3103  if (done)
3104  break;
3105  }
3106  return n;
3107 }
3108 */
3109 
3110 template <
3111  bool IsMulti,
3112  bool IsMap,
3113  class Key,
3114  class T,
3115  class Clock,
3116  class Hash,
3117  class KeyEqual,
3118  class Allocator>
3119 void
3121  IsMulti,
3122  IsMap,
3123  Key,
3124  T,
3125  Clock,
3126  Hash,
3127  KeyEqual,
3128  Allocator>::swap(aged_unordered_container& other) noexcept
3129 {
3130  swap_data(other);
3131  std::swap(chronological, other.chronological);
3132  std::swap(m_cont, other.m_cont);
3133 }
3134 
3135 template <
3136  bool IsMulti,
3137  bool IsMap,
3138  class Key,
3139  class T,
3140  class Clock,
3141  class Hash,
3142  class KeyEqual,
3143  class Allocator>
3144 template <class K>
3145 auto
3147  IsMulti,
3148  IsMap,
3149  Key,
3150  T,
3151  Clock,
3152  Hash,
3153  KeyEqual,
3154  Allocator>::touch(K const& k) -> size_type
3155 {
3156  auto const now(clock().now());
3157  size_type n(0);
3158  auto const range(equal_range(k));
3159  for (auto iter : range)
3160  {
3161  touch(iter, now);
3162  ++n;
3163  }
3164  return n;
3165 }
3166 
3167 template <
3168  bool IsMulti,
3169  bool IsMap,
3170  class Key,
3171  class T,
3172  class Clock,
3173  class Hash,
3174  class KeyEqual,
3175  class Allocator>
3176 template <
3177  bool OtherIsMap,
3178  class OtherKey,
3179  class OtherT,
3180  class OtherDuration,
3181  class OtherHash,
3182  class OtherAllocator,
3183  bool maybe_multi>
3186  IsMulti,
3187  IsMap,
3188  Key,
3189  T,
3190  Clock,
3191  Hash,
3192  KeyEqual,
3193  Allocator>::
3195  false,
3196  OtherIsMap,
3197  OtherKey,
3198  OtherT,
3199  OtherDuration,
3200  OtherHash,
3201  KeyEqual,
3202  OtherAllocator> const& other) const
3203 {
3204  if (size() != other.size())
3205  return false;
3206  for (auto iter(cbegin()), last(cend()), olast(other.cend()); iter != last;
3207  ++iter)
3208  {
3209  auto oiter(other.find(extract(*iter)));
3210  if (oiter == olast)
3211  return false;
3212  }
3213  return true;
3214 }
3215 
3216 template <
3217  bool IsMulti,
3218  bool IsMap,
3219  class Key,
3220  class T,
3221  class Clock,
3222  class Hash,
3223  class KeyEqual,
3224  class Allocator>
3225 template <
3226  bool OtherIsMap,
3227  class OtherKey,
3228  class OtherT,
3229  class OtherDuration,
3230  class OtherHash,
3231  class OtherAllocator,
3232  bool maybe_multi>
3235  IsMulti,
3236  IsMap,
3237  Key,
3238  T,
3239  Clock,
3240  Hash,
3241  KeyEqual,
3242  Allocator>::
3244  true,
3245  OtherIsMap,
3246  OtherKey,
3247  OtherT,
3248  OtherDuration,
3249  OtherHash,
3250  KeyEqual,
3251  OtherAllocator> const& other) const
3252 {
3253  if (size() != other.size())
3254  return false;
3256  for (auto iter(cbegin()), last(cend()); iter != last;)
3257  {
3258  auto const& k(extract(*iter));
3259  auto const eq(equal_range(k));
3260  auto const oeq(other.equal_range(k));
3261 #if BEAST_NO_CXX14_IS_PERMUTATION
3262  if (std::distance(eq.first, eq.second) !=
3263  std::distance(oeq.first, oeq.second) ||
3264  !std::is_permutation(eq.first, eq.second, oeq.first))
3265  return false;
3266 #else
3267  if (!std::is_permutation(eq.first, eq.second, oeq.first, oeq.second))
3268  return false;
3269 #endif
3270  iter = eq.second;
3271  }
3272  return true;
3273 }
3274 
3275 //------------------------------------------------------------------------------
3276 
3277 // map, set
3278 template <
3279  bool IsMulti,
3280  bool IsMap,
3281  class Key,
3282  class T,
3283  class Clock,
3284  class Hash,
3285  class KeyEqual,
3286  class Allocator>
3287 template <bool maybe_multi>
3288 auto
3290  IsMulti,
3291  IsMap,
3292  Key,
3293  T,
3294  Clock,
3295  Hash,
3296  KeyEqual,
3297  Allocator>::insert_unchecked(value_type const& value) ->
3299 {
3300  typename cont_type::insert_commit_data d;
3301  auto const result(m_cont.insert_check(
3302  extract(value),
3303  std::cref(m_config.hash_function()),
3304  std::cref(m_config.key_value_equal()),
3305  d));
3306  if (result.second)
3307  {
3308  element* const p(new_element(value));
3309  auto const iter(m_cont.insert_commit(*p, d));
3310  chronological.list.push_back(*p);
3311  return std::make_pair(iterator(iter), true);
3312  }
3313  return std::make_pair(iterator(result.first), false);
3314 }
3315 
3316 // multimap, multiset
3317 template <
3318  bool IsMulti,
3319  bool IsMap,
3320  class Key,
3321  class T,
3322  class Clock,
3323  class Hash,
3324  class KeyEqual,
3325  class Allocator>
3326 template <bool maybe_multi>
3327 auto
3329  IsMulti,
3330  IsMap,
3331  Key,
3332  T,
3333  Clock,
3334  Hash,
3335  KeyEqual,
3336  Allocator>::insert_unchecked(value_type const& value) ->
3338 {
3339  element* const p(new_element(value));
3340  chronological.list.push_back(*p);
3341  auto const iter(m_cont.insert(*p));
3342  return iterator(iter);
3343 }
3344 
3345 //------------------------------------------------------------------------------
3346 
3347 } // namespace detail
3348 
3349 //------------------------------------------------------------------------------
3350 
3351 template <
3352  bool IsMulti,
3353  bool IsMap,
3354  class Key,
3355  class T,
3356  class Clock,
3357  class Hash,
3358  class KeyEqual,
3359  class Allocator>
3361  IsMulti,
3362  IsMap,
3363  Key,
3364  T,
3365  Clock,
3366  Hash,
3367  KeyEqual,
3368  Allocator>> : std::true_type
3369 {
3370  explicit is_aged_container() = default;
3371 };
3372 
3373 // Free functions
3374 
3375 template <
3376  bool IsMulti,
3377  bool IsMap,
3378  class Key,
3379  class T,
3380  class Clock,
3381  class Hash,
3382  class KeyEqual,
3383  class Allocator>
3384 void
3385 swap(
3387  IsMulti,
3388  IsMap,
3389  Key,
3390  T,
3391  Clock,
3392  Hash,
3393  KeyEqual,
3394  Allocator>& lhs,
3396  IsMulti,
3397  IsMap,
3398  Key,
3399  T,
3400  Clock,
3401  Hash,
3402  KeyEqual,
3403  Allocator>& rhs) noexcept
3404 {
3405  lhs.swap(rhs);
3406 }
3407 
3409 template <
3410  bool IsMulti,
3411  bool IsMap,
3412  class Key,
3413  class T,
3414  class Clock,
3415  class Hash,
3416  class KeyEqual,
3417  class Allocator,
3418  class Rep,
3419  class Period>
3423  IsMulti,
3424  IsMap,
3425  Key,
3426  T,
3427  Clock,
3428  Hash,
3429  KeyEqual,
3430  Allocator>& c,
3431  std::chrono::duration<Rep, Period> const& age) noexcept
3432 {
3433  std::size_t n(0);
3434  auto const expired(c.clock().now() - age);
3435  for (auto iter(c.chronological.cbegin());
3436  iter != c.chronological.cend() && iter.when() <= expired;)
3437  {
3438  iter = c.erase(iter);
3439  ++n;
3440  }
3441  return n;
3442 }
3443 
3444 } // namespace beast
3445 
3446 #endif
beast::detail::aged_unordered_container::end
iterator end()
Definition: aged_unordered_container.h:975
beast::detail::aged_unordered_container::chronological_t::rend
reverse_iterator rend()
Definition: aged_unordered_container.h:684
std::is_standard_layout
beast::detail::aged_unordered_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_unordered_container.h:1116
beast::detail::aged_unordered_container< ID, std::unordered_map< NodeID, Validation >, std::chrono::steady_clock, beast::uhash<> >::time_point
typename clock_type::time_point time_point
Definition: aged_unordered_container.h:89
beast::detail::aged_unordered_container::KeyValueEqual::key_eq
KeyEqual & key_eq()
Definition: aged_unordered_container.h:220
beast::detail::aged_unordered_container::KeyValueEqual::operator()
bool operator()(element const &e, Key const &k) const
Definition: aged_unordered_container.h:208
beast::detail::aged_unordered_container::begin
const_local_iterator begin(size_type n) const
Definition: aged_unordered_container.h:1285
beast::detail::aged_unordered_container::ValueHash::operator()
std::size_t operator()(element const &e) const
Definition: aged_unordered_container.h:166
beast::detail::aged_unordered_container::config_t::config_t
config_t(clock_type &clock_)
Definition: aged_unordered_container.h:269
beast::detail::aged_unordered_container::unlink_and_delete_element
void unlink_and_delete_element(element const *p)
Definition: aged_unordered_container.h:576
std::chrono::steady_clock
beast::detail::aged_unordered_container::element::stashed::time_point
typename aged_unordered_container::time_point time_point
Definition: aged_unordered_container.h:124
std::vector::resize
T resize(T... args)
beast::detail::aged_unordered_container::rehash
void rehash(size_type count)
Definition: aged_unordered_container.h:1364
beast::detail::aged_unordered_container::max_load_factor
void max_load_factor(float ml)
Definition: aged_unordered_container.h:1358
beast::detail::aged_unordered_container::KeyValueEqual::KeyValueEqual
KeyValueEqual()
Definition: aged_unordered_container.h:193
beast::detail::aged_unordered_container< ID, std::unordered_map< NodeID, Validation >, std::chrono::steady_clock, beast::uhash<> >::bucket_type
typename cont_type::bucket_type bucket_type
Definition: aged_unordered_container.h:250
std::true_type
beast::detail::aged_unordered_container::config_t::alloc
ElementAllocator & alloc()
Definition: aged_unordered_container.h:427
beast::detail::aged_unordered_container< ID, std::unordered_map< NodeID, Validation >, std::chrono::steady_clock, beast::uhash<> >::BucketAllocator
typename std::allocator_traits< std::allocator< typename std::conditional< IsMap, std::pair< std::chrono::steady_clock const, beast::uhash<> >, std::chrono::steady_clock >::type > >::template rebind_alloc< element > BucketAllocator
Definition: aged_unordered_container.h:259
beast::detail::aged_unordered_container::config_t::config_t
config_t(config_t const &other)
Definition: aged_unordered_container.h:323
beast::detail::aged_unordered_container::insert
std::enable_if< maybe_multi, iterator >::type insert(const_iterator, value_type &&value)
Definition: aged_unordered_container.h:1102
beast::detail::aged_unordered_container::element::stashed::stashed
stashed()=default
beast::detail::aged_unordered_container::chronological_t::end
iterator end()
Definition: aged_unordered_container.h:648
utility
beast::detail::aged_unordered_container::key_eq
key_equal const & key_eq() const
Definition: aged_unordered_container.h:1389
beast::detail::aged_unordered_container::config_t::value_hash
ValueHash const & value_hash() const
Definition: aged_unordered_container.h:385
beast::detail::aged_unordered_container::KeyValueEqual::operator()
bool operator()(element const &lhs, element const &rhs) const
Definition: aged_unordered_container.h:214
beast::detail::aged_unordered_container::emplace
auto emplace(Args &&... args) -> typename std::enable_if<!maybe_multi, std::pair< iterator, bool >>::type
Definition: aged_unordered_container.h:2876
beast::detail::aged_unordered_container::config_t::config_t
config_t(config_t &&other, Allocator const &alloc)
Definition: aged_unordered_container.h:350
beast::detail::aged_unordered_container::element::element
element(time_point const &when_, value_type const &value_)
Definition: aged_unordered_container.h:127
functional
beast::detail::aged_unordered_container::KeyValueEqual::key_eq
KeyEqual const & key_eq() const
Definition: aged_unordered_container.h:226
beast::detail::aged_unordered_container::insert
void insert(InputIt first, InputIt last, std::random_access_iterator_tag)
Definition: aged_unordered_container.h:1509
beast::detail::aged_unordered_container::insert_unchecked
void insert_unchecked(InputIt first, InputIt last)
Definition: aged_unordered_container.h:1493
beast::detail::aged_unordered_container::config_t::key_value_equal
KeyValueEqual & key_value_equal()
Definition: aged_unordered_container.h:403
beast::detail::aged_unordered_container::m_buck
Buckets m_buck
Definition: aged_unordered_container.h:1551
beast::detail::aged_unordered_container::chronological_t::rbegin
reverse_iterator rbegin()
Definition: aged_unordered_container.h:666
std::pair
beast::detail::aged_unordered_container< ID, std::unordered_map< NodeID, Validation >, std::chrono::steady_clock, beast::uhash<> >::cont_type
typename std::conditional< IsMulti, typename boost::intrusive::make_unordered_multiset< element, boost::intrusive::constant_time_size< true >, boost::intrusive::hash< ValueHash >, boost::intrusive::equal< KeyValueEqual >, boost::intrusive::cache_begin< true > >::type, typename boost::intrusive::make_unordered_set< element, boost::intrusive::constant_time_size< true >, boost::intrusive::hash< ValueHash >, boost::intrusive::equal< KeyValueEqual >, boost::intrusive::cache_begin< true > >::type >::type cont_type
Definition: aged_unordered_container.h:248
beast::detail::aged_unordered_container::extract
static Key const & extract(value_type const &value)
Definition: aged_unordered_container.h:105
beast::detail::aged_unordered_container::chronological_t::rbegin
const_reverse_iterator rbegin() const
Definition: aged_unordered_container.h:672
beast::detail::aged_unordered_container::m_config
config_t m_config
Definition: aged_unordered_container.h:1550
beast::detail::aged_unordered_container::chronological_t::cbegin
const_iterator cbegin() const
Definition: aged_unordered_container.h:642
std::vector< bucket_type, typename std::allocator_traits< Allocator >::template rebind_alloc< bucket_type > >
std::vector::size
T size(T... args)
beast::detail::aged_unordered_container< ID, std::unordered_map< NodeID, Validation >, std::chrono::steady_clock, beast::uhash<> >::ElementAllocator
typename std::allocator_traits< std::allocator< typename std::conditional< IsMap, std::pair< std::chrono::steady_clock const, beast::uhash<> >, std::chrono::steady_clock >::type > >::template rebind_alloc< element > ElementAllocator
Definition: aged_unordered_container.h:254
beast::detail::aged_unordered_container::config_t::config_t
config_t(config_t const &other, Allocator const &alloc)
Definition: aged_unordered_container.h:333
beast::detail::aged_unordered_container::ValueHash
Definition: aged_unordered_container.h:151
beast::is_aged_container
Definition: aged_container.h:28
std::chrono::duration
beast::detail::aged_unordered_container::config_t::config_t
config_t(clock_type &clock_, Hash const &hash)
Definition: aged_unordered_container.h:273
beast::detail::aged_unordered_container::equal_range
std::pair< iterator, iterator > equal_range(K const &k)
Definition: aged_unordered_container.h:1250
beast::detail::aged_unordered_container::reserve
void reserve(size_type count)
Definition: aged_unordered_container.h:1371
iterator
beast::detail::aged_unordered_container::insert
auto insert(value_type const &value) -> typename std::enable_if<!maybe_multi, std::pair< iterator, bool >>::type
Definition: aged_unordered_container.h:2735
beast::detail::aged_unordered_container::clock_type
abstract_clock< Clock > clock_type
Definition: aged_unordered_container.h:88
beast::detail::aged_unordered_container::chronological_t
Definition: aged_unordered_container.h:614
std::input_iterator_tag
std::reference_wrapper::get
T get(T... args)
beast::detail::aged_unordered_container::end
const_iterator end() const
Definition: aged_unordered_container.h:981
beast::detail::aged_unordered_container::clock
clock_type const & clock() const
Definition: aged_unordered_container.h:909
beast::detail::aged_unordered_container::bucket
size_type bucket(Key const &k) const
Definition: aged_unordered_container.h:1333
std::distance
T distance(T... args)
std::unique_ptr::release
T release(T... args)
std::is_permutation
T is_permutation(T... args)
beast::detail::aged_unordered_container::config_t::config_t
config_t(clock_type &clock_, Allocator const &alloc_)
Definition: aged_unordered_container.h:283
beast::detail::aged_unordered_container::Buckets::m_max_load_factor
float m_max_load_factor
Definition: aged_unordered_container.h:534
beast::detail::aged_unordered_container::equal_range
std::pair< const_iterator, const_iterator > equal_range(K const &k) const
Definition: aged_unordered_container.h:1262
beast::detail::aged_unordered_container::swap
void swap(aged_unordered_container &other) noexcept
Definition: aged_unordered_container.h:3128
beast::detail::aged_unordered_container::local_iterator
beast::detail::aged_container_iterator<!IsMap, typename cont_type::local_iterator > local_iterator
Definition: aged_unordered_container.h:601
beast::detail::empty_base_optimization
Definition: empty_base_optimization.h:32
beast::detail::aged_unordered_container::chronological_t::begin
iterator begin()
Definition: aged_unordered_container.h:630
beast::detail::aged_unordered_container::config_t::operator=
config_t & operator=(config_t const &other)
Definition: aged_unordered_container.h:359
beast::detail::aged_unordered_container::swap_data
std::enable_if<!maybe_propagate >::type swap_data(aged_unordered_container &other) noexcept
Definition: aged_unordered_container.h:1543
beast::detail::aged_unordered_container::Buckets::max_bucket_count
size_type max_bucket_count() const
Definition: aged_unordered_container.h:473
beast::detail::aged_unordered_container::const_local_iterator
beast::detail::aged_container_iterator< true, typename cont_type::local_iterator > const_local_iterator
Definition: aged_unordered_container.h:603
cmath
beast::detail::empty_base_optimization< ElementAllocator >::member
ElementAllocator & member() noexcept
Definition: empty_base_optimization.h:50
beast::detail::aged_unordered_container::chronological_t::end
const_iterator end() const
Definition: aged_unordered_container.h:654
beast::detail::aged_unordered_container::config_t::clock
std::reference_wrapper< clock_type > clock
Definition: aged_unordered_container.h:440
std::allocator_traits
algorithm
beast::detail::aged_unordered_container::end
const_local_iterator end(size_type n) const
Definition: aged_unordered_container.h:1303
std::vector::clear
T clear(T... args)
beast::detail::aged_unordered_container::clock
clock_type & clock()
Definition: aged_unordered_container.h:903
beast::detail::aged_unordered_container::insert
void insert(InputIt first, InputIt last)
Definition: aged_unordered_container.h:1135
beast::detail::aged_unordered_container::chronological_t::rend
const_reverse_iterator rend() const
Definition: aged_unordered_container.h:690
beast::detail::aged_unordered_container::Buckets
Definition: aged_unordered_container.h:443
beast::detail::aged_associative_container_extract_t
Definition: aged_associative_container.h:30
beast::detail::aged_unordered_container::insert_unchecked
auto insert_unchecked(value_type const &value) -> typename std::enable_if<!maybe_multi, std::pair< iterator, bool >>::type
Definition: aged_unordered_container.h:3297
beast::detail::aged_unordered_container::allocator_type
Allocator allocator_type
Definition: aged_unordered_container.h:586
beast::detail::aged_unordered_container::const_iterator
beast::detail::aged_container_iterator< true, typename cont_type::iterator > const_iterator
Definition: aged_unordered_container.h:598
std::vector::capacity
T capacity(T... args)
beast::detail::aged_unordered_container::config_t::key_eq
KeyEqual & key_eq()
Definition: aged_unordered_container.h:415
beast::detail::aged_unordered_container::size
size_type size() const noexcept
Definition: aged_unordered_container.h:1025
beast::detail::aged_unordered_container::emplace_hint
std::enable_if< maybe_multi, iterator >::type emplace_hint(const_iterator, Args &&... args)
Definition: aged_unordered_container.h:1170
beast::detail::aged_unordered_container::touch
void touch(beast::detail::aged_container_iterator< is_const, Iterator > pos, typename clock_type::time_point const &now)
Definition: aged_unordered_container.h:1518
beast::detail::aged_unordered_container::config_t::config_t
config_t(clock_type &clock_, Hash const &hash, KeyEqual const &keyEqual, Allocator const &alloc_)
Definition: aged_unordered_container.h:311
beast::detail::aged_unordered_container::element::when
time_point when
Definition: aged_unordered_container.h:147
std::addressof
T addressof(T... args)
std::reference_wrapper
beast::detail::aged_unordered_container::key_equal
KeyEqual key_equal
Definition: aged_unordered_container.h:585
beast::detail::aged_unordered_container::ValueHash::ValueHash
ValueHash(Hash const &h)
Definition: aged_unordered_container.h:161
beast::detail::aged_unordered_container::iterator_to
const_iterator iterator_to(value_type const &value) const
Definition: aged_unordered_container.h:1003
beast::detail::aged_unordered_container::empty
bool empty() const noexcept
Definition: aged_unordered_container.h:1019
beast::detail::aged_unordered_container::cbegin
const_local_iterator cbegin(size_type n) const
Definition: aged_unordered_container.h:1291
beast::detail::aged_unordered_container::Buckets::rehash
void rehash(size_type count, Container &c)
Definition: aged_unordered_container.h:493
beast::detail::aged_unordered_container::iterator_to
iterator iterator_to(value_type &value)
Definition: aged_unordered_container.h:993
beast::detail::aged_unordered_container::operator!=
bool operator!=(aged_unordered_container< OtherIsMulti, OtherIsMap, OtherKey, OtherT, OtherDuration, OtherHash, KeyEqual, OtherAllocator > const &other) const
Definition: aged_unordered_container.h:1451
std::enable_if
beast::detail::aged_unordered_container::list_type
typename boost::intrusive::make_list< element, boost::intrusive::constant_time_size< false > >::type list_type
Definition: aged_unordered_container.h:233
beast::detail::aged_unordered_container::Buckets::resize
void resize(size_type n, Container &c)
Definition: aged_unordered_container.h:526
beast::detail::aged_unordered_container::Buckets::clear
void clear()
Definition: aged_unordered_container.h:467
std::iterator_traits
beast::detail::aged_unordered_container::config_t::config_t
config_t(clock_type &clock_, Hash const &hash, Allocator const &alloc_)
Definition: aged_unordered_container.h:294
std::allocator_traits::allocate
T allocate(T... args)
beast::detail::aged_unordered_container::ValueHash::result_type
size_t result_type
Definition: aged_unordered_container.h:155
beast::detail::aged_unordered_container::config_t
Definition: aged_unordered_container.h:263
beast::detail::aged_unordered_container::chronological_t::list
list_type list
Definition: aged_unordered_container.h:732
std::allocator_traits::deallocate
T deallocate(T... args)
beast::detail::aged_unordered_container::cend
const_iterator cend() const
Definition: aged_unordered_container.h:987
beast::detail::aged_unordered_container::aged_unordered_container
aged_unordered_container()=delete
beast::detail::aged_unordered_container::chronological_t::chronological_t
chronological_t()
Definition: aged_unordered_container.h:724
std::allocator_traits::destroy
T destroy(T... args)
beast::detail::aged_unordered_container::config_t::operator=
config_t & operator=(config_t &&other)
Definition: aged_unordered_container.h:369
beast::detail::aged_unordered_container::hasher
Hash hasher
Definition: aged_unordered_container.h:584
beast::detail::aged_unordered_container::get_allocator
allocator_type get_allocator() const
Definition: aged_unordered_container.h:897
std::vector::get_allocator
T get_allocator(T... args)
beast::detail::aged_unordered_container::chronological_t::reverse_iterator
beast::detail::aged_container_iterator< !IsMap, typename list_type::reverse_iterator > reverse_iterator
Definition: aged_unordered_container.h:625
beast::detail::aged_unordered_container::KeyValueEqual
Definition: aged_unordered_container.h:186
beast::detail::aged_unordered_container::max_bucket_count
size_type max_bucket_count() const
Definition: aged_unordered_container.h:1321
beast::detail::aged_unordered_container::ValueHash::ValueHash
ValueHash()
Definition: aged_unordered_container.h:157
beast::detail::aged_unordered_container::chronological_t::cend
const_iterator cend() const
Definition: aged_unordered_container.h:660
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_unordered_container::ValueHash::hash_function
Hash const & hash_function() const
Definition: aged_unordered_container.h:178
beast::detail::aged_unordered_container< ID, std::unordered_map< NodeID, Validation >, std::chrono::steady_clock, beast::uhash<> >::reference
value_type & reference
Definition: aged_unordered_container.h:587
beast::detail::aged_unordered_container::KeyValueEqual::operator()
bool operator()(Key const &k, element const &e) const
Definition: aged_unordered_container.h:202
beast::detail::aged_unordered_container::config_t::config_t
config_t(clock_type &clock_, KeyEqual const &keyEqual, Allocator const &alloc_)
Definition: aged_unordered_container.h:301
std::forward_as_tuple
T forward_as_tuple(T... args)
beast::detail::aged_unordered_container::config_t::alloc
ElementAllocator const & alloc() const
Definition: aged_unordered_container.h:434
beast::detail::aged_unordered_container::count
size_type count(K const &k) const
Definition: aged_unordered_container.h:1217
beast::detail::aged_unordered_container::chronological_t::iterator
beast::detail::aged_container_iterator<!IsMap, typename list_type::iterator > iterator
Definition: aged_unordered_container.h:620
beast::detail::aged_container_iterator::iterator
Iterator const & iterator() const
Definition: aged_container_iterator.h:170
std::vector::max_size
T max_size(T... args)
std::ceil
T ceil(T... args)
beast::detail::aged_unordered_container::bucket_count
size_type bucket_count() const
Definition: aged_unordered_container.h:1315
beast::abstract_clock< std::chrono::steady_clock >
memory
beast::detail::aged_unordered_container::config_t::config_t
config_t(clock_type &clock_, Hash const &hash, KeyEqual const &keyEqual)
Definition: aged_unordered_container.h:289
beast::detail::aged_unordered_container::Buckets::m_vec
vec_type m_vec
Definition: aged_unordered_container.h:535
beast::detail::aged_unordered_container< ID, std::unordered_map< NodeID, Validation >, std::chrono::steady_clock, beast::uhash<> >::const_pointer
typename std::allocator_traits< std::allocator< typename std::conditional< IsMap, std::pair< std::chrono::steady_clock const, beast::uhash<> >, std::chrono::steady_clock >::type > >::const_pointer const_pointer
Definition: aged_unordered_container.h:591
beast::detail::aged_unordered_container::begin
iterator begin()
Definition: aged_unordered_container.h:957
std::swap
T swap(T... args)
beast::detail::aged_unordered_container::~aged_unordered_container
~aged_unordered_container()
Definition: aged_unordered_container.h:2446
beast::detail::aged_unordered_container::cend
const_local_iterator cend(size_type n) const
Definition: aged_unordered_container.h:1309
std::equal_to
beast::detail::aged_unordered_container< ID, std::unordered_map< NodeID, Validation >, std::chrono::steady_clock, beast::uhash<> >::pointer
typename std::allocator_traits< std::allocator< typename std::conditional< IsMap, std::pair< std::chrono::steady_clock const, beast::uhash<> >, std::chrono::steady_clock >::type > >::pointer pointer
Definition: aged_unordered_container.h:589
beast::detail::aged_unordered_container::chronological_t::crend
const_reverse_iterator crend() const
Definition: aged_unordered_container.h:696
beast::detail::aged_unordered_container
Associative container where each element is also indexed by time.
Definition: aged_unordered_container.h:85
beast::detail::aged_unordered_container::chronological_t::crbegin
const_reverse_iterator crbegin() const
Definition: aged_unordered_container.h:678
beast::detail::aged_unordered_container::bucket_size
size_type bucket_size(size_type n) const
Definition: aged_unordered_container.h:1327
beast::detail::aged_unordered_container::cbegin
const_iterator cbegin() const
Definition: aged_unordered_container.h:969
beast::detail::aged_unordered_container::begin
local_iterator begin(size_type n)
Definition: aged_unordered_container.h:1279
beast::detail::aged_unordered_container::max_load_factor
float max_load_factor() const
Definition: aged_unordered_container.h:1352
beast::detail::aged_unordered_container::load_factor
float load_factor() const
Definition: aged_unordered_container.h:1346
beast::detail::aged_unordered_container::operator==
std::enable_if<!maybe_multi, bool >::type operator==(aged_unordered_container< false, OtherIsMap, OtherKey, OtherT, OtherDuration, OtherHash, KeyEqual, OtherAllocator > const &other) const
Definition: aged_unordered_container.h:3194
beast::detail::aged_unordered_container::KeyValueEqual::result_type
bool result_type
Definition: aged_unordered_container.h:191
beast::detail::aged_unordered_container< ID, std::unordered_map< NodeID, Validation >, std::chrono::steady_clock, beast::uhash<> >::bucket_traits
typename cont_type::bucket_traits bucket_traits
Definition: aged_unordered_container.h:251
beast::detail::aged_unordered_container::m_cont
cont_type m_cont
Definition: aged_unordered_container.h:1552
beast::detail::aged_unordered_container::max_size
size_type max_size() const noexcept
Definition: aged_unordered_container.h:1031
beast::detail::aged_unordered_container::config_t::value_hash
ValueHash & value_hash()
Definition: aged_unordered_container.h:379
std::initializer_list::begin
T begin(T... args)
beast::detail::aged_unordered_container::Buckets::max_load_factor
float & max_load_factor()
Definition: aged_unordered_container.h:479
beast::detail::aged_unordered_container::KeyValueEqual::first_argument_type
Key first_argument_type
Definition: aged_unordered_container.h:189
std
STL namespace.
beast::detail::aged_unordered_container::insert
void insert(InputIt first, InputIt last, std::input_iterator_tag)
Definition: aged_unordered_container.h:1501
beast::detail::aged_unordered_container::begin
const_iterator begin() const
Definition: aged_unordered_container.h:963
beast::detail::aged_unordered_container::element::stashed::value_type
typename aged_unordered_container::value_type value_type
Definition: aged_unordered_container.h:123
beast::detail::aged_unordered_container::Buckets::Buckets
Buckets()
Definition: aged_unordered_container.h:451
beast::detail::aged_unordered_container::KeyValueEqual::KeyValueEqual
KeyValueEqual(KeyEqual const &keyEqual)
Definition: aged_unordered_container.h:197
beast::detail::aged_unordered_container::chronological_t::const_iterator
beast::detail::aged_container_iterator< true, typename list_type::iterator > const_iterator
Definition: aged_unordered_container.h:622
beast::detail::aged_unordered_container::element::element
element(time_point const &when_, Args &&... args)
Definition: aged_unordered_container.h:141
beast::detail::aged_unordered_container::would_exceed
bool would_exceed(size_type additional) const
Definition: aged_unordered_container.h:1466
beast::detail::aged_unordered_container::Buckets::Buckets
Buckets(Allocator const &alloc)
Definition: aged_unordered_container.h:456
beast::detail::aged_unordered_container::config_t::config_t
config_t(clock_type &clock_, KeyEqual const &keyEqual)
Definition: aged_unordered_container.h:278
std::ptrdiff_t
beast::detail::aged_unordered_container::chronological_t::iterator_to
const_iterator iterator_to(value_type const &value) const
Definition: aged_unordered_container.h:713
beast::detail::aged_unordered_container::end
local_iterator end(size_type n)
Definition: aged_unordered_container.h:1297
beast::detail::aged_unordered_container::operator=
aged_unordered_container & operator=(aged_unordered_container const &other)
Definition: aged_unordered_container.h:2469
beast::detail::aged_unordered_container< ID, std::unordered_map< NodeID, Validation >, std::chrono::steady_clock, beast::uhash<> >::const_reference
value_type const & const_reference
Definition: aged_unordered_container.h:588
beast::detail::aged_unordered_container::config_t::key_eq
KeyEqual const & key_eq() const
Definition: aged_unordered_container.h:421
std::out_of_range
STL class.
std::allocator
STL class.
beast::detail::aged_unordered_container::element::element
element(time_point const &when_, value_type &&value_)
Definition: aged_unordered_container.h:132
beast::detail::aged_unordered_container::emplace_hint
auto emplace_hint(const_iterator, Args &&... args) -> typename std::enable_if<!maybe_multi, std::pair< iterator, bool >>::type
Definition: aged_unordered_container.h:2987
std::is_constructible
std::size_t
beast::detail::aged_unordered_container::element::value
value_type value
Definition: aged_unordered_container.h:146
beast::detail::aged_unordered_container::config_t::config_t
config_t(config_t &&other)
Definition: aged_unordered_container.h:341
beast::detail::aged_unordered_container::clear
void clear()
Definition: aged_unordered_container.h:2705
std::make_pair
T make_pair(T... args)
std::initializer_list::end
T end(T... args)
beast::detail::aged_unordered_container::find
iterator find(K const &k)
Definition: aged_unordered_container.h:1228
beast::detail::aged_unordered_container::size_type
std::size_t size_type
Definition: aged_unordered_container.h:95
beast::detail::aged_unordered_container::element::stashed
Definition: aged_unordered_container.h:119
beast::uhash<>
beast::detail::aged_unordered_container::config_t::hash_function
Hash const & hash_function() const
Definition: aged_unordered_container.h:397
beast::detail::aged_unordered_container::ValueHash::hash_function
Hash & hash_function()
Definition: aged_unordered_container.h:172
beast::detail::aged_unordered_container< ID, std::unordered_map< NodeID, Validation >, std::chrono::steady_clock, beast::uhash<> >::value_type
typename std::conditional< IsMap, std::pair< std::chrono::steady_clock const, beast::uhash<> >, std::chrono::steady_clock >::type value_type
Definition: aged_unordered_container.h:94
std::conditional
beast::detail::aged_unordered_container::insert
std::enable_if<!maybe_multi, iterator >::type insert(const_iterator, value_type const &value)
Definition: aged_unordered_container.h:1072
std::max
T max(T... args)
beast::detail::aged_unordered_container< ID, std::unordered_map< NodeID, Validation >, std::chrono::steady_clock, beast::uhash<> >::duration
typename clock_type::duration duration
Definition: aged_unordered_container.h:90
beast::detail::aged_unordered_container::chronological_t::iterator_to
iterator iterator_to(value_type &value)
Definition: aged_unordered_container.h:702
beast::detail::aged_unordered_container::new_element
element * new_element(Args &&... args)
Definition: aged_unordered_container.h:540
beast::detail::aged_unordered_container::config_t::hash_function
Hash & hash_function()
Definition: aged_unordered_container.h:391
beast::detail::aged_unordered_container::erase
beast::detail::aged_container_iterator< false, Iterator > erase(beast::detail::aged_container_iterator< is_const, Iterator > pos)
Definition: aged_unordered_container.h:3029
beast::detail::aged_unordered_container::operator[]
std::conditional< IsMap, T, void * >::type & operator[](Key const &key)
Definition: aged_unordered_container.h:2622
beast::detail::aged_unordered_container::iterator
beast::detail::aged_container_iterator<!IsMap, typename cont_type::iterator > iterator
Definition: aged_unordered_container.h:596
beast::detail::aged_unordered_container::maybe_rehash
void maybe_rehash(size_type additional)
Definition: aged_unordered_container.h:1472
std::unique_ptr
STL class.
beast::detail::aged_unordered_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_unordered_container.h:1128
beast::detail::aged_unordered_container::chronological
class beast::detail::aged_unordered_container::chronological_t chronological
beast::detail::aged_unordered_container::swap_data
std::enable_if< maybe_propagate >::type swap_data(aged_unordered_container &other) noexcept
Definition: aged_unordered_container.h:1532
beast::detail::aged_unordered_container::find
const_iterator find(K const &k) const
Definition: aged_unordered_container.h:1239
beast::detail::aged_unordered_container::hash_function
hasher const & hash_function() const
Definition: aged_unordered_container.h:1383
beast::detail::aged_unordered_container::touch
void touch(beast::detail::aged_container_iterator< is_const, Iterator > pos)
Definition: aged_unordered_container.h:1199
beast::detail::aged_unordered_container::Buckets::max_load_factor
float const & max_load_factor() const
Definition: aged_unordered_container.h:485
beast::detail::aged_unordered_container::chronological_t::begin
const_iterator begin() const
Definition: aged_unordered_container.h:636
beast::abstract_clock::time_point
typename Clock::time_point time_point
Definition: abstract_clock.h:63
beast::detail::aged_unordered_container::chronological_t::const_reverse_iterator
beast::detail::aged_container_iterator< true, typename list_type::reverse_iterator > const_reverse_iterator
Definition: aged_unordered_container.h:627
beast::detail::aged_unordered_container::insert
std::enable_if<!maybe_multi, iterator >::type insert(const_iterator, value_type &&value)
Definition: aged_unordered_container.h:1092
beast::detail::aged_unordered_container::at
std::conditional< IsMap, T, void * >::type & at(K const &k)
Definition: aged_unordered_container.h:2562
type_traits
beast::detail::aged_container_iterator
Definition: aged_container_iterator.h:35
beast::detail::aged_unordered_container::element
Definition: aged_unordered_container.h:111
beast::abstract_clock::duration
typename Clock::duration duration
Definition: abstract_clock.h:62
std::allocator_traits::construct
T construct(T... args)
std::cref
T cref(T... args)
beast::detail::aged_unordered_container::insert
std::enable_if< maybe_multi, iterator >::type insert(const_iterator, value_type const &value)
Definition: aged_unordered_container.h:1082
beast::detail::aged_unordered_container::delete_element
void delete_element(element const *p)
Definition: aged_unordered_container.h:568
beast::detail::aged_unordered_container::config_t::key_value_equal
KeyValueEqual const & key_value_equal() const
Definition: aged_unordered_container.h:409
std::hash
initializer_list
beast::detail::aged_unordered_container::insert
void insert(std::initializer_list< value_type > init)
Definition: aged_unordered_container.h:1144
beast
Definition: base_uint.h:641