brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.1 KiB · 455c268 Raw
166 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// <utility>10 11// template <class T1, class T2> struct pair12 13// Test the SFINAE required by LWG Issue #2367.14// is_default_constructible<pair>15 16// UNSUPPORTED: c++0317 18#include <utility>19#include <type_traits>20#include <cassert>21 22#include "test_macros.h"23 24#if TEST_STD_VER > 1125#define CONSTEXPR_CXX14 constexpr26#define STATIC_ASSERT_CXX14(Pred) static_assert(Pred, "")27#else28#define CONSTEXPR_CXX1429#define STATIC_ASSERT_CXX14(Pred) assert(Pred)30#endif31 32struct DeletedDefault {33    // A class with a deleted default constructor. Used to test the SFINAE34    // on std::pair's default constructor.35    constexpr explicit DeletedDefault(int x) : value(x) {}36    constexpr DeletedDefault() = delete;37    int value;38};39 40template <class Tp, bool>41struct DependantType: public Tp {};42 43template <class T, bool Val>44using DependantIsDefault = DependantType<std::is_default_constructible<T>, Val>;45 46template <class T>47struct DefaultSFINAES {48    template <bool Dummy = false, class = typename std::enable_if<49             DependantIsDefault<T, Dummy>::value50                >::type51            >52    constexpr DefaultSFINAES() : value() {}53    constexpr explicit DefaultSFINAES(T const& x) : value(x) {}54    T value;55};56 57struct NoDefault {58    constexpr NoDefault(int v) : value(v) {}59    int value;60};61 62template <class Tp>63void test_not_is_default_constructible()64{65    {66        typedef std::pair<int, Tp> P;67        static_assert(!std::is_default_constructible<P>::value, "");68        static_assert(std::is_constructible<P, int, Tp>::value, "");69    }70    {71        typedef std::pair<Tp, int> P;72        static_assert(!std::is_default_constructible<P>::value, "");73        static_assert(std::is_constructible<P, Tp, int>::value, "");74    }75    {76        typedef std::pair<Tp, Tp> P;77        static_assert(!std::is_default_constructible<P>::value, "");78        static_assert(std::is_constructible<P, Tp, Tp>::value, "");79    }80}81 82template <class Tp>83void test_is_default_constructible()84{85    {86        typedef std::pair<int, Tp> P;87        static_assert(std::is_default_constructible<P>::value, "");88    }89    {90        typedef std::pair<Tp, int> P;91        static_assert(std::is_default_constructible<P>::value, "");92    }93    {94        typedef std::pair<Tp, Tp> P;95        static_assert(std::is_default_constructible<P>::value, "");96    }97}98 99template <class T>100struct IllFormedDefaultImp {101  constexpr explicit IllFormedDefaultImp(int v) : value(v) {}102  constexpr IllFormedDefaultImp() : value(T::DoesNotExistAndShouldNotCompile) {}103  int value;104};105 106typedef IllFormedDefaultImp<int> IllFormedDefault;107    // A class which provides a constexpr default constructor with a valid108    // signature but an ill-formed body. The A compile error will be emitted if109    // the default constructor is instantiated.110 111 112// Check that the SFINAE on the default constructor is not evaluated when113// it isn't needed. If the default constructor of 'IllFormedDefault' is evaluated114// in C++11, even with is_default_constructible, then this test should fail to115// compile. In C++14 and greater evaluate each test is evaluated as a constant116// expression.117// See LWG issue #2367118void test_illformed_default()119{120    {121    typedef std::pair<IllFormedDefault, int> P;122    static_assert((std::is_constructible<P, IllFormedDefault, int>::value), "");123    CONSTEXPR_CXX14 P p(IllFormedDefault(42), -5);124    STATIC_ASSERT_CXX14(p.first.value == 42 && p.second == -5);125    }126    {127    typedef std::pair<int, IllFormedDefault> P;128    static_assert((std::is_constructible<P, int, IllFormedDefault>::value), "");129    CONSTEXPR_CXX14 IllFormedDefault dd(-5);130    CONSTEXPR_CXX14 P p(42, dd);131    STATIC_ASSERT_CXX14(p.first == 42 && p.second.value == -5);132    }133    {134    typedef std::pair<IllFormedDefault, IllFormedDefault> P;135    static_assert((std::is_constructible<P, IllFormedDefault, IllFormedDefault>::value), "");136    CONSTEXPR_CXX14 P p(IllFormedDefault(42), IllFormedDefault(-5));137    STATIC_ASSERT_CXX14(p.first.value == 42 && p.second.value == -5);138    }139}140 141 142int main(int, char**)143{144    {145        // Check that pair<T, U> can still be used even if146        // is_default_constructible<T> or is_default_constructible<U> cause147        // a compilation error.148        test_illformed_default();149    }150    {151        // pair::pair() is only disable in C++11 and beyond.152        test_not_is_default_constructible<NoDefault>();153        test_not_is_default_constructible<DeletedDefault>();154        test_not_is_default_constructible<DefaultSFINAES<int&>>();155        test_not_is_default_constructible<DefaultSFINAES<int&&>>();156        test_not_is_default_constructible<int&>();157        test_not_is_default_constructible<int&&>();158    }159    {160        test_is_default_constructible<int>();161        test_is_default_constructible<DefaultSFINAES<int>>();162    }163 164  return 0;165}166