1// { dg-options "-std=gnu++14" }
2// { dg-do run }
3
4// Copyright (C) 2013-2015 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
24struct tracker
25{
26  tracker(int value) : value(value) { ++count; }
27  ~tracker() { --count; }
28
29  tracker(tracker const& other) : value(other.value) { ++count; }
30  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
44int tracker::count = 0;
45
46struct exception { };
47
48struct throwing_copy
49{
50  throwing_copy() = default;
51  throwing_copy(throwing_copy const&) { throw exception {}; }
52};
53
54int 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