// 4223. Deduction guides for maps are mishandling tuples and references
template<ranges::input_range _Range>
using __range_key_type
- = remove_const_t<tuple_element_t<0, ranges::range_value_t<_Range>>>;
+ = remove_cvref_t<tuple_element_t<0, ranges::range_value_t<_Range>>>;
template<ranges::input_range _Range>
using __range_mapped_type
- = tuple_element_t<1, ranges::range_value_t<_Range>>;
+ = remove_cvref_t<tuple_element_t<1, ranges::range_value_t<_Range>>>;
// The allocator's value_type for map-like containers.
template<ranges::input_range _Range>
#if __cpp_deduction_guides >= 201606
// These helper traits are used for deduction guides
// of associative containers.
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 4223. Deduction guides for maps are mishandling tuples and references
template<typename _InputIterator>
- using __iter_key_t = remove_const_t<
+ using __iter_key_t = __remove_cvref_t<
#ifdef __glibcxx_tuple_like // >= C++23
tuple_element_t<0, typename iterator_traits<_InputIterator>::value_type>>;
#else
#endif
template<typename _InputIterator>
- using __iter_val_t
+ using __iter_val_t = __remove_cvref_t<
#ifdef __glibcxx_tuple_like // >= C++23
- = tuple_element_t<1, typename iterator_traits<_InputIterator>::value_type>;
+ tuple_element_t<1, typename iterator_traits<_InputIterator>::value_type>>;
#else
- = typename iterator_traits<_InputIterator>::value_type::second_type;
+ typename iterator_traits<_InputIterator>::value_type::second_type>;
#endif
template<typename _T1, typename _T2>
std::vector<long, __gnu_test::SimpleAllocator<long>>,
std::vector<float, __gnu_test::SimpleAllocator<float>>>>);
- // LWG4223: deduces flat_map<long, float const>, which in turn instantiates
- // std::vector<cosnt float> that is ill-formed.
- // __gnu_test::test_input_range<std::pair<const long, const float>> r2(0, 0);
- // std::flat_map it5(r2.begin(), r2.begin());
- // std::flat_map fr5(std::from_range, r2);
-
- // LWG4223: deduces flat_map<const long&, float&>
- //__gnu_test::test_input_range<std::pair<const long&, float&>> r3(0, 0);
- // std::flat_map it6(r3.begin(), r3.begin());
- // std::flat_map fr6(std::from_range, r3);
+ __gnu_test::test_input_range<std::pair<const long, const float>> r2(0, 0);
+ std::flat_map it5(r2.begin(), r2.begin());
+ static_assert(std::is_same_v<decltype(it5), std::flat_map<long, float>>);
+ std::flat_map fr5(std::from_range, r2);
+ static_assert(std::is_same_v<decltype(fr5), std::flat_map<long, float>>);
+
+ __gnu_test::test_input_range<std::pair<const long&, float&>> r3(0, 0);
+ std::flat_map it6(r3.begin(), r3.begin());
+ static_assert(std::is_same_v<decltype(it6), std::flat_map<long, float>>);
+ std::flat_map fr6(std::from_range, r3);
+ static_assert(std::is_same_v<decltype(fr6), std::flat_map<long, float>>);
__gnu_test::test_input_range<std::tuple<long, float>> r4(0, 0);
std::flat_map it7(r4.begin(), r4.begin());
std::vector<long, __gnu_test::SimpleAllocator<long>>,
std::vector<float, __gnu_test::SimpleAllocator<float>>>>);
- // LWG4223: deduces flat_multimap<long, float const>, which in turn instantiates
- // std::vector<cosnt float> that is ill-formed.
- // __gnu_test::test_input_range<std::pair<const long, const float>> r2(0, 0);
- // std::flat_multimap it5(r2.begin(), r2.begin());
- // std::flat_multimap fr5(std::from_range, r2);
-
- // LWG4223: deduces flat_multimap<const long&, float&>
- //__gnu_test::test_input_range<std::pair<const long&, float&>> r3(0, 0);
- // std::flat_multimap it6(r3.begin(), r3.begin());
- // std::flat_multimap fr6(std::from_range, r3);
+ __gnu_test::test_input_range<std::pair<const long, const float>> r2(0, 0);
+ std::flat_multimap it5(r2.begin(), r2.begin());
+ static_assert(std::is_same_v<decltype(it5), std::flat_multimap<long, float>>);
+ std::flat_multimap fr5(std::from_range, r2);
+ static_assert(std::is_same_v<decltype(fr5), std::flat_multimap<long, float>>);
+
+ __gnu_test::test_input_range<std::pair<const long&, float&>> r3(0, 0);
+ std::flat_multimap it6(r3.begin(), r3.begin());
+ static_assert(std::is_same_v<decltype(it6), std::flat_multimap<long, float>>);
+ std::flat_multimap fr6(std::from_range, r3);
+ static_assert(std::is_same_v<decltype(fr6), std::flat_multimap<long, float>>);
__gnu_test::test_input_range<std::tuple<long, float>> r4(0, 0);
std::flat_multimap it7(r4.begin(), r4.begin());
std::map s2(std::move(m), p);
check_type<Map>(s2);
}
+
+struct MyPred
+{
+ template<typename T, typename U>
+ bool operator()(T const&, U const&) const;
+};
+
+template<typename K, typename V>
+constexpr bool test_lwg4223()
+{
+ using KD = std::remove_cv_t<std::remove_reference_t<K>>;
+ using VD = std::remove_cv_t<std::remove_reference_t<V>>;
+ using Alloc = __gnu_test::SimpleAllocator<std::pair<const KD, VD>>;
+
+ std::initializer_list<std::pair<K, V>> il = {};
+ Alloc a;
+ MyPred p;
+
+ // The remove_cvref_t is not applied here.
+ // static_assert(std::is_same_v<
+ // decltype(std::map(il)),
+ // std::map<KD, VD>>);
+
+ static_assert(std::is_same_v<
+ decltype(std::map(il.begin(), il.end())),
+ std::map<KD, VD>>);
+
+ static_assert(std::is_same_v<
+ decltype(std::map(il.begin(), il.end(), p)),
+ std::map<KD, VD, MyPred>>);
+
+ static_assert(std::is_same_v<
+ decltype(std::map(il.begin(), il.end(), a)),
+ std::map<KD, VD, std::less<KD>, Alloc>>);
+
+ static_assert(std::is_same_v<
+ decltype(std::map(il.begin(), il.end(), p, a)),
+ std::map<KD, VD, MyPred, Alloc>>);
+
+ return true;
+}
+
+static_assert(test_lwg4223<const int, const float>());
+static_assert(test_lwg4223<int&, float&>());
+static_assert(test_lwg4223<int&&, float&&>());
+static_assert(test_lwg4223<const int&, const float&>());
__gnu_test::test_input_range<std::pair<const long, const float>> r2(0, 0);
std::map m5(std::from_range, r2);
- static_assert(std::is_same_v<decltype(m5), std::map<long, const float>>);
+ static_assert(std::is_same_v<decltype(m5), std::map<long, float>>);
- // LWG4223: deduces map<const long&, float&>
- //__gnu_test::test_input_range<std::pair<const long&, float&>> r3(0, 0);
- // std::map m6(std::from_range, r3);
+ __gnu_test::test_input_range<std::pair<const long&, float&>> r3(0, 0);
+ std::map m6(std::from_range, r3);
+ static_assert(std::is_same_v<decltype(m6), std::map<long, float>>);
__gnu_test::test_input_range<std::tuple<long, float>> r4(0, 0);
std::map m7(std::from_range, r4);
std::multimap s2(std::move(m), p);
check_type<MMap>(s2);
}
+
+struct MyPred
+{
+ template<typename T, typename U>
+ bool operator()(T const&, U const&) const;
+};
+
+template<typename K, typename V>
+constexpr bool test_lwg4223()
+{
+ using KD = std::remove_cv_t<std::remove_reference_t<K>>;
+ using VD = std::remove_cv_t<std::remove_reference_t<V>>;
+ using Alloc = __gnu_test::SimpleAllocator<std::pair<const KD, VD>>;
+
+ std::initializer_list<std::pair<K, V>> il = {};
+ Alloc a;
+ MyPred p;
+
+ // The remove_cvref_t is not applied here.
+ // static_assert(std::is_same_v<
+ // decltype(std::multimap(il)),
+ // std::multimap<KD, VD>>);
+
+ static_assert(std::is_same_v<
+ decltype(std::multimap(il.begin(), il.end())),
+ std::multimap<KD, VD>>);
+
+ static_assert(std::is_same_v<
+ decltype(std::multimap(il.begin(), il.end(), p)),
+ std::multimap<KD, VD, MyPred>>);
+
+ static_assert(std::is_same_v<
+ decltype(std::multimap(il.begin(), il.end(), a)),
+ std::multimap<KD, VD, std::less<KD>, Alloc>>);
+
+ static_assert(std::is_same_v<
+ decltype(std::multimap(il.begin(), il.end(), p, a)),
+ std::multimap<KD, VD, MyPred, Alloc>>);
+
+ return true;
+}
+
+static_assert(test_lwg4223<const int, const float>());
+static_assert(test_lwg4223<int&, float&>());
+static_assert(test_lwg4223<int&&, float&&>());
+static_assert(test_lwg4223<const int&, const float&>());
__gnu_test::test_input_range<std::pair<const long, const float>> r2(0, 0);
std::multimap m5(std::from_range, r2);
- static_assert(std::is_same_v<decltype(m5), std::multimap<long, const float>>);
+ static_assert(std::is_same_v<decltype(m5), std::multimap<long, float>>);
- // LWG4223: deduces multimap<const long&, float&>
- //__gnu_test::test_input_range<std::pair<const long&, float&>> r3(0, 0);
- // std::multimap m6(std::from_range, r3);
+ __gnu_test::test_input_range<std::pair<const long&, float&>> r3(0, 0);
+ std::multimap m6(std::from_range, r3);
+ static_assert(std::is_same_v<decltype(m6), std::multimap<long, float>>);
__gnu_test::test_input_range<std::tuple<long, float>> r4(0, 0);
std::multimap m7(std::from_range, r4);
std::unordered_map s2(std::move(m), p);
check_type<UMap>(s2);
}
+
+struct MyHash
+{
+ template<typename T>
+ std::size_t operator()(T const&) const;
+};
+
+struct MyPred
+{
+ template<typename T, typename U>
+ bool operator()(T const&, U const&) const;
+};
+
+template<typename K, typename V>
+constexpr bool test_lwg4223()
+{
+ using KD = std::remove_cv_t<std::remove_reference_t<K>>;
+ using VD = std::remove_cv_t<std::remove_reference_t<V>>;
+ using Alloc = __gnu_test::SimpleAllocator<std::pair<const KD, VD>>;
+
+ std::initializer_list<std::pair<K, V>> il = {};
+ Alloc a;
+ MyHash h;
+ MyPred p;
+
+ // The remove_cvref_t is not applied here.
+ // static_assert(std::is_same_v<
+ // decltype(std::unordered_map(il)),
+ // std::unordered_map<KD, VD>>);
+
+ static_assert(std::is_same_v<
+ decltype(std::unordered_map(il.begin(), il.end())),
+ std::unordered_map<KD, VD>>);
+
+ static_assert(std::is_same_v<
+ decltype(std::unordered_map(il.begin(), il.end(), 0)),
+ std::unordered_map<KD, VD>>);
+
+ static_assert(std::is_same_v<
+ decltype(std::unordered_map(il.begin(), il.end(), 0, h)),
+ std::unordered_map<KD, VD, MyHash>>);
+
+ static_assert(std::is_same_v<
+ decltype(std::unordered_map(il.begin(), il.end(), 0, h, p)),
+ std::unordered_map<KD, VD, MyHash, MyPred>>);
+
+ static_assert(std::is_same_v<
+ decltype(std::unordered_map(il.begin(), il.end(), a)),
+ std::unordered_map<KD, VD, std::hash<KD>, std::equal_to<KD>, Alloc>>);
+
+ static_assert(std::is_same_v<
+ decltype(std::unordered_map(il.begin(), il.end(), 0, a)),
+ std::unordered_map<KD, VD, std::hash<KD>, std::equal_to<KD>, Alloc>>);
+
+ static_assert(std::is_same_v<
+ decltype(std::unordered_map(il.begin(), il.end(), 0, h, a)),
+ std::unordered_map<KD, VD, MyHash, std::equal_to<KD>, Alloc>>);
+
+ static_assert(std::is_same_v<
+ decltype(std::unordered_map(il.begin(), il.end(), 0, h, p, a)),
+ std::unordered_map<KD, VD, MyHash, MyPred, Alloc>>);
+
+ return true;
+}
+
+static_assert(test_lwg4223<const int, const float>());
+static_assert(test_lwg4223<int&, float&>());
+static_assert(test_lwg4223<int&&, float&&>());
+static_assert(test_lwg4223<const int&, const float&>());
__gnu_test::test_input_range<std::pair<const long, const float>> r2(0, 0);
std::unordered_map m9(std::from_range, r2);
- static_assert(std::is_same_v<
- decltype(m9),
- std::unordered_map<long, const float>>);
+ static_assert(std::is_same_v<decltype(m9), std::unordered_map<long, float>>);
- // LWG4223: deduces map<const long&, float&>
- // __gnu_test::test_input_range<std::pair<const long&, float&>> r3(0, 0);
- // std::unordered_map m10(std::from_range, r3);
+ __gnu_test::test_input_range<std::pair<const long&, float&>> r3(0, 0);
+ std::unordered_map m10(std::from_range, r3);
+ static_assert(std::is_same_v<decltype(m10), std::unordered_map<long, float>>);
__gnu_test::test_input_range<std::tuple<long, float>> r4(0, 0);
std::unordered_map m11(std::from_range, r4);
std::unordered_multimap s2(std::move(m), p);
check_type<UMMap>(s2);
}
+
+struct MyHash
+{
+ template<typename T>
+ std::size_t operator()(T const&) const;
+};
+
+struct MyPred
+{
+ template<typename T, typename U>
+ bool operator()(T const&, U const&) const;
+};
+
+template<typename K, typename V>
+constexpr bool test_lwg4223()
+{
+ using KD = std::remove_cv_t<std::remove_reference_t<K>>;
+ using VD = std::remove_cv_t<std::remove_reference_t<V>>;
+ using Alloc = __gnu_test::SimpleAllocator<std::pair<const KD, VD>>;
+
+ std::initializer_list<std::pair<K, V>> il = {};
+ Alloc a;
+ MyHash h;
+ MyPred p;
+
+ // The remove_cvref_t is not applied here.
+ // static_assert(std::is_same_v<
+ // decltype(std::unordered_multimap(il)),
+ // std::unordered_multimap<KD, VD>>);
+
+ static_assert(std::is_same_v<
+ decltype(std::unordered_multimap(il.begin(), il.end())),
+ std::unordered_multimap<KD, VD>>);
+
+ static_assert(std::is_same_v<
+ decltype(std::unordered_multimap(il.begin(), il.end(), 0)),
+ std::unordered_multimap<KD, VD>>);
+
+ static_assert(std::is_same_v<
+ decltype(std::unordered_multimap(il.begin(), il.end(), 0, h)),
+ std::unordered_multimap<KD, VD, MyHash>>);
+
+ static_assert(std::is_same_v<
+ decltype(std::unordered_multimap(il.begin(), il.end(), 0, h, p)),
+ std::unordered_multimap<KD, VD, MyHash, MyPred>>);
+
+ static_assert(std::is_same_v<
+ decltype(std::unordered_multimap(il.begin(), il.end(), a)),
+ std::unordered_multimap<KD, VD, std::hash<KD>, std::equal_to<KD>, Alloc>>);
+
+ static_assert(std::is_same_v<
+ decltype(std::unordered_multimap(il.begin(), il.end(), 0, a)),
+ std::unordered_multimap<KD, VD, std::hash<KD>, std::equal_to<KD>, Alloc>>);
+
+ static_assert(std::is_same_v<
+ decltype(std::unordered_multimap(il.begin(), il.end(), 0, h, a)),
+ std::unordered_multimap<KD, VD, MyHash, std::equal_to<KD>, Alloc>>);
+
+ static_assert(std::is_same_v<
+ decltype(std::unordered_multimap(il.begin(), il.end(), 0, h, p, a)),
+ std::unordered_multimap<KD, VD, MyHash, MyPred, Alloc>>);
+
+ return true;
+}
+
+static_assert(test_lwg4223<const int, const float>());
+static_assert(test_lwg4223<int&, float&>());
+static_assert(test_lwg4223<int&&, float&&>());
+static_assert(test_lwg4223<const int&, const float&>());
std::unordered_multimap m9(std::from_range, r2);
static_assert(std::is_same_v<
decltype(m9),
- std::unordered_multimap<long, const float>>);
+ std::unordered_multimap<long, float>>);
- // LWG4223: deduces map<const long&, float&>
- // __gnu_test::test_input_range<std::pair<const long&, float&>> r3(0, 0);
- // std::unordered_multimap m10(std::from_range, r3);
+ __gnu_test::test_input_range<std::pair<const long&, float&>> r3(0, 0);
+ std::unordered_multimap m10(std::from_range, r3);
+ static_assert(std::is_same_v<
+ decltype(m10),
+ std::unordered_multimap<long, float>>);
__gnu_test::test_input_range<std::tuple<long, float>> r4(0, 0);
std::unordered_multimap m11(std::from_range, r4);