
Some tests are marked as failing on platforms where the dylib does not provide the required exception classes. However, when testing with exceptions disabled, those tests shouldn't be marked as failing. llvm-svn: 353210
129 lines
3.3 KiB
C++
129 lines
3.3 KiB
C++
// -*- C++ -*-
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
|
// XFAIL: dylib-has-no-bad_variant_access && !libcpp-no-exceptions
|
|
|
|
// <variant>
|
|
|
|
// template <class ...Types> class variant;
|
|
|
|
// template <class T> constexpr variant(T&&) noexcept(see below);
|
|
|
|
#include <cassert>
|
|
#include <string>
|
|
#include <type_traits>
|
|
#include <variant>
|
|
|
|
#include "test_convertible.hpp"
|
|
#include "test_macros.h"
|
|
#include "variant_test_helpers.hpp"
|
|
|
|
struct Dummy {
|
|
Dummy() = default;
|
|
};
|
|
|
|
struct ThrowsT {
|
|
ThrowsT(int) noexcept(false) {}
|
|
};
|
|
|
|
struct NoThrowT {
|
|
NoThrowT(int) noexcept(true) {}
|
|
};
|
|
|
|
struct AnyConstructible { template <typename T> AnyConstructible(T&&) {} };
|
|
struct NoConstructible { NoConstructible() = delete; };
|
|
|
|
void test_T_ctor_noexcept() {
|
|
{
|
|
using V = std::variant<Dummy, NoThrowT>;
|
|
static_assert(std::is_nothrow_constructible<V, int>::value, "");
|
|
}
|
|
{
|
|
using V = std::variant<Dummy, ThrowsT>;
|
|
static_assert(!std::is_nothrow_constructible<V, int>::value, "");
|
|
}
|
|
}
|
|
|
|
void test_T_ctor_sfinae() {
|
|
{
|
|
using V = std::variant<long, unsigned>;
|
|
static_assert(!std::is_constructible<V, int>::value, "ambiguous");
|
|
}
|
|
{
|
|
using V = std::variant<std::string, std::string>;
|
|
static_assert(!std::is_constructible<V, const char *>::value, "ambiguous");
|
|
}
|
|
{
|
|
using V = std::variant<std::string, void *>;
|
|
static_assert(!std::is_constructible<V, int>::value,
|
|
"no matching constructor");
|
|
}
|
|
{
|
|
using V = std::variant<AnyConstructible, NoConstructible>;
|
|
static_assert(
|
|
!std::is_constructible<V, std::in_place_type_t<NoConstructible>>::value,
|
|
"no matching constructor");
|
|
static_assert(!std::is_constructible<V, std::in_place_index_t<1>>::value,
|
|
"no matching constructor");
|
|
}
|
|
|
|
|
|
|
|
#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
|
|
{
|
|
using V = std::variant<int, int &&>;
|
|
static_assert(!std::is_constructible<V, int>::value, "ambiguous");
|
|
}
|
|
{
|
|
using V = std::variant<int, const int &>;
|
|
static_assert(!std::is_constructible<V, int>::value, "ambiguous");
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void test_T_ctor_basic() {
|
|
{
|
|
constexpr std::variant<int> v(42);
|
|
static_assert(v.index() == 0, "");
|
|
static_assert(std::get<0>(v) == 42, "");
|
|
}
|
|
{
|
|
constexpr std::variant<int, long> v(42l);
|
|
static_assert(v.index() == 1, "");
|
|
static_assert(std::get<1>(v) == 42, "");
|
|
}
|
|
#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
|
|
{
|
|
using V = std::variant<const int &, int &&, long>;
|
|
static_assert(std::is_convertible<int &, V>::value, "must be implicit");
|
|
int x = 42;
|
|
V v(x);
|
|
assert(v.index() == 0);
|
|
assert(&std::get<0>(v) == &x);
|
|
}
|
|
{
|
|
using V = std::variant<const int &, int &&, long>;
|
|
static_assert(std::is_convertible<int, V>::value, "must be implicit");
|
|
int x = 42;
|
|
V v(std::move(x));
|
|
assert(v.index() == 1);
|
|
assert(&std::get<1>(v) == &x);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
int main(int, char**) {
|
|
test_T_ctor_basic();
|
|
test_T_ctor_noexcept();
|
|
test_T_ctor_sfinae();
|
|
|
|
return 0;
|
|
}
|