1 //===----------------------------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // UNSUPPORTED: c++98, c++03, c++11
11 // <optional>
12 
13 // template <class U> T optional<T>::value_or(U&& v) &&;
14 
15 #include <experimental/optional>
16 #include <type_traits>
17 #include <cassert>
18 
19 using std::experimental::optional;
20 using std::experimental::in_place_t;
21 using std::experimental::in_place;
22 
23 struct Y
24 {
25     int i_;
26 
YY27     Y(int i) : i_(i) {}
28 };
29 
30 struct X
31 {
32     int i_;
33 
XX34     X(int i) : i_(i) {}
XX35     X(X&& x) : i_(x.i_) {x.i_ = 0;}
XX36     X(const Y& y) : i_(y.i_) {}
XX37     X(Y&& y) : i_(y.i_+1) {}
operator ==(const X & x,const X & y)38     friend constexpr bool operator==(const X& x, const X& y)
39         {return x.i_ == y.i_;}
40 };
41 
main()42 int main()
43 {
44     {
45         optional<X> opt(in_place, 2);
46         Y y(3);
47         assert(std::move(opt).value_or(y) == 2);
48         assert(*opt == 0);
49     }
50     {
51         optional<X> opt(in_place, 2);
52         assert(std::move(opt).value_or(Y(3)) == 2);
53         assert(*opt == 0);
54     }
55     {
56         optional<X> opt;
57         Y y(3);
58         assert(std::move(opt).value_or(y) == 3);
59         assert(!opt);
60     }
61     {
62         optional<X> opt;
63         assert(std::move(opt).value_or(Y(3)) == 4);
64         assert(!opt);
65     }
66 }
67