diff --git a/stl/inc/xutility b/stl/inc/xutility index 077097f2f3..7190ac3d33 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -2062,16 +2062,19 @@ public: }; template _Ty2> + requires input_iterator> struct common_type, _Ty2> { using type = basic_const_iterator>; }; template _Ty2> + requires input_iterator> struct common_type<_Ty2, basic_const_iterator<_Ty1>> { using type = basic_const_iterator>; }; template _Ty2> + requires input_iterator> struct common_type, basic_const_iterator<_Ty2>> { using type = basic_const_iterator>; }; diff --git a/tests/std/tests/P2278R4_ranges_const_iterator_machinery/test.compile.pass.cpp b/tests/std/tests/P2278R4_ranges_const_iterator_machinery/test.compile.pass.cpp index 892fbf0678..3c9c3501c7 100644 --- a/tests/std/tests/P2278R4_ranges_const_iterator_machinery/test.compile.pass.cpp +++ b/tests/std/tests/P2278R4_ranges_const_iterator_machinery/test.compile.pass.cpp @@ -31,6 +31,76 @@ static_assert(!CanIterConstRef); static_assert(!CanIterConstRef>); static_assert(!CanIterConstRef>); +namespace test_common_type { + struct CommonThing {}; + + template + struct InIter { + using value_type = T; + using difference_type = ptrdiff_t; + + value_type& operator*() const; // not defined + InIter& operator++(); // not defined + void operator++(int); // not defined + operator CommonThing() const; // not defined + }; + + static_assert(input_iterator>); + static_assert(input_iterator>); +} // namespace test_common_type + +template +struct std::common_type, test_common_type::InIter> { + using type = test_common_type::CommonThing; +}; + +static_assert(common_with, test_common_type::InIter>); + +namespace test_common_type { + template + concept CanCommonType = requires { typename common_type_t; }; + + // Validate invalid common types + static_assert(!CanCommonType, long*>); + static_assert(!CanCommonType>); + static_assert(!CanCommonType, basic_const_iterator>); + static_assert(!CanCommonType>, InIter>); + static_assert(!CanCommonType, basic_const_iterator>>); + static_assert(!CanCommonType>, basic_const_iterator>>); + + // Validate common_type + static_assert(same_as, const int*>, basic_const_iterator>); + static_assert(same_as>, basic_const_iterator>); + static_assert(same_as, int*>, basic_const_iterator>); + static_assert(same_as>, basic_const_iterator>); + static_assert(same_as, basic_const_iterator>, + basic_const_iterator>); + static_assert(same_as, basic_const_iterator>, + basic_const_iterator>); + + static_assert(same_as, const int*>, + basic_const_iterator>); + static_assert(same_as>, + basic_const_iterator>); + static_assert(same_as>, + basic_const_iterator>); + static_assert(same_as, volatile int*>, + basic_const_iterator>); + + template + requires requires { + typename common_type_t>; + typename common_type_t, U>; + typename common_type_t, basic_const_iterator>; + } + void test_lwg3862(); // not defined + + template + concept VerifyLWG3862 = requires { test_lwg3862(); }; + + static_assert(!VerifyLWG3862, InIter>); // Hard error before LWG-3862 +} // namespace test_common_type + namespace test_pointer { using Ptr = int*; static_assert(CanIterConstRef); @@ -50,12 +120,6 @@ namespace test_pointer { static_assert(same_as, ConstPtr>); static_assert(same_as>, const int&>); static_assert(same_as, ConstPtr>); - - // Validate common_type - static_assert(same_as, ConstPtr>, basic_const_iterator>); - static_assert(same_as>, basic_const_iterator>); - static_assert(same_as, basic_const_iterator>, - basic_const_iterator>); } // namespace test_pointer namespace test_random_access_iter {