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-exception
6//
7//===----------------------------------------------------------------------===//
8
9// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10
11// template <class I, class T>
12// struct in_value_result;
13
14#include <algorithm>
15#include <cassert>
16#include <type_traits>
17#include <utility>
18
19#include "MoveOnly.h"
20
21struct A {
22 explicit A(int);
23};
24// no implicit conversion
25static_assert(!std::is_constructible_v<std::ranges::in_value_result<A, A>, std::ranges::in_value_result<int, int>>);
26
27struct B {
28 B(int);
29};
30// implicit conversion
31static_assert(std::is_constructible_v<std::ranges::in_value_result<B, B>, std::ranges::in_value_result<int, int>>);
32static_assert(std::is_constructible_v<std::ranges::in_value_result<B, B>, std::ranges::in_value_result<int, int>&>);
33static_assert(
34 std::is_constructible_v<std::ranges::in_value_result<B, B>, const std::ranges::in_value_result<int, int>>);
35static_assert(
36 std::is_constructible_v<std::ranges::in_value_result<B, B>, const std::ranges::in_value_result<int, int>&>);
37
38struct C {
39 C(int&);
40};
41static_assert(!std::is_constructible_v<std::ranges::in_value_result<C, C>, std::ranges::in_value_result<int, int>&>);
42
43// has to be convertible via const&
44static_assert(std::is_convertible_v<std::ranges::in_value_result<int, int>&, std::ranges::in_value_result<long, long>>);
45static_assert(
46 std::is_convertible_v<const std::ranges::in_value_result<int, int>&, std::ranges::in_value_result<long, long>>);
47static_assert(
48 std::is_convertible_v<std::ranges::in_value_result<int, int>&&, std::ranges::in_value_result<long, long>>);
49static_assert(
50 std::is_convertible_v<const std::ranges::in_value_result<int, int>&&, std::ranges::in_value_result<long, long>>);
51
52// should be move constructible
53static_assert(std::is_move_constructible_v<std::ranges::in_value_result<MoveOnly, int>>);
54static_assert(std::is_move_constructible_v<std::ranges::in_value_result<int, MoveOnly>>);
55
56// should not be copy constructible with move-only type
57static_assert(!std::is_copy_constructible_v<std::ranges::in_value_result<MoveOnly, int>>);
58static_assert(!std::is_copy_constructible_v<std::ranges::in_value_result<int, MoveOnly>>);
59
60struct NotConvertible {};
61// conversions should not work if there is no conversion
62static_assert(
63 !std::is_convertible_v<std::ranges::in_value_result<NotConvertible, int>, std::ranges::in_value_result<int, int>>);
64static_assert(
65 !std::is_convertible_v<std::ranges::in_value_result<int, NotConvertible>, std::ranges::in_value_result<int, int>>);
66
67template <class T>
68struct ConvertibleFrom {
69 constexpr ConvertibleFrom(T c) : content{c} {}
70 T content;
71};
72
73constexpr bool test() {
74 // Checks that conversion operations are correct.
75 {
76 std::ranges::in_value_result<int, double> res{10, 0.};
77 assert(res.in == 10);
78 assert(res.value == 0.);
79 std::ranges::in_value_result<ConvertibleFrom<int>, ConvertibleFrom<double>> res2 = res;
80 assert(res2.in.content == 10);
81 assert(res2.value.content == 0.);
82 }
83
84 // Checks that conversions are possible when one of the types is move-only.
85 {
86 std::ranges::in_value_result<MoveOnly, int> res{MoveOnly{}, 2};
87 assert(res.in.get() == 1);
88 assert(res.value == 2);
89 auto res2 = static_cast<std::ranges::in_value_result<MoveOnly, int>>(std::move(res));
90 assert(res.in.get() == 0);
91 assert(res2.in.get() == 1);
92 assert(res2.value == 2);
93 }
94
95 // Checks that structured bindings get the correct values.
96 {
97 auto [in, value] = std::ranges::in_value_result<int, int>{1, 2};
98 assert(in == 1);
99 assert(value == 2);
100 }
101 return true;
102}
103
104int main(int, char**) {
105 test();
106 static_assert(test());
107
108 return 0;
109}
110

source code of libcxx/test/std/algorithms/algorithms.results/in_value_result.pass.cpp