139 lines
4.1 KiB
C++
139 lines
4.1 KiB
C++
// 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;
|
|
}
|
|
}
|