brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.6 KiB · f4f55b8 Raw
123 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++0310 11// TODO: Revisit this test once we have more information12//       with https://gcc.gnu.org/bugzilla/show_bug.cgi?id=10224713// XFAIL: gcc14 15// <utility>16 17// template <class T1, class T2> struct pair18//19// pair(const T1&, const T2&);20// template<class U = T1, class V = T2> pair(U&&, V&&);21 22// This test checks support for brace-initialization of pairs.23 24#include <utility>25#include <cassert>26 27#include "test_macros.h"28 29struct ExplicitT {30  constexpr explicit ExplicitT(int x) : value(x) {}31  constexpr explicit ExplicitT(ExplicitT const& o) : value(o.value) {}32  int value;33};34 35struct ImplicitT {36  constexpr ImplicitT(int x) : value(x) {}37  constexpr ImplicitT(ImplicitT const& o) : value(o.value) {}38  int value;39};40 41template <class T, class = decltype(std::pair<T, T>({}, {}))>42constexpr bool can_construct_with_brace_init(int) { return true; }43template <class T>44constexpr bool can_construct_with_brace_init(...) { return false; }45 46#if TEST_STD_VER >= 17 // CTAD isn't supported before C++1747template <class T, class = decltype(std::pair(T{}, {}))>48constexpr bool can_construct_with_ctad_brace_init(int) { return true; }49template <class T>50constexpr bool can_construct_with_ctad_brace_init(...) { return false; }51#endif52 53struct BraceInit { BraceInit() = default; };54struct NoBraceInit { NoBraceInit(int); };55struct ExplicitBraceInit { explicit ExplicitBraceInit() = default; };56 57constexpr int explicit_vs_implicit_brace_init(std::pair<ExplicitBraceInit, ExplicitBraceInit>) { return 1; }58constexpr int explicit_vs_implicit_brace_init(std::pair<BraceInit, BraceInit>) { return 2; }59 60TEST_CONSTEXPR_CXX14 bool test() {61    // Explicit constructor62    {63        std::pair<ExplicitT, BraceInit> p1(ExplicitT{42}, {});64        assert(p1.first.value == 42);65 66        std::pair<ExplicitT, BraceInit> p2{ExplicitT{42}, {}};67        assert(p2.first.value == 42);68    }69    {70        std::pair<BraceInit, ExplicitT> p1({}, ExplicitT{42});71        assert(p1.second.value == 42);72 73        std::pair<BraceInit, ExplicitT> p2{{}, ExplicitT{42}};74        assert(p2.second.value == 42);75    }76    {77        std::pair<BraceInit, BraceInit> p{{}, {}};78        (void)p;79    }80 81    // Implicit constructor82    {83        std::pair<ImplicitT, BraceInit> p = {42, {}};84        assert(p.first.value == 42);85    }86    {87        std::pair<BraceInit, ImplicitT> p = {{}, 42};88        assert(p.second.value == 42);89    }90    {91        std::pair<BraceInit, BraceInit> p = {{}, {}};92        (void)p;93    }94 95    // SFINAE-friendliness of some invalid cases96    {97        static_assert( can_construct_with_brace_init<BraceInit>(0), "");98        static_assert(!can_construct_with_brace_init<NoBraceInit>(0), "");99 100#if TEST_STD_VER >= 17101        // CTAD with {} should never work, since we can't possibly deduce the types102        static_assert(!can_construct_with_ctad_brace_init<BraceInit>(0), "");103        static_assert(!can_construct_with_ctad_brace_init<int>(0), "");104#endif105    }106 107    // Make sure there is no ambiguity between the explicit and the non-explicit constructors108    {109        assert(explicit_vs_implicit_brace_init({{}, {}}) == 2);110    }111 112    return true;113}114 115int main(int, char**) {116    test();117#if TEST_STD_VER > 11118    static_assert(test(), "");119#endif120 121    return 0;122}123