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>
171 #ifdef MOMO_HAS_CONTAINERS_RANGES
172 template<std::ranges::input_range Range>
173 requires std::convertible_to<std::ranges::range_reference_t<Range>,
value_type>
177 insert_range(std::forward<Range>(values));
180 template<std::ranges::input_range Range>
181 requires std::convertible_to<std::ranges::range_reference_t<Range>,
value_type>
186 insert_range(std::forward<Range>(values));
188 #endif // MOMO_HAS_CONTAINERS_RANGES
191 : mTreeMap(std::move(right.mTreeMap))
196 noexcept(std::is_empty<allocator_type>::value)
197 : mTreeMap(pvCreateMap(
std::move(right), alloc))
202 : mTreeMap(right.mTreeMap)
207 : mTreeMap(right.mTreeMap, MemManager(alloc))
214 noexcept(std::is_empty<allocator_type>::value ||
215 std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value)
219 bool propagate = std::is_empty<allocator_type>::value ||
220 std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value;
222 mTreeMap = pvCreateMap(std::move(right), alloc);
231 bool propagate = std::is_empty<allocator_type>::value ||
232 std::allocator_traits<allocator_type>::propagate_on_container_copy_assignment::value;
234 mTreeMap = TreeMap(right.mTreeMap, MemManager(alloc));
241 MOMO_ASSERT(std::allocator_traits<allocator_type>::propagate_on_container_swap::value
243 mTreeMap.Swap(right.mTreeMap);
258 return ConstIteratorProxy(mTreeMap.GetBegin());
263 return IteratorProxy(mTreeMap.GetBegin());
268 return ConstIteratorProxy(mTreeMap.GetEnd());
273 return IteratorProxy(mTreeMap.GetEnd());
318 return mTreeMap.GetTreeTraits().GetLessFunc();
325 explicit ValueCompareProxy(
const key_compare& keyComp)
330 return ValueCompareProxy(
key_comp());
335 return allocator_type(mTreeMap.GetMemManager().GetByteAllocator());
340 return std::allocator_traits<allocator_type>::max_size(
get_allocator());
345 return mTreeMap.GetCount();
350 return mTreeMap.IsEmpty();
360 return ConstIteratorProxy(mTreeMap.Find(key));
365 return IteratorProxy(mTreeMap.Find(key));
368 template<
typename KeyArg>
372 return ConstIteratorProxy(mTreeMap.Find(key));
375 template<
typename KeyArg>
379 return IteratorProxy(mTreeMap.Find(key));
384 return mTreeMap.GetKeyCount(key);
387 template<
typename KeyArg>
391 return mTreeMap.GetKeyCount(key);
396 return mTreeMap.ContainsKey(key);
399 template<
typename KeyArg>
403 return mTreeMap.ContainsKey(key);
408 return ConstIteratorProxy(mTreeMap.GetLowerBound(key));
413 return IteratorProxy(mTreeMap.GetLowerBound(key));
416 template<
typename KeyArg>
420 return ConstIteratorProxy(mTreeMap.GetLowerBound(key));
423 template<
typename KeyArg>
427 return IteratorProxy(mTreeMap.GetLowerBound(key));
432 return ConstIteratorProxy(mTreeMap.GetUpperBound(key));
437 return IteratorProxy(mTreeMap.GetUpperBound(key));
440 template<
typename KeyArg>
444 return ConstIteratorProxy(mTreeMap.GetUpperBound(key));
447 template<
typename KeyArg>
451 return IteratorProxy(mTreeMap.GetUpperBound(key));
459 if (iter ==
end() || mTreeMap.GetTreeTraits().IsLess(key, iter->first))
460 return { iter, iter };
461 return { iter, std::next(iter) };
469 if (iter ==
end() || mTreeMap.GetTreeTraits().IsLess(key, iter->first))
470 return { iter, iter };
471 return { iter, std::next(iter) };
474 template<
typename KeyArg>
476 std::pair<const_iterator, const_iterator>>
equal_range(
const KeyArg& key)
const
481 template<
typename KeyArg>
488 template<
typename ValueArg = std::pair<key_type, mapped_type>>
490 std::pair<iterator, bool>>
insert(ValueArg&& valueArg)
492 return emplace(std::forward<ValueArg>(valueArg));
495 template<
typename ValueArg = std::pair<key_type, mapped_type>>
499 return emplace_hint(hint, std::forward<ValueArg>(valueArg));
507 std::move(NodeTypeProxy::GetExtractedPair(node)));
516 std::pair<iterator, bool> res = pvFind(hint, node.key());
519 return IteratorProxy(mTreeMap.Add(IteratorProxy::GetBaseIterator(res.first),
520 std::move(NodeTypeProxy::GetExtractedPair(node))));
523 template<
typename Iterator>
524 void insert(Iterator first, Iterator last)
526 pvInsertRange(first, last);
529 void insert(std::initializer_list<value_type> values)
531 mTreeMap.Insert(values.begin(), values.end());
534 #ifdef MOMO_HAS_CONTAINERS_RANGES
535 template<std::ranges::input_range Range>
536 requires std::convertible_to<std::ranges::range_reference_t<Range>,
value_type>
537 void insert_range(Range&& values)
539 pvInsertRange(std::ranges::begin(values), std::ranges::end(values));
541 #endif // MOMO_HAS_CONTAINERS_RANGES
545 return ptEmplace(
nullptr, std::tuple<>(), std::tuple<>());
550 return ptEmplace(hint, std::tuple<>(), std::tuple<>()).first;
553 template<
typename ValueArg>
554 std::pair<iterator, bool>
emplace(ValueArg&& valueArg)
557 std::forward_as_tuple(std::get<0>(std::forward<ValueArg>(valueArg))),
558 std::forward_as_tuple(std::get<1>(std::forward<ValueArg>(valueArg))));
561 template<
typename ValueArg>
565 std::forward_as_tuple(std::get<0>(std::forward<ValueArg>(valueArg))),
566 std::forward_as_tuple(std::get<1>(std::forward<ValueArg>(valueArg)))).first;
569 template<
typename KeyArg,
typename MappedArg>
570 std::pair<iterator, bool>
emplace(KeyArg&& keyArg, MappedArg&& mappedArg)
572 return ptEmplace(
nullptr, std::forward_as_tuple(std::forward<KeyArg>(keyArg)),
573 std::forward_as_tuple(std::forward<MappedArg>(mappedArg)));
576 template<
typename KeyArg,
typename MappedArg>
579 return ptEmplace(hint, std::forward_as_tuple(std::forward<KeyArg>(keyArg)),
580 std::forward_as_tuple(std::forward<MappedArg>(mappedArg))).first;
583 template<
typename... KeyArgs,
typename... MappedArgs>
584 std::pair<iterator, bool>
emplace(std::piecewise_construct_t,
585 std::tuple<KeyArgs...> keyArgs, std::tuple<MappedArgs...> mappedArgs)
587 return ptEmplace(
nullptr, std::move(keyArgs), std::move(mappedArgs));
590 template<
typename... KeyArgs,
typename... MappedArgs>
592 std::tuple<KeyArgs...> keyArgs, std::tuple<MappedArgs...> mappedArgs)
594 return ptEmplace(hint, std::move(keyArgs), std::move(mappedArgs)).first;
599 return IteratorProxy(mTreeMap.Remove(ConstIteratorProxy::GetBaseIterator(where)));
609 return IteratorProxy(mTreeMap.Remove(ConstIteratorProxy::GetBaseIterator(first),
610 ConstIteratorProxy::GetBaseIterator(last)));
615 return mTreeMap.Remove(key);
629 template<
typename Map>
632 mTreeMap.MergeFrom(
map.get_nested_container());
641 #ifdef MOMO_HAS_THREE_WAY_COMPARISON
645 return std::lexicographical_compare_three_way(left.begin(), left.end(),
646 right.begin(), right.end());
651 return std::lexicographical_compare(left.
begin(), left.
end(),
659 void ptAssign(std::initializer_list<value_type> values)
661 TreeMap treeMap(mTreeMap.GetTreeTraits(), MemManager(
get_allocator()));
662 treeMap.Insert(values.begin(), values.end());
663 mTreeMap = std::move(treeMap);
666 template<
typename Hint,
typename... KeyArgs,
typename... MappedArgs>
667 std::pair<iterator, bool>
ptEmplace(Hint hint, std::tuple<KeyArgs...>&& keyArgs,
668 std::tuple<MappedArgs...>&& mappedArgs)
670 typedef typename TreeMap::KeyValueTraits
671 ::template ValueCreator<MappedArgs...> MappedCreator;
672 return pvInsert(hint, std::move(keyArgs),
673 MappedCreator(mTreeMap.GetMemManager(), std::move(mappedArgs)));
679 if (right.get_allocator() == alloc)
680 return std::move(right.mTreeMap);
681 TreeMap treeMap(right.mTreeMap.GetTreeTraits(), MemManager(alloc));
682 treeMap.MergeFrom(right.mTreeMap);
688 const TreeTraits& treeTraits = mTreeMap.GetTreeTraits();
690 : treeTraits.
IsLess(key1, key2);
693 std::pair<iterator, bool> pvFind(std::nullptr_t ,
const key_type& key)
698 iterator prevIter = std::prev(iter);
699 if (!mTreeMap.GetTreeTraits().IsLess(prevIter->first, key))
700 return { prevIter,
false };
702 return { iter,
true };
707 if (hint !=
begin() && !pvIsOrdered(std::prev(hint)->first, key))
708 return pvFind(
nullptr, key);
709 if (hint !=
end() && !pvIsOrdered(key, hint->first))
714 return pvFind(
nullptr, key);
716 return { IteratorProxy(mTreeMap.MakeMutableIterator(
717 ConstIteratorProxy::GetBaseIterator(hint))),
true };
720 template<
typename Hint,
typename... KeyArgs,
typename MappedCreator>
721 std::pair<iterator, bool> pvInsert(Hint hint, std::tuple<KeyArgs...>&& keyArgs,
722 MappedCreator&& mappedCreator)
724 MemManager& memManager = mTreeMap.GetMemManager();
726 TreeMap::KeyValueTraits::keyAlignment> KeyBuffer;
728 typedef typename KeyManager::template Creator<KeyArgs...> KeyCreator;
730 KeyCreator(memManager, std::move(keyArgs))(keyBuffer.GetPtr());
731 key_type* keyPtr = keyBuffer.template GetPtr<true>();
734 std::pair<iterator, bool> res = pvFind(hint, *keyPtr);
737 KeyManager::Destroy(memManager, *keyPtr);
741 auto valueCreator = [&memManager, &keyPtr, &mappedCreator]
744 KeyManager::Relocate(memManager, *keyPtr, newKey);
748 std::forward<MappedCreator>(mappedCreator)(newMapped);
752 KeyManager::Destroy(memManager, *newKey);
756 TreeMapIterator resIter = mTreeMap.AddCrt(
757 IteratorProxy::GetBaseIterator(res.first), valueCreator);
758 return { IteratorProxy(resIter),
true };
762 if (keyPtr !=
nullptr)
763 KeyManager::Destroy(memManager, *keyPtr);
768 template<
typename Hint,
typename RKey,
typename MappedCreator,
769 typename Key =
typename std::decay<RKey>::type>
771 std::pair<iterator, bool>> pvInsert(Hint hint, std::tuple<RKey>&& key,
772 MappedCreator&& mappedCreator)
774 std::pair<iterator, bool> res = pvFind(hint,
775 static_cast<const key_type&
>(std::get<0>(key)));
778 TreeMapIterator resIter = mTreeMap.AddCrt(IteratorProxy::GetBaseIterator(res.first),
779 std::forward<RKey>(std::get<0>(key)), std::forward<MappedCreator>(mappedCreator));
780 return { IteratorProxy(resIter),
true };
783 template<
typename Iterator,
typename Sentinel>
785 void> pvInsertRange(Iterator
begin, Sentinel
end)
787 mTreeMap.Insert(std::move(
begin), std::move(
end));
790 template<
typename Iterator,
typename Sentinel>
792 void> pvInsertRange(Iterator
begin, Sentinel
end)
794 for (Iterator iter = std::move(
begin); iter !=
end; ++iter)
831 template<
typename TKey,
typename TMapped,
832 typename TLessFunc = std::less<TKey>,
833 typename TAllocator = std::allocator<std::pair<const TKey, TMapped>>,
834 typename TTreeMap = TreeMap<TKey, TMapped, TreeTraitsStd<TKey, TLessFunc>,
835 MemManagerStd<TAllocator>>>
840 typedef TTreeMap TreeMap;
852 using BaseMap::BaseMap;
879 throw std::out_of_range(
"invalid map key");
887 throw std::out_of_range(
"invalid map key");
891 template<
typename... MappedArgs>
895 std::forward_as_tuple(std::forward<MappedArgs>(mappedArgs)...));
898 template<
typename... MappedArgs>
902 std::forward_as_tuple(std::forward<MappedArgs>(mappedArgs)...)).first;
905 template<
typename... MappedArgs>
909 std::forward_as_tuple(std::forward<MappedArgs>(mappedArgs)...));
912 template<
typename... MappedArgs>
916 std::forward_as_tuple(std::forward<MappedArgs>(mappedArgs)...)).first;
919 template<
typename MappedArg>
922 return pvInsertOrAssign(
nullptr, std::move(key), std::forward<MappedArg>(mappedArg));
925 template<
typename MappedArg>
928 return pvInsertOrAssign(hint, std::move(key), std::forward<MappedArg>(mappedArg)).first;
931 template<
typename MappedArg>
934 return pvInsertOrAssign(
nullptr, key, std::forward<MappedArg>(mappedArg));
937 template<
typename MappedArg>
940 return pvInsertOrAssign(hint, key, std::forward<MappedArg>(mappedArg)).first;
943 template<
typename ValueFilter>
948 return cont.get_nested_container().Remove(pairFilter);
952 template<
typename H
int,
typename RKey,
typename MappedArg>
953 std::pair<iterator, bool> pvInsertOrAssign(Hint hint, RKey&& key, MappedArg&& mappedArg)
956 std::forward_as_tuple(std::forward<RKey>(key)),
957 std::forward_as_tuple(std::forward<MappedArg>(mappedArg)));
959 res.first->second = std::forward<MappedArg>(mappedArg);
972 template<
typename TKey,
typename TMapped,
973 typename TLessFunc = std::less<TKey>,
974 typename TAllocator = std::allocator<std::pair<const TKey, TMapped>>,
975 typename TTreeMap = TreeMap<TKey, TMapped, TreeTraitsStd<TKey, TLessFunc, true>,
976 MemManagerStd<TAllocator>>>
995 using BaseMap::BaseMap;
1010 template<
typename ValueArg = std::pair<key_type, mapped_type>>
1017 template<
typename ValueArg = std::pair<key_type, mapped_type>>
1034 template<
typename Iterator>
1040 void insert(std::initializer_list<value_type> values)
1045 template<
typename... ValueArgs>
1051 template<
typename ValueFilter>
1056 return cont.get_nested_container().Remove(pairFilter);
1060 #ifdef MOMO_HAS_DEDUCTION_GUIDES
1062 #define MOMO_DECLARE_DEDUCTION_GUIDES(map) \
1063 template<typename Iterator, \
1064 typename Value = typename std::iterator_traits<Iterator>::value_type, \
1065 typename Key = std::decay_t<typename Value::first_type>, \
1066 typename Mapped = std::decay_t<typename Value::second_type>, \
1067 typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
1068 typename = internal::ordered_checker<Key, Allocator>> \
1069 map(Iterator, Iterator, Allocator = Allocator()) \
1070 -> map<Key, Mapped, std::less<Key>, Allocator>; \
1071 template<typename Iterator, typename LessFunc, \
1072 typename Value = typename std::iterator_traits<Iterator>::value_type, \
1073 typename Key = std::decay_t<typename Value::first_type>, \
1074 typename Mapped = std::decay_t<typename Value::second_type>, \
1075 typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
1076 typename = internal::ordered_checker<Key, Allocator, LessFunc>> \
1077 map(Iterator, Iterator, LessFunc, Allocator = Allocator()) \
1078 -> map<Key, Mapped, LessFunc, Allocator>; \
1079 template<typename CKey, typename Mapped, \
1080 typename Key = std::remove_const_t<CKey>, \
1081 typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
1082 typename = internal::ordered_checker<Key, Allocator>> \
1083 map(std::initializer_list<std::pair<CKey, Mapped>>, Allocator = Allocator()) \
1084 -> map<Key, Mapped, std::less<Key>, Allocator>; \
1085 template<typename CKey, typename Mapped, typename LessFunc, \
1086 typename Key = std::remove_const_t<CKey>, \
1087 typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
1088 typename = internal::ordered_checker<Key, Allocator, LessFunc>> \
1089 map(std::initializer_list<std::pair<CKey, Mapped>>, LessFunc, Allocator = Allocator()) \
1090 -> map<Key, Mapped, LessFunc, Allocator>;
1092 MOMO_DECLARE_DEDUCTION_GUIDES(map)
1093 MOMO_DECLARE_DEDUCTION_GUIDES(multimap)
1095 #undef MOMO_DECLARE_DEDUCTION_GUIDES
1097 #ifdef MOMO_HAS_CONTAINERS_RANGES
1099 #define MOMO_DECLARE_DEDUCTION_GUIDES_RANGES(map) \
1100 template<std::ranges::input_range Range, \
1101 typename Value = std::ranges::range_value_t<Range>, \
1102 typename Key = std::decay_t<typename Value::first_type>, \
1103 typename Mapped = std::decay_t<typename Value::second_type>, \
1104 typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
1105 typename = internal::ordered_checker<Key, Allocator>> \
1106 map(std::from_range_t, Range&&, Allocator = Allocator()) \
1107 -> map<Key, Mapped, std::less<Key>, Allocator>; \
1108 template<std::ranges::input_range Range, typename LessFunc, \
1109 typename Value = std::ranges::range_value_t<Range>, \
1110 typename Key = std::decay_t<typename Value::first_type>, \
1111 typename Mapped = std::decay_t<typename Value::second_type>, \
1112 typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
1113 typename = internal::ordered_checker<Key, Allocator, LessFunc>> \
1114 map(std::from_range_t, Range&&, LessFunc, Allocator = Allocator()) \
1115 -> map<Key, Mapped, LessFunc, Allocator>;
1117 MOMO_DECLARE_DEDUCTION_GUIDES_RANGES(map)
1118 MOMO_DECLARE_DEDUCTION_GUIDES_RANGES(multimap)
1120 #undef MOMO_DECLARE_DEDUCTION_GUIDES_RANGES
1122 #endif // MOMO_HAS_CONTAINERS_RANGES
1124 #endif // MOMO_HAS_DEDUCTION_GUIDES
1130 #endif // MOMO_INCLUDE_GUARD_STDISH_MAP