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/container/detail/aged_container_iterator.h>
24 #include <ripple/beast/container/detail/aged_associative_container.h>
25 #include <ripple/beast/container/detail/empty_base_optimization.h>
26 #include <ripple/beast/container/aged_container.h>
27 #include <ripple/beast/clock/abstract_clock.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 <
84  typename std::conditional <IsMap,
86  Key>::type>
87 >
89 {
90 public:
93  using duration = typename clock_type::duration;
94  using key_type = Key;
95  using mapped_type = T;
96  using value_type = typename std::conditional <IsMap,
100 
101  // Introspection (for unit tests)
105 
106 private:
107  static Key const& extract (value_type const& value)
108  {
110  }
111 
112  // VFALCO TODO hoist to remove template argument dependencies
113  struct element
114  : boost::intrusive::unordered_set_base_hook <
115  boost::intrusive::link_mode <
116  boost::intrusive::normal_link>
117  >
118  , boost::intrusive::list_base_hook <
119  boost::intrusive::link_mode <
120  boost::intrusive::normal_link>
121  >
122  {
123  // Stash types here so the iterator doesn't
124  // need to see the container declaration.
125  struct stashed
126  {
127  explicit stashed() = default;
128 
131  };
132 
134  time_point const& when_,
135  value_type const& value_)
136  : value (value_)
137  , when (when_)
138  {
139  }
140 
142  time_point const& when_,
143  value_type&& value_)
144  : value (std::move (value_))
145  , when (when_)
146  {
147  }
148 
149  template <
150  class... Args,
151  class = typename std::enable_if <
153  Args...>::value>::type
154  >
155  element (time_point const& when_, Args&&... args)
156  : value (std::forward <Args> (args)...)
157  , when (when_)
158  {
159  }
160 
163  };
164 
165  // VFALCO TODO hoist to remove template argument dependencies
166  class ValueHash
168 #ifdef _LIBCPP_VERSION
170 #endif
171  {
172  public:
173 #ifndef _LIBCPP_VERSION
175  using result_type = size_t;
176 #endif
177 
179  {
180  }
181 
182  ValueHash (Hash const& h)
183  : beast::detail::empty_base_optimization <Hash> (h)
184  {
185  }
186 
187  std::size_t operator() (element const& e) const
188  {
189  return this->member() (extract (e.value));
190  }
191 
193  {
194  return this->member();
195  }
196 
197  Hash const& hash_function() const
198  {
199  return this->member();
200  }
201  };
202 
203  // Compares value_type against element, used in find/insert_check
204  // VFALCO TODO hoist to remove template argument dependencies
207 #ifdef _LIBCPP_VERSION
209 #endif
210  {
211  public:
212 #ifndef _LIBCPP_VERSION
213  using first_argument_type = Key;
215  using result_type = bool;
216 #endif
217 
219  {
220  }
221 
222  KeyValueEqual (KeyEqual const& keyEqual)
223  : beast::detail::empty_base_optimization <KeyEqual> (keyEqual)
224  {
225  }
226 
227  // VFALCO NOTE WE might want only to enable these overloads
228  // if KeyEqual has is_transparent
229 #if 0
230  template <class K>
231  bool operator() (K const& k, element const& e) const
232  {
233  return this->member() (k, extract (e.value));
234  }
235 
236  template <class K>
237  bool operator() (element const& e, K const& k) const
238  {
239  return this->member() (extract (e.value), k);
240  }
241 #endif
242 
243  bool operator() (Key const& k, element const& e) const
244  {
245  return this->member() (k, extract (e.value));
246  }
247 
248  bool operator() (element const& e, Key const& k) const
249  {
250  return this->member() (extract (e.value), k);
251  }
252 
253  bool operator() (element const& lhs, element const& rhs) const
254  {
255  return this->member() (extract (lhs.value), extract (rhs.value));
256  }
257 
258  KeyEqual& key_eq()
259  {
260  return this->member();
261  }
262 
263  KeyEqual const& key_eq() const
264  {
265  return this->member();
266  }
267  };
268 
269  using list_type = typename boost::intrusive::make_list <element,
270  boost::intrusive::constant_time_size <false>>::type;
271 
272  using cont_type = typename std::conditional <
273  IsMulti,
274  typename boost::intrusive::make_unordered_multiset <element,
275  boost::intrusive::constant_time_size <true>,
276  boost::intrusive::hash <ValueHash>,
277  boost::intrusive::equal <KeyValueEqual>,
278  boost::intrusive::cache_begin <true>
279  >::type,
280  typename boost::intrusive::make_unordered_set <element,
281  boost::intrusive::constant_time_size <true>,
282  boost::intrusive::hash <ValueHash>,
283  boost::intrusive::equal <KeyValueEqual>,
284  boost::intrusive::cache_begin <true>
285  >::type
286  >::type;
287 
288  using bucket_type = typename cont_type::bucket_type;
289  using bucket_traits = typename cont_type::bucket_traits;
290 
291  using ElementAllocator = typename std::allocator_traits <
292  Allocator>::template rebind_alloc <element>;
293 
295 
296  using BucketAllocator = typename std::allocator_traits <
297  Allocator>::template rebind_alloc <element>;
298 
300 
301  class config_t
302  : private ValueHash
303  , private KeyValueEqual
304  , private beast::detail::empty_base_optimization <ElementAllocator>
305  {
306  public:
307  explicit config_t (
308  clock_type& clock_)
309  : clock (clock_)
310  {
311  }
312 
314  clock_type& clock_,
315  Hash const& hash)
316  : ValueHash (hash)
317  , clock (clock_)
318  {
319  }
320 
322  clock_type& clock_,
323  KeyEqual const& keyEqual)
324  : KeyValueEqual (keyEqual)
325  , clock (clock_)
326  {
327  }
328 
330  clock_type& clock_,
331  Allocator const& alloc_)
332  : beast::detail::empty_base_optimization <ElementAllocator> (alloc_)
333  , clock (clock_)
334  {
335  }
336 
338  clock_type& clock_,
339  Hash const& hash,
340  KeyEqual const& keyEqual)
341  : ValueHash (hash)
342  , KeyValueEqual (keyEqual)
343  , clock (clock_)
344  {
345  }
346 
348  clock_type& clock_,
349  Hash const& hash,
350  Allocator const& alloc_)
351  : ValueHash (hash)
352  , beast::detail::empty_base_optimization <ElementAllocator> (alloc_)
353  , clock (clock_)
354  {
355  }
356 
358  clock_type& clock_,
359  KeyEqual const& keyEqual,
360  Allocator const& alloc_)
361  : KeyValueEqual (keyEqual)
362  , beast::detail::empty_base_optimization <ElementAllocator> (alloc_)
363  , clock (clock_)
364  {
365  }
366 
368  clock_type& clock_,
369  Hash const& hash,
370  KeyEqual const& keyEqual,
371  Allocator const& alloc_)
372  : ValueHash (hash)
373  , KeyValueEqual (keyEqual)
374  , beast::detail::empty_base_optimization <ElementAllocator> (alloc_)
375  , clock (clock_)
376  {
377  }
378 
379  config_t (config_t const& other)
380  : ValueHash (other.hash_function())
381  , KeyValueEqual (other.key_eq())
384  select_on_container_copy_construction (
385  other.alloc()))
386  , clock (other.clock)
387  {
388  }
389 
390  config_t (config_t const& other, Allocator const& alloc)
391  : ValueHash (other.hash_function())
392  , KeyValueEqual (other.key_eq())
394  , clock (other.clock)
395  {
396  }
397 
398  config_t (config_t&& other)
399  : ValueHash (std::move (other.hash_function()))
400  , KeyValueEqual (std::move (other.key_eq()))
402  std::move (other.alloc()))
403  , clock (other.clock)
404  {
405  }
406 
407  config_t (config_t&& other, Allocator const& alloc)
408  : ValueHash (std::move (other.hash_function()))
409  , KeyValueEqual (std::move (other.key_eq()))
411  , clock (other.clock)
412  {
413  }
414 
415  config_t& operator= (config_t const& other)
416  {
417  hash_function() = other.hash_function();
418  key_eq() = other.key_eq();
419  alloc() = other.alloc();
420  clock = other.clock;
421  return *this;
422  }
423 
425  {
426  hash_function() = std::move (other.hash_function());
427  key_eq() = std::move (other.key_eq());
428  alloc() = std::move (other.alloc());
429  clock = other.clock;
430  return *this;
431  }
432 
434  {
435  return *this;
436  }
437 
438  ValueHash const& value_hash() const
439  {
440  return *this;
441  }
442 
444  {
445  return ValueHash::hash_function();
446  }
447 
448  Hash const& hash_function() const
449  {
450  return ValueHash::hash_function();
451  }
452 
454  {
455  return *this;
456  }
457 
459  {
460  return *this;
461  }
462 
463  KeyEqual& key_eq()
464  {
465  return key_value_equal().key_eq();
466  }
467 
468  KeyEqual const& key_eq() const
469  {
470  return key_value_equal().key_eq();
471  }
472 
474  {
477  }
478 
479  ElementAllocator const& alloc() const
480  {
483  }
484 
486  };
487 
488  class Buckets
489  {
490  public:
491  using vec_type = std::vector<
492  bucket_type,
494  template rebind_alloc <bucket_type>>;
495 
497  : m_max_load_factor (1.f)
498  , m_vec ()
499  {
500  m_vec.resize (
501  cont_type::suggested_upper_bucket_count (0));
502  }
503 
504  Buckets (Allocator const& alloc)
505  : m_max_load_factor (1.f)
506  , m_vec (alloc)
507  {
508  m_vec.resize (
509  cont_type::suggested_upper_bucket_count (0));
510  }
511 
512  operator bucket_traits()
513  {
514  return bucket_traits (&m_vec[0], m_vec.size());
515  }
516 
517  void clear()
518  {
519  m_vec.clear();
520  }
521 
523  {
524  return m_vec.max_size();
525  }
526 
528  {
529  return m_max_load_factor;
530  }
531 
532  float const& max_load_factor() const
533  {
534  return m_max_load_factor;
535  }
536 
537  // count is the number of buckets
538  template <class Container>
539  void rehash (size_type count, Container& c)
540  {
541  size_type const size (m_vec.size());
542  if (count == size)
543  return;
544  if (count > m_vec.capacity())
545  {
546  // Need two vectors otherwise we
547  // will destroy non-empty buckets.
548  vec_type vec (m_vec.get_allocator());
549  std::swap (m_vec, vec);
550  m_vec.resize (count);
551  c.rehash (bucket_traits (
552  &m_vec[0], m_vec.size()));
553  return;
554  }
555  // Rehash in place.
556  if (count > size)
557  {
558  // This should not reallocate since
559  // we checked capacity earlier.
560  m_vec.resize (count);
561  c.rehash (bucket_traits (
562  &m_vec[0], count));
563  return;
564  }
565  // Resize must happen after rehash otherwise
566  // we might destroy non-empty buckets.
567  c.rehash (bucket_traits (
568  &m_vec[0], count));
569  m_vec.resize (count);
570  }
571 
572  // Resize the buckets to accomodate at least n items.
573  template <class Container>
574  void resize (size_type n, Container& c)
575  {
576  size_type const suggested (
577  cont_type::suggested_upper_bucket_count (n));
578  rehash (suggested, c);
579  }
580 
581  private:
584  };
585 
586  template <class... Args>
587  element* new_element (Args&&... args)
588  {
589  struct Deleter
590  {
592  Deleter (ElementAllocator& a)
593  : a_(a)
594  {
595  }
596 
597  void
598  operator()(element* p)
599  {
601  }
602  };
603 
605  m_config.alloc(), 1), Deleter(m_config.alloc()));
607  p.get(), clock().now(), std::forward <Args> (args)...);
608  return p.release();
609  }
610 
611  void delete_element (element const* p)
612  {
615  m_config.alloc(), const_cast<element*>(p), 1);
616  }
617 
618  void unlink_and_delete_element (element const* p)
619  {
620  chronological.list.erase (
621  chronological.list.iterator_to (*p));
622  m_cont.erase (m_cont.iterator_to (*p));
623  delete_element (p);
624  }
625 
626 public:
627  using hasher = Hash;
628  using key_equal = KeyEqual;
629  using allocator_type = Allocator;
631  using const_reference = value_type const&;
632  using pointer = typename std::allocator_traits <
633  Allocator>::pointer;
634  using const_pointer = typename std::allocator_traits <
635  Allocator>::const_pointer;
636 
637  // A set iterator (IsMap==false) is always const
638  // because the elements of a set are immutable.
640  typename cont_type::iterator>;
642  typename cont_type::iterator>;
643 
645  typename cont_type::local_iterator>;
647  typename cont_type::local_iterator>;
648 
649  //--------------------------------------------------------------------------
650  //
651  // Chronological ordered iterators
652  //
653  // "Memberspace"
654  // http://accu.org/index.php/journals/1527
655  //
656  //--------------------------------------------------------------------------
657 
659  {
660  public:
661  // A set iterator (IsMap==false) is always const
662  // because the elements of a set are immutable.
664  ! IsMap, typename list_type::iterator>;
666  true, typename list_type::iterator>;
668  ! IsMap, typename list_type::reverse_iterator>;
670  true, typename list_type::reverse_iterator>;
671 
673  {
674  return iterator (list.begin());
675  }
676 
678  {
679  return const_iterator (list.begin ());
680  }
681 
683  {
684  return const_iterator (list.begin ());
685  }
686 
688  {
689  return iterator (list.end ());
690  }
691 
693  {
694  return const_iterator (list.end ());
695  }
696 
698  {
699  return const_iterator (list.end ());
700  }
701 
703  {
704  return reverse_iterator (list.rbegin());
705  }
706 
708  {
709  return const_reverse_iterator (list.rbegin ());
710  }
711 
713  {
714  return const_reverse_iterator (list.rbegin ());
715  }
716 
718  {
719  return reverse_iterator (list.rend ());
720  }
721 
723  {
724  return const_reverse_iterator (list.rend ());
725  }
726 
728  {
729  return const_reverse_iterator (list.rend ());
730  }
731 
733  {
735  "must be standard layout");
736  return list.iterator_to (*reinterpret_cast <element*>(
737  reinterpret_cast<uint8_t*>(&value)-((std::size_t)
738  std::addressof(((element*)0)->member))));
739  }
740 
741  const_iterator iterator_to (value_type const& value) const
742  {
744  "must be standard layout");
745  return list.iterator_to (*reinterpret_cast <element const*>(
746  reinterpret_cast<uint8_t const*>(&value)-((std::size_t)
747  std::addressof(((element*)0)->member))));
748  }
749 
750  private:
752  {
753  }
754 
755  chronological_t (chronological_t const&) = delete;
756  chronological_t (chronological_t&&) = delete;
757 
759  list_type mutable list;
760  } chronological;
761 
762  //--------------------------------------------------------------------------
763  //
764  // Construction
765  //
766  //--------------------------------------------------------------------------
767 
768  aged_unordered_container() = delete;
769 
771 
772  aged_unordered_container (clock_type& clock, Hash const& hash);
773 
775  KeyEqual const& key_eq);
776 
778  Allocator const& alloc);
779 
781  Hash const& hash, KeyEqual const& key_eq);
782 
784  Hash const& hash, Allocator const& alloc);
785 
787  KeyEqual const& key_eq, Allocator const& alloc);
788 
790  clock_type& clock, Hash const& hash, KeyEqual const& key_eq,
791  Allocator const& alloc);
792 
793  template <class InputIt>
794  aged_unordered_container (InputIt first, InputIt last,
795  clock_type& clock);
796 
797  template <class InputIt>
798  aged_unordered_container (InputIt first, InputIt last,
799  clock_type& clock, Hash const& hash);
800 
801  template <class InputIt>
802  aged_unordered_container (InputIt first, InputIt last,
803  clock_type& clock, KeyEqual const& key_eq);
804 
805  template <class InputIt>
806  aged_unordered_container (InputIt first, InputIt last,
807  clock_type& clock, Allocator const& alloc);
808 
809  template <class InputIt>
810  aged_unordered_container (InputIt first, InputIt last,
811  clock_type& clock, Hash const& hash, KeyEqual const& key_eq);
812 
813  template <class InputIt>
814  aged_unordered_container (InputIt first, InputIt last,
815  clock_type& clock, Hash const& hash, Allocator const& alloc);
816 
817  template <class InputIt>
818  aged_unordered_container (InputIt first, InputIt last,
819  clock_type& clock, KeyEqual const& key_eq,
820  Allocator const& alloc);
821 
822  template <class InputIt>
823  aged_unordered_container (InputIt first, InputIt last,
824  clock_type& clock, Hash const& hash, KeyEqual const& key_eq,
825  Allocator const& alloc);
826 
828 
830  Allocator const& alloc);
831 
833 
835  Allocator const& alloc);
836 
838  clock_type& clock);
839 
841  clock_type& clock, Hash const& hash);
842 
844  clock_type& clock, KeyEqual const& key_eq);
845 
847  clock_type& clock, Allocator const& alloc);
848 
850  clock_type& clock, Hash const& hash, KeyEqual const& key_eq);
851 
853  clock_type& clock, Hash const& hash, Allocator const& alloc);
854 
856  clock_type& clock, KeyEqual const& key_eq, Allocator const& alloc);
857 
859  clock_type& clock, Hash const& hash, KeyEqual const& key_eq,
860  Allocator const& alloc);
861 
863 
865 
867 
869 
871  {
872  return m_config.alloc();
873  }
874 
876  {
877  return m_config.clock;
878  }
879 
880  clock_type const& clock() const
881  {
882  return m_config.clock;
883  }
884 
885  //--------------------------------------------------------------------------
886  //
887  // Element access (maps)
888  //
889  //--------------------------------------------------------------------------
890 
891  template <
892  class K,
893  bool maybe_multi = IsMulti,
894  bool maybe_map = IsMap,
897  at (K const& k);
898 
899  template <
900  class K,
901  bool maybe_multi = IsMulti,
902  bool maybe_map = IsMap,
905  at (K const& k) const;
906 
907  template <
908  bool maybe_multi = IsMulti,
909  bool maybe_map = IsMap,
912  operator[] (Key const& key);
913 
914  template <
915  bool maybe_multi = IsMulti,
916  bool maybe_map = IsMap,
919  operator[] (Key&& key);
920 
921  //--------------------------------------------------------------------------
922  //
923  // Iterators
924  //
925  //--------------------------------------------------------------------------
926 
927  iterator
928  begin ()
929  {
930  return iterator (m_cont.begin());
931  }
932 
934  begin () const
935  {
936  return const_iterator (m_cont.begin ());
937  }
938 
940  cbegin() const
941  {
942  return const_iterator (m_cont.begin ());
943  }
944 
945  iterator
946  end ()
947  {
948  return iterator (m_cont.end ());
949  }
950 
952  end () const
953  {
954  return const_iterator (m_cont.end ());
955  }
956 
958  cend () const
959  {
960  return const_iterator (m_cont.end ());
961  }
962 
963  iterator
965  {
967  "must be standard layout");
968  return m_cont.iterator_to (*reinterpret_cast <element*>(
969  reinterpret_cast<uint8_t*>(&value)-((std::size_t)
970  std::addressof(((element*)0)->member))));
971  }
972 
974  iterator_to (value_type const& value) const
975  {
977  "must be standard layout");
978  return m_cont.iterator_to (*reinterpret_cast <element const*>(
979  reinterpret_cast<uint8_t const*>(&value)-((std::size_t)
980  std::addressof(((element*)0)->member))));
981  }
982 
983  //--------------------------------------------------------------------------
984  //
985  // Capacity
986  //
987  //--------------------------------------------------------------------------
988 
989  bool empty() const noexcept
990  {
991  return m_cont.empty();
992  }
993 
994  size_type size() const noexcept
995  {
996  return m_cont.size();
997  }
998 
999  size_type max_size() const noexcept
1000  {
1001  return m_config.max_size();
1002  }
1003 
1004  //--------------------------------------------------------------------------
1005  //
1006  // Modifiers
1007  //
1008  //--------------------------------------------------------------------------
1009 
1010  void clear();
1011 
1012  // map, set
1013  template <bool maybe_multi = IsMulti>
1014  auto
1015  insert (value_type const& value) ->
1016  typename std::enable_if <! maybe_multi,
1018 
1019  // multimap, multiset
1020  template <bool maybe_multi = IsMulti>
1021  auto
1022  insert (value_type const& value) ->
1023  typename std::enable_if <maybe_multi,
1024  iterator>::type;
1025 
1026  // map, set
1027  template <bool maybe_multi = IsMulti, bool maybe_map = IsMap>
1028  auto
1029  insert (value_type&& value) ->
1030  typename std::enable_if <! maybe_multi && ! maybe_map,
1032 
1033  // multimap, multiset
1034  template <bool maybe_multi = IsMulti, bool maybe_map = IsMap>
1035  auto
1036  insert (value_type&& value) ->
1037  typename std::enable_if <maybe_multi && ! maybe_map,
1038  iterator>::type;
1039 
1040  // map, set
1041  template <bool maybe_multi = IsMulti>
1042  typename std::enable_if <! maybe_multi,
1043  iterator>::type
1044  insert (const_iterator /*hint*/, value_type const& value)
1045  {
1046  // Hint is ignored but we provide the interface so
1047  // callers may use ordered and unordered interchangeably.
1048  return insert (value).first;
1049  }
1050 
1051  // multimap, multiset
1052  template <bool maybe_multi = IsMulti>
1053  typename std::enable_if <maybe_multi,
1054  iterator>::type
1055  insert (const_iterator /*hint*/, value_type const& value)
1056  {
1057  // VFALCO TODO The hint could be used to let
1058  // the client order equal ranges
1059  return insert (value);
1060  }
1061 
1062  // map, set
1063  template <bool maybe_multi = IsMulti>
1064  typename std::enable_if <! maybe_multi,
1065  iterator>::type
1066  insert (const_iterator /*hint*/, value_type&& value)
1067  {
1068  // Hint is ignored but we provide the interface so
1069  // callers may use ordered and unordered interchangeably.
1070  return insert (std::move (value)).first;
1071  }
1072 
1073  // multimap, multiset
1074  template <bool maybe_multi = IsMulti>
1075  typename std::enable_if <maybe_multi,
1076  iterator>::type
1077  insert (const_iterator /*hint*/, value_type&& value)
1078  {
1079  // VFALCO TODO The hint could be used to let
1080  // the client order equal ranges
1081  return insert (std::move (value));
1082  }
1083 
1084  // map, multimap
1085  template <
1086  class P,
1087  bool maybe_map = IsMap
1088  >
1089  typename std::enable_if <maybe_map &&
1091  typename std::conditional <IsMulti,
1093  >::type
1094  >::type
1095  insert (P&& value)
1096  {
1097  return emplace (std::forward <P> (value));
1098  }
1099 
1100  // map, multimap
1101  template <
1102  class P,
1103  bool maybe_map = IsMap
1104  >
1105  typename std::enable_if <maybe_map &&
1107  typename std::conditional <IsMulti,
1109  >::type
1110  >::type
1111  insert (const_iterator hint, P&& value)
1112  {
1113  return emplace_hint (hint, std::forward <P> (value));
1114  }
1115 
1116  template <class InputIt>
1117  void insert (InputIt first, InputIt last)
1118  {
1119  insert (first, last,
1120  typename std::iterator_traits <
1121  InputIt>::iterator_category());
1122  }
1123 
1124  void
1126  {
1127  insert (init.begin(), init.end());
1128  }
1129 
1130  // set, map
1131  template <bool maybe_multi = IsMulti, class... Args>
1132  auto
1133  emplace (Args&&... args) ->
1134  typename std::enable_if <! maybe_multi,
1136 
1137  // multiset, multimap
1138  template <bool maybe_multi = IsMulti, class... Args>
1139  auto
1140  emplace (Args&&... args) ->
1141  typename std::enable_if <maybe_multi,
1142  iterator>::type;
1143 
1144  // set, map
1145  template <bool maybe_multi = IsMulti, class... Args>
1146  auto
1147  emplace_hint (const_iterator /*hint*/, Args&&... args) ->
1148  typename std::enable_if <! maybe_multi,
1150 
1151  // multiset, multimap
1152  template <bool maybe_multi = IsMulti, class... Args>
1153  typename std::enable_if <maybe_multi,
1154  iterator>::type
1155  emplace_hint (const_iterator /*hint*/, Args&&... args)
1156  {
1157  // VFALCO TODO The hint could be used for multi, to let
1158  // the client order equal ranges
1159  return emplace <maybe_multi> (
1160  std::forward <Args> (args)...);
1161  }
1162 
1163  template <bool is_const, class Iterator, class Base>
1166  is_const, Iterator, Base> pos);
1167 
1168  template <bool is_const, class Iterator, class Base>
1171  is_const, Iterator, Base> first,
1173  is_const, Iterator, Base> last);
1174 
1175  template <class K>
1176  auto
1177  erase (K const& k) ->
1178  size_type;
1179 
1180  void
1181  swap (aged_unordered_container& other) noexcept;
1182 
1183  template <bool is_const, class Iterator, class Base>
1184  void
1186  is_const, Iterator, Base> pos)
1187  {
1188  touch (pos, clock().now());
1189  }
1190 
1191  template <class K>
1192  auto
1193  touch (K const& k) ->
1194  size_type;
1195 
1196  //--------------------------------------------------------------------------
1197  //
1198  // Lookup
1199  //
1200  //--------------------------------------------------------------------------
1201 
1202  // VFALCO TODO Respect is_transparent (c++14)
1203  template <class K>
1204  size_type
1205  count (K const& k) const
1206  {
1207  return m_cont.count (k, std::cref (m_config.hash_function()),
1209  }
1210 
1211  // VFALCO TODO Respect is_transparent (c++14)
1212  template <class K>
1213  iterator
1214  find (K const& k)
1215  {
1216  return iterator (m_cont.find (k,
1219  }
1220 
1221  // VFALCO TODO Respect is_transparent (c++14)
1222  template <class K>
1224  find (K const& k) const
1225  {
1226  return const_iterator (m_cont.find (k,
1229  }
1230 
1231  // VFALCO TODO Respect is_transparent (c++14)
1232  template <class K>
1234  equal_range (K const& k)
1235  {
1236  auto const r (m_cont.equal_range (k,
1239  return std::make_pair (iterator (r.first),
1240  iterator (r.second));
1241  }
1242 
1243  // VFALCO TODO Respect is_transparent (c++14)
1244  template <class K>
1246  equal_range (K const& k) const
1247  {
1248  auto const r (m_cont.equal_range (k,
1251  return std::make_pair (const_iterator (r.first),
1252  const_iterator (r.second));
1253  }
1254 
1255  //--------------------------------------------------------------------------
1256  //
1257  // Bucket interface
1258  //
1259  //--------------------------------------------------------------------------
1260 
1262  {
1263  return local_iterator (m_cont.begin (n));
1264  }
1265 
1267  {
1268  return const_local_iterator (m_cont.begin (n));
1269  }
1270 
1272  {
1273  return const_local_iterator (m_cont.begin (n));
1274  }
1275 
1277  {
1278  return local_iterator (m_cont.end (n));
1279  }
1280 
1282  {
1283  return const_local_iterator (m_cont.end (n));
1284  }
1285 
1287  {
1288  return const_local_iterator (m_cont.end (n));
1289  }
1290 
1292  {
1293  return m_cont.bucket_count();
1294  }
1295 
1297  {
1298  return m_buck.max_bucket_count();
1299  }
1300 
1302  {
1303  return m_cont.bucket_size (n);
1304  }
1305 
1306  size_type bucket (Key const& k) const
1307  {
1308  assert (bucket_count() != 0);
1309  return m_cont.bucket (k,
1311  }
1312 
1313  //--------------------------------------------------------------------------
1314  //
1315  // Hash policy
1316  //
1317  //--------------------------------------------------------------------------
1318 
1319  float load_factor() const
1320  {
1321  return size() /
1322  static_cast <float> (m_cont.bucket_count());
1323  }
1324 
1325  float max_load_factor() const
1326  {
1327  return m_buck.max_load_factor();
1328  }
1329 
1330  void max_load_factor (float ml)
1331  {
1332  m_buck.max_load_factor () =
1334  }
1335 
1337  {
1338  count = std::max (count,
1339  size_type (size() / max_load_factor()));
1341  }
1342 
1344  {
1346  }
1347 
1348  //--------------------------------------------------------------------------
1349  //
1350  // Observers
1351  //
1352  //--------------------------------------------------------------------------
1353 
1354  hasher const& hash_function() const
1355  {
1356  return m_config.hash_function();
1357  }
1358 
1359  key_equal const& key_eq () const
1360  {
1361  return m_config.key_eq();
1362  }
1363 
1364  //--------------------------------------------------------------------------
1365  //
1366  // Comparison
1367  //
1368  //--------------------------------------------------------------------------
1369 
1370  // This differs from the standard in that the comparison
1371  // is only done on the key portion of the value type, ignoring
1372  // the mapped type.
1373  //
1374  template <
1375  bool OtherIsMap,
1376  class OtherKey,
1377  class OtherT,
1378  class OtherDuration,
1379  class OtherHash,
1380  class OtherAllocator,
1381  bool maybe_multi = IsMulti
1382  >
1384  operator== (
1385  aged_unordered_container <false, OtherIsMap,
1386  OtherKey, OtherT, OtherDuration, OtherHash, KeyEqual,
1387  OtherAllocator> const& other) const;
1388 
1389  template <
1390  bool OtherIsMap,
1391  class OtherKey,
1392  class OtherT,
1393  class OtherDuration,
1394  class OtherHash,
1395  class OtherAllocator,
1396  bool maybe_multi = IsMulti
1397  >
1399  operator== (
1400  aged_unordered_container <true, OtherIsMap,
1401  OtherKey, OtherT, OtherDuration, OtherHash, KeyEqual,
1402  OtherAllocator> const& other) const;
1403 
1404  template <
1405  bool OtherIsMulti,
1406  bool OtherIsMap,
1407  class OtherKey,
1408  class OtherT,
1409  class OtherDuration,
1410  class OtherHash,
1411  class OtherAllocator
1412  >
1414  aged_unordered_container <OtherIsMulti, OtherIsMap,
1415  OtherKey, OtherT, OtherDuration, OtherHash, KeyEqual,
1416  OtherAllocator> const& other) const
1417  {
1418  return ! (this->operator== (other));
1419  }
1420 
1421 private:
1422  bool
1423  would_exceed (size_type additional) const
1424  {
1425  return size() + additional >
1427  }
1428 
1429  void
1431  {
1432  if (would_exceed (additional))
1433  m_buck.resize (size() + additional, m_cont);
1434  assert (load_factor() <= max_load_factor());
1435  }
1436 
1437  // map, set
1438  template <bool maybe_multi = IsMulti>
1439  auto
1440  insert_unchecked (value_type const& value) ->
1441  typename std::enable_if <! maybe_multi,
1443 
1444  // multimap, multiset
1445  template <bool maybe_multi = IsMulti>
1446  auto
1447  insert_unchecked (value_type const& value) ->
1448  typename std::enable_if <maybe_multi,
1449  iterator>::type;
1450 
1451  template <class InputIt>
1452  void
1453  insert_unchecked (InputIt first, InputIt last)
1454  {
1455  for (; first != last; ++first)
1456  insert_unchecked (*first);
1457  }
1458 
1459  template <class InputIt>
1460  void
1461  insert (InputIt first, InputIt last,
1463  {
1464  for (; first != last; ++first)
1465  insert (*first);
1466  }
1467 
1468  template <class InputIt>
1469  void
1470  insert (InputIt first, InputIt last,
1472  {
1473  auto const n (std::distance (first, last));
1474  maybe_rehash (n);
1475  insert_unchecked (first, last);
1476  }
1477 
1478  template <bool is_const, class Iterator, class Base>
1479  void
1481  is_const, Iterator, Base> pos,
1482  typename clock_type::time_point const& now)
1483  {
1484  auto& e (*pos.iterator());
1485  e.when = now;
1486  chronological.list.erase (chronological.list.iterator_to (e));
1487  chronological.list.push_back (e);
1488  }
1489 
1490  template <bool maybe_propagate = std::allocator_traits <
1491  Allocator>::propagate_on_container_swap::value>
1494  {
1495  std::swap (m_config.key_compare(), other.m_config.key_compare());
1496  std::swap (m_config.alloc(), other.m_config.alloc());
1497  std::swap (m_config.clock, other.m_config.clock);
1498  }
1499 
1500  template <bool maybe_propagate = std::allocator_traits <
1501  Allocator>::propagate_on_container_swap::value>
1504  {
1505  std::swap (m_config.key_compare(), other.m_config.key_compare());
1506  std::swap (m_config.clock, other.m_config.clock);
1507  }
1508 
1509 private:
1510  config_t m_config;
1511  Buckets m_buck;
1513 };
1514 
1515 //------------------------------------------------------------------------------
1516 
1517 template <bool IsMulti, bool IsMap, class Key, class T,
1518  class Clock, class Hash, class KeyEqual, class Allocator>
1519 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1520  Hash, KeyEqual, Allocator>::
1522  clock_type& clock)
1523  : m_config (clock)
1524  , m_cont (m_buck,
1525  std::cref (m_config.value_hash()),
1526  std::cref (m_config.key_value_equal()))
1527 {
1528 }
1529 
1530 template <bool IsMulti, bool IsMap, class Key, class T,
1531  class Clock, class Hash, class KeyEqual, class Allocator>
1532 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1533  Hash, KeyEqual, Allocator>::
1535  clock_type& clock,
1536  Hash const& hash)
1537  : m_config (clock, hash)
1538  , m_cont (m_buck,
1539  std::cref (m_config.value_hash()),
1540  std::cref (m_config.key_value_equal()))
1541 {
1542 }
1543 
1544 template <bool IsMulti, bool IsMap, class Key, class T,
1545  class Clock, class Hash, class KeyEqual, class Allocator>
1546 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1547  Hash, KeyEqual, Allocator>::
1549  clock_type& clock,
1550  KeyEqual const& key_eq)
1551  : m_config (clock, key_eq)
1552  , m_cont (m_buck,
1553  std::cref (m_config.value_hash()),
1554  std::cref (m_config.key_value_equal()))
1555 {
1556 }
1557 
1558 template <bool IsMulti, bool IsMap, class Key, class T,
1559  class Clock, class Hash, class KeyEqual, class Allocator>
1560 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1561  Hash, KeyEqual, Allocator>::
1563  clock_type& clock,
1564  Allocator const& alloc)
1565  : m_config (clock, alloc)
1566  , m_buck (alloc)
1567  , m_cont (m_buck,
1568  std::cref (m_config.value_hash()),
1569  std::cref (m_config.key_value_equal()))
1570 {
1571 }
1572 
1573 template <bool IsMulti, bool IsMap, class Key, class T,
1574  class Clock, class Hash, class KeyEqual, class Allocator>
1575 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1576  Hash, KeyEqual, Allocator>::
1578  clock_type& clock,
1579  Hash const& hash,
1580  KeyEqual const& key_eq)
1581  : m_config (clock, hash, key_eq)
1582  , m_cont (m_buck,
1583  std::cref (m_config.value_hash()),
1584  std::cref (m_config.key_value_equal()))
1585 {
1586 }
1587 
1588 template <bool IsMulti, bool IsMap, class Key, class T,
1589  class Clock, class Hash, class KeyEqual, class Allocator>
1590 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1591  Hash, KeyEqual, Allocator>::
1593  clock_type& clock,
1594  Hash const& hash,
1595  Allocator const& alloc)
1596  : m_config (clock, hash, alloc)
1597  , m_buck (alloc)
1598  , m_cont (m_buck,
1599  std::cref (m_config.value_hash()),
1600  std::cref (m_config.key_value_equal()))
1601 {
1602 }
1603 
1604 template <bool IsMulti, bool IsMap, class Key, class T,
1605  class Clock, class Hash, class KeyEqual, class Allocator>
1606 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1607  Hash, KeyEqual, Allocator>::
1609  clock_type& clock,
1610  KeyEqual const& key_eq,
1611  Allocator const& alloc)
1612  : m_config (clock, key_eq, alloc)
1613  , m_buck (alloc)
1614  , m_cont (m_buck,
1615  std::cref (m_config.value_hash()),
1616  std::cref (m_config.key_value_equal()))
1617 {
1618 }
1619 
1620 template <bool IsMulti, bool IsMap, class Key, class T,
1621  class Clock, class Hash, class KeyEqual, class Allocator>
1622 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1623  Hash, KeyEqual, Allocator>::
1625  clock_type& clock,
1626  Hash const& hash,
1627  KeyEqual const& key_eq,
1628  Allocator const& alloc)
1629  : m_config (clock, hash, key_eq, alloc)
1630  , m_buck (alloc)
1631  , m_cont (m_buck,
1632  std::cref (m_config.value_hash()),
1633  std::cref (m_config.key_value_equal()))
1634 {
1635 }
1636 
1637 template <bool IsMulti, bool IsMap, class Key, class T,
1638  class Clock, class Hash, class KeyEqual, class Allocator>
1639 template <class InputIt>
1640 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1641  Hash, KeyEqual, Allocator>::
1642 aged_unordered_container (InputIt first, InputIt last,
1643  clock_type& clock)
1644  : m_config (clock)
1645  , m_cont (m_buck,
1646  std::cref (m_config.value_hash()),
1647  std::cref (m_config.key_value_equal()))
1648 {
1649  insert (first, last);
1650 }
1651 
1652 template <bool IsMulti, bool IsMap, class Key, class T,
1653  class Clock, class Hash, class KeyEqual, class Allocator>
1654 template <class InputIt>
1655 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1656  Hash, KeyEqual, Allocator>::
1657 aged_unordered_container (InputIt first, InputIt last,
1658  clock_type& clock,
1659  Hash const& hash)
1660  : m_config (clock, hash)
1661  , m_cont (m_buck,
1662  std::cref (m_config.value_hash()),
1663  std::cref (m_config.key_value_equal()))
1664 {
1665  insert (first, last);
1666 }
1667 
1668 template <bool IsMulti, bool IsMap, class Key, class T,
1669  class Clock, class Hash, class KeyEqual, class Allocator>
1670 template <class InputIt>
1671 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1672  Hash, KeyEqual, Allocator>::
1673 aged_unordered_container (InputIt first, InputIt last,
1674  clock_type& clock,
1675  KeyEqual const& key_eq)
1676  : m_config (clock, key_eq)
1677  , m_cont (m_buck,
1678  std::cref (m_config.value_hash()),
1679  std::cref (m_config.key_value_equal()))
1680 {
1681  insert (first, last);
1682 }
1683 
1684 template <bool IsMulti, bool IsMap, class Key, class T,
1685  class Clock, class Hash, class KeyEqual, class Allocator>
1686 template <class InputIt>
1687 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1688  Hash, KeyEqual, Allocator>::
1689 aged_unordered_container (InputIt first, InputIt last,
1690  clock_type& clock,
1691  Allocator const& alloc)
1692  : m_config (clock, alloc)
1693  , m_buck (alloc)
1694  , m_cont (m_buck,
1695  std::cref (m_config.value_hash()),
1696  std::cref (m_config.key_value_equal()))
1697 {
1698  insert (first, last);
1699 }
1700 
1701 template <bool IsMulti, bool IsMap, class Key, class T,
1702  class Clock, class Hash, class KeyEqual, class Allocator>
1703 template <class InputIt>
1704 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1705  Hash, KeyEqual, Allocator>::
1706 aged_unordered_container (InputIt first, InputIt last,
1707  clock_type& clock,
1708  Hash const& hash,
1709  KeyEqual const& key_eq)
1710  : m_config (clock, hash, key_eq)
1711  , m_cont (m_buck,
1712  std::cref (m_config.value_hash()),
1713  std::cref (m_config.key_value_equal()))
1714 {
1715  insert (first, last);
1716 }
1717 
1718 template <bool IsMulti, bool IsMap, class Key, class T,
1719  class Clock, class Hash, class KeyEqual, class Allocator>
1720 template <class InputIt>
1721 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1722  Hash, KeyEqual, Allocator>::
1723 aged_unordered_container (InputIt first, InputIt last,
1724  clock_type& clock,
1725  Hash const& hash,
1726  Allocator const& alloc)
1727  : m_config (clock, hash, alloc)
1728  , m_buck (alloc)
1729  , m_cont (m_buck,
1730  std::cref (m_config.value_hash()),
1731  std::cref (m_config.key_value_equal()))
1732 {
1733  insert (first, last);
1734 }
1735 
1736 template <bool IsMulti, bool IsMap, class Key, class T,
1737  class Clock, class Hash, class KeyEqual, class Allocator>
1738 template <class InputIt>
1739 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1740  Hash, KeyEqual, Allocator>::
1741 aged_unordered_container (InputIt first, InputIt last,
1742  clock_type& clock,
1743  KeyEqual const& key_eq,
1744  Allocator const& alloc)
1745  : m_config (clock, key_eq, alloc)
1746  , m_buck (alloc)
1747  , m_cont (m_buck,
1748  std::cref (m_config.value_hash()),
1749  std::cref (m_config.key_value_equal()))
1750 {
1751  insert (first, last);
1752 }
1753 
1754 template <bool IsMulti, bool IsMap, class Key, class T,
1755  class Clock, class Hash, class KeyEqual, class Allocator>
1756 template <class InputIt>
1757 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1758  Hash, KeyEqual, Allocator>::
1759 aged_unordered_container (InputIt first, InputIt last,
1760  clock_type& clock,
1761  Hash const& hash,
1762  KeyEqual const& key_eq,
1763  Allocator const& alloc)
1764  : m_config (clock, hash, key_eq, alloc)
1765  , m_buck (alloc)
1766  , m_cont (m_buck,
1767  std::cref (m_config.value_hash()),
1768  std::cref (m_config.key_value_equal()))
1769 {
1770  insert (first, last);
1771 }
1772 
1773 template <bool IsMulti, bool IsMap, class Key, class T,
1774  class Clock, class Hash, class KeyEqual, class Allocator>
1775 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1776  Hash, KeyEqual, Allocator>::
1778  : m_config (other.m_config)
1779  , m_buck (m_config.alloc())
1780  , m_cont (m_buck,
1781  std::cref (m_config.value_hash()),
1782  std::cref (m_config.key_value_equal()))
1783 {
1784  insert (other.cbegin(), other.cend());
1785 }
1786 
1787 template <bool IsMulti, bool IsMap, class Key, class T,
1788  class Clock, class Hash, class KeyEqual, class Allocator>
1789 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1790  Hash, KeyEqual, Allocator>::
1792  Allocator const& alloc)
1793  : m_config (other.m_config, alloc)
1794  , m_buck (alloc)
1795  , m_cont (m_buck,
1796  std::cref (m_config.value_hash()),
1797  std::cref (m_config.key_value_equal()))
1798 {
1799  insert (other.cbegin(), other.cend());
1800 }
1801 
1802 template <bool IsMulti, bool IsMap, class Key, class T,
1803  class Clock, class Hash, class KeyEqual, class Allocator>
1804 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1805  Hash, KeyEqual, Allocator>::
1807  : m_config (std::move (other.m_config))
1808  , m_buck (std::move (other.m_buck))
1809  , m_cont (std::move (other.m_cont))
1810 {
1811  chronological.list = std::move (other.chronological.list);
1812 }
1813 
1814 template <bool IsMulti, bool IsMap, class Key, class T,
1815  class Clock, class Hash, class KeyEqual, class Allocator>
1816 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1817  Hash, KeyEqual, Allocator>::
1819  Allocator const& alloc)
1820  : m_config (std::move (other.m_config), alloc)
1821  , m_buck (alloc)
1822  , m_cont (m_buck,
1823  std::cref (m_config.value_hash()),
1824  std::cref (m_config.key_value_equal()))
1825 {
1826  insert (other.cbegin(), other.cend());
1827  other.clear ();
1828 }
1829 
1830 template <bool IsMulti, bool IsMap, class Key, class T,
1831  class Clock, class Hash, class KeyEqual, class Allocator>
1832 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1833  Hash, KeyEqual, Allocator>::
1835  clock_type& clock)
1836  : m_config (clock)
1837  , m_cont (m_buck,
1838  std::cref (m_config.value_hash()),
1839  std::cref (m_config.key_value_equal()))
1840 {
1841  insert (init.begin(), init.end());
1842 }
1843 
1844 template <bool IsMulti, bool IsMap, class Key, class T,
1845  class Clock, class Hash, class KeyEqual, class Allocator>
1846 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1847  Hash, KeyEqual, Allocator>::
1849  clock_type& clock,
1850  Hash const& hash)
1851  : m_config (clock, hash)
1852  , m_cont (m_buck,
1853  std::cref (m_config.value_hash()),
1854  std::cref (m_config.key_value_equal()))
1855 {
1856  insert (init.begin(), init.end());
1857 }
1858 
1859 template <bool IsMulti, bool IsMap, class Key, class T,
1860  class Clock, class Hash, class KeyEqual, class Allocator>
1861 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1862  Hash, KeyEqual, Allocator>::
1864  clock_type& clock,
1865  KeyEqual const& key_eq)
1866  : m_config (clock, key_eq)
1867  , m_cont (m_buck,
1868  std::cref (m_config.value_hash()),
1869  std::cref (m_config.key_value_equal()))
1870 {
1871  insert (init.begin(), init.end());
1872 }
1873 
1874 template <bool IsMulti, bool IsMap, class Key, class T,
1875  class Clock, class Hash, class KeyEqual, class Allocator>
1876 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1877  Hash, KeyEqual, Allocator>::
1879  clock_type& clock,
1880  Allocator const& alloc)
1881  : m_config (clock, alloc)
1882  , m_buck (alloc)
1883  , m_cont (m_buck,
1884  std::cref (m_config.value_hash()),
1885  std::cref (m_config.key_value_equal()))
1886 {
1887  insert (init.begin(), init.end());
1888 }
1889 
1890 template <bool IsMulti, bool IsMap, class Key, class T,
1891  class Clock, class Hash, class KeyEqual, class Allocator>
1892 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1893  Hash, KeyEqual, Allocator>::
1895  clock_type& clock,
1896  Hash const& hash,
1897  KeyEqual const& key_eq)
1898  : m_config (clock, hash, key_eq)
1899  , m_cont (m_buck,
1900  std::cref (m_config.value_hash()),
1901  std::cref (m_config.key_value_equal()))
1902 {
1903  insert (init.begin(), init.end());
1904 }
1905 
1906 template <bool IsMulti, bool IsMap, class Key, class T,
1907  class Clock, class Hash, class KeyEqual, class Allocator>
1908 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1909  Hash, KeyEqual, Allocator>::
1911  clock_type& clock,
1912  Hash const& hash,
1913  Allocator const& alloc)
1914  : m_config (clock, hash, alloc)
1915  , m_buck (alloc)
1916  , m_cont (m_buck,
1917  std::cref (m_config.value_hash()),
1918  std::cref (m_config.key_value_equal()))
1919 {
1920  insert (init.begin(), init.end());
1921 }
1922 
1923 template <bool IsMulti, bool IsMap, class Key, class T,
1924  class Clock, class Hash, class KeyEqual, class Allocator>
1925 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1926  Hash, KeyEqual, Allocator>::
1928  clock_type& clock,
1929  KeyEqual const& key_eq,
1930  Allocator const& alloc)
1931  : m_config (clock, key_eq, alloc)
1932  , m_buck (alloc)
1933  , m_cont (m_buck,
1934  std::cref (m_config.value_hash()),
1935  std::cref (m_config.key_value_equal()))
1936 {
1937  insert (init.begin(), init.end());
1938 }
1939 
1940 template <bool IsMulti, bool IsMap, class Key, class T,
1941  class Clock, class Hash, class KeyEqual, class Allocator>
1942 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1943  Hash, KeyEqual, Allocator>::
1945  clock_type& clock,
1946  Hash const& hash,
1947  KeyEqual const& key_eq,
1948  Allocator const& alloc)
1949  : m_config (clock, hash, key_eq, alloc)
1950  , m_buck (alloc)
1951  , m_cont (m_buck,
1952  std::cref (m_config.value_hash()),
1953  std::cref (m_config.key_value_equal()))
1954 {
1955  insert (init.begin(), init.end());
1956 }
1957 
1958 template <bool IsMulti, bool IsMap, class Key, class T,
1959  class Clock, class Hash, class KeyEqual, class Allocator>
1960 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1961  Hash, KeyEqual, Allocator>::
1962 ~aged_unordered_container()
1963 {
1964  clear();
1965 }
1966 
1967 template <bool IsMulti, bool IsMap, class Key, class T,
1968  class Clock, class Hash, class KeyEqual, class Allocator>
1969 auto
1970 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1971  Hash, KeyEqual, Allocator>::
1972 operator= (aged_unordered_container const& other)
1974 {
1975  if (this != &other)
1976  {
1977  size_type const n (other.size());
1978  clear();
1979  m_config = other.m_config;
1980  m_buck = Buckets (m_config.alloc());
1981  maybe_rehash (n);
1982  insert_unchecked (other.begin(), other.end());
1983  }
1984  return *this;
1985 }
1986 
1987 template <bool IsMulti, bool IsMap, class Key, class T,
1988  class Clock, class Hash, class KeyEqual, class Allocator>
1989 auto
1990 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
1991  Hash, KeyEqual, Allocator>::
1992 operator= (aged_unordered_container&& other) ->
1994 {
1995  size_type const n (other.size());
1996  clear();
1997  m_config = std::move (other.m_config);
1998  m_buck = Buckets (m_config.alloc());
1999  maybe_rehash (n);
2000  insert_unchecked (other.begin(), other.end());
2001  other.clear();
2002  return *this;
2003 }
2004 
2005 template <bool IsMulti, bool IsMap, class Key, class T,
2006  class Clock, class Hash, class KeyEqual, class Allocator>
2007 auto
2008 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
2009  Hash, KeyEqual, Allocator>::
2012 {
2013  clear ();
2014  insert (init);
2015  return *this;
2016 }
2017 
2018 //------------------------------------------------------------------------------
2019 
2020 template <bool IsMulti, bool IsMap, class Key, class T,
2021  class Clock, class Hash, class KeyEqual, class Allocator>
2022 template <class K, bool maybe_multi, bool maybe_map, class>
2024 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
2025  Hash, KeyEqual, Allocator>::
2026 at (K const& k)
2027 {
2028  auto const iter (m_cont.find (k,
2029  std::cref (m_config.hash_function()),
2030  std::cref (m_config.key_value_equal())));
2031  if (iter == m_cont.end())
2032  throw std::out_of_range ("key not found");
2033  return iter->value.second;
2034 }
2035 
2036 template <bool IsMulti, bool IsMap, class Key, class T,
2037  class Clock, class Hash, class KeyEqual, class Allocator>
2038 template <class K, bool maybe_multi, bool maybe_map, class>
2040 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
2041  Hash, KeyEqual, Allocator>::
2042 at (K const& k) const
2043 {
2044  auto const iter (m_cont.find (k,
2045  std::cref (m_config.hash_function()),
2046  std::cref (m_config.key_value_equal())));
2047  if (iter == m_cont.end())
2048  throw std::out_of_range ("key not found");
2049  return iter->value.second;
2050 }
2051 
2052 template <bool IsMulti, bool IsMap, class Key, class T,
2053  class Clock, class Hash, class KeyEqual, class Allocator>
2054 template <bool maybe_multi, bool maybe_map, class>
2056 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
2057  Hash, KeyEqual, Allocator>::
2058 operator[] (Key const& key)
2059 {
2060  maybe_rehash (1);
2061  typename cont_type::insert_commit_data d;
2062  auto const result (m_cont.insert_check (key,
2063  std::cref (m_config.hash_function()),
2064  std::cref (m_config.key_value_equal()), d));
2065  if (result.second)
2066  {
2067  element* const p (new_element (
2068  std::piecewise_construct,
2069  std::forward_as_tuple (key),
2070  std::forward_as_tuple ()));
2071  m_cont.insert_commit (*p, d);
2072  chronological.list.push_back (*p);
2073  return p->value.second;
2074  }
2075  return result.first->value.second;
2076 }
2077 
2078 template <bool IsMulti, bool IsMap, class Key, class T,
2079  class Clock, class Hash, class KeyEqual, class Allocator>
2080 template <bool maybe_multi, bool maybe_map, class>
2082 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
2083  Hash, KeyEqual, Allocator>::
2084 operator[] (Key&& key)
2085 {
2086  maybe_rehash (1);
2087  typename cont_type::insert_commit_data d;
2088  auto const result (m_cont.insert_check (key,
2089  std::cref (m_config.hash_function()),
2090  std::cref (m_config.key_value_equal()), d));
2091  if (result.second)
2092  {
2093  element* const p (new_element (
2094  std::piecewise_construct,
2095  std::forward_as_tuple (std::move (key)),
2096  std::forward_as_tuple ()));
2097  m_cont.insert_commit (*p, d);
2098  chronological.list.push_back (*p);
2099  return p->value.second;
2100  }
2101  return result.first->value.second;
2102 }
2103 
2104 //------------------------------------------------------------------------------
2105 
2106 template <bool IsMulti, bool IsMap, class Key, class T,
2107  class Clock, class Hash, class KeyEqual, class Allocator>
2108 void
2109 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
2110  Hash, KeyEqual, Allocator>::
2111 clear()
2112 {
2113  for (auto iter (chronological.list.begin());
2114  iter != chronological.list.end();)
2115  unlink_and_delete_element (&*iter++);
2116  chronological.list.clear();
2117  m_cont.clear();
2118  m_buck.clear();
2119 }
2120 
2121 // map, set
2122 template <bool IsMulti, bool IsMap, class Key, class T,
2123  class Clock, class Hash, class KeyEqual, class Allocator>
2124 template <bool maybe_multi>
2125 auto
2126 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
2127  Hash, KeyEqual, Allocator>::
2128 insert (value_type const& value) ->
2129  typename std::enable_if <! maybe_multi,
2131 {
2132  maybe_rehash (1);
2133  typename cont_type::insert_commit_data d;
2134  auto const result (m_cont.insert_check (extract (value),
2135  std::cref (m_config.hash_function()),
2136  std::cref (m_config.key_value_equal()), d));
2137  if (result.second)
2138  {
2139  element* const p (new_element (value));
2140  auto const iter (m_cont.insert_commit (*p, d));
2141  chronological.list.push_back (*p);
2142  return std::make_pair (iterator (iter), true);
2143  }
2144  return std::make_pair (iterator (result.first), false);
2145 }
2146 
2147 // multimap, multiset
2148 template <bool IsMulti, bool IsMap, class Key, class T,
2149  class Clock, class Hash, class KeyEqual, class Allocator>
2150 template <bool maybe_multi>
2151 auto
2152 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
2153  Hash, KeyEqual, Allocator>::
2154 insert (value_type const& value) ->
2155  typename std::enable_if <maybe_multi,
2156  iterator>::type
2157 {
2158  maybe_rehash (1);
2159  element* const p (new_element (value));
2160  chronological.list.push_back (*p);
2161  auto const iter (m_cont.insert (*p));
2162  return iterator (iter);
2163 }
2164 
2165 // map, set
2166 template <bool IsMulti, bool IsMap, class Key, class T,
2167  class Clock, class Hash, class KeyEqual, class Allocator>
2168 template <bool maybe_multi, bool maybe_map>
2169 auto
2170 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
2171  Hash, KeyEqual, Allocator>::
2172 insert (value_type&& value) ->
2173  typename std::enable_if <! maybe_multi && ! maybe_map,
2175 {
2176  maybe_rehash (1);
2177  typename cont_type::insert_commit_data d;
2178  auto const result (m_cont.insert_check (extract (value),
2179  std::cref (m_config.hash_function()),
2180  std::cref (m_config.key_value_equal()), d));
2181  if (result.second)
2182  {
2183  element* const p (new_element (std::move (value)));
2184  auto const iter (m_cont.insert_commit (*p, d));
2185  chronological.list.push_back (*p);
2186  return std::make_pair (iterator (iter), true);
2187  }
2188  return std::make_pair (iterator (result.first), false);
2189 }
2190 
2191 // multimap, multiset
2192 template <bool IsMulti, bool IsMap, class Key, class T,
2193  class Clock, class Hash, class KeyEqual, class Allocator>
2194 template <bool maybe_multi, bool maybe_map>
2195 auto
2196 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
2197  Hash, KeyEqual, Allocator>::
2198 insert (value_type&& value) ->
2199  typename std::enable_if <maybe_multi && ! maybe_map,
2200  iterator>::type
2201 {
2202  maybe_rehash (1);
2203  element* const p (new_element (std::move (value)));
2204  chronological.list.push_back (*p);
2205  auto const iter (m_cont.insert (*p));
2206  return iterator (iter);
2207 }
2208 
2209 #if 1 // Use insert() instead of insert_check() insert_commit()
2210 // set, map
2211 template <bool IsMulti, bool IsMap, class Key, class T,
2212  class Clock, class Hash, class KeyEqual, class Allocator>
2213 template <bool maybe_multi, class... Args>
2214 auto
2215 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
2216  Hash, KeyEqual, Allocator>::
2217 emplace (Args&&... args) ->
2218  typename std::enable_if <! maybe_multi,
2220 {
2221  maybe_rehash (1);
2222  // VFALCO NOTE Its unfortunate that we need to
2223  // construct element here
2224  element* const p (new_element (std::forward <Args> (args)...));
2225  auto const result (m_cont.insert (*p));
2226  if (result.second)
2227  {
2228  chronological.list.push_back (*p);
2229  return std::make_pair (iterator (result.first), true);
2230  }
2231  delete_element (p);
2232  return std::make_pair (iterator (result.first), false);
2233 }
2234 #else // As original, use insert_check() / insert_commit () pair.
2235 // set, map
2236 template <bool IsMulti, bool IsMap, class Key, class T,
2237  class Clock, class Hash, class KeyEqual, class Allocator>
2238 template <bool maybe_multi, class... Args>
2239 auto
2240 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
2241  Hash, KeyEqual, Allocator>::
2242 emplace (Args&&... args) ->
2243  typename std::enable_if <! maybe_multi,
2245 {
2246  maybe_rehash (1);
2247  // VFALCO NOTE Its unfortunate that we need to
2248  // construct element here
2249  element* const p (new_element (
2250  std::forward <Args> (args)...));
2251  typename cont_type::insert_commit_data d;
2252  auto const result (m_cont.insert_check (extract (p->value),
2253  std::cref (m_config.hash_function()),
2254  std::cref (m_config.key_value_equal()), d));
2255  if (result.second)
2256  {
2257  auto const iter (m_cont.insert_commit (*p, d));
2258  chronological.list.push_back (*p);
2259  return std::make_pair (iterator (iter), true);
2260  }
2261  delete_element (p);
2262  return std::make_pair (iterator (result.first), false);
2263 }
2264 #endif // 0
2265 
2266 // multiset, multimap
2267 template <bool IsMulti, bool IsMap, class Key, class T,
2268  class Clock, class Hash, class KeyEqual, class Allocator>
2269 template <bool maybe_multi, class... Args>
2270 auto
2271 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
2272  Hash, KeyEqual, Allocator>::
2273 emplace (Args&&... args) ->
2274  typename std::enable_if <maybe_multi,
2275  iterator>::type
2276 {
2277  maybe_rehash (1);
2278  element* const p (new_element (
2279  std::forward <Args> (args)...));
2280  chronological.list.push_back (*p);
2281  auto const iter (m_cont.insert (*p));
2282  return iterator (iter);
2283 }
2284 
2285 // set, map
2286 template <bool IsMulti, bool IsMap, class Key, class T,
2287  class Clock, class Hash, class KeyEqual, class Allocator>
2288 template <bool maybe_multi, class... Args>
2289 auto
2290 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
2291  Hash, KeyEqual, Allocator>::
2292 emplace_hint (const_iterator /*hint*/, Args&&... args) ->
2293  typename std::enable_if <! maybe_multi,
2295 {
2296  maybe_rehash (1);
2297  // VFALCO NOTE Its unfortunate that we need to
2298  // construct element here
2299  element* const p (new_element (
2300  std::forward <Args> (args)...));
2301  typename cont_type::insert_commit_data d;
2302  auto const result (m_cont.insert_check (extract (p->value),
2303  std::cref (m_config.hash_function()),
2304  std::cref (m_config.key_value_equal()), d));
2305  if (result.second)
2306  {
2307  auto const iter (m_cont.insert_commit (*p, d));
2308  chronological.list.push_back (*p);
2309  return std::make_pair (iterator (iter), true);
2310  }
2311  delete_element (p);
2312  return std::make_pair (iterator (result.first), false);
2313 }
2314 
2315 template <bool IsMulti, bool IsMap, class Key, class T,
2316  class Clock, class Hash, class KeyEqual, class Allocator>
2317 template <bool is_const, class Iterator, class Base>
2319 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
2320  Hash, KeyEqual, Allocator>::
2322  is_const, Iterator, Base> pos)
2323 {
2324  unlink_and_delete_element(&*((pos++).iterator()));
2326  false, Iterator, Base> (pos.iterator());
2327 }
2328 
2329 template <bool IsMulti, bool IsMap, class Key, class T,
2330  class Clock, class Hash, class KeyEqual, class Allocator>
2331 template <bool is_const, class Iterator, class Base>
2333 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
2334  Hash, KeyEqual, Allocator>::
2336  is_const, Iterator, Base> first,
2338  is_const, Iterator, Base> last)
2339 {
2340  for (; first != last;)
2341  unlink_and_delete_element(&*((first++).iterator()));
2342 
2344  false, Iterator, Base> (first.iterator());
2345 }
2346 
2347 template <bool IsMulti, bool IsMap, class Key, class T,
2348  class Clock, class Hash, class KeyEqual, class Allocator>
2349 template <class K>
2350 auto
2351 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
2352  Hash, KeyEqual, Allocator>::
2353 erase (K const& k) ->
2354  size_type
2355 {
2356  auto iter (m_cont.find (k, std::cref (m_config.hash_function()),
2357  std::cref (m_config.key_value_equal())));
2358  if (iter == m_cont.end())
2359  return 0;
2360  size_type n (0);
2361  for (;;)
2362  {
2363  auto p (&*iter++);
2364  bool const done (
2365  m_config (*p, extract (iter->value)));
2366  unlink_and_delete_element (p);
2367  ++n;
2368  if (done)
2369  break;
2370  }
2371  return n;
2372 }
2373 
2374 template <bool IsMulti, bool IsMap, class Key, class T,
2375  class Clock, class Hash, class KeyEqual, class Allocator>
2376 void
2377 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
2378  Hash, KeyEqual, Allocator>::
2379 swap (aged_unordered_container& other) noexcept
2380 {
2381  swap_data (other);
2382  std::swap (chronological, other.chronological);
2383  std::swap (m_cont, other.m_cont);
2384 }
2385 
2386 template <bool IsMulti, bool IsMap, class Key, class T,
2387  class Clock, class Hash, class KeyEqual, class Allocator>
2388 template <class K>
2389 auto
2390 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
2391  Hash, KeyEqual, Allocator>::
2392 touch (K const& k) ->
2393  size_type
2394 {
2395  auto const now (clock().now());
2396  size_type n (0);
2397  auto const range (equal_range (k));
2398  for (auto iter : range)
2399  {
2400  touch (iter, now);
2401  ++n;
2402  }
2403  return n;
2404 }
2405 
2406 template <bool IsMulti, bool IsMap, class Key, class T,
2407  class Clock, class Hash, class KeyEqual, class Allocator>
2408 template <
2409  bool OtherIsMap,
2410  class OtherKey,
2411  class OtherT,
2412  class OtherDuration,
2413  class OtherHash,
2414  class OtherAllocator,
2415  bool maybe_multi
2416 >
2419  IsMulti, IsMap, Key, T, Clock, Hash, KeyEqual, Allocator>::
2420 operator== (
2421  aged_unordered_container <false, OtherIsMap,
2422  OtherKey, OtherT, OtherDuration, OtherHash, KeyEqual,
2423  OtherAllocator> const& other) const
2424 {
2425  if (size() != other.size())
2426  return false;
2427  for (auto iter (cbegin()), last (cend()), olast (other.cend());
2428  iter != last; ++iter)
2429  {
2430  auto oiter (other.find (extract (*iter)));
2431  if (oiter == olast)
2432  return false;
2433  }
2434  return true;
2435 }
2436 
2437 template <bool IsMulti, bool IsMap, class Key, class T,
2438  class Clock, class Hash, class KeyEqual, class Allocator>
2439 template <
2440  bool OtherIsMap,
2441  class OtherKey,
2442  class OtherT,
2443  class OtherDuration,
2444  class OtherHash,
2445  class OtherAllocator,
2446  bool maybe_multi
2447 >
2450  IsMulti, IsMap, Key, T, Clock, Hash, KeyEqual, Allocator>::
2451 operator== (
2452  aged_unordered_container <true, OtherIsMap,
2453  OtherKey, OtherT, OtherDuration, OtherHash, KeyEqual,
2454  OtherAllocator> const& other) const
2455 {
2456  if (size() != other.size())
2457  return false;
2459  for (auto iter (cbegin()), last (cend()); iter != last;)
2460  {
2461  auto const& k (extract (*iter));
2462  auto const eq (equal_range (k));
2463  auto const oeq (other.equal_range (k));
2464 #if BEAST_NO_CXX14_IS_PERMUTATION
2465  if (std::distance (eq.first, eq.second) !=
2466  std::distance (oeq.first, oeq.second) ||
2467  ! std::is_permutation (eq.first, eq.second, oeq.first))
2468  return false;
2469 #else
2470  if (! std::is_permutation (eq.first,
2471  eq.second, oeq.first, oeq.second))
2472  return false;
2473 #endif
2474  iter = eq.second;
2475  }
2476  return true;
2477 }
2478 
2479 //------------------------------------------------------------------------------
2480 
2481 // map, set
2482 template <bool IsMulti, bool IsMap, class Key, class T,
2483  class Clock, class Hash, class KeyEqual, class Allocator>
2484 template <bool maybe_multi>
2485 auto
2486 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
2487  Hash, KeyEqual, Allocator>::
2488 insert_unchecked (value_type const& value) ->
2489  typename std::enable_if <! maybe_multi,
2491 {
2492  typename cont_type::insert_commit_data d;
2493  auto const result (m_cont.insert_check (extract (value),
2494  std::cref (m_config.hash_function()),
2495  std::cref (m_config.key_value_equal()), d));
2496  if (result.second)
2497  {
2498  element* const p (new_element (value));
2499  auto const iter (m_cont.insert_commit (*p, d));
2500  chronological.list.push_back (*p);
2501  return std::make_pair (iterator (iter), true);
2502  }
2503  return std::make_pair (iterator (result.first), false);
2504 }
2505 
2506 // multimap, multiset
2507 template <bool IsMulti, bool IsMap, class Key, class T,
2508  class Clock, class Hash, class KeyEqual, class Allocator>
2509 template <bool maybe_multi>
2510 auto
2511 aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
2512  Hash, KeyEqual, Allocator>::
2513 insert_unchecked (value_type const& value) ->
2514  typename std::enable_if <maybe_multi,
2515  iterator>::type
2516 {
2517  element* const p (new_element (value));
2518  chronological.list.push_back (*p);
2519  auto const iter (m_cont.insert (*p));
2520  return iterator (iter);
2521 }
2522 
2523 //------------------------------------------------------------------------------
2524 
2525 }
2526 
2527 //------------------------------------------------------------------------------
2528 
2529 template <bool IsMulti, bool IsMap, class Key, class T,
2530  class Clock, class Hash, class KeyEqual, class Allocator>
2532  IsMulti, IsMap, Key, T, Clock, Hash, KeyEqual, Allocator>>
2533  : std::true_type
2534 {
2535  explicit is_aged_container() = default;
2536 };
2537 
2538 // Free functions
2539 
2540 template <bool IsMulti, bool IsMap, class Key, class T, class Clock,
2541  class Hash, class KeyEqual, class Allocator>
2542 void swap (
2544  Key, T, Clock, Hash, KeyEqual, Allocator>& lhs,
2546  Key, T, Clock, Hash, KeyEqual, Allocator>& rhs) noexcept
2547 {
2548  lhs.swap (rhs);
2549 }
2550 
2552 template <bool IsMulti, bool IsMap, class Key, class T,
2553  class Clock, class Hash, class KeyEqual, class Allocator,
2554  class Rep, class Period>
2556  IsMulti, IsMap, Key, T, Clock, Hash, KeyEqual, Allocator>& c,
2557  std::chrono::duration <Rep, Period> const& age) noexcept
2558 {
2559  std::size_t n (0);
2560  auto const expired (c.clock().now() - age);
2561  for (auto iter (c.chronological.cbegin());
2562  iter != c.chronological.cend() &&
2563  iter.when() <= expired;)
2564  {
2565  iter = c.erase (iter);
2566  ++n;
2567  }
2568  return n;
2569 }
2570 
2571 }
2572 
2573 #endif
beast::detail::aged_unordered_container::end
iterator end()
Definition: aged_unordered_container.h:946
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:633
beast::detail::aged_unordered_container::chronological_t::rend
reverse_iterator rend()
Definition: aged_unordered_container.h:717
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:2321
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:92
beast::detail::aged_unordered_container::KeyValueEqual::key_eq
KeyEqual & key_eq()
Definition: aged_unordered_container.h:258
beast::detail::aged_unordered_container::begin
const_local_iterator begin(size_type n) const
Definition: aged_unordered_container.h:1266
beast::detail::aged_unordered_container::config_t::config_t
config_t(clock_type &clock_)
Definition: aged_unordered_container.h:307
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:668
beast::detail::aged_unordered_container::unlink_and_delete_element
void unlink_and_delete_element(element const *p)
Definition: aged_unordered_container.h:618
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:130
std::vector::resize
T resize(T... args)
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:1111
std::binary_function
beast::detail::aged_unordered_container::rehash
void rehash(size_type count)
Definition: aged_unordered_container.h:1336
beast::detail::aged_unordered_container::max_load_factor
void max_load_factor(float ml)
Definition: aged_unordered_container.h:1330
beast::detail::aged_unordered_container::KeyValueEqual::KeyValueEqual
KeyValueEqual()
Definition: aged_unordered_container.h:218
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:288
std::true_type
beast::detail::aged_unordered_container::config_t::alloc
ElementAllocator & alloc()
Definition: aged_unordered_container.h:473
beast::detail::aged_unordered_container::config_t::config_t
config_t(config_t const &other)
Definition: aged_unordered_container.h:379
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:2292
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:97
beast::detail::aged_unordered_container::insert
std::enable_if< maybe_multi, iterator >::type insert(const_iterator, value_type &&value)
Definition: aged_unordered_container.h:1077
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:687
utility
beast::detail::aged_unordered_container::key_eq
key_equal const & key_eq() const
Definition: aged_unordered_container.h:1359
beast::detail::aged_unordered_container::config_t::value_hash
ValueHash const & value_hash() const
Definition: aged_unordered_container.h:438
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:645
beast::detail::aged_unordered_container::config_t::config_t
config_t(config_t &&other, Allocator const &alloc)
Definition: aged_unordered_container.h:407
beast::detail::aged_unordered_container::element::element
element(time_point const &when_, value_type const &value_)
Definition: aged_unordered_container.h:133
functional
beast::detail::aged_unordered_container::KeyValueEqual::key_eq
KeyEqual const & key_eq() const
Definition: aged_unordered_container.h:263
beast::detail::aged_unordered_container::insert
void insert(InputIt first, InputIt last, std::random_access_iterator_tag)
Definition: aged_unordered_container.h:1470
beast::detail::aged_unordered_container::insert_unchecked
void insert_unchecked(InputIt first, InputIt last)
Definition: aged_unordered_container.h:1453
beast::detail::aged_unordered_container::config_t::key_value_equal
KeyValueEqual & key_value_equal()
Definition: aged_unordered_container.h:453
beast::detail::aged_unordered_container::m_buck
Buckets m_buck
Definition: aged_unordered_container.h:1511
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:670
beast::detail::aged_unordered_container::chronological_t::rbegin
reverse_iterator rbegin()
Definition: aged_unordered_container.h:702
std::pair
beast::detail::aged_unordered_container::extract
static Key const & extract(value_type const &value)
Definition: aged_unordered_container.h:107
beast::detail::aged_unordered_container::chronological_t::rbegin
const_reverse_iterator rbegin() const
Definition: aged_unordered_container.h:707
beast::detail::aged_unordered_container::m_config
config_t m_config
Definition: aged_unordered_container.h:1510
beast::detail::aged_unordered_container::chronological_t::cbegin
const_iterator cbegin() const
Definition: aged_unordered_container.h:682
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::config_t::config_t
config_t(config_t const &other, Allocator const &alloc)
Definition: aged_unordered_container.h:390
beast::detail::aged_unordered_container::ValueHash
Definition: aged_unordered_container.h:166
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:313
beast::detail::aged_unordered_container::equal_range
std::pair< iterator, iterator > equal_range(K const &k)
Definition: aged_unordered_container.h:1234
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:2488
beast::detail::aged_unordered_container::reserve
void reserve(size_type count)
Definition: aged_unordered_container.h:1343
iterator
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:1503
beast::detail::aged_unordered_container::chronological_t
Definition: aged_unordered_container.h:658
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:952
beast::detail::aged_unordered_container::clock
clock_type const & clock() const
Definition: aged_unordered_container.h:880
beast::detail::aged_unordered_container::bucket
size_type bucket(Key const &k) const
Definition: aged_unordered_container.h:1306
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< 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:286
beast::detail::aged_unordered_container::config_t::config_t
config_t(clock_type &clock_, Allocator const &alloc_)
Definition: aged_unordered_container.h:329
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:1480
beast::detail::aged_unordered_container::Buckets::m_max_load_factor
float m_max_load_factor
Definition: aged_unordered_container.h:582
beast::detail::aged_unordered_container::equal_range
std::pair< const_iterator, const_iterator > equal_range(K const &k) const
Definition: aged_unordered_container.h:1246
beast::detail::aged_unordered_container::swap
void swap(aged_unordered_container &other) noexcept
Definition: aged_unordered_container.h:2379
beast::detail::empty_base_optimization< Hash >
beast::detail::aged_unordered_container::chronological_t::begin
iterator begin()
Definition: aged_unordered_container.h:672
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:635
beast::detail::aged_unordered_container::config_t::operator=
config_t & operator=(config_t const &other)
Definition: aged_unordered_container.h:415
beast::detail::aged_unordered_container::Buckets::max_bucket_count
size_type max_bucket_count() const
Definition: aged_unordered_container.h:522
cmath
beast::detail::empty_base_optimization< ElementAllocator >::member
ElementAllocator & member() noexcept
Definition: empty_base_optimization.h:48
beast::detail::aged_unordered_container::chronological_t::end
const_iterator end() const
Definition: aged_unordered_container.h:692
beast::detail::aged_unordered_container::config_t::clock
std::reference_wrapper< clock_type > clock
Definition: aged_unordered_container.h:485
std::allocator_traits
algorithm
beast::detail::aged_unordered_container::end
const_local_iterator end(size_type n) const
Definition: aged_unordered_container.h:1281
std::vector::clear
T clear(T... args)
beast::detail::aged_unordered_container::clock
clock_type & clock()
Definition: aged_unordered_container.h:875
beast::detail::aged_unordered_container::insert
void insert(InputIt first, InputIt last)
Definition: aged_unordered_container.h:1117
beast::detail::aged_unordered_container::chronological_t::rend
const_reverse_iterator rend() const
Definition: aged_unordered_container.h:722
beast::detail::aged_unordered_container::Buckets
Definition: aged_unordered_container.h:488
beast::detail::aged_associative_container_extract_t
Definition: aged_associative_container.h:30
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:1044
std::vector::capacity
T capacity(T... args)
beast::detail::aged_unordered_container::config_t::key_eq
KeyEqual & key_eq()
Definition: aged_unordered_container.h:463
beast::detail::aged_unordered_container::size
size_type size() const noexcept
Definition: aged_unordered_container.h:994
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:1155
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:367
beast::detail::aged_unordered_container::chronological_t::iterator
beast::detail::aged_container_iterator< ! IsMap, typename list_type::iterator > iterator
Definition: aged_unordered_container.h:664
beast::detail::aged_unordered_container::element::when
time_point when
Definition: aged_unordered_container.h:162
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:1185
std::reference_wrapper
beast::detail::aged_unordered_container::ValueHash::ValueHash
ValueHash(Hash const &h)
Definition: aged_unordered_container.h:182
beast::detail::aged_unordered_container::iterator_to
const_iterator iterator_to(value_type const &value) const
Definition: aged_unordered_container.h:974
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:2128
beast::detail::aged_unordered_container::empty
bool empty() const noexcept
Definition: aged_unordered_container.h:989
beast::detail::aged_unordered_container::cbegin
const_local_iterator cbegin(size_type n) const
Definition: aged_unordered_container.h:1271
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:292
beast::detail::aged_unordered_container::Buckets::rehash
void rehash(size_type count, Container &c)
Definition: aged_unordered_container.h:539
beast::detail::aged_unordered_container::iterator_to
iterator iterator_to(value_type &value)
Definition: aged_unordered_container.h:964
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:1413
std::enable_if
beast::detail::aged_unordered_container::Buckets::resize
void resize(size_type n, Container &c)
Definition: aged_unordered_container.h:574
beast::detail::aged_unordered_container::Buckets::clear
void clear()
Definition: aged_unordered_container.h:517
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:2217
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:347
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:175
beast::detail::aged_unordered_container::config_t
Definition: aged_unordered_container.h:301
beast::detail::aged_unordered_container::chronological_t::list
list_type list
Definition: aged_unordered_container.h:759
std::allocator_traits::deallocate
T deallocate(T... args)
beast::detail::aged_unordered_container::cend
const_iterator cend() const
Definition: aged_unordered_container.h:958
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:751
std::allocator_traits::destroy
T destroy(T... args)
beast::detail::aged_unordered_container::get_allocator
allocator_type get_allocator() const
Definition: aged_unordered_container.h:870
std::vector::get_allocator
T get_allocator(T... args)
beast::detail::aged_unordered_container::KeyValueEqual
Definition: aged_unordered_container.h:205
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:666
beast::detail::aged_unordered_container::max_bucket_count
size_type max_bucket_count() const
Definition: aged_unordered_container.h:1296
beast::detail::aged_unordered_container::ValueHash::ValueHash
ValueHash()
Definition: aged_unordered_container.h:178
beast::detail::aged_unordered_container::chronological_t::cend
const_iterator cend() const
Definition: aged_unordered_container.h:697
beast::detail::init
void init(ripemd160_context &ctx) noexcept
Definition: ripemd_context.h:343
beast::detail::aged_unordered_container::ValueHash::hash_function
Hash const & hash_function() const
Definition: aged_unordered_container.h:197
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:630
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:357
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:479
beast::detail::aged_unordered_container::count
size_type count(K const &k) const
Definition: aged_unordered_container.h:1205
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:1291
beast::abstract_clock< std::chrono::steady_clock >
memory
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:297
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:647
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:337
std::unary_function
beast::detail::aged_unordered_container::Buckets::m_vec
vec_type m_vec
Definition: aged_unordered_container.h:583
beast::detail::aged_unordered_container::begin
iterator begin()
Definition: aged_unordered_container.h:928
std::swap
T swap(T... args)
beast::detail::aged_unordered_container::iterator
beast::detail::aged_container_iterator<!IsMap, typename cont_type::iterator > iterator
Definition: aged_unordered_container.h:640
beast::detail::aged_unordered_container::~aged_unordered_container
~aged_unordered_container()
Definition: aged_unordered_container.h:1962
beast::detail::aged_unordered_container::cend
const_local_iterator cend(size_type n) const
Definition: aged_unordered_container.h:1286
std::equal_to
beast::detail::aged_unordered_container::chronological_t::crend
const_reverse_iterator crend() const
Definition: aged_unordered_container.h:727
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:2420
beast::detail::aged_unordered_container
Associative container where each element is also indexed by time.
Definition: aged_unordered_container.h:88
beast::detail::aged_unordered_container::chronological_t::crbegin
const_reverse_iterator crbegin() const
Definition: aged_unordered_container.h:712
beast::detail::aged_unordered_container::bucket_size
size_type bucket_size(size_type n) const
Definition: aged_unordered_container.h:1301
beast::detail::aged_unordered_container::cbegin
const_iterator cbegin() const
Definition: aged_unordered_container.h:940
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:270
beast::detail::aged_unordered_container::begin
local_iterator begin(size_type n)
Definition: aged_unordered_container.h:1261
beast::detail::aged_unordered_container::max_load_factor
float max_load_factor() const
Definition: aged_unordered_container.h:1325
beast::detail::aged_unordered_container::load_factor
float load_factor() const
Definition: aged_unordered_container.h:1319
beast::detail::aged_unordered_container::KeyValueEqual::result_type
bool result_type
Definition: aged_unordered_container.h:215
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:289
beast::detail::aged_unordered_container::m_cont
cont_type m_cont
Definition: aged_unordered_container.h:1512
beast::detail::aged_unordered_container::max_size
size_type max_size() const noexcept
Definition: aged_unordered_container.h:999
beast::detail::aged_unordered_container::config_t::value_hash
ValueHash & value_hash()
Definition: aged_unordered_container.h:433
beast::detail::aged_unordered_container::Buckets::max_load_factor
float & max_load_factor()
Definition: aged_unordered_container.h:527
beast::detail::aged_unordered_container::KeyValueEqual::first_argument_type
Key first_argument_type
Definition: aged_unordered_container.h:213
std
STL namespace.
beast::detail::aged_unordered_container::insert
void insert(InputIt first, InputIt last, std::input_iterator_tag)
Definition: aged_unordered_container.h:1461
beast::detail::aged_unordered_container::begin
const_iterator begin() const
Definition: aged_unordered_container.h:934
beast::detail::aged_unordered_container::element::stashed::value_type
typename aged_unordered_container::value_type value_type
Definition: aged_unordered_container.h:129
beast::detail::aged_unordered_container::Buckets::Buckets
Buckets()
Definition: aged_unordered_container.h:496
beast::detail::aged_unordered_container::KeyValueEqual::KeyValueEqual
KeyValueEqual(KeyEqual const &keyEqual)
Definition: aged_unordered_container.h:222
beast::detail::aged_unordered_container::element::element
element(time_point const &when_, Args &&... args)
Definition: aged_unordered_container.h:155
beast::detail::aged_unordered_container::would_exceed
bool would_exceed(size_type additional) const
Definition: aged_unordered_container.h:1423
beast::detail::aged_unordered_container::Buckets::Buckets
Buckets(Allocator const &alloc)
Definition: aged_unordered_container.h:504
beast::detail::aged_unordered_container::config_t::config_t
config_t(clock_type &clock_, KeyEqual const &keyEqual)
Definition: aged_unordered_container.h:321
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:741
beast::detail::aged_unordered_container::end
local_iterator end(size_type n)
Definition: aged_unordered_container.h:1276
beast::detail::aged_unordered_container::operator=
aged_unordered_container & operator=(aged_unordered_container const &other)
Definition: aged_unordered_container.h:1972
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:631
beast::detail::aged_unordered_container::config_t::key_eq
KeyEqual const & key_eq() const
Definition: aged_unordered_container.h:468
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:35
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:141
std::is_constructible
std::size_t
beast::detail::aged_unordered_container::element::value
value_type value
Definition: aged_unordered_container.h:161
beast::detail::aged_unordered_container::config_t::config_t
config_t(config_t &&other)
Definition: aged_unordered_container.h:398
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:1095
beast::detail::aged_unordered_container::clear
void clear()
Definition: aged_unordered_container.h:2111
std::make_pair
T make_pair(T... args)
beast::detail::aged_unordered_container::find
iterator find(K const &k)
Definition: aged_unordered_container.h:1214
beast::detail::aged_unordered_container::size_type
std::size_t size_type
Definition: aged_unordered_container.h:98
beast::detail::aged_unordered_container::element::stashed
Definition: aged_unordered_container.h:125
beast::uhash<>
beast::detail::aged_unordered_container::config_t::hash_function
Hash const & hash_function() const
Definition: aged_unordered_container.h:448
beast::detail::aged_unordered_container::ValueHash::hash_function
Hash & hash_function()
Definition: aged_unordered_container.h:192
std::conditional
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:93
beast::detail::aged_unordered_container::chronological_t::iterator_to
iterator iterator_to(value_type &value)
Definition: aged_unordered_container.h:732
beast::detail::aged_unordered_container::const_iterator
beast::detail::aged_container_iterator< true, typename cont_type::iterator > const_iterator
Definition: aged_unordered_container.h:642
beast::detail::aged_unordered_container::new_element
element * new_element(Args &&... args)
Definition: aged_unordered_container.h:587
beast::detail::aged_unordered_container::config_t::hash_function
Hash & hash_function()
Definition: aged_unordered_container.h:443
beast::detail::aged_unordered_container::operator[]
std::conditional< IsMap, T, void * >::type & operator[](Key const &key)
Definition: aged_unordered_container.h:2058
beast::detail::aged_unordered_container::maybe_rehash
void maybe_rehash(size_type additional)
Definition: aged_unordered_container.h:1430
std::unique_ptr
STL class.
beast::detail::aged_unordered_container::chronological
class beast::detail::aged_unordered_container::chronological_t chronological
beast::detail::aged_unordered_container::insert
std::enable_if<! maybe_multi, iterator >::type insert(const_iterator, value_type &&value)
Definition: aged_unordered_container.h:1066
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:1493
beast::detail::aged_unordered_container::find
const_iterator find(K const &k) const
Definition: aged_unordered_container.h:1224
beast::detail::aged_unordered_container::hash_function
hasher const & hash_function() const
Definition: aged_unordered_container.h:1354
beast::detail::aged_unordered_container::Buckets::max_load_factor
float const & max_load_factor() const
Definition: aged_unordered_container.h:532
beast::detail::aged_unordered_container::chronological_t::begin
const_iterator begin() const
Definition: aged_unordered_container.h:677
beast::abstract_clock::time_point
typename Clock::time_point time_point
Definition: abstract_clock.h:63
beast::detail::aged_unordered_container::at
std::conditional< IsMap, T, void * >::type & at(K const &k)
Definition: aged_unordered_container.h:2026
type_traits
beast::detail::aged_container_iterator
Definition: aged_container_iterator.h:48
beast::detail::aged_unordered_container::element
Definition: aged_unordered_container.h:113
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:1055
beast::detail::aged_unordered_container::delete_element
void delete_element(element const *p)
Definition: aged_unordered_container.h:611
beast::detail::aged_unordered_container::config_t::key_value_equal
KeyValueEqual const & key_value_equal() const
Definition: aged_unordered_container.h:458
std::hash
initializer_list
beast::detail::aged_unordered_container::insert
void insert(std::initializer_list< value_type > init)
Definition: aged_unordered_container.h:1125
beast
Definition: base_uint.h:582