//===----------------------------------------------------------------------===// // // 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 // UNSUPPORTED: libcpp-no-concepts, libcpp-has-no-incomplete-ranges // // // namespace ranges { // template // struct in_out_result; // } #include #include #include struct A { A(int&); }; static_assert(!std::is_constructible_v, std::ranges::in_out_result&>); static_assert(std::is_convertible_v&, std::ranges::in_out_result>); static_assert(!std::is_nothrow_convertible_v&, std::ranges::in_out_result>); static_assert(std::is_convertible_v&, std::ranges::in_out_result>); static_assert(!std::is_nothrow_convertible_v&, std::ranges::in_out_result>); static_assert(std::is_convertible_v&&, std::ranges::in_out_result>); static_assert(!std::is_nothrow_convertible_v&&, std::ranges::in_out_result>); static_assert(std::is_convertible_v&&, std::ranges::in_out_result>); static_assert(!std::is_nothrow_convertible_v&&, std::ranges::in_out_result>); int main(int, char**) { // Conversion, fundamental types. { std::ranges::in_out_result x = {2, false}; // FIXME(varconst): try a narrowing conversion. std::ranges::in_out_result y = x; assert(y.in == 2); assert(y.out == '\0'); } // Conversion, user-defined types. { struct From1 { int value = 0; From1(int v) : value(v) {} }; struct To1 { int value = 0; To1(int v) : value(v) {} To1(const From1& f) : value(f.value) {}; }; struct To2 { int value = 0; To2(int v) : value(v) {} }; struct From2 { int value = 0; From2(int v) : value(v) {} operator To2() const { return To2(value); } }; std::ranges::in_out_result x{42, 99}; std::ranges::in_out_result y = x; assert(y.in.value == 42); assert(y.out.value == 99); } // Copy-only type. { struct CopyOnly { int value = 0; CopyOnly() = default; CopyOnly(int v) : value(v) {} CopyOnly(const CopyOnly&) = default; CopyOnly(CopyOnly&&) = delete; }; std::ranges::in_out_result x; x.in.value = 42; x.out.value = 99; auto y = x; assert(y.in.value == 42); assert(y.out.value == 99); } // Move-only type. { struct MoveOnly { int value = 0; MoveOnly(int v) : value(v) {} MoveOnly(MoveOnly&&) = default; MoveOnly(const MoveOnly&) = delete; }; std::ranges::in_out_result x{42, 99}; auto y = std::move(x); assert(y.in.value == 42); assert(y.out.value == 99); } // Unsuccessful conversion. { struct Foo1 {}; struct Foo2 {}; struct Bar1 {}; struct Bar2 {}; static_assert( !std::is_convertible_v, std::ranges::in_out_result>); } return 0; }