19 #ifndef MOMO_INCLUDE_GUARD_STDISH_MAP
20 #define MOMO_INCLUDE_GUARD_STDISH_MAP
23 #include MOMO_PARENT_HEADER(TreeMap)
33 template<
typename TKey,
typename TLessComparer>
41 template<
typename Value>
42 bool operator()(
const Value& value1,
const Value& value2)
const
45 typename std::decay<decltype(value1.first)>::type>::value);
46 return comp(value1.first, value2.first);
59 template<
typename TTreeMap>
63 typedef TTreeMap TreeMap;
79 typedef std::pair<const key_type, mapped_type>
value_type;
80 typedef typename std::allocator_traits<typename MemManager::ByteAllocator>
104 template<
typename KeyArg>
105 struct IsValidKeyArg :
public TreeTraits::template IsValidKeyArg<KeyArg>
115 struct IteratorProxy :
private iterator
133 : mTreeMap(TreeTraits(), MemManager(alloc))
139 : mTreeMap(TreeTraits(lessComp), MemManager(alloc))
143 template<
typename Iterator>
150 template<
typename Iterator>
170 #ifdef MOMO_HAS_CONTAINERS_RANGES
171 template<std::ranges::input_range Range>
172 requires std::convertible_to<std::ranges::range_reference_t<Range>,
value_type>
176 insert_range(std::forward<Range>(values));
179 template<std::ranges::input_range Range>
180 requires std::convertible_to<std::ranges::range_reference_t<Range>,
value_type>
185 insert_range(std::forward<Range>(values));
187 #endif // MOMO_HAS_CONTAINERS_RANGES
195 : mTreeMap(right.mTreeMap.GetTreeTraits(), MemManager(alloc))
197 if (right.get_allocator() == alloc)
199 mTreeMap.Swap(right.mTreeMap);
203 mTreeMap.MergeFrom(right.mTreeMap);
209 : mTreeMap(right.mTreeMap)
214 : mTreeMap(right.mTreeMap, MemManager(alloc))
308 return mTreeMap.GetTreeTraits().GetLessComparer();
315 explicit ValueCompareProxy(
const key_compare& keyComp)
320 return ValueCompareProxy(
key_comp());
325 return allocator_type(mTreeMap.GetMemManager().GetByteAllocator());
330 return std::allocator_traits<allocator_type>::max_size(
get_allocator());
335 return mTreeMap.GetCount();
340 return mTreeMap.IsEmpty();
358 template<
typename KeyArg>
365 template<
typename KeyArg>
374 return mTreeMap.GetKeyCount(key);
377 template<
typename KeyArg>
381 return mTreeMap.GetKeyCount(key);
386 return mTreeMap.ContainsKey(key);
389 template<
typename KeyArg>
393 return mTreeMap.ContainsKey(key);
406 template<
typename KeyArg>
413 template<
typename KeyArg>
430 template<
typename KeyArg>
437 template<
typename KeyArg>
453 if (iter ==
end() || mTreeMap.GetTreeTraits().IsLess(key, iter->first))
454 return { iter, iter };
455 return { iter, std::next(iter) };
468 if (iter ==
end() || mTreeMap.GetTreeTraits().IsLess(key, iter->first))
469 return { iter, iter };
470 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());
520 IteratorProxy::GetBaseIterator(res.first),
521 std::move(NodeTypeProxy::GetExtractedPair(node))));
524 template<
typename Iterator>
525 void insert(Iterator first, Iterator last)
527 pvInsertRange(first, last);
530 void insert(std::initializer_list<value_type> values)
532 mTreeMap.Insert(values.begin(), values.end());
535 #ifdef MOMO_HAS_CONTAINERS_RANGES
536 template<std::ranges::input_range Range>
537 requires std::convertible_to<std::ranges::range_reference_t<Range>,
value_type>
538 void insert_range(Range&& values)
540 pvInsertRange(std::ranges::begin(values), std::ranges::end(values));
542 #endif // MOMO_HAS_CONTAINERS_RANGES
546 return ptEmplace(
nullptr, std::tuple<>(), std::tuple<>());
551 return ptEmplace(hint, std::tuple<>(), std::tuple<>()).first;
554 template<
typename ValueArg>
555 std::pair<iterator, bool>
emplace(ValueArg&& valueArg)
558 std::forward_as_tuple(std::get<0>(std::forward<ValueArg>(valueArg))),
559 std::forward_as_tuple(std::get<1>(std::forward<ValueArg>(valueArg))));
562 template<
typename ValueArg>
566 std::forward_as_tuple(std::get<0>(std::forward<ValueArg>(valueArg))),
567 std::forward_as_tuple(std::get<1>(std::forward<ValueArg>(valueArg)))).first;
570 template<
typename KeyArg,
typename MappedArg>
571 std::pair<iterator, bool>
emplace(KeyArg&& keyArg, MappedArg&& mappedArg)
573 return ptEmplace(
nullptr, std::forward_as_tuple(std::forward<KeyArg>(keyArg)),
574 std::forward_as_tuple(std::forward<MappedArg>(mappedArg)));
577 template<
typename KeyArg,
typename MappedArg>
580 return ptEmplace(hint, std::forward_as_tuple(std::forward<KeyArg>(keyArg)),
581 std::forward_as_tuple(std::forward<MappedArg>(mappedArg))).first;
584 template<
typename... KeyArgs,
typename... MappedArgs>
585 std::pair<iterator, bool>
emplace(std::piecewise_construct_t,
586 std::tuple<KeyArgs...> keyArgs, std::tuple<MappedArgs...> mappedArgs)
588 return ptEmplace(
nullptr, std::move(keyArgs), std::move(mappedArgs));
591 template<
typename... KeyArgs,
typename... MappedArgs>
593 std::tuple<KeyArgs...> keyArgs, std::tuple<MappedArgs...> mappedArgs)
595 return ptEmplace(hint, std::move(keyArgs), std::move(mappedArgs)).first;
601 mTreeMap.Remove(ConstIteratorProxy::GetBaseIterator(where)));
612 ConstIteratorProxy::GetBaseIterator(first),
613 ConstIteratorProxy::GetBaseIterator(last)));
618 return mTreeMap.Remove(key);
621 template<
typename ValueFilter>
626 return cont.mTreeMap.Remove(pairFilter);
640 template<
typename Map>
643 mTreeMap.MergeFrom(
map.get_nested_container());
652 #ifdef MOMO_HAS_THREE_WAY_COMPARISON
656 return std::lexicographical_compare_three_way(left.begin(), left.end(),
657 right.begin(), right.end());
662 return std::lexicographical_compare(left.
begin(), left.
end(),
670 void ptAssign(std::initializer_list<value_type> values)
672 mTreeMap = TreeMap(values, mTreeMap.GetTreeTraits(), MemManager(
get_allocator()));
675 template<
typename Hint,
typename... KeyArgs,
typename... MappedArgs>
676 std::pair<iterator, bool>
ptEmplace(Hint hint, std::tuple<KeyArgs...>&& keyArgs,
677 std::tuple<MappedArgs...>&& mappedArgs)
679 typedef typename TreeMap::KeyValueTraits
680 ::template ValueCreator<MappedArgs...> MappedCreator;
681 return pvInsert(hint, std::move(keyArgs),
682 MappedCreator(mTreeMap.GetMemManager(), std::move(mappedArgs)));
688 const TreeTraits& treeTraits = mTreeMap.GetTreeTraits();
690 : treeTraits.
IsLess(key1, key2);
693 std::pair<iterator, bool> pvFind(std::nullptr_t ,
const key_type& key)
700 iterator prevIter = std::prev(iter);
701 if (!mTreeMap.GetTreeTraits().IsLess(prevIter->first, key))
702 return { prevIter,
false };
705 return { iter,
true };
710 if (hint !=
begin() && !pvIsOrdered(std::prev(hint)->first, key))
711 return pvFind(
nullptr, key);
712 if (hint !=
end() && !pvIsOrdered(key, hint->first))
717 return pvFind(
nullptr, key);
720 ConstIteratorProxy::GetBaseIterator(hint))),
true };
723 template<
typename Hint,
typename... KeyArgs,
typename MappedCreator>
724 std::pair<iterator, bool> pvInsert(Hint hint, std::tuple<KeyArgs...>&& keyArgs,
725 MappedCreator&& mappedCreator)
727 MemManager& memManager = mTreeMap.GetMemManager();
729 TreeMap::KeyValueTraits::keyAlignment> KeyBuffer;
731 typedef typename KeyManager::template Creator<KeyArgs...> KeyCreator;
733 KeyCreator(memManager, std::move(keyArgs))(keyBuffer.GetPtr());
734 typename KeyManager::DestroyFinalizer keyFin(&memManager, keyBuffer.Get());
735 std::pair<iterator, bool> res = pvFind(hint, keyBuffer.Get());
740 KeyManager::Relocate(*keyFin.GetMemManager(), *keyFin.GetPtr(), newKey);
742 typename KeyManager::DestroyFinalizer newKeyFin(keyFin.GetMemManager(), *newKey);
743 std::forward<MappedCreator>(mappedCreator)(newMapped);
744 newKeyFin.ResetPtr();
746 TreeMapIterator resIter = mTreeMap.AddCrt(
747 IteratorProxy::GetBaseIterator(res.first), valueCreator);
751 template<
typename Hint,
typename RKey,
typename MappedCreator,
752 typename Key =
typename std::decay<RKey>::type>
754 std::pair<iterator, bool>> pvInsert(Hint hint, std::tuple<RKey>&& key,
755 MappedCreator&& mappedCreator)
757 std::pair<iterator, bool> res = pvFind(hint,
758 static_cast<const key_type&
>(std::get<0>(key)));
761 TreeMapIterator resIter = mTreeMap.AddCrt(IteratorProxy::GetBaseIterator(res.first),
762 std::forward<RKey>(std::get<0>(key)), std::forward<MappedCreator>(mappedCreator));
766 template<
typename Iterator,
typename Sentinel>
768 void> pvInsertRange(Iterator
begin, Sentinel
end)
770 mTreeMap.Insert(std::move(
begin), std::move(
end));
773 template<
typename Iterator,
typename Sentinel>
775 void> pvInsertRange(Iterator
begin, Sentinel
end)
777 for (Iterator iter = std::move(
begin); iter !=
end; ++iter)
786 template<
typename TTreeMap>
790 typedef TTreeMap TreeMap;
801 using MapAdaptorBase::MapAdaptorBase;
828 MOMO_THROW(std::out_of_range(
"invalid map key"));
836 MOMO_THROW(std::out_of_range(
"invalid map key"));
840 template<
typename... MappedArgs>
844 std::forward_as_tuple(std::forward<MappedArgs>(mappedArgs)...));
847 template<
typename... MappedArgs>
851 std::forward_as_tuple(std::forward<MappedArgs>(mappedArgs)...)).first;
854 template<
typename... MappedArgs>
858 std::forward_as_tuple(std::forward<MappedArgs>(mappedArgs)...));
861 template<
typename... MappedArgs>
865 std::forward_as_tuple(std::forward<MappedArgs>(mappedArgs)...)).first;
868 template<
typename MappedArg>
871 return pvInsertOrAssign(
nullptr, std::move(key), std::forward<MappedArg>(mappedArg));
874 template<
typename MappedArg>
877 return pvInsertOrAssign(hint, std::move(key), std::forward<MappedArg>(mappedArg)).first;
880 template<
typename MappedArg>
883 return pvInsertOrAssign(
nullptr, key, std::forward<MappedArg>(mappedArg));
886 template<
typename MappedArg>
889 return pvInsertOrAssign(hint, key, std::forward<MappedArg>(mappedArg)).first;
893 template<
typename H
int,
typename RKey,
typename MappedArg>
894 std::pair<iterator, bool> pvInsertOrAssign(Hint hint, RKey&& key, MappedArg&& mappedArg)
897 std::forward_as_tuple(std::forward<RKey>(key)),
898 std::forward_as_tuple(std::forward<MappedArg>(mappedArg)));
900 res.first->second = std::forward<MappedArg>(mappedArg);
905 template<
typename TTreeMap>
922 using MapAdaptorBase::MapAdaptorBase;
937 template<
typename ValueArg = std::pair<key_type, mapped_type>>
944 template<
typename ValueArg = std::pair<key_type, mapped_type>>
961 template<
typename Iterator>
962 void insert(Iterator first, Iterator last)
967 void insert(std::initializer_list<value_type> values)
972 template<
typename... ValueArgs>
1007 template<
typename TKey,
typename TMapped,
1008 typename TLessComparer = std::less<TKey>,
1009 typename TAllocator = std::allocator<std::pair<const TKey, TMapped>>>
1011 TreeTraitsStd<TKey, TLessComparer>, MemManagerStd<TAllocator>>>
1018 using MapAdaptor::MapAdaptor;
1020 map&
operator=(std::initializer_list<typename MapAdaptor::value_type> values)
1040 template<
typename TKey,
typename TMapped,
1041 typename TLessComparer = std::less<TKey>,
1042 typename TAllocator = std::allocator<std::pair<const TKey, TMapped>>>
1044 TreeTraitsStd<TKey, TLessComparer, true>, MemManagerStd<TAllocator>>>
1051 using MultiMapAdaptor::MultiMapAdaptor;
1065 #ifdef MOMO_HAS_DEDUCTION_GUIDES
1067 #define MOMO_DECLARE_DEDUCTION_GUIDES(map) \
1068 template<typename Iterator, \
1069 typename Value = typename std::iterator_traits<Iterator>::value_type, \
1070 typename Key = std::decay_t<typename Value::first_type>, \
1071 typename Mapped = std::decay_t<typename Value::second_type>, \
1072 typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
1073 typename = internal::tree_checker<Key, Allocator>> \
1074 map(Iterator, Iterator, Allocator = Allocator()) \
1075 -> map<Key, Mapped, std::less<Key>, Allocator>; \
1076 template<typename Iterator, typename LessComparer, \
1077 typename Value = typename std::iterator_traits<Iterator>::value_type, \
1078 typename Key = std::decay_t<typename Value::first_type>, \
1079 typename Mapped = std::decay_t<typename Value::second_type>, \
1080 typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
1081 typename = internal::tree_checker<Key, Allocator, LessComparer>> \
1082 map(Iterator, Iterator, LessComparer, Allocator = Allocator()) \
1083 -> map<Key, Mapped, LessComparer, Allocator>; \
1084 template<typename QKey, typename Mapped, \
1085 typename Key = std::remove_const_t<QKey>, \
1086 typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
1087 typename = internal::tree_checker<Key, Allocator>> \
1088 map(std::initializer_list<std::pair<QKey, Mapped>>, Allocator = Allocator()) \
1089 -> map<Key, Mapped, std::less<Key>, Allocator>; \
1090 template<typename QKey, typename Mapped, typename LessComparer, \
1091 typename Key = std::remove_const_t<QKey>, \
1092 typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
1093 typename = internal::tree_checker<Key, Allocator, LessComparer>> \
1094 map(std::initializer_list<std::pair<QKey, Mapped>>, LessComparer, Allocator = Allocator()) \
1095 -> map<Key, Mapped, LessComparer, Allocator>; \
1096 template<typename Key, typename Mapped, typename LessComparer, typename Allocator> \
1097 map(map<Key, Mapped, LessComparer, Allocator>, momo::internal::Identity<Allocator>) \
1098 -> map<Key, Mapped, LessComparer, Allocator>;
1100 MOMO_DECLARE_DEDUCTION_GUIDES(map)
1101 MOMO_DECLARE_DEDUCTION_GUIDES(multimap)
1103 #undef MOMO_DECLARE_DEDUCTION_GUIDES
1105 #ifdef MOMO_HAS_CONTAINERS_RANGES
1107 #define MOMO_DECLARE_DEDUCTION_GUIDES_RANGES(map) \
1108 template<std::ranges::input_range Range, \
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::tree_checker<Key, Allocator>> \
1114 map(std::from_range_t, Range&&, Allocator = Allocator()) \
1115 -> map<Key, Mapped, std::less<Key>, Allocator>; \
1116 template<std::ranges::input_range Range, typename LessComparer, \
1117 typename Value = std::ranges::range_value_t<Range>, \
1118 typename Key = std::decay_t<typename Value::first_type>, \
1119 typename Mapped = std::decay_t<typename Value::second_type>, \
1120 typename Allocator = std::allocator<std::pair<const Key, Mapped>>, \
1121 typename = internal::tree_checker<Key, Allocator, LessComparer>> \
1122 map(std::from_range_t, Range&&, LessComparer, Allocator = Allocator()) \
1123 -> map<Key, Mapped, LessComparer, Allocator>;
1125 MOMO_DECLARE_DEDUCTION_GUIDES_RANGES(map)
1126 MOMO_DECLARE_DEDUCTION_GUIDES_RANGES(multimap)
1128 #undef MOMO_DECLARE_DEDUCTION_GUIDES_RANGES
1130 #endif // MOMO_HAS_CONTAINERS_RANGES
1132 #endif // MOMO_HAS_DEDUCTION_GUIDES
1138 #endif // MOMO_INCLUDE_GUARD_STDISH_MAP