1a9e65961SEric Fiselier //===----------------------------------------------------------------------===//
2a9e65961SEric Fiselier //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6a9e65961SEric Fiselier //
7a9e65961SEric Fiselier //===----------------------------------------------------------------------===//
8a9e65961SEric Fiselier 
9*31cbe0f2SLouis Dionne // UNSUPPORTED: c++03, c++11, c++14
10a9e65961SEric Fiselier // <optional>
11a9e65961SEric Fiselier 
12dd7c68bcSCasey Carter // template <class U> constexpr T optional<T>::value_or(U&& v) &&;
13a9e65961SEric Fiselier 
14a9e65961SEric Fiselier #include <optional>
15a9e65961SEric Fiselier #include <type_traits>
16a9e65961SEric Fiselier #include <cassert>
17a9e65961SEric Fiselier 
18a9e65961SEric Fiselier #include "test_macros.h"
19a9e65961SEric Fiselier 
20a9e65961SEric Fiselier using std::optional;
21a9e65961SEric Fiselier using std::in_place_t;
22a9e65961SEric Fiselier using std::in_place;
23a9e65961SEric Fiselier 
24a9e65961SEric Fiselier struct Y
25a9e65961SEric Fiselier {
26a9e65961SEric Fiselier     int i_;
27a9e65961SEric Fiselier 
YY28dd7c68bcSCasey Carter     constexpr Y(int i) : i_(i) {}
29a9e65961SEric Fiselier };
30a9e65961SEric Fiselier 
31a9e65961SEric Fiselier struct X
32a9e65961SEric Fiselier {
33a9e65961SEric Fiselier     int i_;
34a9e65961SEric Fiselier 
XX35dd7c68bcSCasey Carter     constexpr X(int i) : i_(i) {}
XX36dd7c68bcSCasey Carter     constexpr X(X&& x) : i_(x.i_) {x.i_ = 0;}
XX37dd7c68bcSCasey Carter     constexpr X(const Y& y) : i_(y.i_) {}
XX38dd7c68bcSCasey Carter     constexpr X(Y&& y) : i_(y.i_+1) {}
operator ==(const X & x,const X & y)39a9e65961SEric Fiselier     friend constexpr bool operator==(const X& x, const X& y)
40a9e65961SEric Fiselier         {return x.i_ == y.i_;}
41a9e65961SEric Fiselier };
42a9e65961SEric Fiselier 
test()43dd7c68bcSCasey Carter constexpr int test()
44a9e65961SEric Fiselier {
45a9e65961SEric Fiselier     {
46a9e65961SEric Fiselier         optional<X> opt(in_place, 2);
47a9e65961SEric Fiselier         Y y(3);
48a9e65961SEric Fiselier         assert(std::move(opt).value_or(y) == 2);
49a9e65961SEric Fiselier         assert(*opt == 0);
50a9e65961SEric Fiselier     }
51a9e65961SEric Fiselier     {
52a9e65961SEric Fiselier         optional<X> opt(in_place, 2);
53a9e65961SEric Fiselier         assert(std::move(opt).value_or(Y(3)) == 2);
54a9e65961SEric Fiselier         assert(*opt == 0);
55a9e65961SEric Fiselier     }
56a9e65961SEric Fiselier     {
57a9e65961SEric Fiselier         optional<X> opt;
58a9e65961SEric Fiselier         Y y(3);
59a9e65961SEric Fiselier         assert(std::move(opt).value_or(y) == 3);
60a9e65961SEric Fiselier         assert(!opt);
61a9e65961SEric Fiselier     }
62a9e65961SEric Fiselier     {
63a9e65961SEric Fiselier         optional<X> opt;
64a9e65961SEric Fiselier         assert(std::move(opt).value_or(Y(3)) == 4);
65a9e65961SEric Fiselier         assert(!opt);
66a9e65961SEric Fiselier     }
67dd7c68bcSCasey Carter     return 0;
68dd7c68bcSCasey Carter }
69dd7c68bcSCasey Carter 
main(int,char **)702df59c50SJF Bastien int main(int, char**)
71dd7c68bcSCasey Carter {
72dd7c68bcSCasey Carter     static_assert(test() == 0);
732df59c50SJF Bastien 
742df59c50SJF Bastien   return 0;
75a9e65961SEric Fiselier }
76