17 #ifndef MOMO_INCLUDE_GUARD_STDISH_MAP
18 #define MOMO_INCLUDE_GUARD_STDISH_MAP
21 # if __has_include(<momo/Utility.h>)
25 #ifndef MOMO_PARENT_HEADER
26 # include "../Utility.h"
29 #include MOMO_PARENT_HEADER(TreeMap)
40 template<
typename TKey,
typename TLessComparer>
48 template<
typename Value>
49 bool operator()(
const Value& value1,
const Value& value2)
const
52 typename std::decay<decltype(value1.first)>::type>::value);
53 return comp(value1.first, value2.first);
66 template<
typename TKey,
typename TMapped,
typename TLessComparer,
typename TAllocator,
71 typedef TTreeMap TreeMap;
88 typedef std::pair<const key_type, mapped_type>
value_type;
111 template<
typename KeyArg>
112 struct IsValidKeyArg :
public TreeTraits::template IsValidKeyArg<KeyArg>
123 struct IteratorProxy :
public iterator
142 : mTreeMap(TreeTraits(), MemManager(alloc))
147 : mTreeMap(TreeTraits(lessComp), MemManager(alloc))
151 template<
typename Iterator>
158 template<
typename Iterator>
178 #ifdef MOMO_HAS_CONTAINERS_RANGES
179 template<std::ranges::input_range Range>
180 requires std::convertible_to<std::ranges::range_reference_t<Range>,
value_type>
184 insert_range(std::forward<Range>(values));
187 template<std::ranges::input_range Range>
188 requires std::convertible_to<std::ranges::range_reference_t<Range>,
value_type>
193 insert_range(std::forward<Range>(values));
195 #endif // MOMO_HAS_CONTAINERS_RANGES
203 : mTreeMap(right.mTreeMap.GetTreeTraits(), MemManager(alloc))
205 if (right.get_allocator() == alloc)
207 mTreeMap.Swap(right.mTreeMap);
211 mTreeMap.MergeFrom(right.mTreeMap);
217 : mTreeMap(right.mTreeMap)
222 : mTreeMap(right.mTreeMap, MemManager(alloc))
256 return ConstIteratorProxy(mTreeMap.GetBegin());
261 return IteratorProxy(mTreeMap.GetBegin());
266 return ConstIteratorProxy(mTreeMap.GetEnd());
271 return IteratorProxy(mTreeMap.GetEnd());
316 return mTreeMap.GetTreeTraits().GetLessComparer();
323 explicit ValueCompareProxy(
const key_compare& keyComp)
328 return ValueCompareProxy(
key_comp());
333 return allocator_type(mTreeMap.GetMemManager().GetByteAllocator());
338 return std::allocator_traits<allocator_type>::max_size(
get_allocator());
343 return mTreeMap.GetCount();
348 return mTreeMap.IsEmpty();
358 return ConstIteratorProxy(mTreeMap.Find(key));
363 return IteratorProxy(mTreeMap.Find(key));
366 template<
typename KeyArg>
370 return ConstIteratorProxy(mTreeMap.Find(key));
373 template<
typename KeyArg>
377 return IteratorProxy(mTreeMap.Find(key));
382 return mTreeMap.GetKeyCount(key);
385 template<
typename KeyArg>
389 return mTreeMap.GetKeyCount(key);
394 return mTreeMap.ContainsKey(key);
397 template<
typename KeyArg>
401 return mTreeMap.ContainsKey(key);
406 return ConstIteratorProxy(mTreeMap.GetLowerBound(key));
411 return IteratorProxy(mTreeMap.GetLowerBound(key));
414 template<
typename KeyArg>
418 return ConstIteratorProxy(mTreeMap.GetLowerBound(key));
421 template<
typename KeyArg>
425 return IteratorProxy(mTreeMap.GetLowerBound(key));
430 return ConstIteratorProxy(mTreeMap.GetUpperBound(key));
435 return IteratorProxy(mTreeMap.GetUpperBound(key));
438 template<
typename KeyArg>
442 return ConstIteratorProxy(mTreeMap.GetUpperBound(key));
445 template<
typename KeyArg>
449 return IteratorProxy(mTreeMap.GetUpperBound(key));
457 if (iter ==
end() || mTreeMap.GetTreeTraits().IsLess(key, iter->first))
458 return { iter, iter };
459 return { iter, std::next(iter) };
467 if (iter ==
end() || mTreeMap.GetTreeTraits().IsLess(key, iter->first))
468 return { iter, iter };
469 return { iter, std::next(iter) };
472 template<
typename KeyArg>
474 std::pair<const_iterator, const_iterator>>
equal_range(
const KeyArg& key)
const
479 template<
typename KeyArg>
486 template<
typename ValueArg = std::pair<key_type, mapped_type>>
488 std::pair<iterator, bool>>
insert(ValueArg&& valueArg)
490 return emplace(std::forward<ValueArg>(valueArg));
493 template<
typename ValueArg = std::pair<key_type, mapped_type>>
497 return emplace_hint(hint, std::forward<ValueArg>(valueArg));
505 std::move(NodeTypeProxy::GetExtractedPair(node)));
514 std::pair<iterator, bool> res = pvFind(hint, node.key());
517 return IteratorProxy(mTreeMap.Add(IteratorProxy::GetBaseIterator(res.first),
518 std::move(NodeTypeProxy::GetExtractedPair(node))));
521 template<
typename Iterator>
522 void insert(Iterator first, Iterator last)
524 pvInsertRange(first, last);
527 void insert(std::initializer_list<value_type> values)
529 mTreeMap.Insert(values.begin(), values.end());
532 #ifdef MOMO_HAS_CONTAINERS_RANGES
533 template<std::ranges::input_range Range>
534 requires std::convertible_to<std::ranges::range_reference_t<Range>,
value_type>
535 void insert_range(Range&& values)
537 pvInsertRange(std::ranges::begin(values), std::ranges::end(values));
539 #endif // MOMO_HAS_CONTAINERS_RANGES
543 return ptEmplace(
nullptr, std::tuple<>(), std::tuple<>());
548 return ptEmplace(hint, std::tuple<>(), std::tuple<>()).first;
551 template<
typename ValueArg>
552 std::pair<iterator, bool>
emplace(ValueArg&& valueArg)
555 std::forward_as_tuple(std::get<0>(std::forward<ValueArg>(valueArg))),
556 std::forward_as_tuple(std::get<1>(std::forward<ValueArg>(valueArg))));
559 template<
typename ValueArg>
563 std::forward_as_tuple(std::get<0>(std::forward<ValueArg>(valueArg))),
564 std::forward_as_tuple(std::get<1>(std::forward<ValueArg>(valueArg)))).first;
567 template<
typename KeyArg,
typename MappedArg>
568 std::pair<iterator, bool>
emplace(KeyArg&& keyArg, MappedArg&& mappedArg)
570 return ptEmplace(
nullptr, std::forward_as_tuple(std::forward<KeyArg>(keyArg)),
571 std::forward_as_tuple(std::forward<MappedArg>(mappedArg)));
574 template<
typename KeyArg,
typename MappedArg>
577 return ptEmplace(hint, std::forward_as_tuple(std::forward<KeyArg>(keyArg)),
578 std::forward_as_tuple(std::forward<MappedArg>(mappedArg))).first;
581 template<
typename... KeyArgs,
typename... MappedArgs>
582 std::pair<iterator, bool>
emplace(std::piecewise_construct_t,
583 std::tuple<KeyArgs...> keyArgs, std::tuple<MappedArgs...> mappedArgs)
585 return ptEmplace(
nullptr, std::move(keyArgs), std::move(mappedArgs));
588 template<
typename... KeyArgs,
typename... MappedArgs>
590 std::tuple<KeyArgs...> keyArgs, std::tuple<MappedArgs...> mappedArgs)
592 return ptEmplace(hint, std::move(keyArgs), std::move(mappedArgs)).first;
597 return IteratorProxy(mTreeMap.Remove(ConstIteratorProxy::GetBaseIterator(where)));
607 return IteratorProxy(mTreeMap.Remove(ConstIteratorProxy::GetBaseIterator(first),
608 ConstIteratorProxy::GetBaseIterator(last)));
613 return mTreeMap.Remove(key);
627 template<
typename Map>
630 mTreeMap.MergeFrom(
map.get_nested_container());
639 #ifdef MOMO_HAS_THREE_WAY_COMPARISON
643 return std::lexicographical_compare_three_way(left.begin(), left.end(),
644 right.begin(), right.end());
649 return std::lexicographical_compare(left.
begin(), left.
end(),
657 void ptAssign(std::initializer_list<value_type> values)
659 mTreeMap = TreeMap(values, mTreeMap.GetTreeTraits(), MemManager(
get_allocator()));
662 template<
typename Hint,
typename... KeyArgs,
typename... MappedArgs>
663 std::pair<iterator, bool>
ptEmplace(Hint hint, std::tuple<KeyArgs...>&& keyArgs,
664 std::tuple<MappedArgs...>&& mappedArgs)
666 typedef typename TreeMap::KeyValueTraits
667 ::template ValueCreator<MappedArgs...> MappedCreator;
668 return pvInsert(hint, std::move(keyArgs),
669 MappedCreator(mTreeMap.GetMemManager(), std::move(mappedArgs)));
675 const TreeTraits& treeTraits = mTreeMap.GetTreeTraits();
677 : treeTraits.
IsLess(key1, key2);
680 std::pair<iterator, bool> pvFind(std::nullptr_t ,
const key_type& key)
685 iterator prevIter = std::prev(iter);
686 if (!mTreeMap.GetTreeTraits().IsLess(prevIter->first, key))
687 return { prevIter,
false };
689 return { iter,
true };
694 if (hint !=
begin() && !pvIsOrdered(std::prev(hint)->first, key))
695 return pvFind(
nullptr, key);
696 if (hint !=
end() && !pvIsOrdered(key, hint->first))
701 return pvFind(
nullptr, key);
703 return { IteratorProxy(mTreeMap.MakeMutableIterator(
704 ConstIteratorProxy::GetBaseIterator(hint))),
true };
707 template<
typename Hint,
typename... KeyArgs,
typename MappedCreator>
708 std::pair<iterator, bool> pvInsert(Hint hint, std::tuple<KeyArgs...>&& keyArgs,
709 MappedCreator&& mappedCreator)
711 MemManager& memManager = mTreeMap.GetMemManager();
713 TreeMap::KeyValueTraits::keyAlignment> KeyBuffer;
715 typedef typename KeyManager::template Creator<KeyArgs...> KeyCreator;
717 KeyCreator(memManager, std::move(keyArgs))(keyBuffer.GetPtr());
718 key_type* keyPtr = keyBuffer.template GetPtr<true>();
721 std::pair<iterator, bool> res = pvFind(hint, *keyPtr);
724 KeyManager::Destroy(memManager, *keyPtr);
728 auto valueCreator = [&memManager, &keyPtr, &mappedCreator]
731 KeyManager::Relocate(memManager, *keyPtr, newKey);
735 std::forward<MappedCreator>(mappedCreator)(newMapped);
739 KeyManager::Destroy(memManager, *newKey);
743 TreeMapIterator resIter = mTreeMap.AddCrt(
744 IteratorProxy::GetBaseIterator(res.first), valueCreator);
745 return { IteratorProxy(resIter),
true };
749 if (keyPtr !=
nullptr)
750 KeyManager::Destroy(memManager, *keyPtr);
755 template<
typename Hint,
typename RKey,
typename MappedCreator,
756 typename Key =
typename std::decay<RKey>::type>
758 std::pair<iterator, bool>> pvInsert(Hint hint, std::tuple<RKey>&& key,
759 MappedCreator&& mappedCreator)
761 std::pair<iterator, bool> res = pvFind(hint,
762 static_cast<const key_type&
>(std::get<0>(key)));
765 TreeMapIterator resIter = mTreeMap.AddCrt(IteratorProxy::GetBaseIterator(res.first),
766 std::forward<RKey>(std::get<0>(key)), std::forward<MappedCreator>(mappedCreator));
767 return { IteratorProxy(resIter),
true };
770 template<
typename Iterator,
typename Sentinel>
772 void> pvInsertRange(Iterator
begin, Sentinel
end)
774 mTreeMap.Insert(std::move(
begin), std::move(
end));
777 template<
typename Iterator,
typename Sentinel>
779 void> pvInsertRange(Iterator
begin, Sentinel
end)
781 for (Iterator iter = std::move(
begin); iter !=
end; ++iter)
818 template<
typename TKey,
typename TMapped,
819 typename TLessComparer = std::less<TKey>,
820 typename TAllocator = std::allocator<std::pair<const TKey, TMapped>>,
821 typename TTreeMap = TreeMap<TKey, TMapped, TreeTraitsStd<TKey, TLessComparer>,
822 MemManagerStd<TAllocator>>>
827 typedef TTreeMap TreeMap;
839 using MapBase::MapBase;
866 throw std::out_of_range(
"invalid map key");
874 throw std::out_of_range(
"invalid map key");
878 template<
typename... MappedArgs>
882 std::forward_as_tuple(std::forward<MappedArgs>(mappedArgs)...));
885 template<
typename... MappedArgs>
889 std::forward_as_tuple(std::forward<MappedArgs>(mappedArgs)...)).first;
892 template<
typename... MappedArgs>
896 std::forward_as_tuple(std::forward<MappedArgs>(mappedArgs)...));
899 template<
typename... MappedArgs>
903 std::forward_as_tuple(std::forward<MappedArgs>(mappedArgs)...)).first;
906 template<
typename MappedArg>
909 return pvInsertOrAssign(
nullptr, std::move(key), std::forward<MappedArg>(mappedArg));
912 template<
typename MappedArg>
915 return pvInsertOrAssign(hint, std::move(key), std::forward<MappedArg>(mappedArg)).first;
918 template<
typename MappedArg>
921 return pvInsertOrAssign(
nullptr, key, std::forward<MappedArg>(mappedArg));
924 template<
typename MappedArg>
927 return pvInsertOrAssign(hint, key, std::forward<MappedArg>(mappedArg)).first;
930 template<
typename ValueFilter>
935 return cont.get_nested_container().Remove(pairFilter);
939 template<
typename H
int,
typename RKey,
typename MappedArg>
940 std::pair<iterator, bool> pvInsertOrAssign(Hint hint, RKey&& key, MappedArg&& mappedArg)
943 std::forward_as_tuple(std::forward<RKey>(key)),
944 std::forward_as_tuple(std::forward<MappedArg>(mappedArg)));
946 res.first->second = std::forward<MappedArg>(mappedArg);
959 template<
typename TKey,
typename TMapped,
960 typename TLessComparer = std::less<TKey>,
961 typename TAllocator = std::allocator<std::pair<const TKey, TMapped>>,
962 typename TTreeMap = TreeMap<TKey, TMapped, TreeTraitsStd<TKey, TLessComparer, true>,
963 MemManagerStd<TAllocator>>>
982 using MapBase::MapBase;
997 template<
typename ValueArg = std::pair<key_type, mapped_type>>
1004 template<
typename ValueArg = std::pair<key_type, mapped_type>>
1021 template<
typename Iterator>
1027 void insert(std::initializer_list<value_type> values)
1032 template<
typename... ValueArgs>
1038 template<
typename ValueFilter>
1043 return cont.get_nested_container().Remove(pairFilter);
1047 #ifdef MOMO_HAS_DEDUCTION_GUIDES
1049 #define MOMO_DECLARE_DEDUCTION_GUIDES(map) \
1050 template<typename Iterator, \
1051 typename Value = typename std::iterator_traits<Iterator>::value_type, \
1052 typename Key = std::decay_t<typename Value::first_type>, \
1053 typename Mapped = std::decay_t<typename Value::second_type>, \
1054 typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
1055 typename = internal::ordered_checker<Key, Allocator>> \
1056 map(Iterator, Iterator, Allocator = Allocator()) \
1057 -> map<Key, Mapped, std::less<Key>, Allocator>; \
1058 template<typename Iterator, typename LessComparer, \
1059 typename Value = typename std::iterator_traits<Iterator>::value_type, \
1060 typename Key = std::decay_t<typename Value::first_type>, \
1061 typename Mapped = std::decay_t<typename Value::second_type>, \
1062 typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
1063 typename = internal::ordered_checker<Key, Allocator, LessComparer>> \
1064 map(Iterator, Iterator, LessComparer, Allocator = Allocator()) \
1065 -> map<Key, Mapped, LessComparer, Allocator>; \
1066 template<typename QKey, typename Mapped, \
1067 typename Key = std::remove_const_t<QKey>, \
1068 typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
1069 typename = internal::ordered_checker<Key, Allocator>> \
1070 map(std::initializer_list<std::pair<QKey, Mapped>>, Allocator = Allocator()) \
1071 -> map<Key, Mapped, std::less<Key>, Allocator>; \
1072 template<typename QKey, typename Mapped, typename LessComparer, \
1073 typename Key = std::remove_const_t<QKey>, \
1074 typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
1075 typename = internal::ordered_checker<Key, Allocator, LessComparer>> \
1076 map(std::initializer_list<std::pair<QKey, Mapped>>, LessComparer, Allocator = Allocator()) \
1077 -> map<Key, Mapped, LessComparer, Allocator>;
1079 MOMO_DECLARE_DEDUCTION_GUIDES(map)
1080 MOMO_DECLARE_DEDUCTION_GUIDES(multimap)
1082 #undef MOMO_DECLARE_DEDUCTION_GUIDES
1084 #ifdef MOMO_HAS_CONTAINERS_RANGES
1086 #define MOMO_DECLARE_DEDUCTION_GUIDES_RANGES(map) \
1087 template<std::ranges::input_range Range, \
1088 typename Value = std::ranges::range_value_t<Range>, \
1089 typename Key = std::decay_t<typename Value::first_type>, \
1090 typename Mapped = std::decay_t<typename Value::second_type>, \
1091 typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
1092 typename = internal::ordered_checker<Key, Allocator>> \
1093 map(std::from_range_t, Range&&, Allocator = Allocator()) \
1094 -> map<Key, Mapped, std::less<Key>, Allocator>; \
1095 template<std::ranges::input_range Range, typename LessComparer, \
1096 typename Value = std::ranges::range_value_t<Range>, \
1097 typename Key = std::decay_t<typename Value::first_type>, \
1098 typename Mapped = std::decay_t<typename Value::second_type>, \
1099 typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
1100 typename = internal::ordered_checker<Key, Allocator, LessComparer>> \
1101 map(std::from_range_t, Range&&, LessComparer, Allocator = Allocator()) \
1102 -> map<Key, Mapped, LessComparer, Allocator>;
1104 MOMO_DECLARE_DEDUCTION_GUIDES_RANGES(map)
1105 MOMO_DECLARE_DEDUCTION_GUIDES_RANGES(multimap)
1107 #undef MOMO_DECLARE_DEDUCTION_GUIDES_RANGES
1109 #endif // MOMO_HAS_CONTAINERS_RANGES
1111 #endif // MOMO_HAS_DEDUCTION_GUIDES
1117 #endif // MOMO_INCLUDE_GUARD_STDISH_MAP