164 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++1410 11// <variant>12 13// template <size_t I, class... Types>14// constexpr variant_alternative_t<I, variant<Types...>>&15// get(variant<Types...>& v);16// template <size_t I, class... Types>17// constexpr variant_alternative_t<I, variant<Types...>>&&18// get(variant<Types...>&& v);19// template <size_t I, class... Types>20// constexpr variant_alternative_t<I, variant<Types...>> const& get(const21// variant<Types...>& v);22// template <size_t I, class... Types>23// constexpr variant_alternative_t<I, variant<Types...>> const&& get(const24// variant<Types...>&& v);25 26#include "test_macros.h"27#include "test_workarounds.h"28#include "variant_test_helpers.h"29#include <cassert>30#include <type_traits>31#include <utility>32#include <variant>33 34void test_const_lvalue_get() {35 {36 using V = std::variant<int, const long>;37 constexpr V v(42);38 ASSERT_NOT_NOEXCEPT(std::get<0>(v));39 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);40 static_assert(std::get<0>(v) == 42, "");41 }42 {43 using V = std::variant<int, const long>;44 const V v(42);45 ASSERT_NOT_NOEXCEPT(std::get<0>(v));46 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);47 assert(std::get<0>(v) == 42);48 }49 {50 using V = std::variant<int, const long>;51 constexpr V v(42l);52 ASSERT_NOT_NOEXCEPT(std::get<1>(v));53 ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &);54 static_assert(std::get<1>(v) == 42, "");55 }56 {57 using V = std::variant<int, const long>;58 const V v(42l);59 ASSERT_NOT_NOEXCEPT(std::get<1>(v));60 ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &);61 assert(std::get<1>(v) == 42);62 }63}64 65void test_lvalue_get() {66 {67 using V = std::variant<int, const long>;68 V v(42);69 ASSERT_NOT_NOEXCEPT(std::get<0>(v));70 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &);71 assert(std::get<0>(v) == 42);72 }73 {74 using V = std::variant<int, const long>;75 V v(42l);76 ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &);77 assert(std::get<1>(v) == 42);78 }79}80 81void test_rvalue_get() {82 {83 using V = std::variant<int, const long>;84 V v(42);85 ASSERT_NOT_NOEXCEPT(std::get<0>(std::move(v)));86 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &&);87 assert(std::get<0>(std::move(v)) == 42);88 }89 {90 using V = std::variant<int, const long>;91 V v(42l);92 ASSERT_SAME_TYPE(decltype(std::get<1>(std::move(v))), const long &&);93 assert(std::get<1>(std::move(v)) == 42);94 }95}96 97void test_const_rvalue_get() {98 {99 using V = std::variant<int, const long>;100 const V v(42);101 ASSERT_NOT_NOEXCEPT(std::get<0>(std::move(v)));102 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &&);103 assert(std::get<0>(std::move(v)) == 42);104 }105 {106 using V = std::variant<int, const long>;107 const V v(42l);108 ASSERT_SAME_TYPE(decltype(std::get<1>(std::move(v))), const long &&);109 assert(std::get<1>(std::move(v)) == 42);110 }111}112 113template <std::size_t I> using Idx = std::integral_constant<std::size_t, I>;114 115void test_throws_for_all_value_categories() {116#ifndef TEST_HAS_NO_EXCEPTIONS117 using V = std::variant<int, long>;118 V v0(42);119 const V &cv0 = v0;120 assert(v0.index() == 0);121 V v1(42l);122 const V &cv1 = v1;123 assert(v1.index() == 1);124 std::integral_constant<std::size_t, 0> zero;125 std::integral_constant<std::size_t, 1> one;126 auto test = [](auto idx, auto &&v) {127 using Idx = decltype(idx);128 try {129 TEST_IGNORE_NODISCARD std::get<Idx::value>(std::forward<decltype(v)>(v));130 } catch (const std::bad_variant_access &) {131 return true;132 } catch (...) { /* ... */133 }134 return false;135 };136 { // lvalue test cases137 assert(test(one, v0));138 assert(test(zero, v1));139 }140 { // const lvalue test cases141 assert(test(one, cv0));142 assert(test(zero, cv1));143 }144 { // rvalue test cases145 assert(test(one, std::move(v0)));146 assert(test(zero, std::move(v1)));147 }148 { // const rvalue test cases149 assert(test(one, std::move(cv0)));150 assert(test(zero, std::move(cv1)));151 }152#endif153}154 155int main(int, char**) {156 test_const_lvalue_get();157 test_lvalue_get();158 test_rvalue_get();159 test_const_rvalue_get();160 test_throws_for_all_value_categories();161 162 return 0;163}164