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
152 #ifdef _LIBCPP_VERSION
153  ,
155 #endif
156  {
157  public:
158 #ifndef _LIBCPP_VERSION
160  using result_type = size_t;
161 #endif
162 
164  {
165  }
166 
167  ValueHash(Hash const& h)
168  : beast::detail::empty_base_optimization<Hash>(h)
169  {
170  }
171 
173  operator()(element const& e) const
174  {
175  return this->member()(extract(e.value));
176  }
177 
178  Hash&
180  {
181  return this->member();
182  }
183 
184  Hash const&
186  {
187  return this->member();
188  }
189  };
190 
191  // Compares value_type against element, used in find/insert_check
192  // VFALCO TODO hoist to remove template argument dependencies
195 #ifdef _LIBCPP_VERSION
196  ,
198 #endif
199  {
200  public:
201 #ifndef _LIBCPP_VERSION
202  using first_argument_type = Key;
204  using result_type = bool;
205 #endif
206 
208  {
209  }
210 
211  KeyValueEqual(KeyEqual const& keyEqual)
212  : beast::detail::empty_base_optimization<KeyEqual>(keyEqual)
213  {
214  }
215 
216  // VFALCO NOTE WE might want only to enable these overloads
217  // if KeyEqual has is_transparent
218 #if 0
219  template <class K>
220  bool operator() (K const& k, element const& e) const
221  {
222  return this->member() (k, extract (e.value));
223  }
224 
225  template <class K>
226  bool operator() (element const& e, K const& k) const
227  {
228  return this->member() (extract (e.value), k);
229  }
230 #endif
231 
232  bool
233  operator()(Key const& k, element const& e) const
234  {
235  return this->member()(k, extract(e.value));
236  }
237 
238  bool
239  operator()(element const& e, Key const& k) const
240  {
241  return this->member()(extract(e.value), k);
242  }
243 
244  bool
245  operator()(element const& lhs, element const& rhs) const
246  {
247  return this->member()(extract(lhs.value), extract(rhs.value));
248  }
249 
250  KeyEqual&
252  {
253  return this->member();
254  }
255 
256  KeyEqual const&
257  key_eq() const
258  {
259  return this->member();
260  }
261  };
262 
263  using list_type = typename boost::intrusive::
264  make_list<element, boost::intrusive::constant_time_size<false>>::type;
265 
266  using cont_type = typename std::conditional<
267  IsMulti,
268  typename boost::intrusive::make_unordered_multiset<
269  element,
270  boost::intrusive::constant_time_size<true>,
271  boost::intrusive::hash<ValueHash>,
272  boost::intrusive::equal<KeyValueEqual>,
273  boost::intrusive::cache_begin<true>>::type,
274  typename boost::intrusive::make_unordered_set<
275  element,
276  boost::intrusive::constant_time_size<true>,
277  boost::intrusive::hash<ValueHash>,
278  boost::intrusive::equal<KeyValueEqual>,
279  boost::intrusive::cache_begin<true>>::type>::type;
280 
281  using bucket_type = typename cont_type::bucket_type;
282  using bucket_traits = typename cont_type::bucket_traits;
283 
284  using ElementAllocator = typename std::allocator_traits<
285  Allocator>::template rebind_alloc<element>;
286 
288 
289  using BucketAllocator = typename std::allocator_traits<
290  Allocator>::template rebind_alloc<element>;
291 
293 
294  class config_t
295  : private ValueHash,
296  private KeyValueEqual,
297  private beast::detail::empty_base_optimization<ElementAllocator>
298  {
299  public:
300  explicit config_t(clock_type& clock_) : clock(clock_)
301  {
302  }
303 
304  config_t(clock_type& clock_, Hash const& hash)
305  : ValueHash(hash), clock(clock_)
306  {
307  }
308 
309  config_t(clock_type& clock_, KeyEqual const& keyEqual)
310  : KeyValueEqual(keyEqual), clock(clock_)
311  {
312  }
313 
314  config_t(clock_type& clock_, Allocator const& alloc_)
316  , clock(clock_)
317  {
318  }
319 
320  config_t(clock_type& clock_, Hash const& hash, KeyEqual const& keyEqual)
321  : ValueHash(hash), KeyValueEqual(keyEqual), clock(clock_)
322  {
323  }
324 
325  config_t(clock_type& clock_, Hash const& hash, Allocator const& alloc_)
326  : ValueHash(hash)
328  , clock(clock_)
329  {
330  }
331 
333  clock_type& clock_,
334  KeyEqual const& keyEqual,
335  Allocator const& alloc_)
336  : KeyValueEqual(keyEqual)
338  , clock(clock_)
339  {
340  }
341 
343  clock_type& clock_,
344  Hash const& hash,
345  KeyEqual const& keyEqual,
346  Allocator const& alloc_)
347  : ValueHash(hash)
348  , KeyValueEqual(keyEqual)
350  , clock(clock_)
351  {
352  }
353 
354  config_t(config_t const& other)
355  : ValueHash(other.hash_function())
356  , KeyValueEqual(other.key_eq())
358  ElementAllocatorTraits::select_on_container_copy_construction(
359  other.alloc()))
360  , clock(other.clock)
361  {
362  }
363 
364  config_t(config_t const& other, Allocator const& alloc)
365  : ValueHash(other.hash_function())
366  , KeyValueEqual(other.key_eq())
368  , clock(other.clock)
369  {
370  }
371 
373  : ValueHash(std::move(other.hash_function()))
374  , KeyValueEqual(std::move(other.key_eq()))
376  std::move(other.alloc()))
377  , clock(other.clock)
378  {
379  }
380 
381  config_t(config_t&& other, Allocator const& alloc)
382  : ValueHash(std::move(other.hash_function()))
383  , KeyValueEqual(std::move(other.key_eq()))
385  , clock(other.clock)
386  {
387  }
388 
389  config_t&
390  operator=(config_t const& other)
391  {
392  hash_function() = other.hash_function();
393  key_eq() = other.key_eq();
394  alloc() = other.alloc();
395  clock = other.clock;
396  return *this;
397  }
398 
399  config_t&
401  {
402  hash_function() = std::move(other.hash_function());
403  key_eq() = std::move(other.key_eq());
404  alloc() = std::move(other.alloc());
405  clock = other.clock;
406  return *this;
407  }
408 
409  ValueHash&
411  {
412  return *this;
413  }
414 
415  ValueHash const&
416  value_hash() const
417  {
418  return *this;
419  }
420 
421  Hash&
423  {
424  return ValueHash::hash_function();
425  }
426 
427  Hash const&
429  {
430  return ValueHash::hash_function();
431  }
432 
435  {
436  return *this;
437  }
438 
439  KeyValueEqual const&
441  {
442  return *this;
443  }
444 
445  KeyEqual&
447  {
448  return key_value_equal().key_eq();
449  }
450 
451  KeyEqual const&
452  key_eq() const
453  {
454  return key_value_equal().key_eq();
455  }
456 
459  {
462  }
463 
464  ElementAllocator const&
465  alloc() const
466  {
469  }
470 
472  };
473 
474  class Buckets
475  {
476  public:
477  using vec_type = std::vector<
478  bucket_type,
479  typename std::allocator_traits<Allocator>::template rebind_alloc<
481 
483  {
484  m_vec.resize(cont_type::suggested_upper_bucket_count(0));
485  }
486 
487  Buckets(Allocator const& alloc) : m_max_load_factor(1.f), m_vec(alloc)
488  {
489  m_vec.resize(cont_type::suggested_upper_bucket_count(0));
490  }
491 
492  operator bucket_traits()
493  {
494  return bucket_traits(&m_vec[0], m_vec.size());
495  }
496 
497  void
499  {
500  m_vec.clear();
501  }
502 
503  size_type
505  {
506  return m_vec.max_size();
507  }
508 
509  float&
511  {
512  return m_max_load_factor;
513  }
514 
515  float const&
517  {
518  return m_max_load_factor;
519  }
520 
521  // count is the number of buckets
522  template <class Container>
523  void
524  rehash(size_type count, Container& c)
525  {
526  size_type const size(m_vec.size());
527  if (count == size)
528  return;
529  if (count > m_vec.capacity())
530  {
531  // Need two vectors otherwise we
532  // will destroy non-empty buckets.
534  std::swap(m_vec, vec);
535  m_vec.resize(count);
536  c.rehash(bucket_traits(&m_vec[0], m_vec.size()));
537  return;
538  }
539  // Rehash in place.
540  if (count > size)
541  {
542  // This should not reallocate since
543  // we checked capacity earlier.
544  m_vec.resize(count);
545  c.rehash(bucket_traits(&m_vec[0], count));
546  return;
547  }
548  // Resize must happen after rehash otherwise
549  // we might destroy non-empty buckets.
550  c.rehash(bucket_traits(&m_vec[0], count));
551  m_vec.resize(count);
552  }
553 
554  // Resize the buckets to accomodate at least n items.
555  template <class Container>
556  void
557  resize(size_type n, Container& c)
558  {
559  size_type const suggested(
560  cont_type::suggested_upper_bucket_count(n));
561  rehash(suggested, c);
562  }
563 
564  private:
567  };
568 
569  template <class... Args>
570  element*
571  new_element(Args&&... args)
572  {
573  struct Deleter
574  {
576  Deleter(ElementAllocator& a) : a_(a)
577  {
578  }
579 
580  void
581  operator()(element* p)
582  {
584  }
585  };
586 
589  Deleter(m_config.alloc()));
591  m_config.alloc(),
592  p.get(),
593  clock().now(),
594  std::forward<Args>(args)...);
595  return p.release();
596  }
597 
598  void
599  delete_element(element const* p)
600  {
603  m_config.alloc(), const_cast<element*>(p), 1);
604  }
605 
606  void
607  unlink_and_delete_element(element const* p)
608  {
609  chronological.list.erase(chronological.list.iterator_to(*p));
610  m_cont.erase(m_cont.iterator_to(*p));
611  delete_element(p);
612  }
613 
614 public:
615  using hasher = Hash;
616  using key_equal = KeyEqual;
617  using allocator_type = Allocator;
619  using const_reference = value_type const&;
621  using const_pointer =
623 
624  // A set iterator (IsMap==false) is always const
625  // because the elements of a set are immutable.
626  using iterator = beast::detail::
627  aged_container_iterator<!IsMap, typename cont_type::iterator>;
628  using const_iterator = beast::detail::
629  aged_container_iterator<true, typename cont_type::iterator>;
630 
631  using local_iterator = beast::detail::
632  aged_container_iterator<!IsMap, typename cont_type::local_iterator>;
633  using const_local_iterator = beast::detail::
634  aged_container_iterator<true, typename cont_type::local_iterator>;
635 
636  //--------------------------------------------------------------------------
637  //
638  // Chronological ordered iterators
639  //
640  // "Memberspace"
641  // http://accu.org/index.php/journals/1527
642  //
643  //--------------------------------------------------------------------------
644 
646  {
647  public:
648  // A set iterator (IsMap==false) is always const
649  // because the elements of a set are immutable.
650  using iterator = beast::detail::
651  aged_container_iterator<!IsMap, typename list_type::iterator>;
652  using const_iterator = beast::detail::
653  aged_container_iterator<true, typename list_type::iterator>;
655  !IsMap,
656  typename list_type::reverse_iterator>;
657  using const_reverse_iterator = beast::detail::
658  aged_container_iterator<true, typename list_type::reverse_iterator>;
659 
660  iterator
662  {
663  return iterator(list.begin());
664  }
665 
667  begin() const
668  {
669  return const_iterator(list.begin());
670  }
671 
673  cbegin() const
674  {
675  return const_iterator(list.begin());
676  }
677 
678  iterator
679  end()
680  {
681  return iterator(list.end());
682  }
683 
685  end() const
686  {
687  return const_iterator(list.end());
688  }
689 
691  cend() const
692  {
693  return const_iterator(list.end());
694  }
695 
698  {
699  return reverse_iterator(list.rbegin());
700  }
701 
703  rbegin() const
704  {
705  return const_reverse_iterator(list.rbegin());
706  }
707 
709  crbegin() const
710  {
711  return const_reverse_iterator(list.rbegin());
712  }
713 
716  {
717  return reverse_iterator(list.rend());
718  }
719 
721  rend() const
722  {
723  return const_reverse_iterator(list.rend());
724  }
725 
727  crend() const
728  {
729  return const_reverse_iterator(list.rend());
730  }
731 
732  iterator
734  {
735  static_assert(
737  "must be standard layout");
738  return list.iterator_to(*reinterpret_cast<element*>(
739  reinterpret_cast<uint8_t*>(&value) -
740  ((std::size_t)std::addressof(((element*)0)->member))));
741  }
742 
744  iterator_to(value_type const& value) const
745  {
746  static_assert(
748  "must be standard layout");
749  return list.iterator_to(*reinterpret_cast<element const*>(
750  reinterpret_cast<uint8_t const*>(&value) -
751  ((std::size_t)std::addressof(((element*)0)->member))));
752  }
753 
754  private:
756  {
757  }
758 
759  chronological_t(chronological_t const&) = delete;
760  chronological_t(chronological_t&&) = delete;
761 
763  list_type mutable list;
764  } chronological;
765 
766  //--------------------------------------------------------------------------
767  //
768  // Construction
769  //
770  //--------------------------------------------------------------------------
771 
772  aged_unordered_container() = delete;
773 
775 
776  aged_unordered_container(clock_type& clock, Hash const& hash);
777 
778  aged_unordered_container(clock_type& clock, KeyEqual const& key_eq);
779 
780  aged_unordered_container(clock_type& clock, Allocator const& alloc);
781 
783  clock_type& clock,
784  Hash const& hash,
785  KeyEqual const& key_eq);
786 
788  clock_type& clock,
789  Hash const& hash,
790  Allocator const& alloc);
791 
793  clock_type& clock,
794  KeyEqual const& key_eq,
795  Allocator const& alloc);
796 
798  clock_type& clock,
799  Hash const& hash,
800  KeyEqual const& key_eq,
801  Allocator const& alloc);
802 
803  template <class InputIt>
804  aged_unordered_container(InputIt first, InputIt last, clock_type& clock);
805 
806  template <class InputIt>
808  InputIt first,
809  InputIt last,
810  clock_type& clock,
811  Hash const& hash);
812 
813  template <class InputIt>
815  InputIt first,
816  InputIt last,
817  clock_type& clock,
818  KeyEqual const& key_eq);
819 
820  template <class InputIt>
822  InputIt first,
823  InputIt last,
824  clock_type& clock,
825  Allocator const& alloc);
826 
827  template <class InputIt>
829  InputIt first,
830  InputIt last,
831  clock_type& clock,
832  Hash const& hash,
833  KeyEqual const& key_eq);
834 
835  template <class InputIt>
837  InputIt first,
838  InputIt last,
839  clock_type& clock,
840  Hash const& hash,
841  Allocator const& alloc);
842 
843  template <class InputIt>
845  InputIt first,
846  InputIt last,
847  clock_type& clock,
848  KeyEqual const& key_eq,
849  Allocator const& alloc);
850 
851  template <class InputIt>
853  InputIt first,
854  InputIt last,
855  clock_type& clock,
856  Hash const& hash,
857  KeyEqual const& key_eq,
858  Allocator const& alloc);
859 
861 
863  aged_unordered_container const& other,
864  Allocator const& alloc);
865 
867 
869  aged_unordered_container&& other,
870  Allocator const& alloc);
871 
874  clock_type& clock);
875 
878  clock_type& clock,
879  Hash const& hash);
880 
883  clock_type& clock,
884  KeyEqual const& key_eq);
885 
888  clock_type& clock,
889  Allocator const& alloc);
890 
893  clock_type& clock,
894  Hash const& hash,
895  KeyEqual const& key_eq);
896 
899  clock_type& clock,
900  Hash const& hash,
901  Allocator const& alloc);
902 
905  clock_type& clock,
906  KeyEqual const& key_eq,
907  Allocator const& alloc);
908 
911  clock_type& clock,
912  Hash const& hash,
913  KeyEqual const& key_eq,
914  Allocator const& alloc);
915 
917 
919  operator=(aged_unordered_container const& other);
920 
923 
926 
929  {
930  return m_config.alloc();
931  }
932 
933  clock_type&
935  {
936  return m_config.clock;
937  }
938 
939  clock_type const&
940  clock() const
941  {
942  return m_config.clock;
943  }
944 
945  //--------------------------------------------------------------------------
946  //
947  // Element access (maps)
948  //
949  //--------------------------------------------------------------------------
950 
951  template <
952  class K,
953  bool maybe_multi = IsMulti,
954  bool maybe_map = IsMap,
957  at(K const& k);
958 
959  template <
960  class K,
961  bool maybe_multi = IsMulti,
962  bool maybe_map = IsMap,
965  at(K const& k) const;
966 
967  template <
968  bool maybe_multi = IsMulti,
969  bool maybe_map = IsMap,
972  operator[](Key const& key);
973 
974  template <
975  bool maybe_multi = IsMulti,
976  bool maybe_map = IsMap,
979  operator[](Key&& key);
980 
981  //--------------------------------------------------------------------------
982  //
983  // Iterators
984  //
985  //--------------------------------------------------------------------------
986 
987  iterator
989  {
990  return iterator(m_cont.begin());
991  }
992 
994  begin() const
995  {
996  return const_iterator(m_cont.begin());
997  }
998 
1000  cbegin() const
1001  {
1002  return const_iterator(m_cont.begin());
1003  }
1004 
1005  iterator
1007  {
1008  return iterator(m_cont.end());
1009  }
1010 
1012  end() const
1013  {
1014  return const_iterator(m_cont.end());
1015  }
1016 
1018  cend() const
1019  {
1020  return const_iterator(m_cont.end());
1021  }
1022 
1023  iterator
1025  {
1026  static_assert(
1027  std::is_standard_layout<element>::value, "must be standard layout");
1028  return m_cont.iterator_to(*reinterpret_cast<element*>(
1029  reinterpret_cast<uint8_t*>(&value) -
1030  ((std::size_t)std::addressof(((element*)0)->member))));
1031  }
1032 
1034  iterator_to(value_type const& value) const
1035  {
1036  static_assert(
1037  std::is_standard_layout<element>::value, "must be standard layout");
1038  return m_cont.iterator_to(*reinterpret_cast<element const*>(
1039  reinterpret_cast<uint8_t const*>(&value) -
1040  ((std::size_t)std::addressof(((element*)0)->member))));
1041  }
1042 
1043  //--------------------------------------------------------------------------
1044  //
1045  // Capacity
1046  //
1047  //--------------------------------------------------------------------------
1048 
1049  bool
1050  empty() const noexcept
1051  {
1052  return m_cont.empty();
1053  }
1054 
1055  size_type
1056  size() const noexcept
1057  {
1058  return m_cont.size();
1059  }
1060 
1061  size_type
1062  max_size() const noexcept
1063  {
1064  return m_config.max_size();
1065  }
1066 
1067  //--------------------------------------------------------------------------
1068  //
1069  // Modifiers
1070  //
1071  //--------------------------------------------------------------------------
1072 
1073  void
1074  clear();
1075 
1076  // map, set
1077  template <bool maybe_multi = IsMulti>
1078  auto
1079  insert(value_type const& value) ->
1081 
1082  // multimap, multiset
1083  template <bool maybe_multi = IsMulti>
1084  auto
1085  insert(value_type const& value) ->
1087 
1088  // map, set
1089  template <bool maybe_multi = IsMulti, bool maybe_map = IsMap>
1090  auto
1091  insert(value_type&& value) -> typename std::
1092  enable_if<!maybe_multi && !maybe_map, std::pair<iterator, bool>>::type;
1093 
1094  // multimap, multiset
1095  template <bool maybe_multi = IsMulti, bool maybe_map = IsMap>
1096  auto
1097  insert(value_type&& value) ->
1099 
1100  // map, set
1101  template <bool maybe_multi = IsMulti>
1103  insert(const_iterator /*hint*/, value_type const& value)
1104  {
1105  // Hint is ignored but we provide the interface so
1106  // callers may use ordered and unordered interchangeably.
1107  return insert(value).first;
1108  }
1109 
1110  // multimap, multiset
1111  template <bool maybe_multi = IsMulti>
1113  insert(const_iterator /*hint*/, value_type const& value)
1114  {
1115  // VFALCO TODO The hint could be used to let
1116  // the client order equal ranges
1117  return insert(value);
1118  }
1119 
1120  // map, set
1121  template <bool maybe_multi = IsMulti>
1123  insert(const_iterator /*hint*/, value_type&& value)
1124  {
1125  // Hint is ignored but we provide the interface so
1126  // callers may use ordered and unordered interchangeably.
1127  return insert(std::move(value)).first;
1128  }
1129 
1130  // multimap, multiset
1131  template <bool maybe_multi = IsMulti>
1133  insert(const_iterator /*hint*/, value_type&& value)
1134  {
1135  // VFALCO TODO The hint could be used to let
1136  // the client order equal ranges
1137  return insert(std::move(value));
1138  }
1139 
1140  // map, multimap
1141  template <class P, bool maybe_map = IsMap>
1142  typename std::enable_if<
1144  typename std::
1145  conditional<IsMulti, iterator, std::pair<iterator, bool>>::type>::
1146  type
1147  insert(P&& value)
1148  {
1149  return emplace(std::forward<P>(value));
1150  }
1151 
1152  // map, multimap
1153  template <class P, bool maybe_map = IsMap>
1154  typename std::enable_if<
1156  typename std::
1157  conditional<IsMulti, iterator, std::pair<iterator, bool>>::type>::
1158  type
1159  insert(const_iterator hint, P&& value)
1160  {
1161  return emplace_hint(hint, std::forward<P>(value));
1162  }
1163 
1164  template <class InputIt>
1165  void
1166  insert(InputIt first, InputIt last)
1167  {
1168  insert(
1169  first,
1170  last,
1172  }
1173 
1174  void
1176  {
1177  insert(init.begin(), init.end());
1178  }
1179 
1180  // set, map
1181  template <bool maybe_multi = IsMulti, class... Args>
1182  auto
1183  emplace(Args&&... args) ->
1185 
1186  // multiset, multimap
1187  template <bool maybe_multi = IsMulti, class... Args>
1188  auto
1189  emplace(Args&&... args) ->
1191 
1192  // set, map
1193  template <bool maybe_multi = IsMulti, class... Args>
1194  auto
1195  emplace_hint(const_iterator /*hint*/, Args&&... args) ->
1197 
1198  // multiset, multimap
1199  template <bool maybe_multi = IsMulti, class... Args>
1201  emplace_hint(const_iterator /*hint*/, Args&&... args)
1202  {
1203  // VFALCO TODO The hint could be used for multi, to let
1204  // the client order equal ranges
1205  return emplace<maybe_multi>(std::forward<Args>(args)...);
1206  }
1207 
1208  template <bool is_const, class Iterator, class Base>
1211 
1212  template <bool is_const, class Iterator, class Base>
1214  erase(
1217 
1218  template <class K>
1219  auto
1220  erase(K const& k) -> size_type;
1221 
1222  void
1223  swap(aged_unordered_container& other) noexcept;
1224 
1225  template <bool is_const, class Iterator, class Base>
1226  void
1228  {
1229  touch(pos, clock().now());
1230  }
1231 
1232  template <class K>
1233  auto
1234  touch(K const& k) -> size_type;
1235 
1236  //--------------------------------------------------------------------------
1237  //
1238  // Lookup
1239  //
1240  //--------------------------------------------------------------------------
1241 
1242  // VFALCO TODO Respect is_transparent (c++14)
1243  template <class K>
1244  size_type
1245  count(K const& k) const
1246  {
1247  return m_cont.count(
1248  k,
1251  }
1252 
1253  // VFALCO TODO Respect is_transparent (c++14)
1254  template <class K>
1255  iterator
1256  find(K const& k)
1257  {
1258  return iterator(m_cont.find(
1259  k,
1262  }
1263 
1264  // VFALCO TODO Respect is_transparent (c++14)
1265  template <class K>
1267  find(K const& k) const
1268  {
1269  return const_iterator(m_cont.find(
1270  k,
1273  }
1274 
1275  // VFALCO TODO Respect is_transparent (c++14)
1276  template <class K>
1278  equal_range(K const& k)
1279  {
1280  auto const r(m_cont.equal_range(
1281  k,
1284  return std::make_pair(iterator(r.first), iterator(r.second));
1285  }
1286 
1287  // VFALCO TODO Respect is_transparent (c++14)
1288  template <class K>
1290  equal_range(K const& k) const
1291  {
1292  auto const r(m_cont.equal_range(
1293  k,
1296  return std::make_pair(
1297  const_iterator(r.first), const_iterator(r.second));
1298  }
1299 
1300  //--------------------------------------------------------------------------
1301  //
1302  // Bucket interface
1303  //
1304  //--------------------------------------------------------------------------
1305 
1308  {
1309  return local_iterator(m_cont.begin(n));
1310  }
1311 
1313  begin(size_type n) const
1314  {
1315  return const_local_iterator(m_cont.begin(n));
1316  }
1317 
1320  {
1321  return const_local_iterator(m_cont.begin(n));
1322  }
1323 
1326  {
1327  return local_iterator(m_cont.end(n));
1328  }
1329 
1331  end(size_type n) const
1332  {
1333  return const_local_iterator(m_cont.end(n));
1334  }
1335 
1337  cend(size_type n) const
1338  {
1339  return const_local_iterator(m_cont.end(n));
1340  }
1341 
1342  size_type
1344  {
1345  return m_cont.bucket_count();
1346  }
1347 
1348  size_type
1350  {
1351  return m_buck.max_bucket_count();
1352  }
1353 
1354  size_type
1356  {
1357  return m_cont.bucket_size(n);
1358  }
1359 
1360  size_type
1361  bucket(Key const& k) const
1362  {
1363  assert(bucket_count() != 0);
1364  return m_cont.bucket(k, std::cref(m_config.hash_function()));
1365  }
1366 
1367  //--------------------------------------------------------------------------
1368  //
1369  // Hash policy
1370  //
1371  //--------------------------------------------------------------------------
1372 
1373  float
1374  load_factor() const
1375  {
1376  return size() / static_cast<float>(m_cont.bucket_count());
1377  }
1378 
1379  float
1381  {
1382  return m_buck.max_load_factor();
1383  }
1384 
1385  void
1387  {
1389  }
1390 
1391  void
1393  {
1396  }
1397 
1398  void
1400  {
1402  }
1403 
1404  //--------------------------------------------------------------------------
1405  //
1406  // Observers
1407  //
1408  //--------------------------------------------------------------------------
1409 
1410  hasher const&
1412  {
1413  return m_config.hash_function();
1414  }
1415 
1416  key_equal const&
1417  key_eq() const
1418  {
1419  return m_config.key_eq();
1420  }
1421 
1422  //--------------------------------------------------------------------------
1423  //
1424  // Comparison
1425  //
1426  //--------------------------------------------------------------------------
1427 
1428  // This differs from the standard in that the comparison
1429  // is only done on the key portion of the value type, ignoring
1430  // the mapped type.
1431  //
1432  template <
1433  bool OtherIsMap,
1434  class OtherKey,
1435  class OtherT,
1436  class OtherDuration,
1437  class OtherHash,
1438  class OtherAllocator,
1439  bool maybe_multi = IsMulti>
1442  false,
1443  OtherIsMap,
1444  OtherKey,
1445  OtherT,
1446  OtherDuration,
1447  OtherHash,
1448  KeyEqual,
1449  OtherAllocator> const& other) const;
1450 
1451  template <
1452  bool OtherIsMap,
1453  class OtherKey,
1454  class OtherT,
1455  class OtherDuration,
1456  class OtherHash,
1457  class OtherAllocator,
1458  bool maybe_multi = IsMulti>
1461  true,
1462  OtherIsMap,
1463  OtherKey,
1464  OtherT,
1465  OtherDuration,
1466  OtherHash,
1467  KeyEqual,
1468  OtherAllocator> const& other) const;
1469 
1470  template <
1471  bool OtherIsMulti,
1472  bool OtherIsMap,
1473  class OtherKey,
1474  class OtherT,
1475  class OtherDuration,
1476  class OtherHash,
1477  class OtherAllocator>
1478  bool
1480  OtherIsMulti,
1481  OtherIsMap,
1482  OtherKey,
1483  OtherT,
1484  OtherDuration,
1485  OtherHash,
1486  KeyEqual,
1487  OtherAllocator> const& other) const
1488  {
1489  return !(this->operator==(other));
1490  }
1491 
1492 private:
1493  bool
1494  would_exceed(size_type additional) const
1495  {
1496  return size() + additional > bucket_count() * max_load_factor();
1497  }
1498 
1499  void
1501  {
1502  if (would_exceed(additional))
1503  m_buck.resize(size() + additional, m_cont);
1504  assert(load_factor() <= max_load_factor());
1505  }
1506 
1507  // map, set
1508  template <bool maybe_multi = IsMulti>
1509  auto
1510  insert_unchecked(value_type const& value) ->
1512 
1513  // multimap, multiset
1514  template <bool maybe_multi = IsMulti>
1515  auto
1516  insert_unchecked(value_type const& value) ->
1518 
1519  template <class InputIt>
1520  void
1521  insert_unchecked(InputIt first, InputIt last)
1522  {
1523  for (; first != last; ++first)
1524  insert_unchecked(*first);
1525  }
1526 
1527  template <class InputIt>
1528  void
1529  insert(InputIt first, InputIt last, std::input_iterator_tag)
1530  {
1531  for (; first != last; ++first)
1532  insert(*first);
1533  }
1534 
1535  template <class InputIt>
1536  void
1537  insert(InputIt first, InputIt last, std::random_access_iterator_tag)
1538  {
1539  auto const n(std::distance(first, last));
1540  maybe_rehash(n);
1541  insert_unchecked(first, last);
1542  }
1543 
1544  template <bool is_const, class Iterator, class Base>
1545  void
1548  typename clock_type::time_point const& now)
1549  {
1550  auto& e(*pos.iterator());
1551  e.when = now;
1552  chronological.list.erase(chronological.list.iterator_to(e));
1553  chronological.list.push_back(e);
1554  }
1555 
1556  template <
1557  bool maybe_propagate = std::allocator_traits<
1558  Allocator>::propagate_on_container_swap::value>
1561  {
1562  std::swap(m_config.key_compare(), other.m_config.key_compare());
1563  std::swap(m_config.alloc(), other.m_config.alloc());
1564  std::swap(m_config.clock, other.m_config.clock);
1565  }
1566 
1567  template <
1568  bool maybe_propagate = std::allocator_traits<
1569  Allocator>::propagate_on_container_swap::value>
1572  {
1573  std::swap(m_config.key_compare(), other.m_config.key_compare());
1574  std::swap(m_config.clock, other.m_config.clock);
1575  }
1576 
1577 private:
1578  config_t m_config;
1579  Buckets m_buck;
1581 };
1582 
1583 //------------------------------------------------------------------------------
1584 
1585 template <
1586  bool IsMulti,
1587  bool IsMap,
1588  class Key,
1589  class T,
1590  class Clock,
1591  class Hash,
1592  class KeyEqual,
1593  class Allocator>
1595  IsMulti,
1596  IsMap,
1597  Key,
1598  T,
1599  Clock,
1600  Hash,
1601  KeyEqual,
1603  : m_config(clock)
1604  , m_cont(
1605  m_buck,
1606  std::cref(m_config.value_hash()),
1607  std::cref(m_config.key_value_equal()))
1608 {
1609 }
1610 
1611 template <
1612  bool IsMulti,
1613  bool IsMap,
1614  class Key,
1615  class T,
1616  class Clock,
1617  class Hash,
1618  class KeyEqual,
1619  class Allocator>
1621  IsMulti,
1622  IsMap,
1623  Key,
1624  T,
1625  Clock,
1626  Hash,
1627  KeyEqual,
1628  Allocator>::aged_unordered_container(clock_type& clock, Hash const& hash)
1629  : m_config(clock, hash)
1630  , m_cont(
1631  m_buck,
1632  std::cref(m_config.value_hash()),
1633  std::cref(m_config.key_value_equal()))
1634 {
1635 }
1636 
1637 template <
1638  bool IsMulti,
1639  bool IsMap,
1640  class Key,
1641  class T,
1642  class Clock,
1643  class Hash,
1644  class KeyEqual,
1645  class Allocator>
1647  IsMulti,
1648  IsMap,
1649  Key,
1650  T,
1651  Clock,
1652  Hash,
1653  KeyEqual,
1654  Allocator>::
1655  aged_unordered_container(clock_type& clock, KeyEqual const& key_eq)
1656  : m_config(clock, key_eq)
1657  , m_cont(
1658  m_buck,
1659  std::cref(m_config.value_hash()),
1660  std::cref(m_config.key_value_equal()))
1661 {
1662 }
1663 
1664 template <
1665  bool IsMulti,
1666  bool IsMap,
1667  class Key,
1668  class T,
1669  class Clock,
1670  class Hash,
1671  class KeyEqual,
1672  class Allocator>
1674  IsMulti,
1675  IsMap,
1676  Key,
1677  T,
1678  Clock,
1679  Hash,
1680  KeyEqual,
1681  Allocator>::
1682  aged_unordered_container(clock_type& clock, Allocator const& alloc)
1683  : m_config(clock, alloc)
1684  , m_buck(alloc)
1685  , m_cont(
1686  m_buck,
1687  std::cref(m_config.value_hash()),
1688  std::cref(m_config.key_value_equal()))
1689 {
1690 }
1691 
1692 template <
1693  bool IsMulti,
1694  bool IsMap,
1695  class Key,
1696  class T,
1697  class Clock,
1698  class Hash,
1699  class KeyEqual,
1700  class Allocator>
1702  IsMulti,
1703  IsMap,
1704  Key,
1705  T,
1706  Clock,
1707  Hash,
1708  KeyEqual,
1709  Allocator>::
1710  aged_unordered_container(
1711  clock_type& clock,
1712  Hash const& hash,
1713  KeyEqual const& key_eq)
1714  : m_config(clock, hash, key_eq)
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  Hash const& hash,
1743  Allocator const& alloc)
1744  : m_config(clock, hash, 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  KeyEqual const& key_eq,
1774  Allocator const& alloc)
1775  : m_config(clock, key_eq, alloc)
1776  , m_buck(alloc)
1777  , m_cont(
1778  m_buck,
1779  std::cref(m_config.value_hash()),
1780  std::cref(m_config.key_value_equal()))
1781 {
1782 }
1783 
1784 template <
1785  bool IsMulti,
1786  bool IsMap,
1787  class Key,
1788  class T,
1789  class Clock,
1790  class Hash,
1791  class KeyEqual,
1792  class Allocator>
1794  IsMulti,
1795  IsMap,
1796  Key,
1797  T,
1798  Clock,
1799  Hash,
1800  KeyEqual,
1801  Allocator>::
1802  aged_unordered_container(
1803  clock_type& clock,
1804  Hash const& hash,
1805  KeyEqual const& key_eq,
1806  Allocator const& alloc)
1807  : m_config(clock, hash, key_eq, alloc)
1808  , m_buck(alloc)
1809  , m_cont(
1810  m_buck,
1811  std::cref(m_config.value_hash()),
1812  std::cref(m_config.key_value_equal()))
1813 {
1814 }
1815 
1816 template <
1817  bool IsMulti,
1818  bool IsMap,
1819  class Key,
1820  class T,
1821  class Clock,
1822  class Hash,
1823  class KeyEqual,
1824  class Allocator>
1825 template <class InputIt>
1827  IsMulti,
1828  IsMap,
1829  Key,
1830  T,
1831  Clock,
1832  Hash,
1833  KeyEqual,
1834  Allocator>::
1835  aged_unordered_container(InputIt first, InputIt last, clock_type& clock)
1836  : m_config(clock)
1837  , m_cont(
1838  m_buck,
1839  std::cref(m_config.value_hash()),
1840  std::cref(m_config.key_value_equal()))
1841 {
1842  insert(first, last);
1843 }
1844 
1845 template <
1846  bool IsMulti,
1847  bool IsMap,
1848  class Key,
1849  class T,
1850  class Clock,
1851  class Hash,
1852  class KeyEqual,
1853  class Allocator>
1854 template <class InputIt>
1856  IsMulti,
1857  IsMap,
1858  Key,
1859  T,
1860  Clock,
1861  Hash,
1862  KeyEqual,
1863  Allocator>::
1864  aged_unordered_container(
1865  InputIt first,
1866  InputIt last,
1867  clock_type& clock,
1868  Hash const& hash)
1869  : m_config(clock, hash)
1870  , m_cont(
1871  m_buck,
1872  std::cref(m_config.value_hash()),
1873  std::cref(m_config.key_value_equal()))
1874 {
1875  insert(first, last);
1876 }
1877 
1878 template <
1879  bool IsMulti,
1880  bool IsMap,
1881  class Key,
1882  class T,
1883  class Clock,
1884  class Hash,
1885  class KeyEqual,
1886  class Allocator>
1887 template <class InputIt>
1889  IsMulti,
1890  IsMap,
1891  Key,
1892  T,
1893  Clock,
1894  Hash,
1895  KeyEqual,
1896  Allocator>::
1897  aged_unordered_container(
1898  InputIt first,
1899  InputIt last,
1900  clock_type& clock,
1901  KeyEqual const& key_eq)
1902  : m_config(clock, key_eq)
1903  , m_cont(
1904  m_buck,
1905  std::cref(m_config.value_hash()),
1906  std::cref(m_config.key_value_equal()))
1907 {
1908  insert(first, last);
1909 }
1910 
1911 template <
1912  bool IsMulti,
1913  bool IsMap,
1914  class Key,
1915  class T,
1916  class Clock,
1917  class Hash,
1918  class KeyEqual,
1919  class Allocator>
1920 template <class InputIt>
1922  IsMulti,
1923  IsMap,
1924  Key,
1925  T,
1926  Clock,
1927  Hash,
1928  KeyEqual,
1929  Allocator>::
1930  aged_unordered_container(
1931  InputIt first,
1932  InputIt last,
1933  clock_type& clock,
1934  Allocator const& alloc)
1935  : m_config(clock, alloc)
1936  , m_buck(alloc)
1937  , m_cont(
1938  m_buck,
1939  std::cref(m_config.value_hash()),
1940  std::cref(m_config.key_value_equal()))
1941 {
1942  insert(first, last);
1943 }
1944 
1945 template <
1946  bool IsMulti,
1947  bool IsMap,
1948  class Key,
1949  class T,
1950  class Clock,
1951  class Hash,
1952  class KeyEqual,
1953  class Allocator>
1954 template <class InputIt>
1956  IsMulti,
1957  IsMap,
1958  Key,
1959  T,
1960  Clock,
1961  Hash,
1962  KeyEqual,
1963  Allocator>::
1964  aged_unordered_container(
1965  InputIt first,
1966  InputIt last,
1967  clock_type& clock,
1968  Hash const& hash,
1969  KeyEqual const& key_eq)
1970  : m_config(clock, hash, key_eq)
1971  , m_cont(
1972  m_buck,
1973  std::cref(m_config.value_hash()),
1974  std::cref(m_config.key_value_equal()))
1975 {
1976  insert(first, last);
1977 }
1978 
1979 template <
1980  bool IsMulti,
1981  bool IsMap,
1982  class Key,
1983  class T,
1984  class Clock,
1985  class Hash,
1986  class KeyEqual,
1987  class Allocator>
1988 template <class InputIt>
1990  IsMulti,
1991  IsMap,
1992  Key,
1993  T,
1994  Clock,
1995  Hash,
1996  KeyEqual,
1997  Allocator>::
1998  aged_unordered_container(
1999  InputIt first,
2000  InputIt last,
2001  clock_type& clock,
2002  Hash const& hash,
2003  Allocator const& alloc)
2004  : m_config(clock, hash, alloc)
2005  , m_buck(alloc)
2006  , m_cont(
2007  m_buck,
2008  std::cref(m_config.value_hash()),
2009  std::cref(m_config.key_value_equal()))
2010 {
2011  insert(first, last);
2012 }
2013 
2014 template <
2015  bool IsMulti,
2016  bool IsMap,
2017  class Key,
2018  class T,
2019  class Clock,
2020  class Hash,
2021  class KeyEqual,
2022  class Allocator>
2023 template <class InputIt>
2025  IsMulti,
2026  IsMap,
2027  Key,
2028  T,
2029  Clock,
2030  Hash,
2031  KeyEqual,
2032  Allocator>::
2033  aged_unordered_container(
2034  InputIt first,
2035  InputIt last,
2036  clock_type& clock,
2037  KeyEqual const& key_eq,
2038  Allocator const& alloc)
2039  : m_config(clock, key_eq, alloc)
2040  , m_buck(alloc)
2041  , m_cont(
2042  m_buck,
2043  std::cref(m_config.value_hash()),
2044  std::cref(m_config.key_value_equal()))
2045 {
2046  insert(first, last);
2047 }
2048 
2049 template <
2050  bool IsMulti,
2051  bool IsMap,
2052  class Key,
2053  class T,
2054  class Clock,
2055  class Hash,
2056  class KeyEqual,
2057  class Allocator>
2058 template <class InputIt>
2060  IsMulti,
2061  IsMap,
2062  Key,
2063  T,
2064  Clock,
2065  Hash,
2066  KeyEqual,
2067  Allocator>::
2068  aged_unordered_container(
2069  InputIt first,
2070  InputIt last,
2071  clock_type& clock,
2072  Hash const& hash,
2073  KeyEqual const& key_eq,
2074  Allocator const& alloc)
2075  : m_config(clock, hash, key_eq, alloc)
2076  , m_buck(alloc)
2077  , m_cont(
2078  m_buck,
2079  std::cref(m_config.value_hash()),
2080  std::cref(m_config.key_value_equal()))
2081 {
2082  insert(first, last);
2083 }
2084 
2085 template <
2086  bool IsMulti,
2087  bool IsMap,
2088  class Key,
2089  class T,
2090  class Clock,
2091  class Hash,
2092  class KeyEqual,
2093  class Allocator>
2095  IsMulti,
2096  IsMap,
2097  Key,
2098  T,
2099  Clock,
2100  Hash,
2101  KeyEqual,
2103  : m_config(other.m_config)
2104  , m_buck(m_config.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,
2130  Allocator>::
2131  aged_unordered_container(
2132  aged_unordered_container const& other,
2133  Allocator const& alloc)
2134  : m_config(other.m_config, alloc)
2135  , m_buck(alloc)
2136  , m_cont(
2137  m_buck,
2138  std::cref(m_config.value_hash()),
2139  std::cref(m_config.key_value_equal()))
2140 {
2141  insert(other.cbegin(), other.cend());
2142 }
2143 
2144 template <
2145  bool IsMulti,
2146  bool IsMap,
2147  class Key,
2148  class T,
2149  class Clock,
2150  class Hash,
2151  class KeyEqual,
2152  class Allocator>
2154  IsMulti,
2155  IsMap,
2156  Key,
2157  T,
2158  Clock,
2159  Hash,
2160  KeyEqual,
2162  : m_config(std::move(other.m_config))
2163  , m_buck(std::move(other.m_buck))
2164  , m_cont(std::move(other.m_cont))
2165 {
2166  chronological.list = std::move(other.chronological.list);
2167 }
2168 
2169 template <
2170  bool IsMulti,
2171  bool IsMap,
2172  class Key,
2173  class T,
2174  class Clock,
2175  class Hash,
2176  class KeyEqual,
2177  class Allocator>
2179  IsMulti,
2180  IsMap,
2181  Key,
2182  T,
2183  Clock,
2184  Hash,
2185  KeyEqual,
2186  Allocator>::
2187  aged_unordered_container(
2188  aged_unordered_container&& other,
2189  Allocator const& alloc)
2190  : m_config(std::move(other.m_config), alloc)
2191  , m_buck(alloc)
2192  , m_cont(
2193  m_buck,
2194  std::cref(m_config.value_hash()),
2195  std::cref(m_config.key_value_equal()))
2196 {
2197  insert(other.cbegin(), other.cend());
2198  other.clear();
2199 }
2200 
2201 template <
2202  bool IsMulti,
2203  bool IsMap,
2204  class Key,
2205  class T,
2206  class Clock,
2207  class Hash,
2208  class KeyEqual,
2209  class Allocator>
2211  IsMulti,
2212  IsMap,
2213  Key,
2214  T,
2215  Clock,
2216  Hash,
2217  KeyEqual,
2218  Allocator>::
2219  aged_unordered_container(
2221  clock_type& clock)
2222  : m_config(clock)
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  Hash const& hash)
2253  : m_config(clock, hash)
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  KeyEqual const& key_eq)
2284  : m_config(clock, key_eq)
2285  , m_cont(
2286  m_buck,
2287  std::cref(m_config.value_hash()),
2288  std::cref(m_config.key_value_equal()))
2289 {
2290  insert(init.begin(), init.end());
2291 }
2292 
2293 template <
2294  bool IsMulti,
2295  bool IsMap,
2296  class Key,
2297  class T,
2298  class Clock,
2299  class Hash,
2300  class KeyEqual,
2301  class Allocator>
2303  IsMulti,
2304  IsMap,
2305  Key,
2306  T,
2307  Clock,
2308  Hash,
2309  KeyEqual,
2310  Allocator>::
2311  aged_unordered_container(
2313  clock_type& clock,
2314  Allocator const& alloc)
2315  : m_config(clock, alloc)
2316  , m_buck(alloc)
2317  , m_cont(
2318  m_buck,
2319  std::cref(m_config.value_hash()),
2320  std::cref(m_config.key_value_equal()))
2321 {
2322  insert(init.begin(), init.end());
2323 }
2324 
2325 template <
2326  bool IsMulti,
2327  bool IsMap,
2328  class Key,
2329  class T,
2330  class Clock,
2331  class Hash,
2332  class KeyEqual,
2333  class Allocator>
2335  IsMulti,
2336  IsMap,
2337  Key,
2338  T,
2339  Clock,
2340  Hash,
2341  KeyEqual,
2342  Allocator>::
2343  aged_unordered_container(
2345  clock_type& clock,
2346  Hash const& hash,
2347  KeyEqual const& key_eq)
2348  : m_config(clock, hash, key_eq)
2349  , m_cont(
2350  m_buck,
2351  std::cref(m_config.value_hash()),
2352  std::cref(m_config.key_value_equal()))
2353 {
2354  insert(init.begin(), init.end());
2355 }
2356 
2357 template <
2358  bool IsMulti,
2359  bool IsMap,
2360  class Key,
2361  class T,
2362  class Clock,
2363  class Hash,
2364  class KeyEqual,
2365  class Allocator>
2367  IsMulti,
2368  IsMap,
2369  Key,
2370  T,
2371  Clock,
2372  Hash,
2373  KeyEqual,
2374  Allocator>::
2375  aged_unordered_container(
2377  clock_type& clock,
2378  Hash const& hash,
2379  Allocator const& alloc)
2380  : m_config(clock, hash, alloc)
2381  , m_buck(alloc)
2382  , m_cont(
2383  m_buck,
2384  std::cref(m_config.value_hash()),
2385  std::cref(m_config.key_value_equal()))
2386 {
2387  insert(init.begin(), init.end());
2388 }
2389 
2390 template <
2391  bool IsMulti,
2392  bool IsMap,
2393  class Key,
2394  class T,
2395  class Clock,
2396  class Hash,
2397  class KeyEqual,
2398  class Allocator>
2400  IsMulti,
2401  IsMap,
2402  Key,
2403  T,
2404  Clock,
2405  Hash,
2406  KeyEqual,
2407  Allocator>::
2408  aged_unordered_container(
2410  clock_type& clock,
2411  KeyEqual const& key_eq,
2412  Allocator const& alloc)
2413  : m_config(clock, key_eq, alloc)
2414  , m_buck(alloc)
2415  , m_cont(
2416  m_buck,
2417  std::cref(m_config.value_hash()),
2418  std::cref(m_config.key_value_equal()))
2419 {
2420  insert(init.begin(), init.end());
2421 }
2422 
2423 template <
2424  bool IsMulti,
2425  bool IsMap,
2426  class Key,
2427  class T,
2428  class Clock,
2429  class Hash,
2430  class KeyEqual,
2431  class Allocator>
2433  IsMulti,
2434  IsMap,
2435  Key,
2436  T,
2437  Clock,
2438  Hash,
2439  KeyEqual,
2440  Allocator>::
2441  aged_unordered_container(
2443  clock_type& clock,
2444  Hash const& hash,
2445  KeyEqual const& key_eq,
2446  Allocator const& alloc)
2447  : m_config(clock, hash, key_eq, alloc)
2448  , m_buck(alloc)
2449  , m_cont(
2450  m_buck,
2451  std::cref(m_config.value_hash()),
2452  std::cref(m_config.key_value_equal()))
2453 {
2454  insert(init.begin(), init.end());
2455 }
2456 
2457 template <
2458  bool IsMulti,
2459  bool IsMap,
2460  class Key,
2461  class T,
2462  class Clock,
2463  class Hash,
2464  class KeyEqual,
2465  class Allocator>
2467  IsMulti,
2468  IsMap,
2469  Key,
2470  T,
2471  Clock,
2472  Hash,
2473  KeyEqual,
2474  Allocator>::~aged_unordered_container()
2475 {
2476  clear();
2477 }
2478 
2479 template <
2480  bool IsMulti,
2481  bool IsMap,
2482  class Key,
2483  class T,
2484  class Clock,
2485  class Hash,
2486  class KeyEqual,
2487  class Allocator>
2488 auto
2490  IsMulti,
2491  IsMap,
2492  Key,
2493  T,
2494  Clock,
2495  Hash,
2496  KeyEqual,
2497  Allocator>::operator=(aged_unordered_container const& other)
2499 {
2500  if (this != &other)
2501  {
2502  size_type const n(other.size());
2503  clear();
2504  m_config = other.m_config;
2505  m_buck = Buckets(m_config.alloc());
2506  maybe_rehash(n);
2507  insert_unchecked(other.begin(), other.end());
2508  }
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=(aged_unordered_container&& other)
2532 {
2533  size_type const n(other.size());
2534  clear();
2535  m_config = std::move(other.m_config);
2536  m_buck = Buckets(m_config.alloc());
2537  maybe_rehash(n);
2538  insert_unchecked(other.begin(), other.end());
2539  other.clear();
2540  return *this;
2541 }
2542 
2543 template <
2544  bool IsMulti,
2545  bool IsMap,
2546  class Key,
2547  class T,
2548  class Clock,
2549  class Hash,
2550  class KeyEqual,
2551  class Allocator>
2552 auto
2554  IsMulti,
2555  IsMap,
2556  Key,
2557  T,
2558  Clock,
2559  Hash,
2560  KeyEqual,
2563 {
2564  clear();
2565  insert(init);
2566  return *this;
2567 }
2568 
2569 //------------------------------------------------------------------------------
2570 
2571 template <
2572  bool IsMulti,
2573  bool IsMap,
2574  class Key,
2575  class T,
2576  class Clock,
2577  class Hash,
2578  class KeyEqual,
2579  class Allocator>
2580 template <class K, bool maybe_multi, bool maybe_map, class>
2583  IsMulti,
2584  IsMap,
2585  Key,
2586  T,
2587  Clock,
2588  Hash,
2589  KeyEqual,
2590  Allocator>::at(K const& k)
2591 {
2592  auto const iter(m_cont.find(
2593  k,
2594  std::cref(m_config.hash_function()),
2595  std::cref(m_config.key_value_equal())));
2596  if (iter == m_cont.end())
2597  throw std::out_of_range("key not found");
2598  return iter->value.second;
2599 }
2600 
2601 template <
2602  bool IsMulti,
2603  bool IsMap,
2604  class Key,
2605  class T,
2606  class Clock,
2607  class Hash,
2608  class KeyEqual,
2609  class Allocator>
2610 template <class K, bool maybe_multi, bool maybe_map, class>
2613  IsMulti,
2614  IsMap,
2615  Key,
2616  T,
2617  Clock,
2618  Hash,
2619  KeyEqual,
2620  Allocator>::at(K const& k) const
2621 {
2622  auto const iter(m_cont.find(
2623  k,
2624  std::cref(m_config.hash_function()),
2625  std::cref(m_config.key_value_equal())));
2626  if (iter == m_cont.end())
2627  throw std::out_of_range("key not found");
2628  return iter->value.second;
2629 }
2630 
2631 template <
2632  bool IsMulti,
2633  bool IsMap,
2634  class Key,
2635  class T,
2636  class Clock,
2637  class Hash,
2638  class KeyEqual,
2639  class Allocator>
2640 template <bool maybe_multi, bool maybe_map, class>
2643  IsMulti,
2644  IsMap,
2645  Key,
2646  T,
2647  Clock,
2648  Hash,
2649  KeyEqual,
2650  Allocator>::operator[](Key const& key)
2651 {
2652  maybe_rehash(1);
2653  typename cont_type::insert_commit_data d;
2654  auto const result(m_cont.insert_check(
2655  key,
2656  std::cref(m_config.hash_function()),
2657  std::cref(m_config.key_value_equal()),
2658  d));
2659  if (result.second)
2660  {
2661  element* const p(new_element(
2662  std::piecewise_construct,
2663  std::forward_as_tuple(key),
2665  m_cont.insert_commit(*p, d);
2666  chronological.list.push_back(*p);
2667  return p->value.second;
2668  }
2669  return result.first->value.second;
2670 }
2671 
2672 template <
2673  bool IsMulti,
2674  bool IsMap,
2675  class Key,
2676  class T,
2677  class Clock,
2678  class Hash,
2679  class KeyEqual,
2680  class Allocator>
2681 template <bool maybe_multi, bool maybe_map, class>
2684  IsMulti,
2685  IsMap,
2686  Key,
2687  T,
2688  Clock,
2689  Hash,
2690  KeyEqual,
2691  Allocator>::operator[](Key&& key)
2692 {
2693  maybe_rehash(1);
2694  typename cont_type::insert_commit_data d;
2695  auto const result(m_cont.insert_check(
2696  key,
2697  std::cref(m_config.hash_function()),
2698  std::cref(m_config.key_value_equal()),
2699  d));
2700  if (result.second)
2701  {
2702  element* const p(new_element(
2703  std::piecewise_construct,
2704  std::forward_as_tuple(std::move(key)),
2706  m_cont.insert_commit(*p, d);
2707  chronological.list.push_back(*p);
2708  return p->value.second;
2709  }
2710  return result.first->value.second;
2711 }
2712 
2713 //------------------------------------------------------------------------------
2714 
2715 template <
2716  bool IsMulti,
2717  bool IsMap,
2718  class Key,
2719  class T,
2720  class Clock,
2721  class Hash,
2722  class KeyEqual,
2723  class Allocator>
2724 void
2726  IsMulti,
2727  IsMap,
2728  Key,
2729  T,
2730  Clock,
2731  Hash,
2732  KeyEqual,
2733  Allocator>::clear()
2734 {
2735  for (auto iter(chronological.list.begin());
2736  iter != chronological.list.end();)
2737  unlink_and_delete_element(&*iter++);
2738  chronological.list.clear();
2739  m_cont.clear();
2740  m_buck.clear();
2741 }
2742 
2743 // map, set
2744 template <
2745  bool IsMulti,
2746  bool IsMap,
2747  class Key,
2748  class T,
2749  class Clock,
2750  class Hash,
2751  class KeyEqual,
2752  class Allocator>
2753 template <bool maybe_multi>
2754 auto
2756  IsMulti,
2757  IsMap,
2758  Key,
2759  T,
2760  Clock,
2761  Hash,
2762  KeyEqual,
2763  Allocator>::insert(value_type const& value) ->
2765 {
2766  maybe_rehash(1);
2767  typename cont_type::insert_commit_data d;
2768  auto const result(m_cont.insert_check(
2769  extract(value),
2770  std::cref(m_config.hash_function()),
2771  std::cref(m_config.key_value_equal()),
2772  d));
2773  if (result.second)
2774  {
2775  element* const p(new_element(value));
2776  auto const iter(m_cont.insert_commit(*p, d));
2777  chronological.list.push_back(*p);
2778  return std::make_pair(iterator(iter), true);
2779  }
2780  return std::make_pair(iterator(result.first), false);
2781 }
2782 
2783 // multimap, multiset
2784 template <
2785  bool IsMulti,
2786  bool IsMap,
2787  class Key,
2788  class T,
2789  class Clock,
2790  class Hash,
2791  class KeyEqual,
2792  class Allocator>
2793 template <bool maybe_multi>
2794 auto
2796  IsMulti,
2797  IsMap,
2798  Key,
2799  T,
2800  Clock,
2801  Hash,
2802  KeyEqual,
2803  Allocator>::insert(value_type const& value) ->
2805 {
2806  maybe_rehash(1);
2807  element* const p(new_element(value));
2808  chronological.list.push_back(*p);
2809  auto const iter(m_cont.insert(*p));
2810  return iterator(iter);
2811 }
2812 
2813 // map, set
2814 template <
2815  bool IsMulti,
2816  bool IsMap,
2817  class Key,
2818  class T,
2819  class Clock,
2820  class Hash,
2821  class KeyEqual,
2822  class Allocator>
2823 template <bool maybe_multi, bool maybe_map>
2824 auto
2825 aged_unordered_container<
2826  IsMulti,
2827  IsMap,
2828  Key,
2829  T,
2830  Clock,
2831  Hash,
2832  KeyEqual,
2833  Allocator>::insert(value_type&& value) -> typename std::
2834  enable_if<!maybe_multi && !maybe_map, std::pair<iterator, bool>>::type
2835 {
2836  maybe_rehash(1);
2837  typename cont_type::insert_commit_data d;
2838  auto const result(m_cont.insert_check(
2839  extract(value),
2840  std::cref(m_config.hash_function()),
2841  std::cref(m_config.key_value_equal()),
2842  d));
2843  if (result.second)
2844  {
2845  element* const p(new_element(std::move(value)));
2846  auto const iter(m_cont.insert_commit(*p, d));
2847  chronological.list.push_back(*p);
2848  return std::make_pair(iterator(iter), true);
2849  }
2850  return std::make_pair(iterator(result.first), false);
2851 }
2852 
2853 // multimap, multiset
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, bool maybe_map>
2864 auto
2866  IsMulti,
2867  IsMap,
2868  Key,
2869  T,
2870  Clock,
2871  Hash,
2872  KeyEqual,
2873  Allocator>::insert(value_type&& value) ->
2875 {
2876  maybe_rehash(1);
2877  element* const p(new_element(std::move(value)));
2878  chronological.list.push_back(*p);
2879  auto const iter(m_cont.insert(*p));
2880  return iterator(iter);
2881 }
2882 
2883 #if 1 // Use insert() instead of insert_check() insert_commit()
2884 // set, map
2885 template <
2886  bool IsMulti,
2887  bool IsMap,
2888  class Key,
2889  class T,
2890  class Clock,
2891  class Hash,
2892  class KeyEqual,
2893  class Allocator>
2894 template <bool maybe_multi, class... Args>
2895 auto
2896 aged_unordered_container<
2897  IsMulti,
2898  IsMap,
2899  Key,
2900  T,
2901  Clock,
2902  Hash,
2903  KeyEqual,
2904  Allocator>::emplace(Args&&... args) ->
2906 {
2907  maybe_rehash(1);
2908  // VFALCO NOTE Its unfortunate that we need to
2909  // construct element here
2910  element* const p(new_element(std::forward<Args>(args)...));
2911  auto const result(m_cont.insert(*p));
2912  if (result.second)
2913  {
2914  chronological.list.push_back(*p);
2915  return std::make_pair(iterator(result.first), true);
2916  }
2917  delete_element(p);
2918  return std::make_pair(iterator(result.first), false);
2919 }
2920 #else // As original, use insert_check() / insert_commit () pair.
2921 // set, map
2922 template <
2923  bool IsMulti,
2924  bool IsMap,
2925  class Key,
2926  class T,
2927  class Clock,
2928  class Hash,
2929  class KeyEqual,
2930  class Allocator>
2931 template <bool maybe_multi, class... Args>
2932 auto
2934  IsMulti,
2935  IsMap,
2936  Key,
2937  T,
2938  Clock,
2939  Hash,
2940  KeyEqual,
2941  Allocator>::emplace(Args&&... args) ->
2943 {
2944  maybe_rehash(1);
2945  // VFALCO NOTE Its unfortunate that we need to
2946  // construct element here
2947  element* const p(new_element(std::forward<Args>(args)...));
2948  typename cont_type::insert_commit_data d;
2949  auto const result(m_cont.insert_check(
2950  extract(p->value),
2951  std::cref(m_config.hash_function()),
2952  std::cref(m_config.key_value_equal()),
2953  d));
2954  if (result.second)
2955  {
2956  auto const iter(m_cont.insert_commit(*p, d));
2957  chronological.list.push_back(*p);
2958  return std::make_pair(iterator(iter), true);
2959  }
2960  delete_element(p);
2961  return std::make_pair(iterator(result.first), false);
2962 }
2963 #endif // 0
2964 
2965 // multiset, multimap
2966 template <
2967  bool IsMulti,
2968  bool IsMap,
2969  class Key,
2970  class T,
2971  class Clock,
2972  class Hash,
2973  class KeyEqual,
2974  class Allocator>
2975 template <bool maybe_multi, class... Args>
2976 auto
2977 aged_unordered_container<
2978  IsMulti,
2979  IsMap,
2980  Key,
2981  T,
2982  Clock,
2983  Hash,
2984  KeyEqual,
2985  Allocator>::emplace(Args&&... args) ->
2987 {
2988  maybe_rehash(1);
2989  element* const p(new_element(std::forward<Args>(args)...));
2990  chronological.list.push_back(*p);
2991  auto const iter(m_cont.insert(*p));
2992  return iterator(iter);
2993 }
2994 
2995 // set, map
2996 template <
2997  bool IsMulti,
2998  bool IsMap,
2999  class Key,
3000  class T,
3001  class Clock,
3002  class Hash,
3003  class KeyEqual,
3004  class Allocator>
3005 template <bool maybe_multi, class... Args>
3006 auto
3007 aged_unordered_container<
3008  IsMulti,
3009  IsMap,
3010  Key,
3011  T,
3012  Clock,
3013  Hash,
3014  KeyEqual,
3015  Allocator>::emplace_hint(const_iterator /*hint*/, Args&&... args) ->
3017 {
3018  maybe_rehash(1);
3019  // VFALCO NOTE Its unfortunate that we need to
3020  // construct element here
3021  element* const p(new_element(std::forward<Args>(args)...));
3022  typename cont_type::insert_commit_data d;
3023  auto const result(m_cont.insert_check(
3024  extract(p->value),
3025  std::cref(m_config.hash_function()),
3026  std::cref(m_config.key_value_equal()),
3027  d));
3028  if (result.second)
3029  {
3030  auto const iter(m_cont.insert_commit(*p, d));
3031  chronological.list.push_back(*p);
3032  return std::make_pair(iterator(iter), true);
3033  }
3034  delete_element(p);
3035  return std::make_pair(iterator(result.first), false);
3036 }
3037 
3038 template <
3039  bool IsMulti,
3040  bool IsMap,
3041  class Key,
3042  class T,
3043  class Clock,
3044  class Hash,
3045  class KeyEqual,
3046  class Allocator>
3047 template <bool is_const, class Iterator, class Base>
3050  IsMulti,
3051  IsMap,
3052  Key,
3053  T,
3054  Clock,
3055  Hash,
3056  KeyEqual,
3057  Allocator>::
3059 {
3060  unlink_and_delete_element(&*((pos++).iterator()));
3062  pos.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 <bool is_const, class Iterator, class Base>
3077  IsMulti,
3078  IsMap,
3079  Key,
3080  T,
3081  Clock,
3082  Hash,
3083  KeyEqual,
3084  Allocator>::
3085  erase(
3088 {
3089  for (; first != last;)
3090  unlink_and_delete_element(&*((first++).iterator()));
3091 
3093  first.iterator());
3094 }
3095 
3096 template <
3097  bool IsMulti,
3098  bool IsMap,
3099  class Key,
3100  class T,
3101  class Clock,
3102  class Hash,
3103  class KeyEqual,
3104  class Allocator>
3105 template <class K>
3106 auto
3108  IsMulti,
3109  IsMap,
3110  Key,
3111  T,
3112  Clock,
3113  Hash,
3114  KeyEqual,
3115  Allocator>::erase(K const& k) -> size_type
3116 {
3117  auto iter(m_cont.find(
3118  k,
3119  std::cref(m_config.hash_function()),
3120  std::cref(m_config.key_value_equal())));
3121  if (iter == m_cont.end())
3122  return 0;
3123  size_type n(0);
3124  for (;;)
3125  {
3126  auto p(&*iter++);
3127  bool const done(m_config(*p, extract(iter->value)));
3128  unlink_and_delete_element(p);
3129  ++n;
3130  if (done)
3131  break;
3132  }
3133  return n;
3134 }
3135 
3136 template <
3137  bool IsMulti,
3138  bool IsMap,
3139  class Key,
3140  class T,
3141  class Clock,
3142  class Hash,
3143  class KeyEqual,
3144  class Allocator>
3145 void
3147  IsMulti,
3148  IsMap,
3149  Key,
3150  T,
3151  Clock,
3152  Hash,
3153  KeyEqual,
3154  Allocator>::swap(aged_unordered_container& other) noexcept
3155 {
3156  swap_data(other);
3157  std::swap(chronological, other.chronological);
3158  std::swap(m_cont, other.m_cont);
3159 }
3160 
3161 template <
3162  bool IsMulti,
3163  bool IsMap,
3164  class Key,
3165  class T,
3166  class Clock,
3167  class Hash,
3168  class KeyEqual,
3169  class Allocator>
3170 template <class K>
3171 auto
3173  IsMulti,
3174  IsMap,
3175  Key,
3176  T,
3177  Clock,
3178  Hash,
3179  KeyEqual,
3180  Allocator>::touch(K const& k) -> size_type
3181 {
3182  auto const now(clock().now());
3183  size_type n(0);
3184  auto const range(equal_range(k));
3185  for (auto iter : range)
3186  {
3187  touch(iter, now);
3188  ++n;
3189  }
3190  return n;
3191 }
3192 
3193 template <
3194  bool IsMulti,
3195  bool IsMap,
3196  class Key,
3197  class T,
3198  class Clock,
3199  class Hash,
3200  class KeyEqual,
3201  class Allocator>
3202 template <
3203  bool OtherIsMap,
3204  class OtherKey,
3205  class OtherT,
3206  class OtherDuration,
3207  class OtherHash,
3208  class OtherAllocator,
3209  bool maybe_multi>
3212  IsMulti,
3213  IsMap,
3214  Key,
3215  T,
3216  Clock,
3217  Hash,
3218  KeyEqual,
3219  Allocator>::
3221  false,
3222  OtherIsMap,
3223  OtherKey,
3224  OtherT,
3225  OtherDuration,
3226  OtherHash,
3227  KeyEqual,
3228  OtherAllocator> const& other) const
3229 {
3230  if (size() != other.size())
3231  return false;
3232  for (auto iter(cbegin()), last(cend()), olast(other.cend()); iter != last;
3233  ++iter)
3234  {
3235  auto oiter(other.find(extract(*iter)));
3236  if (oiter == olast)
3237  return false;
3238  }
3239  return true;
3240 }
3241 
3242 template <
3243  bool IsMulti,
3244  bool IsMap,
3245  class Key,
3246  class T,
3247  class Clock,
3248  class Hash,
3249  class KeyEqual,
3250  class Allocator>
3251 template <
3252  bool OtherIsMap,
3253  class OtherKey,
3254  class OtherT,
3255  class OtherDuration,
3256  class OtherHash,
3257  class OtherAllocator,
3258  bool maybe_multi>
3261  IsMulti,
3262  IsMap,
3263  Key,
3264  T,
3265  Clock,
3266  Hash,
3267  KeyEqual,
3268  Allocator>::
3270  true,
3271  OtherIsMap,
3272  OtherKey,
3273  OtherT,
3274  OtherDuration,
3275  OtherHash,
3276  KeyEqual,
3277  OtherAllocator> const& other) const
3278 {
3279  if (size() != other.size())
3280  return false;
3282  for (auto iter(cbegin()), last(cend()); iter != last;)
3283  {
3284  auto const& k(extract(*iter));
3285  auto const eq(equal_range(k));
3286  auto const oeq(other.equal_range(k));
3287 #if BEAST_NO_CXX14_IS_PERMUTATION
3288  if (std::distance(eq.first, eq.second) !=
3289  std::distance(oeq.first, oeq.second) ||
3290  !std::is_permutation(eq.first, eq.second, oeq.first))
3291  return false;
3292 #else
3293  if (!std::is_permutation(eq.first, eq.second, oeq.first, oeq.second))
3294  return false;
3295 #endif
3296  iter = eq.second;
3297  }
3298  return true;
3299 }
3300 
3301 //------------------------------------------------------------------------------
3302 
3303 // map, set
3304 template <
3305  bool IsMulti,
3306  bool IsMap,
3307  class Key,
3308  class T,
3309  class Clock,
3310  class Hash,
3311  class KeyEqual,
3312  class Allocator>
3313 template <bool maybe_multi>
3314 auto
3316  IsMulti,
3317  IsMap,
3318  Key,
3319  T,
3320  Clock,
3321  Hash,
3322  KeyEqual,
3323  Allocator>::insert_unchecked(value_type const& value) ->
3325 {
3326  typename cont_type::insert_commit_data d;
3327  auto const result(m_cont.insert_check(
3328  extract(value),
3329  std::cref(m_config.hash_function()),
3330  std::cref(m_config.key_value_equal()),
3331  d));
3332  if (result.second)
3333  {
3334  element* const p(new_element(value));
3335  auto const iter(m_cont.insert_commit(*p, d));
3336  chronological.list.push_back(*p);
3337  return std::make_pair(iterator(iter), true);
3338  }
3339  return std::make_pair(iterator(result.first), false);
3340 }
3341 
3342 // multimap, multiset
3343 template <
3344  bool IsMulti,
3345  bool IsMap,
3346  class Key,
3347  class T,
3348  class Clock,
3349  class Hash,
3350  class KeyEqual,
3351  class Allocator>
3352 template <bool maybe_multi>
3353 auto
3355  IsMulti,
3356  IsMap,
3357  Key,
3358  T,
3359  Clock,
3360  Hash,
3361  KeyEqual,
3362  Allocator>::insert_unchecked(value_type const& value) ->
3364 {
3365  element* const p(new_element(value));
3366  chronological.list.push_back(*p);
3367  auto const iter(m_cont.insert(*p));
3368  return iterator(iter);
3369 }
3370 
3371 //------------------------------------------------------------------------------
3372 
3373 } // namespace detail
3374 
3375 //------------------------------------------------------------------------------
3376 
3377 template <
3378  bool IsMulti,
3379  bool IsMap,
3380  class Key,
3381  class T,
3382  class Clock,
3383  class Hash,
3384  class KeyEqual,
3385  class Allocator>
3387  IsMulti,
3388  IsMap,
3389  Key,
3390  T,
3391  Clock,
3392  Hash,
3393  KeyEqual,
3394  Allocator>> : std::true_type
3395 {
3396  explicit is_aged_container() = default;
3397 };
3398 
3399 // Free functions
3400 
3401 template <
3402  bool IsMulti,
3403  bool IsMap,
3404  class Key,
3405  class T,
3406  class Clock,
3407  class Hash,
3408  class KeyEqual,
3409  class Allocator>
3410 void
3411 swap(
3413  IsMulti,
3414  IsMap,
3415  Key,
3416  T,
3417  Clock,
3418  Hash,
3419  KeyEqual,
3420  Allocator>& lhs,
3422  IsMulti,
3423  IsMap,
3424  Key,
3425  T,
3426  Clock,
3427  Hash,
3428  KeyEqual,
3429  Allocator>& rhs) noexcept
3430 {
3431  lhs.swap(rhs);
3432 }
3433 
3435 template <
3436  bool IsMulti,
3437  bool IsMap,
3438  class Key,
3439  class T,
3440  class Clock,
3441  class Hash,
3442  class KeyEqual,
3443  class Allocator,
3444  class Rep,
3445  class Period>
3449  IsMulti,
3450  IsMap,
3451  Key,
3452  T,
3453  Clock,
3454  Hash,
3455  KeyEqual,
3456  Allocator>& c,
3457  std::chrono::duration<Rep, Period> const& age) noexcept
3458 {
3459  std::size_t n(0);
3460  auto const expired(c.clock().now() - age);
3461  for (auto iter(c.chronological.cbegin());
3462  iter != c.chronological.cend() && iter.when() <= expired;)
3463  {
3464  iter = c.erase(iter);
3465  ++n;
3466  }
3467  return n;
3468 }
3469 
3470 } // namespace beast
3471 
3472 #endif
beast::detail::aged_unordered_container::end
iterator end()
Definition: aged_unordered_container.h:1006
beast::detail::aged_unordered_container::chronological_t::rend
reverse_iterator rend()
Definition: aged_unordered_container.h:715
std::is_standard_layout
beast::detail::aged_unordered_container::erase
beast::detail::aged_container_iterator< false, Iterator, Base > erase(beast::detail::aged_container_iterator< is_const, Iterator, Base > pos)
Definition: aged_unordered_container.h:3058
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:1147
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:251
beast::detail::aged_unordered_container::KeyValueEqual::operator()
bool operator()(element const &e, Key const &k) const
Definition: aged_unordered_container.h:239
beast::detail::aged_unordered_container::begin
const_local_iterator begin(size_type n) const
Definition: aged_unordered_container.h:1313
beast::detail::aged_unordered_container::ValueHash::operator()
std::size_t operator()(element const &e) const
Definition: aged_unordered_container.h:173
beast::detail::aged_unordered_container::config_t::config_t
config_t(clock_type &clock_)
Definition: aged_unordered_container.h:300
beast::detail::aged_unordered_container::unlink_and_delete_element
void unlink_and_delete_element(element const *p)
Definition: aged_unordered_container.h:607
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)
std::binary_function
beast::detail::aged_unordered_container::rehash
void rehash(size_type count)
Definition: aged_unordered_container.h:1392
beast::detail::aged_unordered_container::max_load_factor
void max_load_factor(float ml)
Definition: aged_unordered_container.h:1386
beast::detail::aged_unordered_container::KeyValueEqual::KeyValueEqual
KeyValueEqual()
Definition: aged_unordered_container.h:207
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:281
std::true_type
beast::detail::aged_unordered_container::config_t::alloc
ElementAllocator & alloc()
Definition: aged_unordered_container.h:458
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:290
beast::detail::aged_unordered_container::config_t::config_t
config_t(config_t const &other)
Definition: aged_unordered_container.h:354
beast::detail::aged_unordered_container::insert
std::enable_if< maybe_multi, iterator >::type insert(const_iterator, value_type &&value)
Definition: aged_unordered_container.h:1133
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:679
utility
beast::detail::aged_unordered_container::key_eq
key_equal const & key_eq() const
Definition: aged_unordered_container.h:1417
beast::detail::aged_unordered_container::config_t::value_hash
ValueHash const & value_hash() const
Definition: aged_unordered_container.h:416
beast::detail::aged_unordered_container::KeyValueEqual::operator()
bool operator()(element const &lhs, element const &rhs) const
Definition: aged_unordered_container.h:245
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:2904
beast::detail::aged_unordered_container::config_t::config_t
config_t(config_t &&other, Allocator const &alloc)
Definition: aged_unordered_container.h:381
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:257
beast::detail::aged_unordered_container::insert
void insert(InputIt first, InputIt last, std::random_access_iterator_tag)
Definition: aged_unordered_container.h:1537
beast::detail::aged_unordered_container::insert_unchecked
void insert_unchecked(InputIt first, InputIt last)
Definition: aged_unordered_container.h:1521
beast::detail::aged_unordered_container::config_t::key_value_equal
KeyValueEqual & key_value_equal()
Definition: aged_unordered_container.h:434
beast::detail::aged_unordered_container::m_buck
Buckets m_buck
Definition: aged_unordered_container.h:1579
beast::detail::aged_unordered_container::chronological_t::rbegin
reverse_iterator rbegin()
Definition: aged_unordered_container.h:697
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:279
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:703
beast::detail::aged_unordered_container::m_config
config_t m_config
Definition: aged_unordered_container.h:1578
beast::detail::aged_unordered_container::chronological_t::cbegin
const_iterator cbegin() const
Definition: aged_unordered_container.h:673
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:285
beast::detail::aged_unordered_container::config_t::config_t
config_t(config_t const &other, Allocator const &alloc)
Definition: aged_unordered_container.h:364
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:304
beast::detail::aged_unordered_container::equal_range
std::pair< iterator, iterator > equal_range(K const &k)
Definition: aged_unordered_container.h:1278
beast::detail::aged_unordered_container::reserve
void reserve(size_type count)
Definition: aged_unordered_container.h:1399
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:2763
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:645
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:1012
beast::detail::aged_unordered_container::clock
clock_type const & clock() const
Definition: aged_unordered_container.h:940
beast::detail::aged_unordered_container::bucket
size_type bucket(Key const &k) const
Definition: aged_unordered_container.h:1361
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:314
beast::detail::aged_unordered_container::touch
void touch(beast::detail::aged_container_iterator< is_const, Iterator, Base > pos, typename clock_type::time_point const &now)
Definition: aged_unordered_container.h:1546
beast::detail::aged_unordered_container::Buckets::m_max_load_factor
float m_max_load_factor
Definition: aged_unordered_container.h:565
beast::detail::aged_unordered_container::equal_range
std::pair< const_iterator, const_iterator > equal_range(K const &k) const
Definition: aged_unordered_container.h:1290
beast::detail::aged_unordered_container::swap
void swap(aged_unordered_container &other) noexcept
Definition: aged_unordered_container.h:3154
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:632
beast::detail::empty_base_optimization< Hash >
beast::detail::aged_unordered_container::chronological_t::begin
iterator begin()
Definition: aged_unordered_container.h:661
beast::detail::aged_unordered_container::config_t::operator=
config_t & operator=(config_t const &other)
Definition: aged_unordered_container.h:390
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:1571
beast::detail::aged_unordered_container::Buckets::max_bucket_count
size_type max_bucket_count() const
Definition: aged_unordered_container.h:504
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:634
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:685
beast::detail::aged_unordered_container::config_t::clock
std::reference_wrapper< clock_type > clock
Definition: aged_unordered_container.h:471
std::allocator_traits
algorithm
beast::detail::aged_unordered_container::end
const_local_iterator end(size_type n) const
Definition: aged_unordered_container.h:1331
std::vector::clear
T clear(T... args)
beast::detail::aged_unordered_container::clock
clock_type & clock()
Definition: aged_unordered_container.h:934
beast::detail::aged_unordered_container::insert
void insert(InputIt first, InputIt last)
Definition: aged_unordered_container.h:1166
beast::detail::aged_unordered_container::chronological_t::rend
const_reverse_iterator rend() const
Definition: aged_unordered_container.h:721
beast::detail::aged_unordered_container::Buckets
Definition: aged_unordered_container.h:474
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:3323
beast::detail::aged_unordered_container::allocator_type
Allocator allocator_type
Definition: aged_unordered_container.h:617
beast::detail::aged_unordered_container::const_iterator
beast::detail::aged_container_iterator< true, typename cont_type::iterator > const_iterator
Definition: aged_unordered_container.h:629
std::vector::capacity
T capacity(T... args)
beast::detail::aged_unordered_container::config_t::key_eq
KeyEqual & key_eq()
Definition: aged_unordered_container.h:446
beast::detail::aged_unordered_container::size
size_type size() const noexcept
Definition: aged_unordered_container.h:1056
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:1201
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:342
beast::detail::aged_unordered_container::element::when
time_point when
Definition: aged_unordered_container.h:147
std::addressof
T addressof(T... args)
beast::detail::aged_unordered_container::touch
void touch(beast::detail::aged_container_iterator< is_const, Iterator, Base > pos)
Definition: aged_unordered_container.h:1227
std::reference_wrapper
beast::detail::aged_unordered_container::key_equal
KeyEqual key_equal
Definition: aged_unordered_container.h:616
beast::detail::aged_unordered_container::ValueHash::ValueHash
ValueHash(Hash const &h)
Definition: aged_unordered_container.h:167
beast::detail::aged_unordered_container::iterator_to
const_iterator iterator_to(value_type const &value) const
Definition: aged_unordered_container.h:1034
beast::detail::aged_unordered_container::empty
bool empty() const noexcept
Definition: aged_unordered_container.h:1050
beast::detail::aged_unordered_container::cbegin
const_local_iterator cbegin(size_type n) const
Definition: aged_unordered_container.h:1319
beast::detail::aged_unordered_container::Buckets::rehash
void rehash(size_type count, Container &c)
Definition: aged_unordered_container.h:524
beast::detail::aged_unordered_container::iterator_to
iterator iterator_to(value_type &value)
Definition: aged_unordered_container.h:1024
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:1479
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:264
beast::detail::aged_unordered_container::Buckets::resize
void resize(size_type n, Container &c)
Definition: aged_unordered_container.h:557
beast::detail::aged_unordered_container::Buckets::clear
void clear()
Definition: aged_unordered_container.h:498
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:325
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:160
beast::detail::aged_unordered_container::config_t
Definition: aged_unordered_container.h:294
beast::detail::aged_unordered_container::chronological_t::list
list_type list
Definition: aged_unordered_container.h:763
std::allocator_traits::deallocate
T deallocate(T... args)
beast::detail::aged_unordered_container::cend
const_iterator cend() const
Definition: aged_unordered_container.h:1018
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:755
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:400
beast::detail::aged_unordered_container::hasher
Hash hasher
Definition: aged_unordered_container.h:615
beast::detail::aged_unordered_container::get_allocator
allocator_type get_allocator() const
Definition: aged_unordered_container.h:928
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:656
beast::detail::aged_unordered_container::KeyValueEqual
Definition: aged_unordered_container.h:193
beast::detail::aged_unordered_container::max_bucket_count
size_type max_bucket_count() const
Definition: aged_unordered_container.h:1349
beast::detail::aged_unordered_container::ValueHash::ValueHash
ValueHash()
Definition: aged_unordered_container.h:163
beast::detail::aged_unordered_container::chronological_t::cend
const_iterator cend() const
Definition: aged_unordered_container.h:691
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::init
void init(ripemd160_context &ctx) noexcept
Definition: ripemd_context.h:364
beast::detail::aged_unordered_container::ValueHash::hash_function
Hash const & hash_function() const
Definition: aged_unordered_container.h:185
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:618
beast::detail::aged_unordered_container::KeyValueEqual::operator()
bool operator()(Key const &k, element const &e) const
Definition: aged_unordered_container.h:233
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:332
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:465
beast::detail::aged_unordered_container::count
size_type count(K const &k) const
Definition: aged_unordered_container.h:1245
beast::detail::aged_unordered_container::chronological_t::iterator
beast::detail::aged_container_iterator<!IsMap, typename list_type::iterator > iterator
Definition: aged_unordered_container.h:651
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:1343
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:320
std::unary_function
beast::detail::aged_unordered_container::Buckets::m_vec
vec_type m_vec
Definition: aged_unordered_container.h:566
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:622
beast::detail::aged_unordered_container::begin
iterator begin()
Definition: aged_unordered_container.h:988
std::swap
T swap(T... args)
beast::detail::aged_unordered_container::~aged_unordered_container
~aged_unordered_container()
Definition: aged_unordered_container.h:2474
beast::detail::aged_unordered_container::cend
const_local_iterator cend(size_type n) const
Definition: aged_unordered_container.h:1337
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:620
beast::detail::aged_unordered_container::chronological_t::crend
const_reverse_iterator crend() const
Definition: aged_unordered_container.h:727
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:709
beast::detail::aged_unordered_container::bucket_size
size_type bucket_size(size_type n) const
Definition: aged_unordered_container.h:1355
beast::detail::aged_unordered_container::cbegin
const_iterator cbegin() const
Definition: aged_unordered_container.h:1000
beast::detail::aged_unordered_container::begin
local_iterator begin(size_type n)
Definition: aged_unordered_container.h:1307
beast::detail::aged_unordered_container::max_load_factor
float max_load_factor() const
Definition: aged_unordered_container.h:1380
beast::detail::aged_unordered_container::load_factor
float load_factor() const
Definition: aged_unordered_container.h:1374
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:3220
beast::detail::aged_unordered_container::KeyValueEqual::result_type
bool result_type
Definition: aged_unordered_container.h:204
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:282
beast::detail::aged_unordered_container::m_cont
cont_type m_cont
Definition: aged_unordered_container.h:1580
beast::detail::aged_unordered_container::max_size
size_type max_size() const noexcept
Definition: aged_unordered_container.h:1062
beast::detail::aged_unordered_container::config_t::value_hash
ValueHash & value_hash()
Definition: aged_unordered_container.h:410
beast::detail::aged_unordered_container::Buckets::max_load_factor
float & max_load_factor()
Definition: aged_unordered_container.h:510
beast::detail::aged_unordered_container::KeyValueEqual::first_argument_type
Key first_argument_type
Definition: aged_unordered_container.h:202
std
STL namespace.
beast::detail::aged_unordered_container::insert
void insert(InputIt first, InputIt last, std::input_iterator_tag)
Definition: aged_unordered_container.h:1529
beast::detail::aged_unordered_container::begin
const_iterator begin() const
Definition: aged_unordered_container.h:994
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:482
beast::detail::aged_unordered_container::KeyValueEqual::KeyValueEqual
KeyValueEqual(KeyEqual const &keyEqual)
Definition: aged_unordered_container.h:211
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:653
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:1494
beast::detail::aged_unordered_container::Buckets::Buckets
Buckets(Allocator const &alloc)
Definition: aged_unordered_container.h:487
beast::detail::aged_unordered_container::config_t::config_t
config_t(clock_type &clock_, KeyEqual const &keyEqual)
Definition: aged_unordered_container.h:309
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:744
beast::detail::aged_unordered_container::end
local_iterator end(size_type n)
Definition: aged_unordered_container.h:1325
beast::detail::aged_unordered_container::operator=
aged_unordered_container & operator=(aged_unordered_container const &other)
Definition: aged_unordered_container.h:2497
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:619
beast::detail::aged_unordered_container::config_t::key_eq
KeyEqual const & key_eq() const
Definition: aged_unordered_container.h:452
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:3015
std::is_constructible
beast::detail::aged_container_iterator::iterator
Iterator const & iterator() const
Definition: aged_container_iterator.h:179
std::size_t
beast::detail::aged_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:372
beast::detail::aged_unordered_container::clear
void clear()
Definition: aged_unordered_container.h:2733
std::make_pair
T make_pair(T... args)
beast::detail::aged_unordered_container::find
iterator find(K const &k)
Definition: aged_unordered_container.h:1256
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:428
beast::detail::aged_unordered_container::ValueHash::hash_function
Hash & hash_function()
Definition: aged_unordered_container.h:179
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:1103
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:733
beast::detail::aged_unordered_container::new_element
element * new_element(Args &&... args)
Definition: aged_unordered_container.h:571
beast::detail::aged_unordered_container::config_t::hash_function
Hash & hash_function()
Definition: aged_unordered_container.h:422
beast::detail::aged_unordered_container::operator[]
std::conditional< IsMap, T, void * >::type & operator[](Key const &key)
Definition: aged_unordered_container.h:2650
beast::detail::aged_unordered_container::iterator
beast::detail::aged_container_iterator<!IsMap, typename cont_type::iterator > iterator
Definition: aged_unordered_container.h:627
beast::detail::aged_unordered_container::maybe_rehash
void maybe_rehash(size_type additional)
Definition: aged_unordered_container.h:1500
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:1159
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:1560
beast::detail::aged_unordered_container::find
const_iterator find(K const &k) const
Definition: aged_unordered_container.h:1267
beast::detail::aged_unordered_container::hash_function
hasher const & hash_function() const
Definition: aged_unordered_container.h:1411
beast::detail::aged_unordered_container::Buckets::max_load_factor
float const & max_load_factor() const
Definition: aged_unordered_container.h:516
beast::detail::aged_unordered_container::chronological_t::begin
const_iterator begin() const
Definition: aged_unordered_container.h:667
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:658
beast::detail::aged_unordered_container::insert
std::enable_if<!maybe_multi, iterator >::type insert(const_iterator, value_type &&value)
Definition: aged_unordered_container.h:1123
beast::detail::aged_unordered_container::at
std::conditional< IsMap, T, void * >::type & at(K const &k)
Definition: aged_unordered_container.h:2590
type_traits
beast::detail::aged_container_iterator
Definition: aged_container_iterator.h:47
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:1113
beast::detail::aged_unordered_container::delete_element
void delete_element(element const *p)
Definition: aged_unordered_container.h:599
beast::detail::aged_unordered_container::config_t::key_value_equal
KeyValueEqual const & key_value_equal() const
Definition: aged_unordered_container.h:440
std::hash
initializer_list
beast::detail::aged_unordered_container::insert
void insert(std::initializer_list< value_type > init)
Definition: aged_unordered_container.h:1175
beast
Definition: base_uint.h:646