• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright Louis Dionne 2013-2017
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
4 
5 #include <boost/hana/assert.hpp>
6 #include <boost/hana/tuple.hpp>
7 
8 #include <string>
9 #include <type_traits>
10 namespace hana = boost::hana;
11 
12 
13 struct DefaultOnly {
14     int data_;
15     DefaultOnly(DefaultOnly const&) = delete;
16     DefaultOnly& operator=(DefaultOnly const&) = delete;
17 
18     static int count;
19 
DefaultOnlyDefaultOnly20     DefaultOnly() : data_(-1) { ++count; }
~DefaultOnlyDefaultOnly21     ~DefaultOnly() { data_ = 0; --count; }
22 
operator ==(DefaultOnly const & x,DefaultOnly const & y)23     friend bool operator==(DefaultOnly const& x, DefaultOnly const& y)
24     { return x.data_ == y.data_; }
25 
operator <(DefaultOnly const & x,DefaultOnly const & y)26     friend bool operator< (DefaultOnly const& x, DefaultOnly const& y)
27     { return x.data_ < y.data_; }
28 };
29 
30 int DefaultOnly::count = 0;
31 
32 struct NoDefault {
33     NoDefault() = delete;
NoDefaultNoDefault34     explicit NoDefault(int) { }
35 };
36 
37 struct IllFormedDefault {
IllFormedDefaultIllFormedDefault38     IllFormedDefault(int x) : value(x) {}
39     template <bool Pred = false>
IllFormedDefaultIllFormedDefault40     constexpr IllFormedDefault() {
41         static_assert(Pred,
42             "The default constructor should not be instantiated");
43     }
44     int value;
45 };
46 
main()47 int main() {
48     {
49         hana::tuple<> t; (void)t;
50     }
51     {
52         hana::tuple<int> t;
53         BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
54     }
55     {
56         hana::tuple<int, char*> t;
57         BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
58         BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == nullptr);
59     }
60     {
61         hana::tuple<int, char*, std::string> t;
62         BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
63         BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == nullptr);
64         BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == "");
65     }
66     {
67         hana::tuple<int, char*, std::string, DefaultOnly> t;
68         BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
69         BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == nullptr);
70         BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == "");
71         BOOST_HANA_RUNTIME_CHECK(hana::at_c<3>(t) == DefaultOnly());
72     }
73     {
74         // See LLVM bug #21157.
75         static_assert(!std::is_default_constructible<
76             hana::tuple<NoDefault>
77         >(), "");
78         static_assert(!std::is_default_constructible<
79             hana::tuple<DefaultOnly, NoDefault>
80         >(), "");
81         static_assert(!std::is_default_constructible<
82             hana::tuple<NoDefault, DefaultOnly, NoDefault>
83         >(), "");
84     }
85     {
86         struct T { };
87         struct U { };
88         struct V { };
89 
90         constexpr hana::tuple<> z0;        (void)z0;
91         constexpr hana::tuple<T> z1;       (void)z1;
92         constexpr hana::tuple<T, U> z2;    (void)z2;
93         constexpr hana::tuple<T, U, V> z3; (void)z3;
94     }
95     {
96         constexpr hana::tuple<int> t;
97         BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
98     }
99     {
100         constexpr hana::tuple<int, char*> t;
101         BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
102         BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == nullptr);
103     }
104 
105     // Make sure we can hold non default-constructible elements, and that
106     // it does not trigger an error in the default constructor.
107     {
108         {
109             IllFormedDefault v(0);
110             hana::tuple<IllFormedDefault> t1(v);
111             hana::tuple<IllFormedDefault> t2{v};
112             hana::tuple<IllFormedDefault> t3 = {v};
113             (void)t1;(void)t2;(void)t3; // remove spurious unused variable warning on GCC
114         }
115         {
116             hana::tuple<NoDefault> t1(0);
117             hana::tuple<NoDefault> t2{0};
118             hana::tuple<NoDefault> t3 = {0};
119             (void)t1;(void)t2;(void)t3; // remove spurious unused variable warning on GCC
120         }
121         {
122             NoDefault v(0);
123             hana::tuple<NoDefault> t1(v);
124             hana::tuple<NoDefault> t2{v};
125             hana::tuple<NoDefault> t3 = {v};
126             (void)t1;(void)t2;(void)t3; // remove spurious unused variable warning on GCC
127         }
128     }
129 
130     // Make sure a tuple_t can be default-constructed
131     {
132         struct T;
133         struct U;
134 
135         using Types = decltype(hana::tuple_t<T, U>);
136         Types t{}; (void)t;
137     }
138 }
139