1 // { dg-options "-std=gnu++14" }
2 // { dg-do run }
3 
4 // Copyright (C) 2013-2016 Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option)
10 // any later version.
11 
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING3.  If not see
19 // <http://www.gnu.org/licenses/>.
20 
21 #include <experimental/optional>
22 #include <testsuite_hooks.h>
23 
24 struct tracker
25 {
trackertracker26   tracker(int value) : value(value) { ++count; }
~trackertracker27   ~tracker() { --count; }
28 
trackertracker29   tracker(tracker const& other) : value(other.value) { ++count; }
trackertracker30   tracker(tracker&& other) : value(other.value)
31   {
32     other.value = -1;
33     ++count;
34   }
35 
36   tracker& operator=(tracker const&) = default;
37   tracker& operator=(tracker&&) = default;
38 
39   int value;
40 
41   static int count;
42 };
43 
44 int tracker::count = 0;
45 
46 struct exception { };
47 
48 struct throwing_copy
49 {
50   throwing_copy() = default;
throwing_copythrowing_copy51   throwing_copy(throwing_copy const&) { throw exception {}; }
52 };
53 
main()54 int main()
55 {
56   // [20.5.4.1] Constructors
57 
58   {
59     std::experimental::optional<long> o;
60     auto copy = o;
61     VERIFY( !copy );
62     VERIFY( !o );
63   }
64 
65   {
66     const long val = 0x1234ABCD;
67     std::experimental::optional<long> o { std::experimental::in_place, val};
68     auto copy = o;
69     VERIFY( copy );
70     VERIFY( *copy == val );
71     VERIFY( o && o == val );
72   }
73 
74   {
75     std::experimental::optional<tracker> o;
76     auto copy = o;
77     VERIFY( !copy );
78     VERIFY( tracker::count == 0 );
79     VERIFY( !o );
80   }
81 
82   {
83     std::experimental::optional<tracker> o { std::experimental::in_place, 333 };
84     auto copy = o;
85     VERIFY( copy );
86     VERIFY( copy->value == 333 );
87     VERIFY( tracker::count == 2 );
88     VERIFY( o && o->value == 333 );
89   }
90 
91   enum outcome { nothrow, caught, bad_catch };
92 
93   {
94     outcome result = nothrow;
95     std::experimental::optional<throwing_copy> o;
96 
97     try
98     {
99       auto copy = o;
100     }
101     catch(exception const&)
102     { result = caught; }
103     catch(...)
104     { result = bad_catch; }
105 
106     VERIFY( result == nothrow );
107   }
108 
109   {
110     outcome result = nothrow;
111     std::experimental::optional<throwing_copy> o { std::experimental::in_place };
112 
113     try
114     {
115       auto copy = o;
116     }
117     catch(exception const&)
118     { result = caught; }
119     catch(...)
120     { result = bad_catch; }
121 
122     VERIFY( result == caught );
123   }
124 
125   VERIFY( tracker::count == 0 );
126 }
127