// { dg-options "-std=gnu++17" }
// { dg-do run { target c++17 } }
// Copyright (C) 2016-2019 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();
}