260 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// type_traits10 11// template <class T, class... Args>12// struct is_constructible;13 14#include <type_traits>15#include "test_macros.h"16 17struct A18{19 explicit A(int);20 A(int, double);21 A(int, long, double);22#if TEST_STD_VER >= 1123private:24#endif25 A(char);26};27 28struct Base {};29struct Derived : public Base {};30 31class Abstract32{33 virtual void foo() = 0;34};35 36class AbstractDestructor37{38 virtual ~AbstractDestructor() = 0;39};40 41struct PrivateDtor {42 PrivateDtor(int) {}43private:44 ~PrivateDtor() {}45};46 47struct S {48 template <class T>49#if TEST_STD_VER >= 1150 explicit51#endif52 operator T () const;53};54 55template <class To>56struct ImplicitTo {57 operator To();58};59 60#if TEST_STD_VER >= 1161template <class To>62struct ExplicitTo {63 explicit operator To ();64};65#endif66 67 68template <class T>69void test_is_constructible()70{71 static_assert( (std::is_constructible<T>::value), "");72#if TEST_STD_VER > 1473 static_assert( std::is_constructible_v<T>, "");74#endif75}76 77template <class T, class A0>78void test_is_constructible()79{80 static_assert(( std::is_constructible<T, A0>::value), "");81#if TEST_STD_VER > 1482 static_assert(( std::is_constructible_v<T, A0>), "");83#endif84}85 86template <class T, class A0, class A1>87void test_is_constructible()88{89 static_assert(( std::is_constructible<T, A0, A1>::value), "");90#if TEST_STD_VER > 1491 static_assert(( std::is_constructible_v<T, A0, A1>), "");92#endif93}94 95template <class T, class A0, class A1, class A2>96void test_is_constructible()97{98 static_assert(( std::is_constructible<T, A0, A1, A2>::value), "");99#if TEST_STD_VER > 14100 static_assert(( std::is_constructible_v<T, A0, A1, A2>), "");101#endif102}103 104template <class T>105void test_is_not_constructible()106{107 static_assert((!std::is_constructible<T>::value), "");108#if TEST_STD_VER > 14109 static_assert((!std::is_constructible_v<T>), "");110#endif111}112 113template <class T, class A0>114void test_is_not_constructible()115{116 static_assert((!std::is_constructible<T, A0>::value), "");117#if TEST_STD_VER > 14118 static_assert((!std::is_constructible_v<T, A0>), "");119#endif120}121 122int main(int, char**)123{124 typedef Base B;125 typedef Derived D;126 127 test_is_constructible<int> ();128 test_is_constructible<int, const int> ();129 test_is_constructible<A, int> ();130 test_is_constructible<A, int, double> ();131 test_is_constructible<A, int, long, double> ();132 test_is_constructible<int&, int&> ();133 134 test_is_not_constructible<A> ();135#if TEST_STD_VER >= 11136 test_is_not_constructible<A, char> ();137#else138 test_is_constructible<A, char> ();139#endif140 test_is_not_constructible<A, void> ();141 test_is_not_constructible<int, void()>();142 test_is_not_constructible<int, void(&)()>();143 test_is_not_constructible<int, void() const>();144 test_is_not_constructible<int&, void>();145 test_is_not_constructible<int&, void()>();146 test_is_not_constructible<int&, void() const>();147 test_is_not_constructible<int&, void(&)()>();148 149 test_is_not_constructible<void> ();150 test_is_not_constructible<const void> (); // LWG 2738151 test_is_not_constructible<volatile void> ();152 test_is_not_constructible<const volatile void> ();153 test_is_not_constructible<int&> ();154 test_is_not_constructible<Abstract> ();155 test_is_not_constructible<AbstractDestructor> ();156 test_is_constructible<int, S>();157 test_is_not_constructible<int&, S>();158 159 test_is_constructible<void(&)(), void(&)()>();160 test_is_constructible<void(&)(), void()>();161#if TEST_STD_VER >= 11162 test_is_constructible<void(&&)(), void(&&)()>();163 test_is_constructible<void(&&)(), void()>();164 test_is_constructible<void(&&)(), void(&)()>();165#endif166 167#if TEST_STD_VER >= 11168 test_is_constructible<int const&, int>();169 test_is_constructible<int const&, int&&>();170 171 test_is_constructible<int&&, double&>();172 test_is_constructible<void(&)(), void(&&)()>();173 174 test_is_not_constructible<int&, int>();175 test_is_not_constructible<int&, int const&>();176 test_is_not_constructible<int&, int&&>();177 178 test_is_constructible<int&&, int>();179 test_is_constructible<int&&, int&&>();180 test_is_not_constructible<int&&, int&>();181 test_is_not_constructible<int&&, int const&&>();182 183 test_is_constructible<Base, Derived>();184 test_is_constructible<Base&, Derived&>();185 test_is_not_constructible<Derived&, Base&>();186 test_is_constructible<Base const&, Derived const&>();187#ifndef TEST_COMPILER_GCC188 test_is_not_constructible<Derived const&, Base const&>();189 test_is_not_constructible<Derived const&, Base>();190#endif191 192 test_is_constructible<Base&&, Derived>();193 test_is_constructible<Base&&, Derived&&>();194#ifndef TEST_COMPILER_GCC195 test_is_not_constructible<Derived&&, Base&&>();196 test_is_not_constructible<Derived&&, Base>();197#endif198 199 // test that T must also be destructible200 test_is_constructible<PrivateDtor&, PrivateDtor&>();201 test_is_not_constructible<PrivateDtor, int>();202 203 test_is_not_constructible<void() const, void() const>();204 test_is_not_constructible<void() const, void*>();205 206 test_is_constructible<int&, ImplicitTo<int&>>();207 test_is_constructible<const int&, ImplicitTo<int&&>>();208 test_is_constructible<int&&, ImplicitTo<int&&>>();209 test_is_constructible<const int&, ImplicitTo<int>>();210 211 test_is_not_constructible<B&&, B&>();212 test_is_not_constructible<B&&, D&>();213 test_is_constructible<B&&, ImplicitTo<D&&>>();214 test_is_constructible<B&&, ImplicitTo<D&&>&>();215 test_is_constructible<int&&, double&>();216 test_is_constructible<const int&, ImplicitTo<int&>&>();217 test_is_constructible<const int&, ImplicitTo<int&>>();218 test_is_constructible<const int&, ExplicitTo<int&>&>();219 test_is_constructible<const int&, ExplicitTo<int&>>();220 221 test_is_constructible<const int&, ExplicitTo<int&>&>();222 test_is_constructible<const int&, ExplicitTo<int&>>();223 224 225 // Binding through reference-compatible type is required to perform226 // direct-initialization as described in [over.match.ref] p. 1 b. 1:227 //228 // But the rvalue to lvalue reference binding isn't allowed according to229 // [over.match.ref] despite Clang accepting it.230 test_is_constructible<int&, ExplicitTo<int&>>();231#ifndef TEST_COMPILER_CLANG232 test_is_not_constructible<const int&, ExplicitTo<int&&>>();233#endif234 235 static_assert(std::is_constructible<int&&, ExplicitTo<int&&>>::value, "");236 237#ifdef __clang__238 // FIXME Clang and GCC disagree on the validity of this expression.239 test_is_constructible<const int&, ExplicitTo<int>>();240 static_assert(std::is_constructible<int&&, ExplicitTo<int>>::value, "");241#else242 test_is_not_constructible<const int&, ExplicitTo<int>>();243 test_is_not_constructible<int&&, ExplicitTo<int>>();244#endif245 246 // Binding through temporary behaves like copy-initialization,247 // see [dcl.init.ref] p. 5, very last sub-bullet:248 test_is_not_constructible<const int&, ExplicitTo<double&&>>();249 test_is_not_constructible<int&&, ExplicitTo<double&&>>();250 251 test_is_not_constructible<void()>();252 test_is_not_constructible<void() const> ();253 test_is_not_constructible<void() volatile> ();254 test_is_not_constructible<void() &> ();255 test_is_not_constructible<void() &&> ();256#endif // TEST_STD_VER >= 11257 258 return 0;259}260