Skip to content
Open
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
7 changes: 3 additions & 4 deletions stl/inc/xmemory
Original file line number Diff line number Diff line change
Expand Up @@ -2681,14 +2681,13 @@ concept _Container_compatible_range =
(_RANGES input_range<_Rng>) && convertible_to<_RANGES range_reference_t<_Rng>, _Elem>;

template <_RANGES input_range _Rng>
using _Range_key_type = remove_const_t<typename _RANGES range_value_t<_Rng>::first_type>;
using _Range_key_type = remove_cvref_t<tuple_element_t<0, _RANGES range_value_t<_Rng>>>;

template <_RANGES input_range _Rng>
using _Range_mapped_type = _RANGES range_value_t<_Rng>::second_type;
using _Range_mapped_type = remove_cvref_t<tuple_element_t<1, _RANGES range_value_t<_Rng>>>;

template <_RANGES input_range _Rng>
using _Range_to_alloc_type =
pair<const typename _RANGES range_value_t<_Rng>::first_type, typename _RANGES range_value_t<_Rng>::second_type>;
using _Range_to_alloc_type = pair<const _Range_key_type<_Rng>, _Range_mapped_type<_Rng>>;
#endif // _HAS_CXX23

template <class _Ty,
Expand Down
19 changes: 6 additions & 13 deletions stl/inc/xutility
Original file line number Diff line number Diff line change
Expand Up @@ -1702,32 +1702,25 @@ struct _Is_allocator<_Ty, void_t<typename _Ty::value_type, decltype(_STD declval
: true_type {}; // selected when _Ty resembles an allocator, N4950 [container.reqmts]/69
#endif // ^^^ !_HAS_CXX20 ^^^

// deduction guide utilities (N4950 [associative.general]/2)
// deduction guide utilities (N5050 [associative.general]/2)
template <class _Iter>
using _Guide_key_t =
#if _HAS_CXX23
remove_const_t<tuple_element_t<0, typename iterator_traits<_Iter>::value_type>>;
remove_cvref_t<tuple_element_t<0, typename iterator_traits<_Iter>::value_type>>;
#else // ^^^ _HAS_CXX23 / !_HAS_CXX23 vvv
remove_const_t<typename iterator_traits<_Iter>::value_type::first_type>;
_Remove_cvref_t<typename iterator_traits<_Iter>::value_type::first_type>;
#endif // ^^^ !_HAS_CXX23 ^^^

template <class _Iter>
using _Guide_val_t =
#if _HAS_CXX23
tuple_element_t<1, typename iterator_traits<_Iter>::value_type>;
remove_cvref_t<tuple_element_t<1, typename iterator_traits<_Iter>::value_type>>;
#else // ^^^ _HAS_CXX23 / !_HAS_CXX23 vvv
typename iterator_traits<_Iter>::value_type::second_type;
_Remove_cvref_t<typename iterator_traits<_Iter>::value_type::second_type>;
#endif // ^^^ !_HAS_CXX23 ^^^

template <class _Iter>
using _Guide_pair_t =
#if _HAS_CXX23
pair<add_const_t<tuple_element_t<0, typename iterator_traits<_Iter>::value_type>>,
tuple_element_t<1, typename iterator_traits<_Iter>::value_type>>;
#else // ^^^ _HAS_CXX23 / !_HAS_CXX23 vvv
pair<add_const_t<typename iterator_traits<_Iter>::value_type::first_type>,
typename iterator_traits<_Iter>::value_type::second_type>;
#endif // ^^^ !_HAS_CXX23 ^^^
using _Guide_pair_t = pair<const _Guide_key_t<_Iter>, _Guide_val_t<_Iter>>;

_EXPORT_STD template <class _Ty>
struct _NO_SPECIALIZATIONS_CITING("N5014 [execpol.type]/3") is_execution_policy : false_type {};
Expand Down
183 changes: 176 additions & 7 deletions tests/std/tests/P0429R9_flat_map/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,14 +155,11 @@ class MyAllocator {

template <class T, class U>
struct almost_pair {
using first_type = T;
using second_type = U;
T first_; // to test LWG-4223, this member name is not `first` to avoid accidental relying
U second_; // to test LWG-4223, this member name is not `second` to avoid accidental relying

T first;
U second;

constexpr operator pair<T, U>() const {
return {first, second};
constexpr operator pair<remove_cvref_t<T>, remove_cvref_t<U>>() const {
return {first_, second_};
}
};

Expand Down Expand Up @@ -502,6 +499,33 @@ void test_construction() {
assert(check_value_content(fmmap, {44, 2324, 635462, 7, 433, 5}));
assert(fmmap == fmmap1);
}

almost_pair<int, const int> alter_pairs[]{
{value_types[0].first_, value_types[0].second_},
{value_types[1].first_, value_types[1].second_},
{value_types[2].first_, value_types[2].second_},
{value_types[3].first_, value_types[3].second_},
{value_types[4].first_, value_types[4].second_},
{value_types[5].first_, value_types[5].second_},
};

// Test LWG-4223
{
flat_map fmap{ranges::begin(alter_pairs), ranges::end(alter_pairs)};
flat_map fmap1{ranges::begin(alter_pairs), ranges::end(alter_pairs), less<int>{}};

assert(check_key_content(fmap, {0, 1, 2, 3, 4}));
assert(check_value_content(fmap, {44, 2324, 635462, 433, 5}));
assert(fmap == fmap1);
}
{
flat_multimap fmmap{ranges::begin(alter_pairs), ranges::end(alter_pairs)};
flat_multimap fmmap1{ranges::begin(alter_pairs), ranges::end(alter_pairs), less<int>{}};

assert(check_key_content(fmmap, {0, 1, 2, 2, 3, 4}));
assert(check_value_content(fmmap, {44, 2324, 635462, 7, 433, 5}));
assert(fmmap == fmmap1);
}
}
{
// Test flat_map(iter, iter, const key_comp&, const alloc&)
Expand Down Expand Up @@ -531,6 +555,41 @@ void test_construction() {
assert(check_value_content(fmmap, {44, 2324, 635462, 7, 433, 5}));
assert(fmmap == fmmap1);
}

almost_pair<int, const int&> alter_pairs[]{
{value_types[0].first_, value_types[0].second_},
{value_types[1].first_, value_types[1].second_},
{value_types[2].first_, value_types[2].second_},
{value_types[3].first_, value_types[3].second_},
{value_types[4].first_, value_types[4].second_},
{value_types[5].first_, value_types[5].second_},
};

// Test LWG-4223
{
MyAllocatorCounter allocation_counter;
flat_map_my_allocator fmap{ranges::begin(alter_pairs), ranges::end(alter_pairs), MyAllocator<int>{}};
assert(allocation_counter.check_then_reset());
flat_map_my_allocator fmap1{
ranges::begin(alter_pairs), ranges::end(alter_pairs), less<int>{}, MyAllocator<int>{}};
assert(allocation_counter.check_then_reset());

assert(check_key_content(fmap, {0, 1, 2, 3, 4}));
assert(check_value_content(fmap, {44, 2324, 635462, 433, 5}));
assert(fmap == fmap1);
}
{
MyAllocatorCounter allocation_counter;
flat_multimap_my_allocator fmmap{ranges::begin(alter_pairs), ranges::end(alter_pairs), MyAllocator<int>{}};
assert(allocation_counter.check_then_reset());
flat_multimap_my_allocator fmmap1{
ranges::begin(alter_pairs), ranges::end(alter_pairs), less<int>{}, MyAllocator<int>{}};
assert(allocation_counter.check_then_reset());

assert(check_key_content(fmmap, {0, 1, 2, 2, 3, 4}));
assert(check_value_content(fmmap, {44, 2324, 635462, 7, 433, 5}));
assert(fmmap == fmmap1);
}
}
{
// Test flat_map(from_range_t, _Rng &&, const key_compare&)
Expand All @@ -553,6 +612,33 @@ void test_construction() {
assert(check_value_content(fmmap, {44, 2324, 635462, 7, 433, 5}));
assert(fmmap == fmmap1);
}

almost_pair<int, const int&&> alter_pairs[]{
{value_types[0].first_, move(value_types[0].second_)},
{value_types[1].first_, move(value_types[1].second_)},
{value_types[2].first_, move(value_types[2].second_)},
{value_types[3].first_, move(value_types[3].second_)},
{value_types[4].first_, move(value_types[4].second_)},
{value_types[5].first_, move(value_types[5].second_)},
};

// Test LWG-4223
{
flat_map fmap{from_range, alter_pairs};
flat_map fmap1{from_range, alter_pairs, less<int>{}};

assert(check_key_content(fmap, {0, 1, 2, 3, 4}));
assert(check_value_content(fmap, {44, 2324, 635462, 433, 5}));
assert(fmap == fmap1);
}
{
flat_multimap fmmap{from_range, alter_pairs};
flat_multimap fmmap1{from_range, alter_pairs, less<int>{}};

assert(check_key_content(fmmap, {0, 1, 2, 2, 3, 4}));
assert(check_value_content(fmmap, {44, 2324, 635462, 7, 433, 5}));
assert(fmmap == fmmap1);
}
}
{
// Test flat_map(from_range_t, _Rng &&, const key_compare&, const alloc&)
Expand Down Expand Up @@ -582,6 +668,39 @@ void test_construction() {
assert(check_value_content(fmmap, {44, 2324, 635462, 7, 433, 5}));
assert(fmmap == fmmap1);
}

almost_pair<const int&&, int> alter_pairs[]{
{move(value_types[0].first_), value_types[0].second_},
{move(value_types[1].first_), value_types[1].second_},
{move(value_types[2].first_), value_types[2].second_},
{move(value_types[3].first_), value_types[3].second_},
{move(value_types[4].first_), value_types[4].second_},
{move(value_types[5].first_), value_types[5].second_},
};

// Test LWG-4223
{
MyAllocatorCounter allocation_counter;
flat_map fmap{from_range, alter_pairs, MyAllocator<int>{}};
assert(allocation_counter.check_then_reset());
flat_map fmap1{from_range, alter_pairs, less<int>{}, MyAllocator<int>{}};
assert(allocation_counter.check_then_reset());

assert(check_key_content(fmap, {0, 1, 2, 3, 4}));
assert(check_value_content(fmap, {44, 2324, 635462, 433, 5}));
assert(fmap == fmap1);
}
{
MyAllocatorCounter allocation_counter;
flat_multimap fmmap{from_range, alter_pairs, MyAllocator<int>{}};
assert(allocation_counter.check_then_reset());
flat_multimap fmmap1{from_range, alter_pairs, less<int>{}, MyAllocator<int>{}};
assert(allocation_counter.check_then_reset());

assert(check_key_content(fmmap, {0, 1, 2, 2, 3, 4}));
assert(check_value_content(fmmap, {44, 2324, 635462, 7, 433, 5}));
assert(fmmap == fmmap1);
}
}
{
// Test flat_map(_Sorted_t, iter, iter, comp = key_comp())
Expand All @@ -594,6 +713,17 @@ void test_construction() {
assert(check_key_content(fmap, {0, 1, 2, 3, 4}));
assert(check_value_content(fmap, {44, 2324, 635462, 433, 5}));
assert(fmap == fmap1);

almost_pair<const int&&, int&> alter_pairs[]{
{move(value_types[0].first_), value_types[0].second_},
{move(value_types[1].first_), value_types[1].second_},
{move(value_types[2].first_), value_types[2].second_},
{move(value_types[3].first_), value_types[3].second_},
{move(value_types[4].first_), value_types[4].second_},
};
// Test LWG-4223
flat_map fmap2{sorted_unique, ranges::begin(alter_pairs), ranges::end(alter_pairs), less<int>{}};
assert(fmap2 == fmap);
}
{
almost_pair<int, int> value_types[]{{0, 44}, {1, 2324}, {2, 635462}, {2, 7}, {3, 433}, {4, 5}};
Expand All @@ -604,6 +734,18 @@ void test_construction() {
assert(check_key_content(fmmap, {0, 1, 2, 2, 3, 4}));
assert(check_value_content(fmmap, {44, 2324, 635462, 7, 433, 5}));
assert(fmmap == fmmap1);

almost_pair<const int&&, int&&> alter_pairs[]{
{move(value_types[0].first_), move(value_types[0].second_)},
{move(value_types[1].first_), move(value_types[1].second_)},
{move(value_types[2].first_), move(value_types[2].second_)},
{move(value_types[3].first_), move(value_types[3].second_)},
{move(value_types[4].first_), move(value_types[4].second_)},
{move(value_types[5].first_), move(value_types[5].second_)},
};
// Test LWG-4223
flat_multimap fmmap2{sorted_equivalent, ranges::begin(alter_pairs), ranges::end(alter_pairs), less<int>{}};
assert(fmmap2 == fmmap);
}
}
{
Expand All @@ -623,6 +765,19 @@ void test_construction() {
assert(check_key_content(fmap, {0, 1, 2, 3, 4}));
assert(check_value_content(fmap, {44, 2324, 635462, 433, 5}));
assert(fmap == fmap1);

almost_pair<int&&, int&> alter_pairs[]{
{move(value_types[0].first_), value_types[0].second_},
{move(value_types[1].first_), value_types[1].second_},
{move(value_types[2].first_), value_types[2].second_},
{move(value_types[3].first_), value_types[3].second_},
{move(value_types[4].first_), value_types[4].second_},
};
// Test LWG-4223
flat_map_my_allocator fmap2{
sorted_unique, ranges::begin(alter_pairs), ranges::end(alter_pairs), less<int>{}, MyAllocator<int>{}};
assert(allocation_counter.check_then_reset());
assert(fmap == fmap2);
}
{
almost_pair<int, int> value_types[]{{0, 44}, {1, 2324}, {2, 635462}, {2, 7}, {3, 433}, {4, 5}};
Expand All @@ -638,6 +793,20 @@ void test_construction() {
assert(check_key_content(fmmap, {0, 1, 2, 2, 3, 4}));
assert(check_value_content(fmmap, {44, 2324, 635462, 7, 433, 5}));
assert(fmmap == fmmap1);

almost_pair<int&&, int&&> alter_pairs[]{
{move(value_types[0].first_), move(value_types[0].second_)},
{move(value_types[1].first_), move(value_types[1].second_)},
{move(value_types[2].first_), move(value_types[2].second_)},
{move(value_types[3].first_), move(value_types[3].second_)},
{move(value_types[4].first_), move(value_types[4].second_)},
{move(value_types[5].first_), move(value_types[5].second_)},
};
// Test LWG-4223
flat_multimap_my_allocator fmmap2{sorted_equivalent, ranges::begin(alter_pairs), ranges::end(alter_pairs),
less<int>{}, MyAllocator<int>{}};
assert(allocation_counter.check_then_reset());
assert(fmmap == fmmap2);
}
}
{
Expand Down
Loading