summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/hana/test/tuple/cnstr.default.cpp
blob: 5d9af67a2a9a50d84808b2c649608d8c2c3626cc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)

#include <boost/hana/assert.hpp>
#include <boost/hana/tuple.hpp>

#include <string>
#include <type_traits>
namespace hana = boost::hana;


struct DefaultOnly {
    int data_;
    DefaultOnly(DefaultOnly const&) = delete;
    DefaultOnly& operator=(DefaultOnly const&) = delete;

    static int count;

    DefaultOnly() : data_(-1) { ++count; }
    ~DefaultOnly() { data_ = 0; --count; }

    friend bool operator==(DefaultOnly const& x, DefaultOnly const& y)
    { return x.data_ == y.data_; }

    friend bool operator< (DefaultOnly const& x, DefaultOnly const& y)
    { return x.data_ < y.data_; }
};

int DefaultOnly::count = 0;

struct NoDefault {
    NoDefault() = delete;
    explicit NoDefault(int) { }
};

struct IllFormedDefault {
    IllFormedDefault(int x) : value(x) {}
    template <bool Pred = false>
    constexpr IllFormedDefault() {
        static_assert(Pred,
            "The default constructor should not be instantiated");
    }
    int value;
};

int main() {
    {
        hana::tuple<> t; (void)t;
    }
    {
        hana::tuple<int> t;
        BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
    }
    {
        hana::tuple<int, char*> t;
        BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
        BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == nullptr);
    }
    {
        hana::tuple<int, char*, std::string> t;
        BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
        BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == nullptr);
        BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == "");
    }
    {
        hana::tuple<int, char*, std::string, DefaultOnly> t;
        BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
        BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == nullptr);
        BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == "");
        BOOST_HANA_RUNTIME_CHECK(hana::at_c<3>(t) == DefaultOnly());
    }
    {
        // See LLVM bug #21157.
        static_assert(!std::is_default_constructible<
            hana::tuple<NoDefault>
        >(), "");
        static_assert(!std::is_default_constructible<
            hana::tuple<DefaultOnly, NoDefault>
        >(), "");
        static_assert(!std::is_default_constructible<
            hana::tuple<NoDefault, DefaultOnly, NoDefault>
        >(), "");
    }
    {
        struct T { };
        struct U { };
        struct V { };

        constexpr hana::tuple<> z0;        (void)z0;
        constexpr hana::tuple<T> z1;       (void)z1;
        constexpr hana::tuple<T, U> z2;    (void)z2;
        constexpr hana::tuple<T, U, V> z3; (void)z3;
    }
    {
        constexpr hana::tuple<int> t;
        BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
    }
    {
        constexpr hana::tuple<int, char*> t;
        BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
        BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == nullptr);
    }

    // Make sure we can hold non default-constructible elements, and that
    // it does not trigger an error in the default constructor.
    {
        {
            IllFormedDefault v(0);
            hana::tuple<IllFormedDefault> t1(v);
            hana::tuple<IllFormedDefault> t2{v};
            hana::tuple<IllFormedDefault> t3 = {v};
            (void)t1;(void)t2;(void)t3; // remove spurious unused variable warning on GCC
        }
        {
            hana::tuple<NoDefault> t1(0);
            hana::tuple<NoDefault> t2{0};
            hana::tuple<NoDefault> t3 = {0};
            (void)t1;(void)t2;(void)t3; // remove spurious unused variable warning on GCC
        }
        {
            NoDefault v(0);
            hana::tuple<NoDefault> t1(v);
            hana::tuple<NoDefault> t2{v};
            hana::tuple<NoDefault> t3 = {v};
            (void)t1;(void)t2;(void)t3; // remove spurious unused variable warning on GCC
        }
    }

    // Make sure a tuple_t can be default-constructed
    {
        struct T;
        struct U;

        using Types = decltype(hana::tuple_t<T, U>);
        Types t{}; (void)t;
    }
}