diff options
author | Michael Brune <lucdanton@free.fr> | 2013-11-01 21:08:39 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2013-11-01 20:08:39 +0000 |
commit | 2b5ab1e438e5cf3838922dede7f1b8ea4974b32c (patch) | |
tree | bde4bff4bf62bef490a103fa4bdfecfb41ec1aba /libstdc++-v3 | |
parent | a7920263202cd3d7b421750abc49cf5b66f31d25 (diff) | |
download | gcc-2b5ab1e438e5cf3838922dede7f1b8ea4974b32c.zip gcc-2b5ab1e438e5cf3838922dede7f1b8ea4974b32c.tar.gz gcc-2b5ab1e438e5cf3838922dede7f1b8ea4974b32c.tar.bz2 |
enable_special_members.h: New.
2013-10-31 Michael Brune <lucdanton@free.fr>
* include/bits/enable_special_members.h: New.
* include/experimental/optional: New.
* include/Makefile.am: Handle include/experimental.
* include/Makefile.in: Regenerate.
* testsuite/libstdc++-dg/conformance.exp: Run tests from
testsuite/experimental sub-directory.
* testsuite/experimental/optional/assignment/1.cc: New.
* testsuite/experimental/optional/assignment/2.cc: New.
* testsuite/experimental/optional/assignment/3.cc: New.
* testsuite/experimental/optional/assignment/4.cc: New.
* testsuite/experimental/optional/assignment/5.cc: New.
* testsuite/experimental/optional/assignment/6.cc: New.
* testsuite/experimental/optional/cons/copy.cc: New.
* testsuite/experimental/optional/cons/default.cc: New.
* testsuite/experimental/optional/cons/move.cc: New.
* testsuite/experimental/optional/cons/value.cc: New.
* testsuite/experimental/optional/constexpr/cons/default.cc: New.
* testsuite/experimental/optional/constexpr/cons/value.cc: New.
* testsuite/experimental/optional/constexpr/in_place.cc: New.
* testsuite/experimental/optional/constexpr/make_optional.cc: New.
* testsuite/experimental/optional/constexpr/nullopt.cc: New.
* testsuite/experimental/optional/constexpr/observers/1.cc: New.
* testsuite/experimental/optional/constexpr/observers/2.cc: New.
* testsuite/experimental/optional/constexpr/observers/3.cc: New.
* testsuite/experimental/optional/constexpr/observers/4.cc: New.
* testsuite/experimental/optional/constexpr/observers/5.cc: New.
* testsuite/experimental/optional/constexpr/relops/1.cc: New.
* testsuite/experimental/optional/constexpr/relops/2.cc: New.
* testsuite/experimental/optional/constexpr/relops/3.cc: New.
* testsuite/experimental/optional/constexpr/relops/4.cc: New.
* testsuite/experimental/optional/constexpr/relops/5.cc: New.
* testsuite/experimental/optional/constexpr/relops/6.cc: New.
* testsuite/experimental/optional/in_place.cc: New.
* testsuite/experimental/optional/make_optional.cc: New.
* testsuite/experimental/optional/nullopt.cc: New.
* testsuite/experimental/optional/observers/1.cc: New.
* testsuite/experimental/optional/observers/2.cc: New.
* testsuite/experimental/optional/observers/3.cc: New.
* testsuite/experimental/optional/observers/4.cc: New.
* testsuite/experimental/optional/observers/5.cc: New.
* testsuite/experimental/optional/relops/1.cc: New.
* testsuite/experimental/optional/relops/2.cc: New.
* testsuite/experimental/optional/relops/3.cc: New.
* testsuite/experimental/optional/relops/4.cc: New.
* testsuite/experimental/optional/relops/5.cc: New.
* testsuite/experimental/optional/relops/6.cc: New.
* testsuite/experimental/optional/requirements.cc: New.
* testsuite/experimental/optional/swap/1.cc: New.
From-SVN: r204299
Diffstat (limited to 'libstdc++-v3')
48 files changed, 4785 insertions, 6 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index a7b19ac..f512932 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,54 @@ +2013-10-31 Michael Brune <lucdanton@free.fr> + + * include/bits/enable_special_members.h: New. + * include/experimental/optional: New. + * include/Makefile.am: Handle include/experimental. + * include/Makefile.in: Regenerate. + * testsuite/libstdc++-dg/conformance.exp: Run tests from + testsuite/experimental sub-directory. + * testsuite/experimental/optional/assignment/1.cc: New. + * testsuite/experimental/optional/assignment/2.cc: New. + * testsuite/experimental/optional/assignment/3.cc: New. + * testsuite/experimental/optional/assignment/4.cc: New. + * testsuite/experimental/optional/assignment/5.cc: New. + * testsuite/experimental/optional/assignment/6.cc: New. + * testsuite/experimental/optional/cons/copy.cc: New. + * testsuite/experimental/optional/cons/default.cc: New. + * testsuite/experimental/optional/cons/move.cc: New. + * testsuite/experimental/optional/cons/value.cc: New. + * testsuite/experimental/optional/constexpr/cons/default.cc: New. + * testsuite/experimental/optional/constexpr/cons/value.cc: New. + * testsuite/experimental/optional/constexpr/in_place.cc: New. + * testsuite/experimental/optional/constexpr/make_optional.cc: New. + * testsuite/experimental/optional/constexpr/nullopt.cc: New. + * testsuite/experimental/optional/constexpr/observers/1.cc: New. + * testsuite/experimental/optional/constexpr/observers/2.cc: New. + * testsuite/experimental/optional/constexpr/observers/3.cc: New. + * testsuite/experimental/optional/constexpr/observers/4.cc: New. + * testsuite/experimental/optional/constexpr/observers/5.cc: New. + * testsuite/experimental/optional/constexpr/relops/1.cc: New. + * testsuite/experimental/optional/constexpr/relops/2.cc: New. + * testsuite/experimental/optional/constexpr/relops/3.cc: New. + * testsuite/experimental/optional/constexpr/relops/4.cc: New. + * testsuite/experimental/optional/constexpr/relops/5.cc: New. + * testsuite/experimental/optional/constexpr/relops/6.cc: New. + * testsuite/experimental/optional/in_place.cc: New. + * testsuite/experimental/optional/make_optional.cc: New. + * testsuite/experimental/optional/nullopt.cc: New. + * testsuite/experimental/optional/observers/1.cc: New. + * testsuite/experimental/optional/observers/2.cc: New. + * testsuite/experimental/optional/observers/3.cc: New. + * testsuite/experimental/optional/observers/4.cc: New. + * testsuite/experimental/optional/observers/5.cc: New. + * testsuite/experimental/optional/relops/1.cc: New. + * testsuite/experimental/optional/relops/2.cc: New. + * testsuite/experimental/optional/relops/3.cc: New. + * testsuite/experimental/optional/relops/4.cc: New. + * testsuite/experimental/optional/relops/5.cc: New. + * testsuite/experimental/optional/relops/6.cc: New. + * testsuite/experimental/optional/requirements.cc: New. + * testsuite/experimental/optional/swap/1.cc: New. + 2013-11-01 Jonathan Wakely <jwakely.gcc@gmail.com> * include/bits/stl_function.h (logical_not<void>): Add noexcept. diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 0ddc8b5..505679a 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -94,6 +94,7 @@ bits_headers = \ ${bits_srcdir}/concept_check.h \ ${bits_srcdir}/cpp_type_traits.h \ ${bits_srcdir}/deque.tcc \ + ${bits_srcdir}/enable_special_members.h \ ${bits_srcdir}/forward_list.h \ ${bits_srcdir}/forward_list.tcc \ ${bits_srcdir}/fstream.tcc \ @@ -633,6 +634,12 @@ decimal_headers = \ ${decimal_srcdir}/decimal \ ${decimal_srcdir}/decimal.h +# Post-C++11 TS's +experimental_srcdir = ${glibcxx_srcdir}/include/experimental +experimental_builddir = ./experimental +experimental_headers = \ + ${experimental_srcdir}/optional + # This is the common subset of C++ files that all three "C" header models use. c_base_srcdir = $(C_INCLUDE_DIR) c_base_builddir = . @@ -910,8 +917,8 @@ endif allstamped = \ stamp-std stamp-bits stamp-bits-sup stamp-c_base stamp-c_compatibility \ stamp-backward stamp-ext stamp-pb stamp-tr1 stamp-tr2 stamp-decimal \ - stamp-debug stamp-parallel stamp-profile stamp-profile-impl \ - stamp-host + stamp-experimental stamp-debug stamp-parallel stamp-profile \ + stamp-profile-impl stamp-host # List of all files that are created by explicit building, editing, or # catenation. @@ -1034,6 +1041,11 @@ stamp-decimal: ${decimal_headers} @-cd ${decimal_builddir} && $(LN_S) $? . 2>/dev/null @$(STAMP) stamp-decimal +stamp-experimental: ${experimental_headers} + @-mkdir -p ${experimental_builddir} + @-cd ${experimental_builddir} && $(LN_S) $? . 2>/dev/null + @$(STAMP) stamp-experimental + stamp-debug: ${debug_headers} @-mkdir -p ${debug_builddir} @-cd ${debug_builddir} && $(LN_S) $? . 2>/dev/null @@ -1277,6 +1289,9 @@ install-headers: $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${decimal_builddir} for file in ${decimal_headers}; do \ $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${decimal_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${experimental_builddir} + for file in ${experimental_headers}; do \ + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${experimental_builddir}; done $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${c_base_builddir} for file in ${c_base_headers}; do \ $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${c_base_builddir}; done @@ -1322,9 +1337,10 @@ clean-local: # directory. (This is more of an example of how this kind of rule can # be made.) .PRECIOUS: $(std_headers) $(c_base_headers) $(tr1_headers) $(tr2_headers) - $(decimal_headers) $(ext_headers) + $(decimal_headers) $(ext_headers) $(experimental_headers) $(std_headers): ; @: $(c_base_headers): ; @: $(tr1_headers): ; @: $(decimal_headers): ; @: $(ext_headers): ; @: +$(experimental_headers): ; @: diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index a1fd1d3..1f5daba 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -361,6 +361,7 @@ bits_headers = \ ${bits_srcdir}/concept_check.h \ ${bits_srcdir}/cpp_type_traits.h \ ${bits_srcdir}/deque.tcc \ + ${bits_srcdir}/enable_special_members.h \ ${bits_srcdir}/forward_list.h \ ${bits_srcdir}/forward_list.tcc \ ${bits_srcdir}/fstream.tcc \ @@ -899,6 +900,13 @@ decimal_headers = \ ${decimal_srcdir}/decimal.h +# Post-C++11 TS's +experimental_srcdir = ${glibcxx_srcdir}/include/experimental +experimental_builddir = ./experimental +experimental_headers = \ + ${experimental_srcdir}/optional + + # This is the common subset of C++ files that all three "C" header models use. c_base_srcdir = $(C_INCLUDE_DIR) c_base_builddir = . @@ -1166,8 +1174,8 @@ PCHFLAGS = -x c++-header -nostdinc++ $(CXXFLAGS) $(VTV_PCH_CXXFLAGS) allstamped = \ stamp-std stamp-bits stamp-bits-sup stamp-c_base stamp-c_compatibility \ stamp-backward stamp-ext stamp-pb stamp-tr1 stamp-tr2 stamp-decimal \ - stamp-debug stamp-parallel stamp-profile stamp-profile-impl \ - stamp-host + stamp-experimental stamp-debug stamp-parallel stamp-profile \ + stamp-profile-impl stamp-host # List of all files that are created by explicit building, editing, or @@ -1452,6 +1460,11 @@ stamp-decimal: ${decimal_headers} @-cd ${decimal_builddir} && $(LN_S) $? . 2>/dev/null @$(STAMP) stamp-decimal +stamp-experimental: ${experimental_headers} + @-mkdir -p ${experimental_builddir} + @-cd ${experimental_builddir} && $(LN_S) $? . 2>/dev/null + @$(STAMP) stamp-experimental + stamp-debug: ${debug_headers} @-mkdir -p ${debug_builddir} @-cd ${debug_builddir} && $(LN_S) $? . 2>/dev/null @@ -1680,6 +1693,9 @@ install-headers: $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${decimal_builddir} for file in ${decimal_headers}; do \ $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${decimal_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${experimental_builddir} + for file in ${experimental_headers}; do \ + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${experimental_builddir}; done $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${c_base_builddir} for file in ${c_base_headers}; do \ $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${c_base_builddir}; done @@ -1722,12 +1738,13 @@ clean-local: # directory. (This is more of an example of how this kind of rule can # be made.) .PRECIOUS: $(std_headers) $(c_base_headers) $(tr1_headers) $(tr2_headers) - $(decimal_headers) $(ext_headers) + $(decimal_headers) $(ext_headers) $(experimental_headers) $(std_headers): ; @: $(c_base_headers): ; @: $(tr1_headers): ; @: $(decimal_headers): ; @: $(ext_headers): ; @: +$(experimental_headers): ; @: # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/libstdc++-v3/include/bits/enable_special_members.h b/libstdc++-v3/include/bits/enable_special_members.h new file mode 100644 index 0000000..eb90037 --- /dev/null +++ b/libstdc++-v3/include/bits/enable_special_members.h @@ -0,0 +1,278 @@ +// <bits/enable_special_members.h> -*- C++ -*- + +// Copyright (C) 2013 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file bits/enable_special_members.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. + */ + +#ifndef _ENABLE_SPECIAL_MEMBERS_H +#define _ENABLE_SPECIAL_MEMBERS_H 1 + +#pragma GCC system_header + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + +/** + * @brief A mixin helper to conditionally enable or disable the default + * constructor. + * @sa _Enable_special_members + */ +template<bool _Switch, typename _Tag = void> + struct _Enable_default_constructor { }; + + +/** + * @brief A mixin helper to conditionally enable or disable the default + * destructor. + * @sa _Enable_special_members + */ +template<bool _Switch, typename _Tag = void> + struct _Enable_destructor { }; + +/** + * @brief A mixin helper to conditionally enable or disable the copy/move + * special members. + * @sa _Enable_special_members + */ +template<bool _Copy, bool _CopyAssignment, + bool _Move, bool _MoveAssignment, + typename _Tag = void> + struct _Enable_copy_move { }; + +/** + * @brief A mixin helper to conditionally enable or disable the special + * members. + * + * The @c _Tag type parameter is to make mixin bases unique and thus avoid + * ambiguities. + */ +template<bool _Default, bool _Destructor, + bool _Copy, bool _CopyAssignment, + bool _Move, bool _MoveAssignment, + typename _Tag = void> + struct _Enable_special_members + : private _Enable_default_constructor<_Default, _Tag>, + private _Enable_destructor<_Destructor, _Tag>, + private _Enable_copy_move<_Copy, _CopyAssignment, + _Move, _MoveAssignment, + _Tag> + { }; + +// Boilerplate follows. + +template<typename _Tag> + struct _Enable_default_constructor<false, _Tag> + { constexpr _Enable_default_constructor() noexcept = delete; }; + +template<typename _Tag> + struct _Enable_destructor<false, _Tag> + { ~_Enable_destructor() noexcept = delete; }; + +template<typename _Tag> + struct _Enable_copy_move<false, true, true, true, _Tag> + { + constexpr _Enable_copy_move() noexcept = default; + constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete; + constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default; + _Enable_copy_move& + operator=(_Enable_copy_move const&) noexcept = default; + _Enable_copy_move& + operator=(_Enable_copy_move&&) noexcept = default; + }; + +template<typename _Tag> + struct _Enable_copy_move<true, false, true, true, _Tag> + { + constexpr _Enable_copy_move() noexcept = default; + constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default; + constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default; + _Enable_copy_move& + operator=(_Enable_copy_move const&) noexcept = delete; + _Enable_copy_move& + operator=(_Enable_copy_move&&) noexcept = default; + }; + +template<typename _Tag> + struct _Enable_copy_move<false, false, true, true, _Tag> + { + constexpr _Enable_copy_move() noexcept = default; + constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete; + constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default; + _Enable_copy_move& + operator=(_Enable_copy_move const&) noexcept = delete; + _Enable_copy_move& + operator=(_Enable_copy_move&&) noexcept = default; + }; + +template<typename _Tag> + struct _Enable_copy_move<true, true, false, true, _Tag> + { + constexpr _Enable_copy_move() noexcept = default; + constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default; + constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete; + _Enable_copy_move& + operator=(_Enable_copy_move const&) noexcept = default; + _Enable_copy_move& + operator=(_Enable_copy_move&&) noexcept = default; + }; + +template<typename _Tag> + struct _Enable_copy_move<false, true, false, true, _Tag> + { + constexpr _Enable_copy_move() noexcept = default; + constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete; + constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete; + _Enable_copy_move& + operator=(_Enable_copy_move const&) noexcept = default; + _Enable_copy_move& + operator=(_Enable_copy_move&&) noexcept = default; + }; + +template<typename _Tag> + struct _Enable_copy_move<true, false, false, true, _Tag> + { + constexpr _Enable_copy_move() noexcept = default; + constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default; + constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete; + _Enable_copy_move& + operator=(_Enable_copy_move const&) noexcept = delete; + _Enable_copy_move& + operator=(_Enable_copy_move&&) noexcept = default; + }; + +template<typename _Tag> + struct _Enable_copy_move<false, false, false, true, _Tag> + { + constexpr _Enable_copy_move() noexcept = default; + constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete; + constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete; + _Enable_copy_move& + operator=(_Enable_copy_move const&) noexcept = delete; + _Enable_copy_move& + operator=(_Enable_copy_move&&) noexcept = default; + }; + +template<typename _Tag> + struct _Enable_copy_move<true, true, true, false, _Tag> + { + constexpr _Enable_copy_move() noexcept = default; + constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default; + constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default; + _Enable_copy_move& + operator=(_Enable_copy_move const&) noexcept = default; + _Enable_copy_move& + operator=(_Enable_copy_move&&) noexcept = delete; + }; + +template<typename _Tag> + struct _Enable_copy_move<false, true, true, false, _Tag> + { + constexpr _Enable_copy_move() noexcept = default; + constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete; + constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default; + _Enable_copy_move& + operator=(_Enable_copy_move const&) noexcept = default; + _Enable_copy_move& + operator=(_Enable_copy_move&&) noexcept = delete; + }; + +template<typename _Tag> + struct _Enable_copy_move<true, false, true, false, _Tag> + { + constexpr _Enable_copy_move() noexcept = default; + constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default; + constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default; + _Enable_copy_move& + operator=(_Enable_copy_move const&) noexcept = delete; + _Enable_copy_move& + operator=(_Enable_copy_move&&) noexcept = delete; + }; + +template<typename _Tag> + struct _Enable_copy_move<false, false, true, false, _Tag> + { + constexpr _Enable_copy_move() noexcept = default; + constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete; + constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default; + _Enable_copy_move& + operator=(_Enable_copy_move const&) noexcept = delete; + _Enable_copy_move& + operator=(_Enable_copy_move&&) noexcept = delete; + }; + +template<typename _Tag> + struct _Enable_copy_move<true, true, false, false, _Tag> + { + constexpr _Enable_copy_move() noexcept = default; + constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default; + constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete; + _Enable_copy_move& + operator=(_Enable_copy_move const&) noexcept = default; + _Enable_copy_move& + operator=(_Enable_copy_move&&) noexcept = delete; + }; + +template<typename _Tag> + struct _Enable_copy_move<false, true, false, false, _Tag> + { + constexpr _Enable_copy_move() noexcept = default; + constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete; + constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete; + _Enable_copy_move& + operator=(_Enable_copy_move const&) noexcept = default; + _Enable_copy_move& + operator=(_Enable_copy_move&&) noexcept = delete; + }; + +template<typename _Tag> + struct _Enable_copy_move<true, false, false, false, _Tag> + { + constexpr _Enable_copy_move() noexcept = default; + constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default; + constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete; + _Enable_copy_move& + operator=(_Enable_copy_move const&) noexcept = delete; + _Enable_copy_move& + operator=(_Enable_copy_move&&) noexcept = delete; + }; + +template<typename _Tag> + struct _Enable_copy_move<false, false, false, false, _Tag> + { + constexpr _Enable_copy_move() noexcept = default; + constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete; + constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete; + _Enable_copy_move& + operator=(_Enable_copy_move const&) noexcept = delete; + _Enable_copy_move& + operator=(_Enable_copy_move&&) noexcept = delete; + }; + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std + +#endif // _ENABLE_SPECIAL_MEMBERS_H diff --git a/libstdc++-v3/include/experimental/optional b/libstdc++-v3/include/experimental/optional new file mode 100644 index 0000000..5915892 --- /dev/null +++ b/libstdc++-v3/include/experimental/optional @@ -0,0 +1,828 @@ +// <optional> -*- C++ -*- + +// Copyright (C) 2013 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file experimental/optional + * This is a TS C++ Library header. + */ + +#ifndef _GLIBCXX_EXPERIMENTAL_OPTIONAL +#define _GLIBCXX_EXPERIMENTAL_OPTIONAL 1 + +/** + * @defgroup experimental Experimental + * + * Components specified by various Technical Specifications. + */ + +#if __cplusplus <= 201103L +# include <bits/c++14_warning.h> +#else + +#include <utility> +#include <type_traits> +#include <stdexcept> +#include <new> +#include <initializer_list> +#include <bits/functexcept.h> +#include <bits/functional_hash.h> +#include <bits/enable_special_members.h> + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace experimental +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @defgroup optional Optional values + * @ingroup experimental + * + * Class template for optional values and surrounding facilities, as + * described in n3793 "A proposal to add a utility class to represent + * optional objects (Revision 5)". + * + * @{ + */ + + // All subsequent [X.Y.n] references are against n3793. + + // [X.Y.4] + template<typename _Tp> + class optional; + + // [X.Y.5] + /// Tag type for in-place construction. + struct in_place_t { }; + + /// Tag for in-place construction. + constexpr in_place_t in_place { }; + + // [X.Y.6] + /// Tag type to disengage optional objects. + struct nullopt_t + { + // Do not user-declare default constructor at all for + // optional_value = {} syntax to work. + // nullopt_t() = delete; + + // Used for constructing nullopt. + enum class _Construct { _Token }; + + // Must be constexpr for nullopt_t to be literal. + explicit constexpr nullopt_t(_Construct) { } + }; + + // [X.Y.6] + /// Tag to disengage optional objects. + constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token }; + + // [X.Y.7] + /** + * @brief Exception class thrown when a disengaged optional object is + * dereferenced. + * @ingroup exceptions + */ + class bad_optional_access : public logic_error + { + public: + // XXX Should not be inline + explicit bad_optional_access(const string& __arg) : logic_error(__arg) { } + + explicit bad_optional_access(const char* __arg) : logic_error(__arg) { } + + virtual ~bad_optional_access() noexcept = default; + }; + + void + __throw_bad_optional_access(const char*) + __attribute__((__noreturn__)); + + // XXX Does not belong here. + inline void + __throw_bad_optional_access(const char* __s) + { _GLIBCXX_THROW_OR_ABORT(bad_optional_access(__s)); } + + template<typename _Tp, typename _Sfinae = void> + struct _Has_addressof_impl : std::false_type { }; + + template<typename _Tp> + struct _Has_addressof_impl<_Tp, + decltype( std::declval<const _Tp&>().operator&(), void() )> + : std::true_type { }; + + /** + * @brief Trait that detects the presence of an overloaded unary operator&. + * + * Practically speaking this detects the presence of such an operator when + * called on a const-qualified lvalue (i.e. + * declval<_Tp * const&>().operator&()). + */ + template<typename _Tp> + struct _Has_addressof : _Has_addressof_impl<_Tp>::type { }; + + /** + * @brief An overload that attempts to take the address of an lvalue as a + * constant expression. Falls back to __addressof in the presence of an + * overloaded addressof operator (unary operator&), in which case the call + * will not be a constant expression. + */ + template<typename _Tp, typename enable_if<!_Has_addressof<_Tp>::value, + int>::type...> + constexpr _Tp* __constexpr_addressof(_Tp& __t) + { return &__t; } + + /** + * @brief Fallback overload that defers to __addressof. + */ + template<typename _Tp, typename enable_if<_Has_addressof<_Tp>::value, + int>::type...> + _Tp* __constexpr_addressof(_Tp& __t) + { return std::__addressof(__t); } + + /** + * @brief Class template that holds the necessary state for @ref optional + * and that has the responsibility for construction and the special members. + * + * Such a separate base class template is necessary in order to + * conditionally enable the special members (e.g. copy/move constructors). + * Note that this means that @ref _Optional_base implements the + * functionality for copy and move assignment, but not for converting + * assignment. + * + * @see optional, _Enable_special_members + */ + template<typename _Tp, bool _ShouldProvideDestructor = + !is_trivially_destructible<_Tp>::value> + class _Optional_base + { + private: + // Remove const to avoid prohibition of reusing object storage for + // const-qualified types in [3.8/9]. This is strictly internal + // and even optional itself is oblivious to it. + using _Stored_type = typename remove_const<_Tp>::type; + + public: + // [X.Y.4.1] Constructors. + + // Constructors for disengaged optionals. + constexpr _Optional_base() noexcept + : _M_empty{} { } + + constexpr _Optional_base(nullopt_t) noexcept + : _Optional_base{} { } + + // Constructors for engaged optionals. + constexpr _Optional_base(const _Tp& __t) + : _M_payload(__t), _M_engaged(true) { } + + constexpr _Optional_base(_Tp&& __t) + : _M_payload(std::move(__t)), _M_engaged(true) { } + + template<typename... _Args> + constexpr explicit _Optional_base(in_place_t, _Args&&... __args) + : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { } + + template<typename _Up, typename... _Args, + typename enable_if<is_constructible<_Tp, + initializer_list<_Up>&, + _Args&&...>::value, + int>::type...> + constexpr explicit _Optional_base(in_place_t, + initializer_list<_Up> __il, + _Args&&... __args) + : _M_payload(__il, std::forward<_Args>(__args)...), + _M_engaged(true) { } + + // Copy and move constructors. + _Optional_base(const _Optional_base& __other) + { + if (__other._M_engaged) + this->_M_construct(__other._M_get()); + } + + _Optional_base(_Optional_base&& __other) + noexcept(is_nothrow_move_constructible<_Tp>()) + { + if (__other._M_engaged) + this->_M_construct(std::move(__other._M_get())); + } + + // [X.Y.4.3] (partly) Assignment. + _Optional_base& + operator=(const _Optional_base& __other) + { + if (this->_M_engaged && __other._M_engaged) + this->_M_get() = __other._M_get(); + else + { + if (__other._M_engaged) + this->_M_construct(__other._M_get()); + else + this->_M_reset(); + } + + return *this; + } + + _Optional_base& + operator=(_Optional_base&& __other) + noexcept(is_nothrow_move_constructible<_Tp>() + && is_nothrow_move_assignable<_Tp>()) + { + if (this->_M_engaged && __other._M_engaged) + this->_M_get() = std::move(__other._M_get()); + else + { + if (__other._M_engaged) + this->_M_construct(std::move(__other._M_get())); + else + this->_M_reset(); + } + + return *this; + } + + // [X.Y.4.2] Destructor. + ~_Optional_base() + { + if (this->_M_engaged) + this->_M_payload.~_Stored_type(); + } + + // The following functionality is also needed by optional, hence the + // protected accessibility. + protected: + constexpr bool _M_is_engaged() const noexcept + { return this->_M_engaged; } + + // The _M_get operations have _M_engaged as a precondition. + _Tp& + _M_get() noexcept + { return _M_payload; } + + constexpr const _Tp& + _M_get() const noexcept + { return _M_payload; } + + // The _M_construct operation has !_M_engaged as a precondition + // while _M_destruct has _M_engaged as a precondition. + template<typename... _Args> + void + _M_construct(_Args&&... __args) + noexcept(is_nothrow_constructible<_Stored_type, _Args...>()) + { + ::new (std::__addressof(this->_M_payload)) + _Stored_type(std::forward<_Args>(__args)...); + this->_M_engaged = true; + } + + void + _M_destruct() + { + this->_M_engaged = false; + this->_M_payload.~_Stored_type(); + } + + // _M_reset is a 'safe' operation with no precondition. + void + _M_reset() + { + if (this->_M_engaged) + this->_M_destruct(); + } + + private: + struct _Empty_byte { }; + union { + _Empty_byte _M_empty; + _Stored_type _M_payload; + }; + bool _M_engaged = false; + }; + + /// Partial specialization that is exactly identical to the primary template + /// save for not providing a destructor, to fulfill triviality requirements. + template<typename _Tp> + class _Optional_base<_Tp, false> + { + private: + using _Stored_type = typename remove_const<_Tp>::type; + + public: + constexpr _Optional_base() noexcept + : _M_empty{} { } + + constexpr _Optional_base(nullopt_t) noexcept + : _Optional_base{} { } + + constexpr _Optional_base(const _Tp& __t) + : _M_payload(__t), _M_engaged(true) { } + + constexpr _Optional_base(_Tp&& __t) + : _M_payload(std::move(__t)), _M_engaged(true) { } + + template<typename... _Args> + constexpr explicit _Optional_base(in_place_t, _Args&&... __args) + : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { } + + template<typename _Up, typename... _Args, + typename enable_if<is_constructible<_Tp, + initializer_list<_Up>&, + _Args&&...>::value, + int>::type...> + constexpr explicit _Optional_base(in_place_t, + initializer_list<_Up> __il, + _Args&&... __args) + : _M_payload(__il, std::forward<_Args>(__args)...), + _M_engaged(true) { } + + _Optional_base(const _Optional_base& __other) + { + if (__other._M_engaged) + this->_M_construct(__other._M_get()); + } + + _Optional_base(_Optional_base&& __other) + noexcept(is_nothrow_move_constructible<_Tp>()) + { + if (__other._M_engaged) + this->_M_construct(std::move(__other._M_get())); + } + + _Optional_base& + operator=(const _Optional_base& __other) + { + if (this->_M_engaged && __other._M_engaged) + this->_M_get() = __other._M_get(); + else + { + if (__other._M_engaged) + this->_M_construct(__other._M_get()); + else + this->_M_reset(); + } + + return *this; + } + + _Optional_base& + operator=(_Optional_base&& __other) + noexcept(is_nothrow_move_constructible<_Tp>() + && is_nothrow_move_assignable<_Tp>()) + { + if (this->_M_engaged && __other._M_engaged) + this->_M_get() = std::move(__other._M_get()); + else + { + if (__other._M_engaged) + this->_M_construct(std::move(__other._M_get())); + else + this->_M_reset(); + } + + return *this; + } + + // Sole difference + // ~_Optional_base() noexcept = default; + + protected: + constexpr bool _M_is_engaged() const noexcept + { return this->_M_engaged; } + + _Tp& + _M_get() noexcept + { return _M_payload; } + + constexpr const _Tp& + _M_get() const noexcept + { return _M_payload; } + + template<typename... _Args> + void + _M_construct(_Args&&... __args) + noexcept(is_nothrow_constructible<_Stored_type, _Args...>()) + { + ::new (std::__addressof(this->_M_payload)) + _Stored_type(std::forward<_Args>(__args)...); + this->_M_engaged = true; + } + + void + _M_destruct() + { + this->_M_engaged = false; + this->_M_payload.~_Stored_type(); + } + + void + _M_reset() + { + if (this->_M_engaged) + this->_M_destruct(); + } + + private: + struct _Empty_byte { }; + union { + _Empty_byte _M_empty; + _Stored_type _M_payload; + }; + bool _M_engaged = false; + }; + + /** + * @brief Class template for optional values. + */ + template<typename _Tp> + class optional + : private _Optional_base<_Tp>, + private _Enable_copy_move< + // Copy constructor. + is_copy_constructible<_Tp>::value, + // Copy assignment. + is_copy_constructible<_Tp>::value + && is_copy_assignable<_Tp>::value, + // Move constructor. + is_move_constructible<_Tp>::value, + // Move assignment. + is_move_constructible<_Tp>::value + && is_move_assignable<_Tp>::value, + // Unique tag type. + optional<_Tp>> + { + static_assert(!is_same<typename remove_cv<_Tp>::type, + nullopt_t>() + && !is_same<typename remove_cv<_Tp>::type, + in_place_t>() + && !is_reference<_Tp>(), + "Invalid instantiation of optional<T>."); + + private: + using _Base = _Optional_base<_Tp>; + + public: + using value_type = _Tp; + + // _Optional_base has the responsibility for construction. + using _Base::_Base; + + // [X.Y.4.3] (partly) Assignment. + optional& + operator=(nullopt_t) noexcept + { + this->_M_reset(); + return *this; + } + + template<typename _Up> + typename enable_if< + is_same<_Tp, typename decay<_Up>::type>::value, + optional& + >::type + operator=(_Up&& __u) + { + static_assert(is_constructible<_Tp, _Up>() + && is_assignable<_Tp&, _Up>(), + "Cannot assign to value type from argument."); + + if (this->_M_is_engaged()) + this->_M_get() = std::forward<_Up>(__u); + else + this->_M_construct(std::forward<_Up>(__u)); + + return *this; + } + + template<typename... _Args> + void + emplace(_Args&&... __args) + { + static_assert(is_constructible<_Tp, _Args&&...>(), + "Cannot emplace value type from arguments."); + + this->_M_reset(); + this->_M_construct(std::forward<_Args>(__args)...); + } + + template<typename _Up, typename... _Args> + typename enable_if< + is_constructible<_Tp, + initializer_list<_Up>&, + _Args&&...>::value + >::type + emplace(initializer_list<_Up> __il, _Args&&... __args) + { + this->_M_reset(); + this->_M_construct(__il, std::forward<_Args>(__args)...); + } + + // [X.Y.4.2] Destructor is implicit, implemented in _Optional_base. + + // [X.Y.4.4] Swap. + void + swap(optional& __other) + noexcept(is_nothrow_move_constructible<_Tp>() + && noexcept(swap(declval<_Tp&>(), declval<_Tp&>()))) + { + using std::swap; + + if (this->_M_is_engaged() && __other._M_is_engaged()) + swap(this->_M_get(), __other._M_get()); + else if (this->_M_is_engaged()) + { + __other._M_construct(std::move(this->_M_get())); + this->_M_destruct(); + } + else if (__other._M_is_engaged()) + { + this->_M_construct(std::move(__other._M_get())); + __other._M_destruct(); + } + } + + // [X.Y.4.5] Observers. + constexpr const _Tp* + operator->() const + { return __constexpr_addressof(this->_M_get()); } + + _Tp* + operator->() + { return std::__addressof(this->_M_get()); } + + constexpr const _Tp& + operator*() const + { return this->_M_get(); } + + _Tp& + operator*() + { return this->_M_get(); } + + constexpr explicit operator bool() const noexcept + { return this->_M_is_engaged(); } + + constexpr const _Tp& + value() const + { + return this->_M_is_engaged() ? + this->_M_get() : + (__throw_bad_optional_access("Attempt to access value of a disengaged" + " optional object."), + this->_M_get()); + } + + _Tp& + value() + { + if (this->_M_is_engaged()) + return this->_M_get(); + + __throw_bad_optional_access("Attempt to access value of a disengaged" + " optional object."); + } + + template<typename _Up> + constexpr _Tp + value_or(_Up&& __u) const& + { + static_assert(is_copy_constructible<_Tp>() + && is_convertible<_Up&&, _Tp>(), + "Cannot return value."); + + return this->_M_is_engaged() ? + this->_M_get() : + static_cast<_Tp>(std::forward<_Up>(__u)); + } + + template<typename _Up> + _Tp + value_or(_Up&& __u) && + { + static_assert( is_move_constructible<_Tp>() + && is_convertible<_Up&&, _Tp>(), + "Cannot return value." ); + + return this->_M_is_engaged() ? + std::move(this->_M_get()) : + static_cast<_Tp>(std::forward<_Up>(__u)); + } + }; + + // [X.Y.8] Comparisons between optional values. + template<typename _Tp> + constexpr bool + operator==(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs) + { + return static_cast<bool>(__lhs) == static_cast<bool>(__rhs) + && (!__lhs || *__lhs == *__rhs); + } + + template<typename _Tp> + constexpr bool + operator!=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs) + { return !(__lhs == __rhs); } + + template<typename _Tp> + constexpr bool + operator<(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs) + { + return static_cast<bool>(__rhs) + && (!__lhs || *__lhs < *__rhs); + } + + template<typename _Tp> + constexpr bool + operator>(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs) + { return __rhs < __lhs; } + + template<typename _Tp> + constexpr bool + operator<=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs) + { return !(__rhs < __lhs); } + + template<typename _Tp> + constexpr bool + operator>=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs) + { return !(__lhs < __rhs); } + + // [X.Y.9] Comparisons with nullopt. + template<typename _Tp> + constexpr bool + operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept + { return !__lhs; } + + template<typename _Tp> + constexpr bool + operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept + { return !__rhs; } + + template<typename _Tp> + constexpr bool + operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept + { return static_cast<bool>(__lhs); } + + template<typename _Tp> + constexpr bool + operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept + { return static_cast<bool>(__rhs); } + + template<typename _Tp> + constexpr bool + operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept + { return false; } + + template<typename _Tp> + constexpr bool + operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept + { return static_cast<bool>(__rhs); } + + template<typename _Tp> + constexpr bool + operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept + { return static_cast<bool>(__lhs); } + + template<typename _Tp> + constexpr bool + operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept + { return false; } + + template<typename _Tp> + constexpr bool + operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept + { return !__lhs; } + + template<typename _Tp> + constexpr bool + operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept + { return true; } + + template<typename _Tp> + constexpr bool + operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept + { return true; } + + template<typename _Tp> + constexpr bool + operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept + { return !__rhs; } + + // [X.Y.10] Comparisons with value type. + template<typename _Tp> + constexpr bool + operator==(const optional<_Tp>& __lhs, const _Tp& __rhs) + { return __lhs && *__lhs == __rhs; } + + template<typename _Tp> + constexpr bool + operator==(const _Tp& __lhs, const optional<_Tp>& __rhs) + { return __rhs && __lhs == *__rhs; } + + template<typename _Tp> + constexpr bool + operator!=(const optional<_Tp>& __lhs, _Tp const& __rhs) + { return !__lhs || *__lhs != __rhs; } + + template<typename _Tp> + constexpr bool + operator!=(const _Tp& __lhs, const optional<_Tp>& __rhs) + { return !__rhs || __lhs != *__rhs; } + + template<typename _Tp> + constexpr bool + operator<(const optional<_Tp>& __lhs, const _Tp& __rhs) + { return !__lhs || *__lhs < __rhs; } + + template<typename _Tp> + constexpr bool + operator<(const _Tp& __lhs, const optional<_Tp>& __rhs) + { return __rhs && __lhs < *__rhs; } + + template<typename _Tp> + constexpr bool + operator>(const optional<_Tp>& __lhs, const _Tp& __rhs) + { return __lhs && __rhs < *__lhs; } + + template<typename _Tp> + constexpr bool + operator>(const _Tp& __lhs, const optional<_Tp>& __rhs) + { return !__rhs || *__rhs < __lhs; } + + template<typename _Tp> + constexpr bool + operator<=(const optional<_Tp>& __lhs, const _Tp& __rhs) + { return !__lhs || !(__rhs < *__lhs); } + + template<typename _Tp> + constexpr bool + operator<=(const _Tp& __lhs, const optional<_Tp>& __rhs) + { return __rhs && !(*__rhs < __lhs); } + + template<typename _Tp> + constexpr bool + operator>=(const optional<_Tp>& __lhs, const _Tp& __rhs) + { return __lhs && !(*__lhs < __rhs); } + + template<typename _Tp> + constexpr bool + operator>=(const _Tp& __lhs, const optional<_Tp>& __rhs) + { return !__rhs || !(__lhs < *__rhs); } + + // [X.Y.11] + template<typename _Tp> + void + swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs) + noexcept(noexcept(__lhs.swap(__rhs))) + { __lhs.swap(__rhs); } + + template<typename _Tp> + constexpr optional<typename decay<_Tp>::type> + make_optional(_Tp&& __t) + { return optional<typename decay<_Tp>::type> { std::forward<_Tp>(__t) }; } + + // @} group optional +_GLIBCXX_END_NAMESPACE_VERSION +} + + // [X.Y.12] + template<typename _Tp> + struct hash<experimental::optional<_Tp>> + { + using result_type = size_t; + using argument_type = experimental::optional<_Tp>; + + size_t + operator()(const experimental::optional<_Tp>& __t) const + noexcept(noexcept(hash<_Tp> {}(*__t))) + { + // We pick an arbitrary hash for disengaged optionals which hopefully + // usual values of _Tp won't typically hash to. + constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333); + return __t ? hash<_Tp> {}(*__t) : __magic_disengaged_hash; + } + }; +} + +#endif // C++14 + +#endif // _GLIBCXX_EXPERIMENTAL_OPTIONAL diff --git a/libstdc++-v3/testsuite/experimental/optional/assignment/1.cc b/libstdc++-v3/testsuite/experimental/optional/assignment/1.cc new file mode 100644 index 0000000..b09e0ac --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/assignment/1.cc @@ -0,0 +1,195 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do run } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +struct exception {}; + +int counter = 0; + +struct mixin_counter +{ + mixin_counter() { ++counter; } + mixin_counter(mixin_counter const&) { ++counter; } + ~mixin_counter() { --counter; } +}; + +struct value_type : private mixin_counter +{ + enum state_type + { + zero, + moved_from, + throwing_construction, + throwing_copy, + throwing_copy_assignment, + throwing_move, + throwing_move_assignment, + threw, + }; + + value_type() = default; + + explicit value_type(state_type state_) + : state(state_) + { + throw_if(throwing_construction); + } + + value_type(value_type const& other) + : state(other.state) + { + throw_if(throwing_copy); + } + + value_type& + operator=(value_type const& other) + { + state = other.state; + throw_if(throwing_copy_assignment); + return *this; + } + + value_type(value_type&& other) + : state(other.state) + { + other.state = moved_from; + throw_if(throwing_move); + } + + value_type& + operator=(value_type&& other) + { + state = other.state; + other.state = moved_from; + throw_if(throwing_move_assignment); + return *this; + } + + void throw_if(state_type match) + { + if(state == match) + { + state = threw; + throw exception {}; + } + } + + state_type state = zero; +}; + +int main() +{ + using O = std::experimental::optional<value_type>; + using S = value_type::state_type; + auto const make = [](S s = S::zero) { return O { std::experimental::in_place, s }; }; + + enum outcome_type { nothrow, caught, bad_catch }; + + // Check copy/move assignment for disengaged optional + + // From disengaged optional + { + O o; + VERIFY( !o ); + O p; + o = p; + VERIFY( !o ); + VERIFY( !p ); + } + + { + O o; + VERIFY( !o ); + O p; + o = std::move(p); + VERIFY( !o ); + VERIFY( !p ); + } + + { + O o; + VERIFY( !o ); + o = {}; + VERIFY( !o ); + } + + // From engaged optional + { + O o; + VERIFY( !o ); + O p = make(S::throwing_copy_assignment); + o = p; + VERIFY( o && o->state == S::throwing_copy_assignment ); + VERIFY( p && p->state == S::throwing_copy_assignment ); + } + + { + O o; + VERIFY( !o ); + O p = make(S::throwing_move_assignment); + o = std::move(p); + VERIFY( o && o->state == S::throwing_move_assignment ); + VERIFY( p && p->state == S::moved_from ); + } + + { + outcome_type outcome {}; + O o; + VERIFY( !o ); + O p = make(S::throwing_copy); + + try + { + o = p; + } + catch(exception const&) + { outcome = caught; } + catch(...) + { outcome = bad_catch; } + + VERIFY( outcome == caught ); + VERIFY( !o ); + VERIFY( p && p->state == S::throwing_copy ); + } + + { + outcome_type outcome {}; + O o; + VERIFY( !o ); + O p = make(S::throwing_move); + + try + { + o = std::move(p); + } + catch(exception const&) + { outcome = caught; } + catch(...) + { outcome = bad_catch; } + + VERIFY( outcome == caught ); + VERIFY( !o ); + VERIFY( p && p->state == S::moved_from ); + } + + VERIFY( counter == 0 ); +} diff --git a/libstdc++-v3/testsuite/experimental/optional/assignment/2.cc b/libstdc++-v3/testsuite/experimental/optional/assignment/2.cc new file mode 100644 index 0000000..7985fff --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/assignment/2.cc @@ -0,0 +1,193 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do run } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +struct exception {}; + +int counter = 0; + +struct mixin_counter +{ + mixin_counter() { ++counter; } + mixin_counter(mixin_counter const&) { ++counter; } + ~mixin_counter() { --counter; } +}; + +struct value_type : private mixin_counter +{ + enum state_type + { + zero, + moved_from, + throwing_construction, + throwing_copy, + throwing_copy_assignment, + throwing_move, + throwing_move_assignment, + threw, + }; + + value_type() = default; + + explicit value_type(state_type state_) + : state(state_) + { + throw_if(throwing_construction); + } + + value_type(value_type const& other) + : state(other.state) + { + throw_if(throwing_copy); + } + + value_type& + operator=(value_type const& other) + { + state = other.state; + throw_if(throwing_copy_assignment); + return *this; + } + + value_type(value_type&& other) + : state(other.state) + { + other.state = moved_from; + throw_if(throwing_move); + } + + value_type& + operator=(value_type&& other) + { + state = other.state; + other.state = moved_from; + throw_if(throwing_move_assignment); + return *this; + } + + void throw_if(state_type match) + { + if(state == match) + { + state = threw; + throw exception {}; + } + } + + state_type state = zero; +}; + +int main() +{ + using O = std::experimental::optional<value_type>; + using S = value_type::state_type; + auto const make = [](S s = S::zero) { return O { std::experimental::in_place, s }; }; + + enum outcome_type { nothrow, caught, bad_catch }; + + // Check copy/move assignment for engaged optional + + // From disengaged optional + { + O o = make(S::zero); + VERIFY( o ); + O p; + o = p; + VERIFY( !o ); + VERIFY( !p ); + } + + { + O o = make(S::zero); + VERIFY( o ); + O p; + o = std::move(p); + VERIFY( !o ); + VERIFY( !p ); + } + + { + O o = make(S::zero); + VERIFY( o ); + o = {}; + VERIFY( !o ); + } + + // From engaged optional + { + O o = make(S::zero); + VERIFY( o ); + O p = make(S::throwing_copy); + o = p; + VERIFY( o && o->state == S::throwing_copy); + VERIFY( p && p->state == S::throwing_copy); + } + + { + O o = make(S::zero); + VERIFY( o ); + O p = make(S::throwing_move); + o = std::move(p); + VERIFY( o && o->state == S::throwing_move); + VERIFY( p && p->state == S::moved_from); + } + + { + outcome_type outcome {}; + O o = make(S::zero); + VERIFY( o ); + O p = make(S::throwing_copy_assignment); + + try + { + o = p; + } + catch(exception const&) + { outcome = caught; } + catch(...) + { outcome = bad_catch; } + + VERIFY( o && o->state == S::threw); + VERIFY( p && p->state == S::throwing_copy_assignment); + } + + { + outcome_type outcome {}; + O o = make(S::zero); + VERIFY( o ); + O p = make(S::throwing_move_assignment); + + try + { + o = std::move(p); + } + catch(exception const&) + { outcome = caught; } + catch(...) + { outcome = bad_catch; } + + VERIFY( o && o->state == S::threw); + VERIFY( p && p->state == S::moved_from); + } + + VERIFY( counter == 0 ); +} diff --git a/libstdc++-v3/testsuite/experimental/optional/assignment/3.cc b/libstdc++-v3/testsuite/experimental/optional/assignment/3.cc new file mode 100644 index 0000000..d631886 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/assignment/3.cc @@ -0,0 +1,158 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do run } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +struct exception {}; + +int counter = 0; + +struct mixin_counter +{ + mixin_counter() { ++counter; } + mixin_counter(mixin_counter const&) { ++counter; } + ~mixin_counter() { --counter; } +}; + +struct value_type : private mixin_counter +{ + enum state_type + { + zero, + moved_from, + throwing_construction, + throwing_copy, + throwing_copy_assignment, + throwing_move, + throwing_move_assignment, + threw, + }; + + value_type() = default; + + explicit value_type(state_type state_) + : state(state_) + { + throw_if(throwing_construction); + } + + value_type(value_type const& other) + : state(other.state) + { + throw_if(throwing_copy); + } + + value_type& + operator=(value_type const& other) + { + state = other.state; + throw_if(throwing_copy_assignment); + return *this; + } + + value_type(value_type&& other) + : state(other.state) + { + other.state = moved_from; + throw_if(throwing_move); + } + + value_type& + operator=(value_type&& other) + { + state = other.state; + other.state = moved_from; + throw_if(throwing_move_assignment); + return *this; + } + + void throw_if(state_type match) + { + if(state == match) + { + state = threw; + throw exception {}; + } + } + + state_type state = zero; +}; + +int main() +{ + using O = std::experimental::optional<value_type>; + using S = value_type::state_type; + auto const make = [](S s = S::zero) { return value_type { s }; }; + + enum outcome_type { nothrow, caught, bad_catch }; + + // Check value assignment for disengaged optional + + { + O o; + value_type v = make(S::throwing_copy_assignment); + o = v; + VERIFY( o && o->state == S::throwing_copy_assignment ); + } + + { + O o; + value_type v = make(S::throwing_move_assignment); + o = std::move(v); + VERIFY( o && o->state == S::throwing_move_assignment ); + } + + { + outcome_type outcome {}; + O o; + value_type v = make(S::throwing_copy); + + try + { + o = v; + } + catch(exception const&) + { outcome = caught; } + catch(...) + { outcome = bad_catch; } + + VERIFY( !o ); + } + + { + outcome_type outcome {}; + O o; + value_type v = make(S::throwing_move); + + try + { + o = std::move(v); + } + catch(exception const&) + { outcome = caught; } + catch(...) + { outcome = bad_catch; } + + VERIFY( !o ); + } + + VERIFY( counter == 0 ); +} diff --git a/libstdc++-v3/testsuite/experimental/optional/assignment/4.cc b/libstdc++-v3/testsuite/experimental/optional/assignment/4.cc new file mode 100644 index 0000000..e5f1f16 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/assignment/4.cc @@ -0,0 +1,158 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do run } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +struct exception {}; + +int counter = 0; + +struct mixin_counter +{ + mixin_counter() { ++counter; } + mixin_counter(mixin_counter const&) { ++counter; } + ~mixin_counter() { --counter; } +}; + +struct value_type : private mixin_counter +{ + enum state_type + { + zero, + moved_from, + throwing_construction, + throwing_copy, + throwing_copy_assignment, + throwing_move, + throwing_move_assignment, + threw, + }; + + value_type() = default; + + explicit value_type(state_type state_) + : state(state_) + { + throw_if(throwing_construction); + } + + value_type(value_type const& other) + : state(other.state) + { + throw_if(throwing_copy); + } + + value_type& + operator=(value_type const& other) + { + state = other.state; + throw_if(throwing_copy_assignment); + return *this; + } + + value_type(value_type&& other) + : state(other.state) + { + other.state = moved_from; + throw_if(throwing_move); + } + + value_type& + operator=(value_type&& other) + { + state = other.state; + other.state = moved_from; + throw_if(throwing_move_assignment); + return *this; + } + + void throw_if(state_type match) + { + if(state == match) + { + state = threw; + throw exception {}; + } + } + + state_type state = zero; +}; + +int main() +{ + using O = std::experimental::optional<value_type>; + using S = value_type::state_type; + auto const make = [](S s = S::zero) { return value_type { s }; }; + + enum outcome_type { nothrow, caught, bad_catch }; + + // Check value assignment for engaged optional + + { + O o = make(); + value_type v = make(S::throwing_copy); + o = v; + VERIFY( o && o->state == S::throwing_copy); + } + + { + O o = make(); + value_type v = make(S::throwing_move); + o = std::move(v); + VERIFY( o && o->state == S::throwing_move); + } + + { + outcome_type outcome {}; + O o = make(); + value_type v = make(S::throwing_copy_assignment); + + try + { + o = v; + } + catch(exception const&) + { outcome = caught; } + catch(...) + { outcome = bad_catch; } + + VERIFY( o && o->state == S::threw ); + } + + { + outcome_type outcome {}; + O o = make(); + value_type v = make(S::throwing_move_assignment); + + try + { + o = std::move(v); + } + catch(exception const&) + { outcome = caught; } + catch(...) + { outcome = bad_catch; } + + VERIFY( o && o->state == S::threw ); + } + + VERIFY( counter == 0 ); +} diff --git a/libstdc++-v3/testsuite/experimental/optional/assignment/5.cc b/libstdc++-v3/testsuite/experimental/optional/assignment/5.cc new file mode 100644 index 0000000..d6e268f --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/assignment/5.cc @@ -0,0 +1,66 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do run } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +int counter = 0; + +struct mixin_counter +{ + mixin_counter() { ++counter; } + mixin_counter(mixin_counter const&) { ++counter; } + ~mixin_counter() { --counter; } +}; + +struct value_type : private mixin_counter { }; + +int main() +{ + using O = std::experimental::optional<value_type>; + + // Check std::experimental::nullopt_t and 'default' (= {}) assignment + + { + O o; + o = std::experimental::nullopt; + VERIFY( !o ); + } + + { + O o { std::experimental::in_place }; + o = std::experimental::nullopt; + VERIFY( !o ); + } + + { + O o; + o = {}; + VERIFY( !o ); + } + + { + O o { std::experimental::in_place }; + o = {}; + VERIFY( !o ); + } + + VERIFY( counter == 0 ); +} diff --git a/libstdc++-v3/testsuite/experimental/optional/assignment/6.cc b/libstdc++-v3/testsuite/experimental/optional/assignment/6.cc new file mode 100644 index 0000000..55be89d --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/assignment/6.cc @@ -0,0 +1,83 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do run } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +int counter = 0; + +struct mixin_counter +{ + mixin_counter() { ++counter; } + mixin_counter(mixin_counter const&) { ++counter; } + ~mixin_counter() { --counter; } +}; + +struct value_type : private mixin_counter +{ + value_type() = default; + value_type(int) : state(1) { } + value_type(std::initializer_list<char>, const char*) : state(2) { } + int state = 0; +}; + +int main() +{ + using O = std::experimental::optional<value_type>; + + // Check emplace + + { + O o; + o.emplace(); + VERIFY( o && o->state == 0 ); + } + { + O o { std::experimental::in_place, 0 }; + o.emplace(); + VERIFY( o && o->state == 0 ); + } + + { + O o; + o.emplace(0); + VERIFY( o && o->state == 1 ); + } + { + O o { std::experimental::in_place }; + o.emplace(0); + VERIFY( o && o->state == 1 ); + } + + { + O o; + o.emplace({ 'a' }, ""); + VERIFY( o && o->state == 2 ); + } + { + O o { std::experimental::in_place }; + o.emplace({ 'a' }, ""); + VERIFY( o && o->state == 2 ); + } + + static_assert( !std::is_constructible<O, std::initializer_list<int>, int>(), "" ); + + VERIFY( counter == 0 ); +} diff --git a/libstdc++-v3/testsuite/experimental/optional/cons/copy.cc b/libstdc++-v3/testsuite/experimental/optional/cons/copy.cc new file mode 100644 index 0000000..bbd9328 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/cons/copy.cc @@ -0,0 +1,125 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do run } + +// Copyright (C) 2013 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 +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +struct tracker +{ + tracker(int value) : value(value) { ++count; } + ~tracker() { --count; } + + tracker(tracker const& other) : value(other.value) { ++count; } + tracker(tracker&& other) : value(other.value) + { + other.value = -1; + ++count; + } + + tracker& operator=(tracker const&) = default; + tracker& operator=(tracker&&) = default; + + int value; + + static int count; +}; + +int tracker::count = 0; + +struct exception { }; + +struct throwing_copy +{ + throwing_copy() = default; + throwing_copy(throwing_copy const&) { throw exception {}; } +}; + +int main() +{ + // [20.5.4.1] Constructors + + { + std::experimental::optional<long> o; + auto copy = o; + VERIFY( !copy ); + VERIFY( !o ); + } + + { + std::experimental::optional<long> o { std::experimental::in_place, 0x1234ABCDF1E2D3C4 }; + auto copy = o; + VERIFY( copy ); + VERIFY( *copy == 0x1234ABCDF1E2D3C4 ); + VERIFY( o && o == 0x1234ABCDF1E2D3C4 ); + } + + { + std::experimental::optional<tracker> o; + auto copy = o; + VERIFY( !copy ); + VERIFY( tracker::count == 0 ); + VERIFY( !o ); + } + + { + std::experimental::optional<tracker> o { std::experimental::in_place, 333 }; + auto copy = o; + VERIFY( copy ); + VERIFY( copy->value == 333 ); + VERIFY( tracker::count == 2 ); + VERIFY( o && o->value == 333 ); + } + + enum outcome { nothrow, caught, bad_catch }; + + { + outcome result = nothrow; + std::experimental::optional<throwing_copy> o; + + try + { + auto copy = o; + } + catch(exception const&) + { result = caught; } + catch(...) + { result = bad_catch; } + + VERIFY( result == nothrow ); + } + + { + outcome result = nothrow; + std::experimental::optional<throwing_copy> o { std::experimental::in_place }; + + try + { + auto copy = o; + } + catch(exception const&) + { result = caught; } + catch(...) + { result = bad_catch; } + + VERIFY( result == caught ); + } + + VERIFY( tracker::count == 0 ); +} diff --git a/libstdc++-v3/testsuite/experimental/optional/cons/default.cc b/libstdc++-v3/testsuite/experimental/optional/cons/default.cc new file mode 100644 index 0000000..452f2d0 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/cons/default.cc @@ -0,0 +1,60 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do run } + +// Copyright (C) 2013 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 +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +struct tracker +{ + tracker() { ++count; } + ~tracker() { --count; } + + tracker(tracker const&) { ++count; } + tracker(tracker&&) { ++count; } + + tracker& operator=(tracker const&) = default; + tracker& operator=(tracker&&) = default; + + static int count; +}; + +int tracker::count = 0; + +int main() +{ + // [20.5.4.1] Constructors + + { + std::experimental::optional<tracker> o; + VERIFY( !o ); + } + + { + std::experimental::optional<tracker> o {}; + VERIFY( !o ); + } + + { + std::experimental::optional<tracker> o = {}; + VERIFY( !o ); + } + + VERIFY( tracker::count == 0 ); +} diff --git a/libstdc++-v3/testsuite/experimental/optional/cons/move.cc b/libstdc++-v3/testsuite/experimental/optional/cons/move.cc new file mode 100644 index 0000000..75d7677 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/cons/move.cc @@ -0,0 +1,125 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do run } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +struct tracker +{ + tracker(int value) : value(value) { ++count; } + ~tracker() { --count; } + + tracker(tracker const& other) : value(other.value) { ++count; } + tracker(tracker&& other) : value(other.value) + { + other.value = -1; + ++count; + } + + tracker& operator=(tracker const&) = default; + tracker& operator=(tracker&&) = default; + + int value; + + static int count; +}; + +int tracker::count = 0; + +struct exception { }; + +struct throwing_move +{ + throwing_move() = default; + throwing_move(throwing_move const&) { throw exception {}; } +}; + +int main() +{ + // [20.5.4.1] Constructors + + { + std::experimental::optional<long> o; + auto moved_to = std::move(o); + VERIFY( !moved_to ); + VERIFY( !o ); + } + + { + std::experimental::optional<long> o { std::experimental::in_place, 0x1234ABCDF1E2D3C4 }; + auto moved_to = std::move(o); + VERIFY( moved_to ); + VERIFY( *moved_to == 0x1234ABCDF1E2D3C4 ); + VERIFY( o && *o == 0x1234ABCDF1E2D3C4 ); + } + + { + std::experimental::optional<tracker> o; + auto moved_to = std::move(o); + VERIFY( !moved_to ); + VERIFY( tracker::count == 0 ); + VERIFY( !o ); + } + + { + std::experimental::optional<tracker> o { std::experimental::in_place, 333 }; + auto moved_to = std::move(o); + VERIFY( moved_to ); + VERIFY( moved_to->value == 333 ); + VERIFY( tracker::count == 2 ); + VERIFY( o && o->value == -1 ); + } + + enum outcome { nothrow, caught, bad_catch }; + + { + outcome result = nothrow; + std::experimental::optional<throwing_move> o; + + try + { + auto moved_to = std::move(o); + } + catch(exception const&) + { result = caught; } + catch(...) + { result = bad_catch; } + + VERIFY( result == nothrow ); + } + + { + outcome result = nothrow; + std::experimental::optional<throwing_move> o { std::experimental::in_place }; + + try + { + auto moved_to = std::move(o); + } + catch(exception const&) + { result = caught; } + catch(...) + { result = bad_catch; } + + VERIFY( result == caught ); + } + + VERIFY( tracker::count == 0 ); +} diff --git a/libstdc++-v3/testsuite/experimental/optional/cons/value.cc b/libstdc++-v3/testsuite/experimental/optional/cons/value.cc new file mode 100644 index 0000000..339c120 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/cons/value.cc @@ -0,0 +1,239 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do run } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +#include <vector> + +struct tracker +{ + tracker(int value) : value(value) { ++count; } + ~tracker() { --count; } + + tracker(tracker const& other) : value(other.value) { ++count; } + tracker(tracker&& other) : value(other.value) + { + other.value = -1; + ++count; + } + + tracker& operator=(tracker const&) = default; + tracker& operator=(tracker&&) = default; + + int value; + + static int count; +}; + +int tracker::count = 0; + +struct exception { }; + +struct throwing_construction +{ + explicit throwing_construction(bool propagate) : propagate(propagate) { } + + throwing_construction(throwing_construction const& other) + : propagate(other.propagate) + { + if(propagate) + throw exception {}; + } + + bool propagate; +}; + +int main() +{ + // [20.5.4.1] Constructors + + { + auto i = 0x1234ABCDF1E2D3C4; + std::experimental::optional<long> o { i }; + VERIFY( o ); + VERIFY( *o == 0x1234ABCDF1E2D3C4 ); + VERIFY( i == 0x1234ABCDF1E2D3C4 ); + } + + { + auto i = 0x1234ABCDF1E2D3C4; + std::experimental::optional<long> o = i; + VERIFY( o ); + VERIFY( *o == 0x1234ABCDF1E2D3C4 ); + VERIFY( i == 0x1234ABCDF1E2D3C4 ); + } + + { + auto i = 0x1234ABCDF1E2D3C4; + std::experimental::optional<long> o = { i }; + VERIFY( o ); + VERIFY( *o == 0x1234ABCDF1E2D3C4 ); + VERIFY( i == 0x1234ABCDF1E2D3C4 ); + } + + { + auto i = 0x1234ABCDF1E2D3C4; + std::experimental::optional<long> o { std::move(i) }; + VERIFY( o ); + VERIFY( *o == 0x1234ABCDF1E2D3C4 ); + VERIFY( i == 0x1234ABCDF1E2D3C4 ); + } + + { + auto i = 0x1234ABCDF1E2D3C4; + std::experimental::optional<long> o = std::move(i); + VERIFY( o ); + VERIFY( *o == 0x1234ABCDF1E2D3C4 ); + VERIFY( i == 0x1234ABCDF1E2D3C4 ); + } + + { + auto i = 0x1234ABCDF1E2D3C4; + std::experimental::optional<long> o = { std::move(i) }; + VERIFY( o ); + VERIFY( *o == 0x1234ABCDF1E2D3C4 ); + VERIFY( i == 0x1234ABCDF1E2D3C4 ); + } + + { + std::vector<int> v = { 0, 1, 2, 3, 4, 5 }; + std::experimental::optional<std::vector<int>> o { v }; + VERIFY( !v.empty() ); + VERIFY( o->size() == 6 ); + } + + { + std::vector<int> v = { 0, 1, 2, 3, 4, 5 }; + std::experimental::optional<std::vector<int>> o = v; + VERIFY( !v.empty() ); + VERIFY( o->size() == 6 ); + } + + { + std::vector<int> v = { 0, 1, 2, 3, 4, 5 }; + std::experimental::optional<std::vector<int>> o { v }; + VERIFY( !v.empty() ); + VERIFY( o->size() == 6 ); + } + + { + std::vector<int> v = { 0, 1, 2, 3, 4, 5 }; + std::experimental::optional<std::vector<int>> o { std::move(v) }; + VERIFY( v.empty() ); + VERIFY( o->size() == 6 ); + } + + { + std::vector<int> v = { 0, 1, 2, 3, 4, 5 }; + std::experimental::optional<std::vector<int>> o = std::move(v); + VERIFY( v.empty() ); + VERIFY( o->size() == 6 ); + } + + { + std::vector<int> v = { 0, 1, 2, 3, 4, 5 }; + std::experimental::optional<std::vector<int>> o { std::move(v) }; + VERIFY( v.empty() ); + VERIFY( o->size() == 6 ); + } + + { + tracker t { 333 }; + std::experimental::optional<tracker> o = t; + VERIFY( o->value == 333 ); + VERIFY( tracker::count == 2 ); + VERIFY( t.value == 333 ); + } + + { + tracker t { 333 }; + std::experimental::optional<tracker> o = std::move(t); + VERIFY( o->value == 333 ); + VERIFY( tracker::count == 2 ); + VERIFY( t.value == -1 ); + } + + enum outcome { nothrow, caught, bad_catch }; + + { + outcome result = nothrow; + throwing_construction t { false }; + + try + { + std::experimental::optional<throwing_construction> o { t }; + } + catch(exception const&) + { result = caught; } + catch(...) + { result = bad_catch; } + + VERIFY( result == nothrow ); + } + + { + outcome result = nothrow; + throwing_construction t { true }; + + try + { + std::experimental::optional<throwing_construction> o { t }; + } + catch(exception const&) + { result = caught; } + catch(...) + { result = bad_catch; } + + VERIFY( result == caught ); + } + + { + outcome result = nothrow; + throwing_construction t { false }; + + try + { + std::experimental::optional<throwing_construction> o { std::move(t) }; + } + catch(exception const&) + { result = caught; } + catch(...) + { result = bad_catch; } + + VERIFY( result == nothrow ); + } + + { + outcome result = nothrow; + throwing_construction t { true }; + + try + { + std::experimental::optional<throwing_construction> o { std::move(t) }; + } + catch(exception const&) + { result = caught; } + catch(...) + { result = bad_catch; } + + VERIFY( result == caught ); + } +} diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/cons/default.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/cons/default.cc new file mode 100644 index 0000000..d437cd8 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/constexpr/cons/default.cc @@ -0,0 +1,42 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do compile } + +// Copyright (C) 2013 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 +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +int main() +{ + // [20.5.4.1] Constructors + + { + constexpr std::experimental::optional<int> o; + static_assert( !o, "" ); + } + + { + constexpr std::experimental::optional<int> o {}; + static_assert( !o, "" ); + } + + { + constexpr std::experimental::optional<int> o = {}; + static_assert( !o, "" ); + } +} diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/cons/value.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/cons/value.cc new file mode 100644 index 0000000..98e0a22 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/constexpr/cons/value.cc @@ -0,0 +1,69 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do compile } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +int main() +{ + // [20.5.4.1] Constructors + + { + constexpr auto i = 0x1234ABCDF1E2D3C4; + constexpr std::experimental::optional<long> o { i }; + static_assert( o, "" ); + static_assert( *o == 0x1234ABCDF1E2D3C4, "" ); + } + + { + constexpr auto i = 0x1234ABCDF1E2D3C4; + constexpr std::experimental::optional<long> o = i; + static_assert( o, "" ); + static_assert( *o == 0x1234ABCDF1E2D3C4, "" ); + } + + { + constexpr auto i = 0x1234ABCDF1E2D3C4; + constexpr std::experimental::optional<long> o = { i }; + static_assert( o, "" ); + static_assert( *o == 0x1234ABCDF1E2D3C4, "" ); + } + + { + constexpr auto i = 0x1234ABCDF1E2D3C4; + constexpr std::experimental::optional<long> o { std::move(i) }; + static_assert( o, "" ); + static_assert( *o == 0x1234ABCDF1E2D3C4, "" ); + } + + { + constexpr auto i = 0x1234ABCDF1E2D3C4; + constexpr std::experimental::optional<long> o = std::move(i); + static_assert( o, "" ); + static_assert( *o == 0x1234ABCDF1E2D3C4, "" ); + } + + { + constexpr auto i = 0x1234ABCDF1E2D3C4; + constexpr std::experimental::optional<long> o = { std::move(i) }; + static_assert( o, "" ); + static_assert( *o == 0x1234ABCDF1E2D3C4, "" ); + } +} diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/in_place.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/in_place.cc new file mode 100644 index 0000000..f2bb8fd --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/constexpr/in_place.cc @@ -0,0 +1,43 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do compile } + +// Copyright (C) 2013 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 +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +int main() +{ + // [20.5.5] In-place construction + static_assert( std::is_same<decltype(std::experimental::in_place), const std::experimental::in_place_t>(), "" ); + static_assert( std::is_empty<std::experimental::in_place_t>(), "" ); + + { + constexpr std::experimental::optional<int> o { std::experimental::in_place }; + static_assert( o, "" ); + static_assert( *o == int {}, "" ); + + static_assert( !std::is_convertible<std::experimental::in_place_t, std::experimental::optional<int>>(), "" ); + } + + { + constexpr std::experimental::optional<int> o { std::experimental::in_place, 42 }; + static_assert( o, "" ); + static_assert( *o == 42, "" ); + } +} diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/make_optional.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/make_optional.cc new file mode 100644 index 0000000..4b59ba9 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/constexpr/make_optional.cc @@ -0,0 +1,33 @@ +// { dg-options "-std=gnu++1y" } +// XFAIL pending resolution of PR libstdc++/58777 +// { dg-do compile { xfail *-*-* } } +// { dg-excess-errors "" } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +int main() +{ + constexpr int i = 42; + constexpr auto o = std::experimental::make_optional(i); + static_assert( std::is_same<decltype(o), const std::experimental::optional<int>>(), "" ); + static_assert( o && *o == 42, "" ); + static_assert( &*o != &i, "" ); +} diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/nullopt.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/nullopt.cc new file mode 100644 index 0000000..08566e1 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/constexpr/nullopt.cc @@ -0,0 +1,46 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do compile } + +// Copyright (C) 2013 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 +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +int main() +{ + // [20.5.6] Disengaged state indicator + static_assert( std::is_same<decltype(std::experimental::nullopt), const std::experimental::nullopt_t>(), "" ); + static_assert( std::is_empty<std::experimental::nullopt_t>(), "" ); + static_assert( std::is_literal_type<std::experimental::nullopt_t>(), "" ); + static_assert( !std::is_default_constructible<std::experimental::nullopt_t>(), "" ); + + { + constexpr std::experimental::optional<int> o = std::experimental::nullopt; + static_assert( !o, "" ); + } + + { + constexpr std::experimental::optional<int> o = { std::experimental::nullopt }; + static_assert( !o, "" ); + } + + { + constexpr std::experimental::optional<int> o { std::experimental::nullopt }; + static_assert( !o, "" ); + } +} diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/1.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/1.cc new file mode 100644 index 0000000..5943a35 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/1.cc @@ -0,0 +1,33 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do compile } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +struct value_type +{ + int i; +}; + +int main() +{ + constexpr std::experimental::optional<value_type> o { value_type { 51 } }; + static_assert( (*o).i == 51, "" ); +} diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/2.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/2.cc new file mode 100644 index 0000000..3df68d3 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/2.cc @@ -0,0 +1,37 @@ +// { dg-options "-std=gnu++1y" } +// XFAIL pending resolution of PR libstdc++/58777 +// { dg-do compile { xfail *-*-* } } +// { dg-excess-errors "" } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +struct value_type +{ + int i; +}; + +int main() +{ + constexpr std::experimental::optional<value_type> o { value_type { 51 } }; + static_assert( o->i == 51, "" ); + static_assert( o->i == (*o).i, "" ); + static_assert( &o->i == &(*o).i, "" ); +} diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/3.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/3.cc new file mode 100644 index 0000000..6528d99 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/3.cc @@ -0,0 +1,37 @@ +// { dg-options "-std=gnu++1y" } +// XFAIL pending resolution of PR libstdc++/58777 +// { dg-do compile { xfail *-*-* } } +// { dg-excess-errors "" } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +struct value_type +{ + int i; +}; + +int main() +{ + constexpr std::experimental::optional<value_type> o { value_type { 51 } }; + static_assert( o.value().i == 51, "" ); + static_assert( o.value().i == (*o).i, "" ); + static_assert( &o.value().i == &(*o).i, "" ); +} diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/4.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/4.cc new file mode 100644 index 0000000..9098c0c --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/4.cc @@ -0,0 +1,35 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do compile } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +struct value_type +{ + int i; +}; + +int main() +{ + constexpr std::experimental::optional<value_type> o { value_type { 51 } }; + constexpr value_type fallback { 3 }; + static_assert( o.value_or(fallback).i == 51, "" ); + static_assert( o.value_or(fallback).i == (*o).i, "" ); +} diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/5.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/5.cc new file mode 100644 index 0000000..e86d040 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/5.cc @@ -0,0 +1,40 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do compile } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +struct value_type +{ + int i; +}; + +int main() +{ + { + constexpr std::experimental::optional<value_type> o = std::experimental::nullopt; + static_assert( !o, "" ); + } + + { + constexpr std::experimental::optional<value_type> o { value_type { 51 } }; + static_assert( o, "" ); + } +} diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/1.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/1.cc new file mode 100644 index 0000000..591eb13 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/1.cc @@ -0,0 +1,99 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do compile } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +namespace ns +{ + struct value_type + { + int i; + const char* s; + }; + + constexpr bool + strcmp(const char* lhs, const char* rhs) + { + return *lhs == *rhs && (!*lhs || strcmp(lhs + 1, rhs + 1)); + } + + constexpr bool + strrel(const char* lhs, const char* rhs) + { + return (*rhs && (!*lhs || (*lhs < *rhs))) + || ((*lhs && *rhs && !(*rhs < *lhs)) && strrel(lhs + 1, rhs + 1)); + } + + constexpr bool + operator==(value_type const& lhs, value_type const& rhs) + { return (lhs.i == rhs.i) && strcmp(lhs.s, rhs.s); } + + constexpr bool + operator!=(value_type const& lhs, value_type const& rhs) + { return !(lhs == rhs); } + + constexpr bool + operator<(value_type const& lhs, value_type const& rhs) + { return (lhs.i < rhs.i) || (!(rhs.i < lhs.i) && strrel(lhs.s, rhs.s)); } + +} // namespace ns + +int main() +{ + using ns::value_type; + using O = std::experimental::optional<value_type>; + + { + constexpr O o, p; + static_assert( o == p, "" ); + static_assert( !(o != p), "" ); + } + + { + constexpr O o { value_type { 42, "forty-two" } }, p; + static_assert( !(o == p), "" ); + static_assert( o != p, "" ); + } + + { + constexpr O o, p { value_type { 42, "forty-two" } }; + static_assert( !(o == p), "" ); + static_assert( o != p, "" ); + } + + { + constexpr O o { value_type { 11, "eleventy" } }, p { value_type { 42, "forty-two" } }; + static_assert( !(o == p), "" ); + static_assert( o != p, "" ); + } + + { + constexpr O o { value_type { 42, "forty-two" } }, p { value_type { 11, "eleventy" } }; + static_assert( !(o == p), "" ); + static_assert( o != p, "" ); + } + + { + constexpr O o { value_type { 42, "forty-two" } }, p { value_type { 42, "forty-two" } }; + static_assert( o == p, "" ); + static_assert( !(o != p), "" ); + } +} diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/2.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/2.cc new file mode 100644 index 0000000..9bc140d --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/2.cc @@ -0,0 +1,111 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do compile } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +namespace ns +{ + struct value_type + { + int i; + const char* s; + }; + + constexpr bool + strcmp(const char* lhs, const char* rhs) + { + return *lhs == *rhs && (!*lhs || strcmp(lhs + 1, rhs + 1)); + } + + constexpr bool + strrel(const char* lhs, const char* rhs) + { + return (*rhs && (!*lhs || (*lhs < *rhs))) + || ((*lhs && *rhs && !(*rhs < *lhs)) && strrel(lhs + 1, rhs + 1)); + } + + constexpr bool + operator==(value_type const& lhs, value_type const& rhs) + { return (lhs.i == rhs.i) && strcmp(lhs.s, rhs.s); } + + constexpr bool + operator!=(value_type const& lhs, value_type const& rhs) + { return !(lhs == rhs); } + + constexpr bool + operator<(value_type const& lhs, value_type const& rhs) + { return (lhs.i < rhs.i) || (!(rhs.i < lhs.i) && strrel(lhs.s, rhs.s)); } + +} // namespace ns + +int main() +{ + using ns::value_type; + using O = std::experimental::optional<value_type>; + + { + constexpr O o, p; + static_assert( !(o < p), "" ); + static_assert( !(o > p), "" ); + static_assert( o <= p, "" ); + static_assert( o >= p, "" ); + } + + { + constexpr O o { value_type { 42, "forty-two" } }, p; + static_assert( !(o < p), "" ); + static_assert( o > p, "" ); + static_assert( !(o <= p), "" ); + static_assert( o >= p, "" ); + } + + { + constexpr O o, p { value_type { 42, "forty-two" } }; + static_assert( o < p, "" ); + static_assert( !(o > p), "" ); + static_assert( o <= p, "" ); + static_assert( !(o >= p), "" ); + } + + { + constexpr O o { value_type { 11, "eleventy" } }, p { value_type { 42, "forty-two" } }; + static_assert( o < p, "" ); + static_assert( !(o > p), "" ); + static_assert( o <= p, "" ); + static_assert( !(o >= p), "" ); + } + + { + constexpr O o { value_type { 42, "forty-two" } }, p { value_type { 11, "eleventy" } }; + static_assert( !(o < p), "" ); + static_assert( o > p, "" ); + static_assert( !(o <= p), "" ); + static_assert( o >= p, "" ); + } + + { + constexpr O o { value_type { 42, "forty-two" } }, p { value_type { 42, "forty-two" } }; + static_assert( !(o < p), "" ); + static_assert( !(o > p), "" ); + static_assert( o <= p, "" ); + static_assert( o >= p, "" ); + } +} diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/3.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/3.cc new file mode 100644 index 0000000..6ffd2b6 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/3.cc @@ -0,0 +1,89 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do compile } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +namespace ns +{ + struct value_type + { + int i; + const char* s; + }; + + constexpr bool + strcmp(const char* lhs, const char* rhs) + { + return *lhs == *rhs && (!*lhs || strcmp(lhs + 1, rhs + 1)); + } + + constexpr bool + strrel(const char* lhs, const char* rhs) + { + return (*rhs && (!*lhs || (*lhs < *rhs))) + || ((*lhs && *rhs && !(*rhs < *lhs)) && strrel(lhs + 1, rhs + 1)); + } + + constexpr bool + operator==(value_type const& lhs, value_type const& rhs) + { return (lhs.i == rhs.i) && strcmp(lhs.s, rhs.s); } + + constexpr bool + operator!=(value_type const& lhs, value_type const& rhs) + { return !(lhs == rhs); } + + constexpr bool + operator<(value_type const& lhs, value_type const& rhs) + { return (lhs.i < rhs.i) || (!(rhs.i < lhs.i) && strrel(lhs.s, rhs.s)); } + +} // namespace ns + +int main() +{ + using ns::value_type; + using O = std::experimental::optional<value_type>; + + constexpr value_type reference { 42, "forty-two" }; + + { + constexpr O o; + static_assert( !(o == reference), "" ); + static_assert( !(reference == o), "" ); + static_assert( o != reference, "" ); + static_assert( reference != o, "" ); + } + + { + constexpr O o { value_type { 11, "eleventy" } }; + static_assert( !(o == reference), "" ); + static_assert( !(reference == o), "" ); + static_assert( o != reference, "" ); + static_assert( reference != o, "" ); + } + + { + constexpr O o { value_type { 42, "forty-two" } }; + static_assert( o == reference, "" ); + static_assert( reference == o, "" ); + static_assert( !(o != reference), "" ); + static_assert( !(reference != o), "" ); + } +} diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/4.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/4.cc new file mode 100644 index 0000000..8df602c --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/4.cc @@ -0,0 +1,101 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do compile } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +namespace ns +{ + struct value_type + { + int i; + const char* s; + }; + + constexpr bool + strcmp(const char* lhs, const char* rhs) + { + return *lhs == *rhs && (!*lhs || strcmp(lhs + 1, rhs + 1)); + } + + constexpr bool + strrel(const char* lhs, const char* rhs) + { + return (*rhs && (!*lhs || (*lhs < *rhs))) + || ((*lhs && *rhs && !(*rhs < *lhs)) && strrel(lhs + 1, rhs + 1)); + } + + constexpr bool + operator==(value_type const& lhs, value_type const& rhs) + { return (lhs.i == rhs.i) && strcmp(lhs.s, rhs.s); } + + constexpr bool + operator!=(value_type const& lhs, value_type const& rhs) + { return !(lhs == rhs); } + + constexpr bool + operator<(value_type const& lhs, value_type const& rhs) + { return (lhs.i < rhs.i) || (!(rhs.i < lhs.i) && strrel(lhs.s, rhs.s)); } + +} // namespace ns + +int main() +{ + using ns::value_type; + using O = std::experimental::optional<value_type>; + + constexpr value_type reference { 42, "forty-two" }; + + { + constexpr O o; + static_assert( o < reference, "" ); + static_assert( !(reference < o), "" ); + static_assert( !(o > reference), "" ); + static_assert( reference > o, "" ); + static_assert( o <= reference, "" ); + static_assert( !(reference <= o), "" ); + static_assert( !(o >= reference), "" ); + static_assert( reference >= o, "" ); + } + + { + constexpr O o { value_type { 11, "eleventy" } }; + static_assert( o < reference, "" ); + static_assert( !(reference < o), "" ); + static_assert( !(o > reference), "" ); + static_assert( reference > o, "" ); + static_assert( o <= reference, "" ); + static_assert( !(reference <= o), "" ); + static_assert( !(o >= reference), "" ); + static_assert( reference >= o, "" ); + } + + { + constexpr O o { value_type { 42, "forty-two" } }; + static_assert( !(o < reference), "" ); + static_assert( !(reference < o), "" ); + static_assert( !(o > reference), "" ); + static_assert( !(reference > o), "" ); + static_assert( o <= reference, "" ); + static_assert( reference <= o, "" ); + static_assert( o >= reference, "" ); + static_assert( reference >= o, "" ); + } +} diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/5.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/5.cc new file mode 100644 index 0000000..241a71b --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/5.cc @@ -0,0 +1,80 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do compile } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +namespace ns +{ + struct value_type + { + int i; + const char* s; + }; + + constexpr bool + strcmp(const char* lhs, const char* rhs) + { + return *lhs == *rhs && (!*lhs || strcmp(lhs + 1, rhs + 1)); + } + + constexpr bool + strrel(const char* lhs, const char* rhs) + { + return (*rhs && (!*lhs || (*lhs < *rhs))) + || ((*lhs && *rhs && !(*rhs < *lhs)) && strrel(lhs + 1, rhs + 1)); + } + + constexpr bool + operator==(value_type const& lhs, value_type const& rhs) + { return (lhs.i == rhs.i) && strcmp(lhs.s, rhs.s); } + + constexpr bool + operator!=(value_type const& lhs, value_type const& rhs) + { return !(lhs == rhs); } + + constexpr bool + operator<(value_type const& lhs, value_type const& rhs) + { return (lhs.i < rhs.i) || (!(rhs.i < lhs.i) && strrel(lhs.s, rhs.s)); } + +} // namespace ns + +int main() +{ + using ns::value_type; + using O = std::experimental::optional<value_type>; + using std::experimental::nullopt; + + { + constexpr O o; + static_assert( o == nullopt, "" ); + static_assert( nullopt == o, "" ); + static_assert( !(o != nullopt), "" ); + static_assert( !(nullopt != o), "" ); + } + + { + constexpr O o { std::experimental::in_place }; + static_assert( !(o == nullopt), "" ); + static_assert( !(nullopt == o), "" ); + static_assert( o != nullopt, "" ); + static_assert( nullopt != o, "" ); + } +} diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/6.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/6.cc new file mode 100644 index 0000000..a4282d8 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/6.cc @@ -0,0 +1,88 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do compile } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +namespace ns +{ + struct value_type + { + int i; + const char* s; + }; + + constexpr bool + strcmp(const char* lhs, const char* rhs) + { + return *lhs == *rhs && (!*lhs || strcmp(lhs + 1, rhs + 1)); + } + + constexpr bool + strrel(const char* lhs, const char* rhs) + { + return (*rhs && (!*lhs || (*lhs < *rhs))) + || ((*lhs && *rhs && !(*rhs < *lhs)) && strrel(lhs + 1, rhs + 1)); + } + + constexpr bool + operator==(value_type const& lhs, value_type const& rhs) + { return (lhs.i == rhs.i) && strcmp(lhs.s, rhs.s); } + + constexpr bool + operator!=(value_type const& lhs, value_type const& rhs) + { return !(lhs == rhs); } + + constexpr bool + operator<(value_type const& lhs, value_type const& rhs) + { return (lhs.i < rhs.i) || (!(rhs.i < lhs.i) && strrel(lhs.s, rhs.s)); } + +} // namespace ns + +int main() +{ + using ns::value_type; + using O = std::experimental::optional<value_type>; + using std::experimental::nullopt; + + { + constexpr O o; + static_assert( !(o < nullopt), "" ); + static_assert( !(nullopt < o), "" ); + static_assert( !(o > nullopt), "" ); + static_assert( !(nullopt > o), "" ); + static_assert( o <= nullopt, "" ); + static_assert( nullopt <= o, "" ); + static_assert( o >= nullopt, "" ); + static_assert( nullopt >= o, "" ); + } + + { + constexpr O o { std::experimental::in_place }; + static_assert( !(o < nullopt), "" ); + static_assert( nullopt < o, "" ); + static_assert( o > nullopt, "" ); + static_assert( !(nullopt > o), "" ); + static_assert( !(o <= nullopt), "" ); + static_assert( nullopt <= o, "" ); + static_assert( o >= nullopt, "" ); + static_assert( !(nullopt >= o), "" ); + } +} diff --git a/libstdc++-v3/testsuite/experimental/optional/in_place.cc b/libstdc++-v3/testsuite/experimental/optional/in_place.cc new file mode 100644 index 0000000..ceaa97d --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/in_place.cc @@ -0,0 +1,66 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do run } + +// Copyright (C) 2013 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 +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +#include <vector> + +int main() +{ + // [20.5.5] In-place construction + static_assert( std::is_same<decltype(std::experimental::in_place), const std::experimental::in_place_t>(), "" ); + static_assert( std::is_empty<std::experimental::in_place_t>(), "" ); + + { + std::experimental::optional<int> o { std::experimental::in_place }; + VERIFY( o ); + VERIFY( *o == int() ); + + static_assert( !std::is_convertible<std::experimental::in_place_t, std::experimental::optional<int>>(), "" ); + } + + { + std::experimental::optional<int> o { std::experimental::in_place, 42 }; + VERIFY( o ); + VERIFY( *o == 42 ); + } + + { + std::experimental::optional<std::vector<int>> o { std::experimental::in_place, 18, 4 }; + VERIFY( o ); + VERIFY( o->size() == 18 ); + VERIFY( (*o)[17] == 4 ); + } + + { + std::experimental::optional<std::vector<int>> o { std::experimental::in_place, { 18, 4 } }; + VERIFY( o ); + VERIFY( o->size() == 2 ); + VERIFY( (*o)[0] == 18 ); + } + + { + std::experimental::optional<std::vector<int>> o { std::experimental::in_place, { 18, 4 }, std::allocator<int> {} }; + VERIFY( o ); + VERIFY( o->size() == 2 ); + VERIFY( (*o)[0] == 18 ); + } +} diff --git a/libstdc++-v3/testsuite/experimental/optional/make_optional.cc b/libstdc++-v3/testsuite/experimental/optional/make_optional.cc new file mode 100644 index 0000000..90ebe6c --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/make_optional.cc @@ -0,0 +1,31 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do run } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +int main() +{ + const int i = 42; + auto o = std::experimental::make_optional(i); + static_assert( std::is_same<decltype(o), std::experimental::optional<int>>(), "" ); + VERIFY( o && *o == 42 ); + VERIFY( &*o != &i ); +} diff --git a/libstdc++-v3/testsuite/experimental/optional/nullopt.cc b/libstdc++-v3/testsuite/experimental/optional/nullopt.cc new file mode 100644 index 0000000..f1b1bb6 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/nullopt.cc @@ -0,0 +1,46 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do run } + +// Copyright (C) 2013 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 +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +int main() +{ + // [20.5.6] Disengaged state indicator + static_assert( std::is_same<decltype(std::experimental::nullopt), const std::experimental::nullopt_t>(), "" ); + static_assert( std::is_empty<std::experimental::nullopt_t>(), "" ); + static_assert( std::is_literal_type<std::experimental::nullopt_t>(), "" ); + static_assert( !std::is_default_constructible<std::experimental::nullopt_t>(), "" ); + + { + std::experimental::optional<int> o = std::experimental::nullopt; + VERIFY( !o ); + } + + { + std::experimental::optional<int> o = { std::experimental::nullopt }; + VERIFY( !o ); + } + + { + std::experimental::optional<int> o { std::experimental::nullopt }; + VERIFY( !o ); + } +} diff --git a/libstdc++-v3/testsuite/experimental/optional/observers/1.cc b/libstdc++-v3/testsuite/experimental/optional/observers/1.cc new file mode 100644 index 0000000..5ffa3a5 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/observers/1.cc @@ -0,0 +1,33 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do run } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +struct value_type +{ + int i; +}; + +int main() +{ + std::experimental::optional<value_type> o { value_type { 51 } }; + VERIFY( (*o).i == 51 ); +} diff --git a/libstdc++-v3/testsuite/experimental/optional/observers/2.cc b/libstdc++-v3/testsuite/experimental/optional/observers/2.cc new file mode 100644 index 0000000..444a141 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/observers/2.cc @@ -0,0 +1,35 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do run } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +struct value_type +{ + int i; +}; + +int main() +{ + std::experimental::optional<value_type> o { value_type { 51 } }; + VERIFY( o->i == 51 ); + VERIFY( o->i == (*o).i ); + VERIFY( &o->i == &(*o).i ); +} diff --git a/libstdc++-v3/testsuite/experimental/optional/observers/3.cc b/libstdc++-v3/testsuite/experimental/optional/observers/3.cc new file mode 100644 index 0000000..b82142d --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/observers/3.cc @@ -0,0 +1,58 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do run } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +struct value_type +{ + int i; +}; + +int main() +{ + { + std::experimental::optional<value_type> o { value_type { 51 } }; + VERIFY( o.value().i == 51 ); + VERIFY( o.value().i == (*o).i ); + VERIFY( &o.value().i == &(*o).i ); + } + + { + enum outcome_type { nothrow, caught, bad_catch }; + + outcome_type outcome {}; + std::experimental::optional<value_type> o = std::experimental::nullopt; + bool called = false; + auto const eat = [&called](int) { called = true; }; + + try + { + eat(o.value().i); + } + catch(std::experimental::bad_optional_access const&) + { outcome = caught; } + catch(...) + { outcome = bad_catch; } + + VERIFY( outcome == caught ); + VERIFY( !called ); + } +} diff --git a/libstdc++-v3/testsuite/experimental/optional/observers/4.cc b/libstdc++-v3/testsuite/experimental/optional/observers/4.cc new file mode 100644 index 0000000..3b43c77 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/observers/4.cc @@ -0,0 +1,35 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do run } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +struct value_type +{ + int i; +}; + +int main() +{ + std::experimental::optional<value_type> o { value_type { 51 } }; + value_type fallback { 3 }; + VERIFY( o.value_or(fallback).i == 51 ); + VERIFY( o.value_or(fallback).i == (*o).i ); +} diff --git a/libstdc++-v3/testsuite/experimental/optional/observers/5.cc b/libstdc++-v3/testsuite/experimental/optional/observers/5.cc new file mode 100644 index 0000000..c6957ec --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/observers/5.cc @@ -0,0 +1,40 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do run } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +struct value_type +{ + int i; +}; + +int main() +{ + { + std::experimental::optional<value_type> o = std::experimental::nullopt; + VERIFY( !o ); + } + + { + std::experimental::optional<value_type> o { value_type { 51 } }; + VERIFY( o ); + } +} diff --git a/libstdc++-v3/testsuite/experimental/optional/relops/1.cc b/libstdc++-v3/testsuite/experimental/optional/relops/1.cc new file mode 100644 index 0000000..6f0c60f --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/relops/1.cc @@ -0,0 +1,89 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do run } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +#include <tuple> +#include <string> + +namespace ns +{ + struct value_type + { + int i; + std::string s; + }; + + bool + operator==(value_type const& lhs, value_type const& rhs) + { return std::tie(lhs.i, lhs.s) == std::tie(rhs.i, rhs.s); } + + bool + operator!=(value_type const& lhs, value_type const& rhs) + { return !(lhs == rhs); } + + bool + operator<(value_type const& lhs, value_type const& rhs) + { return std::tie(lhs.i, lhs.s) < std::tie(rhs.i, rhs.s); } + +} // namespace ns + +int main() +{ + using ns::value_type; + using O = std::experimental::optional<value_type>; + + { + O o, p; + VERIFY( o == p ); + VERIFY( !(o != p) ); + } + + { + O o { value_type { 42, "forty-two" } }, p; + VERIFY( !(o == p) ); + VERIFY( o != p ); + } + + { + O o, p { value_type { 42, "forty-two" } }; + VERIFY( !(o == p) ); + VERIFY( o != p ); + } + + { + O o { value_type { 11, "eleventy" } }, p { value_type { 42, "forty-two" } }; + VERIFY( !(o == p) ); + VERIFY( o != p ); + } + + { + O o { value_type { 42, "forty-two" } }, p { value_type { 11, "eleventy" } }; + VERIFY( !(o == p) ); + VERIFY( o != p ); + } + + { + O o { value_type { 42, "forty-two" } }, p { value_type { 42, "forty-two" } }; + VERIFY( o == p ); + VERIFY( !(o != p) ); + } +} diff --git a/libstdc++-v3/testsuite/experimental/optional/relops/2.cc b/libstdc++-v3/testsuite/experimental/optional/relops/2.cc new file mode 100644 index 0000000..b1ae705 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/relops/2.cc @@ -0,0 +1,101 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do run } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +#include <tuple> +#include <string> + +namespace ns +{ + struct value_type + { + int i; + std::string s; + }; + + bool + operator==(value_type const& lhs, value_type const& rhs) + { return std::tie(lhs.i, lhs.s) == std::tie(rhs.i, rhs.s); } + + bool + operator!=(value_type const& lhs, value_type const& rhs) + { return !(lhs == rhs); } + + bool + operator<(value_type const& lhs, value_type const& rhs) + { return std::tie(lhs.i, lhs.s) < std::tie(rhs.i, rhs.s); } + +} // namespace ns + +int main() +{ + using ns::value_type; + using O = std::experimental::optional<value_type>; + + { + O o, p; + VERIFY( !(o < p) ); + VERIFY( !(o > p) ); + VERIFY( o <= p ); + VERIFY( o >= p ); + } + + { + O o { value_type { 42, "forty-two" } }, p; + VERIFY( !(o < p) ); + VERIFY( o > p ); + VERIFY( !(o <= p) ); + VERIFY( o >= p ); + } + + { + O o, p { value_type { 42, "forty-two" } }; + VERIFY( o < p ); + VERIFY( !(o > p) ); + VERIFY( o <= p ); + VERIFY( !(o >= p) ); + } + + { + O o { value_type { 11, "eleventy" } }, p { value_type { 42, "forty-two" } }; + VERIFY( o < p ); + VERIFY( !(o > p) ); + VERIFY( o <= p ); + VERIFY( !(o >= p) ); + } + + { + O o { value_type { 42, "forty-two" } }, p { value_type { 11, "eleventy" } }; + VERIFY( !(o < p) ); + VERIFY( o > p ); + VERIFY( !(o <= p) ); + VERIFY( o >= p ); + } + + { + O o { value_type { 42, "forty-two" } }, p { value_type { 42, "forty-two" } }; + VERIFY( !(o < p) ); + VERIFY( !(o > p) ); + VERIFY( o <= p ); + VERIFY( o >= p ); + } +} diff --git a/libstdc++-v3/testsuite/experimental/optional/relops/3.cc b/libstdc++-v3/testsuite/experimental/optional/relops/3.cc new file mode 100644 index 0000000..6b361df --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/relops/3.cc @@ -0,0 +1,79 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do run } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +#include <tuple> +#include <string> + +namespace ns +{ + struct value_type + { + int i; + std::string s; + }; + + bool + operator==(value_type const& lhs, value_type const& rhs) + { return std::tie(lhs.i, lhs.s) == std::tie(rhs.i, rhs.s); } + + bool + operator!=(value_type const& lhs, value_type const& rhs) + { return !(lhs == rhs); } + + bool + operator<(value_type const& lhs, value_type const& rhs) + { return std::tie(lhs.i, lhs.s) < std::tie(rhs.i, rhs.s); } + +} // namespace ns + +int main() +{ + using ns::value_type; + using O = std::experimental::optional<value_type>; + + value_type const reference { 42, "forty-two" }; + + { + O o; + VERIFY( !(o == reference) ); + VERIFY( !(reference == o) ); + VERIFY( o != reference ); + VERIFY( reference != o ); + } + + { + O o { value_type { 11, "eleventy" } }; + VERIFY( !(o == reference) ); + VERIFY( !(reference == o) ); + VERIFY( o != reference ); + VERIFY( reference != o ); + } + + { + O o { value_type { 42, "forty-two" } }; + VERIFY( o == reference ); + VERIFY( reference == o ); + VERIFY( !(o != reference) ); + VERIFY( !(reference != o) ); + } +} diff --git a/libstdc++-v3/testsuite/experimental/optional/relops/4.cc b/libstdc++-v3/testsuite/experimental/optional/relops/4.cc new file mode 100644 index 0000000..9f316f1 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/relops/4.cc @@ -0,0 +1,91 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do run } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +#include <tuple> +#include <string> + +namespace ns +{ + struct value_type + { + int i; + std::string s; + }; + + bool + operator==(value_type const& lhs, value_type const& rhs) + { return std::tie(lhs.i, lhs.s) == std::tie(rhs.i, rhs.s); } + + bool + operator!=(value_type const& lhs, value_type const& rhs) + { return !(lhs == rhs); } + + bool + operator<(value_type const& lhs, value_type const& rhs) + { return std::tie(lhs.i, lhs.s) < std::tie(rhs.i, rhs.s); } + +} // namespace ns + +int main() +{ + using ns::value_type; + using O = std::experimental::optional<value_type>; + + value_type const reference { 42, "forty-two" }; + + { + O o; + VERIFY( o < reference ); + VERIFY( !(reference < o) ); + VERIFY( !(o > reference) ); + VERIFY( reference > o ); + VERIFY( o <= reference ); + VERIFY( !(reference <= o) ); + VERIFY( !(o >= reference) ); + VERIFY( reference >= o ); + } + + { + O o { value_type { 11, "eleventy" } }; + VERIFY( o < reference ); + VERIFY( !(reference < o) ); + VERIFY( !(o > reference) ); + VERIFY( reference > o ); + VERIFY( o <= reference ); + VERIFY( !(reference <= o) ); + VERIFY( !(o >= reference) ); + VERIFY( reference >= o ); + } + + { + O o { value_type { 42, "forty-two" } }; + VERIFY( !(o < reference) ); + VERIFY( !(reference < o) ); + VERIFY( !(o > reference) ); + VERIFY( !(reference > o) ); + VERIFY( o <= reference ); + VERIFY( reference <= o ); + VERIFY( o >= reference ); + VERIFY( reference >= o ); + } +} diff --git a/libstdc++-v3/testsuite/experimental/optional/relops/5.cc b/libstdc++-v3/testsuite/experimental/optional/relops/5.cc new file mode 100644 index 0000000..c7b27bb --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/relops/5.cc @@ -0,0 +1,70 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do run } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +#include <tuple> +#include <string> + +namespace ns +{ + struct value_type + { + int i; + std::string s; + }; + + bool + operator==(value_type const& lhs, value_type const& rhs) + { return std::tie(lhs.i, lhs.s) == std::tie(rhs.i, rhs.s); } + + bool + operator!=(value_type const& lhs, value_type const& rhs) + { return !(lhs == rhs); } + + bool + operator<(value_type const& lhs, value_type const& rhs) + { return std::tie(lhs.i, lhs.s) < std::tie(rhs.i, rhs.s); } + +} // namespace ns + +int main() +{ + using ns::value_type; + using O = std::experimental::optional<value_type>; + using std::experimental::nullopt; + + { + O o; + VERIFY( o == nullopt ); + VERIFY( nullopt == o ); + VERIFY( !(o != nullopt) ); + VERIFY( !(nullopt != o) ); + } + + { + O o { std::experimental::in_place }; + VERIFY( !(o == nullopt) ); + VERIFY( !(nullopt == o) ); + VERIFY( o != nullopt ); + VERIFY( nullopt != o ); + } +} diff --git a/libstdc++-v3/testsuite/experimental/optional/relops/6.cc b/libstdc++-v3/testsuite/experimental/optional/relops/6.cc new file mode 100644 index 0000000..d8a4f6f --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/relops/6.cc @@ -0,0 +1,78 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do run } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +#include <tuple> +#include <string> + +namespace ns +{ + struct value_type + { + int i; + std::string s; + }; + + bool + operator==(value_type const& lhs, value_type const& rhs) + { return std::tie(lhs.i, lhs.s) == std::tie(rhs.i, rhs.s); } + + bool + operator!=(value_type const& lhs, value_type const& rhs) + { return !(lhs == rhs); } + + bool + operator<(value_type const& lhs, value_type const& rhs) + { return std::tie(lhs.i, lhs.s) < std::tie(rhs.i, rhs.s); } + +} // namespace ns + +int main() +{ + using ns::value_type; + using O = std::experimental::optional<value_type>; + using std::experimental::nullopt; + + { + O o; + VERIFY( !(o < nullopt) ); + VERIFY( !(nullopt < o) ); + VERIFY( !(o > nullopt) ); + VERIFY( !(nullopt > o) ); + VERIFY( o <= nullopt ); + VERIFY( nullopt <= o ); + VERIFY( o >= nullopt ); + VERIFY( nullopt >= o ); + } + + { + O o { std::experimental::in_place }; + VERIFY( !(o < nullopt) ); + VERIFY( nullopt < o ); + VERIFY( o > nullopt ); + VERIFY( !(nullopt > o) ); + VERIFY( !(o <= nullopt) ); + VERIFY( nullopt <= o ); + VERIFY( o >= nullopt ); + VERIFY( !(nullopt >= o) ); + } +} diff --git a/libstdc++-v3/testsuite/experimental/optional/requirements.cc b/libstdc++-v3/testsuite/experimental/optional/requirements.cc new file mode 100644 index 0000000..c97cde5 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/requirements.cc @@ -0,0 +1,256 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do run } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +#include <tuple> + +struct trivially_destructible +{ + trivially_destructible() = delete; + trivially_destructible(trivially_destructible const&) = delete; + trivially_destructible& operator=(trivially_destructible const&) = delete; + trivially_destructible(trivially_destructible&&) = delete; + trivially_destructible& operator=(trivially_destructible&&) = delete; + ~trivially_destructible() noexcept = default; +}; + +static_assert( std::is_trivially_destructible<trivially_destructible>(), "" ); + +struct no_default_constructor +{ + no_default_constructor() = delete; +}; + +struct no_copy_constructor +{ + no_copy_constructor() = default; + no_copy_constructor(no_copy_constructor const&) = delete; + no_copy_constructor& operator=(no_copy_constructor const&) = default; + no_copy_constructor(no_copy_constructor&&) = default; + no_copy_constructor& operator=(no_copy_constructor&&) = default; +}; + +struct no_copy_assignment +{ + no_copy_assignment() = default; + no_copy_assignment(no_copy_assignment const&) = default; + no_copy_assignment(no_copy_assignment&&) = default; + no_copy_assignment& operator=(no_copy_assignment&&) = default; +}; + +struct no_move_constructor +{ + no_move_constructor() = default; + no_move_constructor(no_move_constructor const&) = default; + no_move_constructor& operator=(no_move_constructor const&) = default; + no_move_constructor(no_move_constructor&&) = delete; + no_move_constructor& operator=(no_move_constructor&&) = default; +}; + +struct no_move_assignment +{ + no_move_assignment() = default; + no_move_assignment(no_move_assignment const&) = default; + no_move_assignment& operator=(no_move_assignment const&) = default; + no_move_assignment(no_move_assignment&&) = default; + no_move_assignment& operator=(no_move_assignment&&) = delete; +}; + +struct no_copy : no_copy_constructor, no_copy_assignment { }; +struct no_move : no_move_constructor, no_move_assignment { }; + +// Laxest possible model of a value type for optional +struct only_destructible +{ + only_destructible(only_destructible&&) = delete; +}; + +int main() +{ + { + static_assert( std::is_trivially_destructible<std::experimental::optional<trivially_destructible>>(), "" ); + } + + { + using T = no_default_constructor; + using O = std::experimental::optional<T>; + static_assert( std::is_same<O::value_type, T>(), "" ); + static_assert( std::is_default_constructible<O>(), "" ); + { O o; } + static_assert( std::is_copy_constructible<O>(), "" ); + { O o; auto copy = o; } + static_assert( std::is_copy_assignable<O>(), "" ); + { O o, p; p = o; } + static_assert( std::is_move_constructible<O>(), "" ); + { O o; auto moved_to = std::move(o); } + static_assert( std::is_move_assignable<O>(), "" ); + { O o, p; p = std::move(o); } + } + + { + using T = no_copy_constructor; + using O = std::experimental::optional<T>; + static_assert( std::is_same<O::value_type, T>(), "" ); + static_assert( std::is_default_constructible<O>(), "" ); + { O o; } + static_assert( !std::is_copy_constructible<O>(), "" ); + static_assert( !std::is_copy_assignable<O>(), "" ); + static_assert( std::is_move_constructible<O>(), "" ); + { O o; auto moved_to = std::move(o); } + static_assert( std::is_move_assignable<O>(), "" ); + { O o, p; p = std::move(o); } + } + + { + using T = no_copy_assignment; + using O = std::experimental::optional<T>; + static_assert( std::is_default_constructible<O>(), "" ); + { O o; } + static_assert( std::is_copy_constructible<O>(), "" ); + { O o; auto copy = o; } + static_assert( !std::is_copy_assignable<O>(), "" ); + static_assert( std::is_move_constructible<O>(), "" ); + { O o; auto moved_to = std::move(o); } + static_assert( std::is_move_assignable<O>(), "" ); + { O o, p; p = std::move(o); } + } + + { + using T = no_copy; + using O = std::experimental::optional<T>; + static_assert( std::is_same<O::value_type, T>(), "" ); + static_assert( std::is_default_constructible<O>(), "" ); + { O o; } + static_assert( !std::is_copy_constructible<O>(), "" ); + static_assert( !std::is_copy_assignable<O>(), "" ); + static_assert( std::is_move_constructible<O>(), "" ); + { O o; auto moved_to = std::move(o); } + static_assert( std::is_move_assignable<O>(), "" ); + { O o, p; p = std::move(o); } + } + + { + using T = no_move_constructor; + using O = std::experimental::optional<T>; + static_assert( std::is_same<O::value_type, T>(), "" ); + static_assert( std::is_default_constructible<O>(), "" ); + { O o; } + static_assert( std::is_copy_constructible<O>(), "" ); + { O o; auto copy = o; } + static_assert( std::is_copy_assignable<O>(), "" ); + /* + * T should be move constructible due to [12.8/11], which is a new rule in C++1y + * not yet implemented by GCC. Because there is already a special exception in C++11 + * for the generation of the special members that GCC implements (at least some of the + * time), this does not affect the std::experimental::optional implementation however. So the assertion + * for T should be changed (or removed altogether) when the time comes, but the rest + * should however remain correct and unchanged. + */ + static_assert( !std::is_move_constructible<T>(), "" ); + static_assert( std::is_move_constructible<O>(), "" ); + { O o; auto moved_to = std::move(o); } + static_assert( std::is_move_assignable<O>(), "" ); + { O o, p; p = std::move(o); } + } + + { + using T = no_move_assignment; + using O = std::experimental::optional<T>; + static_assert( std::is_same<O::value_type, T>(), "" ); + static_assert( std::is_default_constructible<O>(), "" ); + { O o; } + static_assert( std::is_copy_constructible<O>(), "" ); + { O o; auto copy = o; } + static_assert( std::is_copy_assignable<O>(), "" ); + { O o, p; p = o; } + static_assert( std::is_move_constructible<O>(), "" ); + { O o; auto moved_to = std::move(o); } + /* + * Paragraph 23 of same leads to a similar situation but with respect to move + * assignment. + */ + static_assert( !std::is_move_assignable<T>(), "" ); + static_assert( std::is_move_assignable<O>(), "" ); + { O o, p; p = std::move(o); } + } + + { + using T = no_move; + using O = std::experimental::optional<T>; + static_assert( std::is_same<O::value_type, T>(), "" ); + static_assert( std::is_default_constructible<O>(), "" ); + { O o; } + static_assert( std::is_copy_constructible<O>(), "" ); + { O o; auto copy = o; } + static_assert( std::is_copy_assignable<O>(), "" ); + { O o, p; p = o; } + static_assert( std::is_move_constructible<O>(), "" ); + { O o; auto moved_to = std::move(o); } + static_assert( std::is_move_assignable<O>(), "" ); + { O o, p; p = std::move(o); } + } + + { + using T = only_destructible; + using O = std::experimental::optional<T>; + static_assert( std::is_same<O::value_type, T>(), "" ); + static_assert( std::is_default_constructible<O>(), "" ); + { O o; } + static_assert( !std::is_copy_constructible<O>(), "" ); + static_assert( !std::is_copy_assignable<O>(), "" ); + static_assert( !std::is_move_constructible<O>(), "" ); + static_assert( !std::is_move_assignable<O>(), "" ); + } + + { + /* + * Should not complain about 'invalid' specializations as long as + * they're not instantiated. + */ + using A = std::experimental::optional<int&>; + using B = std::experimental::optional<int&&>; + using C1 = std::experimental::optional<std::experimental::in_place_t>; + using C2 = std::experimental::optional<std::experimental::in_place_t const>; + using C3 = std::experimental::optional<std::experimental::in_place_t volatile>; + using C4 = std::experimental::optional<std::experimental::in_place_t const volatile>; + using D1 = std::experimental::optional<std::experimental::nullopt_t>; + using D2 = std::experimental::optional<std::experimental::nullopt_t const>; + using D3 = std::experimental::optional<std::experimental::nullopt_t volatile>; + using D4 = std::experimental::optional<std::experimental::nullopt_t const volatile>; + + using X = std::tuple<A, B, C1, C2, C3, C4, D1, D2, D3, D4>; + } + + { + std::experimental::optional<const int> o { 42 }; + static_assert( std::is_same<decltype(o)::value_type, const int>(), "" ); + VERIFY( o ); + VERIFY( *o == 42 ); + } + + { + constexpr std::experimental::optional<const int> o { 33 }; + static_assert( std::is_same<decltype(o)::value_type, const int>(), "" ); + static_assert( o, "" ); + static_assert( *o == 33, "" ); + } +} diff --git a/libstdc++-v3/testsuite/experimental/optional/swap/1.cc b/libstdc++-v3/testsuite/experimental/optional/swap/1.cc new file mode 100644 index 0000000..95235b3 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/swap/1.cc @@ -0,0 +1,95 @@ +// { dg-options "-std=gnu++1y" } +// { dg-do run } + +// Copyright (C) 2013 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/optional> +#include <testsuite_hooks.h> + +struct exception {}; + +int counter = 0; + +struct mixin_counter +{ + mixin_counter() { ++counter; } + mixin_counter(mixin_counter const&) { ++counter; } + ~mixin_counter() { --counter; } +}; + +namespace ns +{ + +struct value_type : private mixin_counter +{ + explicit value_type(int state) : state(state) { } + int state; +}; + +int swaps = 0; + +void +swap(value_type& lhs, value_type& rhs) +{ + ++swaps; + using std::swap; + swap(lhs.state, rhs.state); +} + +} // namespace ns + +int main() +{ + using O = std::experimental::optional<ns::value_type>; + + VERIFY( ns::swaps == 0 ); + + { + O o, p; + swap(o, p); + VERIFY( !o ); + VERIFY( !p ); + } + + { + O o { std::experimental::in_place, 45 }, p; + swap(o, p); + VERIFY( !o ); + VERIFY( p && p->state == 45 ); + } + + { + O o, p { std::experimental::in_place, 45 }; + swap(o, p); + VERIFY( o && o->state == 45 ); + VERIFY( !p ); + } + + { + O o { std::experimental::in_place, 167 }, p { std::experimental::in_place, 999 }; + VERIFY( ns::swaps == 0 ); + + swap(o, p); + + VERIFY( o && o->state == 999 ); + VERIFY( p && p->state == 167 ); + VERIFY( ns::swaps == 1 ); + } + + VERIFY( counter == 0 ); +} diff --git a/libstdc++-v3/testsuite/libstdc++-dg/conformance.exp b/libstdc++-v3/testsuite/libstdc++-dg/conformance.exp index 5e7ba3a..b6976fc 100644 --- a/libstdc++-v3/testsuite/libstdc++-dg/conformance.exp +++ b/libstdc++-v3/testsuite/libstdc++-dg/conformance.exp @@ -60,6 +60,7 @@ if {[info exists tests_file] && [file exists $tests_file]} { lappend subdirs "$srcdir/tr1" lappend subdirs "$srcdir/tr2" lappend subdirs "$srcdir/decimal" + lappend subdirs "$srcdir/experimental" verbose "subdirs are $subdirs" # Find all the tests. |