Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 22 additions & 27 deletions libcxx/include/__flat_map/flat_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,15 @@
#define _LIBCPP___FLAT_MAP_FLAT_MAP_H

#include <__algorithm/lexicographical_compare_three_way.h>
#include <__algorithm/lower_bound.h>
#include <__algorithm/min.h>
#include <__algorithm/ranges_adjacent_find.h>
#include <__algorithm/ranges_equal.h>
#include <__algorithm/ranges_inplace_merge.h>
#include <__algorithm/ranges_lower_bound.h>
#include <__algorithm/ranges_partition_point.h>
#include <__algorithm/ranges_sort.h>
#include <__algorithm/ranges_unique.h>
#include <__algorithm/ranges_upper_bound.h>
#include <__algorithm/remove_if.h>
#include <__algorithm/upper_bound.h>
#include <__assert>
#include <__compare/synth_three_way.h>
#include <__concepts/swappable.h>
Expand Down Expand Up @@ -863,6 +862,13 @@ class flat_map {
__containers_.values.erase(__containers_.values.begin() + __dist, __containers_.values.end());
}

template <class _Self, class _KeyIter>
_LIBCPP_HIDE_FROM_ABI static auto __corresponding_mapped_it(_Self&& __self, _KeyIter&& __key_iter) {
return __self.__containers_.values.begin() +
static_cast<ranges::range_difference_t<mapped_container_type>>(
ranges::distance(__self.__containers_.keys.begin(), __key_iter));
}

template <bool _WasSorted, class _InputIterator, class _Sentinel>
_LIBCPP_HIDE_FROM_ABI void __append_sort_merge_unique(_InputIterator __first, _Sentinel __last) {
auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; });
Expand Down Expand Up @@ -903,7 +909,8 @@ class flat_map {

template <class _Self, class _Kp>
_LIBCPP_HIDE_FROM_ABI static auto __key_equal_range(_Self&& __self, const _Kp& __key) {
auto __it = ranges::lower_bound(__self.__containers_.keys, __key, __self.__compare_);
auto __it =
std::lower_bound(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __key, __self.__compare_);
auto __last = __self.__containers_.keys.end();
if (__it == __last || __self.__compare_(__key, *__it)) {
return std::make_pair(__it, __it);
Expand All @@ -914,42 +921,30 @@ class flat_map {
template <class _Self, class _Kp>
_LIBCPP_HIDE_FROM_ABI static auto __equal_range_impl(_Self&& __self, const _Kp& __key) {
auto [__key_first, __key_last] = __key_equal_range(__self, __key);

const auto __make_mapped_iter = [&](const auto& __key_iter) {
return __self.__containers_.values.begin() +
static_cast<ranges::range_difference_t<mapped_container_type>>(
ranges::distance(__self.__containers_.keys.begin(), __key_iter));
};

using __iterator_type = ranges::iterator_t<decltype(__self)>;
return std::make_pair(__iterator_type(__key_first, __make_mapped_iter(__key_first)),
__iterator_type(__key_last, __make_mapped_iter(__key_last)));
using __iterator_type = ranges::iterator_t<decltype(__self)>;
return std::make_pair(__iterator_type(__key_first, __corresponding_mapped_it(__self, __key_first)),
__iterator_type(__key_last, __corresponding_mapped_it(__self, __key_last)));
}

template <class _Res, class _Self, class _Kp>
_LIBCPP_HIDE_FROM_ABI static _Res __lower_bound(_Self&& __self, _Kp& __x) {
return __binary_search<_Res>(__self, ranges::lower_bound, __x);
auto __key_iter =
std::lower_bound(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __x, __self.__compare_);
auto __mapped_iter = __corresponding_mapped_it(__self, __key_iter);
return _Res(std::move(__key_iter), std::move(__mapped_iter));
}

template <class _Res, class _Self, class _Kp>
_LIBCPP_HIDE_FROM_ABI static _Res __upper_bound(_Self&& __self, _Kp& __x) {
return __binary_search<_Res>(__self, ranges::upper_bound, __x);
}

template <class _Res, class _Self, class _Fn, class _Kp>
_LIBCPP_HIDE_FROM_ABI static _Res __binary_search(_Self&& __self, _Fn __search_fn, _Kp& __x) {
auto __key_iter = __search_fn(__self.__containers_.keys, __x, __self.__compare_);
auto __mapped_iter =
__self.__containers_.values.begin() +
static_cast<ranges::range_difference_t<mapped_container_type>>(
ranges::distance(__self.__containers_.keys.begin(), __key_iter));

auto __key_iter =
std::upper_bound(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __x, __self.__compare_);
auto __mapped_iter = __corresponding_mapped_it(__self, __key_iter);
return _Res(std::move(__key_iter), std::move(__mapped_iter));
}

template <class _KeyArg, class... _MArgs>
_LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __try_emplace(_KeyArg&& __key, _MArgs&&... __mapped_args) {
auto __key_it = ranges::lower_bound(__containers_.keys, __key, __compare_);
auto __key_it = std::lower_bound(__containers_.keys.begin(), __containers_.keys.end(), __key, __compare_);
auto __mapped_it = __containers_.values.begin() + ranges::distance(__containers_.keys.begin(), __key_it);

if (__key_it == __containers_.keys.end() || __compare_(__key, *__key_it)) {
Expand Down
23 changes: 12 additions & 11 deletions libcxx/include/__flat_map/flat_multimap.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,16 @@
#ifndef _LIBCPP___FLAT_MAP_FLAT_MULTIMAP_H
#define _LIBCPP___FLAT_MAP_FLAT_MULTIMAP_H

#include <__algorithm/equal_range.h>
#include <__algorithm/lexicographical_compare_three_way.h>
#include <__algorithm/lower_bound.h>
#include <__algorithm/min.h>
#include <__algorithm/ranges_equal.h>
#include <__algorithm/ranges_equal_range.h>
#include <__algorithm/ranges_inplace_merge.h>
#include <__algorithm/ranges_is_sorted.h>
#include <__algorithm/ranges_lower_bound.h>
#include <__algorithm/ranges_partition_point.h>
#include <__algorithm/ranges_sort.h>
#include <__algorithm/ranges_unique.h>
#include <__algorithm/ranges_upper_bound.h>
#include <__algorithm/remove_if.h>
#include <__algorithm/upper_bound.h>
#include <__assert>
#include <__compare/synth_three_way.h>
#include <__concepts/convertible_to.h>
Expand Down Expand Up @@ -443,7 +441,7 @@ class flat_multimap {
is_move_constructible_v<mapped_type>
_LIBCPP_HIDE_FROM_ABI iterator emplace(_Args&&... __args) {
std::pair<key_type, mapped_type> __pair(std::forward<_Args>(__args)...);
auto __key_it = ranges::upper_bound(__containers_.keys, __pair.first, __compare_);
auto __key_it = std::upper_bound(__containers_.keys.begin(), __containers_.keys.end(), __pair.first, __compare_);
auto __mapped_it = __corresponding_mapped_it(*this, __key_it);

return __flat_map_utils::__emplace_exact_pos(
Expand Down Expand Up @@ -473,7 +471,7 @@ class flat_multimap {
// |
// hint
// We want to insert "2" after the last existing "2"
__key_iter = ranges::upper_bound(__containers_.keys.begin(), __key_iter, __pair.first, __compare_);
__key_iter = std::upper_bound(__containers_.keys.begin(), __key_iter, __pair.first, __compare_);
__mapped_iter = __corresponding_mapped_it(*this, __key_iter);
} else {
_LIBCPP_ASSERT_INTERNAL(!__prev_larger && __next_smaller, "this means that the multimap is not sorted");
Expand All @@ -485,7 +483,7 @@ class flat_multimap {
// |
// hint
// We want to insert "2" before the first existing "2"
__key_iter = ranges::lower_bound(__key_iter, __containers_.keys.end(), __pair.first, __compare_);
__key_iter = std::lower_bound(__key_iter, __containers_.keys.end(), __pair.first, __compare_);
__mapped_iter = __corresponding_mapped_it(*this, __key_iter);
}
return __flat_map_utils::__emplace_exact_pos(
Expand Down Expand Up @@ -804,7 +802,8 @@ class flat_multimap {

template <class _Self, class _Kp>
_LIBCPP_HIDE_FROM_ABI static auto __equal_range_impl(_Self&& __self, const _Kp& __key) {
auto [__key_first, __key_last] = ranges::equal_range(__self.__containers_.keys, __key, __self.__compare_);
auto [__key_first, __key_last] =
std::equal_range(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __key, __self.__compare_);

using __iterator_type = ranges::iterator_t<decltype(__self)>;
return std::make_pair(__iterator_type(__key_first, __corresponding_mapped_it(__self, __key_first)),
Expand All @@ -813,14 +812,16 @@ class flat_multimap {

template <class _Res, class _Self, class _Kp>
_LIBCPP_HIDE_FROM_ABI static _Res __lower_bound(_Self&& __self, _Kp& __x) {
auto __key_iter = ranges::lower_bound(__self.__containers_.keys, __x, __self.__compare_);
auto __key_iter =
std::lower_bound(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __x, __self.__compare_);
auto __mapped_iter = __corresponding_mapped_it(__self, __key_iter);
return _Res(std::move(__key_iter), std::move(__mapped_iter));
}

template <class _Res, class _Self, class _Kp>
_LIBCPP_HIDE_FROM_ABI static _Res __upper_bound(_Self&& __self, _Kp& __x) {
auto __key_iter = ranges::upper_bound(__self.__containers_.keys, __x, __self.__compare_);
auto __key_iter =
std::upper_bound(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __x, __self.__compare_);
auto __mapped_iter = __corresponding_mapped_it(__self, __key_iter);
return _Res(std::move(__key_iter), std::move(__mapped_iter));
}
Expand Down
1 change: 0 additions & 1 deletion libcxx/include/__flat_set/flat_set.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include <__algorithm/ranges_adjacent_find.h>
#include <__algorithm/ranges_equal.h>
#include <__algorithm/ranges_inplace_merge.h>
#include <__algorithm/ranges_partition_point.h>
#include <__algorithm/ranges_sort.h>
#include <__algorithm/ranges_unique.h>
#include <__algorithm/remove_if.h>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,13 @@ int main(int, char**) {
TEST_IGNORE_NODISCARD m.at(Transparent<int>{3});
assert(transparent_used);
}
{
// LWG4239 std::string and C string literal
using M = std::flat_map<std::string, int, std::less<>>;
M m{{"alpha", 1}, {"beta", 2}, {"epsilon", 1}, {"eta", 3}, {"gamma", 3}};
int& x = m.at("alpha");
assert(x == 1);
}

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,13 @@ int main(int, char**) {
m[ConvertibleTransparent<int>{3}];
assert(transparent_used);
}
{
// LWG4239 std::string and C string literal
using M = std::flat_map<std::string, int, std::less<>>;
M m{{"alpha", 1}, {"beta", 2}, {"epsilon", 1}, {"eta", 3}, {"gamma", 3}};
int& x = m["alpha"];
assert(x == 1);
}
{
auto index_func = [](auto& m, auto key_arg, auto value_arg) {
using FlatMap = std::decay_t<decltype(m)>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,13 @@ int main(int, char**) {
};
test_erase_exception_guarantee(erase_transparent);
}
{
// LWG4239 std::string and C string literal
using M = std::flat_map<std::string, int, std::less<>>;
M m{{"alpha", 1}, {"beta", 2}, {"epsilon", 1}, {"eta", 3}, {"gamma", 3}};
auto n = m.erase("beta");
assert(n == 1);
}

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,18 @@ int main(int, char**) {
};
test_emplace_exception_guarantee(insert_or_assign_iter);
}
{
// LWG4239 std::string and C string literal
using M = std::flat_map<std::string, int, std::less<>>;
M m{{"alpha", 1}, {"beta", 2}, {"epsilon", 1}, {"eta", 3}, {"gamma", 3}};
auto [it, inserted] = m.insert_or_assign("alpha", 2);
assert(!inserted);
assert(it == m.begin());
assert(it->second == 2);
auto it2 = m.insert_or_assign(m.begin(), "beta2", 2);
assert(it2 == m.begin() + 2);
assert(it2->second == 2);
}

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -163,5 +163,15 @@ int main(int, char**) {
};
test_emplace_exception_guarantee(insert_func_iter);
}
{
// LWG4239 std::string and C string literal
using M = std::flat_map<std::string, int, std::less<>>;
M m{{"alpha", 1}, {"beta", 2}, {"epsilon", 1}, {"eta", 3}, {"gamma", 3}};
auto [it, inserted] = m.insert({"alpha", 1});
assert(!inserted);
assert(it == m.begin());
auto it2 = m.insert(m.begin(), {"beta2", 2});
assert(it2 == m.begin() + 2);
}
return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,17 @@ int main(int, char**) {
assert(p->second == 3);
assert(transparent_used);
}
{
// LWG4239 std::string and C string literal
using M = std::flat_map<std::string, int, std::less<>>;
M m{{"alpha", 1}, {"beta", 2}, {"epsilon", 1}, {"eta", 3}, {"gamma", 3}};
auto [it1, inserted] = m.try_emplace("charlie", 4);
assert(it1 == m.begin() + 2);
assert(inserted);

auto it2 = m.try_emplace(m.begin(), "beta2", 2);
assert(it2 == m.begin() + 2);
}
{
auto try_emplace = [](auto& m, auto key_arg, auto value_arg) {
using M = std::decay_t<decltype(m)>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include <cassert>
#include <flat_map>
#include <functional>
#include <string>
#include <utility>
#include <deque>
Expand Down Expand Up @@ -67,5 +68,12 @@ int main(int, char**) {
assert(b);
assert(transparent_used);
}
{
// LWG4239 std::string and C string literal
using M = std::flat_map<std::string, int, std::less<>>;
M m{{"alpha", 1}, {"beta", 2}, {"epsilon", 1}, {"eta", 3}, {"gamma", 3}};
assert(m.contains("beta") == true);
assert(m.contains("charlie") == false);
}
return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <cassert>
#include <deque>
#include <flat_map>
#include <functional>
#include <string>
#include <utility>

Expand Down Expand Up @@ -67,6 +68,13 @@ int main(int, char**) {
assert(n == 1);
assert(transparent_used);
}
{
// LWG4239 std::string and C string literal
using M = std::flat_map<std::string, int, std::less<>>;
M m{{"alpha", 1}, {"beta", 2}, {"epsilon", 1}, {"eta", 3}, {"gamma", 3}};
assert(m.count("alpha") == 1);
assert(m.count("charlie") == 0);
}

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <cassert>
#include <deque>
#include <flat_map>
#include <functional>
#include <string>
#include <utility>

Expand Down Expand Up @@ -95,6 +96,14 @@ int main(int, char**) {
assert(p.first != p.second);
assert(transparent_used);
}
{
// LWG4239 std::string and C string literal
using M = std::flat_map<std::string, int, std::less<>>;
M m{{"alpha", 1}, {"beta", 2}, {"epsilon", 1}, {"eta", 3}, {"gamma", 3}};
auto [first, last] = m.equal_range("beta");
assert(first == m.begin() + 1);
assert(last == m.begin() + 2);
}

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <cassert>
#include <deque>
#include <flat_map>
#include <functional>
#include <string>
#include <utility>

Expand Down Expand Up @@ -83,6 +84,13 @@ int main(int, char**) {
assert(it != m.end());
assert(transparent_used);
}
{
// LWG4239 std::string and C string literal
using M = std::flat_map<std::string, int, std::less<>>;
M m{{"alpha", 1}, {"beta", 2}, {"epsilon", 1}, {"eta", 3}, {"gamma", 3}};
auto it = m.find("beta");
assert(it == m.begin() + 1);
}

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <cassert>
#include <deque>
#include <flat_map>
#include <functional>
#include <string>
#include <utility>

Expand Down Expand Up @@ -90,6 +91,13 @@ int main(int, char**) {
assert(it != m.end());
assert(transparent_used);
}
{
// LWG4239 std::string and C string literal
using M = std::flat_map<std::string, int, std::less<>>;
M m{{"alpha", 1}, {"beta", 2}, {"epsilon", 1}, {"eta", 3}, {"gamma", 3}};
auto it = m.lower_bound("charlie");
assert(it == m.begin() + 2);
}

return 0;
}
Loading
Loading