// { dg-options "-std=gnu++17" } // { dg-do run { target c++17 } } // Copyright (C) 2016-2020 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . #include #include using std::optional; #include void test01() { optional> nested_element; optional element = {}; nested_element = element; VERIFY(nested_element); } template struct service_result { static optional get_result() { T sr; return sr; } static optional get_result_with_cond(bool cond) { if (cond) return T{}; return {}; } }; void test02() { VERIFY(service_result::get_result()); VERIFY(service_result>::get_result()); VERIFY(service_result::get_result_with_cond(true)); VERIFY(service_result>::get_result_with_cond(true)); VERIFY(!service_result::get_result_with_cond(false)); VERIFY(!service_result>::get_result_with_cond(false)); } struct Widget { Widget(int) {} Widget(optional) {} }; void test03() { optional w; w = optional(); VERIFY(w); static_assert(!std::is_assignable_v&, optional>);; w = optional>(); VERIFY(!w); static_assert(!std::is_assignable_v&, optional>>);; optional w2{optional()}; VERIFY(w2); optional w3 = optional(); VERIFY(w3); optional w4{optional()}; VERIFY(w4); static_assert(!std::is_convertible_v&&, optional>); optional w6{optional>()}; VERIFY(!w6); optional w7 = optional>(); VERIFY(!w7); optional w8{optional>()}; VERIFY(!w8); static_assert(!std::is_convertible_v>&&, optional>); optional w10{optional>(10)}; VERIFY(w10); optional w11 = std::nullopt; VERIFY(!w11); optional w12 = {}; VERIFY(!w12); optional w13{std::nullopt}; VERIFY(!w13); optional w14; w14 = {}; VERIFY(!w14); } struct Widget2 { Widget2(int) {} Widget2(optional) {} Widget2& operator=(int) {return *this;} Widget2& operator=(optional) {return *this;} }; void test04() { optional w; w = optional(); VERIFY(w); w = optional(); VERIFY(w); w = optional>(); VERIFY(!w); w = optional>(); VERIFY(!w); w = optional>(10); optional w2 = std::nullopt; VERIFY(!w2); optional w3 = {}; VERIFY(!w3); optional w4{std::nullopt}; VERIFY(!w4); optional w5; w5 = {}; VERIFY(!w5); } struct Thingy { Thingy(int) {} Thingy(Widget) {} }; void test05() { optional ot; static_assert(!std::is_assignable_v&, optional>); static_assert(std::is_assignable_v&, optional>); static_assert(!std::is_assignable_v&, optional>>); ot = optional(); VERIFY(!ot); optional ot2{optional()}; VERIFY(ot2); static_assert(!std::is_convertible_v&&, optional>); optional ot3{optional()}; VERIFY(!ot3); optional ot4 = optional(); VERIFY(!ot4); optional ot5{optional>()}; VERIFY(!ot5); static_assert(!std::is_convertible_v>&&, optional>); optional ot7{optional()}; VERIFY(!ot7); optional ot8 = optional(); VERIFY(!ot8); static_assert(!std::is_constructible_v, optional>>); static_assert(!std::is_convertible_v>, optional>); static_assert(!std::is_assignable_v&, optional>>); optional ot9 = std::nullopt; VERIFY(!ot9); optional ot10 = {}; VERIFY(!ot10); optional ot11{std::nullopt}; VERIFY(!ot11); optional ot12; ot12 = {}; VERIFY(!ot12); } struct RvalueConstructible { RvalueConstructible(int) {} RvalueConstructible(optional&&) {} }; void test06() { optional oi; optional ori; static_assert(!std::is_assignable_v&, optional&>); ori = std::move(oi); VERIFY(ori); optional> ooi; static_assert(!std::is_assignable_v&, optional>&>); ori = std::move(ooi); VERIFY(!ori); static_assert(!std::is_constructible_v, optional&>); static_assert(!std::is_convertible_v&, optional>); optional ori2(std::move(oi)); VERIFY(ori2); optional ori3 = std::move(oi); VERIFY(ori3); static_assert(!std::is_constructible_v, optional>&>); static_assert(!std::is_convertible_v>&, optional>); optional ori6(std::move(ooi)); VERIFY(!ori6); optional ori7 = std::move(ooi); VERIFY(!ori7); optional ori8 = std::nullopt; VERIFY(!ori8); optional ori9 = {}; VERIFY(!ori9); optional ori10{std::nullopt}; VERIFY(!ori10); optional ori11; ori11 = {}; VERIFY(!ori11); } struct Thingy2 { Thingy2(int) {} explicit Thingy2(optional) {} Thingy2(Widget) {} }; void test07() { optional ot{optional{}}; VERIFY(ot); static_assert(!std::is_convertible_v, optional>); optional ot2{optional{}}; VERIFY(ot2); static_assert(!std::is_convertible_v, optional>); optional ot3{optional>{}}; VERIFY(!ot3); static_assert(!std::is_convertible_v>, optional>); optional ot4{optional>{}}; VERIFY(!ot4); static_assert(!std::is_convertible_v>, optional>); optional ot5{optional{}}; VERIFY(!ot5); optional ot6 = optional(); VERIFY(!ot6); static_assert(!std::is_assignable_v&, optional>); static_assert(!std::is_assignable_v&, optional>); static_assert(!std::is_assignable_v&, optional>>); static_assert(!std::is_assignable_v&, optional>>); optional ot7; ot = optional(); VERIFY(!ot7); optional ot8 = std::nullopt; VERIFY(!ot8); optional ot9 = {}; VERIFY(!ot9); optional ot10{std::nullopt}; VERIFY(!ot10); optional ot11; ot11 = {}; VERIFY(!ot11); } struct Thingy3 { Thingy3(int) {} template, bool> = true> explicit Thingy3(Args&&... args) {} Thingy3(Widget) {} }; void test08() { optional ot{optional{}}; VERIFY(ot); static_assert(!std::is_convertible_v, optional>); optional ot2{optional{}}; VERIFY(ot2); static_assert(!std::is_convertible_v, optional>); optional ot3{optional>{}}; VERIFY(!ot3); static_assert(!std::is_convertible_v>, optional>); optional ot4{optional>{}}; VERIFY(!ot4); static_assert(!std::is_convertible_v>, optional>); optional ot5{optional{}}; VERIFY(!ot5); optional ot6 = optional(); VERIFY(!ot6); static_assert(!std::is_assignable_v&, optional>); static_assert(!std::is_assignable_v&, optional>); static_assert(!std::is_assignable_v&, optional>>); static_assert(!std::is_assignable_v&, optional>>); optional ot7; ot = optional(); VERIFY(!ot7); optional ot8 = std::nullopt; VERIFY(!ot8); optional ot9 = {}; VERIFY(!ot9); optional ot10{std::nullopt}; VERIFY(!ot10); optional ot11; ot11 = {}; VERIFY(!ot11); } void test09() { std::any a = 42; optional oa2 = a; VERIFY(oa2); VERIFY(std::any_cast(*oa2) == 42); optional oa3 = oa2; VERIFY(oa3); VERIFY(std::any_cast(*oa3) == 42); optional oa4{oa2}; VERIFY(oa4); VERIFY(std::any_cast(*oa4) == 42); optional oa5(oa2); VERIFY(oa5); VERIFY(std::any_cast(*oa5) == 42); optional oa6; VERIFY(!oa6); optional oa7 = oa6; VERIFY(!oa7); optional oa8{oa6}; VERIFY(!oa8); optional oa9(oa6); VERIFY(!oa9); } void test10() { struct X {}; optional oi(std::in_place); oi = {}; VERIFY(oi.has_value() == false); optional ot(std::in_place); ot = {}; VERIFY(ot.has_value() == false); optional oi2(std::in_place); short int si = 6; oi2 = si; } int main() { test01(); test02(); test03(); test04(); test05(); test06(); test07(); test08(); test09(); test10(); }