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
This commit is contained in:
Michael Brune 2013-11-01 21:08:39 +01:00 committed by Jonathan Wakely
parent a792026320
commit 2b5ab1e438
48 changed files with 4785 additions and 6 deletions

View File

@ -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.

View File

@ -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): ; @:

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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 );
}

View File

@ -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 );
}

View File

@ -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 );
}

View File

@ -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 );
}

View File

@ -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 );
}

View File

@ -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 );
}

View File

@ -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 );
}

View File

@ -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 );
}

View File

@ -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 );
}

View File

@ -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 );
}
}

View File

@ -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, "" );
}
}

View File

@ -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, "" );
}
}

View File

@ -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, "" );
}
}

View File

@ -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, "" );
}

View File

@ -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, "" );
}
}

View File

@ -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, "" );
}

View File

@ -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, "" );
}

View File

@ -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, "" );
}

View File

@ -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, "" );
}

View File

@ -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, "" );
}
}

View File

@ -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), "" );
}
}

View File

@ -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, "" );
}
}

View File

@ -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), "" );
}
}

View File

@ -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, "" );
}
}

View File

@ -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, "" );
}
}

View File

@ -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), "" );
}
}

View File

@ -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 );
}
}

View File

@ -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 );
}

View File

@ -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 );
}
}

View File

@ -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 );
}

View File

@ -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 );
}

View File

@ -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 );
}
}

View File

@ -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 );
}

View File

@ -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 );
}
}

View File

@ -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) );
}
}

View File

@ -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 );
}
}

View File

@ -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) );
}
}

View File

@ -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 );
}
}

View File

@ -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 );
}
}

View File

@ -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) );
}
}

View File

@ -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, "" );
}
}

View File

@ -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 );
}

View File

@ -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.