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  template <class K>
1188  auto
1189  erase(K const& k) -> size_type;
1190 
1191  void
1192  swap(aged_unordered_container& other) noexcept;
1193 
1194  template <bool is_const, class Iterator>
1195  void
1197  {
1198  touch(pos, clock().now());
1199  }
1200 
1201  template <class K>
1202  auto
1203  touch(K const& k) -> size_type;
1204 
1205  //--------------------------------------------------------------------------
1206  //
1207  // Lookup
1208  //
1209  //--------------------------------------------------------------------------
1210 
1211  // VFALCO TODO Respect is_transparent (c++14)
1212  template <class K>
1213  size_type
1214  count(K const& k) const
1215  {
1216  return m_cont.count(
1217  k,
1220  }
1221 
1222  // VFALCO TODO Respect is_transparent (c++14)
1223  template <class K>
1224  iterator
1225  find(K const& k)
1226  {
1227  return iterator(m_cont.find(
1228  k,
1231  }
1232 
1233  // VFALCO TODO Respect is_transparent (c++14)
1234  template <class K>
1236  find(K const& k) const
1237  {
1238  return const_iterator(m_cont.find(
1239  k,
1242  }
1243 
1244  // VFALCO TODO Respect is_transparent (c++14)
1245  template <class K>
1247  equal_range(K const& k)
1248  {
1249  auto const r(m_cont.equal_range(
1250  k,
1253  return std::make_pair(iterator(r.first), iterator(r.second));
1254  }
1255 
1256  // VFALCO TODO Respect is_transparent (c++14)
1257  template <class K>
1259  equal_range(K const& k) const
1260  {
1261  auto const r(m_cont.equal_range(
1262  k,
1265  return std::make_pair(
1266  const_iterator(r.first), const_iterator(r.second));
1267  }
1268 
1269  //--------------------------------------------------------------------------
1270  //
1271  // Bucket interface
1272  //
1273  //--------------------------------------------------------------------------
1274 
1277  {
1278  return local_iterator(m_cont.begin(n));
1279  }
1280 
1282  begin(size_type n) const
1283  {
1284  return const_local_iterator(m_cont.begin(n));
1285  }
1286 
1289  {
1290  return const_local_iterator(m_cont.begin(n));
1291  }
1292 
1295  {
1296  return local_iterator(m_cont.end(n));
1297  }
1298 
1300  end(size_type n) const
1301  {
1302  return const_local_iterator(m_cont.end(n));
1303  }
1304 
1306  cend(size_type n) const
1307  {
1308  return const_local_iterator(m_cont.end(n));
1309  }
1310 
1311  size_type
1313  {
1314  return m_cont.bucket_count();
1315  }
1316 
1317  size_type
1319  {
1320  return m_buck.max_bucket_count();
1321  }
1322 
1323  size_type
1325  {
1326  return m_cont.bucket_size(n);
1327  }
1328 
1329  size_type
1330  bucket(Key const& k) const
1331  {
1332  assert(bucket_count() != 0);
1333  return m_cont.bucket(k, std::cref(m_config.hash_function()));
1334  }
1335 
1336  //--------------------------------------------------------------------------
1337  //
1338  // Hash policy
1339  //
1340  //--------------------------------------------------------------------------
1341 
1342  float
1343  load_factor() const
1344  {
1345  return size() / static_cast<float>(m_cont.bucket_count());
1346  }
1347 
1348  float
1350  {
1351  return m_buck.max_load_factor();
1352  }
1353 
1354  void
1356  {
1358  }
1359 
1360  void
1362  {
1365  }
1366 
1367  void
1369  {
1371  }
1372 
1373  //--------------------------------------------------------------------------
1374  //
1375  // Observers
1376  //
1377  //--------------------------------------------------------------------------
1378 
1379  hasher const&
1381  {
1382  return m_config.hash_function();
1383  }
1384 
1385  key_equal const&
1386  key_eq() const
1387  {
1388  return m_config.key_eq();
1389  }
1390 
1391  //--------------------------------------------------------------------------
1392  //
1393  // Comparison
1394  //
1395  //--------------------------------------------------------------------------
1396 
1397  // This differs from the standard in that the comparison
1398  // is only done on the key portion of the value type, ignoring
1399  // the mapped type.
1400  //
1401  template <
1402  bool OtherIsMap,
1403  class OtherKey,
1404  class OtherT,
1405  class OtherDuration,
1406  class OtherHash,
1407  class OtherAllocator,
1408  bool maybe_multi = IsMulti>
1411  false,
1412  OtherIsMap,
1413  OtherKey,
1414  OtherT,
1415  OtherDuration,
1416  OtherHash,
1417  KeyEqual,
1418  OtherAllocator> const& other) const;
1419 
1420  template <
1421  bool OtherIsMap,
1422  class OtherKey,
1423  class OtherT,
1424  class OtherDuration,
1425  class OtherHash,
1426  class OtherAllocator,
1427  bool maybe_multi = IsMulti>
1430  true,
1431  OtherIsMap,
1432  OtherKey,
1433  OtherT,
1434  OtherDuration,
1435  OtherHash,
1436  KeyEqual,
1437  OtherAllocator> const& other) const;
1438 
1439  template <
1440  bool OtherIsMulti,
1441  bool OtherIsMap,
1442  class OtherKey,
1443  class OtherT,
1444  class OtherDuration,
1445  class OtherHash,
1446  class OtherAllocator>
1447  bool
1449  OtherIsMulti,
1450  OtherIsMap,
1451  OtherKey,
1452  OtherT,
1453  OtherDuration,
1454  OtherHash,
1455  KeyEqual,
1456  OtherAllocator> const& other) const
1457  {
1458  return !(this->operator==(other));
1459  }
1460 
1461 private:
1462  bool
1463  would_exceed(size_type additional) const
1464  {
1465  return size() + additional > bucket_count() * max_load_factor();
1466  }
1467 
1468  void
1470  {
1471  if (would_exceed(additional))
1472  m_buck.resize(size() + additional, m_cont);
1473  assert(load_factor() <= max_load_factor());
1474  }
1475 
1476  // map, set
1477  template <bool maybe_multi = IsMulti>
1478  auto
1479  insert_unchecked(value_type const& value) ->
1481 
1482  // multimap, multiset
1483  template <bool maybe_multi = IsMulti>
1484  auto
1485  insert_unchecked(value_type const& value) ->
1487 
1488  template <class InputIt>
1489  void
1490  insert_unchecked(InputIt first, InputIt last)
1491  {
1492  for (; first != last; ++first)
1493  insert_unchecked(*first);
1494  }
1495 
1496  template <class InputIt>
1497  void
1498  insert(InputIt first, InputIt last, std::input_iterator_tag)
1499  {
1500  for (; first != last; ++first)
1501  insert(*first);
1502  }
1503 
1504  template <class InputIt>
1505  void
1506  insert(InputIt first, InputIt last, std::random_access_iterator_tag)
1507  {
1508  auto const n(std::distance(first, last));
1509  maybe_rehash(n);
1510  insert_unchecked(first, last);
1511  }
1512 
1513  template <bool is_const, class Iterator>
1514  void
1517  typename clock_type::time_point const& now)
1518  {
1519  auto& e(*pos.iterator());
1520  e.when = now;
1521  chronological.list.erase(chronological.list.iterator_to(e));
1522  chronological.list.push_back(e);
1523  }
1524 
1525  template <
1526  bool maybe_propagate = std::allocator_traits<
1527  Allocator>::propagate_on_container_swap::value>
1530  {
1531  std::swap(m_config.key_compare(), other.m_config.key_compare());
1532  std::swap(m_config.alloc(), other.m_config.alloc());
1533  std::swap(m_config.clock, other.m_config.clock);
1534  }
1535 
1536  template <
1537  bool maybe_propagate = std::allocator_traits<
1538  Allocator>::propagate_on_container_swap::value>
1541  {
1542  std::swap(m_config.key_compare(), other.m_config.key_compare());
1543  std::swap(m_config.clock, other.m_config.clock);
1544  }
1545 
1546 private:
1547  config_t m_config;
1548  Buckets m_buck;
1550 };
1551 
1552 //------------------------------------------------------------------------------
1553 
1554 template <
1555  bool IsMulti,
1556  bool IsMap,
1557  class Key,
1558  class T,
1559  class Clock,
1560  class Hash,
1561  class KeyEqual,
1562  class Allocator>
1564  IsMulti,
1565  IsMap,
1566  Key,
1567  T,
1568  Clock,
1569  Hash,
1570  KeyEqual,
1572  : m_config(clock)
1573  , m_cont(
1574  m_buck,
1575  std::cref(m_config.value_hash()),
1576  std::cref(m_config.key_value_equal()))
1577 {
1578 }
1579 
1580 template <
1581  bool IsMulti,
1582  bool IsMap,
1583  class Key,
1584  class T,
1585  class Clock,
1586  class Hash,
1587  class KeyEqual,
1588  class Allocator>
1590  IsMulti,
1591  IsMap,
1592  Key,
1593  T,
1594  Clock,
1595  Hash,
1596  KeyEqual,
1597  Allocator>::aged_unordered_container(clock_type& clock, Hash const& hash)
1598  : m_config(clock, hash)
1599  , m_cont(
1600  m_buck,
1601  std::cref(m_config.value_hash()),
1602  std::cref(m_config.key_value_equal()))
1603 {
1604 }
1605 
1606 template <
1607  bool IsMulti,
1608  bool IsMap,
1609  class Key,
1610  class T,
1611  class Clock,
1612  class Hash,
1613  class KeyEqual,
1614  class Allocator>
1616  IsMulti,
1617  IsMap,
1618  Key,
1619  T,
1620  Clock,
1621  Hash,
1622  KeyEqual,
1623  Allocator>::
1624  aged_unordered_container(clock_type& clock, KeyEqual const& key_eq)
1625  : m_config(clock, key_eq)
1626  , m_cont(
1627  m_buck,
1628  std::cref(m_config.value_hash()),
1629  std::cref(m_config.key_value_equal()))
1630 {
1631 }
1632 
1633 template <
1634  bool IsMulti,
1635  bool IsMap,
1636  class Key,
1637  class T,
1638  class Clock,
1639  class Hash,
1640  class KeyEqual,
1641  class Allocator>
1643  IsMulti,
1644  IsMap,
1645  Key,
1646  T,
1647  Clock,
1648  Hash,
1649  KeyEqual,
1650  Allocator>::
1651  aged_unordered_container(clock_type& clock, Allocator const& alloc)
1652  : m_config(clock, alloc)
1653  , m_buck(alloc)
1654  , m_cont(
1655  m_buck,
1656  std::cref(m_config.value_hash()),
1657  std::cref(m_config.key_value_equal()))
1658 {
1659 }
1660 
1661 template <
1662  bool IsMulti,
1663  bool IsMap,
1664  class Key,
1665  class T,
1666  class Clock,
1667  class Hash,
1668  class KeyEqual,
1669  class Allocator>
1671  IsMulti,
1672  IsMap,
1673  Key,
1674  T,
1675  Clock,
1676  Hash,
1677  KeyEqual,
1678  Allocator>::
1679  aged_unordered_container(
1680  clock_type& clock,
1681  Hash const& hash,
1682  KeyEqual const& key_eq)
1683  : m_config(clock, hash, key_eq)
1684  , m_cont(
1685  m_buck,
1686  std::cref(m_config.value_hash()),
1687  std::cref(m_config.key_value_equal()))
1688 {
1689 }
1690 
1691 template <
1692  bool IsMulti,
1693  bool IsMap,
1694  class Key,
1695  class T,
1696  class Clock,
1697  class Hash,
1698  class KeyEqual,
1699  class Allocator>
1701  IsMulti,
1702  IsMap,
1703  Key,
1704  T,
1705  Clock,
1706  Hash,
1707  KeyEqual,
1708  Allocator>::
1709  aged_unordered_container(
1710  clock_type& clock,
1711  Hash const& hash,
1712  Allocator const& alloc)
1713  : m_config(clock, hash, alloc)
1714  , m_buck(alloc)
1715  , m_cont(
1716  m_buck,
1717  std::cref(m_config.value_hash()),
1718  std::cref(m_config.key_value_equal()))
1719 {
1720 }
1721 
1722 template <
1723  bool IsMulti,
1724  bool IsMap,
1725  class Key,
1726  class T,
1727  class Clock,
1728  class Hash,
1729  class KeyEqual,
1730  class Allocator>
1732  IsMulti,
1733  IsMap,
1734  Key,
1735  T,
1736  Clock,
1737  Hash,
1738  KeyEqual,
1739  Allocator>::
1740  aged_unordered_container(
1741  clock_type& clock,
1742  KeyEqual const& key_eq,
1743  Allocator const& alloc)
1744  : m_config(clock, key_eq, alloc)
1745  , m_buck(alloc)
1746  , m_cont(
1747  m_buck,
1748  std::cref(m_config.value_hash()),
1749  std::cref(m_config.key_value_equal()))
1750 {
1751 }
1752 
1753 template <
1754  bool IsMulti,
1755  bool IsMap,
1756  class Key,
1757  class T,
1758  class Clock,
1759  class Hash,
1760  class KeyEqual,
1761  class Allocator>
1763  IsMulti,
1764  IsMap,
1765  Key,
1766  T,
1767  Clock,
1768  Hash,
1769  KeyEqual,
1770  Allocator>::
1771  aged_unordered_container(
1772  clock_type& clock,
1773  Hash const& hash,
1774  KeyEqual const& key_eq,
1775  Allocator const& alloc)
1776  : m_config(clock, hash, key_eq, alloc)
1777  , m_buck(alloc)
1778  , m_cont(
1779  m_buck,
1780  std::cref(m_config.value_hash()),
1781  std::cref(m_config.key_value_equal()))
1782 {
1783 }
1784 
1785 template <
1786  bool IsMulti,
1787  bool IsMap,
1788  class Key,
1789  class T,
1790  class Clock,
1791  class Hash,
1792  class KeyEqual,
1793  class Allocator>
1794 template <class InputIt>
1796  IsMulti,
1797  IsMap,
1798  Key,
1799  T,
1800  Clock,
1801  Hash,
1802  KeyEqual,
1803  Allocator>::
1804  aged_unordered_container(InputIt first, InputIt last, clock_type& clock)
1805  : m_config(clock)
1806  , m_cont(
1807  m_buck,
1808  std::cref(m_config.value_hash()),
1809  std::cref(m_config.key_value_equal()))
1810 {
1811  insert(first, last);
1812 }
1813 
1814 template <
1815  bool IsMulti,
1816  bool IsMap,
1817  class Key,
1818  class T,
1819  class Clock,
1820  class Hash,
1821  class KeyEqual,
1822  class Allocator>
1823 template <class InputIt>
1825  IsMulti,
1826  IsMap,
1827  Key,
1828  T,
1829  Clock,
1830  Hash,
1831  KeyEqual,
1832  Allocator>::
1833  aged_unordered_container(
1834  InputIt first,
1835  InputIt last,
1836  clock_type& clock,
1837  Hash const& hash)
1838  : m_config(clock, hash)
1839  , m_cont(
1840  m_buck,
1841  std::cref(m_config.value_hash()),
1842  std::cref(m_config.key_value_equal()))
1843 {
1844  insert(first, last);
1845 }
1846 
1847 template <
1848  bool IsMulti,
1849  bool IsMap,
1850  class Key,
1851  class T,
1852  class Clock,
1853  class Hash,
1854  class KeyEqual,
1855  class Allocator>
1856 template <class InputIt>
1858  IsMulti,
1859  IsMap,
1860  Key,
1861  T,
1862  Clock,
1863  Hash,
1864  KeyEqual,
1865  Allocator>::
1866  aged_unordered_container(
1867  InputIt first,
1868  InputIt last,
1869  clock_type& clock,
1870  KeyEqual const& key_eq)
1871  : m_config(clock, key_eq)
1872  , m_cont(
1873  m_buck,
1874  std::cref(m_config.value_hash()),
1875  std::cref(m_config.key_value_equal()))
1876 {
1877  insert(first, last);
1878 }
1879 
1880 template <
1881  bool IsMulti,
1882  bool IsMap,
1883  class Key,
1884  class T,
1885  class Clock,
1886  class Hash,
1887  class KeyEqual,
1888  class Allocator>
1889 template <class InputIt>
1891  IsMulti,
1892  IsMap,
1893  Key,
1894  T,
1895  Clock,
1896  Hash,
1897  KeyEqual,
1898  Allocator>::
1899  aged_unordered_container(
1900  InputIt first,
1901  InputIt last,
1902  clock_type& clock,
1903  Allocator const& alloc)
1904  : m_config(clock, alloc)
1905  , m_buck(alloc)
1906  , m_cont(
1907  m_buck,
1908  std::cref(m_config.value_hash()),
1909  std::cref(m_config.key_value_equal()))
1910 {
1911  insert(first, last);
1912 }
1913 
1914 template <
1915  bool IsMulti,
1916  bool IsMap,
1917  class Key,
1918  class T,
1919  class Clock,
1920  class Hash,
1921  class KeyEqual,
1922  class Allocator>
1923 template <class InputIt>
1925  IsMulti,
1926  IsMap,
1927  Key,
1928  T,
1929  Clock,
1930  Hash,
1931  KeyEqual,
1932  Allocator>::
1933  aged_unordered_container(
1934  InputIt first,
1935  InputIt last,
1936  clock_type& clock,
1937  Hash const& hash,
1938  KeyEqual const& key_eq)
1939  : m_config(clock, hash, key_eq)
1940  , m_cont(
1941  m_buck,
1942  std::cref(m_config.value_hash()),
1943  std::cref(m_config.key_value_equal()))
1944 {
1945  insert(first, last);
1946 }
1947 
1948 template <
1949  bool IsMulti,
1950  bool IsMap,
1951  class Key,
1952  class T,
1953  class Clock,
1954  class Hash,
1955  class KeyEqual,
1956  class Allocator>
1957 template <class InputIt>
1959  IsMulti,
1960  IsMap,
1961  Key,
1962  T,
1963  Clock,
1964  Hash,
1965  KeyEqual,
1966  Allocator>::
1967  aged_unordered_container(
1968  InputIt first,
1969  InputIt last,
1970  clock_type& clock,
1971  Hash const& hash,
1972  Allocator const& alloc)
1973  : m_config(clock, hash, alloc)
1974  , m_buck(alloc)
1975  , m_cont(
1976  m_buck,
1977  std::cref(m_config.value_hash()),
1978  std::cref(m_config.key_value_equal()))
1979 {
1980  insert(first, last);
1981 }
1982 
1983 template <
1984  bool IsMulti,
1985  bool IsMap,
1986  class Key,
1987  class T,
1988  class Clock,
1989  class Hash,
1990  class KeyEqual,
1991  class Allocator>
1992 template <class InputIt>
1994  IsMulti,
1995  IsMap,
1996  Key,
1997  T,
1998  Clock,
1999  Hash,
2000  KeyEqual,
2001  Allocator>::
2002  aged_unordered_container(
2003  InputIt first,
2004  InputIt last,
2005  clock_type& clock,
2006  KeyEqual const& key_eq,
2007  Allocator const& alloc)
2008  : m_config(clock, key_eq, alloc)
2009  , m_buck(alloc)
2010  , m_cont(
2011  m_buck,
2012  std::cref(m_config.value_hash()),
2013  std::cref(m_config.key_value_equal()))
2014 {
2015  insert(first, last);
2016 }
2017 
2018 template <
2019  bool IsMulti,
2020  bool IsMap,
2021  class Key,
2022  class T,
2023  class Clock,
2024  class Hash,
2025  class KeyEqual,
2026  class Allocator>
2027 template <class InputIt>
2029  IsMulti,
2030  IsMap,
2031  Key,
2032  T,
2033  Clock,
2034  Hash,
2035  KeyEqual,
2036  Allocator>::
2037  aged_unordered_container(
2038  InputIt first,
2039  InputIt last,
2040  clock_type& clock,
2041  Hash const& hash,
2042  KeyEqual const& key_eq,
2043  Allocator const& alloc)
2044  : m_config(clock, hash, key_eq, alloc)
2045  , m_buck(alloc)
2046  , m_cont(
2047  m_buck,
2048  std::cref(m_config.value_hash()),
2049  std::cref(m_config.key_value_equal()))
2050 {
2051  insert(first, last);
2052 }
2053 
2054 template <
2055  bool IsMulti,
2056  bool IsMap,
2057  class Key,
2058  class T,
2059  class Clock,
2060  class Hash,
2061  class KeyEqual,
2062  class Allocator>
2064  IsMulti,
2065  IsMap,
2066  Key,
2067  T,
2068  Clock,
2069  Hash,
2070  KeyEqual,
2072  : m_config(other.m_config)
2073  , m_buck(m_config.alloc())
2074  , m_cont(
2075  m_buck,
2076  std::cref(m_config.value_hash()),
2077  std::cref(m_config.key_value_equal()))
2078 {
2079  insert(other.cbegin(), other.cend());
2080 }
2081 
2082 template <
2083  bool IsMulti,
2084  bool IsMap,
2085  class Key,
2086  class T,
2087  class Clock,
2088  class Hash,
2089  class KeyEqual,
2090  class Allocator>
2092  IsMulti,
2093  IsMap,
2094  Key,
2095  T,
2096  Clock,
2097  Hash,
2098  KeyEqual,
2099  Allocator>::
2100  aged_unordered_container(
2101  aged_unordered_container const& other,
2102  Allocator const& alloc)
2103  : m_config(other.m_config, alloc)
2104  , m_buck(alloc)
2105  , m_cont(
2106  m_buck,
2107  std::cref(m_config.value_hash()),
2108  std::cref(m_config.key_value_equal()))
2109 {
2110  insert(other.cbegin(), other.cend());
2111 }
2112 
2113 template <
2114  bool IsMulti,
2115  bool IsMap,
2116  class Key,
2117  class T,
2118  class Clock,
2119  class Hash,
2120  class KeyEqual,
2121  class Allocator>
2123  IsMulti,
2124  IsMap,
2125  Key,
2126  T,
2127  Clock,
2128  Hash,
2129  KeyEqual,
2131  : m_config(std::move(other.m_config))
2132  , m_buck(std::move(other.m_buck))
2133  , m_cont(std::move(other.m_cont))
2134 {
2135  chronological.list = std::move(other.chronological.list);
2136 }
2137 
2138 template <
2139  bool IsMulti,
2140  bool IsMap,
2141  class Key,
2142  class T,
2143  class Clock,
2144  class Hash,
2145  class KeyEqual,
2146  class Allocator>
2148  IsMulti,
2149  IsMap,
2150  Key,
2151  T,
2152  Clock,
2153  Hash,
2154  KeyEqual,
2155  Allocator>::
2156  aged_unordered_container(
2157  aged_unordered_container&& other,
2158  Allocator const& alloc)
2159  : m_config(std::move(other.m_config), alloc)
2160  , m_buck(alloc)
2161  , m_cont(
2162  m_buck,
2163  std::cref(m_config.value_hash()),
2164  std::cref(m_config.key_value_equal()))
2165 {
2166  insert(other.cbegin(), other.cend());
2167  other.clear();
2168 }
2169 
2170 template <
2171  bool IsMulti,
2172  bool IsMap,
2173  class Key,
2174  class T,
2175  class Clock,
2176  class Hash,
2177  class KeyEqual,
2178  class Allocator>
2180  IsMulti,
2181  IsMap,
2182  Key,
2183  T,
2184  Clock,
2185  Hash,
2186  KeyEqual,
2187  Allocator>::
2188  aged_unordered_container(
2190  clock_type& clock)
2191  : m_config(clock)
2192  , m_cont(
2193  m_buck,
2194  std::cref(m_config.value_hash()),
2195  std::cref(m_config.key_value_equal()))
2196 {
2197  insert(init.begin(), init.end());
2198 }
2199 
2200 template <
2201  bool IsMulti,
2202  bool IsMap,
2203  class Key,
2204  class T,
2205  class Clock,
2206  class Hash,
2207  class KeyEqual,
2208  class Allocator>
2210  IsMulti,
2211  IsMap,
2212  Key,
2213  T,
2214  Clock,
2215  Hash,
2216  KeyEqual,
2217  Allocator>::
2218  aged_unordered_container(
2220  clock_type& clock,
2221  Hash const& hash)
2222  : m_config(clock, hash)
2223  , m_cont(
2224  m_buck,
2225  std::cref(m_config.value_hash()),
2226  std::cref(m_config.key_value_equal()))
2227 {
2228  insert(init.begin(), init.end());
2229 }
2230 
2231 template <
2232  bool IsMulti,
2233  bool IsMap,
2234  class Key,
2235  class T,
2236  class Clock,
2237  class Hash,
2238  class KeyEqual,
2239  class Allocator>
2241  IsMulti,
2242  IsMap,
2243  Key,
2244  T,
2245  Clock,
2246  Hash,
2247  KeyEqual,
2248  Allocator>::
2249  aged_unordered_container(
2251  clock_type& clock,
2252  KeyEqual const& key_eq)
2253  : m_config(clock, key_eq)
2254  , m_cont(
2255  m_buck,
2256  std::cref(m_config.value_hash()),
2257  std::cref(m_config.key_value_equal()))
2258 {
2259  insert(init.begin(), init.end());
2260 }
2261 
2262 template <
2263  bool IsMulti,
2264  bool IsMap,
2265  class Key,
2266  class T,
2267  class Clock,
2268  class Hash,
2269  class KeyEqual,
2270  class Allocator>
2272  IsMulti,
2273  IsMap,
2274  Key,
2275  T,
2276  Clock,
2277  Hash,
2278  KeyEqual,
2279  Allocator>::
2280  aged_unordered_container(
2282  clock_type& clock,
2283  Allocator const& alloc)
2284  : m_config(clock, alloc)
2285  , m_buck(alloc)
2286  , m_cont(
2287  m_buck,
2288  std::cref(m_config.value_hash()),
2289  std::cref(m_config.key_value_equal()))
2290 {
2291  insert(init.begin(), init.end());
2292 }
2293 
2294 template <
2295  bool IsMulti,
2296  bool IsMap,
2297  class Key,
2298  class T,
2299  class Clock,
2300  class Hash,
2301  class KeyEqual,
2302  class Allocator>
2304  IsMulti,
2305  IsMap,
2306  Key,
2307  T,
2308  Clock,
2309  Hash,
2310  KeyEqual,
2311  Allocator>::
2312  aged_unordered_container(
2314  clock_type& clock,
2315  Hash const& hash,
2316  KeyEqual const& key_eq)
2317  : m_config(clock, hash, key_eq)
2318  , m_cont(
2319  m_buck,
2320  std::cref(m_config.value_hash()),
2321  std::cref(m_config.key_value_equal()))
2322 {
2323  insert(init.begin(), init.end());
2324 }
2325 
2326 template <
2327  bool IsMulti,
2328  bool IsMap,
2329  class Key,
2330  class T,
2331  class Clock,
2332  class Hash,
2333  class KeyEqual,
2334  class Allocator>
2336  IsMulti,
2337  IsMap,
2338  Key,
2339  T,
2340  Clock,
2341  Hash,
2342  KeyEqual,
2343  Allocator>::
2344  aged_unordered_container(
2346  clock_type& clock,
2347  Hash const& hash,
2348  Allocator const& alloc)
2349  : m_config(clock, hash, alloc)
2350  , m_buck(alloc)
2351  , m_cont(
2352  m_buck,
2353  std::cref(m_config.value_hash()),
2354  std::cref(m_config.key_value_equal()))
2355 {
2356  insert(init.begin(), init.end());
2357 }
2358 
2359 template <
2360  bool IsMulti,
2361  bool IsMap,
2362  class Key,
2363  class T,
2364  class Clock,
2365  class Hash,
2366  class KeyEqual,
2367  class Allocator>
2369  IsMulti,
2370  IsMap,
2371  Key,
2372  T,
2373  Clock,
2374  Hash,
2375  KeyEqual,
2376  Allocator>::
2377  aged_unordered_container(
2379  clock_type& clock,
2380  KeyEqual const& key_eq,
2381  Allocator const& alloc)
2382  : m_config(clock, key_eq, alloc)
2383  , m_buck(alloc)
2384  , m_cont(
2385  m_buck,
2386  std::cref(m_config.value_hash()),
2387  std::cref(m_config.key_value_equal()))
2388 {
2389  insert(init.begin(), init.end());
2390 }
2391 
2392 template <
2393  bool IsMulti,
2394  bool IsMap,
2395  class Key,
2396  class T,
2397  class Clock,
2398  class Hash,
2399  class KeyEqual,
2400  class Allocator>
2402  IsMulti,
2403  IsMap,
2404  Key,
2405  T,
2406  Clock,
2407  Hash,
2408  KeyEqual,
2409  Allocator>::
2410  aged_unordered_container(
2412  clock_type& clock,
2413  Hash const& hash,
2414  KeyEqual const& key_eq,
2415  Allocator const& alloc)
2416  : m_config(clock, hash, key_eq, alloc)
2417  , m_buck(alloc)
2418  , m_cont(
2419  m_buck,
2420  std::cref(m_config.value_hash()),
2421  std::cref(m_config.key_value_equal()))
2422 {
2423  insert(init.begin(), init.end());
2424 }
2425 
2426 template <
2427  bool IsMulti,
2428  bool IsMap,
2429  class Key,
2430  class T,
2431  class Clock,
2432  class Hash,
2433  class KeyEqual,
2434  class Allocator>
2436  IsMulti,
2437  IsMap,
2438  Key,
2439  T,
2440  Clock,
2441  Hash,
2442  KeyEqual,
2443  Allocator>::~aged_unordered_container()
2444 {
2445  clear();
2446 }
2447 
2448 template <
2449  bool IsMulti,
2450  bool IsMap,
2451  class Key,
2452  class T,
2453  class Clock,
2454  class Hash,
2455  class KeyEqual,
2456  class Allocator>
2457 auto
2459  IsMulti,
2460  IsMap,
2461  Key,
2462  T,
2463  Clock,
2464  Hash,
2465  KeyEqual,
2466  Allocator>::operator=(aged_unordered_container const& other)
2468 {
2469  if (this != &other)
2470  {
2471  size_type const n(other.size());
2472  clear();
2473  m_config = other.m_config;
2474  m_buck = Buckets(m_config.alloc());
2475  maybe_rehash(n);
2476  insert_unchecked(other.begin(), other.end());
2477  }
2478  return *this;
2479 }
2480 
2481 template <
2482  bool IsMulti,
2483  bool IsMap,
2484  class Key,
2485  class T,
2486  class Clock,
2487  class Hash,
2488  class KeyEqual,
2489  class Allocator>
2490 auto
2492  IsMulti,
2493  IsMap,
2494  Key,
2495  T,
2496  Clock,
2497  Hash,
2498  KeyEqual,
2499  Allocator>::operator=(aged_unordered_container&& other)
2501 {
2502  size_type const n(other.size());
2503  clear();
2504  m_config = std::move(other.m_config);
2505  m_buck = Buckets(m_config.alloc());
2506  maybe_rehash(n);
2507  insert_unchecked(other.begin(), other.end());
2508  other.clear();
2509  return *this;
2510 }
2511 
2512 template <
2513  bool IsMulti,
2514  bool IsMap,
2515  class Key,
2516  class T,
2517  class Clock,
2518  class Hash,
2519  class KeyEqual,
2520  class Allocator>
2521 auto
2523  IsMulti,
2524  IsMap,
2525  Key,
2526  T,
2527  Clock,
2528  Hash,
2529  KeyEqual,
2530  Allocator>::operator=(std::initializer_list<value_type> init)
2532 {
2533  clear();
2534  insert(init);
2535  return *this;
2536 }
2537 
2538 //------------------------------------------------------------------------------
2539 
2540 template <
2541  bool IsMulti,
2542  bool IsMap,
2543  class Key,
2544  class T,
2545  class Clock,
2546  class Hash,
2547  class KeyEqual,
2548  class Allocator>
2549 template <class K, bool maybe_multi, bool maybe_map, class>
2552  IsMulti,
2553  IsMap,
2554  Key,
2555  T,
2556  Clock,
2557  Hash,
2558  KeyEqual,
2559  Allocator>::at(K const& k)
2560 {
2561  auto const iter(m_cont.find(
2562  k,
2563  std::cref(m_config.hash_function()),
2564  std::cref(m_config.key_value_equal())));
2565  if (iter == m_cont.end())
2566  throw std::out_of_range("key not found");
2567  return iter->value.second;
2568 }
2569 
2570 template <
2571  bool IsMulti,
2572  bool IsMap,
2573  class Key,
2574  class T,
2575  class Clock,
2576  class Hash,
2577  class KeyEqual,
2578  class Allocator>
2579 template <class K, bool maybe_multi, bool maybe_map, class>
2582  IsMulti,
2583  IsMap,
2584  Key,
2585  T,
2586  Clock,
2587  Hash,
2588  KeyEqual,
2589  Allocator>::at(K const& k) const
2590 {
2591  auto const iter(m_cont.find(
2592  k,
2593  std::cref(m_config.hash_function()),
2594  std::cref(m_config.key_value_equal())));
2595  if (iter == m_cont.end())
2596  throw std::out_of_range("key not found");
2597  return iter->value.second;
2598 }
2599 
2600 template <
2601  bool IsMulti,
2602  bool IsMap,
2603  class Key,
2604  class T,
2605  class Clock,
2606  class Hash,
2607  class KeyEqual,
2608  class Allocator>
2609 template <bool maybe_multi, bool maybe_map, class>
2612  IsMulti,
2613  IsMap,
2614  Key,
2615  T,
2616  Clock,
2617  Hash,
2618  KeyEqual,
2619  Allocator>::operator[](Key const& key)
2620 {
2621  maybe_rehash(1);
2622  typename cont_type::insert_commit_data d;
2623  auto const result(m_cont.insert_check(
2624  key,
2625  std::cref(m_config.hash_function()),
2626  std::cref(m_config.key_value_equal()),
2627  d));
2628  if (result.second)
2629  {
2630  element* const p(new_element(
2631  std::piecewise_construct,
2632  std::forward_as_tuple(key),
2634  m_cont.insert_commit(*p, d);
2635  chronological.list.push_back(*p);
2636  return p->value.second;
2637  }
2638  return result.first->value.second;
2639 }
2640 
2641 template <
2642  bool IsMulti,
2643  bool IsMap,
2644  class Key,
2645  class T,
2646  class Clock,
2647  class Hash,
2648  class KeyEqual,
2649  class Allocator>
2650 template <bool maybe_multi, bool maybe_map, class>
2653  IsMulti,
2654  IsMap,
2655  Key,
2656  T,
2657  Clock,
2658  Hash,
2659  KeyEqual,
2660  Allocator>::operator[](Key&& key)
2661 {
2662  maybe_rehash(1);
2663  typename cont_type::insert_commit_data d;
2664  auto const result(m_cont.insert_check(
2665  key,
2666  std::cref(m_config.hash_function()),
2667  std::cref(m_config.key_value_equal()),
2668  d));
2669  if (result.second)
2670  {
2671  element* const p(new_element(
2672  std::piecewise_construct,
2673  std::forward_as_tuple(std::move(key)),
2675  m_cont.insert_commit(*p, d);
2676  chronological.list.push_back(*p);
2677  return p->value.second;
2678  }
2679  return result.first->value.second;
2680 }
2681 
2682 //------------------------------------------------------------------------------
2683 
2684 template <
2685  bool IsMulti,
2686  bool IsMap,
2687  class Key,
2688  class T,
2689  class Clock,
2690  class Hash,
2691  class KeyEqual,
2692  class Allocator>
2693 void
2695  IsMulti,
2696  IsMap,
2697  Key,
2698  T,
2699  Clock,
2700  Hash,
2701  KeyEqual,
2702  Allocator>::clear()
2703 {
2704  for (auto iter(chronological.list.begin());
2705  iter != chronological.list.end();)
2706  unlink_and_delete_element(&*iter++);
2707  chronological.list.clear();
2708  m_cont.clear();
2709  m_buck.clear();
2710 }
2711 
2712 // map, set
2713 template <
2714  bool IsMulti,
2715  bool IsMap,
2716  class Key,
2717  class T,
2718  class Clock,
2719  class Hash,
2720  class KeyEqual,
2721  class Allocator>
2722 template <bool maybe_multi>
2723 auto
2725  IsMulti,
2726  IsMap,
2727  Key,
2728  T,
2729  Clock,
2730  Hash,
2731  KeyEqual,
2732  Allocator>::insert(value_type const& value) ->
2734 {
2735  maybe_rehash(1);
2736  typename cont_type::insert_commit_data d;
2737  auto const result(m_cont.insert_check(
2738  extract(value),
2739  std::cref(m_config.hash_function()),
2740  std::cref(m_config.key_value_equal()),
2741  d));
2742  if (result.second)
2743  {
2744  element* const p(new_element(value));
2745  auto const iter(m_cont.insert_commit(*p, d));
2746  chronological.list.push_back(*p);
2747  return std::make_pair(iterator(iter), true);
2748  }
2749  return std::make_pair(iterator(result.first), false);
2750 }
2751 
2752 // multimap, multiset
2753 template <
2754  bool IsMulti,
2755  bool IsMap,
2756  class Key,
2757  class T,
2758  class Clock,
2759  class Hash,
2760  class KeyEqual,
2761  class Allocator>
2762 template <bool maybe_multi>
2763 auto
2765  IsMulti,
2766  IsMap,
2767  Key,
2768  T,
2769  Clock,
2770  Hash,
2771  KeyEqual,
2772  Allocator>::insert(value_type const& value) ->
2774 {
2775  maybe_rehash(1);
2776  element* const p(new_element(value));
2777  chronological.list.push_back(*p);
2778  auto const iter(m_cont.insert(*p));
2779  return iterator(iter);
2780 }
2781 
2782 // map, set
2783 template <
2784  bool IsMulti,
2785  bool IsMap,
2786  class Key,
2787  class T,
2788  class Clock,
2789  class Hash,
2790  class KeyEqual,
2791  class Allocator>
2792 template <bool maybe_multi, bool maybe_map>
2793 auto
2794 aged_unordered_container<
2795  IsMulti,
2796  IsMap,
2797  Key,
2798  T,
2799  Clock,
2800  Hash,
2801  KeyEqual,
2802  Allocator>::insert(value_type&& value) -> typename std::
2803  enable_if<!maybe_multi && !maybe_map, std::pair<iterator, bool>>::type
2804 {
2805  maybe_rehash(1);
2806  typename cont_type::insert_commit_data d;
2807  auto const result(m_cont.insert_check(
2808  extract(value),
2809  std::cref(m_config.hash_function()),
2810  std::cref(m_config.key_value_equal()),
2811  d));
2812  if (result.second)
2813  {
2814  element* const p(new_element(std::move(value)));
2815  auto const iter(m_cont.insert_commit(*p, d));
2816  chronological.list.push_back(*p);
2817  return std::make_pair(iterator(iter), true);
2818  }
2819  return std::make_pair(iterator(result.first), false);
2820 }
2821 
2822 // multimap, multiset
2823 template <
2824  bool IsMulti,
2825  bool IsMap,
2826  class Key,
2827  class T,
2828  class Clock,
2829  class Hash,
2830  class KeyEqual,
2831  class Allocator>
2832 template <bool maybe_multi, bool maybe_map>
2833 auto
2835  IsMulti,
2836  IsMap,
2837  Key,
2838  T,
2839  Clock,
2840  Hash,
2841  KeyEqual,
2842  Allocator>::insert(value_type&& value) ->
2844 {
2845  maybe_rehash(1);
2846  element* const p(new_element(std::move(value)));
2847  chronological.list.push_back(*p);
2848  auto const iter(m_cont.insert(*p));
2849  return iterator(iter);
2850 }
2851 
2852 #if 1 // Use insert() instead of insert_check() insert_commit()
2853 // set, map
2854 template <
2855  bool IsMulti,
2856  bool IsMap,
2857  class Key,
2858  class T,
2859  class Clock,
2860  class Hash,
2861  class KeyEqual,
2862  class Allocator>
2863 template <bool maybe_multi, class... Args>
2864 auto
2865 aged_unordered_container<
2866  IsMulti,
2867  IsMap,
2868  Key,
2869  T,
2870  Clock,
2871  Hash,
2872  KeyEqual,
2873  Allocator>::emplace(Args&&... args) ->
2875 {
2876  maybe_rehash(1);
2877  // VFALCO NOTE Its unfortunate that we need to
2878  // construct element here
2879  element* const p(new_element(std::forward<Args>(args)...));
2880  auto const result(m_cont.insert(*p));
2881  if (result.second)
2882  {
2883  chronological.list.push_back(*p);
2884  return std::make_pair(iterator(result.first), true);
2885  }
2886  delete_element(p);
2887  return std::make_pair(iterator(result.first), false);
2888 }
2889 #else // As original, use insert_check() / insert_commit () pair.
2890 // set, map
2891 template <
2892  bool IsMulti,
2893  bool IsMap,
2894  class Key,
2895  class T,
2896  class Clock,
2897  class Hash,
2898  class KeyEqual,
2899  class Allocator>
2900 template <bool maybe_multi, class... Args>
2901 auto
2903  IsMulti,
2904  IsMap,
2905  Key,
2906  T,
2907  Clock,
2908  Hash,
2909  KeyEqual,
2910  Allocator>::emplace(Args&&... args) ->
2912 {
2913  maybe_rehash(1);
2914  // VFALCO NOTE Its unfortunate that we need to
2915  // construct element here
2916  element* const p(new_element(std::forward<Args>(args)...));
2917  typename cont_type::insert_commit_data d;
2918  auto const result(m_cont.insert_check(
2919  extract(p->value),
2920  std::cref(m_config.hash_function()),
2921  std::cref(m_config.key_value_equal()),
2922  d));
2923  if (result.second)
2924  {
2925  auto const iter(m_cont.insert_commit(*p, d));
2926  chronological.list.push_back(*p);
2927  return std::make_pair(iterator(iter), true);
2928  }
2929  delete_element(p);
2930  return std::make_pair(iterator(result.first), false);
2931 }
2932 #endif // 0
2933 
2934 // multiset, multimap
2935 template <
2936  bool IsMulti,
2937  bool IsMap,
2938  class Key,
2939  class T,
2940  class Clock,
2941  class Hash,
2942  class KeyEqual,
2943  class Allocator>
2944 template <bool maybe_multi, class... Args>
2945 auto
2946 aged_unordered_container<
2947  IsMulti,
2948  IsMap,
2949  Key,
2950  T,
2951  Clock,
2952  Hash,
2953  KeyEqual,
2954  Allocator>::emplace(Args&&... args) ->
2956 {
2957  maybe_rehash(1);
2958  element* const p(new_element(std::forward<Args>(args)...));
2959  chronological.list.push_back(*p);
2960  auto const iter(m_cont.insert(*p));
2961  return iterator(iter);
2962 }
2963 
2964 // set, map
2965 template <
2966  bool IsMulti,
2967  bool IsMap,
2968  class Key,
2969  class T,
2970  class Clock,
2971  class Hash,
2972  class KeyEqual,
2973  class Allocator>
2974 template <bool maybe_multi, class... Args>
2975 auto
2976 aged_unordered_container<
2977  IsMulti,
2978  IsMap,
2979  Key,
2980  T,
2981  Clock,
2982  Hash,
2983  KeyEqual,
2984  Allocator>::emplace_hint(const_iterator /*hint*/, Args&&... args) ->
2986 {
2987  maybe_rehash(1);
2988  // VFALCO NOTE Its unfortunate that we need to
2989  // construct element here
2990  element* const p(new_element(std::forward<Args>(args)...));
2991  typename cont_type::insert_commit_data d;
2992  auto const result(m_cont.insert_check(
2993  extract(p->value),
2994  std::cref(m_config.hash_function()),
2995  std::cref(m_config.key_value_equal()),
2996  d));
2997  if (result.second)
2998  {
2999  auto const iter(m_cont.insert_commit(*p, d));
3000  chronological.list.push_back(*p);
3001  return std::make_pair(iterator(iter), true);
3002  }
3003  delete_element(p);
3004  return std::make_pair(iterator(result.first), false);
3005 }
3006 
3007 template <
3008  bool IsMulti,
3009  bool IsMap,
3010  class Key,
3011  class T,
3012  class Clock,
3013  class Hash,
3014  class KeyEqual,
3015  class Allocator>
3016 template <bool is_const, class Iterator>
3019  IsMulti,
3020  IsMap,
3021  Key,
3022  T,
3023  Clock,
3024  Hash,
3025  KeyEqual,
3027  pos)
3028 {
3029  unlink_and_delete_element(&*((pos++).iterator()));
3031  pos.iterator());
3032 }
3033 
3034 template <
3035  bool IsMulti,
3036  bool IsMap,
3037  class Key,
3038  class T,
3039  class Clock,
3040  class Hash,
3041  class KeyEqual,
3042  class Allocator>
3043 template <bool is_const, class Iterator>
3046  IsMulti,
3047  IsMap,
3048  Key,
3049  T,
3050  Clock,
3051  Hash,
3052  KeyEqual,
3053  Allocator>::
3054  erase(
3057 {
3058  for (; first != last;)
3059  unlink_and_delete_element(&*((first++).iterator()));
3060 
3062  first.iterator());
3063 }
3064 
3065 template <
3066  bool IsMulti,
3067  bool IsMap,
3068  class Key,
3069  class T,
3070  class Clock,
3071  class Hash,
3072  class KeyEqual,
3073  class Allocator>
3074 template <class K>
3075 auto
3077  IsMulti,
3078  IsMap,
3079  Key,
3080  T,
3081  Clock,
3082  Hash,
3083  KeyEqual,
3084  Allocator>::erase(K const& k) -> size_type
3085 {
3086  auto iter(m_cont.find(
3087  k,
3088  std::cref(m_config.hash_function()),
3089  std::cref(m_config.key_value_equal())));
3090  if (iter == m_cont.end())
3091  return 0;
3092  size_type n(0);
3093  for (;;)
3094  {
3095  auto p(&*iter++);
3096  bool const done(m_config(*p, extract(iter->value)));
3097  unlink_and_delete_element(p);
3098  ++n;
3099  if (done)
3100  break;
3101  }
3102  return n;
3103 }
3104 
3105 template <
3106  bool IsMulti,
3107  bool IsMap,
3108  class Key,
3109  class T,
3110  class Clock,
3111  class Hash,
3112  class KeyEqual,
3113  class Allocator>
3114 void
3116  IsMulti,
3117  IsMap,
3118  Key,
3119  T,
3120  Clock,
3121  Hash,
3122  KeyEqual,
3123  Allocator>::swap(aged_unordered_container& other) noexcept
3124 {
3125  swap_data(other);
3126  std::swap(chronological, other.chronological);
3127  std::swap(m_cont, other.m_cont);
3128 }
3129 
3130 template <
3131  bool IsMulti,
3132  bool IsMap,
3133  class Key,
3134  class T,
3135  class Clock,
3136  class Hash,
3137  class KeyEqual,
3138  class Allocator>
3139 template <class K>
3140 auto
3142  IsMulti,
3143  IsMap,
3144  Key,
3145  T,
3146  Clock,
3147  Hash,
3148  KeyEqual,
3149  Allocator>::touch(K const& k) -> size_type
3150 {
3151  auto const now(clock().now());
3152  size_type n(0);
3153  auto const range(equal_range(k));
3154  for (auto iter : range)
3155  {
3156  touch(iter, now);
3157  ++n;
3158  }
3159  return n;
3160 }
3161 
3162 template <
3163  bool IsMulti,
3164  bool IsMap,
3165  class Key,
3166  class T,
3167  class Clock,
3168  class Hash,
3169  class KeyEqual,
3170  class Allocator>
3171 template <
3172  bool OtherIsMap,
3173  class OtherKey,
3174  class OtherT,
3175  class OtherDuration,
3176  class OtherHash,
3177  class OtherAllocator,
3178  bool maybe_multi>
3181  IsMulti,
3182  IsMap,
3183  Key,
3184  T,
3185  Clock,
3186  Hash,
3187  KeyEqual,
3188  Allocator>::
3190  false,
3191  OtherIsMap,
3192  OtherKey,
3193  OtherT,
3194  OtherDuration,
3195  OtherHash,
3196  KeyEqual,
3197  OtherAllocator> const& other) const
3198 {
3199  if (size() != other.size())
3200  return false;
3201  for (auto iter(cbegin()), last(cend()), olast(other.cend()); iter != last;
3202  ++iter)
3203  {
3204  auto oiter(other.find(extract(*iter)));
3205  if (oiter == olast)
3206  return false;
3207  }
3208  return true;
3209 }
3210 
3211 template <
3212  bool IsMulti,
3213  bool IsMap,
3214  class Key,
3215  class T,
3216  class Clock,
3217  class Hash,
3218  class KeyEqual,
3219  class Allocator>
3220 template <
3221  bool OtherIsMap,
3222  class OtherKey,
3223  class OtherT,
3224  class OtherDuration,
3225  class OtherHash,
3226  class OtherAllocator,
3227  bool maybe_multi>
3230  IsMulti,
3231  IsMap,
3232  Key,
3233  T,
3234  Clock,
3235  Hash,
3236  KeyEqual,
3237  Allocator>::
3239  true,
3240  OtherIsMap,
3241  OtherKey,
3242  OtherT,
3243  OtherDuration,
3244  OtherHash,
3245  KeyEqual,
3246  OtherAllocator> const& other) const
3247 {
3248  if (size() != other.size())
3249  return false;
3251  for (auto iter(cbegin()), last(cend()); iter != last;)
3252  {
3253  auto const& k(extract(*iter));
3254  auto const eq(equal_range(k));
3255  auto const oeq(other.equal_range(k));
3256 #if BEAST_NO_CXX14_IS_PERMUTATION
3257  if (std::distance(eq.first, eq.second) !=
3258  std::distance(oeq.first, oeq.second) ||
3259  !std::is_permutation(eq.first, eq.second, oeq.first))
3260  return false;
3261 #else
3262  if (!std::is_permutation(eq.first, eq.second, oeq.first, oeq.second))
3263  return false;
3264 #endif
3265  iter = eq.second;
3266  }
3267  return true;
3268 }
3269 
3270 //------------------------------------------------------------------------------
3271 
3272 // map, set
3273 template <
3274  bool IsMulti,
3275  bool IsMap,
3276  class Key,
3277  class T,
3278  class Clock,
3279  class Hash,
3280  class KeyEqual,
3281  class Allocator>
3282 template <bool maybe_multi>
3283 auto
3285  IsMulti,
3286  IsMap,
3287  Key,
3288  T,
3289  Clock,
3290  Hash,
3291  KeyEqual,
3292  Allocator>::insert_unchecked(value_type const& value) ->
3294 {
3295  typename cont_type::insert_commit_data d;
3296  auto const result(m_cont.insert_check(
3297  extract(value),
3298  std::cref(m_config.hash_function()),
3299  std::cref(m_config.key_value_equal()),
3300  d));
3301  if (result.second)
3302  {
3303  element* const p(new_element(value));
3304  auto const iter(m_cont.insert_commit(*p, d));
3305  chronological.list.push_back(*p);
3306  return std::make_pair(iterator(iter), true);
3307  }
3308  return std::make_pair(iterator(result.first), false);
3309 }
3310 
3311 // multimap, multiset
3312 template <
3313  bool IsMulti,
3314  bool IsMap,
3315  class Key,
3316  class T,
3317  class Clock,
3318  class Hash,
3319  class KeyEqual,
3320  class Allocator>
3321 template <bool maybe_multi>
3322 auto
3324  IsMulti,
3325  IsMap,
3326  Key,
3327  T,
3328  Clock,
3329  Hash,
3330  KeyEqual,
3331  Allocator>::insert_unchecked(value_type const& value) ->
3333 {
3334  element* const p(new_element(value));
3335  chronological.list.push_back(*p);
3336  auto const iter(m_cont.insert(*p));
3337  return iterator(iter);
3338 }
3339 
3340 //------------------------------------------------------------------------------
3341 
3342 } // namespace detail
3343 
3344 //------------------------------------------------------------------------------
3345 
3346 template <
3347  bool IsMulti,
3348  bool IsMap,
3349  class Key,
3350  class T,
3351  class Clock,
3352  class Hash,
3353  class KeyEqual,
3354  class Allocator>
3356  IsMulti,
3357  IsMap,
3358  Key,
3359  T,
3360  Clock,
3361  Hash,
3362  KeyEqual,
3363  Allocator>> : std::true_type
3364 {
3365  explicit is_aged_container() = default;
3366 };
3367 
3368 // Free functions
3369 
3370 template <
3371  bool IsMulti,
3372  bool IsMap,
3373  class Key,
3374  class T,
3375  class Clock,
3376  class Hash,
3377  class KeyEqual,
3378  class Allocator>
3379 void
3380 swap(
3382  IsMulti,
3383  IsMap,
3384  Key,
3385  T,
3386  Clock,
3387  Hash,
3388  KeyEqual,
3389  Allocator>& lhs,
3391  IsMulti,
3392  IsMap,
3393  Key,
3394  T,
3395  Clock,
3396  Hash,
3397  KeyEqual,
3398  Allocator>& rhs) noexcept
3399 {
3400  lhs.swap(rhs);
3401 }
3402 
3404 template <
3405  bool IsMulti,
3406  bool IsMap,
3407  class Key,
3408  class T,
3409  class Clock,
3410  class Hash,
3411  class KeyEqual,
3412  class Allocator,
3413  class Rep,
3414  class Period>
3418  IsMulti,
3419  IsMap,
3420  Key,
3421  T,
3422  Clock,
3423  Hash,
3424  KeyEqual,
3425  Allocator>& c,
3426  std::chrono::duration<Rep, Period> const& age) noexcept
3427 {
3428  std::size_t n(0);
3429  auto const expired(c.clock().now() - age);
3430  for (auto iter(c.chronological.cbegin());
3431  iter != c.chronological.cend() && iter.when() <= expired;)
3432  {
3433  iter = c.erase(iter);
3434  ++n;
3435  }
3436  return n;
3437 }
3438 
3439 } // namespace beast
3440 
3441 #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:1282
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:1361
beast::detail::aged_unordered_container::max_load_factor
void max_load_factor(float ml)
Definition: aged_unordered_container.h:1355
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:1386
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:2873
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:1506
beast::detail::aged_unordered_container::insert_unchecked
void insert_unchecked(InputIt first, InputIt last)
Definition: aged_unordered_container.h:1490
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:1548
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:1547
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:1247
beast::detail::aged_unordered_container::reserve
void reserve(size_type count)
Definition: aged_unordered_container.h:1368
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:2732
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:1330
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:1259
beast::detail::aged_unordered_container::swap
void swap(aged_unordered_container &other) noexcept
Definition: aged_unordered_container.h:3123
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:1540
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:1300
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:3292
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:1515
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:1288
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:1448
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:1318
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:1214
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:1312
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:2443
beast::detail::aged_unordered_container::cend
const_local_iterator cend(size_type n) const
Definition: aged_unordered_container.h:1306
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:1324
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:1276
beast::detail::aged_unordered_container::max_load_factor
float max_load_factor() const
Definition: aged_unordered_container.h:1349
beast::detail::aged_unordered_container::load_factor
float load_factor() const
Definition: aged_unordered_container.h:1343
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:3189
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:1549
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:1498
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:1463
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:1294
beast::detail::aged_unordered_container::operator=
aged_unordered_container & operator=(aged_unordered_container const &other)
Definition: aged_unordered_container.h:2466
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:2984
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:2702
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:1225
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:3026
beast::detail::aged_unordered_container::operator[]
std::conditional< IsMap, T, void * >::type & operator[](Key const &key)
Definition: aged_unordered_container.h:2619
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:1469
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:1529
beast::detail::aged_unordered_container::find
const_iterator find(K const &k) const
Definition: aged_unordered_container.h:1236
beast::detail::aged_unordered_container::hash_function
hasher const & hash_function() const
Definition: aged_unordered_container.h:1380
beast::detail::aged_unordered_container::touch
void touch(beast::detail::aged_container_iterator< is_const, Iterator > pos)
Definition: aged_unordered_container.h:1196
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:2559
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