17 #ifndef MOMO_INCLUDE_GUARD_STDISH_MAP
18 #define MOMO_INCLUDE_GUARD_STDISH_MAP
20 #include "../TreeMap.h"
31 template<
typename TKey,
typename TLessFunc>
39 template<
typename Value>
40 bool operator()(
const Value& value1,
const Value& value2)
const
43 typename std::decay<decltype(value1.first)>::type>::value));
44 return comp(value1.first, value2.first);
57 template<
typename TKey,
typename TMapped,
typename TLessFunc,
typename TAllocator,
62 typedef TTreeMap TreeMap;
79 typedef std::pair<const key_type, mapped_type>
value_type;
102 template<
typename KeyArg>
103 struct IsValidKeyArg :
public TreeTraits::template IsValidKeyArg<KeyArg>
115 struct IteratorProxy :
public iterator
135 : mTreeMap(TreeTraits(), MemManager(alloc))
140 : mTreeMap(TreeTraits(lessFunc), MemManager(alloc))
144 template<
typename Iterator>
151 template<
typename Iterator>
172 : mTreeMap(std::move(right.mTreeMap))
177 noexcept(std::is_empty<allocator_type>::value)
178 : mTreeMap(pvCreateMap(
std::move(right), alloc))
183 : mTreeMap(right.mTreeMap)
188 : mTreeMap(right.mTreeMap, MemManager(alloc))
195 noexcept(std::is_empty<allocator_type>::value ||
196 std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value)
200 bool propagate = std::is_empty<allocator_type>::value ||
201 std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value;
203 mTreeMap = pvCreateMap(std::move(right), alloc);
212 bool propagate = std::is_empty<allocator_type>::value ||
213 std::allocator_traits<allocator_type>::propagate_on_container_copy_assignment::value;
215 mTreeMap = TreeMap(right.mTreeMap, MemManager(alloc));
222 MOMO_ASSERT(std::allocator_traits<allocator_type>::propagate_on_container_swap::value
224 mTreeMap.Swap(right.mTreeMap);
239 return ConstIteratorProxy(mTreeMap.GetBegin());
244 return IteratorProxy(mTreeMap.GetBegin());
249 return ConstIteratorProxy(mTreeMap.GetEnd());
254 return IteratorProxy(mTreeMap.GetEnd());
299 return mTreeMap.GetTreeTraits().GetLessFunc();
306 explicit ValueCompareProxy(
const key_compare& keyComp)
311 return ValueCompareProxy(
key_comp());
316 return allocator_type(mTreeMap.GetMemManager().GetByteAllocator());
321 return std::allocator_traits<allocator_type>::max_size(
get_allocator());
326 return mTreeMap.GetCount();
331 return mTreeMap.IsEmpty();
341 return ConstIteratorProxy(mTreeMap.Find(key));
346 return IteratorProxy(mTreeMap.Find(key));
349 template<
typename KeyArg>
353 return ConstIteratorProxy(mTreeMap.Find(key));
356 template<
typename KeyArg>
360 return IteratorProxy(mTreeMap.Find(key));
365 return mTreeMap.GetKeyCount(key);
368 template<
typename KeyArg>
372 return mTreeMap.GetKeyCount(key);
377 return mTreeMap.ContainsKey(key);
380 template<
typename KeyArg>
384 return mTreeMap.ContainsKey(key);
389 return ConstIteratorProxy(mTreeMap.GetLowerBound(key));
394 return IteratorProxy(mTreeMap.GetLowerBound(key));
397 template<
typename KeyArg>
401 return ConstIteratorProxy(mTreeMap.GetLowerBound(key));
404 template<
typename KeyArg>
408 return IteratorProxy(mTreeMap.GetLowerBound(key));
413 return ConstIteratorProxy(mTreeMap.GetUpperBound(key));
418 return IteratorProxy(mTreeMap.GetUpperBound(key));
421 template<
typename KeyArg>
425 return ConstIteratorProxy(mTreeMap.GetUpperBound(key));
428 template<
typename KeyArg>
432 return IteratorProxy(mTreeMap.GetUpperBound(key));
440 if (iter ==
end() || mTreeMap.GetTreeTraits().IsLess(key, iter->first))
441 return { iter, iter };
442 return { iter, std::next(iter) };
450 if (iter ==
end() || mTreeMap.GetTreeTraits().IsLess(key, iter->first))
451 return { iter, iter };
452 return { iter, std::next(iter) };
455 template<
typename KeyArg>
457 std::pair<const_iterator, const_iterator>>
equal_range(
const KeyArg& key)
const
462 template<
typename KeyArg>
485 std::pair<iterator, bool>
insert(std::pair<key_type, mapped_type>&& value)
487 return ptEmplace(
nullptr, std::forward_as_tuple(std::move(value.first)),
488 std::forward_as_tuple(std::move(value.second)));
493 return ptEmplace(hint, std::forward_as_tuple(std::move(value.first)),
494 std::forward_as_tuple(std::move(value.second))).first;
497 template<
typename First,
typename Second>
499 && std::is_constructible<mapped_type, const Second&>::value,
500 std::pair<iterator, bool>>
insert(
const std::pair<First, Second>& value)
502 return ptEmplace(
nullptr, std::forward_as_tuple(value.first),
503 std::forward_as_tuple(value.second));
506 template<
typename First,
typename Second>
508 && std::is_constructible<mapped_type, const Second&>::value,
511 return ptEmplace(hint, std::forward_as_tuple(value.first),
512 std::forward_as_tuple(value.second)).first;
515 template<
typename First,
typename Second>
517 && std::is_constructible<mapped_type, Second&&>::value,
518 std::pair<iterator, bool>>
insert(std::pair<First, Second>&& value)
520 return ptEmplace(
nullptr, std::forward_as_tuple(std::forward<First>(value.first)),
521 std::forward_as_tuple(std::forward<Second>(value.second)));
524 template<
typename First,
typename Second>
526 && std::is_constructible<mapped_type, Second&&>::value,
529 return ptEmplace(hint, std::forward_as_tuple(std::forward<First>(value.first)),
530 std::forward_as_tuple(std::forward<Second>(value.second))).first;
538 std::move(NodeTypeProxy::GetExtractedPair(node)));
547 std::pair<iterator, bool> res = pvFind(hint, node.key());
550 return IteratorProxy(mTreeMap.Add(IteratorProxy::GetBaseIterator(res.first),
551 std::move(NodeTypeProxy::GetExtractedPair(node))));
554 template<
typename Iterator>
555 void insert(Iterator first, Iterator last)
560 void insert(std::initializer_list<value_type> values)
562 mTreeMap.Insert(values.begin(), values.end());
567 return ptEmplace(
nullptr, std::tuple<>(), std::tuple<>());
572 return ptEmplace(hint, std::tuple<>(), std::tuple<>()).first;
575 template<
typename ValueArg>
576 std::pair<iterator, bool>
emplace(ValueArg&& valueArg)
578 return insert(std::forward<ValueArg>(valueArg));
581 template<
typename ValueArg>
584 return insert(hint, std::forward<ValueArg>(valueArg));
587 template<
typename KeyArg,
typename MappedArg>
588 std::pair<iterator, bool>
emplace(KeyArg&& keyArg, MappedArg&& mappedArg)
590 return ptEmplace(
nullptr, std::forward_as_tuple(std::forward<KeyArg>(keyArg)),
591 std::forward_as_tuple(std::forward<MappedArg>(mappedArg)));
594 template<
typename KeyArg,
typename MappedArg>
597 return ptEmplace(hint, std::forward_as_tuple(std::forward<KeyArg>(keyArg)),
598 std::forward_as_tuple(std::forward<MappedArg>(mappedArg))).first;
601 template<
typename... KeyArgs,
typename... MappedArgs>
602 std::pair<iterator, bool>
emplace(std::piecewise_construct_t,
603 std::tuple<KeyArgs...> keyArgs, std::tuple<MappedArgs...> mappedArgs)
605 return ptEmplace(
nullptr, std::move(keyArgs), std::move(mappedArgs));
608 template<
typename... KeyArgs,
typename... MappedArgs>
610 std::tuple<KeyArgs...> keyArgs, std::tuple<MappedArgs...> mappedArgs)
612 return ptEmplace(hint, std::move(keyArgs), std::move(mappedArgs)).first;
617 return IteratorProxy(mTreeMap.Remove(ConstIteratorProxy::GetBaseIterator(where)));
627 return IteratorProxy(mTreeMap.Remove(ConstIteratorProxy::GetBaseIterator(first),
628 ConstIteratorProxy::GetBaseIterator(last)));
633 return mTreeMap.Remove(key);
647 template<
typename Map>
650 mTreeMap.MergeFrom(
map.get_nested_container());
660 return !(*
this == right);
663 #ifdef MOMO_HAS_THREE_WAY_COMPARISON
664 auto operator<=>(
const map_base& right)
const
667 return std::lexicographical_compare_three_way(
begin(),
end(),
668 right.begin(), right.end());
673 return std::lexicographical_compare(
begin(),
end(), right.
begin(), right.
end());
678 return right < *
this;
683 return !(right < *
this);
688 return right <= *
this;
693 void ptAssign(std::initializer_list<value_type> values)
695 TreeMap treeMap(mTreeMap.GetTreeTraits(), MemManager(
get_allocator()));
696 treeMap.Insert(values.begin(), values.end());
697 mTreeMap = std::move(treeMap);
700 template<
typename Hint,
typename... KeyArgs,
typename... MappedArgs>
701 std::pair<iterator, bool>
ptEmplace(Hint hint, std::tuple<KeyArgs...>&& keyArgs,
702 std::tuple<MappedArgs...>&& mappedArgs)
704 typedef typename TreeMap::KeyValueTraits
705 ::template ValueCreator<MappedArgs...> MappedCreator;
706 return pvInsert(hint, std::move(keyArgs),
707 MappedCreator(mTreeMap.GetMemManager(), std::move(mappedArgs)));
713 if (right.get_allocator() == alloc)
714 return std::move(right.mTreeMap);
715 TreeMap treeMap(right.mTreeMap.GetTreeTraits(), MemManager(alloc));
716 treeMap.MergeFrom(right.mTreeMap);
722 const TreeTraits& treeTraits = mTreeMap.GetTreeTraits();
724 : treeTraits.
IsLess(key1, key2);
727 std::pair<iterator, bool> pvFind(std::nullptr_t ,
const key_type& key)
732 iterator prevIter = std::prev(iter);
733 if (!mTreeMap.GetTreeTraits().IsLess(prevIter->first, key))
734 return { prevIter,
false };
736 return { iter,
true };
741 if (hint !=
begin() && !pvIsOrdered(std::prev(hint)->first, key))
742 return pvFind(
nullptr, key);
743 if (hint !=
end() && !pvIsOrdered(key, hint->first))
748 return pvFind(
nullptr, key);
750 return { IteratorProxy(mTreeMap.MakeMutableIterator(
751 ConstIteratorProxy::GetBaseIterator(hint))),
true };
754 template<
typename Hint,
typename... KeyArgs,
typename MappedCreator>
755 std::pair<iterator, bool> pvInsert(Hint hint, std::tuple<KeyArgs...>&& keyArgs,
756 MappedCreator&& mappedCreator)
758 MemManager& memManager = mTreeMap.GetMemManager();
760 TreeMap::KeyValueTraits::keyAlignment> KeyBuffer;
762 typedef typename KeyManager::template Creator<KeyArgs...> KeyCreator;
764 KeyCreator(memManager, std::move(keyArgs))(&keyBuffer);
765 bool keyDestroyed =
false;
768 std::pair<iterator, bool> res = pvFind(hint, *&keyBuffer);
771 KeyManager::Destroy(memManager, *&keyBuffer);
775 auto valueCreator = [&memManager, &keyBuffer, &mappedCreator, &keyDestroyed]
778 KeyManager::Relocate(memManager, *&keyBuffer, newKey);
782 std::forward<MappedCreator>(mappedCreator)(newMapped);
786 KeyManager::Destroy(memManager, *newKey);
790 TreeMapIterator resIter = mTreeMap.AddCrt(
791 IteratorProxy::GetBaseIterator(res.first), valueCreator);
792 return { IteratorProxy(resIter),
true };
797 KeyManager::Destroy(memManager, *&keyBuffer);
802 template<
typename Hint,
typename RKey,
typename MappedCreator,
803 typename Key =
typename std::decay<RKey>::type>
805 std::pair<iterator, bool>> pvInsert(Hint hint, std::tuple<RKey>&& key,
806 MappedCreator&& mappedCreator)
808 std::pair<iterator, bool> res = pvFind(hint,
809 static_cast<const key_type&
>(std::get<0>(key)));
812 TreeMapIterator resIter = mTreeMap.AddCrt(IteratorProxy::GetBaseIterator(res.first),
813 std::forward<RKey>(std::get<0>(key)), std::forward<MappedCreator>(mappedCreator));
814 return { IteratorProxy(resIter),
true };
817 template<
typename Iterator>
818 void pvInsert(Iterator first, Iterator last, std::true_type )
820 mTreeMap.Insert(first, last);
823 template<
typename Iterator>
824 void pvInsert(Iterator first, Iterator last, std::false_type )
826 for (Iterator iter = first; iter != last; ++iter)
863 template<
typename TKey,
typename TMapped,
864 typename TLessFunc = std::less<TKey>,
865 typename TAllocator = std::allocator<std::pair<const TKey, TMapped>>,
866 typename TTreeMap = TreeMap<TKey, TMapped, TreeTraitsStd<TKey, TLessFunc>,
867 MemManagerStd<TAllocator>>>
872 typedef TTreeMap TreeMap;
884 using BaseMap::BaseMap;
911 throw std::out_of_range(
"invalid map key");
919 throw std::out_of_range(
"invalid map key");
923 template<
typename... MappedArgs>
927 std::forward_as_tuple(std::forward<MappedArgs>(mappedArgs)...));
930 template<
typename... MappedArgs>
934 std::forward_as_tuple(std::forward<MappedArgs>(mappedArgs)...)).first;
937 template<
typename... MappedArgs>
941 std::forward_as_tuple(std::forward<MappedArgs>(mappedArgs)...));
944 template<
typename... MappedArgs>
948 std::forward_as_tuple(std::forward<MappedArgs>(mappedArgs)...)).first;
951 template<
typename MappedArg>
954 return pvInsertOrAssign(
nullptr, std::move(key), std::forward<MappedArg>(mappedArg));
957 template<
typename MappedArg>
960 return pvInsertOrAssign(hint, std::move(key), std::forward<MappedArg>(mappedArg)).first;
963 template<
typename MappedArg>
966 return pvInsertOrAssign(
nullptr, key, std::forward<MappedArg>(mappedArg));
969 template<
typename MappedArg>
972 return pvInsertOrAssign(hint, key, std::forward<MappedArg>(mappedArg)).first;
975 template<
typename ValueFilter>
980 return cont.get_nested_container().Remove(pairFilter);
984 template<
typename H
int,
typename RKey,
typename MappedArg>
985 std::pair<iterator, bool> pvInsertOrAssign(Hint hint, RKey&& key, MappedArg&& mappedArg)
988 std::forward_as_tuple(std::forward<RKey>(key)),
989 std::forward_as_tuple(std::forward<MappedArg>(mappedArg)));
991 res.first->second = std::forward<MappedArg>(mappedArg);
1004 template<
typename TKey,
typename TMapped,
1005 typename TLessFunc = std::less<TKey>,
1006 typename TAllocator = std::allocator<std::pair<const TKey, TMapped>>,
1007 typename TTreeMap = TreeMap<TKey, TMapped, TreeTraitsStd<TKey, TLessFunc, true>,
1008 MemManagerStd<TAllocator>>>
1027 using BaseMap::BaseMap;
1052 template<
typename First,
typename Second>
1054 && std::is_constructible<mapped_type, const Second&>::value,
1060 template<
typename First,
typename Second>
1062 && std::is_constructible<mapped_type, const Second&>::value,
1068 template<
typename First,
typename Second>
1070 && std::is_constructible<mapped_type, Second&&>::value,
1076 template<
typename First,
typename Second>
1078 && std::is_constructible<mapped_type, Second&&>::value,
1094 template<
typename Iterator>
1100 void insert(std::initializer_list<value_type> values)
1105 template<
typename... ValueArgs>
1111 template<
typename ValueFilter>
1116 return cont.get_nested_container().Remove(pairFilter);
1120 #ifdef MOMO_HAS_DEDUCTION_GUIDES
1122 #define MOMO_DECLARE_DEDUCTION_GUIDES(map) \
1123 template<typename Iterator, \
1124 typename Key = std::remove_const_t<typename std::iterator_traits<Iterator>::value_type::first_type>, \
1125 typename Mapped = typename std::iterator_traits<Iterator>::value_type::second_type, \
1126 typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
1127 typename = decltype(std::declval<Allocator&>().allocate(size_t{}))> \
1128 map(Iterator, Iterator, Allocator = Allocator()) \
1129 -> map<Key, Mapped, std::less<Key>, Allocator>; \
1130 template<typename Iterator, typename LessFunc, \
1131 typename Key = std::remove_const_t<typename std::iterator_traits<Iterator>::value_type::first_type>, \
1132 typename Mapped = typename std::iterator_traits<Iterator>::value_type::second_type, \
1133 typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
1134 typename = decltype(std::declval<LessFunc&>()(std::declval<const Key&>(), std::declval<const Key&>()))> \
1135 map(Iterator, Iterator, LessFunc, Allocator = Allocator()) \
1136 -> map<Key, Mapped, LessFunc, Allocator>; \
1137 template<typename Key, typename Mapped, \
1138 typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
1139 typename = decltype(std::declval<Allocator&>().allocate(size_t{}))> \
1140 map(std::initializer_list<std::pair<Key, Mapped>>, Allocator = Allocator()) \
1141 -> map<Key, Mapped, std::less<Key>, Allocator>; \
1142 template<typename Key, typename Mapped, typename LessFunc, \
1143 typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
1144 typename = decltype(std::declval<LessFunc&>()(std::declval<const Key&>(), std::declval<const Key&>()))> \
1145 map(std::initializer_list<std::pair<Key, Mapped>>, LessFunc, Allocator = Allocator()) \
1146 -> map<Key, Mapped, LessFunc, Allocator>;
1148 MOMO_DECLARE_DEDUCTION_GUIDES(map)
1149 MOMO_DECLARE_DEDUCTION_GUIDES(multimap)
1151 #undef MOMO_DECLARE_DEDUCTION_GUIDES
1153 #endif // MOMO_HAS_DEDUCTION_GUIDES
1159 #endif // MOMO_INCLUDE_GUARD_STDISH_MAP