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 namespace hana = boost::hana;
10
11
12 template <typename ...>
13 struct never { static constexpr bool value = false; };
14
15 struct NoValueCtor {
NoValueCtorNoValueCtor16 NoValueCtor() : id(++count) {}
NoValueCtorNoValueCtor17 NoValueCtor(NoValueCtor const & other) : id(other.id) { ++count; }
18
19 // The constexpr is required to make is_constructible instantiate this
20 // template. The explicit is needed to test-around a similar bug with
21 // is_convertible.
22 template <typename T>
NoValueCtorNoValueCtor23 constexpr explicit NoValueCtor(T)
24 { static_assert(never<T>::value, "This should not be instantiated"); }
25
26 static int count;
27 int id;
28 };
29
30 int NoValueCtor::count = 0;
31
32
33 struct NoValueCtorEmpty {
NoValueCtorEmptyNoValueCtorEmpty34 NoValueCtorEmpty() {}
NoValueCtorEmptyNoValueCtorEmpty35 NoValueCtorEmpty(NoValueCtorEmpty const &) {}
36
37 template <typename T>
NoValueCtorEmptyNoValueCtorEmpty38 constexpr explicit NoValueCtorEmpty(T)
39 { static_assert(never<T>::value, "This should not be instantiated"); }
40 };
41
main()42 int main() {
43 {
44 hana::tuple<int> t(2);
45 BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2);
46 }
47 {
48 constexpr hana::tuple<int> t(2);
49 static_assert(hana::at_c<0>(t) == 2, "");
50 }
51 {
52 constexpr hana::tuple<int> t;
53 static_assert(hana::at_c<0>(t) == 0, "");
54 }
55 {
56 constexpr hana::tuple<int, char*> t(2, nullptr);
57 static_assert(hana::at_c<0>(t) == 2, "");
58 static_assert(hana::at_c<1>(t) == nullptr, "");
59 }
60 {
61 hana::tuple<int, char*> t(2, nullptr);
62 BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2);
63 BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == nullptr);
64 }
65 {
66 hana::tuple<int, char*, std::string> t(2, nullptr, "text");
67 BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2);
68 BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == nullptr);
69 BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == "text");
70 }
71 {
72 hana::tuple<int, NoValueCtor, int, int> t(1, NoValueCtor(), 2, 3);
73 BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 1);
74 BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t).id == 1);
75 BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == 2);
76 BOOST_HANA_RUNTIME_CHECK(hana::at_c<3>(t) == 3);
77 }
78 {
79 hana::tuple<int, NoValueCtorEmpty, int, int> t(1, NoValueCtorEmpty(), 2, 3);
80 BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 1);
81 BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == 2);
82 BOOST_HANA_RUNTIME_CHECK(hana::at_c<3>(t) == 3);
83 }
84 {
85 struct T { };
86 struct U { };
87 struct V { };
88
89 constexpr T t{};
90 constexpr U u{};
91 constexpr V v{};
92
93 constexpr hana::tuple<T> x1{t}; (void)x1;
94 constexpr hana::tuple<T, U> x2{t, u}; (void)x2;
95 constexpr hana::tuple<T, U, V> x3{t, u, v}; (void)x3;
96 }
97 {
98 struct T { };
99 struct U { };
100 struct V { };
101
102 // Check for SFINAE-friendliness
103 static_assert(!std::is_constructible<
104 hana::tuple<T, U>, T
105 >{}, "");
106
107 static_assert(!std::is_constructible<
108 hana::tuple<T, U>, U, T
109 >{}, "");
110
111 static_assert(!std::is_constructible<
112 hana::tuple<T, U>, T, U, V
113 >{}, "");
114 }
115
116 // Make sure we can initialize elements with the brace-init syntax.
117 {
118 struct Member { };
119 struct Element { Member member; };
120
121 hana::tuple<Element, Element> xs{{Member()}, {Member()}};
122 hana::tuple<Element, Element> ys = {{Member()}, {Member()}};
123 (void)xs; (void)ys;
124 }
125 }
126