momo  3.11
unordered_multimap.h
Go to the documentation of this file.
1 /**********************************************************\
2 
3  This file is part of the
4  https://github.com/morzhovets/momo
5  project, distributed under the MIT License. See
6  https://github.com/morzhovets/momo/blob/branch_cpp11/LICENSE
7  for details.
8 
9  momo/stdish/unordered_multimap.h
10 
11  namespace momo::stdish:
12  class unordered_multimap
13  class unordered_multimap_open
14 
15 \**********************************************************/
16 
17 #ifndef MOMO_INCLUDE_GUARD_STDISH_UNORDERED_MULTIMAP
18 #define MOMO_INCLUDE_GUARD_STDISH_UNORDERED_MULTIMAP
19 
20 #ifdef __has_include
21 # if __has_include(<momo/Utility.h>)
22 # include <momo/Utility.h>
23 # endif
24 #endif
25 #ifndef MOMO_PARENT_HEADER
26 # include "../Utility.h"
27 #endif
28 
29 #include MOMO_PARENT_HEADER(HashMultiMap)
30 #include "set_map_utility.h"
31 
32 namespace momo
33 {
34 
35 namespace stdish
36 {
37 
67 template<typename TKey, typename TMapped,
68  typename THasher = HashCoder<TKey>,
69  typename TEqualComparer = std::equal_to<TKey>,
70  typename TAllocator = std::allocator<std::pair<const TKey, TMapped>>,
71  typename THashMultiMap = HashMultiMap<TKey, TMapped, HashTraitsStd<TKey, THasher, TEqualComparer>,
72  MemManagerStd<TAllocator>>>
74 {
75 private:
76  typedef THashMultiMap HashMultiMap;
77  typedef typename HashMultiMap::HashTraits HashTraits;
78  typedef typename HashMultiMap::MemManager MemManager;
79 
80 public:
81  typedef TKey key_type;
82  typedef TMapped mapped_type;
83  typedef THasher hasher;
84  typedef TEqualComparer key_equal;
85  typedef TAllocator allocator_type;
86 
87  typedef HashMultiMap nested_container_type;
88 
89  typedef size_t size_type;
90  typedef ptrdiff_t difference_type;
91 
92  typedef std::pair<const key_type, mapped_type> value_type;
93 
97 
98  typedef typename iterator::Reference reference;
100 
101  typedef typename iterator::Pointer pointer;
103  //typedef typename std::allocator_traits<allocator_type>::pointer pointer;
104  //typedef typename std::allocator_traits<allocator_type>::const_pointer const_pointer;
105 
106  //node_type;
107 
108  //local_iterator;
109  //const_local_iterator;
110 
111 private:
112  template<typename KeyArg>
113  struct IsValidKeyArg : public HashTraits::template IsValidKeyArg<KeyArg>
114  {
115  };
116 
117  struct ConstIteratorProxy : public const_iterator
118  {
119  typedef const_iterator ConstIterator;
120  MOMO_DECLARE_PROXY_CONSTRUCTOR(ConstIterator)
121  MOMO_DECLARE_PROXY_FUNCTION(ConstIterator, GetBaseIterator)
122  };
123 
124  struct IteratorProxy : public iterator
125  {
126  typedef iterator Iterator;
128  };
129 
130 public:
132  {
133  }
134 
135  explicit unordered_multimap(const allocator_type& alloc)
136  : mHashMultiMap(HashTraits(), MemManager(alloc))
137  {
138  }
139 
140  explicit unordered_multimap(size_type bucketCount,
141  const allocator_type& alloc = allocator_type())
142  : mHashMultiMap(HashTraits(bucketCount), MemManager(alloc))
143  {
144  }
145 
146  unordered_multimap(size_type bucketCount, const hasher& hashFunc,
147  const allocator_type& alloc = allocator_type())
148  : mHashMultiMap(HashTraits(bucketCount, hashFunc), MemManager(alloc))
149  {
150  }
151 
152  unordered_multimap(size_type bucketCount, const hasher& hashFunc, const key_equal& equalComp,
153  const allocator_type& alloc = allocator_type())
154  : mHashMultiMap(HashTraits(bucketCount, hashFunc, equalComp), MemManager(alloc))
155  {
156  }
157 
158  template<typename Iterator>
159  unordered_multimap(Iterator first, Iterator last)
160  {
161  insert(first, last);
162  }
163 
164  template<typename Iterator>
165  unordered_multimap(Iterator first, Iterator last, size_type bucketCount,
166  const allocator_type& alloc = allocator_type())
167  : unordered_multimap(bucketCount, alloc)
168  {
169  insert(first, last);
170  }
171 
172  template<typename Iterator>
173  unordered_multimap(Iterator first, Iterator last, size_type bucketCount,
174  const hasher& hashFunc, const allocator_type& alloc = allocator_type())
175  : unordered_multimap(bucketCount, hashFunc, alloc)
176  {
177  insert(first, last);
178  }
179 
180  template<typename Iterator>
181  unordered_multimap(Iterator first, Iterator last, size_type bucketCount,
182  const hasher& hashFunc, const key_equal& equalComp,
183  const allocator_type& alloc = allocator_type())
184  : unordered_multimap(bucketCount, hashFunc, equalComp, alloc)
185  {
186  insert(first, last);
187  }
188 
190  : unordered_multimap(values.begin(), values.end())
191  {
192  }
193 
195  size_type bucketCount, const allocator_type& alloc = allocator_type())
196  : unordered_multimap(values.begin(), values.end(), bucketCount, alloc)
197  {
198  }
199 
201  size_type bucketCount, const hasher& hashFunc, const allocator_type& alloc = allocator_type())
202  : unordered_multimap(values.begin(), values.end(), bucketCount, hashFunc, alloc)
203  {
204  }
205 
207  size_type bucketCount, const hasher& hashFunc, const key_equal& equalComp,
208  const allocator_type& alloc = allocator_type())
209  : unordered_multimap(values.begin(), values.end(), bucketCount, hashFunc, equalComp, alloc)
210  {
211  }
212 
213 #ifdef MOMO_HAS_CONTAINERS_RANGES
214  template<std::ranges::input_range Range>
215  requires std::convertible_to<std::ranges::range_reference_t<Range>, value_type>
216  unordered_multimap(std::from_range_t, Range&& values)
217  {
218  insert_range(std::forward<Range>(values));
219  }
220 
221  template<std::ranges::input_range Range>
222  requires std::convertible_to<std::ranges::range_reference_t<Range>, value_type>
223  unordered_multimap(std::from_range_t, Range&& values, size_type bucketCount,
224  const allocator_type& alloc = allocator_type())
225  : unordered_multimap(bucketCount, alloc)
226  {
227  insert_range(std::forward<Range>(values));
228  }
229 
230  template<std::ranges::input_range Range>
231  requires std::convertible_to<std::ranges::range_reference_t<Range>, value_type>
232  unordered_multimap(std::from_range_t, Range&& values, size_type bucketCount,
233  const hasher& hashFunc, const allocator_type& alloc = allocator_type())
234  : unordered_multimap(bucketCount, hashFunc, alloc)
235  {
236  insert_range(std::forward<Range>(values));
237  }
238 
239  template<std::ranges::input_range Range>
240  requires std::convertible_to<std::ranges::range_reference_t<Range>, value_type>
241  unordered_multimap(std::from_range_t, Range&& values, size_type bucketCount,
242  const hasher& hashFunc, const key_equal& equalComp,
243  const allocator_type& alloc = allocator_type())
244  : unordered_multimap(bucketCount, hashFunc, equalComp, alloc)
245  {
246  insert_range(std::forward<Range>(values));
247  }
248 #endif // MOMO_HAS_CONTAINERS_RANGES
249 
251  : unordered_multimap(std::move(right), right.get_allocator())
252  {
253  }
254 
257  : mHashMultiMap(right.mHashMultiMap.GetHashTraits(), MemManager(alloc))
258  {
259  if (right.get_allocator() == alloc)
260  {
261  mHashMultiMap.Swap(right.mHashMultiMap);
262  }
263  else
264  {
265  for (reference ref : right)
266  mHashMultiMap.Add(ref.first, std::move(ref.second));
267  right.clear();
268  }
269  }
270 
272  : mHashMultiMap(right.mHashMultiMap)
273  {
274  }
275 
278  : mHashMultiMap(right.mHashMultiMap, MemManager(alloc))
279  {
280  }
281 
282  ~unordered_multimap() = default;
283 
286  {
287  return momo::internal::ContainerAssignerStd::Move(std::move(right), *this);
288  }
289 
291  {
292  return momo::internal::ContainerAssignerStd::Copy(right, *this);
293  }
294 
295  unordered_multimap& operator=(std::initializer_list<value_type> values)
296  {
297  mHashMultiMap = HashMultiMap(values, mHashMultiMap.GetHashTraits(), MemManager(get_allocator()));
298  return *this;
299  }
300 
301  void swap(unordered_multimap& right) noexcept
302  {
304  }
305 
306  friend void swap(unordered_multimap& left, unordered_multimap& right) noexcept
307  {
308  left.swap(right);
309  }
310 
312  {
313  return mHashMultiMap;
314  }
315 
317  {
318  return mHashMultiMap;
319  }
320 
321  const_iterator begin() const noexcept
322  {
323  return ConstIteratorProxy(mHashMultiMap.GetBegin());
324  }
325 
326  iterator begin() noexcept
327  {
328  return IteratorProxy(mHashMultiMap.GetBegin());
329  }
330 
331  const_iterator end() const noexcept
332  {
333  return ConstIteratorProxy(mHashMultiMap.GetEnd());
334  }
335 
336  iterator end() noexcept
337  {
338  return IteratorProxy(mHashMultiMap.GetEnd());
339  }
340 
341  const_iterator cbegin() const noexcept
342  {
343  return begin();
344  }
345 
346  const_iterator cend() const noexcept
347  {
348  return end();
349  }
350 
351  //float max_load_factor() const noexcept
352  //void max_load_factor(float maxLoadFactor)
353 
355  {
356  return mHashMultiMap.GetHashTraits().GetHasher();
357  }
358 
360  {
361  return mHashMultiMap.GetHashTraits().GetEqualComparer();
362  }
363 
364  allocator_type get_allocator() const noexcept
365  {
366  return allocator_type(mHashMultiMap.GetMemManager().GetByteAllocator());
367  }
368 
369  size_type max_size() const noexcept
370  {
371  return std::allocator_traits<allocator_type>::max_size(get_allocator());
372  }
373 
374  size_type size() const noexcept
375  {
376  return mHashMultiMap.GetCount();
377  }
378 
379  MOMO_NODISCARD bool empty() const noexcept
380  {
381  return mHashMultiMap.IsEmpty();
382  }
383 
384  void clear() noexcept
385  {
386  mHashMultiMap.Clear();
387  }
388 
389  //void rehash(size_type bucketCount)
390  //void reserve(size_type count)
391 
393  {
394  return equal_range(key).first;
395  }
396 
398  {
399  return equal_range(key).first;
400  }
401 
402  template<typename KeyArg>
404  const_iterator> find(const KeyArg& key) const
405  {
406  return equal_range(key).first;
407  }
408 
409  template<typename KeyArg>
411  iterator> find(const KeyArg& key)
412  {
413  return equal_range(key).first;
414  }
415 
417  {
418  typename HashMultiMap::ConstKeyIterator keyIter = mHashMultiMap.Find(key);
419  return !!keyIter ? keyIter->GetCount() : 0;
420  }
421 
422  template<typename KeyArg>
424  size_type> count(const KeyArg& key) const
425  {
426  typename HashMultiMap::ConstKeyIterator keyIter = mHashMultiMap.Find(key);
427  return !!keyIter ? keyIter->GetCount() : 0;
428  }
429 
430  MOMO_FORCEINLINE bool contains(const key_type& key) const
431  {
432  return count(key) > 0;
433  }
434 
435  template<typename KeyArg>
437  bool> contains(const KeyArg& key) const
438  {
439  return count(key) > 0;
440  }
441 
442  MOMO_FORCEINLINE std::pair<const_iterator, const_iterator> equal_range(const key_type& key) const
443  {
444  return pvEqualRange<const_iterator, ConstIteratorProxy>(mHashMultiMap,
445  mHashMultiMap.Find(key));
446  }
447 
448  MOMO_FORCEINLINE std::pair<iterator, iterator> equal_range(const key_type& key)
449  {
450  return pvEqualRange<iterator, IteratorProxy>(mHashMultiMap, mHashMultiMap.Find(key));
451  }
452 
453  template<typename KeyArg>
455  std::pair<const_iterator, const_iterator>> equal_range(const KeyArg& key) const
456  {
457  return pvEqualRange<const_iterator, ConstIteratorProxy>(mHashMultiMap,
458  mHashMultiMap.Find(key));
459  }
460 
461  template<typename KeyArg>
463  std::pair<iterator, iterator>> equal_range(const KeyArg& key)
464  {
465  return pvEqualRange<iterator, IteratorProxy>(mHashMultiMap, mHashMultiMap.Find(key));
466  }
467 
468  template<typename ValueArg = std::pair<key_type, mapped_type>>
470  iterator> insert(ValueArg&& valueArg)
471  {
472  return emplace(std::forward<ValueArg>(valueArg));
473  }
474 
475  template<typename ValueArg = std::pair<key_type, mapped_type>>
477  iterator> insert(const_iterator, ValueArg&& valueArg)
478  {
479  return insert(std::forward<ValueArg>(valueArg));
480  }
481 
482  template<typename Iterator>
483  void insert(Iterator first, Iterator last)
484  {
485  pvInsertRange(first, last);
486  }
487 
488  void insert(std::initializer_list<value_type> values)
489  {
490  mHashMultiMap.Add(values.begin(), values.end());
491  }
492 
493 #ifdef MOMO_HAS_CONTAINERS_RANGES
494  template<std::ranges::input_range Range>
495  requires std::convertible_to<std::ranges::range_reference_t<Range>, value_type>
496  void insert_range(Range&& values)
497  {
498  pvInsertRange(std::ranges::begin(values), std::ranges::end(values));
499  }
500 #endif // MOMO_HAS_CONTAINERS_RANGES
501 
503  {
504  return pvEmplace(std::tuple<>(), std::tuple<>());
505  }
506 
508  {
509  return emplace();
510  }
511 
512  template<typename ValueArg>
513  iterator emplace(ValueArg&& valueArg)
514  {
515  return pvEmplace(std::forward_as_tuple(std::get<0>(std::forward<ValueArg>(valueArg))),
516  std::forward_as_tuple(std::get<1>(std::forward<ValueArg>(valueArg))));
517  }
518 
519  template<typename ValueArg>
520  iterator emplace_hint(const_iterator, ValueArg&& valueArg)
521  {
522  return emplace(std::forward<ValueArg>(valueArg));
523  }
524 
525  template<typename KeyArg, typename MappedArg>
526  iterator emplace(KeyArg&& keyArg, MappedArg&& mappedArg)
527  {
528  return pvEmplace(std::forward_as_tuple(std::forward<KeyArg>(keyArg)),
529  std::forward_as_tuple(std::forward<MappedArg>(mappedArg)));
530  }
531 
532  template<typename KeyArg, typename MappedArg>
533  iterator emplace_hint(const_iterator, KeyArg&& keyArg, MappedArg&& mappedArg)
534  {
535  return emplace(std::forward<KeyArg>(keyArg), std::forward<MappedArg>(mappedArg));
536  }
537 
538  template<typename... KeyArgs, typename... MappedArgs>
539  iterator emplace(std::piecewise_construct_t,
540  std::tuple<KeyArgs...> keyArgs, std::tuple<MappedArgs...> mappedArgs)
541  {
542  return pvEmplace(std::move(keyArgs), std::move(mappedArgs));
543  }
544 
545  template<typename... KeyArgs, typename... MappedArgs>
546  iterator emplace_hint(const_iterator, std::piecewise_construct_t,
547  std::tuple<KeyArgs...> keyArgs, std::tuple<MappedArgs...> mappedArgs)
548  {
549  return pvEmplace(std::move(keyArgs), std::move(mappedArgs));
550  }
551 
553  {
554  typename HashMultiMap::ConstIterator iter = ConstIteratorProxy::GetBaseIterator(where);
555  typename HashMultiMap::ConstKeyIterator keyIter = iter.GetKeyIterator();
556  if (keyIter->GetCount() == 1)
557  return IteratorProxy(mHashMultiMap.MakeIterator(mHashMultiMap.RemoveKey(keyIter)));
558  else
559  return IteratorProxy(mHashMultiMap.Remove(iter));
560  }
561 
563  {
564  return erase(static_cast<const_iterator>(where));
565  }
566 
568  {
569  if (first == begin() && last == end())
570  {
571  clear();
572  return end();
573  }
574  if (first == last)
575  {
576  return IteratorProxy(mHashMultiMap.MakeMutableIterator(
577  ConstIteratorProxy::GetBaseIterator(first)));
578  }
579  if (first != end())
580  {
581  if (std::next(first) == last)
582  return erase(first);
583  typename HashMultiMap::ConstKeyIterator keyIter =
584  ConstIteratorProxy::GetBaseIterator(first).GetKeyIterator();
585  if (last == ConstIteratorProxy(mHashMultiMap.MakeIterator(keyIter, keyIter->GetCount())))
586  return IteratorProxy(mHashMultiMap.MakeIterator(mHashMultiMap.RemoveKey(keyIter)));
587  }
588  throw std::invalid_argument("invalid unordered_multimap erase arguments");
589  }
590 
592  {
593  return mHashMultiMap.RemoveKey(key);
594  }
595 
596  template<typename ValueFilter>
597  friend size_type erase_if(unordered_multimap& cont, const ValueFilter& valueFilter)
598  {
599  auto pairFilter = [&valueFilter] (const key_type& key, const mapped_type& mapped)
600  { return valueFilter(const_reference(key, mapped)); };
601  return cont.mHashMultiMap.Remove(pairFilter);
602  }
603 
604  //iterator insert(node_type&& node)
605  //iterator insert(const_iterator, node_type&& node)
606  //node_type extract(const_iterator where)
607  //node_type extract(const key_type& key)
608  //void merge(...)
609 
610  //size_type max_bucket_count() const noexcept
611  //size_type bucket_count() const noexcept
612  //size_type bucket_size(size_type bucketIndex) const
613  //local_iterator begin(size_type bucketIndex)
614  //const_local_iterator begin(size_type bucketIndex) const
615  //local_iterator end(size_type bucketIndex)
616  //const_local_iterator end(size_type bucketIndex) const
617  //const_local_iterator cbegin(size_type bucketIndex) const
618  //const_local_iterator cend(size_type bucketIndex) const
619  //size_type bucket(const key_type& key) const
620  //float load_factor() const noexcept
621 
622  friend bool operator==(const unordered_multimap& left, const unordered_multimap& right)
623  {
624  if (left.mHashMultiMap.GetKeyCount() != right.mHashMultiMap.GetKeyCount())
625  return false;
626  if (left.mHashMultiMap.GetCount() != right.mHashMultiMap.GetCount())
627  return false;
628  typedef typename HashMultiMap::ConstKeyIterator ConstKeyIterator;
629  for (typename ConstKeyIterator::Reference ref : left.mHashMultiMap.GetKeyBounds())
630  {
631  if (ref.GetCount() == 0)
632  continue;
633  ConstKeyIterator rightKeyIter = right.mHashMultiMap.Find(ref.key);
634  if (!rightKeyIter)
635  return false;
636  if (ref.GetCount() != rightKeyIter->GetCount())
637  return false;
638  if (!std::is_permutation(ref.GetBegin(), ref.GetEnd(), rightKeyIter->GetBegin()))
639  return false;
640  }
641  return true;
642  }
643 
644  friend bool operator!=(const unordered_multimap& left, const unordered_multimap& right)
645  {
646  return !(left == right);
647  }
648 
649 private:
650  template<typename Iterator, typename IteratorProxy, typename HashMultiMap, typename KeyIterator>
651  static std::pair<Iterator, Iterator> pvEqualRange(HashMultiMap& hashMultiMap,
652  KeyIterator keyIter)
653  {
654  Iterator end = IteratorProxy(hashMultiMap.GetEnd());
655  if (!keyIter)
656  return { end, end };
657  size_t count = keyIter->GetCount();
658  if (count == 0)
659  return { end, end };
660  Iterator first = IteratorProxy(hashMultiMap.MakeIterator(keyIter, 0));
661  Iterator last = IteratorProxy(hashMultiMap.MakeIterator(keyIter, count));
662  return { first, last };
663  }
664 
665  template<typename... KeyArgs, typename... MappedArgs>
666  iterator pvEmplace(std::tuple<KeyArgs...>&& keyArgs, std::tuple<MappedArgs...>&& mappedArgs)
667  {
668  typedef typename HashMultiMap::KeyValueTraits
669  ::template ValueCreator<MappedArgs...> MappedCreator;
670  return pvInsert(std::move(keyArgs),
671  MappedCreator(mHashMultiMap.GetMemManager(), std::move(mappedArgs)));
672  }
673 
674  template<typename... KeyArgs, typename MappedCreator>
675  iterator pvInsert(std::tuple<KeyArgs...>&& keyArgs, MappedCreator&& mappedCreator)
676  {
677  MemManager& memManager = mHashMultiMap.GetMemManager();
680  typedef typename KeyManager::template Creator<KeyArgs...> KeyCreator;
681  KeyBuffer keyBuffer;
682  KeyCreator(memManager, std::move(keyArgs))(keyBuffer.GetPtr());
683  iterator resIter;
684  try
685  {
686  resIter = pvInsert(std::forward_as_tuple(std::move(keyBuffer.Get())),
687  std::forward<MappedCreator>(mappedCreator));
688  }
689  catch (...)
690  {
691  KeyManager::Destroy(memManager, keyBuffer.Get());
692  throw;
693  }
694  KeyManager::Destroy(memManager, keyBuffer.Get());
695  return resIter;
696  }
697 
698  template<typename RKey, typename MappedCreator,
699  typename Key = typename std::decay<RKey>::type>
701  iterator> pvInsert(std::tuple<RKey>&& key, MappedCreator&& mappedCreator)
702  {
703  return IteratorProxy(mHashMultiMap.AddCrt(
704  std::forward<RKey>(std::get<0>(key)), std::forward<MappedCreator>(mappedCreator)));
705  }
706 
707  template<typename Iterator, typename Sentinel>
709  void> pvInsertRange(Iterator begin, Sentinel end)
710  {
711  mHashMultiMap.Add(std::move(begin), std::move(end));
712  }
713 
714  template<typename Iterator, typename Sentinel>
716  void> pvInsertRange(Iterator begin, Sentinel end)
717  {
718  for (Iterator iter = std::move(begin); iter != end; ++iter)
719  insert(*iter);
720  }
721 
722 private:
723  HashMultiMap mHashMultiMap;
724 };
725 
735 template<typename TKey, typename TMapped,
736  typename THasher = HashCoder<TKey>,
737  typename TEqualComparer = std::equal_to<TKey>,
738  typename TAllocator = std::allocator<std::pair<const TKey, TMapped>>>
739 class unordered_multimap_open : public unordered_multimap<TKey, TMapped, THasher, TEqualComparer, TAllocator,
740  HashMultiMap<TKey, TMapped, HashTraitsStd<TKey, THasher, TEqualComparer, HashBucketOpenDefault>,
741  MemManagerStd<TAllocator>>>
742 {
743 private:
744  typedef unordered_multimap<TKey, TMapped, THasher, TEqualComparer, TAllocator,
747 
748 public:
749  using typename UnorderedMultiMap::key_type;
750  using typename UnorderedMultiMap::mapped_type;
751  using typename UnorderedMultiMap::size_type;
752  using typename UnorderedMultiMap::value_type;
753  using typename UnorderedMultiMap::const_reference;
754 
755 public:
756  using UnorderedMultiMap::UnorderedMultiMap;
757 
758  unordered_multimap_open& operator=(std::initializer_list<value_type> values)
759  {
761  return *this;
762  }
763 
764  friend void swap(unordered_multimap_open& left, unordered_multimap_open& right) noexcept
765  {
766  left.swap(right);
767  }
768 
769  template<typename ValueFilter>
770  friend size_type erase_if(unordered_multimap_open& cont, const ValueFilter& valueFilter)
771  {
772  auto pairFilter = [&valueFilter] (const key_type& key, const mapped_type& mapped)
773  { return valueFilter(const_reference(key, mapped)); };
774  return cont.get_nested_container().Remove(pairFilter);
775  }
776 };
777 
778 #ifdef MOMO_HAS_DEDUCTION_GUIDES
779 
780 #define MOMO_DECLARE_DEDUCTION_GUIDES(unordered_multimap) \
781 template<typename Iterator, \
782  typename Value = typename std::iterator_traits<Iterator>::value_type, \
783  typename Key = std::decay_t<typename Value::first_type>, \
784  typename Mapped = std::decay_t<typename Value::second_type>> \
785 unordered_multimap(Iterator, Iterator) \
786  -> unordered_multimap<Key, Mapped>; \
787 template<typename Iterator, \
788  typename Value = typename std::iterator_traits<Iterator>::value_type, \
789  typename Key = std::decay_t<typename Value::first_type>, \
790  typename Mapped = std::decay_t<typename Value::second_type>, \
791  typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
792  typename = internal::unordered_checker<Key, Allocator, HashCoder<Key>>> \
793 unordered_multimap(Iterator, Iterator, size_t, Allocator = Allocator()) \
794  -> unordered_multimap<Key, Mapped, HashCoder<Key>, std::equal_to<Key>, Allocator>; \
795 template<typename Iterator, typename Hasher, \
796  typename Value = typename std::iterator_traits<Iterator>::value_type, \
797  typename Key = std::decay_t<typename Value::first_type>, \
798  typename Mapped = std::decay_t<typename Value::second_type>, \
799  typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
800  typename = internal::unordered_checker<Key, Allocator, Hasher>> \
801 unordered_multimap(Iterator, Iterator, size_t, Hasher, Allocator = Allocator()) \
802  -> unordered_multimap<Key, Mapped, Hasher, std::equal_to<Key>, Allocator>; \
803 template<typename Iterator, typename Hasher, typename EqualComparer, \
804  typename Value = typename std::iterator_traits<Iterator>::value_type, \
805  typename Key = std::decay_t<typename Value::first_type>, \
806  typename Mapped = std::decay_t<typename Value::second_type>, \
807  typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
808  typename = internal::unordered_checker<Key, Allocator, Hasher, EqualComparer>> \
809 unordered_multimap(Iterator, Iterator, size_t, Hasher, EqualComparer, Allocator = Allocator()) \
810  -> unordered_multimap<Key, Mapped, Hasher, EqualComparer, Allocator>; \
811 template<typename QKey, typename Mapped, \
812  typename Key = std::remove_const_t<QKey>> \
813 unordered_multimap(std::initializer_list<std::pair<QKey, Mapped>>) \
814  -> unordered_multimap<Key, Mapped>; \
815 template<typename QKey, typename Mapped, \
816  typename Key = std::remove_const_t<QKey>, \
817  typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
818  typename = internal::unordered_checker<Key, Allocator, HashCoder<Key>>> \
819 unordered_multimap(std::initializer_list<std::pair<QKey, Mapped>>, size_t, Allocator = Allocator()) \
820  -> unordered_multimap<Key, Mapped, HashCoder<Key>, std::equal_to<Key>, Allocator>; \
821 template<typename QKey, typename Mapped, typename Hasher, \
822  typename Key = std::remove_const_t<QKey>, \
823  typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
824  typename = internal::unordered_checker<Key, Allocator, Hasher>> \
825 unordered_multimap(std::initializer_list<std::pair<QKey, Mapped>>, size_t, Hasher, Allocator = Allocator()) \
826  -> unordered_multimap<Key, Mapped, Hasher, std::equal_to<Key>, Allocator>; \
827 template<typename QKey, typename Mapped, typename Hasher, typename EqualComparer, \
828  typename Key = std::remove_const_t<QKey>, \
829  typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
830  typename = internal::unordered_checker<Key, Allocator, Hasher, EqualComparer>> \
831 unordered_multimap(std::initializer_list<std::pair<QKey, Mapped>>, size_t, Hasher, EqualComparer, Allocator = Allocator()) \
832  -> unordered_multimap<Key, Mapped, Hasher, EqualComparer, Allocator>;
833 
834 MOMO_DECLARE_DEDUCTION_GUIDES(unordered_multimap)
835 MOMO_DECLARE_DEDUCTION_GUIDES(unordered_multimap_open)
836 
837 #undef MOMO_DECLARE_DEDUCTION_GUIDES
838 
839 #ifdef MOMO_HAS_CONTAINERS_RANGES
840 
841 #define MOMO_DECLARE_DEDUCTION_GUIDES_RANGES(unordered_multimap) \
842 template<std::ranges::input_range Range, \
843  typename Value = std::ranges::range_value_t<Range>, \
844  typename Key = std::decay_t<typename Value::first_type>, \
845  typename Mapped = std::decay_t<typename Value::second_type>> \
846 unordered_multimap(std::from_range_t, Range&&) \
847  -> unordered_multimap<Key, Mapped>; \
848 template<std::ranges::input_range Range, \
849  typename Value = std::ranges::range_value_t<Range>, \
850  typename Key = std::decay_t<typename Value::first_type>, \
851  typename Mapped = std::decay_t<typename Value::second_type>, \
852  typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
853  typename = internal::unordered_checker<Key, Allocator, HashCoder<Key>>> \
854 unordered_multimap(std::from_range_t, Range&&, size_t, Allocator = Allocator()) \
855  -> unordered_multimap<Key, Mapped, HashCoder<Key>, std::equal_to<Key>, Allocator>; \
856 template<std::ranges::input_range Range, typename Hasher, \
857  typename Value = std::ranges::range_value_t<Range>, \
858  typename Key = std::decay_t<typename Value::first_type>, \
859  typename Mapped = std::decay_t<typename Value::second_type>, \
860  typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
861  typename = internal::unordered_checker<Key, Allocator, Hasher>> \
862 unordered_multimap(std::from_range_t, Range&&, size_t, Hasher, Allocator = Allocator()) \
863  -> unordered_multimap<Key, Mapped, Hasher, std::equal_to<Key>, Allocator>; \
864 template<std::ranges::input_range Range, typename Hasher, typename EqualComparer, \
865  typename Value = std::ranges::range_value_t<Range>, \
866  typename Key = std::decay_t<typename Value::first_type>, \
867  typename Mapped = std::decay_t<typename Value::second_type>, \
868  typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
869  typename = internal::unordered_checker<Key, Allocator, Hasher, EqualComparer>> \
870 unordered_multimap(std::from_range_t, Range&&, size_t, Hasher, EqualComparer, Allocator = Allocator()) \
871  -> unordered_multimap<Key, Mapped, Hasher, EqualComparer, Allocator>;
872 
873 MOMO_DECLARE_DEDUCTION_GUIDES_RANGES(unordered_multimap)
874 MOMO_DECLARE_DEDUCTION_GUIDES_RANGES(unordered_multimap_open)
875 
876 #undef MOMO_DECLARE_DEDUCTION_GUIDES_RANGES
877 
878 #endif // MOMO_HAS_CONTAINERS_RANGES
879 
880 #endif // MOMO_HAS_DEDUCTION_GUIDES
881 
882 } // namespace stdish
883 
884 } // namespace momo
885 
886 #endif // MOMO_INCLUDE_GUARD_STDISH_UNORDERED_MULTIMAP
momo::stdish::unordered_multimap::swap
friend void swap(unordered_multimap &left, unordered_multimap &right) noexcept
Definition: unordered_multimap.h:306
momo::stdish::unordered_multimap_open::mapped_type
TMapped mapped_type
Definition: unordered_multimap.h:82
momo::internal::ObjectManager
Definition: ObjectManager.h:240
momo::stdish::unordered_multimap::unordered_multimap
unordered_multimap(size_type bucketCount, const allocator_type &alloc=allocator_type())
Definition: unordered_multimap.h:140
momo::HashMultiMap::Iterator
internal::HashMultiMapIterator< KeyIterator, Settings > Iterator
Definition: HashMultiMap.h:674
momo::stdish::unordered_multimap::emplace
iterator emplace(KeyArg &&keyArg, MappedArg &&mappedArg)
Definition: unordered_multimap.h:526
momo::internal::HashMultiMapIterator
Definition: HashMultiMap.h:182
momo::stdish::unordered_multimap::const_reference
const_iterator::Reference const_reference
Definition: unordered_multimap.h:99
momo::stdish::unordered_multimap::emplace_hint
iterator emplace_hint(const_iterator, ValueArg &&valueArg)
Definition: unordered_multimap.h:520
momo::HashMultiMap::MakeIterator
ConstIterator MakeIterator(ConstKeyIterator keyIter, size_t valueIndex=0) const
Definition: HashMultiMap.h:1132
momo::internal::HashDerivedIterator::Reference
TReference< typename BaseIterator::Reference > Reference
Definition: IteratorUtility.h:381
momo::stdish::unordered_multimap::erase
size_type erase(const key_type &key)
Definition: unordered_multimap.h:591
momo::stdish::unordered_multimap::swap
void swap(unordered_multimap &right) noexcept
Definition: unordered_multimap.h:301
momo::stdish::unordered_multimap::cbegin
const_iterator cbegin() const noexcept
Definition: unordered_multimap.h:341
momo::stdish::unordered_multimap::erase
iterator erase(iterator where)
Definition: unordered_multimap.h:562
momo::stdish::unordered_multimap::mapped_type
TMapped mapped_type
Definition: unordered_multimap.h:82
momo::stdish::unordered_multimap::difference_type
ptrdiff_t difference_type
Definition: unordered_multimap.h:90
momo::HashMultiMap::HashTraits
THashTraits HashTraits
Definition: HashMultiMap.h:564
momo::stdish::unordered_multimap::unordered_multimap
unordered_multimap(unordered_multimap &&right, const momo::internal::Identity< allocator_type > &alloc)
Definition: unordered_multimap.h:255
momo::stdish::unordered_multimap::unordered_multimap
unordered_multimap(Iterator first, Iterator last, size_type bucketCount, const hasher &hashFunc, const allocator_type &alloc=allocator_type())
Definition: unordered_multimap.h:173
momo::stdish::unordered_multimap_open::size_type
size_t size_type
Definition: unordered_multimap.h:89
momo::stdish::unordered_multimap::equal_range
MOMO_FORCEINLINE std::pair< const_iterator, const_iterator > equal_range(const key_type &key) const
Definition: unordered_multimap.h:442
set_map_utility.h
momo::stdish::unordered_multimap::pointer
iterator::Pointer pointer
Definition: unordered_multimap.h:101
momo::stdish::unordered_multimap::operator!=
friend bool operator!=(const unordered_multimap &left, const unordered_multimap &right)
Definition: unordered_multimap.h:644
momo::stdish::unordered_multimap::operator=
unordered_multimap & operator=(const unordered_multimap &right)
Definition: unordered_multimap.h:290
momo::stdish::unordered_multimap::unordered_multimap
unordered_multimap(std::initializer_list< momo::internal::Identity< value_type >> values, size_type bucketCount, const hasher &hashFunc, const allocator_type &alloc=allocator_type())
Definition: unordered_multimap.h:200
momo::stdish::unordered_multimap::insert
momo::internal::EnableIf< std::is_constructible< value_type, ValueArg && >::value, iterator > insert(const_iterator, ValueArg &&valueArg)
Definition: unordered_multimap.h:477
momo::stdish::unordered_multimap::erase
iterator erase(const_iterator first, const_iterator last)
Definition: unordered_multimap.h:567
momo::stdish::unordered_multimap_open::key_type
TKey key_type
Definition: unordered_multimap.h:81
momo::stdish::unordered_multimap::unordered_multimap
unordered_multimap(const unordered_multimap &right)
Definition: unordered_multimap.h:271
momo::stdish::unordered_multimap
momo::stdish::unordered_multimap is similar to std::unordered_multimap, but much more efficient in me...
Definition: unordered_multimap.h:74
momo::stdish::unordered_multimap::unordered_multimap
unordered_multimap()
Definition: unordered_multimap.h:131
momo::stdish::unordered_multimap::contains
MOMO_FORCEINLINE momo::internal::EnableIf< IsValidKeyArg< KeyArg >::value, bool > contains(const KeyArg &key) const
Definition: unordered_multimap.h:437
momo::stdish::unordered_multimap::unordered_multimap
unordered_multimap(Iterator first, Iterator last, size_type bucketCount, const hasher &hashFunc, const key_equal &equalComp, const allocator_type &alloc=allocator_type())
Definition: unordered_multimap.h:181
momo::stdish::unordered_multimap::contains
MOMO_FORCEINLINE bool contains(const key_type &key) const
Definition: unordered_multimap.h:430
momo::stdish::unordered_multimap::count
MOMO_FORCEINLINE size_type count(const key_type &key) const
Definition: unordered_multimap.h:416
momo::internal::HashMultiMapIterator::GetKeyIterator
KeyIterator GetKeyIterator() const noexcept
Definition: HashMultiMap.h:249
momo::stdish::unordered_multimap_open::const_reference
const_iterator::Reference const_reference
Definition: unordered_multimap.h:99
momo::MemManagerStd
MemManagerStd uses allocator<unsigned char>::allocate and deallocate
Definition: MemManager.h:177
momo::stdish::unordered_multimap::insert
void insert(std::initializer_list< value_type > values)
Definition: unordered_multimap.h:488
momo::stdish::unordered_multimap::size
size_type size() const noexcept
Definition: unordered_multimap.h:374
momo::stdish::unordered_multimap::~unordered_multimap
~unordered_multimap()=default
momo::stdish::unordered_multimap::operator=
unordered_multimap & operator=(std::initializer_list< value_type > values)
Definition: unordered_multimap.h:295
momo::stdish::unordered_multimap::unordered_multimap
unordered_multimap(std::initializer_list< momo::internal::Identity< value_type >> values)
Definition: unordered_multimap.h:189
momo::internal::ContainerAssignerStd::Move
static Container & Move(Container &&srcCont, Container &dstCont) noexcept(IsNothrowMoveAssignable< Container >::value)
Definition: Utility.h:496
momo::stdish::unordered_multimap::const_pointer
const_iterator::Pointer const_pointer
Definition: unordered_multimap.h:102
momo::stdish::unordered_multimap::insert
void insert(Iterator first, Iterator last)
Definition: unordered_multimap.h:483
momo::stdish::unordered_multimap::insert
momo::internal::EnableIf< std::is_constructible< value_type, ValueArg && >::value, iterator > insert(ValueArg &&valueArg)
Definition: unordered_multimap.h:470
momo::stdish::unordered_multimap::erase_if
friend size_type erase_if(unordered_multimap &cont, const ValueFilter &valueFilter)
Definition: unordered_multimap.h:597
momo::stdish::unordered_multimap::count
MOMO_FORCEINLINE momo::internal::EnableIf< IsValidKeyArg< KeyArg >::value, size_type > count(const KeyArg &key) const
Definition: unordered_multimap.h:424
momo::stdish::unordered_multimap::equal_range
MOMO_FORCEINLINE momo::internal::EnableIf< IsValidKeyArg< KeyArg >::value, std::pair< const_iterator, const_iterator > > equal_range(const KeyArg &key) const
Definition: unordered_multimap.h:455
momo::stdish::unordered_multimap::unordered_multimap
unordered_multimap(unordered_multimap &&right)
Definition: unordered_multimap.h:250
momo::internal::EnableIf
typename std::enable_if< value, Type >::type EnableIf
Definition: Utility.h:209
momo::stdish::unordered_multimap::iterator
momo::internal::HashDerivedIterator< typename HashMultiMap::Iterator, momo::internal::MapReferenceStd > iterator
Definition: unordered_multimap.h:95
momo::stdish::unordered_multimap::emplace_hint
iterator emplace_hint(const_iterator, std::piecewise_construct_t, std::tuple< KeyArgs... > keyArgs, std::tuple< MappedArgs... > mappedArgs)
Definition: unordered_multimap.h:546
momo::stdish::unordered_multimap_open
momo::stdish::unordered_multimap_open is similar to std::unordered_multimap, but much more efficient ...
Definition: unordered_multimap.h:742
momo
Definition: Array.h:26
momo::stdish::unordered_multimap::cend
const_iterator cend() const noexcept
Definition: unordered_multimap.h:346
momo::stdish::unordered_multimap_open::swap
friend void swap(unordered_multimap_open &left, unordered_multimap_open &right) noexcept
Definition: unordered_multimap.h:764
momo::internal::ContainerAssignerStd::IsNothrowMoveAssignable
BoolConstant< std::is_empty< Allocator >::value||std::allocator_traits< Allocator >::propagate_on_container_move_assignment::value > IsNothrowMoveAssignable
Definition: Utility.h:492
momo::stdish::unordered_multimap::erase
iterator erase(const_iterator where)
Definition: unordered_multimap.h:552
momo::stdish::unordered_multimap::find
MOMO_FORCEINLINE momo::internal::EnableIf< IsValidKeyArg< KeyArg >::value, iterator > find(const KeyArg &key)
Definition: unordered_multimap.h:411
momo::stdish::unordered_multimap::emplace
iterator emplace(std::piecewise_construct_t, std::tuple< KeyArgs... > keyArgs, std::tuple< MappedArgs... > mappedArgs)
Definition: unordered_multimap.h:539
momo::internal::IteratorPointer
Definition: IteratorUtility.h:264
momo::stdish::unordered_multimap::operator=
unordered_multimap & operator=(unordered_multimap &&right) noexcept(momo::internal::ContainerAssignerStd::IsNothrowMoveAssignable< unordered_multimap >::value)
Definition: unordered_multimap.h:284
momo::stdish::unordered_multimap::const_iterator
iterator::ConstIterator const_iterator
Definition: unordered_multimap.h:96
momo::internal::Identity
EnableIf< true, Type > Identity
Definition: Utility.h:212
momo::stdish::unordered_multimap::begin
iterator begin() noexcept
Definition: unordered_multimap.h:326
momo::stdish::unordered_multimap::unordered_multimap
unordered_multimap(size_type bucketCount, const hasher &hashFunc, const key_equal &equalComp, const allocator_type &alloc=allocator_type())
Definition: unordered_multimap.h:152
momo::stdish::unordered_multimap::unordered_multimap
unordered_multimap(const unordered_multimap &right, const momo::internal::Identity< allocator_type > &alloc)
Definition: unordered_multimap.h:276
momo::stdish::unordered_multimap_open::erase_if
friend size_type erase_if(unordered_multimap_open &cont, const ValueFilter &valueFilter)
Definition: unordered_multimap.h:770
momo::stdish::unordered_multimap::max_size
size_type max_size() const noexcept
Definition: unordered_multimap.h:369
MOMO_DECLARE_PROXY_CONSTRUCTOR
#define MOMO_DECLARE_PROXY_CONSTRUCTOR(Object)
Definition: Utility.h:118
momo::stdish::unordered_multimap::find
MOMO_FORCEINLINE momo::internal::EnableIf< IsValidKeyArg< KeyArg >::value, const_iterator > find(const KeyArg &key) const
Definition: unordered_multimap.h:404
momo::stdish::unordered_multimap::hash_function
hasher hash_function() const
Definition: unordered_multimap.h:354
momo::stdish::unordered_multimap::begin
const_iterator begin() const noexcept
Definition: unordered_multimap.h:321
momo::stdish::unordered_multimap::get_nested_container
nested_container_type & get_nested_container() noexcept
Definition: unordered_multimap.h:316
momo::stdish::unordered_multimap::find
MOMO_FORCEINLINE iterator find(const key_type &key)
Definition: unordered_multimap.h:397
momo::stdish::unordered_multimap::equal_range
MOMO_FORCEINLINE momo::internal::EnableIf< IsValidKeyArg< KeyArg >::value, std::pair< iterator, iterator > > equal_range(const KeyArg &key)
Definition: unordered_multimap.h:463
momo::stdish::unordered_multimap::equal_range
MOMO_FORCEINLINE std::pair< iterator, iterator > equal_range(const key_type &key)
Definition: unordered_multimap.h:448
momo::stdish::unordered_multimap::get_nested_container
const nested_container_type & get_nested_container() const noexcept
Definition: unordered_multimap.h:311
momo::stdish::unordered_multimap::unordered_multimap
unordered_multimap(const allocator_type &alloc)
Definition: unordered_multimap.h:135
momo::stdish::unordered_multimap::reference
iterator::Reference reference
Definition: unordered_multimap.h:98
momo::stdish::unordered_multimap::unordered_multimap
unordered_multimap(std::initializer_list< momo::internal::Identity< value_type >> values, size_type bucketCount, const hasher &hashFunc, const key_equal &equalComp, const allocator_type &alloc=allocator_type())
Definition: unordered_multimap.h:206
momo::internal::HashDerivedIterator
Definition: IteratorUtility.h:376
momo::stdish::unordered_multimap::clear
void clear() noexcept
Definition: unordered_multimap.h:384
momo::stdish::unordered_multimap::unordered_multimap
unordered_multimap(Iterator first, Iterator last)
Definition: unordered_multimap.h:159
MOMO_DECLARE_PROXY_FUNCTION
#define MOMO_DECLARE_PROXY_FUNCTION(Object, Func)
Definition: Utility.h:126
momo::stdish::unordered_multimap::key_type
TKey key_type
Definition: unordered_multimap.h:81
momo::stdish::unordered_multimap::nested_container_type
HashMultiMap nested_container_type
Definition: unordered_multimap.h:87
momo::internal::ObjectBuffer
Definition: ObjectManager.h:189
momo::stdish::unordered_multimap::end
const_iterator end() const noexcept
Definition: unordered_multimap.h:331
momo::stdish::unordered_multimap::operator==
friend bool operator==(const unordered_multimap &left, const unordered_multimap &right)
Definition: unordered_multimap.h:622
std
Definition: Array.h:1173
MOMO_FORCEINLINE
#define MOMO_FORCEINLINE
Definition: UserSettings.h:119
momo::stdish::unordered_multimap::unordered_multimap
unordered_multimap(std::initializer_list< momo::internal::Identity< value_type >> values, size_type bucketCount, const allocator_type &alloc=allocator_type())
Definition: unordered_multimap.h:194
momo::stdish::unordered_multimap::find
MOMO_FORCEINLINE const_iterator find(const key_type &key) const
Definition: unordered_multimap.h:392
momo::HashMultiMap::GetEnd
ConstIterator GetEnd() const noexcept
Definition: HashMultiMap.h:827
momo::stdish::unordered_multimap::key_eq
key_equal key_eq() const
Definition: unordered_multimap.h:359
momo::stdish::unordered_multimap::unordered_multimap
unordered_multimap(size_type bucketCount, const hasher &hashFunc, const allocator_type &alloc=allocator_type())
Definition: unordered_multimap.h:146
momo::HashMultiMap
Definition: HashMultiMap.h:560
momo::HashMultiMap::MemManager
TMemManager MemManager
Definition: HashMultiMap.h:565
momo::stdish::unordered_multimap::emplace
iterator emplace()
Definition: unordered_multimap.h:502
momo::stdish::unordered_multimap::get_allocator
allocator_type get_allocator() const noexcept
Definition: unordered_multimap.h:364
momo::stdish::unordered_multimap::end
iterator end() noexcept
Definition: unordered_multimap.h:336
momo::stdish::unordered_multimap::emplace_hint
iterator emplace_hint(const_iterator)
Definition: unordered_multimap.h:507
momo::stdish::unordered_multimap::allocator_type
TAllocator allocator_type
Definition: unordered_multimap.h:85
momo::internal::ContainerAssignerStd::Copy
static Container & Copy(const Container &srcCont, Container &dstCont)
Definition: Utility.h:512
momo::stdish::unordered_multimap::emplace
iterator emplace(ValueArg &&valueArg)
Definition: unordered_multimap.h:513
momo::stdish::unordered_multimap_open::operator=
unordered_multimap_open & operator=(std::initializer_list< value_type > values)
Definition: unordered_multimap.h:758
Utility.h
momo::stdish::unordered_multimap::unordered_multimap
unordered_multimap(Iterator first, Iterator last, size_type bucketCount, const allocator_type &alloc=allocator_type())
Definition: unordered_multimap.h:165
momo::stdish::unordered_multimap::value_type
std::pair< const key_type, mapped_type > value_type
Definition: unordered_multimap.h:92
momo::internal::ContainerAssignerStd::Swap
static void Swap(Container &cont1, Container &cont2) noexcept
Definition: Utility.h:527
momo::stdish::unordered_multimap::size_type
size_t size_type
Definition: unordered_multimap.h:89
momo::stdish::unordered_multimap::hasher
THasher hasher
Definition: unordered_multimap.h:83
momo::stdish::unordered_multimap::key_equal
TEqualComparer key_equal
Definition: unordered_multimap.h:84
momo::stdish::unordered_multimap::empty
MOMO_NODISCARD bool empty() const noexcept
Definition: unordered_multimap.h:379
MOMO_NODISCARD
#define MOMO_NODISCARD
Definition: UserSettings.h:217
momo::stdish::unordered_multimap::emplace_hint
iterator emplace_hint(const_iterator, KeyArg &&keyArg, MappedArg &&mappedArg)
Definition: unordered_multimap.h:533
momo::internal::MapReferenceStd
Definition: MapUtility.h:68