// -*- C++ -*- //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++98, c++03, c++11, c++14 // // template class variant; // template void emplace(Args&&... args); #include #include #include #include #include "archetypes.hpp" #include "test_convertible.hpp" #include "test_macros.h" #include "variant_test_helpers.hpp" template constexpr auto test_emplace_exists_imp(int) -> decltype( std::declval().template emplace(std::declval()...), true) { return true; } template constexpr auto test_emplace_exists_imp(long) -> bool { return false; } template constexpr bool emplace_exists() { return test_emplace_exists_imp(0); } void test_emplace_sfinae() { { using V = std::variant; static_assert(emplace_exists(), ""); static_assert(emplace_exists(), ""); static_assert(!emplace_exists(), "cannot construct"); static_assert(emplace_exists(), ""); static_assert(!emplace_exists(), "cannot construct"); static_assert(emplace_exists(), ""); static_assert(!emplace_exists(), ""); static_assert(emplace_exists(), ""); static_assert(emplace_exists(), ""); static_assert(!emplace_exists(), "cannot construct"); } #if !defined(TEST_VARIANT_HAS_NO_REFERENCES) using V = std::variant; static_assert(emplace_exists(), ""); static_assert(emplace_exists(), ""); static_assert(emplace_exists(), ""); static_assert(!emplace_exists(), "too many args"); static_assert(emplace_exists(), ""); static_assert(!emplace_exists(), "cannot default construct ref"); static_assert(!emplace_exists(), "cannot bind ref"); static_assert(!emplace_exists(), "cannot bind ref"); static_assert(emplace_exists(), ""); static_assert(emplace_exists(), ""); static_assert(emplace_exists(), ""); static_assert(!emplace_exists(), "not constructible from void*"); static_assert(emplace_exists(), ""); static_assert(!emplace_exists(), "cannot bind ref"); static_assert(!emplace_exists(), "cannot bind ref"); static_assert(!emplace_exists(), "cannot bind ref"); static_assert(!emplace_exists(), "ambiguous"); static_assert(!emplace_exists(), "cannot construct void"); #endif } void test_basic() { { using V = std::variant; V v(42); v.emplace(); assert(std::get<0>(v) == 0); v.emplace(42); assert(std::get<0>(v) == 42); } { using V = std::variant; const int x = 100; V v(std::in_place_type, -1); // default emplace a value v.emplace(); assert(std::get<1>(v) == 0); v.emplace(&x); assert(std::get<2>(v) == &x); // emplace with multiple args v.emplace(3, 'a'); assert(std::get<4>(v) == "aaa"); } #if !defined(TEST_VARIANT_HAS_NO_REFERENCES) { using V = std::variant; const int x = 100; int y = 42; int z = 43; V v(std::in_place_index<0>, -1); // default emplace a value v.emplace(); assert(std::get(v) == 0); // emplace a reference v.emplace(x); assert(&std::get(v) == &x); // emplace an rvalue reference v.emplace(std::move(y)); assert(&std::get(v) == &y); // re-emplace a new reference over the active member v.emplace(std::move(z)); assert(&std::get(v) == &z); // emplace with multiple args v.emplace(3, 'a'); assert(std::get(v) == "aaa"); } #endif } int main() { test_basic(); test_emplace_sfinae(); }