//===----------------------------------------------------------------------===// // // 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++03, c++11, c++14, c++17, c++20 // template // struct in_value_result; #include #include #include #include #include "MoveOnly.h" struct A { explicit A(int); }; // no implicit conversion static_assert(!std::is_constructible_v, std::ranges::in_value_result>); struct B { B(int); }; // implicit conversion static_assert(std::is_constructible_v, std::ranges::in_value_result>); static_assert(std::is_constructible_v, std::ranges::in_value_result&>); static_assert( std::is_constructible_v, const std::ranges::in_value_result>); static_assert( std::is_constructible_v, const std::ranges::in_value_result&>); struct C { C(int&); }; static_assert(!std::is_constructible_v, std::ranges::in_value_result&>); // has to be convertible via const& static_assert(std::is_convertible_v&, std::ranges::in_value_result>); static_assert( std::is_convertible_v&, std::ranges::in_value_result>); static_assert( std::is_convertible_v&&, std::ranges::in_value_result>); static_assert( std::is_convertible_v&&, std::ranges::in_value_result>); // should be move constructible static_assert(std::is_move_constructible_v>); static_assert(std::is_move_constructible_v>); // should not be copy constructible with move-only type static_assert(!std::is_copy_constructible_v>); static_assert(!std::is_copy_constructible_v>); struct NotConvertible {}; // conversions should not work if there is no conversion static_assert( !std::is_convertible_v, std::ranges::in_value_result>); static_assert( !std::is_convertible_v, std::ranges::in_value_result>); template struct ConvertibleFrom { constexpr ConvertibleFrom(T c) : content{c} {} T content; }; constexpr bool test() { // Checks that conversion operations are correct. { std::ranges::in_value_result res{10, 0.}; assert(res.in == 10); assert(res.value == 0.); std::ranges::in_value_result, ConvertibleFrom> res2 = res; assert(res2.in.content == 10); assert(res2.value.content == 0.); } // Checks that conversions are possible when one of the types is move-only. { std::ranges::in_value_result res{MoveOnly{}, 2}; assert(res.in.get() == 1); assert(res.value == 2); auto res2 = static_cast>(std::move(res)); assert(res.in.get() == 0); assert(res2.in.get() == 1); assert(res2.value == 2); } // Checks that structured bindings get the correct values. { auto [in, value] = std::ranges::in_value_result{1, 2}; assert(in == 1); assert(value == 2); } return true; } int main(int, char**) { test(); static_assert(test()); return 0; }