340 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++1710 11// template<class From, class To>12// concept common_reference_with;13 14#include <concepts>15#include <type_traits>16 17#include "test_macros.h"18 19template <class T, class U>20constexpr bool CheckCommonReferenceWith() noexcept {21 static_assert(std::common_reference_with<T, U&>);22 static_assert(std::common_reference_with<T, const U&>);23 static_assert(std::common_reference_with<T, volatile U&>);24 static_assert(std::common_reference_with<T, const volatile U&>);25 static_assert(std::common_reference_with<T, U&&>);26 static_assert(std::common_reference_with<T, const U&&>);27 static_assert(std::common_reference_with<T, volatile U&&>);28 static_assert(std::common_reference_with<T, const volatile U&&>);29 static_assert(std::common_reference_with<T&, U&&>);30 static_assert(std::common_reference_with<T&, const U&&>);31 static_assert(std::common_reference_with<T&, volatile U&&>);32 static_assert(std::common_reference_with<T&, const volatile U&&>);33 static_assert(std::common_reference_with<const T&, U&&>);34 static_assert(std::common_reference_with<const T&, const U&&>);35 static_assert(std::common_reference_with<const T&, volatile U&&>);36 static_assert(std::common_reference_with<const T&, const volatile U&&>);37 static_assert(std::common_reference_with<volatile T&, U&&>);38 static_assert(std::common_reference_with<volatile T&, const U&&>);39 static_assert(std::common_reference_with<volatile T&, volatile U&&>);40 static_assert(std::common_reference_with<volatile T&, const volatile U&&>);41 static_assert(std::common_reference_with<const volatile T&, U&&>);42 static_assert(std::common_reference_with<const volatile T&, const U&&>);43 static_assert(std::common_reference_with<const volatile T&, volatile U&&>);44 static_assert(45 std::common_reference_with<const volatile T&, const volatile U&&>);46 47 return std::common_reference_with<T, U>;48}49 50namespace BuiltinTypes {51// fundamental types52static_assert(std::common_reference_with<void, void>);53static_assert(CheckCommonReferenceWith<int, int>());54static_assert(CheckCommonReferenceWith<int, long>());55static_assert(CheckCommonReferenceWith<int, unsigned char>());56#ifndef TEST_HAS_NO_INT12857static_assert(CheckCommonReferenceWith<int, __int128_t>());58#endif59static_assert(CheckCommonReferenceWith<int, double>());60 61// arrays62static_assert(CheckCommonReferenceWith<int[5], int[5]>());63 64// pointers (common with void*)65static_assert(CheckCommonReferenceWith<int*, void*>());66static_assert(CheckCommonReferenceWith<int*, const void*>());67static_assert(CheckCommonReferenceWith<int*, volatile void*>());68static_assert(CheckCommonReferenceWith<int*, const volatile void*>());69static_assert(CheckCommonReferenceWith<const int*, void*>());70static_assert(CheckCommonReferenceWith<const int*, const void*>());71static_assert(CheckCommonReferenceWith<const int*, volatile void*>());72static_assert(CheckCommonReferenceWith<const int*, const volatile void*>());73static_assert(CheckCommonReferenceWith<volatile int*, void*>());74static_assert(CheckCommonReferenceWith<volatile int*, const void*>());75static_assert(CheckCommonReferenceWith<volatile int*, volatile void*>());76static_assert(CheckCommonReferenceWith<volatile int*, const volatile void*>());77static_assert(CheckCommonReferenceWith<const volatile int*, void*>());78static_assert(CheckCommonReferenceWith<const volatile int*, const void*>());79static_assert(CheckCommonReferenceWith<const volatile int*, volatile void*>());80static_assert(81 CheckCommonReferenceWith<const volatile int*, const volatile void*>());82 83static_assert(CheckCommonReferenceWith<int (*)(), int (*)()>());84static_assert(CheckCommonReferenceWith<int (*)(), int (*)() noexcept>());85struct S {};86static_assert(CheckCommonReferenceWith<int S::*, int S::*>());87static_assert(CheckCommonReferenceWith<int S::*, const int S::*>());88static_assert(CheckCommonReferenceWith<int (S::*)(), int (S::*)()>());89static_assert(CheckCommonReferenceWith<int (S::*)(), int (S::*)() noexcept>());90static_assert(91 CheckCommonReferenceWith<int (S::*)() const, int (S::*)() const>());92static_assert(CheckCommonReferenceWith<int (S::*)() const,93 int (S::*)() const noexcept>());94static_assert(95 CheckCommonReferenceWith<int (S::*)() volatile, int (S::*)() volatile>());96static_assert(CheckCommonReferenceWith<int (S::*)() volatile,97 int (S::*)() volatile noexcept>());98static_assert(CheckCommonReferenceWith<int (S::*)() const volatile,99 int (S::*)() const volatile>());100static_assert(CheckCommonReferenceWith<int (S::*)() const volatile,101 int (S::*)() const volatile noexcept>());102 103// nonsense104static_assert(!std::common_reference_with<double, float*>);105static_assert(!std::common_reference_with<int, int[5]>);106static_assert(!std::common_reference_with<int*, long*>);107static_assert(!std::common_reference_with<int*, unsigned int*>);108static_assert(!std::common_reference_with<int (*)(), int (*)(int)>);109static_assert(!std::common_reference_with<int S::*, float S::*>);110static_assert(!std::common_reference_with<int (S::*)(), int (S::*)() const>);111static_assert(!std::common_reference_with<int (S::*)(), int (S::*)() volatile>);112static_assert(113 !std::common_reference_with<int (S::*)(), int (S::*)() const volatile>);114static_assert(115 !std::common_reference_with<int (S::*)() const, int (S::*)() volatile>);116static_assert(!std::common_reference_with<int (S::*)() const,117 int (S::*)() const volatile>);118static_assert(!std::common_reference_with<int (S::*)() volatile,119 int (S::*)() const volatile>);120} // namespace BuiltinTypes121 122namespace NoDefaultCommonReference {123class T {};124 125static_assert(!std::common_reference_with<T, int>);126static_assert(!std::common_reference_with<int, T>);127static_assert(!std::common_reference_with<T, int[10]>);128static_assert(!std::common_reference_with<T[10], int>);129static_assert(!std::common_reference_with<T*, int*>);130static_assert(!std::common_reference_with<T*, const int*>);131static_assert(!std::common_reference_with<T*, volatile int*>);132static_assert(!std::common_reference_with<T*, const volatile int*>);133static_assert(!std::common_reference_with<const T*, int*>);134static_assert(!std::common_reference_with<volatile T*, int*>);135static_assert(!std::common_reference_with<const volatile T*, int*>);136static_assert(!std::common_reference_with<const T*, const int*>);137static_assert(!std::common_reference_with<const T*, volatile int*>);138static_assert(!std::common_reference_with<const T*, const volatile int*>);139static_assert(!std::common_reference_with<const T*, const int*>);140static_assert(!std::common_reference_with<volatile T*, const int*>);141static_assert(!std::common_reference_with<const volatile T*, const int*>);142static_assert(!std::common_reference_with<volatile T*, const int*>);143static_assert(!std::common_reference_with<volatile T*, volatile int*>);144static_assert(!std::common_reference_with<volatile T*, const volatile int*>);145static_assert(!std::common_reference_with<const T*, volatile int*>);146static_assert(!std::common_reference_with<volatile T*, volatile int*>);147static_assert(!std::common_reference_with<const volatile T*, volatile int*>);148static_assert(!std::common_reference_with<const volatile T*, const int*>);149static_assert(!std::common_reference_with<const volatile T*, volatile int*>);150static_assert(151 !std::common_reference_with<const volatile T*, const volatile int*>);152static_assert(!std::common_reference_with<const T*, const volatile int*>);153static_assert(!std::common_reference_with<volatile T*, const volatile int*>);154static_assert(155 !std::common_reference_with<const volatile T*, const volatile int*>);156static_assert(!std::common_reference_with<T&, int&>);157static_assert(!std::common_reference_with<T&, const int&>);158static_assert(!std::common_reference_with<T&, volatile int&>);159static_assert(!std::common_reference_with<T&, const volatile int&>);160static_assert(!std::common_reference_with<const T&, int&>);161static_assert(!std::common_reference_with<volatile T&, int&>);162static_assert(!std::common_reference_with<const volatile T&, int&>);163static_assert(!std::common_reference_with<const T&, const int&>);164static_assert(!std::common_reference_with<const T&, volatile int&>);165static_assert(!std::common_reference_with<const T&, const volatile int&>);166static_assert(!std::common_reference_with<const T&, const int&>);167static_assert(!std::common_reference_with<volatile T&, const int&>);168static_assert(!std::common_reference_with<const volatile T&, const int&>);169static_assert(!std::common_reference_with<volatile T&, const int&>);170static_assert(!std::common_reference_with<volatile T&, volatile int&>);171static_assert(!std::common_reference_with<volatile T&, const volatile int&>);172static_assert(!std::common_reference_with<const T&, volatile int&>);173static_assert(!std::common_reference_with<volatile T&, volatile int&>);174static_assert(!std::common_reference_with<const volatile T&, volatile int&>);175static_assert(!std::common_reference_with<const volatile T&, const int&>);176static_assert(!std::common_reference_with<const volatile T&, volatile int&>);177static_assert(178 !std::common_reference_with<const volatile T&, const volatile int&>);179static_assert(!std::common_reference_with<const T&, const volatile int&>);180static_assert(!std::common_reference_with<volatile T&, const volatile int&>);181static_assert(182 !std::common_reference_with<const volatile T&, const volatile int&>);183static_assert(!std::common_reference_with<T&, int&&>);184static_assert(!std::common_reference_with<T&, const int&&>);185static_assert(!std::common_reference_with<T&, volatile int&&>);186static_assert(!std::common_reference_with<T&, const volatile int&&>);187static_assert(!std::common_reference_with<const T&, int&&>);188static_assert(!std::common_reference_with<volatile T&, int&&>);189static_assert(!std::common_reference_with<const volatile T&, int&&>);190static_assert(!std::common_reference_with<const T&, const int&&>);191static_assert(!std::common_reference_with<const T&, volatile int&&>);192static_assert(!std::common_reference_with<const T&, const volatile int&&>);193static_assert(!std::common_reference_with<const T&, const int&&>);194static_assert(!std::common_reference_with<volatile T&, const int&&>);195static_assert(!std::common_reference_with<const volatile T&, const int&&>);196static_assert(!std::common_reference_with<volatile T&, const int&&>);197static_assert(!std::common_reference_with<volatile T&, volatile int&&>);198static_assert(!std::common_reference_with<volatile T&, const volatile int&&>);199static_assert(!std::common_reference_with<const T&, volatile int&&>);200static_assert(!std::common_reference_with<volatile T&, volatile int&&>);201static_assert(!std::common_reference_with<const volatile T&, volatile int&&>);202static_assert(!std::common_reference_with<const volatile T&, const int&&>);203static_assert(!std::common_reference_with<const volatile T&, volatile int&&>);204static_assert(205 !std::common_reference_with<const volatile T&, const volatile int&&>);206static_assert(!std::common_reference_with<const T&, const volatile int&&>);207static_assert(!std::common_reference_with<volatile T&, const volatile int&&>);208static_assert(209 !std::common_reference_with<const volatile T&, const volatile int&&>);210static_assert(!std::common_reference_with<T&&, int&>);211static_assert(!std::common_reference_with<T&&, const int&>);212static_assert(!std::common_reference_with<T&&, volatile int&>);213static_assert(!std::common_reference_with<T&&, const volatile int&>);214static_assert(!std::common_reference_with<const T&&, int&>);215static_assert(!std::common_reference_with<volatile T&&, int&>);216static_assert(!std::common_reference_with<const volatile T&&, int&>);217static_assert(!std::common_reference_with<const T&&, const int&>);218static_assert(!std::common_reference_with<const T&&, volatile int&>);219static_assert(!std::common_reference_with<const T&&, const volatile int&>);220static_assert(!std::common_reference_with<const T&&, const int&>);221static_assert(!std::common_reference_with<volatile T&&, const int&>);222static_assert(!std::common_reference_with<const volatile T&&, const int&>);223static_assert(!std::common_reference_with<volatile T&&, const int&>);224static_assert(!std::common_reference_with<volatile T&&, volatile int&>);225static_assert(!std::common_reference_with<volatile T&&, const volatile int&>);226static_assert(!std::common_reference_with<const T&&, volatile int&>);227static_assert(!std::common_reference_with<volatile T&&, volatile int&>);228static_assert(!std::common_reference_with<const volatile T&&, volatile int&>);229static_assert(!std::common_reference_with<const volatile T&&, const int&>);230static_assert(!std::common_reference_with<const volatile T&&, volatile int&>);231static_assert(232 !std::common_reference_with<const volatile T&&, const volatile int&>);233static_assert(!std::common_reference_with<const T&&, const volatile int&>);234static_assert(!std::common_reference_with<volatile T&&, const volatile int&>);235static_assert(236 !std::common_reference_with<const volatile T&&, const volatile int&>);237static_assert(!std::common_reference_with<T&&, int&&>);238static_assert(!std::common_reference_with<T&&, const int&&>);239static_assert(!std::common_reference_with<T&&, volatile int&&>);240static_assert(!std::common_reference_with<T&&, const volatile int&&>);241static_assert(!std::common_reference_with<const T&&, int&&>);242static_assert(!std::common_reference_with<volatile T&&, int&&>);243static_assert(!std::common_reference_with<const volatile T&&, int&&>);244static_assert(!std::common_reference_with<const T&&, const int&&>);245static_assert(!std::common_reference_with<const T&&, volatile int&&>);246static_assert(!std::common_reference_with<const T&&, const volatile int&&>);247static_assert(!std::common_reference_with<const T&&, const int&&>);248static_assert(!std::common_reference_with<volatile T&&, const int&&>);249static_assert(!std::common_reference_with<const volatile T&&, const int&&>);250static_assert(!std::common_reference_with<volatile T&&, const int&&>);251static_assert(!std::common_reference_with<volatile T&&, volatile int&&>);252static_assert(!std::common_reference_with<volatile T&&, const volatile int&&>);253static_assert(!std::common_reference_with<const T&&, volatile int&&>);254static_assert(!std::common_reference_with<volatile T&&, volatile int&&>);255static_assert(!std::common_reference_with<const volatile T&&, volatile int&&>);256static_assert(!std::common_reference_with<const volatile T&&, const int&&>);257static_assert(!std::common_reference_with<const volatile T&&, volatile int&&>);258static_assert(259 !std::common_reference_with<const volatile T&&, const volatile int&&>);260static_assert(!std::common_reference_with<const T&&, const volatile int&&>);261static_assert(!std::common_reference_with<volatile T&&, const volatile int&&>);262static_assert(263 !std::common_reference_with<const volatile T&&, const volatile int&&>);264} // namespace NoDefaultCommonReference265 266struct BadBasicCommonReference {267 // This test is ill-formed, NDR. If it ever blows up in our faces: that's a good thing.268 // In the meantime, the test should be included. If compiler support is added, then an include guard269 // should be placed so the test doesn't get deleted.270 operator int() const;271 operator int&();272};273static_assert(std::convertible_to<BadBasicCommonReference, int>);274static_assert(std::convertible_to<BadBasicCommonReference, int&>);275 276template <template <class> class X, template <class> class Y>277struct std::basic_common_reference<BadBasicCommonReference, int, X, Y> {278 using type = BadBasicCommonReference&;279};280 281template <template <class> class X, template <class> class Y>282struct std::basic_common_reference<int, BadBasicCommonReference, X, Y> {283 using type = int&;284};285 286static_assert(!std::common_reference_with<BadBasicCommonReference, int>);287 288struct StructNotConvertibleToCommonReference {289 explicit(false) StructNotConvertibleToCommonReference(int);290};291static_assert(std::convertible_to<int, StructNotConvertibleToCommonReference>);292 293template <template <class> class X, template <class> class Y>294struct std::basic_common_reference<StructNotConvertibleToCommonReference, int, X, Y> {295 using type = int&;296};297 298template <template <class> class X, template <class> class Y>299struct std::basic_common_reference<int, StructNotConvertibleToCommonReference, X, Y> {300 using type = int&;301};302 303static_assert(304 !std::common_reference_with<StructNotConvertibleToCommonReference, int>);305 306struct IntNotConvertibleToCommonReference {307 operator int&() const;308};309 310template <template <class> class X, template <class> class Y>311struct std::basic_common_reference<IntNotConvertibleToCommonReference, int, X, Y> {312 using type = int&;313};314 315template <template <class> class X, template <class> class Y>316struct std::basic_common_reference<int, IntNotConvertibleToCommonReference, X, Y> {317 using type = int&;318};319 320static_assert(321 !std::common_reference_with<StructNotConvertibleToCommonReference, int>);322 323struct HasCommonReference {324 explicit(false) HasCommonReference(int);325 operator int&() const;326};327 328template <template <class> class X, template <class> class Y>329struct std::basic_common_reference<HasCommonReference, int, X, Y> {330 using type = int&;331};332 333template <template <class> class X, template <class> class Y>334struct std::basic_common_reference<int, HasCommonReference, X, Y> {335 using type = int&;336};337 338static_assert(!std::common_reference_with<HasCommonReference, int>);339static_assert(std::common_reference_with<HasCommonReference, int&>);340