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
10 // <optional>
11 
12 // template <class U> constexpr T optional<T>::value_or(U&& v) &&;
13 
14 #include <optional>
15 #include <type_traits>
16 #include <cassert>
17 
18 #include "test_macros.h"
19 
20 using std::optional;
21 using std::in_place_t;
22 using std::in_place;
23 
24 struct Y
25 {
26     int i_;
27 
YY28     constexpr Y(int i) : i_(i) {}
29 };
30 
31 struct X
32 {
33     int i_;
34 
XX35     constexpr X(int i) : i_(i) {}
XX36     constexpr X(X&& x) : i_(x.i_) {x.i_ = 0;}
XX37     constexpr X(const Y& y) : i_(y.i_) {}
XX38     constexpr X(Y&& y) : i_(y.i_+1) {}
operator ==(const X & x,const X & y)39     friend constexpr bool operator==(const X& x, const X& y)
40         {return x.i_ == y.i_;}
41 };
42 
test()43 constexpr int test()
44 {
45     {
46         optional<X> opt(in_place, 2);
47         Y y(3);
48         assert(std::move(opt).value_or(y) == 2);
49         assert(*opt == 0);
50     }
51     {
52         optional<X> opt(in_place, 2);
53         assert(std::move(opt).value_or(Y(3)) == 2);
54         assert(*opt == 0);
55     }
56     {
57         optional<X> opt;
58         Y y(3);
59         assert(std::move(opt).value_or(y) == 3);
60         assert(!opt);
61     }
62     {
63         optional<X> opt;
64         assert(std::move(opt).value_or(Y(3)) == 4);
65         assert(!opt);
66     }
67     return 0;
68 }
69 
main(int,char **)70 int main(int, char**)
71 {
72     static_assert(test() == 0);
73 
74   return 0;
75 }
76