]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
enable_special_members.h: New.
authorMichael Brune <lucdanton@free.fr>
Fri, 1 Nov 2013 20:08:39 +0000 (21:08 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Fri, 1 Nov 2013 20:08:39 +0000 (20:08 +0000)
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

48 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/include/Makefile.am
libstdc++-v3/include/Makefile.in
libstdc++-v3/include/bits/enable_special_members.h [new file with mode: 0644]
libstdc++-v3/include/experimental/optional [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/assignment/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/assignment/2.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/assignment/3.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/assignment/4.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/assignment/5.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/assignment/6.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/cons/copy.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/cons/default.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/cons/move.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/cons/value.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/constexpr/cons/default.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/constexpr/cons/value.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/constexpr/in_place.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/constexpr/make_optional.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/constexpr/nullopt.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/constexpr/observers/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/constexpr/observers/2.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/constexpr/observers/3.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/constexpr/observers/4.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/constexpr/observers/5.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/constexpr/relops/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/constexpr/relops/2.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/constexpr/relops/3.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/constexpr/relops/4.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/constexpr/relops/5.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/constexpr/relops/6.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/in_place.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/make_optional.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/nullopt.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/observers/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/observers/2.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/observers/3.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/observers/4.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/observers/5.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/relops/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/relops/2.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/relops/3.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/relops/4.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/relops/5.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/relops/6.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/requirements.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/optional/swap/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/libstdc++-dg/conformance.exp

index a7b19ac97a747426a0fd3c972ddef8815e12fffb..f5129329636b76685dfa3d204cff99889e736b82 100644 (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.
index 0ddc8b51419f57ee7780f06786ec131ce2b0a098..505679af5ae092e0e5f0c81f20e2023704ac3057 100644 (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): ; @:
index a1fd1d39982da8520c33fae9cbcc752e4c5b0efe..1f5daba83f77915cb0461cf59dfbfd09ee7fd011 100644 (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.
diff --git a/libstdc++-v3/include/bits/enable_special_members.h b/libstdc++-v3/include/bits/enable_special_members.h
new file mode 100644 (file)
index 0000000..eb90037
--- /dev/null
@@ -0,0 +1,278 @@
+// <bits/enable_special_members.h> -*- C++ -*-
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/enable_special_members.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly.
+ */
+
+#ifndef _ENABLE_SPECIAL_MEMBERS_H
+#define _ENABLE_SPECIAL_MEMBERS_H 1
+
+#pragma GCC system_header
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+/**
+  * @brief A mixin helper to conditionally enable or disable the default
+  * constructor.
+  * @sa _Enable_special_members
+  */
+template<bool _Switch, typename _Tag = void>
+  struct _Enable_default_constructor { };
+
+
+/**
+  * @brief A mixin helper to conditionally enable or disable the default
+  * destructor.
+  * @sa _Enable_special_members
+  */
+template<bool _Switch, typename _Tag = void>
+  struct _Enable_destructor { };
+
+/**
+  * @brief A mixin helper to conditionally enable or disable the copy/move
+  * special members.
+  * @sa _Enable_special_members
+  */
+template<bool _Copy, bool _CopyAssignment,
+         bool _Move, bool _MoveAssignment,
+         typename _Tag = void>
+  struct _Enable_copy_move { };
+
+/**
+  * @brief A mixin helper to conditionally enable or disable the special
+  * members.
+  *
+  * The @c _Tag type parameter is to make mixin bases unique and thus avoid
+  * ambiguities.
+  */
+template<bool _Default, bool _Destructor,
+         bool _Copy, bool _CopyAssignment,
+         bool _Move, bool _MoveAssignment,
+         typename _Tag = void>
+  struct _Enable_special_members
+  : private _Enable_default_constructor<_Default, _Tag>,
+    private _Enable_destructor<_Destructor, _Tag>,
+    private _Enable_copy_move<_Copy, _CopyAssignment,
+                              _Move, _MoveAssignment,
+                              _Tag>
+  { };
+
+// Boilerplate follows.
+
+template<typename _Tag>
+  struct _Enable_default_constructor<false, _Tag>
+  { constexpr _Enable_default_constructor() noexcept = delete; };
+
+template<typename _Tag>
+  struct _Enable_destructor<false, _Tag>
+  { ~_Enable_destructor() noexcept = delete; };
+
+template<typename _Tag>
+  struct _Enable_copy_move<false, true, true, true, _Tag>
+  {
+    constexpr _Enable_copy_move() noexcept                          = default;
+    constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = delete;
+    constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = default;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move const&) noexcept                    = default;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move&&) noexcept                         = default;
+  };
+
+template<typename _Tag>
+  struct _Enable_copy_move<true, false, true, true, _Tag>
+  {
+    constexpr _Enable_copy_move() noexcept                          = default;
+    constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = default;
+    constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = default;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move const&) noexcept                    = delete;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move&&) noexcept                         = default;
+  };
+
+template<typename _Tag>
+  struct _Enable_copy_move<false, false, true, true, _Tag>
+  {
+    constexpr _Enable_copy_move() noexcept                          = default;
+    constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = delete;
+    constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = default;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move const&) noexcept                    = delete;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move&&) noexcept                         = default;
+  };
+
+template<typename _Tag>
+  struct _Enable_copy_move<true, true, false, true, _Tag>
+  {
+    constexpr _Enable_copy_move() noexcept                          = default;
+    constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = default;
+    constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = delete;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move const&) noexcept                    = default;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move&&) noexcept                         = default;
+  };
+
+template<typename _Tag>
+  struct _Enable_copy_move<false, true, false, true, _Tag>
+  {
+    constexpr _Enable_copy_move() noexcept                          = default;
+    constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = delete;
+    constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = delete;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move const&) noexcept                    = default;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move&&) noexcept                         = default;
+  };
+
+template<typename _Tag>
+  struct _Enable_copy_move<true, false, false, true, _Tag>
+  {
+    constexpr _Enable_copy_move() noexcept                          = default;
+    constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = default;
+    constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = delete;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move const&) noexcept                    = delete;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move&&) noexcept                         = default;
+  };
+
+template<typename _Tag>
+  struct _Enable_copy_move<false, false, false, true, _Tag>
+  {
+    constexpr _Enable_copy_move() noexcept                          = default;
+    constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = delete;
+    constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = delete;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move const&) noexcept                    = delete;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move&&) noexcept                         = default;
+  };
+
+template<typename _Tag>
+  struct _Enable_copy_move<true, true, true, false, _Tag>
+  {
+    constexpr _Enable_copy_move() noexcept                          = default;
+    constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = default;
+    constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = default;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move const&) noexcept                    = default;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move&&) noexcept                         = delete;
+  };
+
+template<typename _Tag>
+  struct _Enable_copy_move<false, true, true, false, _Tag>
+  {
+    constexpr _Enable_copy_move() noexcept                          = default;
+    constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = delete;
+    constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = default;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move const&) noexcept                    = default;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move&&) noexcept                         = delete;
+  };
+
+template<typename _Tag>
+  struct _Enable_copy_move<true, false, true, false, _Tag>
+  {
+    constexpr _Enable_copy_move() noexcept                          = default;
+    constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = default;
+    constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = default;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move const&) noexcept                    = delete;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move&&) noexcept                         = delete;
+  };
+
+template<typename _Tag>
+  struct _Enable_copy_move<false, false, true, false, _Tag>
+  {
+    constexpr _Enable_copy_move() noexcept                          = default;
+    constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = delete;
+    constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = default;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move const&) noexcept                    = delete;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move&&) noexcept                         = delete;
+  };
+
+template<typename _Tag>
+  struct _Enable_copy_move<true, true, false, false, _Tag>
+  {
+    constexpr _Enable_copy_move() noexcept                          = default;
+    constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = default;
+    constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = delete;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move const&) noexcept                    = default;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move&&) noexcept                         = delete;
+  };
+
+template<typename _Tag>
+  struct _Enable_copy_move<false, true, false, false, _Tag>
+  {
+    constexpr _Enable_copy_move() noexcept                          = default;
+    constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = delete;
+    constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = delete;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move const&) noexcept                    = default;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move&&) noexcept                         = delete;
+  };
+
+template<typename _Tag>
+  struct _Enable_copy_move<true, false, false, false, _Tag>
+  {
+    constexpr _Enable_copy_move() noexcept                          = default;
+    constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = default;
+    constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = delete;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move const&) noexcept                    = delete;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move&&) noexcept                         = delete;
+  };
+
+template<typename _Tag>
+  struct _Enable_copy_move<false, false, false, false, _Tag>
+  {
+    constexpr _Enable_copy_move() noexcept                          = default;
+    constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = delete;
+    constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = delete;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move const&) noexcept                    = delete;
+    _Enable_copy_move&
+    operator=(_Enable_copy_move&&) noexcept                         = delete;
+  };
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+
+#endif // _ENABLE_SPECIAL_MEMBERS_H
diff --git a/libstdc++-v3/include/experimental/optional b/libstdc++-v3/include/experimental/optional
new file mode 100644 (file)
index 0000000..5915892
--- /dev/null
@@ -0,0 +1,828 @@
+// <optional> -*- C++ -*-
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file experimental/optional
+ *  This is a TS C++ Library header.
+ */
+
+#ifndef _GLIBCXX_EXPERIMENTAL_OPTIONAL
+#define _GLIBCXX_EXPERIMENTAL_OPTIONAL 1
+
+/**
+ * @defgroup experimental Experimental
+ *
+ * Components specified by various Technical Specifications.
+ */
+
+#if __cplusplus <= 201103L
+# include <bits/c++14_warning.h>
+#else
+
+#include <utility>
+#include <type_traits>
+#include <stdexcept>
+#include <new>
+#include <initializer_list>
+#include <bits/functexcept.h>
+#include <bits/functional_hash.h>
+#include <bits/enable_special_members.h>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+namespace experimental
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  /**
+   * @defgroup optional Optional values
+   * @ingroup experimental
+   *
+   * Class template for optional values and surrounding facilities, as
+   * described in n3793 "A proposal to add a utility class to represent
+   * optional objects (Revision 5)".
+   *
+   * @{
+   */
+
+  // All subsequent [X.Y.n] references are against n3793.
+
+  // [X.Y.4]
+  template<typename _Tp>
+    class optional;
+
+  // [X.Y.5]
+  /// Tag type for in-place construction.
+  struct in_place_t { };
+
+  /// Tag for in-place construction.
+  constexpr in_place_t in_place { };
+
+  // [X.Y.6]
+  /// Tag type to disengage optional objects.
+  struct nullopt_t
+  {
+    // Do not user-declare default constructor at all for
+    // optional_value = {} syntax to work.
+    // nullopt_t() = delete;
+
+    // Used for constructing nullopt.
+    enum class _Construct { _Token };
+
+    // Must be constexpr for nullopt_t to be literal.
+    explicit constexpr nullopt_t(_Construct) { }
+  };
+
+  // [X.Y.6]
+  /// Tag to disengage optional objects.
+  constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token };
+
+  // [X.Y.7]
+  /**
+   *  @brief Exception class thrown when a disengaged optional object is
+   *  dereferenced.
+   *  @ingroup exceptions
+   */
+  class bad_optional_access : public logic_error
+  {
+  public:
+    // XXX Should not be inline
+    explicit bad_optional_access(const string& __arg) : logic_error(__arg) { }
+
+    explicit bad_optional_access(const char* __arg) : logic_error(__arg) { }
+
+    virtual ~bad_optional_access() noexcept = default;
+  };
+
+  void
+  __throw_bad_optional_access(const char*)
+  __attribute__((__noreturn__));
+
+  // XXX Does not belong here.
+  inline void
+  __throw_bad_optional_access(const char* __s)
+  { _GLIBCXX_THROW_OR_ABORT(bad_optional_access(__s)); }
+
+  template<typename _Tp, typename _Sfinae = void>
+    struct _Has_addressof_impl : std::false_type { };
+
+  template<typename _Tp>
+    struct _Has_addressof_impl<_Tp,
+      decltype( std::declval<const _Tp&>().operator&(), void() )>
+    : std::true_type { };
+
+  /**
+    * @brief Trait that detects the presence of an overloaded unary operator&.
+    *
+    * Practically speaking this detects the presence of such an operator when
+    * called on a const-qualified lvalue (i.e.
+    * declval<_Tp * const&>().operator&()).
+    */
+  template<typename _Tp>
+    struct _Has_addressof : _Has_addressof_impl<_Tp>::type { };
+
+  /**
+    * @brief An overload that attempts to take the address of an lvalue as a
+    * constant expression. Falls back to __addressof in the presence of an
+    * overloaded addressof operator (unary operator&), in which case the call
+    * will not be a constant expression.
+    */
+  template<typename _Tp, typename enable_if<!_Has_addressof<_Tp>::value,
+                                            int>::type...>
+    constexpr _Tp* __constexpr_addressof(_Tp& __t)
+    { return &__t; }
+
+  /**
+    * @brief Fallback overload that defers to __addressof.
+    */
+  template<typename _Tp, typename enable_if<_Has_addressof<_Tp>::value,
+                                            int>::type...>
+    _Tp* __constexpr_addressof(_Tp& __t)
+    { return std::__addressof(__t); }
+
+  /**
+    * @brief Class template that holds the necessary state for @ref optional
+    * and that has the responsibility for construction and the special members.
+    *
+    * Such a separate base class template is necessary in order to
+    * conditionally enable the special members (e.g. copy/move constructors).
+    * Note that this means that @ref _Optional_base implements the
+    * functionality for copy and move assignment, but not for converting
+    * assignment.
+    *
+    * @see optional, _Enable_special_members
+    */
+  template<typename _Tp, bool _ShouldProvideDestructor =
+          !is_trivially_destructible<_Tp>::value>
+    class _Optional_base
+    {
+    private:
+      // Remove const to avoid prohibition of reusing object storage for
+      // const-qualified types in [3.8/9]. This is strictly internal
+      // and even optional itself is oblivious to it.
+      using _Stored_type = typename remove_const<_Tp>::type;
+
+    public:
+      // [X.Y.4.1] Constructors.
+
+      // Constructors for disengaged optionals.
+      constexpr _Optional_base() noexcept
+      : _M_empty{} { }
+
+      constexpr _Optional_base(nullopt_t) noexcept
+      : _Optional_base{} { }
+
+      // Constructors for engaged optionals.
+      constexpr _Optional_base(const _Tp& __t)
+      : _M_payload(__t), _M_engaged(true) { }
+
+      constexpr _Optional_base(_Tp&& __t)
+      : _M_payload(std::move(__t)), _M_engaged(true) { }
+
+      template<typename... _Args>
+        constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
+        : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { }
+
+      template<typename _Up, typename... _Args,
+               typename enable_if<is_constructible<_Tp,
+                                                   initializer_list<_Up>&,
+                                                   _Args&&...>::value,
+                                  int>::type...>
+        constexpr explicit _Optional_base(in_place_t,
+                                          initializer_list<_Up> __il,
+                                          _Args&&... __args)
+        : _M_payload(__il, std::forward<_Args>(__args)...),
+          _M_engaged(true) { }
+
+      // Copy and move constructors.
+      _Optional_base(const _Optional_base& __other)
+      {
+        if (__other._M_engaged)
+          this->_M_construct(__other._M_get());
+      }
+
+      _Optional_base(_Optional_base&& __other)
+      noexcept(is_nothrow_move_constructible<_Tp>())
+      {
+        if (__other._M_engaged)
+          this->_M_construct(std::move(__other._M_get()));
+      }
+
+      // [X.Y.4.3] (partly) Assignment.
+      _Optional_base&
+      operator=(const _Optional_base& __other)
+      {
+        if (this->_M_engaged && __other._M_engaged)
+          this->_M_get() = __other._M_get();
+        else
+        {
+          if (__other._M_engaged)
+            this->_M_construct(__other._M_get());
+          else
+            this->_M_reset();
+        }
+
+        return *this;
+      }
+
+      _Optional_base&
+      operator=(_Optional_base&& __other)
+      noexcept(is_nothrow_move_constructible<_Tp>()
+               && is_nothrow_move_assignable<_Tp>())
+      {
+        if (this->_M_engaged && __other._M_engaged)
+          this->_M_get() = std::move(__other._M_get());
+        else
+        {
+          if (__other._M_engaged)
+            this->_M_construct(std::move(__other._M_get()));
+          else
+            this->_M_reset();
+        }
+
+        return *this;
+      }
+
+      // [X.Y.4.2] Destructor.
+      ~_Optional_base()
+      {
+        if (this->_M_engaged)
+          this->_M_payload.~_Stored_type();
+      }
+
+      // The following functionality is also needed by optional, hence the
+      // protected accessibility.
+    protected:
+      constexpr bool _M_is_engaged() const noexcept
+      { return this->_M_engaged; }
+
+      // The _M_get operations have _M_engaged as a precondition.
+      _Tp&
+      _M_get() noexcept
+      { return _M_payload; }
+
+      constexpr const _Tp&
+      _M_get() const noexcept
+      { return _M_payload; }
+
+      // The _M_construct operation has !_M_engaged as a precondition
+      // while _M_destruct has _M_engaged as a precondition.
+      template<typename... _Args>
+        void
+        _M_construct(_Args&&... __args)
+        noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
+        {
+          ::new (std::__addressof(this->_M_payload))
+            _Stored_type(std::forward<_Args>(__args)...);
+          this->_M_engaged = true;
+        }
+
+      void
+      _M_destruct()
+      {
+        this->_M_engaged = false;
+        this->_M_payload.~_Stored_type();
+      }
+
+      // _M_reset is a 'safe' operation with no precondition.
+      void
+      _M_reset()
+      {
+        if (this->_M_engaged)
+          this->_M_destruct();
+      }
+
+    private:
+      struct _Empty_byte { };
+      union {
+          _Empty_byte _M_empty;
+          _Stored_type _M_payload;
+      };
+      bool _M_engaged = false;
+    };
+
+  /// Partial specialization that is exactly identical to the primary template
+  /// save for not providing a destructor, to fulfill triviality requirements.
+  template<typename _Tp>
+    class _Optional_base<_Tp, false>
+    {
+    private:
+      using _Stored_type = typename remove_const<_Tp>::type;
+
+    public:
+      constexpr _Optional_base() noexcept
+      : _M_empty{} { }
+
+      constexpr _Optional_base(nullopt_t) noexcept
+      : _Optional_base{} { }
+
+      constexpr _Optional_base(const _Tp& __t)
+      : _M_payload(__t), _M_engaged(true) { }
+
+      constexpr _Optional_base(_Tp&& __t)
+      : _M_payload(std::move(__t)), _M_engaged(true) { }
+
+      template<typename... _Args>
+        constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
+        : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { }
+
+      template<typename _Up, typename... _Args,
+               typename enable_if<is_constructible<_Tp,
+                                                   initializer_list<_Up>&,
+                                                   _Args&&...>::value,
+                                  int>::type...>
+        constexpr explicit _Optional_base(in_place_t,
+                                          initializer_list<_Up> __il,
+                                          _Args&&... __args)
+        : _M_payload(__il, std::forward<_Args>(__args)...),
+          _M_engaged(true) { }
+
+      _Optional_base(const _Optional_base& __other)
+      {
+        if (__other._M_engaged)
+          this->_M_construct(__other._M_get());
+      }
+
+      _Optional_base(_Optional_base&& __other)
+      noexcept(is_nothrow_move_constructible<_Tp>())
+      {
+        if (__other._M_engaged)
+          this->_M_construct(std::move(__other._M_get()));
+      }
+
+      _Optional_base&
+      operator=(const _Optional_base& __other)
+      {
+        if (this->_M_engaged && __other._M_engaged)
+          this->_M_get() = __other._M_get();
+        else
+        {
+          if (__other._M_engaged)
+            this->_M_construct(__other._M_get());
+          else
+            this->_M_reset();
+        }
+
+        return *this;
+      }
+
+      _Optional_base&
+      operator=(_Optional_base&& __other)
+      noexcept(is_nothrow_move_constructible<_Tp>()
+               && is_nothrow_move_assignable<_Tp>())
+      {
+        if (this->_M_engaged && __other._M_engaged)
+          this->_M_get() = std::move(__other._M_get());
+        else
+        {
+          if (__other._M_engaged)
+            this->_M_construct(std::move(__other._M_get()));
+          else
+            this->_M_reset();
+        }
+
+        return *this;
+      }
+
+      // Sole difference
+      // ~_Optional_base() noexcept = default;
+
+    protected:
+      constexpr bool _M_is_engaged() const noexcept
+      { return this->_M_engaged; }
+
+      _Tp&
+      _M_get() noexcept
+      { return _M_payload; }
+
+      constexpr const _Tp&
+      _M_get() const noexcept
+      { return _M_payload; }
+
+      template<typename... _Args>
+        void
+        _M_construct(_Args&&... __args)
+        noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
+        {
+          ::new (std::__addressof(this->_M_payload))
+            _Stored_type(std::forward<_Args>(__args)...);
+          this->_M_engaged = true;
+        }
+
+      void
+      _M_destruct()
+      {
+        this->_M_engaged = false;
+        this->_M_payload.~_Stored_type();
+      }
+
+      void
+      _M_reset()
+      {
+        if (this->_M_engaged)
+          this->_M_destruct();
+      }
+
+    private:
+      struct _Empty_byte { };
+      union {
+          _Empty_byte _M_empty;
+          _Stored_type _M_payload;
+      };
+      bool _M_engaged = false;
+    };
+
+  /**
+    * @brief Class template for optional values.
+    */
+  template<typename _Tp>
+    class optional
+    : private _Optional_base<_Tp>,
+      private _Enable_copy_move<
+        // Copy constructor.
+        is_copy_constructible<_Tp>::value,
+        // Copy assignment.
+        is_copy_constructible<_Tp>::value
+        && is_copy_assignable<_Tp>::value,
+        // Move constructor.
+        is_move_constructible<_Tp>::value,
+        // Move assignment.
+        is_move_constructible<_Tp>::value
+        && is_move_assignable<_Tp>::value,
+        // Unique tag type.
+        optional<_Tp>>
+    {
+      static_assert(!is_same<typename remove_cv<_Tp>::type,
+                             nullopt_t>()
+                    && !is_same<typename remove_cv<_Tp>::type,
+                             in_place_t>()
+                    && !is_reference<_Tp>(),
+                    "Invalid instantiation of optional<T>.");
+
+    private:
+      using _Base = _Optional_base<_Tp>;
+
+    public:
+      using value_type = _Tp;
+
+      // _Optional_base has the responsibility for construction.
+      using _Base::_Base;
+
+      // [X.Y.4.3] (partly) Assignment.
+      optional&
+      operator=(nullopt_t) noexcept
+      {
+        this->_M_reset();
+        return *this;
+      }
+
+      template<typename _Up>
+        typename enable_if<
+                 is_same<_Tp, typename decay<_Up>::type>::value,
+                 optional&
+               >::type
+        operator=(_Up&& __u)
+        {
+          static_assert(is_constructible<_Tp, _Up>()
+                        && is_assignable<_Tp&, _Up>(),
+                        "Cannot assign to value type from argument.");
+
+          if (this->_M_is_engaged())
+            this->_M_get() = std::forward<_Up>(__u);
+          else
+            this->_M_construct(std::forward<_Up>(__u));
+
+          return *this;
+        }
+
+      template<typename... _Args>
+       void
+       emplace(_Args&&... __args)
+       {
+         static_assert(is_constructible<_Tp, _Args&&...>(),
+                       "Cannot emplace value type from arguments.");
+
+         this->_M_reset();
+         this->_M_construct(std::forward<_Args>(__args)...);
+       }
+
+      template<typename _Up, typename... _Args>
+        typename enable_if<
+                 is_constructible<_Tp,
+                                  initializer_list<_Up>&,
+                                  _Args&&...>::value
+               >::type
+       emplace(initializer_list<_Up> __il, _Args&&... __args)
+       {
+         this->_M_reset();
+         this->_M_construct(__il, std::forward<_Args>(__args)...);
+       }
+
+      // [X.Y.4.2] Destructor is implicit, implemented in _Optional_base.
+
+      // [X.Y.4.4] Swap.
+      void
+      swap(optional& __other)
+      noexcept(is_nothrow_move_constructible<_Tp>()
+               && noexcept(swap(declval<_Tp&>(), declval<_Tp&>())))
+      {
+        using std::swap;
+
+        if (this->_M_is_engaged() && __other._M_is_engaged())
+          swap(this->_M_get(), __other._M_get());
+        else if (this->_M_is_engaged())
+        {
+          __other._M_construct(std::move(this->_M_get()));
+          this->_M_destruct();
+        }
+        else if (__other._M_is_engaged())
+        {
+          this->_M_construct(std::move(__other._M_get()));
+          __other._M_destruct();
+        }
+      }
+
+      // [X.Y.4.5] Observers.
+      constexpr const _Tp*
+      operator->() const
+      { return __constexpr_addressof(this->_M_get()); }
+
+      _Tp*
+      operator->()
+      { return std::__addressof(this->_M_get()); }
+
+      constexpr const _Tp&
+      operator*() const
+      { return this->_M_get(); }
+
+      _Tp&
+      operator*()
+      { return this->_M_get(); }
+
+      constexpr explicit operator bool() const noexcept
+      { return this->_M_is_engaged(); }
+
+      constexpr const _Tp&
+      value() const
+      {
+        return this->_M_is_engaged() ?
+          this->_M_get() :
+          (__throw_bad_optional_access("Attempt to access value of a disengaged"
+                                       " optional object."),
+           this->_M_get());
+      }
+
+      _Tp&
+      value()
+      {
+        if (this->_M_is_engaged())
+          return this->_M_get();
+
+        __throw_bad_optional_access("Attempt to access value of a disengaged"
+                                    " optional object.");
+      }
+
+      template<typename _Up>
+       constexpr _Tp
+       value_or(_Up&& __u) const&
+       {
+         static_assert(is_copy_constructible<_Tp>()
+                       && is_convertible<_Up&&, _Tp>(),
+                       "Cannot return value.");
+
+         return this->_M_is_engaged() ?
+           this->_M_get() :
+           static_cast<_Tp>(std::forward<_Up>(__u));
+       }
+
+      template<typename _Up>
+       _Tp
+       value_or(_Up&& __u) &&
+       {
+         static_assert( is_move_constructible<_Tp>()
+                       && is_convertible<_Up&&, _Tp>(),
+                       "Cannot return value." );
+
+         return this->_M_is_engaged() ?
+           std::move(this->_M_get()) :
+           static_cast<_Tp>(std::forward<_Up>(__u));
+       }
+    };
+
+  // [X.Y.8] Comparisons between optional values.
+  template<typename _Tp>
+    constexpr bool
+    operator==(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
+    {
+      return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
+        && (!__lhs || *__lhs == *__rhs);
+    }
+
+  template<typename _Tp>
+    constexpr bool
+    operator!=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
+    { return !(__lhs == __rhs); }
+
+  template<typename _Tp>
+    constexpr bool
+    operator<(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
+    {
+      return static_cast<bool>(__rhs)
+        && (!__lhs || *__lhs < *__rhs);
+    }
+
+  template<typename _Tp>
+    constexpr bool
+    operator>(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
+    { return __rhs < __lhs; }
+
+  template<typename _Tp>
+    constexpr bool
+    operator<=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
+    { return !(__rhs < __lhs); }
+
+  template<typename _Tp>
+    constexpr bool
+    operator>=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
+    { return !(__lhs < __rhs); }
+
+  // [X.Y.9] Comparisons with nullopt.
+  template<typename _Tp>
+    constexpr bool
+    operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept
+    { return !__lhs; }
+
+  template<typename _Tp>
+    constexpr bool
+    operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept
+    { return !__rhs; }
+
+  template<typename _Tp>
+    constexpr bool
+    operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept
+    { return static_cast<bool>(__lhs); }
+
+  template<typename _Tp>
+    constexpr bool
+    operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept
+    { return static_cast<bool>(__rhs); }
+
+  template<typename _Tp>
+    constexpr bool
+    operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
+    { return false; }
+
+  template<typename _Tp>
+    constexpr bool
+    operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept
+    { return static_cast<bool>(__rhs); }
+
+  template<typename _Tp>
+    constexpr bool
+    operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept
+    { return static_cast<bool>(__lhs); }
+
+  template<typename _Tp>
+    constexpr bool
+    operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
+    { return false; }
+
+  template<typename _Tp>
+    constexpr bool
+    operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept
+    { return !__lhs; }
+
+  template<typename _Tp>
+    constexpr bool
+    operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
+    { return true; }
+
+  template<typename _Tp>
+    constexpr bool
+    operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
+    { return true; }
+
+  template<typename _Tp>
+    constexpr bool
+    operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept
+    { return !__rhs; }
+
+  // [X.Y.10] Comparisons with value type.
+  template<typename _Tp>
+    constexpr bool
+    operator==(const optional<_Tp>& __lhs, const _Tp& __rhs)
+    { return __lhs && *__lhs == __rhs; }
+
+  template<typename _Tp>
+    constexpr bool
+    operator==(const _Tp& __lhs, const optional<_Tp>& __rhs)
+    { return __rhs && __lhs == *__rhs; }
+
+  template<typename _Tp>
+    constexpr bool
+    operator!=(const optional<_Tp>& __lhs, _Tp const& __rhs)
+    { return !__lhs || *__lhs != __rhs; }
+
+  template<typename _Tp>
+    constexpr bool
+    operator!=(const _Tp& __lhs, const optional<_Tp>& __rhs)
+    { return !__rhs || __lhs != *__rhs; }
+
+  template<typename _Tp>
+    constexpr bool
+    operator<(const optional<_Tp>& __lhs, const _Tp& __rhs)
+    { return !__lhs || *__lhs < __rhs; }
+
+  template<typename _Tp>
+    constexpr bool
+    operator<(const _Tp& __lhs, const optional<_Tp>& __rhs)
+    { return __rhs && __lhs < *__rhs; }
+
+  template<typename _Tp>
+    constexpr bool
+    operator>(const optional<_Tp>& __lhs, const _Tp& __rhs)
+    { return __lhs && __rhs < *__lhs; }
+
+  template<typename _Tp>
+    constexpr bool
+    operator>(const _Tp& __lhs, const optional<_Tp>& __rhs)
+    { return !__rhs || *__rhs < __lhs; }
+
+  template<typename _Tp>
+    constexpr bool
+    operator<=(const optional<_Tp>& __lhs, const _Tp& __rhs)
+    { return !__lhs || !(__rhs < *__lhs); }
+
+  template<typename _Tp>
+    constexpr bool
+    operator<=(const _Tp& __lhs, const optional<_Tp>& __rhs)
+    { return __rhs && !(*__rhs < __lhs); }
+
+  template<typename _Tp>
+    constexpr bool
+    operator>=(const optional<_Tp>& __lhs, const _Tp& __rhs)
+    { return __lhs && !(*__lhs < __rhs); }
+
+  template<typename _Tp>
+    constexpr bool
+    operator>=(const _Tp& __lhs, const optional<_Tp>& __rhs)
+    { return !__rhs || !(__lhs < *__rhs); }
+
+  // [X.Y.11]
+  template<typename _Tp>
+    void
+    swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
+    noexcept(noexcept(__lhs.swap(__rhs)))
+    { __lhs.swap(__rhs); }
+
+  template<typename _Tp>
+    constexpr optional<typename decay<_Tp>::type>
+    make_optional(_Tp&& __t)
+    { return optional<typename decay<_Tp>::type> { std::forward<_Tp>(__t) }; }
+
+  // @} group optional
+_GLIBCXX_END_NAMESPACE_VERSION
+}
+
+  // [X.Y.12]
+  template<typename _Tp>
+    struct hash<experimental::optional<_Tp>>
+    {
+      using result_type = size_t;
+      using argument_type = experimental::optional<_Tp>;
+
+      size_t
+      operator()(const experimental::optional<_Tp>& __t) const
+      noexcept(noexcept(hash<_Tp> {}(*__t)))
+      {
+        // We pick an arbitrary hash for disengaged optionals which hopefully
+        // usual values of _Tp won't typically hash to.
+        constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333);
+        return __t ? hash<_Tp> {}(*__t) : __magic_disengaged_hash;
+      }
+    };
+}
+
+#endif // C++14
+
+#endif // _GLIBCXX_EXPERIMENTAL_OPTIONAL
diff --git a/libstdc++-v3/testsuite/experimental/optional/assignment/1.cc b/libstdc++-v3/testsuite/experimental/optional/assignment/1.cc
new file mode 100644 (file)
index 0000000..b09e0ac
--- /dev/null
@@ -0,0 +1,195 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do run }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+struct exception {};
+
+int counter = 0;
+
+struct mixin_counter
+{
+  mixin_counter() { ++counter; }
+  mixin_counter(mixin_counter const&) { ++counter; }
+  ~mixin_counter() { --counter; }
+};
+
+struct value_type : private mixin_counter
+{
+  enum state_type
+  {
+    zero,
+    moved_from,
+    throwing_construction,
+    throwing_copy,
+    throwing_copy_assignment,
+    throwing_move,
+    throwing_move_assignment,
+    threw,
+  };
+
+  value_type() = default;
+
+  explicit value_type(state_type state_)
+  : state(state_)
+  {
+    throw_if(throwing_construction);
+  }
+
+  value_type(value_type const& other)
+  : state(other.state)
+  {
+    throw_if(throwing_copy);
+  }
+
+  value_type&
+  operator=(value_type const& other)
+  {
+    state = other.state;
+    throw_if(throwing_copy_assignment);
+    return *this;
+  }
+
+  value_type(value_type&& other)
+  : state(other.state)
+  {
+    other.state = moved_from;
+    throw_if(throwing_move);
+  }
+
+  value_type&
+  operator=(value_type&& other)
+  {
+    state = other.state;
+    other.state = moved_from;
+    throw_if(throwing_move_assignment);
+    return *this;
+  }
+
+  void throw_if(state_type match)
+  {
+    if(state == match)
+    {
+      state = threw;
+      throw exception {};
+    }
+  }
+
+  state_type state = zero;
+};
+
+int main()
+{
+  using O = std::experimental::optional<value_type>;
+  using S = value_type::state_type;
+  auto const make = [](S s = S::zero) { return O { std::experimental::in_place, s }; };
+
+  enum outcome_type { nothrow, caught, bad_catch };
+
+  // Check copy/move assignment for disengaged optional
+
+  // From disengaged optional
+  {
+    O o;
+    VERIFY( !o );
+    O p;
+    o = p;
+    VERIFY( !o );
+    VERIFY( !p );
+  }
+
+  {
+    O o;
+    VERIFY( !o );
+    O p;
+    o = std::move(p);
+    VERIFY( !o );
+    VERIFY( !p );
+  }
+
+  {
+    O o;
+    VERIFY( !o );
+    o = {};
+    VERIFY( !o );
+  }
+
+  // From engaged optional
+  {
+    O o;
+    VERIFY( !o );
+    O p = make(S::throwing_copy_assignment);
+    o = p;
+    VERIFY( o && o->state == S::throwing_copy_assignment );
+    VERIFY( p && p->state == S::throwing_copy_assignment );
+  }
+
+  {
+    O o;
+    VERIFY( !o );
+    O p = make(S::throwing_move_assignment);
+    o = std::move(p);
+    VERIFY( o && o->state == S::throwing_move_assignment );
+    VERIFY( p && p->state == S::moved_from );
+  }
+
+  {
+    outcome_type outcome {};
+    O o;
+    VERIFY( !o );
+    O p = make(S::throwing_copy);
+
+    try
+    {
+      o = p;
+    }
+    catch(exception const&)
+    { outcome = caught; }
+    catch(...)
+    { outcome = bad_catch; }
+
+    VERIFY( outcome == caught );
+    VERIFY( !o );
+    VERIFY( p && p->state == S::throwing_copy );
+  }
+
+  {
+    outcome_type outcome {};
+    O o;
+    VERIFY( !o );
+    O p = make(S::throwing_move);
+
+    try
+    {
+      o = std::move(p);
+    }
+    catch(exception const&)
+    { outcome = caught; }
+    catch(...)
+    { outcome = bad_catch; }
+
+    VERIFY( outcome == caught );
+    VERIFY( !o );
+    VERIFY( p && p->state == S::moved_from );
+  }
+
+  VERIFY( counter == 0 );
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/assignment/2.cc b/libstdc++-v3/testsuite/experimental/optional/assignment/2.cc
new file mode 100644 (file)
index 0000000..7985fff
--- /dev/null
@@ -0,0 +1,193 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do run }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+struct exception {};
+
+int counter = 0;
+
+struct mixin_counter
+{
+  mixin_counter() { ++counter; }
+  mixin_counter(mixin_counter const&) { ++counter; }
+  ~mixin_counter() { --counter; }
+};
+
+struct value_type : private mixin_counter
+{
+  enum state_type
+  {
+    zero,
+    moved_from,
+    throwing_construction,
+    throwing_copy,
+    throwing_copy_assignment,
+    throwing_move,
+    throwing_move_assignment,
+    threw,
+  };
+
+  value_type() = default;
+
+  explicit value_type(state_type state_)
+  : state(state_)
+  {
+    throw_if(throwing_construction);
+  }
+
+  value_type(value_type const& other)
+  : state(other.state)
+  {
+    throw_if(throwing_copy);
+  }
+
+  value_type&
+  operator=(value_type const& other)
+  {
+    state = other.state;
+    throw_if(throwing_copy_assignment);
+    return *this;
+  }
+
+  value_type(value_type&& other)
+  : state(other.state)
+  {
+    other.state = moved_from;
+    throw_if(throwing_move);
+  }
+
+  value_type&
+  operator=(value_type&& other)
+  {
+    state = other.state;
+    other.state = moved_from;
+    throw_if(throwing_move_assignment);
+    return *this;
+  }
+
+  void throw_if(state_type match)
+  {
+    if(state == match)
+    {
+      state = threw;
+      throw exception {};
+    }
+  }
+
+  state_type state = zero;
+};
+
+int main()
+{
+  using O = std::experimental::optional<value_type>;
+  using S = value_type::state_type;
+  auto const make = [](S s = S::zero) { return O { std::experimental::in_place, s }; };
+
+  enum outcome_type { nothrow, caught, bad_catch };
+
+  // Check copy/move assignment for engaged optional
+
+  // From disengaged optional
+  {
+    O o = make(S::zero);
+    VERIFY( o );
+    O p;
+    o = p;
+    VERIFY( !o );
+    VERIFY( !p );
+  }
+
+  {
+    O o = make(S::zero);
+    VERIFY( o );
+    O p;
+    o = std::move(p);
+    VERIFY( !o );
+    VERIFY( !p );
+  }
+
+  {
+    O o = make(S::zero);
+    VERIFY( o );
+    o = {};
+    VERIFY( !o );
+  }
+
+  // From engaged optional
+  {
+    O o = make(S::zero);
+    VERIFY( o );
+    O p = make(S::throwing_copy);
+    o = p;
+    VERIFY( o && o->state == S::throwing_copy);
+    VERIFY( p && p->state == S::throwing_copy);
+  }
+
+  {
+    O o = make(S::zero);
+    VERIFY( o );
+    O p = make(S::throwing_move);
+    o = std::move(p);
+    VERIFY( o && o->state == S::throwing_move);
+    VERIFY( p && p->state == S::moved_from);
+  }
+
+  {
+    outcome_type outcome {};
+    O o = make(S::zero);
+    VERIFY( o );
+    O p = make(S::throwing_copy_assignment);
+
+    try
+    {
+      o = p;
+    }
+    catch(exception const&)
+    { outcome = caught; }
+    catch(...)
+    { outcome = bad_catch; }
+
+    VERIFY( o && o->state == S::threw);
+    VERIFY( p && p->state == S::throwing_copy_assignment);
+  }
+
+  {
+    outcome_type outcome {};
+    O o = make(S::zero);
+    VERIFY( o );
+    O p = make(S::throwing_move_assignment);
+
+    try
+    {
+      o = std::move(p);
+    }
+    catch(exception const&)
+    { outcome = caught; }
+    catch(...)
+    { outcome = bad_catch; }
+
+    VERIFY( o && o->state == S::threw);
+    VERIFY( p && p->state == S::moved_from);
+  }
+
+  VERIFY( counter == 0 );
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/assignment/3.cc b/libstdc++-v3/testsuite/experimental/optional/assignment/3.cc
new file mode 100644 (file)
index 0000000..d631886
--- /dev/null
@@ -0,0 +1,158 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do run }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+struct exception {};
+
+int counter = 0;
+
+struct mixin_counter
+{
+  mixin_counter() { ++counter; }
+  mixin_counter(mixin_counter const&) { ++counter; }
+  ~mixin_counter() { --counter; }
+};
+
+struct value_type : private mixin_counter
+{
+  enum state_type
+  {
+    zero,
+    moved_from,
+    throwing_construction,
+    throwing_copy,
+    throwing_copy_assignment,
+    throwing_move,
+    throwing_move_assignment,
+    threw,
+  };
+
+  value_type() = default;
+
+  explicit value_type(state_type state_)
+  : state(state_)
+  {
+    throw_if(throwing_construction);
+  }
+
+  value_type(value_type const& other)
+  : state(other.state)
+  {
+    throw_if(throwing_copy);
+  }
+
+  value_type&
+  operator=(value_type const& other)
+  {
+    state = other.state;
+    throw_if(throwing_copy_assignment);
+    return *this;
+  }
+
+  value_type(value_type&& other)
+  : state(other.state)
+  {
+    other.state = moved_from;
+    throw_if(throwing_move);
+  }
+
+  value_type&
+  operator=(value_type&& other)
+  {
+    state = other.state;
+    other.state = moved_from;
+    throw_if(throwing_move_assignment);
+    return *this;
+  }
+
+  void throw_if(state_type match)
+  {
+    if(state == match)
+    {
+      state = threw;
+      throw exception {};
+    }
+  }
+
+  state_type state = zero;
+};
+
+int main()
+{
+  using O = std::experimental::optional<value_type>;
+  using S = value_type::state_type;
+  auto const make = [](S s = S::zero) { return value_type { s }; };
+
+  enum outcome_type { nothrow, caught, bad_catch };
+
+  // Check value assignment for disengaged optional
+
+  {
+    O o;
+    value_type v = make(S::throwing_copy_assignment);
+    o = v;
+    VERIFY( o && o->state == S::throwing_copy_assignment );
+  }
+
+  {
+    O o;
+    value_type v = make(S::throwing_move_assignment);
+    o = std::move(v);
+    VERIFY( o && o->state == S::throwing_move_assignment );
+  }
+
+  {
+    outcome_type outcome {};
+    O o;
+    value_type v = make(S::throwing_copy);
+
+    try
+    {
+      o = v;
+    }
+    catch(exception const&)
+    { outcome = caught; }
+    catch(...)
+    { outcome = bad_catch; }
+
+    VERIFY( !o );
+  }
+
+  {
+    outcome_type outcome {};
+    O o;
+    value_type v = make(S::throwing_move);
+
+    try
+    {
+      o = std::move(v);
+    }
+    catch(exception const&)
+    { outcome = caught; }
+    catch(...)
+    { outcome = bad_catch; }
+
+    VERIFY( !o );
+  }
+
+  VERIFY( counter == 0 );
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/assignment/4.cc b/libstdc++-v3/testsuite/experimental/optional/assignment/4.cc
new file mode 100644 (file)
index 0000000..e5f1f16
--- /dev/null
@@ -0,0 +1,158 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do run }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+struct exception {};
+
+int counter = 0;
+
+struct mixin_counter
+{
+  mixin_counter() { ++counter; }
+  mixin_counter(mixin_counter const&) { ++counter; }
+  ~mixin_counter() { --counter; }
+};
+
+struct value_type : private mixin_counter
+{
+  enum state_type
+  {
+    zero,
+    moved_from,
+    throwing_construction,
+    throwing_copy,
+    throwing_copy_assignment,
+    throwing_move,
+    throwing_move_assignment,
+    threw,
+  };
+
+  value_type() = default;
+
+  explicit value_type(state_type state_)
+  : state(state_)
+  {
+    throw_if(throwing_construction);
+  }
+
+  value_type(value_type const& other)
+  : state(other.state)
+  {
+    throw_if(throwing_copy);
+  }
+
+  value_type&
+  operator=(value_type const& other)
+  {
+    state = other.state;
+    throw_if(throwing_copy_assignment);
+    return *this;
+  }
+
+  value_type(value_type&& other)
+  : state(other.state)
+  {
+    other.state = moved_from;
+    throw_if(throwing_move);
+  }
+
+  value_type&
+  operator=(value_type&& other)
+  {
+    state = other.state;
+    other.state = moved_from;
+    throw_if(throwing_move_assignment);
+    return *this;
+  }
+
+  void throw_if(state_type match)
+  {
+    if(state == match)
+    {
+      state = threw;
+      throw exception {};
+    }
+  }
+
+  state_type state = zero;
+};
+
+int main()
+{
+  using O = std::experimental::optional<value_type>;
+  using S = value_type::state_type;
+  auto const make = [](S s = S::zero) { return value_type { s }; };
+
+  enum outcome_type { nothrow, caught, bad_catch };
+
+  // Check value assignment for engaged optional
+
+  {
+    O o = make();
+    value_type v = make(S::throwing_copy);
+    o = v;
+    VERIFY( o && o->state == S::throwing_copy);
+  }
+
+  {
+    O o = make();
+    value_type v = make(S::throwing_move);
+    o = std::move(v);
+    VERIFY( o && o->state == S::throwing_move);
+  }
+
+  {
+    outcome_type outcome {};
+    O o = make();
+    value_type v = make(S::throwing_copy_assignment);
+
+    try
+    {
+      o = v;
+    }
+    catch(exception const&)
+    { outcome = caught; }
+    catch(...)
+    { outcome = bad_catch; }
+
+    VERIFY( o && o->state == S::threw );
+  }
+
+  {
+    outcome_type outcome {};
+    O o = make();
+    value_type v = make(S::throwing_move_assignment);
+
+    try
+    {
+      o = std::move(v);
+    }
+    catch(exception const&)
+    { outcome = caught; }
+    catch(...)
+    { outcome = bad_catch; }
+
+    VERIFY( o && o->state == S::threw );
+  }
+
+  VERIFY( counter == 0 );
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/assignment/5.cc b/libstdc++-v3/testsuite/experimental/optional/assignment/5.cc
new file mode 100644 (file)
index 0000000..d6e268f
--- /dev/null
@@ -0,0 +1,66 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do run }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+int counter = 0;
+
+struct mixin_counter
+{
+  mixin_counter() { ++counter; }
+  mixin_counter(mixin_counter const&) { ++counter; }
+  ~mixin_counter() { --counter; }
+};
+
+struct value_type : private mixin_counter { };
+
+int main()
+{
+  using O = std::experimental::optional<value_type>;
+
+  // Check std::experimental::nullopt_t and 'default' (= {}) assignment
+
+  {
+    O o;
+    o = std::experimental::nullopt;
+    VERIFY( !o );
+  }
+
+  {
+    O o { std::experimental::in_place };
+    o = std::experimental::nullopt;
+    VERIFY( !o );
+  }
+
+  {
+    O o;
+    o = {};
+    VERIFY( !o );
+  }
+
+  {
+    O o { std::experimental::in_place };
+    o = {};
+    VERIFY( !o );
+  }
+
+  VERIFY( counter == 0 );
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/assignment/6.cc b/libstdc++-v3/testsuite/experimental/optional/assignment/6.cc
new file mode 100644 (file)
index 0000000..55be89d
--- /dev/null
@@ -0,0 +1,83 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do run }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+int counter = 0;
+
+struct mixin_counter
+{
+  mixin_counter() { ++counter; }
+  mixin_counter(mixin_counter const&) { ++counter; }
+  ~mixin_counter() { --counter; }
+};
+
+struct value_type : private mixin_counter
+{
+  value_type() = default;
+  value_type(int) : state(1) { }
+  value_type(std::initializer_list<char>, const char*) : state(2) { }
+  int state = 0;
+};
+
+int main()
+{
+  using O = std::experimental::optional<value_type>;
+
+  // Check emplace
+
+  {
+    O o;
+    o.emplace();
+    VERIFY( o && o->state == 0 );
+  }
+  {
+    O o { std::experimental::in_place, 0 };
+    o.emplace();
+    VERIFY( o && o->state == 0 );
+  }
+
+  {
+    O o;
+    o.emplace(0);
+    VERIFY( o && o->state == 1 );
+  }
+  {
+    O o { std::experimental::in_place };
+    o.emplace(0);
+    VERIFY( o && o->state == 1 );
+  }
+
+  {
+    O o;
+    o.emplace({ 'a' }, "");
+    VERIFY( o && o->state == 2 );
+  }
+  {
+    O o { std::experimental::in_place };
+    o.emplace({ 'a' }, "");
+    VERIFY( o && o->state == 2 );
+  }
+
+  static_assert( !std::is_constructible<O, std::initializer_list<int>, int>(), "" );
+
+  VERIFY( counter == 0 );
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/cons/copy.cc b/libstdc++-v3/testsuite/experimental/optional/cons/copy.cc
new file mode 100644 (file)
index 0000000..bbd9328
--- /dev/null
@@ -0,0 +1,125 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do run }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+struct tracker
+{
+  tracker(int value) : value(value) { ++count; }
+  ~tracker() { --count; }
+
+  tracker(tracker const& other) : value(other.value) { ++count; }
+  tracker(tracker&& other) : value(other.value)
+  {
+    other.value = -1;
+    ++count;
+  }
+
+  tracker& operator=(tracker const&) = default;
+  tracker& operator=(tracker&&) = default;
+
+  int value;
+
+  static int count;
+};
+
+int tracker::count = 0;
+
+struct exception { };
+
+struct throwing_copy
+{
+  throwing_copy() = default;
+  throwing_copy(throwing_copy const&) { throw exception {}; }
+};
+
+int main()
+{
+  // [20.5.4.1] Constructors
+
+  {
+    std::experimental::optional<long> o;
+    auto copy = o;
+    VERIFY( !copy );
+    VERIFY( !o );
+  }
+
+  {
+    std::experimental::optional<long> o { std::experimental::in_place, 0x1234ABCDF1E2D3C4 };
+    auto copy = o;
+    VERIFY( copy );
+    VERIFY( *copy == 0x1234ABCDF1E2D3C4 );
+    VERIFY( o && o == 0x1234ABCDF1E2D3C4 );
+  }
+
+  {
+    std::experimental::optional<tracker> o;
+    auto copy = o;
+    VERIFY( !copy );
+    VERIFY( tracker::count == 0 );
+    VERIFY( !o );
+  }
+
+  {
+    std::experimental::optional<tracker> o { std::experimental::in_place, 333 };
+    auto copy = o;
+    VERIFY( copy );
+    VERIFY( copy->value == 333 );
+    VERIFY( tracker::count == 2 );
+    VERIFY( o && o->value == 333 );
+  }
+
+  enum outcome { nothrow, caught, bad_catch };
+
+  {
+    outcome result = nothrow;
+    std::experimental::optional<throwing_copy> o;
+
+    try
+    {
+      auto copy = o;
+    }
+    catch(exception const&)
+    { result = caught; }
+    catch(...)
+    { result = bad_catch; }
+
+    VERIFY( result == nothrow );
+  }
+
+  {
+    outcome result = nothrow;
+    std::experimental::optional<throwing_copy> o { std::experimental::in_place };
+
+    try
+    {
+      auto copy = o;
+    }
+    catch(exception const&)
+    { result = caught; }
+    catch(...)
+    { result = bad_catch; }
+
+    VERIFY( result == caught );
+  }
+
+  VERIFY( tracker::count == 0 );
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/cons/default.cc b/libstdc++-v3/testsuite/experimental/optional/cons/default.cc
new file mode 100644 (file)
index 0000000..452f2d0
--- /dev/null
@@ -0,0 +1,60 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do run }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+struct tracker
+{
+  tracker() { ++count; }
+  ~tracker() { --count; }
+
+  tracker(tracker const&) { ++count; }
+  tracker(tracker&&) { ++count; }
+
+  tracker& operator=(tracker const&) = default;
+  tracker& operator=(tracker&&) = default;
+
+  static int count;
+};
+
+int tracker::count = 0;
+
+int main()
+{
+  // [20.5.4.1] Constructors
+
+  {
+    std::experimental::optional<tracker> o;
+    VERIFY( !o );
+  }
+
+  {
+    std::experimental::optional<tracker> o {};
+    VERIFY( !o );
+  }
+
+  {
+    std::experimental::optional<tracker> o = {};
+    VERIFY( !o );
+  }
+
+  VERIFY( tracker::count == 0 );
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/cons/move.cc b/libstdc++-v3/testsuite/experimental/optional/cons/move.cc
new file mode 100644 (file)
index 0000000..75d7677
--- /dev/null
@@ -0,0 +1,125 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do run }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+struct tracker
+{
+  tracker(int value) : value(value) { ++count; }
+  ~tracker() { --count; }
+
+  tracker(tracker const& other) : value(other.value) { ++count; }
+  tracker(tracker&& other) : value(other.value)
+  {
+    other.value = -1;
+    ++count;
+  }
+
+  tracker& operator=(tracker const&) = default;
+  tracker& operator=(tracker&&) = default;
+
+  int value;
+
+  static int count;
+};
+
+int tracker::count = 0;
+
+struct exception { };
+
+struct throwing_move
+{
+  throwing_move() = default;
+  throwing_move(throwing_move const&) { throw exception {}; }
+};
+
+int main()
+{
+  // [20.5.4.1] Constructors
+
+  {
+    std::experimental::optional<long> o;
+    auto moved_to = std::move(o);
+    VERIFY( !moved_to );
+    VERIFY( !o );
+  }
+
+  {
+    std::experimental::optional<long> o { std::experimental::in_place, 0x1234ABCDF1E2D3C4 };
+    auto moved_to = std::move(o);
+    VERIFY( moved_to );
+    VERIFY( *moved_to == 0x1234ABCDF1E2D3C4 );
+    VERIFY( o && *o == 0x1234ABCDF1E2D3C4 );
+  }
+
+  {
+    std::experimental::optional<tracker> o;
+    auto moved_to = std::move(o);
+    VERIFY( !moved_to );
+    VERIFY( tracker::count == 0 );
+    VERIFY( !o );
+  }
+
+  {
+    std::experimental::optional<tracker> o { std::experimental::in_place, 333 };
+    auto moved_to = std::move(o);
+    VERIFY( moved_to );
+    VERIFY( moved_to->value == 333 );
+    VERIFY( tracker::count == 2 );
+    VERIFY( o && o->value == -1 );
+  }
+
+  enum outcome { nothrow, caught, bad_catch };
+
+  {
+    outcome result = nothrow;
+    std::experimental::optional<throwing_move> o;
+
+    try
+    {
+      auto moved_to = std::move(o);
+    }
+    catch(exception const&)
+    { result = caught; }
+    catch(...)
+    { result = bad_catch; }
+
+    VERIFY( result == nothrow );
+  }
+
+  {
+    outcome result = nothrow;
+    std::experimental::optional<throwing_move> o { std::experimental::in_place };
+
+    try
+    {
+      auto moved_to = std::move(o);
+    }
+    catch(exception const&)
+    { result = caught; }
+    catch(...)
+    { result = bad_catch; }
+
+    VERIFY( result == caught );
+  }
+
+  VERIFY( tracker::count == 0 );
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/cons/value.cc b/libstdc++-v3/testsuite/experimental/optional/cons/value.cc
new file mode 100644 (file)
index 0000000..339c120
--- /dev/null
@@ -0,0 +1,239 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do run }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+#include <vector>
+
+struct tracker
+{
+  tracker(int value) : value(value) { ++count; }
+  ~tracker() { --count; }
+
+  tracker(tracker const& other) : value(other.value) { ++count; }
+  tracker(tracker&& other) : value(other.value)
+  {
+    other.value = -1;
+    ++count;
+  }
+
+  tracker& operator=(tracker const&) = default;
+  tracker& operator=(tracker&&) = default;
+
+  int value;
+
+  static int count;
+};
+
+int tracker::count = 0;
+
+struct exception { };
+
+struct throwing_construction
+{
+  explicit throwing_construction(bool propagate) : propagate(propagate) { }
+
+  throwing_construction(throwing_construction const& other)
+  : propagate(other.propagate)
+  {
+    if(propagate)
+      throw exception {};
+  }
+
+  bool propagate;
+};
+
+int main()
+{
+  // [20.5.4.1] Constructors
+
+  {
+    auto i = 0x1234ABCDF1E2D3C4;
+    std::experimental::optional<long> o { i };
+    VERIFY( o );
+    VERIFY( *o == 0x1234ABCDF1E2D3C4 );
+    VERIFY( i == 0x1234ABCDF1E2D3C4 );
+  }
+
+  {
+    auto i = 0x1234ABCDF1E2D3C4;
+    std::experimental::optional<long> o = i;
+    VERIFY( o );
+    VERIFY( *o == 0x1234ABCDF1E2D3C4 );
+    VERIFY( i == 0x1234ABCDF1E2D3C4 );
+  }
+
+  {
+    auto i = 0x1234ABCDF1E2D3C4;
+    std::experimental::optional<long> o = { i };
+    VERIFY( o );
+    VERIFY( *o == 0x1234ABCDF1E2D3C4 );
+    VERIFY( i == 0x1234ABCDF1E2D3C4 );
+  }
+
+  {
+    auto i = 0x1234ABCDF1E2D3C4;
+    std::experimental::optional<long> o { std::move(i) };
+    VERIFY( o );
+    VERIFY( *o == 0x1234ABCDF1E2D3C4 );
+    VERIFY( i == 0x1234ABCDF1E2D3C4 );
+  }
+
+  {
+    auto i = 0x1234ABCDF1E2D3C4;
+    std::experimental::optional<long> o = std::move(i);
+    VERIFY( o );
+    VERIFY( *o == 0x1234ABCDF1E2D3C4 );
+    VERIFY( i == 0x1234ABCDF1E2D3C4 );
+  }
+
+  {
+    auto i = 0x1234ABCDF1E2D3C4;
+    std::experimental::optional<long> o = { std::move(i) };
+    VERIFY( o );
+    VERIFY( *o == 0x1234ABCDF1E2D3C4 );
+    VERIFY( i == 0x1234ABCDF1E2D3C4 );
+  }
+
+  {
+    std::vector<int> v = { 0, 1, 2, 3, 4, 5 };
+    std::experimental::optional<std::vector<int>> o { v };
+    VERIFY( !v.empty() );
+    VERIFY( o->size() == 6 );
+  }
+
+  {
+    std::vector<int> v = { 0, 1, 2, 3, 4, 5 };
+    std::experimental::optional<std::vector<int>> o = v;
+    VERIFY( !v.empty() );
+    VERIFY( o->size() == 6 );
+  }
+
+  {
+    std::vector<int> v = { 0, 1, 2, 3, 4, 5 };
+    std::experimental::optional<std::vector<int>> o { v };
+    VERIFY( !v.empty() );
+    VERIFY( o->size() == 6 );
+  }
+
+  {
+    std::vector<int> v = { 0, 1, 2, 3, 4, 5 };
+    std::experimental::optional<std::vector<int>> o { std::move(v) };
+    VERIFY( v.empty() );
+    VERIFY( o->size() == 6 );
+  }
+
+  {
+    std::vector<int> v = { 0, 1, 2, 3, 4, 5 };
+    std::experimental::optional<std::vector<int>> o = std::move(v);
+    VERIFY( v.empty() );
+    VERIFY( o->size() == 6 );
+  }
+
+  {
+    std::vector<int> v = { 0, 1, 2, 3, 4, 5 };
+    std::experimental::optional<std::vector<int>> o { std::move(v) };
+    VERIFY( v.empty() );
+    VERIFY( o->size() == 6 );
+  }
+
+  {
+    tracker t { 333 };
+    std::experimental::optional<tracker> o = t;
+    VERIFY( o->value == 333 );
+    VERIFY( tracker::count == 2 );
+    VERIFY( t.value == 333 );
+  }
+
+  {
+    tracker t { 333 };
+    std::experimental::optional<tracker> o = std::move(t);
+    VERIFY( o->value == 333 );
+    VERIFY( tracker::count == 2 );
+    VERIFY( t.value == -1 );
+  }
+
+  enum outcome { nothrow, caught, bad_catch };
+
+  {
+    outcome result = nothrow;
+    throwing_construction t { false };
+
+    try
+    {
+      std::experimental::optional<throwing_construction> o { t };
+    }
+    catch(exception const&)
+    { result = caught; }
+    catch(...)
+    { result = bad_catch; }
+
+    VERIFY( result == nothrow );
+  }
+
+  {
+    outcome result = nothrow;
+    throwing_construction t { true };
+
+    try
+    {
+      std::experimental::optional<throwing_construction> o { t };
+    }
+    catch(exception const&)
+    { result = caught; }
+    catch(...)
+    { result = bad_catch; }
+
+    VERIFY( result == caught );
+  }
+
+  {
+    outcome result = nothrow;
+    throwing_construction t { false };
+
+    try
+    {
+      std::experimental::optional<throwing_construction> o { std::move(t) };
+    }
+    catch(exception const&)
+    { result = caught; }
+    catch(...)
+    { result = bad_catch; }
+
+    VERIFY( result == nothrow );
+  }
+
+  {
+    outcome result = nothrow;
+    throwing_construction t { true };
+
+    try
+    {
+      std::experimental::optional<throwing_construction> o { std::move(t) };
+    }
+    catch(exception const&)
+    { result = caught; }
+    catch(...)
+    { result = bad_catch; }
+
+    VERIFY( result == caught );
+  }
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/cons/default.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/cons/default.cc
new file mode 100644 (file)
index 0000000..d437cd8
--- /dev/null
@@ -0,0 +1,42 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do compile }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+int main()
+{
+  // [20.5.4.1] Constructors
+
+  {
+    constexpr std::experimental::optional<int> o;
+    static_assert( !o, "" );
+  }
+
+  {
+    constexpr std::experimental::optional<int> o {};
+    static_assert( !o, "" );
+  }
+
+  {
+    constexpr std::experimental::optional<int> o = {};
+    static_assert( !o, "" );
+  }
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/cons/value.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/cons/value.cc
new file mode 100644 (file)
index 0000000..98e0a22
--- /dev/null
@@ -0,0 +1,69 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do compile }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+int main()
+{
+  // [20.5.4.1] Constructors
+
+  {
+    constexpr auto i = 0x1234ABCDF1E2D3C4;
+    constexpr std::experimental::optional<long> o { i };
+    static_assert( o, "" );
+    static_assert( *o == 0x1234ABCDF1E2D3C4, "" );
+  }
+
+  {
+    constexpr auto i = 0x1234ABCDF1E2D3C4;
+    constexpr std::experimental::optional<long> o = i;
+    static_assert( o, "" );
+    static_assert( *o == 0x1234ABCDF1E2D3C4, "" );
+  }
+
+  {
+    constexpr auto i = 0x1234ABCDF1E2D3C4;
+    constexpr std::experimental::optional<long> o = { i };
+    static_assert( o, "" );
+    static_assert( *o == 0x1234ABCDF1E2D3C4, "" );
+  }
+
+  {
+    constexpr auto i = 0x1234ABCDF1E2D3C4;
+    constexpr std::experimental::optional<long> o { std::move(i) };
+    static_assert( o, "" );
+    static_assert( *o == 0x1234ABCDF1E2D3C4, "" );
+  }
+
+  {
+    constexpr auto i = 0x1234ABCDF1E2D3C4;
+    constexpr std::experimental::optional<long> o = std::move(i);
+    static_assert( o, "" );
+    static_assert( *o == 0x1234ABCDF1E2D3C4, "" );
+  }
+
+  {
+    constexpr auto i = 0x1234ABCDF1E2D3C4;
+    constexpr std::experimental::optional<long> o = { std::move(i) };
+    static_assert( o, "" );
+    static_assert( *o == 0x1234ABCDF1E2D3C4, "" );
+  }
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/in_place.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/in_place.cc
new file mode 100644 (file)
index 0000000..f2bb8fd
--- /dev/null
@@ -0,0 +1,43 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do compile }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+int main()
+{
+  // [20.5.5] In-place construction
+  static_assert( std::is_same<decltype(std::experimental::in_place), const std::experimental::in_place_t>(), "" );
+  static_assert( std::is_empty<std::experimental::in_place_t>(), "" );
+
+  {
+    constexpr std::experimental::optional<int> o { std::experimental::in_place };
+    static_assert( o, "" );
+    static_assert( *o == int {}, "" );
+
+    static_assert( !std::is_convertible<std::experimental::in_place_t, std::experimental::optional<int>>(), "" );
+  }
+
+  {
+    constexpr std::experimental::optional<int> o { std::experimental::in_place, 42 };
+    static_assert( o, "" );
+    static_assert( *o == 42, "" );
+  }
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/make_optional.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/make_optional.cc
new file mode 100644 (file)
index 0000000..4b59ba9
--- /dev/null
@@ -0,0 +1,33 @@
+// { dg-options "-std=gnu++1y" }
+// XFAIL pending resolution of PR libstdc++/58777
+// { dg-do compile { xfail *-*-* } }
+// { dg-excess-errors "" }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+int main()
+{
+  constexpr int i = 42;
+  constexpr auto o = std::experimental::make_optional(i);
+  static_assert( std::is_same<decltype(o), const std::experimental::optional<int>>(), "" );
+  static_assert( o && *o == 42, "" );
+  static_assert( &*o != &i, "" );
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/nullopt.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/nullopt.cc
new file mode 100644 (file)
index 0000000..08566e1
--- /dev/null
@@ -0,0 +1,46 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do compile }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+int main()
+{
+  // [20.5.6] Disengaged state indicator
+  static_assert( std::is_same<decltype(std::experimental::nullopt), const std::experimental::nullopt_t>(), "" );
+  static_assert( std::is_empty<std::experimental::nullopt_t>(), "" );
+  static_assert( std::is_literal_type<std::experimental::nullopt_t>(), "" );
+  static_assert( !std::is_default_constructible<std::experimental::nullopt_t>(), "" );
+
+  {
+    constexpr std::experimental::optional<int> o = std::experimental::nullopt;
+    static_assert( !o, "" );
+  }
+
+  {
+    constexpr std::experimental::optional<int> o = { std::experimental::nullopt };
+    static_assert( !o, "" );
+  }
+
+  {
+    constexpr std::experimental::optional<int> o { std::experimental::nullopt };
+    static_assert( !o, "" );
+  }
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/1.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/1.cc
new file mode 100644 (file)
index 0000000..5943a35
--- /dev/null
@@ -0,0 +1,33 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do compile }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+struct value_type
+{
+  int i;
+};
+
+int main()
+{
+  constexpr std::experimental::optional<value_type> o { value_type { 51 } };
+  static_assert( (*o).i == 51, "" );
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/2.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/2.cc
new file mode 100644 (file)
index 0000000..3df68d3
--- /dev/null
@@ -0,0 +1,37 @@
+// { dg-options "-std=gnu++1y" }
+// XFAIL pending resolution of PR libstdc++/58777
+// { dg-do compile { xfail *-*-* } }
+// { dg-excess-errors "" }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+struct value_type
+{
+  int i;
+};
+
+int main()
+{
+  constexpr std::experimental::optional<value_type> o { value_type { 51 } };
+  static_assert( o->i == 51, "" );
+  static_assert( o->i == (*o).i, "" );
+  static_assert( &o->i == &(*o).i, "" );
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/3.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/3.cc
new file mode 100644 (file)
index 0000000..6528d99
--- /dev/null
@@ -0,0 +1,37 @@
+// { dg-options "-std=gnu++1y" }
+// XFAIL pending resolution of PR libstdc++/58777
+// { dg-do compile { xfail *-*-* } }
+// { dg-excess-errors "" }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+struct value_type
+{
+  int i;
+};
+
+int main()
+{
+  constexpr std::experimental::optional<value_type> o { value_type { 51 } };
+  static_assert( o.value().i == 51, "" );
+  static_assert( o.value().i == (*o).i, "" );
+  static_assert( &o.value().i == &(*o).i, "" );
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/4.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/4.cc
new file mode 100644 (file)
index 0000000..9098c0c
--- /dev/null
@@ -0,0 +1,35 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do compile }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+struct value_type
+{
+  int i;
+};
+
+int main()
+{
+  constexpr std::experimental::optional<value_type> o { value_type { 51 } };
+  constexpr value_type fallback { 3 };
+  static_assert( o.value_or(fallback).i == 51, "" );
+  static_assert( o.value_or(fallback).i == (*o).i, "" );
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/5.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/5.cc
new file mode 100644 (file)
index 0000000..e86d040
--- /dev/null
@@ -0,0 +1,40 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do compile }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+struct value_type
+{
+  int i;
+};
+
+int main()
+{
+  {
+    constexpr std::experimental::optional<value_type> o = std::experimental::nullopt;
+    static_assert( !o, "" );
+  }
+
+  {
+    constexpr std::experimental::optional<value_type> o { value_type { 51 } };
+    static_assert( o, "" );
+  }
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/1.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/1.cc
new file mode 100644 (file)
index 0000000..591eb13
--- /dev/null
@@ -0,0 +1,99 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do compile }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+namespace ns
+{
+  struct value_type
+  {
+    int i;
+    const char* s;
+  };
+
+  constexpr bool
+  strcmp(const char* lhs, const char* rhs)
+  {
+    return *lhs == *rhs && (!*lhs || strcmp(lhs + 1, rhs + 1));
+  }
+
+  constexpr bool
+  strrel(const char* lhs, const char* rhs)
+  {
+    return (*rhs && (!*lhs || (*lhs < *rhs)))
+      || ((*lhs && *rhs && !(*rhs < *lhs)) && strrel(lhs + 1, rhs + 1));
+  }
+
+  constexpr bool
+  operator==(value_type const& lhs, value_type const& rhs)
+  { return (lhs.i == rhs.i) && strcmp(lhs.s, rhs.s); }
+
+  constexpr bool
+  operator!=(value_type const& lhs, value_type const& rhs)
+  { return !(lhs == rhs); }
+
+  constexpr bool
+  operator<(value_type const& lhs, value_type const& rhs)
+  { return (lhs.i < rhs.i) || (!(rhs.i < lhs.i) && strrel(lhs.s, rhs.s)); }
+
+} // namespace ns
+
+int main()
+{
+  using ns::value_type;
+  using O = std::experimental::optional<value_type>;
+
+  {
+    constexpr O o, p;
+    static_assert( o == p, "" );
+    static_assert( !(o != p), "" );
+  }
+
+  {
+    constexpr O o { value_type { 42, "forty-two" } }, p;
+    static_assert( !(o == p), "" );
+    static_assert( o != p, "" );
+  }
+
+  {
+    constexpr O o, p { value_type { 42, "forty-two" } };
+    static_assert( !(o == p), "" );
+    static_assert( o != p, "" );
+  }
+
+  {
+    constexpr O o { value_type { 11, "eleventy" } }, p { value_type { 42, "forty-two" } };
+    static_assert( !(o == p), "" );
+    static_assert( o != p, "" );
+  }
+
+  {
+    constexpr O o { value_type { 42, "forty-two" } }, p { value_type { 11, "eleventy" } };
+    static_assert( !(o == p), "" );
+    static_assert( o != p, "" );
+  }
+
+  {
+    constexpr O o { value_type { 42, "forty-two" } }, p { value_type { 42, "forty-two" } };
+    static_assert( o == p, "" );
+    static_assert( !(o != p), "" );
+  }
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/2.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/2.cc
new file mode 100644 (file)
index 0000000..9bc140d
--- /dev/null
@@ -0,0 +1,111 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do compile }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+namespace ns
+{
+  struct value_type
+  {
+    int i;
+    const char* s;
+  };
+
+  constexpr bool
+  strcmp(const char* lhs, const char* rhs)
+  {
+    return *lhs == *rhs && (!*lhs || strcmp(lhs + 1, rhs + 1));
+  }
+
+  constexpr bool
+  strrel(const char* lhs, const char* rhs)
+  {
+    return (*rhs && (!*lhs || (*lhs < *rhs)))
+      || ((*lhs && *rhs && !(*rhs < *lhs)) && strrel(lhs + 1, rhs + 1));
+  }
+
+  constexpr bool
+  operator==(value_type const& lhs, value_type const& rhs)
+  { return (lhs.i == rhs.i) && strcmp(lhs.s, rhs.s); }
+
+  constexpr bool
+  operator!=(value_type const& lhs, value_type const& rhs)
+  { return !(lhs == rhs); }
+
+  constexpr bool
+  operator<(value_type const& lhs, value_type const& rhs)
+  { return (lhs.i < rhs.i) || (!(rhs.i < lhs.i) && strrel(lhs.s, rhs.s)); }
+
+} // namespace ns
+
+int main()
+{
+  using ns::value_type;
+  using O = std::experimental::optional<value_type>;
+
+  {
+    constexpr O o, p;
+    static_assert( !(o < p), "" );
+    static_assert( !(o > p), "" );
+    static_assert( o <= p, "" );
+    static_assert( o >= p, "" );
+  }
+
+  {
+    constexpr O o { value_type { 42, "forty-two" } }, p;
+    static_assert( !(o < p), "" );
+    static_assert( o > p, "" );
+    static_assert( !(o <= p), "" );
+    static_assert( o >= p, "" );
+  }
+
+  {
+    constexpr O o, p { value_type { 42, "forty-two" } };
+    static_assert( o < p, "" );
+    static_assert( !(o > p), "" );
+    static_assert( o <= p, "" );
+    static_assert( !(o >= p), "" );
+  }
+
+  {
+    constexpr O o { value_type { 11, "eleventy" } }, p { value_type { 42, "forty-two" } };
+    static_assert( o < p, "" );
+    static_assert( !(o > p), "" );
+    static_assert( o <= p, "" );
+    static_assert( !(o >= p), "" );
+  }
+
+  {
+    constexpr O o { value_type { 42, "forty-two" } }, p { value_type { 11, "eleventy" } };
+    static_assert( !(o < p), "" );
+    static_assert( o > p, "" );
+    static_assert( !(o <= p), "" );
+    static_assert( o >= p, "" );
+  }
+
+  {
+    constexpr O o { value_type { 42, "forty-two" } }, p { value_type { 42, "forty-two" } };
+    static_assert( !(o < p), "" );
+    static_assert( !(o > p), "" );
+    static_assert( o <= p, "" );
+    static_assert( o >= p, "" );
+  }
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/3.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/3.cc
new file mode 100644 (file)
index 0000000..6ffd2b6
--- /dev/null
@@ -0,0 +1,89 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do compile }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+namespace ns
+{
+  struct value_type
+  {
+    int i;
+    const char* s;
+  };
+
+  constexpr bool
+  strcmp(const char* lhs, const char* rhs)
+  {
+    return *lhs == *rhs && (!*lhs || strcmp(lhs + 1, rhs + 1));
+  }
+
+  constexpr bool
+  strrel(const char* lhs, const char* rhs)
+  {
+    return (*rhs && (!*lhs || (*lhs < *rhs)))
+      || ((*lhs && *rhs && !(*rhs < *lhs)) && strrel(lhs + 1, rhs + 1));
+  }
+
+  constexpr bool
+  operator==(value_type const& lhs, value_type const& rhs)
+  { return (lhs.i == rhs.i) && strcmp(lhs.s, rhs.s); }
+
+  constexpr bool
+  operator!=(value_type const& lhs, value_type const& rhs)
+  { return !(lhs == rhs); }
+
+  constexpr bool
+  operator<(value_type const& lhs, value_type const& rhs)
+  { return (lhs.i < rhs.i) || (!(rhs.i < lhs.i) && strrel(lhs.s, rhs.s)); }
+
+} // namespace ns
+
+int main()
+{
+  using ns::value_type;
+  using O = std::experimental::optional<value_type>;
+
+  constexpr value_type reference { 42, "forty-two" };
+
+  {
+    constexpr O o;
+    static_assert( !(o == reference), "" );
+    static_assert( !(reference == o), "" );
+    static_assert( o != reference, "" );
+    static_assert( reference != o, "" );
+  }
+
+  {
+    constexpr O o { value_type { 11, "eleventy" } };
+    static_assert( !(o == reference), "" );
+    static_assert( !(reference == o), "" );
+    static_assert( o != reference, "" );
+    static_assert( reference != o, "" );
+  }
+
+  {
+    constexpr O o { value_type { 42, "forty-two" } };
+    static_assert( o == reference, "" );
+    static_assert( reference == o, "" );
+    static_assert( !(o != reference), "" );
+    static_assert( !(reference != o), "" );
+  }
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/4.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/4.cc
new file mode 100644 (file)
index 0000000..8df602c
--- /dev/null
@@ -0,0 +1,101 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do compile }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+namespace ns
+{
+  struct value_type
+  {
+    int i;
+    const char* s;
+  };
+
+  constexpr bool
+  strcmp(const char* lhs, const char* rhs)
+  {
+    return *lhs == *rhs && (!*lhs || strcmp(lhs + 1, rhs + 1));
+  }
+
+  constexpr bool
+  strrel(const char* lhs, const char* rhs)
+  {
+    return (*rhs && (!*lhs || (*lhs < *rhs)))
+      || ((*lhs && *rhs && !(*rhs < *lhs)) && strrel(lhs + 1, rhs + 1));
+  }
+
+  constexpr bool
+  operator==(value_type const& lhs, value_type const& rhs)
+  { return (lhs.i == rhs.i) && strcmp(lhs.s, rhs.s); }
+
+  constexpr bool
+  operator!=(value_type const& lhs, value_type const& rhs)
+  { return !(lhs == rhs); }
+
+  constexpr bool
+  operator<(value_type const& lhs, value_type const& rhs)
+  { return (lhs.i < rhs.i) || (!(rhs.i < lhs.i) && strrel(lhs.s, rhs.s)); }
+
+} // namespace ns
+
+int main()
+{
+  using ns::value_type;
+  using O = std::experimental::optional<value_type>;
+
+  constexpr value_type reference { 42, "forty-two" };
+
+  {
+    constexpr O o;
+    static_assert( o < reference, "" );
+    static_assert( !(reference < o), "" );
+    static_assert( !(o > reference), "" );
+    static_assert( reference > o, "" );
+    static_assert( o <= reference, "" );
+    static_assert( !(reference <= o), "" );
+    static_assert( !(o >= reference), "" );
+    static_assert( reference >= o, "" );
+  }
+
+  {
+    constexpr O o { value_type { 11, "eleventy" } };
+    static_assert( o < reference, "" );
+    static_assert( !(reference < o), "" );
+    static_assert( !(o > reference), "" );
+    static_assert( reference > o, "" );
+    static_assert( o <= reference, "" );
+    static_assert( !(reference <= o), "" );
+    static_assert( !(o >= reference), "" );
+    static_assert( reference >= o, "" );
+  }
+
+  {
+    constexpr O o { value_type { 42, "forty-two" } };
+    static_assert( !(o < reference), "" );
+    static_assert( !(reference < o), "" );
+    static_assert( !(o > reference), "" );
+    static_assert( !(reference > o), "" );
+    static_assert( o <= reference, "" );
+    static_assert( reference <= o, "" );
+    static_assert( o >= reference, "" );
+    static_assert( reference >= o, "" );
+  }
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/5.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/5.cc
new file mode 100644 (file)
index 0000000..241a71b
--- /dev/null
@@ -0,0 +1,80 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do compile }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+namespace ns
+{
+  struct value_type
+  {
+    int i;
+    const char* s;
+  };
+
+  constexpr bool
+  strcmp(const char* lhs, const char* rhs)
+  {
+    return *lhs == *rhs && (!*lhs || strcmp(lhs + 1, rhs + 1));
+  }
+
+  constexpr bool
+  strrel(const char* lhs, const char* rhs)
+  {
+    return (*rhs && (!*lhs || (*lhs < *rhs)))
+      || ((*lhs && *rhs && !(*rhs < *lhs)) && strrel(lhs + 1, rhs + 1));
+  }
+
+  constexpr bool
+  operator==(value_type const& lhs, value_type const& rhs)
+  { return (lhs.i == rhs.i) && strcmp(lhs.s, rhs.s); }
+
+  constexpr bool
+  operator!=(value_type const& lhs, value_type const& rhs)
+  { return !(lhs == rhs); }
+
+  constexpr bool
+  operator<(value_type const& lhs, value_type const& rhs)
+  { return (lhs.i < rhs.i) || (!(rhs.i < lhs.i) && strrel(lhs.s, rhs.s)); }
+
+} // namespace ns
+
+int main()
+{
+  using ns::value_type;
+  using O = std::experimental::optional<value_type>;
+  using std::experimental::nullopt;
+
+  {
+    constexpr O o;
+    static_assert( o == nullopt, "" );
+    static_assert( nullopt == o, "" );
+    static_assert( !(o != nullopt), "" );
+    static_assert( !(nullopt != o), "" );
+  }
+
+  {
+    constexpr O o { std::experimental::in_place };
+    static_assert( !(o == nullopt), "" );
+    static_assert( !(nullopt == o), "" );
+    static_assert( o != nullopt, "" );
+    static_assert( nullopt != o, "" );
+  }
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/6.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/relops/6.cc
new file mode 100644 (file)
index 0000000..a4282d8
--- /dev/null
@@ -0,0 +1,88 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do compile }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+namespace ns
+{
+  struct value_type
+  {
+    int i;
+    const char* s;
+  };
+
+  constexpr bool
+  strcmp(const char* lhs, const char* rhs)
+  {
+    return *lhs == *rhs && (!*lhs || strcmp(lhs + 1, rhs + 1));
+  }
+
+  constexpr bool
+  strrel(const char* lhs, const char* rhs)
+  {
+    return (*rhs && (!*lhs || (*lhs < *rhs)))
+      || ((*lhs && *rhs && !(*rhs < *lhs)) && strrel(lhs + 1, rhs + 1));
+  }
+
+  constexpr bool
+  operator==(value_type const& lhs, value_type const& rhs)
+  { return (lhs.i == rhs.i) && strcmp(lhs.s, rhs.s); }
+
+  constexpr bool
+  operator!=(value_type const& lhs, value_type const& rhs)
+  { return !(lhs == rhs); }
+
+  constexpr bool
+  operator<(value_type const& lhs, value_type const& rhs)
+  { return (lhs.i < rhs.i) || (!(rhs.i < lhs.i) && strrel(lhs.s, rhs.s)); }
+
+} // namespace ns
+
+int main()
+{
+  using ns::value_type;
+  using O = std::experimental::optional<value_type>;
+  using std::experimental::nullopt;
+
+  {
+    constexpr O o;
+    static_assert( !(o < nullopt), "" );
+    static_assert( !(nullopt < o), "" );
+    static_assert( !(o > nullopt), "" );
+    static_assert( !(nullopt > o), "" );
+    static_assert( o <= nullopt, "" );
+    static_assert( nullopt <= o, "" );
+    static_assert( o >= nullopt, "" );
+    static_assert( nullopt >= o, "" );
+  }
+
+  {
+    constexpr O o { std::experimental::in_place };
+    static_assert( !(o < nullopt), "" );
+    static_assert( nullopt < o, "" );
+    static_assert( o > nullopt, "" );
+    static_assert( !(nullopt > o), "" );
+    static_assert( !(o <= nullopt), "" );
+    static_assert( nullopt <= o, "" );
+    static_assert( o >= nullopt, "" );
+    static_assert( !(nullopt >= o), "" );
+  }
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/in_place.cc b/libstdc++-v3/testsuite/experimental/optional/in_place.cc
new file mode 100644 (file)
index 0000000..ceaa97d
--- /dev/null
@@ -0,0 +1,66 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do run }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+#include <vector>
+
+int main()
+{
+  // [20.5.5] In-place construction
+  static_assert( std::is_same<decltype(std::experimental::in_place), const std::experimental::in_place_t>(), "" );
+  static_assert( std::is_empty<std::experimental::in_place_t>(), "" );
+
+  {
+    std::experimental::optional<int> o { std::experimental::in_place };
+    VERIFY( o );
+    VERIFY( *o == int() );
+
+    static_assert( !std::is_convertible<std::experimental::in_place_t, std::experimental::optional<int>>(), "" );
+  }
+
+  {
+    std::experimental::optional<int> o { std::experimental::in_place, 42 };
+    VERIFY( o );
+    VERIFY( *o == 42 );
+  }
+
+  {
+    std::experimental::optional<std::vector<int>> o { std::experimental::in_place, 18, 4 };
+    VERIFY( o );
+    VERIFY( o->size() == 18 );
+    VERIFY( (*o)[17] == 4 );
+  }
+
+  {
+    std::experimental::optional<std::vector<int>> o { std::experimental::in_place, { 18, 4 } };
+    VERIFY( o );
+    VERIFY( o->size() == 2 );
+    VERIFY( (*o)[0] == 18 );
+  }
+
+  {
+    std::experimental::optional<std::vector<int>> o { std::experimental::in_place, { 18, 4 }, std::allocator<int> {} };
+    VERIFY( o );
+    VERIFY( o->size() == 2 );
+    VERIFY( (*o)[0] == 18 );
+  }
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/make_optional.cc b/libstdc++-v3/testsuite/experimental/optional/make_optional.cc
new file mode 100644 (file)
index 0000000..90ebe6c
--- /dev/null
@@ -0,0 +1,31 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do run }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+int main()
+{
+  const int i = 42;
+  auto o = std::experimental::make_optional(i);
+  static_assert( std::is_same<decltype(o), std::experimental::optional<int>>(), "" );
+  VERIFY( o && *o == 42 );
+  VERIFY( &*o != &i );
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/nullopt.cc b/libstdc++-v3/testsuite/experimental/optional/nullopt.cc
new file mode 100644 (file)
index 0000000..f1b1bb6
--- /dev/null
@@ -0,0 +1,46 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do run }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+int main()
+{
+  // [20.5.6] Disengaged state indicator
+  static_assert( std::is_same<decltype(std::experimental::nullopt), const std::experimental::nullopt_t>(), "" );
+  static_assert( std::is_empty<std::experimental::nullopt_t>(), "" );
+  static_assert( std::is_literal_type<std::experimental::nullopt_t>(), "" );
+  static_assert( !std::is_default_constructible<std::experimental::nullopt_t>(), "" );
+
+  {
+    std::experimental::optional<int> o = std::experimental::nullopt;
+    VERIFY( !o );
+  }
+
+  {
+    std::experimental::optional<int> o = { std::experimental::nullopt };
+    VERIFY( !o );
+  }
+
+  {
+    std::experimental::optional<int> o { std::experimental::nullopt };
+    VERIFY( !o );
+  }
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/observers/1.cc b/libstdc++-v3/testsuite/experimental/optional/observers/1.cc
new file mode 100644 (file)
index 0000000..5ffa3a5
--- /dev/null
@@ -0,0 +1,33 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do run }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+struct value_type
+{
+  int i;
+};
+
+int main()
+{
+  std::experimental::optional<value_type> o { value_type { 51 } };
+  VERIFY( (*o).i == 51 );
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/observers/2.cc b/libstdc++-v3/testsuite/experimental/optional/observers/2.cc
new file mode 100644 (file)
index 0000000..444a141
--- /dev/null
@@ -0,0 +1,35 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do run }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+struct value_type
+{
+  int i;
+};
+
+int main()
+{
+  std::experimental::optional<value_type> o { value_type { 51 } };
+  VERIFY( o->i == 51 );
+  VERIFY( o->i == (*o).i );
+  VERIFY( &o->i == &(*o).i );
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/observers/3.cc b/libstdc++-v3/testsuite/experimental/optional/observers/3.cc
new file mode 100644 (file)
index 0000000..b82142d
--- /dev/null
@@ -0,0 +1,58 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do run }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+struct value_type
+{
+  int i;
+};
+
+int main()
+{
+  {
+    std::experimental::optional<value_type> o { value_type { 51 } };
+    VERIFY( o.value().i == 51 );
+    VERIFY( o.value().i == (*o).i );
+    VERIFY( &o.value().i == &(*o).i );
+  }
+
+  {
+    enum outcome_type { nothrow, caught, bad_catch };
+
+    outcome_type outcome {};
+    std::experimental::optional<value_type> o = std::experimental::nullopt;
+    bool called = false;
+    auto const eat = [&called](int) { called = true; };
+
+    try
+    {
+      eat(o.value().i);
+    }
+    catch(std::experimental::bad_optional_access const&)
+    { outcome = caught; }
+    catch(...)
+    { outcome = bad_catch; }
+
+    VERIFY( outcome == caught );
+    VERIFY( !called );
+  }
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/observers/4.cc b/libstdc++-v3/testsuite/experimental/optional/observers/4.cc
new file mode 100644 (file)
index 0000000..3b43c77
--- /dev/null
@@ -0,0 +1,35 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do run }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+struct value_type
+{
+  int i;
+};
+
+int main()
+{
+  std::experimental::optional<value_type> o { value_type { 51 } };
+  value_type fallback { 3 };
+  VERIFY( o.value_or(fallback).i == 51 );
+  VERIFY( o.value_or(fallback).i == (*o).i );
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/observers/5.cc b/libstdc++-v3/testsuite/experimental/optional/observers/5.cc
new file mode 100644 (file)
index 0000000..c6957ec
--- /dev/null
@@ -0,0 +1,40 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do run }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+struct value_type
+{
+  int i;
+};
+
+int main()
+{
+  {
+    std::experimental::optional<value_type> o = std::experimental::nullopt;
+    VERIFY( !o );
+  }
+
+  {
+    std::experimental::optional<value_type> o { value_type { 51 } };
+    VERIFY( o );
+  }
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/relops/1.cc b/libstdc++-v3/testsuite/experimental/optional/relops/1.cc
new file mode 100644 (file)
index 0000000..6f0c60f
--- /dev/null
@@ -0,0 +1,89 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do run }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+#include <tuple>
+#include <string>
+
+namespace ns
+{
+  struct value_type
+  {
+    int i;
+    std::string s;
+  };
+
+  bool
+  operator==(value_type const& lhs, value_type const& rhs)
+  { return std::tie(lhs.i, lhs.s) == std::tie(rhs.i, rhs.s); }
+
+  bool
+  operator!=(value_type const& lhs, value_type const& rhs)
+  { return !(lhs == rhs); }
+
+  bool
+  operator<(value_type const& lhs, value_type const& rhs)
+  { return std::tie(lhs.i, lhs.s) < std::tie(rhs.i, rhs.s); }
+
+} // namespace ns
+
+int main()
+{
+  using ns::value_type;
+  using O = std::experimental::optional<value_type>;
+
+  {
+    O o, p;
+    VERIFY( o == p );
+    VERIFY( !(o != p) );
+  }
+
+  {
+    O o { value_type { 42, "forty-two" } }, p;
+    VERIFY( !(o == p) );
+    VERIFY( o != p );
+  }
+
+  {
+    O o, p { value_type { 42, "forty-two" } };
+    VERIFY( !(o == p) );
+    VERIFY( o != p );
+  }
+
+  {
+    O o { value_type { 11, "eleventy" } }, p { value_type { 42, "forty-two" } };
+    VERIFY( !(o == p) );
+    VERIFY( o != p );
+  }
+
+  {
+    O o { value_type { 42, "forty-two" } }, p { value_type { 11, "eleventy" } };
+    VERIFY( !(o == p) );
+    VERIFY( o != p );
+  }
+
+  {
+    O o { value_type { 42, "forty-two" } }, p { value_type { 42, "forty-two" } };
+    VERIFY( o == p );
+    VERIFY( !(o != p) );
+  }
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/relops/2.cc b/libstdc++-v3/testsuite/experimental/optional/relops/2.cc
new file mode 100644 (file)
index 0000000..b1ae705
--- /dev/null
@@ -0,0 +1,101 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do run }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+#include <tuple>
+#include <string>
+
+namespace ns
+{
+  struct value_type
+  {
+    int i;
+    std::string s;
+  };
+
+  bool
+  operator==(value_type const& lhs, value_type const& rhs)
+  { return std::tie(lhs.i, lhs.s) == std::tie(rhs.i, rhs.s); }
+
+  bool
+  operator!=(value_type const& lhs, value_type const& rhs)
+  { return !(lhs == rhs); }
+
+  bool
+  operator<(value_type const& lhs, value_type const& rhs)
+  { return std::tie(lhs.i, lhs.s) < std::tie(rhs.i, rhs.s); }
+
+} // namespace ns
+
+int main()
+{
+  using ns::value_type;
+  using O = std::experimental::optional<value_type>;
+
+  {
+    O o, p;
+    VERIFY( !(o < p) );
+    VERIFY( !(o > p) );
+    VERIFY( o <= p );
+    VERIFY( o >= p );
+  }
+
+  {
+    O o { value_type { 42, "forty-two" } }, p;
+    VERIFY( !(o < p) );
+    VERIFY( o > p );
+    VERIFY( !(o <= p) );
+    VERIFY( o >= p );
+  }
+
+  {
+    O o, p { value_type { 42, "forty-two" } };
+    VERIFY( o < p );
+    VERIFY( !(o > p) );
+    VERIFY( o <= p );
+    VERIFY( !(o >= p) );
+  }
+
+  {
+    O o { value_type { 11, "eleventy" } }, p { value_type { 42, "forty-two" } };
+    VERIFY( o < p );
+    VERIFY( !(o > p) );
+    VERIFY( o <= p );
+    VERIFY( !(o >= p) );
+  }
+
+  {
+    O o { value_type { 42, "forty-two" } }, p { value_type { 11, "eleventy" } };
+    VERIFY( !(o < p) );
+    VERIFY( o > p );
+    VERIFY( !(o <= p) );
+    VERIFY( o >= p );
+  }
+
+  {
+    O o { value_type { 42, "forty-two" } }, p { value_type { 42, "forty-two" } };
+    VERIFY( !(o < p) );
+    VERIFY( !(o > p) );
+    VERIFY( o <= p );
+    VERIFY( o >= p );
+  }
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/relops/3.cc b/libstdc++-v3/testsuite/experimental/optional/relops/3.cc
new file mode 100644 (file)
index 0000000..6b361df
--- /dev/null
@@ -0,0 +1,79 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do run }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+#include <tuple>
+#include <string>
+
+namespace ns
+{
+  struct value_type
+  {
+    int i;
+    std::string s;
+  };
+
+  bool
+  operator==(value_type const& lhs, value_type const& rhs)
+  { return std::tie(lhs.i, lhs.s) == std::tie(rhs.i, rhs.s); }
+
+  bool
+  operator!=(value_type const& lhs, value_type const& rhs)
+  { return !(lhs == rhs); }
+
+  bool
+  operator<(value_type const& lhs, value_type const& rhs)
+  { return std::tie(lhs.i, lhs.s) < std::tie(rhs.i, rhs.s); }
+
+} // namespace ns
+
+int main()
+{
+  using ns::value_type;
+  using O = std::experimental::optional<value_type>;
+
+  value_type const reference { 42, "forty-two" };
+
+  {
+    O o;
+    VERIFY( !(o == reference) );
+    VERIFY( !(reference == o) );
+    VERIFY( o != reference );
+    VERIFY( reference != o );
+  }
+
+  {
+    O o { value_type { 11, "eleventy" } };
+    VERIFY( !(o == reference) );
+    VERIFY( !(reference == o) );
+    VERIFY( o != reference );
+    VERIFY( reference != o );
+  }
+
+  {
+    O o { value_type { 42, "forty-two" } };
+    VERIFY( o == reference );
+    VERIFY( reference == o );
+    VERIFY( !(o != reference) );
+    VERIFY( !(reference != o) );
+  }
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/relops/4.cc b/libstdc++-v3/testsuite/experimental/optional/relops/4.cc
new file mode 100644 (file)
index 0000000..9f316f1
--- /dev/null
@@ -0,0 +1,91 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do run }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+#include <tuple>
+#include <string>
+
+namespace ns
+{
+  struct value_type
+  {
+    int i;
+    std::string s;
+  };
+
+  bool
+  operator==(value_type const& lhs, value_type const& rhs)
+  { return std::tie(lhs.i, lhs.s) == std::tie(rhs.i, rhs.s); }
+
+  bool
+  operator!=(value_type const& lhs, value_type const& rhs)
+  { return !(lhs == rhs); }
+
+  bool
+  operator<(value_type const& lhs, value_type const& rhs)
+  { return std::tie(lhs.i, lhs.s) < std::tie(rhs.i, rhs.s); }
+
+} // namespace ns
+
+int main()
+{
+  using ns::value_type;
+  using O = std::experimental::optional<value_type>;
+
+  value_type const reference { 42, "forty-two" };
+
+  {
+    O o;
+    VERIFY( o < reference );
+    VERIFY( !(reference < o) );
+    VERIFY( !(o > reference) );
+    VERIFY( reference > o );
+    VERIFY( o <= reference );
+    VERIFY( !(reference <= o) );
+    VERIFY( !(o >= reference) );
+    VERIFY( reference >= o );
+  }
+
+  {
+    O o { value_type { 11, "eleventy" } };
+    VERIFY( o < reference );
+    VERIFY( !(reference < o) );
+    VERIFY( !(o > reference) );
+    VERIFY( reference > o );
+    VERIFY( o <= reference );
+    VERIFY( !(reference <= o) );
+    VERIFY( !(o >= reference) );
+    VERIFY( reference >= o );
+  }
+
+  {
+    O o { value_type { 42, "forty-two" } };
+    VERIFY( !(o < reference) );
+    VERIFY( !(reference < o) );
+    VERIFY( !(o > reference) );
+    VERIFY( !(reference > o) );
+    VERIFY( o <= reference );
+    VERIFY( reference <= o );
+    VERIFY( o >= reference );
+    VERIFY( reference >= o );
+  }
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/relops/5.cc b/libstdc++-v3/testsuite/experimental/optional/relops/5.cc
new file mode 100644 (file)
index 0000000..c7b27bb
--- /dev/null
@@ -0,0 +1,70 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do run }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+#include <tuple>
+#include <string>
+
+namespace ns
+{
+  struct value_type
+  {
+    int i;
+    std::string s;
+  };
+
+  bool
+  operator==(value_type const& lhs, value_type const& rhs)
+  { return std::tie(lhs.i, lhs.s) == std::tie(rhs.i, rhs.s); }
+
+  bool
+  operator!=(value_type const& lhs, value_type const& rhs)
+  { return !(lhs == rhs); }
+
+  bool
+  operator<(value_type const& lhs, value_type const& rhs)
+  { return std::tie(lhs.i, lhs.s) < std::tie(rhs.i, rhs.s); }
+
+} // namespace ns
+
+int main()
+{
+  using ns::value_type;
+  using O = std::experimental::optional<value_type>;
+  using std::experimental::nullopt;
+
+  {
+    O o;
+    VERIFY( o == nullopt );
+    VERIFY( nullopt == o );
+    VERIFY( !(o != nullopt) );
+    VERIFY( !(nullopt != o) );
+  }
+
+  {
+    O o { std::experimental::in_place };
+    VERIFY( !(o == nullopt) );
+    VERIFY( !(nullopt == o) );
+    VERIFY( o != nullopt );
+    VERIFY( nullopt != o );
+  }
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/relops/6.cc b/libstdc++-v3/testsuite/experimental/optional/relops/6.cc
new file mode 100644 (file)
index 0000000..d8a4f6f
--- /dev/null
@@ -0,0 +1,78 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do run }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+#include <tuple>
+#include <string>
+
+namespace ns
+{
+  struct value_type
+  {
+    int i;
+    std::string s;
+  };
+
+  bool
+  operator==(value_type const& lhs, value_type const& rhs)
+  { return std::tie(lhs.i, lhs.s) == std::tie(rhs.i, rhs.s); }
+
+  bool
+  operator!=(value_type const& lhs, value_type const& rhs)
+  { return !(lhs == rhs); }
+
+  bool
+  operator<(value_type const& lhs, value_type const& rhs)
+  { return std::tie(lhs.i, lhs.s) < std::tie(rhs.i, rhs.s); }
+
+} // namespace ns
+
+int main()
+{
+  using ns::value_type;
+  using O = std::experimental::optional<value_type>;
+  using std::experimental::nullopt;
+
+  {
+    O o;
+    VERIFY( !(o < nullopt) );
+    VERIFY( !(nullopt < o) );
+    VERIFY( !(o > nullopt) );
+    VERIFY( !(nullopt > o) );
+    VERIFY( o <= nullopt );
+    VERIFY( nullopt <= o );
+    VERIFY( o >= nullopt );
+    VERIFY( nullopt >= o );
+  }
+
+  {
+    O o { std::experimental::in_place };
+    VERIFY( !(o < nullopt) );
+    VERIFY( nullopt < o );
+    VERIFY( o > nullopt );
+    VERIFY( !(nullopt > o) );
+    VERIFY( !(o <= nullopt) );
+    VERIFY( nullopt <= o );
+    VERIFY( o >= nullopt );
+    VERIFY( !(nullopt >= o) );
+  }
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/requirements.cc b/libstdc++-v3/testsuite/experimental/optional/requirements.cc
new file mode 100644 (file)
index 0000000..c97cde5
--- /dev/null
@@ -0,0 +1,256 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do run }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/optional>
+#include <testsuite_hooks.h>
+
+#include <tuple>
+
+struct trivially_destructible
+{
+  trivially_destructible() = delete;
+  trivially_destructible(trivially_destructible const&) = delete;
+  trivially_destructible& operator=(trivially_destructible const&) = delete;
+  trivially_destructible(trivially_destructible&&) = delete;
+  trivially_destructible& operator=(trivially_destructible&&) = delete;
+  ~trivially_destructible() noexcept = default;
+};
+
+static_assert( std::is_trivially_destructible<trivially_destructible>(), "" );
+
+struct no_default_constructor
+{
+  no_default_constructor() = delete;
+};
+
+struct no_copy_constructor
+{
+  no_copy_constructor() = default;
+  no_copy_constructor(no_copy_constructor const&) = delete;
+  no_copy_constructor& operator=(no_copy_constructor const&) = default;
+  no_copy_constructor(no_copy_constructor&&) = default;
+  no_copy_constructor& operator=(no_copy_constructor&&) = default;
+};
+
+struct no_copy_assignment
+{
+  no_copy_assignment() = default;
+  no_copy_assignment(no_copy_assignment const&) = default;
+  no_copy_assignment(no_copy_assignment&&) = default;
+  no_copy_assignment& operator=(no_copy_assignment&&) = default;
+};
+
+struct no_move_constructor
+{
+  no_move_constructor() = default;
+  no_move_constructor(no_move_constructor const&) = default;
+  no_move_constructor& operator=(no_move_constructor const&) = default;
+  no_move_constructor(no_move_constructor&&) = delete;
+  no_move_constructor& operator=(no_move_constructor&&) = default;
+};
+
+struct no_move_assignment
+{
+  no_move_assignment() = default;
+  no_move_assignment(no_move_assignment const&) = default;
+  no_move_assignment& operator=(no_move_assignment const&) = default;
+  no_move_assignment(no_move_assignment&&) = default;
+  no_move_assignment& operator=(no_move_assignment&&) = delete;
+};
+
+struct no_copy : no_copy_constructor, no_copy_assignment { };
+struct no_move : no_move_constructor, no_move_assignment { };
+
+// Laxest possible model of a value type for optional
+struct only_destructible
+{
+  only_destructible(only_destructible&&) = delete;
+};
+
+int main()
+{
+  {
+    static_assert( std::is_trivially_destructible<std::experimental::optional<trivially_destructible>>(), "" );
+  }
+
+  {
+    using T = no_default_constructor;
+    using O = std::experimental::optional<T>;
+    static_assert( std::is_same<O::value_type, T>(), "" );
+    static_assert( std::is_default_constructible<O>(), "" );
+    { O o; }
+    static_assert( std::is_copy_constructible<O>(), "" );
+    { O o; auto copy = o; }
+    static_assert( std::is_copy_assignable<O>(), "" );
+    { O o, p; p = o; }
+    static_assert( std::is_move_constructible<O>(), "" );
+    { O o; auto moved_to = std::move(o); }
+    static_assert( std::is_move_assignable<O>(), "" );
+    { O o, p; p = std::move(o); }
+  }
+
+  {
+    using T = no_copy_constructor;
+    using O = std::experimental::optional<T>;
+    static_assert( std::is_same<O::value_type, T>(), "" );
+    static_assert( std::is_default_constructible<O>(), "" );
+    { O o; }
+    static_assert( !std::is_copy_constructible<O>(), "" );
+    static_assert( !std::is_copy_assignable<O>(), "" );
+    static_assert( std::is_move_constructible<O>(), "" );
+    { O o; auto moved_to = std::move(o); }
+    static_assert( std::is_move_assignable<O>(), "" );
+    { O o, p; p = std::move(o); }
+  }
+
+  {
+    using T = no_copy_assignment;
+    using O = std::experimental::optional<T>;
+    static_assert( std::is_default_constructible<O>(), "" );
+    { O o; }
+    static_assert( std::is_copy_constructible<O>(), "" );
+    { O o; auto copy = o; }
+    static_assert( !std::is_copy_assignable<O>(), "" );
+    static_assert( std::is_move_constructible<O>(), "" );
+    { O o; auto moved_to = std::move(o); }
+    static_assert( std::is_move_assignable<O>(), "" );
+    { O o, p; p = std::move(o); }
+  }
+
+  {
+    using T = no_copy;
+    using O = std::experimental::optional<T>;
+    static_assert( std::is_same<O::value_type, T>(), "" );
+    static_assert( std::is_default_constructible<O>(), "" );
+    { O o; }
+    static_assert( !std::is_copy_constructible<O>(), "" );
+    static_assert( !std::is_copy_assignable<O>(), "" );
+    static_assert( std::is_move_constructible<O>(), "" );
+    { O o; auto moved_to = std::move(o); }
+    static_assert( std::is_move_assignable<O>(), "" );
+    { O o, p; p = std::move(o); }
+  }
+
+  {
+    using T = no_move_constructor;
+    using O = std::experimental::optional<T>;
+    static_assert( std::is_same<O::value_type, T>(), "" );
+    static_assert( std::is_default_constructible<O>(), "" );
+    { O o; }
+    static_assert( std::is_copy_constructible<O>(), "" );
+    { O o; auto copy = o; }
+    static_assert( std::is_copy_assignable<O>(), "" );
+    /*
+     * T should be move constructible due to [12.8/11], which is a new rule in C++1y
+     * not yet implemented by GCC. Because there is already a special exception in C++11
+     * for the generation of the special members that GCC implements (at least some of the
+     * time), this does not affect the std::experimental::optional implementation however. So the assertion
+     * for T should be changed (or removed altogether) when the time comes, but the rest
+     * should however remain correct and unchanged.
+     */
+    static_assert( !std::is_move_constructible<T>(), "" );
+    static_assert( std::is_move_constructible<O>(), "" );
+    { O o; auto moved_to = std::move(o); }
+    static_assert( std::is_move_assignable<O>(), "" );
+    { O o, p; p = std::move(o); }
+  }
+
+  {
+    using T = no_move_assignment;
+    using O = std::experimental::optional<T>;
+    static_assert( std::is_same<O::value_type, T>(), "" );
+    static_assert( std::is_default_constructible<O>(), "" );
+    { O o; }
+    static_assert( std::is_copy_constructible<O>(), "" );
+    { O o; auto copy = o; }
+    static_assert( std::is_copy_assignable<O>(), "" );
+    { O o, p; p = o; }
+    static_assert( std::is_move_constructible<O>(), "" );
+    { O o; auto moved_to = std::move(o); }
+    /*
+     * Paragraph 23 of same leads to a similar situation but with respect to move
+     * assignment.
+     */
+    static_assert( !std::is_move_assignable<T>(), "" );
+    static_assert( std::is_move_assignable<O>(), "" );
+    { O o, p; p = std::move(o); }
+  }
+
+  {
+    using T = no_move;
+    using O = std::experimental::optional<T>;
+    static_assert( std::is_same<O::value_type, T>(), "" );
+    static_assert( std::is_default_constructible<O>(), "" );
+    { O o; }
+    static_assert( std::is_copy_constructible<O>(), "" );
+    { O o; auto copy = o; }
+    static_assert( std::is_copy_assignable<O>(), "" );
+    { O o, p; p = o; }
+    static_assert( std::is_move_constructible<O>(), "" );
+    { O o; auto moved_to = std::move(o); }
+    static_assert( std::is_move_assignable<O>(), "" );
+    { O o, p; p = std::move(o); }
+  }
+
+  {
+    using T = only_destructible;
+    using O = std::experimental::optional<T>;
+    static_assert( std::is_same<O::value_type, T>(), "" );
+    static_assert( std::is_default_constructible<O>(), "" );
+    { O o; }
+    static_assert( !std::is_copy_constructible<O>(), "" );
+    static_assert( !std::is_copy_assignable<O>(), "" );
+    static_assert( !std::is_move_constructible<O>(), "" );
+    static_assert( !std::is_move_assignable<O>(), "" );
+  }
+
+  {
+    /*
+     * Should not complain about 'invalid' specializations as long as
+     * they're not instantiated.
+     */
+    using A = std::experimental::optional<int&>;
+    using B = std::experimental::optional<int&&>;
+    using C1 = std::experimental::optional<std::experimental::in_place_t>;
+    using C2 = std::experimental::optional<std::experimental::in_place_t const>;
+    using C3 = std::experimental::optional<std::experimental::in_place_t volatile>;
+    using C4 = std::experimental::optional<std::experimental::in_place_t const volatile>;
+    using D1 = std::experimental::optional<std::experimental::nullopt_t>;
+    using D2 = std::experimental::optional<std::experimental::nullopt_t const>;
+    using D3 = std::experimental::optional<std::experimental::nullopt_t volatile>;
+    using D4 = std::experimental::optional<std::experimental::nullopt_t const volatile>;
+
+    using X = std::tuple<A, B, C1, C2, C3, C4, D1, D2, D3, D4>;
+  }
+
+  {
+    std::experimental::optional<const int> o { 42 };
+    static_assert( std::is_same<decltype(o)::value_type, const int>(), "" );
+    VERIFY( o );
+    VERIFY( *o == 42 );
+  }
+
+  {
+    constexpr std::experimental::optional<const int> o { 33 };
+    static_assert( std::is_same<decltype(o)::value_type, const int>(), "" );
+    static_assert( o, "" );
+    static_assert( *o == 33, "" );
+  }
+}
diff --git a/libstdc++-v3/testsuite/experimental/optional/swap/1.cc b/libstdc++-v3/testsuite/experimental/optional/swap/1.cc
new file mode 100644 (file)
index 0000000..95235b3
--- /dev/null
@@ -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 );
+}
index 5e7ba3ae9d77054be35337f3f8a4110f04b26a4d..b6976fcb4b272def8db8e93f3371d6dff6c31a8b 100644 (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.