[libcxx] r283980 - Implement N4606 optional

Eric Fiselier via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 12 01:55:56 PDT 2016


This commit is responsible for breaking the libc++ bots hosted
on gribozavr4. The issue is a bug in Clang which was fixed prior to the 3.9
release.
I've asked Dimitri to upgrade the compiler to fix the bots.

/Eric




On Wed, Oct 12, 2016 at 1:46 AM, Eric Fiselier via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> Author: ericwf
> Date: Wed Oct 12 02:46:20 2016
> New Revision: 283980
>
> URL: http://llvm.org/viewvc/llvm-project?rev=283980&view=rev
> Log:
> Implement N4606 optional
>
> Summary:
> Adapt implementation of Library Fundamentals TS optional into an
> implementation of N4606 optional.
>
>   - Update relational operators per http://wg21.link/P0307
>   - Update to requirements of http://wg21.link/P0032
>   - Extension: Implement trivial copy/move construction/assignment for
> `optional<T>` when `T` is trivially copyable.
>
> Audit P/Rs for optional LWG issues:
>   - 2756 "C++ WP optional<T> should 'forward' T's implicit conversions"
> Implemented, which also resolves 2753 "Optional's constructors and
> assignments need constraints" (modulo my refusal to explicitly delete the
> move operations, which is a design error that I'm working on correcting in
> the 2756 P/R).
>   - 2736 "nullopt_t insufficiently constrained" Already conforming. I've
> added a test ensuring that `nullopt_t` is not copy-initializable from an
> empty braced-init-list, which I believe is the root intent of the issue, to
> avoid regression.
>   - 2740 "constexpr optional<T>::operator->" Already conforming.
>   - 2746 "Inconsistency between requirements for emplace between optional
> and variant" No P/R, but note that the author's '"suggested resolution" is
> already implemented.
>   - 2748 "swappable traits for optionals" Already conforming.
>   - 2753 "Optional's constructors and assignments need constraints"
> Implemented.
>
> Most of the work for this patch was done by Casey Carter @ Microsoft.
> Thank you Casey!
>
>
>
> Reviewers: mclow.lists, CaseyCarter, EricWF
>
> Differential Revision: https://reviews.llvm.org/D22741
>
> Added:
>     libcxx/trunk/include/optional
>     libcxx/trunk/test/libcxx/utilities/optional/
>     libcxx/trunk/test/libcxx/utilities/optional/optional.object/
>     libcxx/trunk/test/libcxx/utilities/optional/optional.object/
> optional.object.assign/
>     libcxx/trunk/test/libcxx/utilities/optional/optional.object/
> optional.object.assign/copy.pass.cpp
>     libcxx/trunk/test/libcxx/utilities/optional/optional.object/
> optional.object.assign/move.pass.cpp
>     libcxx/trunk/test/libcxx/utilities/optional/optional.object/
> optional.object.ctor/
>     libcxx/trunk/test/libcxx/utilities/optional/optional.object/
> optional.object.ctor/copy.pass.cpp
>     libcxx/trunk/test/libcxx/utilities/optional/optional.object/
> optional.object.ctor/move.pass.cpp
>     libcxx/trunk/test/libcxx/utilities/optional/optional.object/
> special_member_gen.pass.cpp
>     libcxx/trunk/test/libcxx/utilities/optional/version.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/
>     libcxx/trunk/test/std/utilities/optional/optional.bad_optional_access/
>     libcxx/trunk/test/std/utilities/optional/optional.bad_
> optional_access/default.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.bad_
> optional_access/derive.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.comp_with_t/
>     libcxx/trunk/test/std/utilities/optional/optional.comp_with_
> t/equal.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.comp_with_
> t/greater.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.comp_with_
> t/greater_equal.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.comp_with_
> t/less_equal.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.comp_with_
> t/less_than.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.comp_with_
> t/not_equal.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.hash/
>     libcxx/trunk/test/std/utilities/optional/optional.hash/hash.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.nullops/
>     libcxx/trunk/test/std/utilities/optional/optional.nullops/
> equal.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.nullops/
> greater.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.nullops/
> greater_equal.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.nullops/
> less_equal.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.nullops/
> less_than.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.nullops/
> not_equal.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.nullopt/
>     libcxx/trunk/test/std/utilities/optional/optional.nullopt/
> not_brace_initializable.fail.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.nullopt/
> nullopt_t.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/assign_value.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/const_optional_U.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/copy.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/emplace.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/emplace_initializer_list.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/move.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/nullopt_t.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/optional_U.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/U.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/const_T.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/const_optional_U.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/copy.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/default.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/explicit_const_optional_U.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/explicit_optional_U.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/in_place_t.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/initializer_list.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/move.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/nullopt_t.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/optional_U.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/rvalue_T.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.dtor/
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.dtor/dtor.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.mod/
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.mod/reset.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/bool.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/dereference.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/dereference_const.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/dereference_const_rvalue.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/dereference_rvalue.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/has_value.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/op_arrow.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/op_arrow_const.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value_const.fail.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value_const.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value_const_rvalue.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value_or.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value_or_const.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value_rvalue.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.swap/
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.swap/swap.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> optional_requires_destructible_object.fail.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> special_member_gen.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.object/
> types.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.relops/
>     libcxx/trunk/test/std/utilities/optional/optional.relops/
> equal.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.relops/
> greater_equal.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.relops/
> greater_than.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.relops/
> less_equal.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.relops/
> less_than.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.relops/
> not_equal.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.specalg/
>     libcxx/trunk/test/std/utilities/optional/optional.specalg/
> make_optional.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.specalg/
> make_optional_explicit.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.specalg/
> make_optional_explicit_initializer_list.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.specalg/
> swap.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.syn/
>     libcxx/trunk/test/std/utilities/optional/optional.syn/
> optional_in_place_t.fail.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.syn/
> optional_includes_initializer_list.pass.cpp
>     libcxx/trunk/test/std/utilities/optional/optional.syn/
> optional_nullopt_t.fail.cpp
> Modified:
>     libcxx/trunk/.gitignore
>     libcxx/trunk/include/__config
>     libcxx/trunk/include/type_traits
>     libcxx/trunk/src/optional.cpp
>     libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.
> prop/is_nothrow_swappable_with.pass.cpp
>     libcxx/trunk/test/support/archetypes.hpp
>     libcxx/trunk/test/support/archetypes.ipp
>
> Modified: libcxx/trunk/.gitignore
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/.gitignore?
> rev=283980&r1=283979&r2=283980&view=diff
> ============================================================
> ==================
> --- libcxx/trunk/.gitignore (original)
> +++ libcxx/trunk/.gitignore Wed Oct 12 02:46:20 2016
> @@ -56,3 +56,6 @@ target/
>  # MSVC libraries test harness
>  env.lst
>  keep.lst
> +
> +# Editor by-products
> +.vscode/
>
> Modified: libcxx/trunk/include/__config
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__
> config?rev=283980&r1=283979&r2=283980&view=diff
> ============================================================
> ==================
> --- libcxx/trunk/include/__config (original)
> +++ libcxx/trunk/include/__config Wed Oct 12 02:46:20 2016
> @@ -914,6 +914,10 @@ extern "C" void __sanitizer_annotate_con
>  #define _LIBCPP_SAFE_STATIC
>  #endif
>
> +#if !__has_builtin(__builtin_addressof) && _GNUC_VER < 700
> +#define _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
> +#endif
> +
>  #endif // __cplusplus
>
>  #endif // _LIBCPP_CONFIG
>
> Added: libcxx/trunk/include/optional
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/opt
> ional?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/include/optional (added)
> +++ libcxx/trunk/include/optional Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,1313 @@
> +// -*- C++ -*-
> +//===-------------------------- optional ------------------------------
> ----===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +#ifndef _LIBCPP_OPTIONAL
> +#define _LIBCPP_OPTIONAL
> +
> +/*
> +    optional synopsis
> +
> +// C++1z
> +
> +namespace std {
> +  // 20.6.3, optional for object types
> +  template <class T> class optional;
> +
> +  // 20.6.4, no-value state indicator
> +  struct nullopt_t{see below };
> +  constexpr nullopt_t nullopt(unspecified );
> +
> +  // 20.6.5, class bad_optional_access
> +  class bad_optional_access;
> +
> +  // 20.6.6, relational operators
> +  template <class T>
> +  constexpr bool operator==(const optional<T>&, const optional<T>&);
> +  template <class T>
> +  constexpr bool operator!=(const optional<T>&, const optional<T>&);
> +  template <class T>
> +  constexpr bool operator<(const optional<T>&, const optional<T>&);
> +  template <class T>
> +  constexpr bool operator>(const optional<T>&, const optional<T>&);
> +  template <class T>
> +  constexpr bool operator<=(const optional<T>&, const optional<T>&);
> +  template <class T>
> +  constexpr bool operator>=(const optional<T>&, const optional<T>&);
> +  template <class T> constexpr bool operator==(const optional<T>&,
> nullopt_t) noexcept;
> +  template <class T> constexpr bool operator==(nullopt_t, const
> optional<T>&) noexcept;
> +  template <class T> constexpr bool operator!=(const optional<T>&,
> nullopt_t) noexcept;
> +  template <class T> constexpr bool operator!=(nullopt_t, const
> optional<T>&) noexcept;
> +  template <class T> constexpr bool operator<(const optional<T>&,
> nullopt_t) noexcept;
> +  template <class T> constexpr bool operator<(nullopt_t, const
> optional<T>&) noexcept;
> +  template <class T> constexpr bool operator<=(const optional<T>&,
> nullopt_t) noexcept;
> +  template <class T> constexpr bool operator<=(nullopt_t, const
> optional<T>&) noexcept;
> +  template <class T> constexpr bool operator>(const optional<T>&,
> nullopt_t) noexcept;
> +  template <class T> constexpr bool operator>(nullopt_t, const
> optional<T>&) noexcept;
> +  template <class T> constexpr bool operator>=(const optional<T>&,
> nullopt_t) noexcept;
> +  template <class T> constexpr bool operator>=(nullopt_t, const
> optional<T>&) noexcept;
> +
> +  // 20.6.8, comparison with T
> +  template <class T> constexpr bool operator==(const optional<T>&, const
> T&);
> +  template <class T> constexpr bool operator==(const T&, const
> optional<T>&);
> +  template <class T> constexpr bool operator!=(const optional<T>&, const
> T&);
> +  template <class T> constexpr bool operator!=(const T&, const
> optional<T>&);
> +  template <class T> constexpr bool operator<(const optional<T>&, const
> T&);
> +  template <class T> constexpr bool operator<(const T&, const
> optional<T>&);
> +  template <class T> constexpr bool operator<=(const optional<T>&, const
> T&);
> +  template <class T> constexpr bool operator<=(const T&, const
> optional<T>&);
> +  template <class T> constexpr bool operator>(const optional<T>&, const
> T&);
> +  template <class T> constexpr bool operator>(const T&, const
> optional<T>&);
> +  template <class T> constexpr bool operator>=(const optional<T>&, const
> T&);
> +  template <class T> constexpr bool operator>=(const T&, const
> optional<T>&);
> +
> +  // 20.6.9, specialized algorithms
> +  template <class T> void swap(optional<T>&, optional<T>&) noexcept(see
> below );
> +  template <class T> constexpr optional<see below > make_optional(T&&);
> +  template <class T, class... Args>
> +    constexpr optional<T> make_optional(Args&&... args);
> +  template <class T, class U, class... Args>
> +    constexpr optional<T> make_optional(initializer_list<U> il,
> Args&&... args);
> +
> +  // 20.6.10, hash support
> +  template <class T> struct hash;
> +  template <class T> struct hash<optional<T>>;
> +
> +  template <class T> class optional {
> +  public:
> +    using value_type = T;
> +
> +    // 20.6.3.1, constructors
> +    constexpr optional() noexcept;
> +    constexpr optional(nullopt_t) noexcept;
> +    optional(const optional &);
> +    optional(optional &&) noexcept(see below );
> +    template <class... Args> constexpr explicit optional(in_place_t, Args
> &&...);
> +    template <class U, class... Args>
> +      constexpr explicit optional(in_place_t, initializer_list<U>, Args
> &&...);
> +    template <class U = T>
> +      constexpr EXPLICIT optional(U &&);
> +    template <class U>
> +      constexpr EXPLICIT optional(const optional<U> &);
> +    template <class U>
> +      constexpr EXPLICIT optional(optional<U> &&);
> +
> +    // 20.6.3.2, destructor
> +    ~optional();
> +
> +    // 20.6.3.3, assignment
> +    optional &operator=(nullopt_t) noexcept;
> +    optional &operator=(const optional &);
> +    optional &operator=(optional &&) noexcept(see below );
> +    template <class U = T> optional &operator=(U &&);
> +    template <class U> optional &operator=(const optional<U> &);
> +    template <class U> optional &operator=(optional<U> &&);
> +    template <class... Args> void emplace(Args &&...);
> +    template <class U, class... Args>
> +      void emplace(initializer_list<U>, Args &&...);
> +
> +    // 20.6.3.4, swap
> +    void swap(optional &) noexcept(see below );
> +
> +    // 20.6.3.5, observers
> +    constexpr T const *operator->() const;
> +    constexpr T *operator->();
> +    constexpr T const &operator*() const &;
> +    constexpr T &operator*() &;
> +    constexpr T &&operator*() &&;
> +    constexpr const T &&operator*() const &&;
> +    constexpr explicit operator bool() const noexcept;
> +    constexpr bool has_value() const noexcept;
> +    constexpr T const &value() const &;
> +    constexpr T &value() &;
> +    constexpr T &&value() &&;
> +    constexpr const T &&value() const &&;
> +    template <class U> constexpr T value_or(U &&) const &;
> +    template <class U> constexpr T value_or(U &&) &&;
> +
> +    // 20.6.3.6, modifiers
> +    void reset() noexcept;
> +
> +  private:
> +    T *val; // exposition only
> +  };
> +} // namespace std
> +
> +*/
> +
> +#include <__config>
> +#include <__debug>
> +#include <__functional_base>
> +#include <__undef_min_max>
> +#include <functional>
> +#include <initializer_list>
> +#include <new>
> +#include <stdexcept>
> +#include <type_traits>
> +#include <utility>
> +
> +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
> +#pragma GCC system_header
> +#endif
> +
> +namespace std  // purposefully not using versioning namespace
> +{
> +
> +class _LIBCPP_EXCEPTION_ABI bad_optional_access
> +    : public logic_error
> +{
> +public:
> +    _LIBCPP_INLINE_VISIBILITY
> +    bad_optional_access() : logic_error("bad optional access") {}
> +
> +    // Get the key function ~bad_optional_access() into the dylib
> +    _LIBCPP_FUNC_VIS
> +    virtual ~bad_optional_access() _NOEXCEPT;
> +};
> +
> +}  // std
> +
> +#if _LIBCPP_STD_VER > 14
> +
> +_LIBCPP_BEGIN_NAMESPACE_STD
> +
> +_LIBCPP_NORETURN
> +inline _LIBCPP_INLINE_VISIBILITY
> +void __throw_bad_optional_access() {
> +#ifndef _LIBCPP_NO_EXCEPTIONS
> +        throw bad_optional_access();
> +#else
> +        _VSTD::abort();
> +#endif
> +}
> +
> +struct nullopt_t
> +{
> +    struct __secret_tag { _LIBCPP_INLINE_VISIBILITY explicit
> __secret_tag() = default; };
> +    _LIBCPP_INLINE_VISIBILITY constexpr explicit nullopt_t(__secret_tag,
> __secret_tag) noexcept {}
> +};
> +
> +/* inline */ constexpr nullopt_t nullopt{nullopt_t::__secret_tag{},
> nullopt_t::__secret_tag{}};
> +
> +template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
> +struct __optional_destruct_base;
> +
> +template <class _Tp>
> +struct __optional_destruct_base<_Tp, false>
> +{
> +    typedef _Tp value_type;
> +    static_assert(is_object_v<value_type>,
> +        "instantiation of optional with a non-object type is undefined
> behavior");
> +    union
> +    {
> +        char __null_state_;
> +        value_type __val_;
> +    };
> +    bool __engaged_;
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    ~__optional_destruct_base()
> +    {
> +        if (__engaged_)
> +            __val_.~value_type();
> +    }
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr __optional_destruct_base() noexcept
> +        :  __null_state_(),
> +           __engaged_(false) {}
> +
> +    template <class... _Args>
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr explicit __optional_destruct_base(in_place_t, _Args&&...
> __args)
> +        :  __val_(_VSTD::forward<_Args>(__args)...),
> +           __engaged_(true) {}
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    void reset() noexcept
> +    {
> +        if (__engaged_)
> +        {
> +            __val_.~value_type();
> +            __engaged_ = false;
> +        }
> +    }
> +};
> +
> +template <class _Tp>
> +struct __optional_destruct_base<_Tp, true>
> +{
> +    typedef _Tp value_type;
> +    static_assert(is_object_v<value_type>,
> +        "instantiation of optional with a non-object type is undefined
> behavior");
> +    union
> +    {
> +        char __null_state_;
> +        value_type __val_;
> +    };
> +    bool __engaged_;
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr __optional_destruct_base() noexcept
> +        :  __null_state_(),
> +           __engaged_(false) {}
> +
> +    template <class... _Args>
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr explicit __optional_destruct_base(in_place_t, _Args&&...
> __args)
> +        :  __val_(_VSTD::forward<_Args>(__args)...),
> +           __engaged_(true) {}
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    void reset() noexcept
> +    {
> +        if (__engaged_)
> +        {
> +            __engaged_ = false;
> +        }
> +    }
> +};
> +
> +template <class _Tp, bool = is_reference<_Tp>::value>
> +struct __optional_storage_base : __optional_destruct_base<_Tp>
> +{
> +    using __base = __optional_destruct_base<_Tp>;
> +    using value_type = _Tp;
> +    using __base::__base;
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr bool has_value() const noexcept
> +    {
> +        return this->__engaged_;
> +    }
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr value_type& __get() & noexcept
> +    {
> +        return this->__val_;
> +    }
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr const value_type& __get() const& noexcept
> +    {
> +        return this->__val_;
> +    }
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr value_type&& __get() && noexcept
> +    {
> +        return _VSTD::move(this->__val_);
> +    }
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr const value_type&& __get() const&& noexcept
> +    {
> +        return _VSTD::move(this->__val_);
> +    }
> +
> +    template <class... _Args>
> +    _LIBCPP_INLINE_VISIBILITY
> +    void __construct(_Args&&... __args)
> +    {
> +        _LIBCPP_ASSERT(!has_value(), "__construct called for engaged
> __optional_storage");
> +        ::new((void*)_VSTD::addressof(this->__val_))
> value_type(_VSTD::forward<_Args>(__args)...);
> +        this->__engaged_ = true;
> +    }
> +
> +    template <class _That>
> +    _LIBCPP_INLINE_VISIBILITY
> +    void __construct_from(_That&& __opt)
> +    {
> +        if (__opt.has_value())
> +            __construct(_VSTD::forward<_That>(__opt).__get());
> +    }
> +
> +    template <class _That>
> +    _LIBCPP_INLINE_VISIBILITY
> +    void __assign_from(_That&& __opt)
> +    {
> +        if (this->__engaged_ == __opt.has_value())
> +        {
> +            if (this->__engaged_)
> +                this->__val_ = _VSTD::forward<_That>(__opt).__get();
> +        }
> +        else
> +        {
> +            if (this->__engaged_)
> +                this->reset();
> +            else
> +                __construct(_VSTD::forward<_That>(__opt).__get());
> +        }
> +    }
> +};
> +
> +// optional<T&> is currently required ill-formed, however it may to be in
> the
> +// future. For this reason it has already been implemented to ensure we
> can
> +// make the change in an ABI compatible manner.
> +template <class _Tp>
> +struct __optional_storage_base<_Tp, true>
> +{
> +    using value_type = _Tp;
> +    using __raw_type = remove_reference_t<_Tp>;
> +    __raw_type* __value_;
> +
> +    template <class _Up>
> +    static constexpr bool __can_bind_reference() {
> +        using _RawUp = typename remove_reference<_Up>::type;
> +        using _UpPtr = _RawUp*;
> +        using _RawTp = typename remove_reference<_Tp>::type;
> +        using _TpPtr = _RawTp*;
> +        using _CheckLValueArg = integral_constant<bool,
> +            (is_lvalue_reference<_Up>::value && is_convertible<_UpPtr,
> _TpPtr>::value)
> +        ||  is_same<_RawUp, reference_wrapper<_RawTp>>::value
> +        ||  is_same<_RawUp, reference_wrapper<typename
> remove_const<_RawTp>::type>>::value
> +        >;
> +        return (is_lvalue_reference<_Tp>::value &&
> _CheckLValueArg::value)
> +            || (is_rvalue_reference<_Tp>::value &&
> !is_lvalue_reference<_Up>::value &&
> +                is_convertible<_UpPtr, _TpPtr>::value);
> +    }
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr __optional_storage_base() noexcept
> +        :  __value_(nullptr) {}
> +
> +    template <class _UArg>
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr explicit __optional_storage_base(in_place_t, _UArg&&
> __uarg)
> +        :  __value_(_VSTD::addressof(__uarg))
> +    {
> +      static_assert(__can_bind_reference<_UArg>(),
> +        "Attempted to construct a reference element in tuple from a "
> +        "possible temporary");
> +    }
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    void reset() noexcept { __value_ = nullptr; }
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr bool has_value() const noexcept
> +      { return __value_ != nullptr; }
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr value_type& __get() const& noexcept
> +      { return *__value_; }
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr value_type&& __get() const&& noexcept
> +      { return _VSTD::forward<value_type>(*__value_); }
> +
> +    template <class _UArg>
> +    _LIBCPP_INLINE_VISIBILITY
> +    void __construct(_UArg&& __val)
> +    {
> +        _LIBCPP_ASSERT(!has_value(), "__construct called for engaged
> __optional_storage");
> +        static_assert(__can_bind_reference<_UArg>(),
> +            "Attempted to construct a reference element in tuple from a "
> +            "possible temporary");
> +        __value_ = _VSTD::addressof(__val);
> +    }
> +
> +    template <class _That>
> +    _LIBCPP_INLINE_VISIBILITY
> +    void __construct_from(_That&& __opt)
> +    {
> +        if (__opt.has_value())
> +            __construct(_VSTD::forward<_That>(__opt).__get());
> +    }
> +
> +    template <class _That>
> +    _LIBCPP_INLINE_VISIBILITY
> +    void __assign_from(_That&& __opt)
> +    {
> +        if (has_value() == __opt.has_value())
> +        {
> +            if (has_value())
> +                *__value_ = _VSTD::forward<_That>(__opt).__get();
> +        }
> +        else
> +        {
> +            if (has_value())
> +                reset();
> +            else
> +                __construct(_VSTD::forward<_That>(__opt).__get());
> +        }
> +    }
> +};
> +
> +template <class _Tp, bool = is_trivially_copyable<_Tp>::value>
> +struct __optional_storage;
> +
> +template <class _Tp>
> +struct __optional_storage<_Tp, true> : __optional_storage_base<_Tp>
> +{
> +    using __optional_storage_base<_Tp>::__optional_storage_base;
> +};
> +
> +template <class _Tp>
> +struct __optional_storage<_Tp, false> : __optional_storage_base<_Tp>
> +{
> +    using value_type = _Tp;
> +    using __optional_storage_base<_Tp>::__optional_storage_base;
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    __optional_storage() = default;
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    __optional_storage(const __optional_storage& __opt)
> +    {
> +        this->__construct_from(__opt);
> +    }
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    __optional_storage(__optional_storage&& __opt)
> +        noexcept(is_nothrow_move_constructible_v<value_type>)
> +    {
> +        this->__construct_from(_VSTD::move(__opt));
> +    }
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    __optional_storage& operator=(const __optional_storage& __opt)
> +    {
> +        this->__assign_from(__opt);
> +        return *this;
> +    }
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    __optional_storage& operator=(__optional_storage&& __opt)
> +        noexcept(is_nothrow_move_assignable_v<value_type> &&
> +                 is_nothrow_move_constructible_v<value_type>)
> +    {
> +        this->__assign_from(_VSTD::move(__opt));
> +        return *this;
> +    }
> +};
> +
> +template <class _Tp>
> +using __optional_sfinae_ctor_base_t = __sfinae_ctor_base<
> +    is_copy_constructible<_Tp>::value,
> +    is_move_constructible<_Tp>::value
> +>;
> +
> +template <class _Tp>
> +using __optional_sfinae_assign_base_t = __sfinae_assign_base<
> +    (is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value
> ),
> +    (is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value)
> +>;
> +
> +template <class _Tp>
> +class optional
> +    : private __optional_storage<_Tp>
> +    , private __optional_sfinae_ctor_base_t<_Tp>
> +    , private __optional_sfinae_assign_base_t<_Tp>
> +{
> +    using __base = __optional_storage<_Tp>;
> +public:
> +    using value_type = _Tp;
> +
> +private:
> +     // Disable the reference extension using this static assert.
> +    static_assert(!is_same_v<value_type, in_place_t>,
> +        "instantiation of optional with in_place_t is ill-formed");
> +    static_assert(!is_same_v<__uncvref_t<value_type>, nullopt_t>,
> +        "instantiation of optional with nullopt_t is ill-formed");
> +    static_assert(!is_reference_v<value_type>,
> +        "instantiation of optional with a reference type is ill-formed");
> +    static_assert(is_destructible_v<value_type>,
> +        "instantiation of optional with a non-destructible type is
> ill-formed");
> +
> +    // LWG2756: conditionally explicit conversion from _Up
> +    struct _CheckOptionalArgsConstructor {
> +      template <class _Up>
> +      static constexpr bool __enable_implicit() {
> +          return is_constructible_v<_Tp, _Up&&> &&
> +                 is_convertible_v<_Up&&, _Tp>;
> +      }
> +
> +      template <class _Up>
> +      static constexpr bool __enable_explicit() {
> +          return is_constructible_v<_Tp, _Up&&> &&
> +                 !is_convertible_v<_Up&&, _Tp>;
> +      }
> +    };
> +    template <class _Up>
> +    using _CheckOptionalArgsCtor = conditional_t<
> +        !is_same_v<in_place_t, _Up> &&
> +        !is_same_v<decay_t<_Up>, optional>,
> +        _CheckOptionalArgsConstructor,
> +        __check_tuple_constructor_fail
> +    >;
> +    template <class _QualUp>
> +    struct _CheckOptionalLikeConstructor {
> +      template <class _Up, class _Opt = optional<_Up>>
> +      using __check_constructible_from_opt = __lazy_or<
> +          is_constructible<_Tp, _Opt&>,
> +          is_constructible<_Tp, _Opt const&>,
> +          is_constructible<_Tp, _Opt&&>,
> +          is_constructible<_Tp, _Opt const&&>,
> +          is_convertible<_Opt&, _Tp>,
> +          is_convertible<_Opt const&, _Tp>,
> +          is_convertible<_Opt&&, _Tp>,
> +          is_convertible<_Opt const&&, _Tp>
> +      >;
> +      template <class _Up, class _Opt = optional<_Up>>
> +      using __check_assignable_from_opt = __lazy_or<
> +          is_assignable<_Tp&, _Opt&>,
> +          is_assignable<_Tp&, _Opt const&>,
> +          is_assignable<_Tp&, _Opt&&>,
> +          is_assignable<_Tp&, _Opt const&&>
> +      >;
> +      template <class _Up, class _QUp = _QualUp>
> +      static constexpr bool __enable_implicit() {
> +          return is_convertible<_QUp, _Tp>::value &&
> +              !__check_constructible_from_opt<_Up>::value;
> +      }
> +      template <class _Up, class _QUp = _QualUp>
> +      static constexpr bool __enable_explicit() {
> +          return !is_convertible<_QUp, _Tp>::value &&
> +              !__check_constructible_from_opt<_Up>::value;
> +      }
> +      template <class _Up, class _QUp = _QualUp>
> +      static constexpr bool __enable_assign() {
> +          // Construction and assignability of _Qup to _Tp has already
> been
> +          // checked.
> +          return !__check_constructible_from_opt<_Up>::value &&
> +              !__check_assignable_from_opt<_Up>::value;
> +      }
> +    };
> +
> +    template <class _Up, class _QualUp>
> +    using _CheckOptionalLikeCtor = conditional_t<
> +      __lazy_and<
> +          __lazy_not<is_same<_Up, _Tp>>,
> +          is_constructible<_Tp, _QualUp>
> +      >::value,
> +      _CheckOptionalLikeConstructor<_QualUp>,
> +      __check_tuple_constructor_fail
> +    >;
> +    template <class _Up, class _QualUp>
> +    using _CheckOptionalLikeAssign = conditional_t<
> +      __lazy_and<
> +          __lazy_not<is_same<_Up, _Tp>>,
> +          is_constructible<_Tp, _QualUp>,
> +          is_assignable<_Tp&, _QualUp>
> +      >::value,
> +      _CheckOptionalLikeConstructor<_QualUp>,
> +      __check_tuple_constructor_fail
> +    >;
> +public:
> +
> +    _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
> +    _LIBCPP_INLINE_VISIBILITY optional(const optional&) = default;
> +    _LIBCPP_INLINE_VISIBILITY optional(optional&&) = default;
> +    _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
> +
> +    template <class... _Args, class = enable_if_t<
> +        is_constructible_v<value_type, _Args...>>
> +    >
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr explicit optional(in_place_t, _Args&&... __args)
> +        : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
> +
> +    template <class _Up, class... _Args, class = enable_if_t<
> +        is_constructible_v<value_type, initializer_list<_Up>&, _Args...>>
> +    >
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr explicit optional(in_place_t, initializer_list<_Up> __il,
> _Args&&... __args)
> +        : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
> +
> +    template <class _Up = value_type, enable_if_t<
> +        _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>()
> +    , int> = 0>
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr optional(_Up&& __v)
> +        : __base(in_place, _VSTD::forward<_Up>(__v)) {}
> +
> +    template <class _Up, enable_if_t<
> +        _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>()
> +    , int> = 0>
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr explicit optional(_Up&& __v)
> +        : __base(in_place, _VSTD::forward<_Up>(__v)) {}
> +
> +    // LWG2756: conditionally explicit conversion from const
> optional<_Up>&
> +    template <class _Up, enable_if_t<
> +        _CheckOptionalLikeCtor<_Up, _Up const&>::template
> __enable_implicit<_Up>()
> +    , int> = 0>
> +    _LIBCPP_INLINE_VISIBILITY
> +    optional(const optional<_Up>& __v)
> +    {
> +        this->__construct_from(__v);
> +    }
> +    template <class _Up, enable_if_t<
> +        _CheckOptionalLikeCtor<_Up, _Up const&>::template
> __enable_explicit<_Up>()
> +    , int> = 0>
> +    _LIBCPP_INLINE_VISIBILITY
> +    explicit optional(const optional<_Up>& __v)
> +    {
> +        this->__construct_from(__v);
> +    }
> +
> +    // LWG2756: conditionally explicit conversion from optional<_Up>&&
> +    template <class _Up, enable_if_t<
> +        _CheckOptionalLikeCtor<_Up, _Up &&>::template
> __enable_implicit<_Up>()
> +    , int> = 0>
> +    _LIBCPP_INLINE_VISIBILITY
> +    optional(optional<_Up>&& __v)
> +    {
> +        this->__construct_from(_VSTD::move(__v));
> +    }
> +    template <class _Up, enable_if_t<
> +        _CheckOptionalLikeCtor<_Up, _Up &&>::template
> __enable_explicit<_Up>()
> +    , int> = 0>
> +    _LIBCPP_INLINE_VISIBILITY
> +    explicit optional(optional<_Up>&& __v)
> +    {
> +        this->__construct_from(_VSTD::move(__v));
> +    }
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    optional& operator=(nullopt_t) noexcept
> +    {
> +        reset();
> +        return *this;
> +    }
> +
> +    _LIBCPP_INLINE_VISIBILITY optional& operator=(const optional&) =
> default;
> +    _LIBCPP_INLINE_VISIBILITY optional& operator=(optional&&) = default;
> +
> +    // LWG2756
> +    template <class _Up = value_type,
> +              class = enable_if_t
> +                      <
> +                          !is_same_v<_Up, optional> &&
> +                          !(is_same_v<_Up, value_type> &&
> is_scalar_v<value_type>) &&
> +                          is_constructible_v<value_type, _Up> &&
> +                          is_assignable_v<value_type&, _Up>
> +                      >
> +             >
> +    _LIBCPP_INLINE_VISIBILITY
> +    optional&
> +    operator=(_Up&& __v)
> +    {
> +        if (this->has_value())
> +            this->__get() = _VSTD::forward<_Up>(__v);
> +        else
> +            this->__construct(_VSTD::forward<_Up>(__v));
> +        return *this;
> +    }
> +
> +    // LWG2756
> +    template <class _Up, enable_if_t<
> +        _CheckOptionalLikeAssign<_Up, _Up const&>::template
> __enable_assign<_Up>()
> +    , int> = 0>
> +    _LIBCPP_INLINE_VISIBILITY
> +    optional&
> +    operator=(const optional<_Up>& __v)
> +    {
> +        this->__assign_from(__v);
> +        return *this;
> +    }
> +
> +    // LWG2756
> +    template <class _Up, enable_if_t<
> +        _CheckOptionalLikeCtor<_Up, _Up &&>::template
> __enable_assign<_Up>()
> +    , int> = 0>
> +    _LIBCPP_INLINE_VISIBILITY
> +    optional&
> +    operator=(optional<_Up>&& __v)
> +    {
> +        this->__assign_from(_VSTD::move(__v));
> +        return *this;
> +    }
> +
> +    template <class... _Args,
> +              class = enable_if_t
> +                      <
> +                          is_constructible_v<value_type, _Args...>
> +                      >
> +             >
> +    _LIBCPP_INLINE_VISIBILITY
> +    void
> +    emplace(_Args&&... __args)
> +    {
> +        reset();
> +        this->__construct(_VSTD::forward<_Args>(__args)...);
> +    }
> +
> +    template <class _Up, class... _Args,
> +              class = enable_if_t
> +                      <
> +                          is_constructible_v<value_type,
> initializer_list<_Up>&, _Args...>
> +                      >
> +             >
> +    _LIBCPP_INLINE_VISIBILITY
> +    void
> +    emplace(initializer_list<_Up> __il, _Args&&... __args)
> +    {
> +        reset();
> +        this->__construct(__il, _VSTD::forward<_Args>(__args)...);
> +    }
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    void swap(optional& __opt)
> +        noexcept(is_nothrow_move_constructible_v<value_type> &&
> +                 is_nothrow_swappable_v<value_type>)
> +    {
> +        if (this->has_value() == __opt.has_value())
> +        {
> +            using _VSTD::swap;
> +            if (this->has_value())
> +                swap(this->__get(), __opt.__get());
> +        }
> +        else
> +        {
> +            if (this->has_value())
> +            {
> +                __opt.__construct(_VSTD::move(this->__get()));
> +                reset();
> +            }
> +            else
> +            {
> +                this->__construct(_VSTD::move(__opt.__get()));
> +                __opt.reset();
> +            }
> +        }
> +    }
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr
> +    add_pointer_t<value_type const>
> +    operator->() const
> +    {
> +        _LIBCPP_ASSERT(this->has_value(), "optional operator-> called
> for disengaged value");
> +#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
> +        return _VSTD::addressof(this->__get());
> +#else
> +        return __operator_arrow(__has_operator_addressof<value_type>{},
> this->__get());
> +#endif
> +    }
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr
> +    add_pointer_t<value_type>
> +    operator->()
> +    {
> +        _LIBCPP_ASSERT(this->has_value(), "optional operator-> called
> for disengaged value");
> +#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
> +        return _VSTD::addressof(this->__get());
> +#else
> +        return __operator_arrow(__has_operator_addressof<value_type>{},
> this->__get());
> +#endif
> +    }
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr
> +    const value_type&
> +    operator*() const&
> +    {
> +        _LIBCPP_ASSERT(this->has_value(), "optional operator* called for
> disengaged value");
> +        return this->__get();
> +    }
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr
> +    value_type&
> +    operator*() &
> +    {
> +        _LIBCPP_ASSERT(this->has_value(), "optional operator* called for
> disengaged value");
> +        return this->__get();
> +    }
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr
> +    value_type&&
> +    operator*() &&
> +    {
> +        _LIBCPP_ASSERT(this->has_value(), "optional operator* called for
> disengaged value");
> +        return _VSTD::move(this->__get());
> +    }
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr
> +    const value_type&&
> +    operator*() const&&
> +    {
> +        _LIBCPP_ASSERT(this->has_value(), "optional operator* called for
> disengaged value");
> +        return _VSTD::move(this->__get());
> +    }
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr explicit operator bool() const noexcept { return
> has_value(); }
> +
> +    using __base::has_value;
> +    using __base::__get;
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr value_type const& value() const&
> +    {
> +        if (!this->has_value())
> +            __throw_bad_optional_access();
> +        return this->__get();
> +    }
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr value_type& value() &
> +    {
> +        if (!this->has_value())
> +            __throw_bad_optional_access();
> +        return this->__get();
> +    }
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr value_type&& value() &&
> +    {
> +        if (!this->has_value())
> +            __throw_bad_optional_access();
> +        return _VSTD::move(this->__get());
> +    }
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr value_type const&& value() const&&
> +    {
> +        if (!this->has_value())
> +            __throw_bad_optional_access();
> +        return _VSTD::move(this->__get());
> +    }
> +
> +    template <class _Up>
> +    _LIBCPP_INLINE_VISIBILITY
> +    constexpr value_type value_or(_Up&& __v) const&
> +    {
> +        static_assert(is_copy_constructible_v<value_type>,
> +                      "optional<T>::value_or: T must be copy
> constructible");
> +        static_assert(is_convertible_v<_Up, value_type>,
> +                      "optional<T>::value_or: U must be convertible to
> T");
> +        return this->has_value() ? this->__get() :
> +                                  static_cast<value_type>(_VSTD:
> :forward<_Up>(__v));
> +    }
> +
> +    template <class _Up>
> +    _LIBCPP_INLINE_VISIBILITY
> +    value_type value_or(_Up&& __v) &&
> +    {
> +        static_assert(is_move_constructible_v<value_type>,
> +                      "optional<T>::value_or: T must be move
> constructible");
> +        static_assert(is_convertible_v<_Up, value_type>,
> +                      "optional<T>::value_or: U must be convertible to
> T");
> +        return this->has_value() ? _VSTD::move(this->__get()) :
> +                                  static_cast<value_type>(_VSTD:
> :forward<_Up>(__v));
> +    }
> +
> +    using __base::reset;
> +
> +private:
> +    template <class _Up>
> +    _LIBCPP_INLINE_VISIBILITY
> +    static _Up*
> +    __operator_arrow(true_type, _Up& __x)
> +    {
> +        return _VSTD::addressof(__x);
> +    }
> +
> +    template <class _Up>
> +    _LIBCPP_INLINE_VISIBILITY
> +    static constexpr _Up*
> +    __operator_arrow(false_type, _Up& __x)
> +    {
> +        return &__x;
> +    }
> +};
> +
> +// Comparisons between optionals
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +enable_if_t<
> +    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
> +        _VSTD::declval<const _Tp&>()), bool>,
> +    bool
> +>
> +operator==(const optional<_Tp>& __x, const optional<_Tp>& __y)
> +{
> +    if (static_cast<bool>(__x) != static_cast<bool>(__y))
> +        return false;
> +    if (!static_cast<bool>(__x))
> +        return true;
> +    return *__x == *__y;
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +enable_if_t<
> +    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
> +        _VSTD::declval<const _Tp&>()), bool>,
> +    bool
> +>
> +operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y)
> +{
> +    if (static_cast<bool>(__x) != static_cast<bool>(__y))
> +        return true;
> +    if (!static_cast<bool>(__x))
> +        return false;
> +    return *__x != *__y;
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +enable_if_t<
> +    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
> +        _VSTD::declval<const _Tp&>()), bool>,
> +    bool
> +>
> +operator<(const optional<_Tp>& __x, const optional<_Tp>& __y)
> +{
> +    if (!static_cast<bool>(__y))
> +        return false;
> +    if (!static_cast<bool>(__x))
> +        return true;
> +    return *__x < *__y;
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +enable_if_t<
> +    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
> +        _VSTD::declval<const _Tp&>()), bool>,
> +    bool
> +>
> +operator>(const optional<_Tp>& __x, const optional<_Tp>& __y)
> +{
> +    if (!static_cast<bool>(__x))
> +        return false;
> +    if (!static_cast<bool>(__y))
> +        return true;
> +    return *__x > *__y;
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +enable_if_t<
> +    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
> +        _VSTD::declval<const _Tp&>()), bool>,
> +    bool
> +>
> +operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y)
> +{
> +    if (!static_cast<bool>(__x))
> +        return true;
> +    if (!static_cast<bool>(__y))
> +        return false;
> +    return *__x <= *__y;
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +enable_if_t<
> +    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
> +        _VSTD::declval<const _Tp&>()), bool>,
> +    bool
> +>
> +operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y)
> +{
> +    if (!static_cast<bool>(__y))
> +        return true;
> +    if (!static_cast<bool>(__x))
> +        return false;
> +    return *__x >= *__y;
> +}
> +
> +// Comparisons with nullopt
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +bool
> +operator==(const optional<_Tp>& __x, nullopt_t) noexcept
> +{
> +    return !static_cast<bool>(__x);
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +bool
> +operator==(nullopt_t, const optional<_Tp>& __x) noexcept
> +{
> +    return !static_cast<bool>(__x);
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +bool
> +operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
> +{
> +    return static_cast<bool>(__x);
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +bool
> +operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
> +{
> +    return static_cast<bool>(__x);
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +bool
> +operator<(const optional<_Tp>&, nullopt_t) noexcept
> +{
> +    return false;
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +bool
> +operator<(nullopt_t, const optional<_Tp>& __x) noexcept
> +{
> +    return static_cast<bool>(__x);
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +bool
> +operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
> +{
> +    return !static_cast<bool>(__x);
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +bool
> +operator<=(nullopt_t, const optional<_Tp>& __x) noexcept
> +{
> +    return true;
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +bool
> +operator>(const optional<_Tp>& __x, nullopt_t) noexcept
> +{
> +    return static_cast<bool>(__x);
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +bool
> +operator>(nullopt_t, const optional<_Tp>& __x) noexcept
> +{
> +    return false;
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +bool
> +operator>=(const optional<_Tp>&, nullopt_t) noexcept
> +{
> +    return true;
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +bool
> +operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
> +{
> +    return !static_cast<bool>(__x);
> +}
> +
> +// Comparisons with T
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +enable_if_t<
> +    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
> +        _VSTD::declval<const _Tp&>()), bool>,
> +    bool
> +>
> +operator==(const optional<_Tp>& __x, const _Tp& __v)
> +{
> +    return static_cast<bool>(__x) ? *__x == __v : false;
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +enable_if_t<
> +    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
> +        _VSTD::declval<const _Tp&>()), bool>,
> +    bool
> +>
> +operator==(const _Tp& __v, const optional<_Tp>& __x)
> +{
> +    return static_cast<bool>(__x) ? __v == *__x : false;
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +enable_if_t<
> +    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
> +        _VSTD::declval<const _Tp&>()), bool>,
> +    bool
> +>
> +operator!=(const optional<_Tp>& __x, const _Tp& __v)
> +{
> +    return static_cast<bool>(__x) ? *__x != __v : true;
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +enable_if_t<
> +    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
> +        _VSTD::declval<const _Tp&>()), bool>,
> +    bool
> +>
> +operator!=(const _Tp& __v, const optional<_Tp>& __x)
> +{
> +    return static_cast<bool>(__x) ? __v != *__x : true;
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +enable_if_t<
> +    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
> +        _VSTD::declval<const _Tp&>()), bool>,
> +    bool
> +>
> +operator<(const optional<_Tp>& __x, const _Tp& __v)
> +{
> +    return static_cast<bool>(__x) ? *__x < __v : true;
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +enable_if_t<
> +    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
> +        _VSTD::declval<const _Tp&>()), bool>,
> +    bool
> +>
> +operator<(const _Tp& __v, const optional<_Tp>& __x)
> +{
> +    return static_cast<bool>(__x) ? __v < *__x : false;
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +enable_if_t<
> +    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
> +        _VSTD::declval<const _Tp&>()), bool>,
> +    bool
> +>
> +operator<=(const optional<_Tp>& __x, const _Tp& __v)
> +{
> +    return static_cast<bool>(__x) ? *__x <= __v : true;
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +enable_if_t<
> +    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
> +        _VSTD::declval<const _Tp&>()), bool>,
> +    bool
> +>
> +operator<=(const _Tp& __v, const optional<_Tp>& __x)
> +{
> +    return static_cast<bool>(__x) ? __v <= *__x : false;
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +enable_if_t<
> +    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
> +        _VSTD::declval<const _Tp&>()), bool>,
> +    bool
> +>
> +operator>(const optional<_Tp>& __x, const _Tp& __v)
> +{
> +    return static_cast<bool>(__x) ? *__x > __v : false;
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +enable_if_t<
> +    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
> +        _VSTD::declval<const _Tp&>()), bool>,
> +    bool
> +>
> +operator>(const _Tp& __v, const optional<_Tp>& __x)
> +{
> +    return static_cast<bool>(__x) ? __v > *__x : true;
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +enable_if_t<
> +    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
> +        _VSTD::declval<const _Tp&>()), bool>,
> +    bool
> +>
> +operator>=(const optional<_Tp>& __x, const _Tp& __v)
> +{
> +    return static_cast<bool>(__x) ? *__x >= __v : false;
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +enable_if_t<
> +    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
> +        _VSTD::declval<const _Tp&>()), bool>,
> +    bool
> +>
> +operator>=(const _Tp& __v, const optional<_Tp>& __x)
> +{
> +    return static_cast<bool>(__x) ? __v >= *__x : true;
> +}
> +
> +
> +template <class _Tp>
> +inline _LIBCPP_INLINE_VISIBILITY
> +enable_if_t<
> +    is_move_constructible_v<_Tp> && is_swappable_v<_Tp>,
> +    void
> +>
> +swap(optional<_Tp>& __x, optional<_Tp>& __y)
> noexcept(noexcept(__x.swap(__y)))
> +{
> +    __x.swap(__y);
> +}
> +
> +template <class _Tp>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +optional<decay_t<_Tp>> make_optional(_Tp&& __v)
> +{
> +    return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v));
> +}
> +
> +template <class _Tp, class... _Args>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +optional<_Tp> make_optional(_Args&&... __args)
> +{
> +    return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...);
> +}
> +
> +template <class _Tp, class _Up, class... _Args>
> +_LIBCPP_INLINE_VISIBILITY constexpr
> +optional<_Tp> make_optional(initializer_list<_Up> __il,  _Args&&...
> __args)
> +{
> +    return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args).
> ..);
> +}
> +
> +template <class _Tp>
> +struct _LIBCPP_TYPE_VIS_ONLY hash<optional<_Tp> >
> +{
> +    typedef optional<_Tp> argument_type;
> +    typedef size_t        result_type;
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    result_type operator()(const argument_type& __opt) const _NOEXCEPT
> +    {
> +        return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0;
> +    }
> +};
> +
> +_LIBCPP_END_NAMESPACE_STD
> +
> +#endif  // _LIBCPP_STD_VER > 14
> +
> +#endif  // _LIBCPP_OPTIONAL
>
> Modified: libcxx/trunk/include/type_traits
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/typ
> e_traits?rev=283980&r1=283979&r2=283980&view=diff
> ============================================================
> ==================
> --- libcxx/trunk/include/type_traits (original)
> +++ libcxx/trunk/include/type_traits Wed Oct 12 02:46:20 2016
> @@ -425,7 +425,7 @@ template <bool _Bp, class _Tp = void> us
>  #endif
>
>  // addressof
> -#if __has_builtin(__builtin_addressof) || _GNUC_VER >= 700
> +#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
>
>  template <class _Tp>
>  inline _LIBCPP_CONSTEXPR_AFTER_CXX14
> @@ -446,7 +446,7 @@ addressof(_Tp& __x) _NOEXCEPT
>      return (_Tp*)&reinterpret_cast<const volatile char&>(__x);
>  }
>
> -#endif // __has_builtin(__builtin_addressof)
> +#endif // _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
>
>  #if defined(_LIBCPP_HAS_OBJC_ARC) && !defined(_LIBCPP_PREDEFINED_OB
> JC_ARC_ADDRESSOF)
>  // Objective-C++ Automatic Reference Counting uses qualified pointers
>
> Modified: libcxx/trunk/src/optional.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/optiona
> l.cpp?rev=283980&r1=283979&r2=283980&view=diff
> ============================================================
> ==================
> --- libcxx/trunk/src/optional.cpp (original)
> +++ libcxx/trunk/src/optional.cpp Wed Oct 12 02:46:20 2016
> @@ -7,18 +7,18 @@
>  //
>  //===------------------------------------------------------
> ----------------===//
>
> +#include "optional"
>  #include "experimental/optional"
>
> -_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
> +namespace std
> +{
>
> -#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
> +bad_optional_access::~bad_optional_access() _NOEXCEPT = default;
>
> -bad_optional_access::~bad_optional_access() _NOEXCEPT {}
> +} // std
>
> -#else
> +_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
>
>  bad_optional_access::~bad_optional_access() _NOEXCEPT = default;
>
> -#endif
> -
>  _LIBCPP_END_NAMESPACE_EXPERIMENTAL
>
> Added: libcxx/trunk/test/libcxx/utilities/optional/optional.object/
> optional.object.assign/copy.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx
> /utilities/optional/optional.object/optional.object.assign/
> copy.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/libcxx/utilities/optional/optional.object/
> optional.object.assign/copy.pass.cpp (added)
> +++ libcxx/trunk/test/libcxx/utilities/optional/optional.object/
> optional.object.assign/copy.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,81 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// XFAIL: libcpp-no-exceptions
> +// <optional>
> +
> +// optional<T>& operator=(const optional<T>& rhs);
> +
> +#include <optional>
> +#include <string>
> +#include <type_traits>
> +
> +using std::optional;
> +
> +struct X {};
> +
> +struct Y
> +{
> +    Y() = default;
> +    Y& operator=(const Y&) { return *this; }
> +};
> +
> +struct Z1
> +{
> +    Z1() = default;
> +    Z1(Z1&&) = default;
> +    Z1(const Z1&) = default;
> +    Z1& operator=(Z1&&) = default;
> +    Z1& operator=(const Z1&) = delete;
> +};
> +
> +struct Z2
> +{
> +    Z2() = default;
> +    Z2(Z2&&) = default;
> +    Z2(const Z2&) = delete;
> +    Z2& operator=(Z2&&) = default;
> +    Z2& operator=(const Z2&) = default;
> +};
> +
> +#if __cplusplus >= 201402
> +template <class T>
> +constexpr bool
> +test()
> +{
> +    optional<T> opt;
> +    optional<T> opt2;
> +    opt = opt2;
> +    return true;
> +}
> +#endif
> +
> +int main()
> +{
> +    {
> +        using T = int;
> +        static_assert((std::is_trivially_copy_assignable<optional<T>>::value),
> "");
> +#if __cplusplus >= 201402
> +        static_assert(test<T>(), "");
> +#endif
> +    }
> +    {
> +        using T = X;
> +        static_assert((std::is_trivially_copy_assignable<optional<T>>::value),
> "");
> +#if __cplusplus >= 201402
> +        static_assert(test<T>(), "");
> +#endif
> +    }
> +    static_assert(!(std::is_trivially_copy_assignable<optional<Y>>::value),
> "");
> +    static_assert(!(std::is_trivially_copy_assignable<optional<std::string>>::value),
> "");
> +
> +    static_assert(!(std::is_copy_assignable<optional<Z1>>::value), "");
> +    static_assert(!(std::is_copy_assignable<optional<Z2>>::value), "");
> +}
>
> Added: libcxx/trunk/test/libcxx/utilities/optional/optional.object/
> optional.object.assign/move.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx
> /utilities/optional/optional.object/optional.object.assign/
> move.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/libcxx/utilities/optional/optional.object/
> optional.object.assign/move.pass.cpp (added)
> +++ libcxx/trunk/test/libcxx/utilities/optional/optional.object/
> optional.object.assign/move.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,78 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// XFAIL: libcpp-no-exceptions
> +// <optional>
> +
> +// optional<T>& operator=(optional<T>&& rhs);
> +
> +#include <optional>
> +#include <string>
> +#include <type_traits>
> +#include <utility>
> +
> +using std::optional;
> +
> +struct X {};
> +
> +struct Y
> +{
> +    Y() = default;
> +    Y& operator=(Y&&) { return *this; }
> +};
> +
> +struct Z1
> +{
> +    Z1() = default;
> +    Z1(Z1&&) = default;
> +    Z1& operator=(Z1&&) = delete;
> +};
> +
> +struct Z2
> +{
> +    Z2() = default;
> +    Z2(Z2&&) = delete;
> +    Z2& operator=(Z2&&) = default;
> +};
> +
> +#if __cplusplus >= 201402
> +template <class T>
> +constexpr bool
> +test()
> +{
> +    optional<T> opt;
> +    optional<T> opt2;
> +    opt = std::move(opt2);
> +    return true;
> +}
> +#endif
> +
> +int main()
> +{
> +    {
> +        using T = int;
> +        static_assert((std::is_trivially_copy_constructible<optional<T>>::value),
> "");
> +#if __cplusplus >= 201402
> +        static_assert(test<T>(), "");
> +#endif
> +    }
> +    {
> +        using T = X;
> +        static_assert((std::is_trivially_copy_constructible<optional<T>>::value),
> "");
> +#if __cplusplus >= 201402
> +        static_assert(test<T>(), "");
> +#endif
> +    }
> +    static_assert(!(std::is_trivially_move_assignable<optional<Y>>::value),
> "");
> +    static_assert(!(std::is_trivially_move_assignable<optional<std::string>>::value),
> "");
> +
> +    static_assert(!(std::is_move_assignable<optional<Z1>>::value), "");
> +    static_assert(!(std::is_move_assignable<optional<Z2>>::value), "");
> +}
>
> Added: libcxx/trunk/test/libcxx/utilities/optional/optional.object/
> optional.object.ctor/copy.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx
> /utilities/optional/optional.object/optional.object.ctor/
> copy.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/libcxx/utilities/optional/optional.object/
> optional.object.ctor/copy.pass.cpp (added)
> +++ libcxx/trunk/test/libcxx/utilities/optional/optional.object/
> optional.object.ctor/copy.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,59 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// XFAIL: libcpp-no-exceptions
> +// <optional>
> +
> +// optional(const optional<T>& rhs);
> +
> +#include <optional>
> +#include <string>
> +#include <type_traits>
> +
> +using std::optional;
> +
> +struct X {};
> +
> +struct Y
> +{
> +    Y() = default;
> +    Y(const Y&) {}
> +};
> +
> +struct Z
> +{
> +    Z() = default;
> +    Z(Z&&) = delete;
> +    Z(const Z&) = delete;
> +    Z& operator=(Z&&) = delete;
> +    Z& operator=(const Z&) = delete;
> +};
> +
> +int main()
> +{
> +    {
> +        using T = int;
> +        static_assert((std::is_trivially_copy_constructible<optional<T>>::value),
> "");
> +        constexpr optional<T> opt;
> +        constexpr optional<T> opt2 = opt;
> +        (void)opt2;
> +    }
> +    {
> +        using T = X;
> +        static_assert((std::is_trivially_copy_constructible<optional<T>>::value),
> "");
> +        constexpr optional<T> opt;
> +        constexpr optional<T> opt2 = opt;
> +        (void)opt2;
> +    }
> +    static_assert(!(std::is_trivially_copy_constructible<optional<Y>>::value),
> "");
> +    static_assert(!(std::is_trivially_copy_constructible<optional<std::string>>::value),
> "");
> +
> +    static_assert(!(std::is_copy_constructible<optional<Z>>::value), "");
> +}
>
> Added: libcxx/trunk/test/libcxx/utilities/optional/optional.object/
> optional.object.ctor/move.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx
> /utilities/optional/optional.object/optional.object.ctor/
> move.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/libcxx/utilities/optional/optional.object/
> optional.object.ctor/move.pass.cpp (added)
> +++ libcxx/trunk/test/libcxx/utilities/optional/optional.object/
> optional.object.ctor/move.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,60 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// XFAIL: libcpp-no-exceptions
> +// <optional>
> +
> +// optional(optional<T>&& rhs);
> +
> +#include <optional>
> +#include <string>
> +#include <type_traits>
> +#include <utility>
> +
> +using std::optional;
> +
> +struct X {};
> +
> +struct Y
> +{
> +    Y() = default;
> +    Y(Y&&) {}
> +};
> +
> +struct Z
> +{
> +    Z() = default;
> +    Z(Z&&) = delete;
> +    Z(const Z&) = delete;
> +    Z& operator=(Z&&) = delete;
> +    Z& operator=(const Z&) = delete;
> +};
> +
> +int main()
> +{
> +    {
> +        using T = int;
> +        static_assert((std::is_trivially_copy_constructible<optional<T>>::value),
> "");
> +        constexpr optional<T> opt;
> +        constexpr optional<T> opt2 = std::move(opt);
> +        (void)opt2;
> +    }
> +    {
> +        using T = X;
> +        static_assert((std::is_trivially_copy_constructible<optional<T>>::value),
> "");
> +        constexpr optional<T> opt;
> +        constexpr optional<T> opt2 = std::move(opt);
> +        (void)opt2;
> +    }
> +    static_assert(!(std::is_trivially_move_constructible<optional<Y>>::value),
> "");
> +    static_assert(!(std::is_trivially_move_constructible<optional<std::string>>::value),
> "");
> +
> +    static_assert(!(std::is_move_constructible<optional<Z>>::value), "");
> +}
>
> Added: libcxx/trunk/test/libcxx/utilities/optional/optional.object/
> special_member_gen.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx
> /utilities/optional/optional.object/special_member_gen.
> pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/libcxx/utilities/optional/optional.object/special_member_gen.pass.cpp
> (added)
> +++ libcxx/trunk/test/libcxx/utilities/optional/optional.object/special_member_gen.pass.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,66 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "archetypes.hpp"
> +
> +template <class T>
> +struct SpecialMemberTest {
> +    using O = std::optional<T>;
> +
> +    template <template <class> class TestMF>
> +    static constexpr bool check_same() {
> +        return TestMF<O>::value == TestMF<T>::value;
> +    }
> +
> +    // Test that optional inherits the correct trivial/non-trivial members
> +    static_assert(check_same<std::is_trivially_destructible>(), "");
> +    static_assert(check_same<std::is_trivially_copyable>(), "");
> +};
> +
> +template <class ...Args> static void sink(Args&&...) {}
> +
> +template <class ...TestTypes>
> +struct DoTestsMetafunction {
> +    DoTestsMetafunction() { sink(SpecialMemberTest<TestTypes>{}...); }
> +};
> +
> +struct TrivialMoveNonTrivialCopy {
> +    TrivialMoveNonTrivialCopy() = default;
> +    TrivialMoveNonTrivialCopy(const TrivialMoveNonTrivialCopy&) {}
> +    TrivialMoveNonTrivialCopy(TrivialMoveNonTrivialCopy&&) = default;
> +    TrivialMoveNonTrivialCopy& operator=(const
> TrivialMoveNonTrivialCopy&) { return *this; }
> +    TrivialMoveNonTrivialCopy& operator=(TrivialMoveNonTrivialCopy&&) =
> default;
> +};
> +
> +struct TrivialCopyNonTrivialMove {
> +    TrivialCopyNonTrivialMove() = default;
> +    TrivialCopyNonTrivialMove(const TrivialCopyNonTrivialMove&) =
> default;
> +    TrivialCopyNonTrivialMove(TrivialCopyNonTrivialMove&&) {}
> +    TrivialCopyNonTrivialMove& operator=(const
> TrivialCopyNonTrivialMove&) = default;
> +    TrivialCopyNonTrivialMove& operator=(TrivialCopyNonTrivialMove&&) {
> return *this; }
> +};
> +
> +int main()
> +{
> +    sink(
> +        ImplicitTypes::ApplyTypes<DoTestsMetafunction>{},
> +        ExplicitTypes::ApplyTypes<DoTestsMetafunction>{},
> +        NonLiteralTypes::ApplyTypes<DoTestsMetafunction>{},
> +        NonTrivialTypes::ApplyTypes<DoTestsMetafunction>{},
> +        DoTestsMetafunction<TrivialMoveNonTrivialCopy,
> TrivialCopyNonTrivialMove>{}
> +    );
> +}
>
> Added: libcxx/trunk/test/libcxx/utilities/optional/version.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx
> /utilities/optional/version.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/libcxx/utilities/optional/version.pass.cpp (added)
> +++ libcxx/trunk/test/libcxx/utilities/optional/version.pass.cpp Wed Oct
> 12 02:46:20 2016
> @@ -0,0 +1,20 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// <optional>
> +
> +#include <optional>
> +
> +#ifndef _LIBCPP_VERSION
> +#error _LIBCPP_VERSION not defined
> +#endif
> +
> +int main()
> +{
> +}
>
> Modified: libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.
> prop/is_nothrow_swappable_with.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappabl
> e_with.pass.cpp?rev=283980&r1=283979&r2=283980&view=diff
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.
> prop/is_nothrow_swappable_with.pass.cpp (original)
> +++ libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.
> prop/is_nothrow_swappable_with.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -59,7 +59,7 @@ int main()
>                        !std::is_nothrow_swappable_with<A&, A&>::value,
> "");
>      }
>      {
> -        // test that hetrogenius swap is allowed only if both 'swap(A,
> B)' and
> +        // test that heterogeneous swap is allowed only if both 'swap(A,
> B)' and
>          // 'swap(B, A)' are valid.
>          static_assert(std::is_nothrow_swappable_with<A&, B&>::value, "");
>          static_assert(!std::is_nothrow_swappable_with<A&, C&>::value &&
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.bad_
> optional_access/default.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.bad_optional_access/default.pass.
> cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.bad_
> optional_access/default.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.bad_
> optional_access/default.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,23 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +
> +// <optional>
> +
> +// class bad_optional_access is default constructible
> +
> +#include <optional>
> +#include <type_traits>
> +
> +int main()
> +{
> +    using std::bad_optional_access;
> +    bad_optional_access ex;
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.bad_
> optional_access/derive.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.bad_optional_access/derive.pass.
> cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.bad_
> optional_access/derive.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.bad_
> optional_access/derive.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,25 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +
> +// <optional>
> +
> +// class bad_optional_access : public logic_error
> +
> +#include <optional>
> +#include <type_traits>
> +
> +int main()
> +{
> +    using std::bad_optional_access;
> +
> +    static_assert(std::is_base_of<std::logic_error,
> bad_optional_access>::value, "");
> +    static_assert(std::is_convertible<bad_optional_access*,
> std::logic_error*>::value, "");
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.comp_with_
> t/equal.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.comp_with_t/equal.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.comp_with_t/equal.pass.cpp
> (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.comp_with_t/equal.pass.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,53 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class T> constexpr bool operator==(const optional<T>& x,
> const T& v);
> +// template <class T> constexpr bool operator==(const T& v, const
> optional<T>& x);
> +
> +#include <optional>
> +
> +using std::optional;
> +
> +struct X
> +{
> +    int i_;
> +
> +    constexpr X(int i) : i_(i) {}
> +};
> +
> +constexpr bool operator == ( const X &lhs, const X &rhs )
> +    { return lhs.i_ == rhs.i_ ; }
> +
> +int main()
> +{
> +    {
> +    typedef X T;
> +    typedef optional<T> O;
> +
> +    constexpr T val(2);
> +    constexpr O o1;       // disengaged
> +    constexpr O o2{1};    // engaged
> +    constexpr O o3{val};  // engaged
> +
> +    static_assert ( !(o1 == T(1)), "" );
> +    static_assert (  (o2 == T(1)), "" );
> +    static_assert ( !(o3 == T(1)), "" );
> +    static_assert (  (o3 == T(2)), "" );
> +    static_assert (  (o3 == val),  "" );
> +
> +    static_assert ( !(T(1) == o1), "" );
> +    static_assert (  (T(1) == o2), "" );
> +    static_assert ( !(T(1) == o3), "" );
> +    static_assert (  (T(2) == o3), "" );
> +    static_assert (  (val  == o3), "" );
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.comp_with_
> t/greater.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.comp_with_t/greater.pass.cpp?rev=
> 283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.comp_with_t/greater.pass.cpp
> (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.comp_with_t/greater.pass.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,55 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class T> constexpr bool operator>(const optional<T>& x,
> const T& v);
> +// template <class T> constexpr bool operator>(const T& v, const
> optional<T>& x);
> +
> +#include <optional>
> +
> +using std::optional;
> +
> +struct X
> +{
> +    int i_;
> +
> +    constexpr X(int i) : i_(i) {}
> +};
> +
> +constexpr bool operator > ( const X &lhs, const X &rhs )
> +    { return lhs.i_ > rhs.i_ ; }
> +
> +int main()
> +{
> +    {
> +    typedef X T;
> +    typedef optional<T> O;
> +
> +    constexpr T val(2);
> +    constexpr O o1;       // disengaged
> +    constexpr O o2{1};    // engaged
> +    constexpr O o3{val};  // engaged
> +
> +    static_assert ( !(o1 > T(1)), "" );
> +    static_assert ( !(o2 > T(1)), "" );  // equal
> +    static_assert (  (o3 > T(1)), "" );
> +    static_assert ( !(o2 >  val), "" );
> +    static_assert ( !(o3 >  val), "" );  // equal
> +    static_assert ( !(o3 > T(3)), "" );
> +
> +    static_assert (   (T(1) > o1), "" );
> +    static_assert (  !(T(1) > o2), "" ); // equal
> +    static_assert (  !(T(1) > o3), "" );
> +    static_assert (   (val  > o2), "" );
> +    static_assert (  !(val  > o3), "" ); // equal
> +    static_assert (   (T(3) > o3), "" );
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.comp_with_
> t/greater_equal.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.comp_with_t/greater_equal.pass.
> cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.comp_with_t/greater_equal.pass.cpp
> (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.comp_with_t/greater_equal.pass.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,55 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class T> constexpr bool operator>=(const optional<T>& x,
> const T& v);
> +// template <class T> constexpr bool operator>=(const T& v, const
> optional<T>& x);
> +
> +#include <optional>
> +
> +using std::optional;
> +
> +struct X
> +{
> +    int i_;
> +
> +    constexpr X(int i) : i_(i) {}
> +};
> +
> +constexpr bool operator >= ( const X &lhs, const X &rhs )
> +    { return lhs.i_ >= rhs.i_ ; }
> +
> +int main()
> +{
> +    {
> +    typedef X T;
> +    typedef optional<T> O;
> +
> +    constexpr T val(2);
> +    constexpr O o1;       // disengaged
> +    constexpr O o2{1};    // engaged
> +    constexpr O o3{val};  // engaged
> +
> +    static_assert ( !(o1 >= T(1)), "" );
> +    static_assert (  (o2 >= T(1)), "" );  // equal
> +    static_assert (  (o3 >= T(1)), "" );
> +    static_assert ( !(o2 >=  val), "" );
> +    static_assert (  (o3 >=  val), "" );  // equal
> +    static_assert ( !(o3 >= T(3)), "" );
> +
> +    static_assert (   (T(1) >= o1), "" );
> +    static_assert (   (T(1) >= o2), "" ); // equal
> +    static_assert (  !(T(1) >= o3), "" );
> +    static_assert (   (val  >= o2), "" );
> +    static_assert (   (val  >= o3), "" ); // equal
> +    static_assert (   (T(3) >= o3), "" );
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.comp_with_
> t/less_equal.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.comp_with_t/less_equal.pass.cpp?
> rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.comp_with_t/less_equal.pass.cpp
> (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.comp_with_t/less_equal.pass.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,55 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class T> constexpr bool operator<=(const optional<T>& x,
> const T& v);
> +// template <class T> constexpr bool operator<=(const T& v, const
> optional<T>& x);
> +
> +#include <optional>
> +
> +using std::optional;
> +
> +struct X
> +{
> +    int i_;
> +
> +    constexpr X(int i) : i_(i) {}
> +};
> +
> +constexpr bool operator <= ( const X &lhs, const X &rhs )
> +    { return lhs.i_ <= rhs.i_ ; }
> +
> +int main()
> +{
> +    {
> +    typedef X T;
> +    typedef optional<T> O;
> +
> +    constexpr T val(2);
> +    constexpr O o1;       // disengaged
> +    constexpr O o2{1};    // engaged
> +    constexpr O o3{val};  // engaged
> +
> +    static_assert (  (o1 <= T(1)), "" );
> +    static_assert (  (o2 <= T(1)), "" );  // equal
> +    static_assert ( !(o3 <= T(1)), "" );
> +    static_assert (  (o2 <=  val), "" );
> +    static_assert (  (o3 <=  val), "" );  // equal
> +    static_assert (  (o3 <= T(3)), "" );
> +
> +    static_assert (  !(T(1) <= o1), "" );
> +    static_assert (   (T(1) <= o2), "" ); // equal
> +    static_assert (   (T(1) <= o3), "" );
> +    static_assert (  !(val  <= o2), "" );
> +    static_assert (   (val  <= o3), "" ); // equal
> +    static_assert (  !(T(3) <= o3), "" );
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.comp_with_
> t/less_than.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.comp_with_t/less_than.pass.cpp?
> rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.comp_with_t/less_than.pass.cpp
> (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.comp_with_t/less_than.pass.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,55 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class T> constexpr bool operator<(const optional<T>& x,
> const T& v);
> +// template <class T> constexpr bool operator<(const T& v, const
> optional<T>& x);
> +
> +#include <optional>
> +
> +using std::optional;
> +
> +struct X
> +{
> +    int i_;
> +
> +    constexpr X(int i) : i_(i) {}
> +};
> +
> +constexpr bool operator < ( const X &lhs, const X &rhs )
> +    { return lhs.i_ < rhs.i_ ; }
> +
> +int main()
> +{
> +    {
> +    typedef X T;
> +    typedef optional<T> O;
> +
> +    constexpr T val(2);
> +    constexpr O o1;       // disengaged
> +    constexpr O o2{1};    // engaged
> +    constexpr O o3{val};  // engaged
> +
> +    static_assert (  (o1 < T(1)), "" );
> +    static_assert ( !(o2 < T(1)), "" );  // equal
> +    static_assert ( !(o3 < T(1)), "" );
> +    static_assert (  (o2 <  val), "" );
> +    static_assert ( !(o3 <  val), "" );  // equal
> +    static_assert (  (o3 < T(3)), "" );
> +
> +    static_assert (  !(T(1) < o1), "" );
> +    static_assert (  !(T(1) < o2), "" ); // equal
> +    static_assert (   (T(1) < o3), "" );
> +    static_assert (  !(val  < o2), "" );
> +    static_assert (  !(val  < o3), "" ); // equal
> +    static_assert (  !(T(3) < o3), "" );
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.comp_with_
> t/not_equal.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.comp_with_t/not_equal.pass.cpp?
> rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.comp_with_t/not_equal.pass.cpp
> (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.comp_with_t/not_equal.pass.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,53 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class T> constexpr bool operator!=(const optional<T>& x,
> const T& v);
> +// template <class T> constexpr bool operator!=(const T& v, const
> optional<T>& x);
> +
> +#include <optional>
> +
> +using std::optional;
> +
> +struct X
> +{
> +    int i_;
> +
> +    constexpr X(int i) : i_(i) {}
> +};
> +
> +constexpr bool operator != ( const X &lhs, const X &rhs )
> +    { return lhs.i_ != rhs.i_ ; }
> +
> +int main()
> +{
> +    {
> +    typedef X T;
> +    typedef optional<T> O;
> +
> +    constexpr T val(2);
> +    constexpr O o1;       // disengaged
> +    constexpr O o2{1};    // engaged
> +    constexpr O o3{val};  // engaged
> +
> +    static_assert (  (o1 != T(1)), "" );
> +    static_assert ( !(o2 != T(1)), "" );
> +    static_assert (  (o3 != T(1)), "" );
> +    static_assert ( !(o3 != T(2)), "" );
> +    static_assert ( !(o3 != val),  "" );
> +
> +    static_assert (  (T(1) != o1), "" );
> +    static_assert ( !(T(1) != o2), "" );
> +    static_assert (  (T(1) != o3), "" );
> +    static_assert ( !(T(2) != o3), "" );
> +    static_assert ( !(val  != o3), "" );
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.hash/hash.
> pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.hash/hash.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.hash/hash.pass.cpp
> (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.hash/hash.pass.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,48 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class T> struct hash<optional<T>>;
> +
> +#include <optional>
> +#include <string>
> +#include <memory>
> +#include <cassert>
> +
> +
> +int main()
> +{
> +    using std::optional;
> +    const std::size_t nullopt_hash =
> +        std::hash<optional<double>>{}(optional<double>{});
> +
> +    {
> +        typedef int T;
> +        optional<T> opt;
> +        assert(std::hash<optional<T>>{}(opt) == nullopt_hash);
> +        opt = 2;
> +        assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt));
> +    }
> +    {
> +        typedef std::string T;
> +        optional<T> opt;
> +        assert(std::hash<optional<T>>{}(opt) == nullopt_hash);
> +        opt = std::string("123");
> +        assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt));
> +    }
> +    {
> +        typedef std::unique_ptr<int> T;
> +        optional<T> opt;
> +        assert(std::hash<optional<T>>{}(opt) == nullopt_hash);
> +        opt = std::unique_ptr<int>(new int(3));
> +        assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt));
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.nullops/
> equal.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.nullops/equal.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.nullops/equal.pass.cpp
> (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.nullops/equal.pass.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,39 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class T> constexpr bool operator==(const optional<T>& x,
> nullopt_t) noexcept;
> +// template <class T> constexpr bool operator==(nullopt_t, const
> optional<T>& x) noexcept;
> +
> +#include <optional>
> +
> +int main()
> +{
> +    using std::optional;
> +    using std::nullopt_t;
> +    using std::nullopt;
> +
> +    {
> +    typedef int T;
> +    typedef optional<T> O;
> +
> +    constexpr O o1;     // disengaged
> +    constexpr O o2{1};  // engaged
> +
> +    static_assert (  (nullopt == o1), "" );
> +    static_assert ( !(nullopt == o2), "" );
> +    static_assert (  (o1 == nullopt), "" );
> +    static_assert ( !(o2 == nullopt), "" );
> +
> +    static_assert (noexcept(nullopt == o1), "");
> +    static_assert (noexcept(o1 == nullopt), "");
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.nullops/
> greater.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.nullops/greater.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.nullops/greater.pass.cpp
> (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.nullops/greater.pass.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,39 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class T> constexpr bool operator>(const optional<T>& x,
> nullopt_t) noexcept;
> +// template <class T> constexpr bool operator>(nullopt_t, const
> optional<T>& x) noexcept;
> +
> +#include <optional>
> +
> +int main()
> +{
> +    using std::optional;
> +    using std::nullopt_t;
> +    using std::nullopt;
> +
> +    {
> +    typedef int T;
> +    typedef optional<T> O;
> +
> +    constexpr O o1;     // disengaged
> +    constexpr O o2{1};  // engaged
> +
> +    static_assert ( !(nullopt > o1), "" );
> +    static_assert ( !(nullopt > o2), "" );
> +    static_assert ( !(o1 > nullopt), "" );
> +    static_assert (  (o2 > nullopt), "" );
> +
> +    static_assert (noexcept(nullopt > o1), "");
> +    static_assert (noexcept(o1 > nullopt), "");
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.nullops/
> greater_equal.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.nullops/greater_equal.pass.cpp?
> rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.nullops/greater_equal.pass.cpp
> (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.nullops/greater_equal.pass.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,39 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class T> constexpr bool operator>=(const optional<T>& x,
> nullopt_t) noexcept;
> +// template <class T> constexpr bool operator>=(nullopt_t, const
> optional<T>& x) noexcept;
> +
> +#include <optional>
> +
> +int main()
> +{
> +    using std::optional;
> +    using std::nullopt_t;
> +    using std::nullopt;
> +
> +    {
> +    typedef int T;
> +    typedef optional<T> O;
> +
> +    constexpr O o1;     // disengaged
> +    constexpr O o2{1};  // engaged
> +
> +    static_assert (  (nullopt >= o1), "" );
> +    static_assert ( !(nullopt >= o2), "" );
> +    static_assert (  (o1 >= nullopt), "" );
> +    static_assert (  (o2 >= nullopt), "" );
> +
> +    static_assert (noexcept(nullopt >= o1), "");
> +    static_assert (noexcept(o1 >= nullopt), "");
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.nullops/
> less_equal.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.nullops/less_equal.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.nullops/less_equal.pass.cpp
> (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.nullops/less_equal.pass.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,40 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +
> +// <optional>
> +
> +// template <class T> constexpr bool operator<=(const optional<T>& x,
> nullopt_t) noexcept;
> +// template <class T> constexpr bool operator<=(nullopt_t, const
> optional<T>& x) noexcept;
> +
> +#include <optional>
> +
> +int main()
> +{
> +    using std::optional;
> +    using std::nullopt_t;
> +    using std::nullopt;
> +
> +    {
> +    typedef int T;
> +    typedef optional<T> O;
> +
> +    constexpr O o1;     // disengaged
> +    constexpr O o2{1};  // engaged
> +
> +    static_assert (  (nullopt <= o1), "" );
> +    static_assert (  (nullopt <= o2), "" );
> +    static_assert (  (o1 <= nullopt), "" );
> +    static_assert ( !(o2 <= nullopt), "" );
> +
> +    static_assert (noexcept(nullopt <= o1), "");
> +    static_assert (noexcept(o1 <= nullopt), "");
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.nullops/
> less_than.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.nullops/less_than.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.nullops/less_than.pass.cpp
> (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.nullops/less_than.pass.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,39 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class T> constexpr bool operator<(const optional<T>& x,
> nullopt_t) noexcept;
> +// template <class T> constexpr bool operator<(nullopt_t, const
> optional<T>& x) noexcept;
> +
> +#include <optional>
> +
> +int main()
> +{
> +    using std::optional;
> +    using std::nullopt_t;
> +    using std::nullopt;
> +
> +    {
> +    typedef int T;
> +    typedef optional<T> O;
> +
> +    constexpr O o1;     // disengaged
> +    constexpr O o2{1};  // engaged
> +
> +    static_assert ( !(nullopt < o1), "" );
> +    static_assert (  (nullopt < o2), "" );
> +    static_assert ( !(o1 < nullopt), "" );
> +    static_assert ( !(o2 < nullopt), "" );
> +
> +    static_assert (noexcept(nullopt < o1), "");
> +    static_assert (noexcept(o1 < nullopt), "");
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.nullops/
> not_equal.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.nullops/not_equal.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.nullops/not_equal.pass.cpp
> (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.nullops/not_equal.pass.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,39 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class T> constexpr bool operator!=(const optional<T>& x,
> nullopt_t) noexcept;
> +// template <class T> constexpr bool operator!=(nullopt_t, const
> optional<T>& x) noexcept;
> +
> +#include <optional>
> +
> +int main()
> +{
> +    using std::optional;
> +    using std::nullopt_t;
> +    using std::nullopt;
> +
> +    {
> +    typedef int T;
> +    typedef optional<T> O;
> +
> +    constexpr O o1;     // disengaged
> +    constexpr O o2{1};  // engaged
> +
> +    static_assert ( !(nullopt != o1), "" );
> +    static_assert (  (nullopt != o2), "" );
> +    static_assert ( !(o1 != nullopt), "" );
> +    static_assert (  (o2 != nullopt), "" );
> +
> +    static_assert (noexcept(nullopt != o1), "");
> +    static_assert (noexcept(o1 != nullopt), "");
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.nullopt/
> not_brace_initializable.fail.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.nullopt/not_brace_initializable.
> fail.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.nullopt/
> not_brace_initializable.fail.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.nullopt/
> not_brace_initializable.fail.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,25 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// struct nullopt_t{see below};
> +
> +#include <optional>
> +
> +using std::optional;
> +using std::nullopt_t;
> +
> +int main()
> +{
> +    // I roughly interpret LWG2736 as "it shall not be possible to
> copy-list-initialize nullopt_t with an
> +    // empty braced-init-list."
> +    nullopt_t foo = {};
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.nullopt/
> nullopt_t.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.nullopt/nullopt_t.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.nullopt/nullopt_t.pass.cpp
> (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.nullopt/nullopt_t.pass.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,38 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// struct nullopt_t{see below};
> +// constexpr nullopt_t nullopt(unspecified);
> +
> +#include <optional>
> +#include <type_traits>
> +
> +using std::optional;
> +using std::nullopt_t;
> +using std::nullopt;
> +
> +constexpr
> +int
> +test(const nullopt_t&)
> +{
> +    return 3;
> +}
> +
> +int main()
> +{
> +    static_assert((std::is_class<nullopt_t>::value), "");
> +    static_assert((std::is_empty<nullopt_t>::value), "");
> +    static_assert((std::is_literal_type<nullopt_t>::value), "");
> +    static_assert((!std::is_default_constructible<nullopt_t>::value),
> "");
> +
> +    static_assert(test(nullopt) == 3, "");
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/assign_value.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.assign/assi
> gn_value.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/assign_value.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/assign_value.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,261 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class U> optional<T>& operator=(U&& v);
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +#include <memory>
> +
> +#include "test_macros.h"
> +#include "archetypes.hpp"
> +
> +using std::optional;
> +
> +struct ThrowAssign {
> +  static int dtor_called;
> +  ThrowAssign() = default;
> +  ThrowAssign(int) { TEST_THROW(42); }
> +  ThrowAssign& operator=(int) {
> +      TEST_THROW(42);
> +  }
> +  ~ThrowAssign() { ++dtor_called; }
> +};
> +int ThrowAssign::dtor_called = 0;
> +
> +template <class T, class Arg = T, bool Expect = true>
> +void assert_assignable() {
> +    static_assert(std::is_assignable<optional<T>&, Arg>::value ==
> Expect, "");
> +    static_assert(!std::is_assignable<const optional<T>&, Arg>::value,
> "");
> +}
> +
> +struct MismatchType {
> +  explicit MismatchType(int) {}
> +  explicit MismatchType(char*) {}
> +  explicit MismatchType(int*) = delete;
> +  MismatchType& operator=(int) { return *this; }
> +  MismatchType& operator=(int*) { return *this; }
> +  MismatchType& operator=(char*) = delete;
> +};
> +
> +void test_sfinae() {
> +    using I = TestTypes::TestType;
> +    using E = ExplicitTestTypes::TestType;
> +    assert_assignable<int>();
> +    assert_assignable<int, int&>();
> +    assert_assignable<int, int const&>();
> +    // Implicit test type
> +    assert_assignable<I, I const&>();
> +    assert_assignable<I, I&&>();
> +    assert_assignable<I, int>();
> +    assert_assignable<I, void*, false>();
> +    // Explicit test type
> +    assert_assignable<E, E const&>();
> +    assert_assignable<E, E &&>();
> +    assert_assignable<E, int>();
> +    assert_assignable<E, void*, false>();
> +    // Mismatch type
> +    assert_assignable<MismatchType, int>();
> +    assert_assignable<MismatchType, int*, false>();
> +    assert_assignable<MismatchType, char*, false>();
> +}
> +
> +void test_with_test_type()
> +{
> +    using T = TestTypes::TestType;
> +    T::reset();
> +    { // to empty
> +        optional<T> opt;
> +        opt = 3;
> +        assert(T::alive == 1);
> +        assert(T::constructed == 1);
> +        assert(T::value_constructed == 1);
> +        assert(T::assigned == 0);
> +        assert(T::destroyed == 0);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(3));
> +    }
> +    { // to existing
> +        optional<T> opt(42);
> +        T::reset_constructors();
> +        opt = 3;
> +        assert(T::alive == 1);
> +        assert(T::constructed == 0);
> +        assert(T::assigned == 1);
> +        assert(T::value_assigned == 1);
> +        assert(T::destroyed == 0);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(3));
> +    }
> +    { // test default argument
> +        optional<T> opt;
> +        T::reset_constructors();
> +        opt = {1, 2};
> +        assert(T::alive == 1);
> +        assert(T::constructed == 2);
> +        assert(T::value_constructed == 1);
> +        assert(T::move_constructed == 1);
> +        assert(T::assigned == 0);
> +        assert(T::destroyed == 1);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(1, 2));
> +    }
> +    { // test default argument
> +        optional<T> opt(42);
> +        T::reset_constructors();
> +        opt = {1, 2};
> +        assert(T::alive == 1);
> +        assert(T::constructed == 1);
> +        assert(T::value_constructed == 1);
> +        assert(T::assigned == 1);
> +        assert(T::move_assigned == 1);
> +        assert(T::destroyed == 1);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(1, 2));
> +    }
> +    { // test default argument
> +        optional<T> opt;
> +        T::reset_constructors();
> +        opt = {1};
> +        assert(T::alive == 1);
> +        assert(T::constructed == 2);
> +        assert(T::value_constructed == 1);
> +        assert(T::move_constructed == 1);
> +        assert(T::assigned == 0);
> +        assert(T::destroyed == 1);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(1));
> +    }
> +    { // test default argument
> +        optional<T> opt(42);
> +        T::reset_constructors();
> +        opt = {};
> +        assert(static_cast<bool>(opt) == false);
> +        assert(T::alive == 0);
> +        assert(T::constructed == 0);
> +        assert(T::assigned == 0);
> +        assert(T::destroyed == 1);
> +    }
> +}
> +
> +template <class T, class Value = int>
> +void test_with_type() {
> +    { // to empty
> +        optional<T> opt;
> +        opt = Value(3);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(3));
> +    }
> +    { // to existing
> +        optional<T> opt(Value(42));
> +        opt = Value(3);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(3));
> +    }
> +    { // test const
> +        optional<T> opt(Value(42));
> +        const T t(Value(3));
> +        opt = t;
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(3));
> +    }
> +    { // test default argument
> +        optional<T> opt;
> +        opt = {Value(1)};
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(1));
> +    }
> +    { // test default argument
> +        optional<T> opt(Value(42));
> +        opt = {};
> +        assert(static_cast<bool>(opt) == false);
> +    }
> +}
> +
> +template <class T>
> +void test_with_type_multi() {
> +    test_with_type<T>();
> +    { // test default argument
> +        optional<T> opt;
> +        opt = {1, 2};
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(1, 2));
> +    }
> +    { // test default argument
> +        optional<T> opt(42);
> +        opt = {1, 2};
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(1, 2));
> +    }
> +}
> +
> +void test_throws()
> +{
> +#ifndef TEST_HAS_NO_EXCEPTIONS
> +    using T = ThrowAssign;
> +    {
> +        using T = ThrowAssign;
> +        optional<T> opt;
> +        try {
> +            opt = 42;
> +            assert(false);
> +        } catch (int) {}
> +        assert(static_cast<bool>(opt) == false);
> +    }
> +    assert(T::dtor_called == 0);
> +    {
> +        T::dtor_called = 0;
> +        optional<T> opt(std::in_place);
> +        try {
> +            opt = 42;
> +            assert(false);
> +        } catch (int) {}
> +        assert(static_cast<bool>(opt) == true);
> +        assert(T::dtor_called == 0);
> +    }
> +    assert(T::dtor_called == 1);
> +#endif
> +}
> +
> +enum MyEnum { Zero, One, Two, Three, FortyTwo = 42 };
> +
> +using Fn = void(*)();
> +
> +int main()
> +{
> +    test_sfinae();
> +    // Test with instrumented type
> +    test_with_test_type();
> +    // Test with various scalar types
> +    test_with_type<int>();
> +    test_with_type<MyEnum, MyEnum>();
> +    test_with_type<int, MyEnum>();
> +    test_with_type<Fn, Fn>();
> +    // Test types with multi argument constructors
> +    test_with_type_multi<ConstexprTestTypes::TestType>();
> +    test_with_type_multi<TrivialTestTypes::TestType>();
> +    // Test move only types
> +    {
> +        optional<std::unique_ptr<int>> opt;
> +        opt = std::unique_ptr<int>(new int(3));
> +        assert(static_cast<bool>(opt) == true);
> +        assert(**opt == 3);
> +    }
> +    {
> +        optional<std::unique_ptr<int>> opt(std::unique_ptr<int>(new
> int(2)));
> +        opt = std::unique_ptr<int>(new int(3));
> +        assert(static_cast<bool>(opt) == true);
> +        assert(**opt == 3);
> +    }
> +    test_throws();
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/const_optional_U.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.assign/cons
> t_optional_U.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/const_optional_U.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/const_optional_U.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,254 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// From LWG2451:
> +// template<class U>
> +//   optional<T>& operator=(const optional<U>& rhs);
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +#include "archetypes.hpp"
> +
> +using std::optional;
> +
> +struct X
> +{
> +    static bool throw_now;
> +
> +    X() = default;
> +    X(int)
> +    {
> +        if (throw_now)
> +            TEST_THROW(6);
> +    }
> +};
> +
> +bool X::throw_now = false;
> +
> +struct Y1
> +{
> +    Y1() = default;
> +    Y1(const int&) {}
> +    Y1& operator=(const Y1&) = delete;
> +};
> +
> +struct Y2
> +{
> +    Y2() = default;
> +    Y2(const int&) = delete;
> +    Y2& operator=(const int&) { return *this; }
> +};
> +
> +template <class T>
> +struct AssignableFrom {
> +  static int type_constructed;
> +  static int type_assigned;
> +static int int_constructed;
> +  static int int_assigned;
> +
> +  static void reset() {
> +      type_constructed = int_constructed = 0;
> +      type_assigned = int_assigned = 0;
> +  }
> +
> +  AssignableFrom() = default;
> +
> +  explicit AssignableFrom(T) { ++type_constructed; }
> +  AssignableFrom& operator=(T) { ++type_assigned; return *this; }
> +
> +  AssignableFrom(int) { ++int_constructed; }
> +  AssignableFrom& operator=(int) { ++int_assigned; return *this; }
> +private:
> +  AssignableFrom(AssignableFrom const&) = delete;
> +  AssignableFrom& operator=(AssignableFrom const&) = delete;
> +};
> +
> +template <class T> int AssignableFrom<T>::type_constructed = 0;
> +template <class T> int AssignableFrom<T>::type_assigned = 0;
> +template <class T> int AssignableFrom<T>::int_constructed = 0;
> +template <class T> int AssignableFrom<T>::int_assigned = 0;
> +
> +
> +void test_with_test_type() {
> +    using T = TestTypes::TestType;
> +    T::reset();
> +    { // non-empty to empty
> +        T::reset_constructors();
> +        optional<T> opt;
> +        const optional<int> other(42);
> +        opt = other;
> +        assert(T::alive == 1);
> +        assert(T::constructed == 1);
> +        assert(T::value_constructed == 1);
> +        assert(T::assigned == 0);
> +        assert(T::destroyed == 0);
> +        assert(static_cast<bool>(other) == true);
> +        assert(*other == 42);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(42));
> +    }
> +    assert(T::alive == 0);
> +    { // non-empty to non-empty
> +        optional<T> opt(101);
> +        const optional<int> other(42);
> +        T::reset_constructors();
> +        opt = other;
> +        assert(T::alive == 1);
> +        assert(T::constructed == 0);
> +        assert(T::assigned == 1);
> +        assert(T::value_assigned == 1);
> +        assert(T::destroyed == 0);
> +        assert(static_cast<bool>(other) == true);
> +        assert(*other == 42);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(42));
> +    }
> +    assert(T::alive == 0);
> +    { // empty to non-empty
> +        optional<T> opt(101);
> +        const optional<int> other;
> +        T::reset_constructors();
> +        opt = other;
> +        assert(T::alive == 0);
> +        assert(T::constructed == 0);
> +        assert(T::assigned == 0);
> +        assert(T::destroyed == 1);
> +        assert(static_cast<bool>(other) == false);
> +        assert(static_cast<bool>(opt) == false);
> +    }
> +    assert(T::alive == 0);
> +    { // empty to empty
> +        optional<T> opt;
> +        const optional<int> other;
> +        T::reset_constructors();
> +        opt = other;
> +        assert(T::alive == 0);
> +        assert(T::constructed == 0);
> +        assert(T::assigned == 0);
> +        assert(T::destroyed == 0);
> +        assert(static_cast<bool>(other) == false);
> +        assert(static_cast<bool>(opt) == false);
> +    }
> +    assert(T::alive == 0);
> +}
> +
> +void test_ambigious_assign() {
> +    using OptInt = std::optional<int>;
> +    {
> +        using T = AssignableFrom<OptInt const&>;
> +        const OptInt a(42);
> +        T::reset();
> +        {
> +            std::optional<T> t;
> +            t = a;
> +            assert(T::type_constructed == 1);
> +            assert(T::type_assigned == 0);
> +            assert(T::int_constructed == 0);
> +            assert(T::int_assigned == 0);
> +        }
> +        T::reset();
> +        {
> +            std::optional<T> t(42);
> +            t = a;
> +            assert(T::type_constructed == 0);
> +            assert(T::type_assigned == 1);
> +            assert(T::int_constructed == 1);
> +            assert(T::int_assigned == 0);
> +        }
> +        T::reset();
> +        {
> +            std::optional<T> t(42);
> +            t = std::move(a);
> +            assert(T::type_constructed == 0);
> +            assert(T::type_assigned == 1);
> +            assert(T::int_constructed == 1);
> +            assert(T::int_assigned == 0);
> +        }
> +    }
> +    {
> +        using T = AssignableFrom<OptInt&>;
> +        OptInt a(42);
> +        T::reset();
> +        {
> +            std::optional<T> t;
> +            t = a;
> +            assert(T::type_constructed == 1);
> +            assert(T::type_assigned == 0);
> +            assert(T::int_constructed == 0);
> +            assert(T::int_assigned == 0);
> +        }
> +        {
> +            using Opt = std::optional<T>;
> +            static_assert(!std::is_assignable_v<Opt&, OptInt const&>,
> "");
> +        }
> +    }
> +}
> +
> +
> +int main()
> +{
> +    test_with_test_type();
> +    test_ambigious_assign();
> +    {
> +        optional<int> opt;
> +        constexpr optional<short> opt2;
> +        opt = opt2;
> +        static_assert(static_cast<bool>(opt2) == false, "");
> +        assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
> +    }
> +    {
> +        optional<int> opt;
> +        constexpr optional<short> opt2(short{2});
> +        opt = opt2;
> +        static_assert(static_cast<bool>(opt2) == true, "");
> +        static_assert(*opt2 == 2, "");
> +        assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
> +        assert(*opt == *opt2);
> +    }
> +    {
> +        optional<int> opt(3);
> +        constexpr optional<short> opt2;
> +        opt = opt2;
> +        static_assert(static_cast<bool>(opt2) == false, "");
> +        assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
> +    }
> +    {
> +        optional<int> opt(3);
> +        constexpr optional<short> opt2(short{2});
> +        opt = opt2;
> +        static_assert(static_cast<bool>(opt2) == true, "");
> +        static_assert(*opt2 == 2, "");
> +        assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
> +        assert(*opt == *opt2);
> +    }
> +#ifndef TEST_HAS_NO_EXCEPTIONS
> +    {
> +        optional<X> opt;
> +        optional<int> opt2(42);
> +        assert(static_cast<bool>(opt2) == true);
> +        try
> +        {
> +            X::throw_now = true;
> +            opt = opt2;
> +            assert(false);
> +        }
> +        catch (int i)
> +        {
> +            assert(i == 6);
> +            assert(static_cast<bool>(opt) == false);
> +        }
> +    }
> +#endif
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/copy.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.assign/copy
> .pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/copy.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/copy.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,102 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// optional<T>& operator=(const optional<T>& rhs);
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +#include "archetypes.hpp"
> +
> +using std::optional;
> +
> +struct X
> +{
> +    static bool throw_now;
> +
> +    X() = default;
> +    X(const X&)
> +    {
> +        if (throw_now)
> +            TEST_THROW(6);
> +    }
> +};
> +
> +bool X::throw_now = false;
> +
> +template <class Tp>
> +constexpr bool assign_empty(optional<Tp>&& lhs) {
> +    const optional<Tp> rhs;
> +    lhs = rhs;
> +    return !lhs.has_value() && !rhs.has_value();
> +}
> +
> +template <class Tp>
> +constexpr bool assign_value(optional<Tp>&& lhs) {
> +    const optional<Tp> rhs(101);
> +    lhs = rhs;
> +    return lhs.has_value() && rhs.has_value() && *lhs == *rhs;
> +}
> +
> +int main()
> +{
> +    {
> +        using O = optional<int>;
> +        LIBCPP_STATIC_ASSERT(assign_empty(O{42}), "");
> +        LIBCPP_STATIC_ASSERT(assign_value(O{42}), "");
> +        assert(assign_empty(O{42}));
> +        assert(assign_value(O{42}));
> +    }
> +    {
> +        using O = optional<TrivialTestTypes::TestType>;
> +        LIBCPP_STATIC_ASSERT(assign_empty(O{42}), "");
> +        LIBCPP_STATIC_ASSERT(assign_value(O{42}), "");
> +        assert(assign_empty(O{42}));
> +        assert(assign_value(O{42}));
> +    }
> +    {
> +        using O = optional<TestTypes::TestType>;
> +        assert(assign_empty(O{42}));
> +        assert(assign_value(O{42}));
> +    }
> +    {
> +        using T = TestTypes::TestType;
> +        T::reset();
> +        optional<T> opt(3);
> +        const optional<T> opt2;
> +        assert(T::alive == 1);
> +        opt = opt2;
> +        assert(T::alive == 0);
> +        assert(!opt2.has_value());
> +        assert(!opt.has_value());
> +    }
> +#ifndef TEST_HAS_NO_EXCEPTIONS
> +    {
> +        optional<X> opt;
> +        optional<X> opt2(X{});
> +        assert(static_cast<bool>(opt2) == true);
> +        try
> +        {
> +            X::throw_now = true;
> +            opt = opt2;
> +            assert(false);
> +        }
> +        catch (int i)
> +        {
> +            assert(i == 6);
> +            assert(static_cast<bool>(opt) == false);
> +        }
> +    }
> +#endif
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/emplace.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.assign/empl
> ace.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/emplace.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/emplace.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,237 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class... Args> void optional<T>::emplace(Args&&... args);
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +#include <memory>
> +
> +#include "test_macros.h"
> +#include "archetypes.hpp"
> +
> +using std::optional;
> +
> +class X
> +{
> +    int i_;
> +    int j_ = 0;
> +public:
> +    X() : i_(0) {}
> +    X(int i) : i_(i) {}
> +    X(int i, int j) : i_(i), j_(j) {}
> +
> +    friend bool operator==(const X& x, const X& y)
> +        {return x.i_ == y.i_ && x.j_ == y.j_;}
> +};
> +
> +class Y
> +{
> +public:
> +    static bool dtor_called;
> +    Y() = default;
> +    Y(int) { TEST_THROW(6);}
> +    ~Y() {dtor_called = true;}
> +};
> +
> +bool Y::dtor_called = false;
> +
> +template <class T>
> +void test_one_arg() {
> +    using Opt = std::optional<T>;
> +    {
> +        Opt opt;
> +        opt.emplace();
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(0));
> +    }
> +    {
> +        Opt opt;
> +        opt.emplace(1);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(1));
> +    }
> +    {
> +        Opt opt(2);
> +        opt.emplace();
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(0));
> +    }
> +    {
> +        Opt opt(2);
> +        opt.emplace(1);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(1));
> +    }
> +}
> +
> +
> +template <class T>
> +void test_multi_arg()
> +{
> +    test_one_arg<T>();
> +    using Opt = std::optional<T>;
> +    Opt opt;
> +    {
> +        opt.emplace(101, 41);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(101, 41));
> +    }
> +    {
> +        Opt opt;
> +        opt.emplace({1, 2, 3, 4});
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(4)); // T sets its value to the size of the init
> list
> +    }
> +    {
> +        Opt opt;
> +        opt.emplace({1, 2, 3, 4, 5}, 6);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(5)); // T sets its value to the size of the init
> list
> +    }
> +}
> +
> +template <class T>
> +void test_on_test_type() {
> +
> +    T::reset();
> +    optional<T> opt;
> +    assert(T::alive == 0);
> +    {
> +        T::reset_constructors();
> +        opt.emplace();
> +        assert(T::alive == 1);
> +        assert(T::constructed == 1);
> +        assert(T::default_constructed == 1);
> +        assert(T::destroyed == 0);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T());
> +    }
> +    {
> +        T::reset_constructors();
> +        opt.emplace();
> +        assert(T::alive == 1);
> +        assert(T::constructed == 1);
> +        assert(T::default_constructed == 1);
> +        assert(T::destroyed == 1);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T());
> +    }
> +    {
> +        T::reset_constructors();
> +        opt.emplace(101);
> +        assert(T::alive == 1);
> +        assert(T::constructed == 1);
> +        assert(T::value_constructed == 1);
> +        assert(T::destroyed == 1);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(101));
> +    }
> +    {
> +        T::reset_constructors();
> +        opt.emplace(-10, 99);
> +        assert(T::alive == 1);
> +        assert(T::constructed == 1);
> +        assert(T::value_constructed == 1);
> +        assert(T::destroyed == 1);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(-10, 99));
> +    }
> +    {
> +        T::reset_constructors();
> +        opt.emplace(-10, 99);
> +        assert(T::alive == 1);
> +        assert(T::constructed == 1);
> +        assert(T::value_constructed == 1);
> +        assert(T::destroyed == 1);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(-10, 99));
> +    }
> +    {
> +        T::reset_constructors();
> +        opt.emplace({-10, 99, 42, 1});
> +        assert(T::alive == 1);
> +        assert(T::constructed == 1);
> +        assert(T::value_constructed == 1);
> +        assert(T::destroyed == 1);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(4)); // size of the initializer list
> +    }
> +    {
> +        T::reset_constructors();
> +        opt.emplace({-10, 99, 42, 1}, 42);
> +        assert(T::alive == 1);
> +        assert(T::constructed == 1);
> +        assert(T::value_constructed == 1);
> +        assert(T::destroyed == 1);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(4)); // size of the initializer list
> +    }
> +}
> +
> +
> +
> +int main()
> +{
> +    {
> +        test_on_test_type<TestTypes::TestType>();
> +        test_on_test_type<ExplicitTestTypes::TestType>();
> +    }
> +    {
> +        using T = int;
> +        test_one_arg<T>();
> +        test_one_arg<const T>();
> +    }
> +    {
> +        using T = ConstexprTestTypes::TestType;
> +        test_multi_arg<T>();
> +    }
> +    {
> +        using T = ExplicitConstexprTestTypes::TestType;
> +        test_multi_arg<T>();
> +    }
> +    {
> +        using T = TrivialTestTypes::TestType;
> +        test_multi_arg<T>();
> +    }
> +    {
> +        using T = ExplicitTrivialTestTypes::TestType;
> +        test_multi_arg<T>();
> +    }
> +    {
> +        optional<const int> opt;
> +        opt.emplace(42);
> +        assert(*opt == 42);
> +        opt.emplace();
> +        assert(*opt == 0);
> +    }
> +#ifndef TEST_HAS_NO_EXCEPTIONS
> +    Y::dtor_called = false;
> +    {
> +        Y y;
> +        optional<Y> opt(y);
> +        try
> +        {
> +            assert(static_cast<bool>(opt) == true);
> +            assert(Y::dtor_called == false);
> +            opt.emplace(1);
> +        }
> +        catch (int i)
> +        {
> +            assert(i == 6);
> +            assert(static_cast<bool>(opt) == false);
> +            assert(Y::dtor_called == true);
> +        }
> +    }
> +#endif
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/emplace_initializer_list.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.assign/empl
> ace_initializer_list.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/emplace_initializer_list.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/emplace_initializer_list.pass.cpp Wed Oct 12
> 02:46:20 2016
> @@ -0,0 +1,113 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class U, class... Args>
> +//   void optional<T>::emplace(initializer_list<U> il, Args&&... args);
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +#include <vector>
> +
> +#include "test_macros.h"
> +
> +using std::optional;
> +
> +class X
> +{
> +    int i_;
> +    int j_ = 0;
> +public:
> +    static bool dtor_called;
> +    constexpr X() : i_(0) {}
> +    constexpr X(int i) : i_(i) {}
> +    constexpr X(std::initializer_list<int> il) : i_(il.begin()[0]),
> j_(il.begin()[1]) {}
> +    ~X() {dtor_called = true;}
> +
> +    friend constexpr bool operator==(const X& x, const X& y)
> +        {return x.i_ == y.i_ && x.j_ == y.j_;}
> +};
> +
> +bool X::dtor_called = false;
> +
> +class Y
> +{
> +    int i_;
> +    int j_ = 0;
> +public:
> +    constexpr Y() : i_(0) {}
> +    constexpr Y(int i) : i_(i) {}
> +    constexpr Y(std::initializer_list<int> il) : i_(il.begin()[0]),
> j_(il.begin()[1]) {}
> +
> +    friend constexpr bool operator==(const Y& x, const Y& y)
> +        {return x.i_ == y.i_ && x.j_ == y.j_;}
> +};
> +
> +class Z
> +{
> +    int i_;
> +    int j_ = 0;
> +public:
> +    static bool dtor_called;
> +    Z() : i_(0) {}
> +    Z(int i) : i_(i) {}
> +    Z(std::initializer_list<int> il) : i_(il.begin()[0]),
> j_(il.begin()[1])
> +        { TEST_THROW(6);}
> +    ~Z() {dtor_called = true;}
> +
> +    friend bool operator==(const Z& x, const Z& y)
> +        {return x.i_ == y.i_ && x.j_ == y.j_;}
> +};
> +
> +bool Z::dtor_called = false;
> +
> +int main()
> +{
> +    {
> +        X x;
> +        optional<X> opt(x);
> +        assert(X::dtor_called == false);
> +        opt.emplace({1, 2});
> +        assert(X::dtor_called == true);
> +        assert(*opt == X({1, 2}));
> +    }
> +    {
> +        optional<std::vector<int>> opt;
> +        opt.emplace({1, 2, 3}, std::allocator<int>());
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == std::vector<int>({1, 2, 3}));
> +    }
> +    {
> +        optional<Y> opt;
> +        opt.emplace({1, 2});
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == Y({1, 2}));
> +    }
> +#ifndef TEST_HAS_NO_EXCEPTIONS
> +    {
> +        Z z;
> +        optional<Z> opt(z);
> +        try
> +        {
> +            assert(static_cast<bool>(opt) == true);
> +            assert(Z::dtor_called == false);
> +            opt.emplace({1, 2});
> +        }
> +        catch (int i)
> +        {
> +            assert(i == 6);
> +            assert(static_cast<bool>(opt) == false);
> +            assert(Z::dtor_called == true);
> +        }
> +    }
> +#endif
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/move.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.assign/move
> .pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/move.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/move.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,174 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// optional<T>& operator=(optional<T>&& rhs)
> +//     noexcept(is_nothrow_move_assignable<T>::value &&
> +//              is_nothrow_move_constructible<T>::value);
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +#include "archetypes.hpp"
> +
> +using std::optional;
> +
> +struct X
> +{
> +    static bool throw_now;
> +    static int alive;
> +
> +    X() { ++alive; }
> +    X(X&&)
> +    {
> +        if (throw_now)
> +            TEST_THROW(6);
> +        ++alive;
> +    }
> +
> +    X& operator=(X&&)
> +    {
> +        if (throw_now)
> +            TEST_THROW(42);
> +        return *this;
> +    }
> +
> +    ~X() { assert(alive > 0); --alive; }
> +};
> +
> +struct Y {};
> +
> +bool X::throw_now = false;
> +int X::alive = 0;
> +
> +int main()
> +{
> +    {
> +        static_assert(std::is_nothrow_move_assignable<optional<int>>::value,
> "");
> +        optional<int> opt;
> +        constexpr optional<int> opt2;
> +        opt = std::move(opt2);
> +        static_assert(static_cast<bool>(opt2) == false, "");
> +        assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
> +    }
> +    {
> +        optional<int> opt;
> +        constexpr optional<int> opt2(2);
> +        opt = std::move(opt2);
> +        static_assert(static_cast<bool>(opt2) == true, "");
> +        static_assert(*opt2 == 2, "");
> +        assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
> +        assert(*opt == *opt2);
> +    }
> +    {
> +        optional<int> opt(3);
> +        constexpr optional<int> opt2;
> +        opt = std::move(opt2);
> +        static_assert(static_cast<bool>(opt2) == false, "");
> +        assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
> +    }
> +    {
> +        using T = TestTypes::TestType;
> +        T::reset();
> +        optional<T> opt(3);
> +        optional<T> opt2;
> +        assert(T::alive == 1);
> +        opt = std::move(opt2);
> +        assert(T::alive == 0);
> +        assert(static_cast<bool>(opt2) == false);
> +        assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
> +    }
> +    {
> +        optional<int> opt(3);
> +        constexpr optional<int> opt2(2);
> +        opt = std::move(opt2);
> +        static_assert(static_cast<bool>(opt2) == true, "");
> +        static_assert(*opt2 == 2, "");
> +        assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
> +        assert(*opt == *opt2);
> +    }
> +#ifndef TEST_HAS_NO_EXCEPTIONS
> +    {
> +        static_assert(!std::is_nothrow_move_assignable<optional<X>>::value,
> "");
> +        X::alive = 0;
> +        X::throw_now = false;
> +        optional<X> opt;
> +        optional<X> opt2(X{});
> +        assert(X::alive == 1);
> +        assert(static_cast<bool>(opt2) == true);
> +        try
> +        {
> +            X::throw_now = true;
> +            opt = std::move(opt2);
> +            assert(false);
> +        }
> +        catch (int i)
> +        {
> +            assert(i == 6);
> +            assert(static_cast<bool>(opt) == false);
> +        }
> +        assert(X::alive == 1);
> +    }
> +    assert(X::alive == 0);
> +    {
> +        static_assert(!std::is_nothrow_move_assignable<optional<X>>::value,
> "");
> +        X::throw_now = false;
> +        optional<X> opt(X{});
> +        optional<X> opt2(X{});
> +        assert(X::alive == 2);
> +        assert(static_cast<bool>(opt2) == true);
> +        try
> +        {
> +            X::throw_now = true;
> +            opt = std::move(opt2);
> +            assert(false);
> +        }
> +        catch (int i)
> +        {
> +            assert(i == 42);
> +            assert(static_cast<bool>(opt) == true);
> +        }
> +        assert(X::alive == 2);
> +    }
> +    assert(X::alive == 0);
> +#endif // TEST_HAS_NO_EXCEPTIONS
> +    {
> +        static_assert(std::is_nothrow_move_assignable<optional<Y>>::value,
> "");
> +    }
> +    {
> +        struct ThrowsMove {
> +          ThrowsMove() noexcept {}
> +          ThrowsMove(ThrowsMove const&) noexcept {}
> +          ThrowsMove(ThrowsMove &&) noexcept(false) {}
> +          ThrowsMove& operator=(ThrowsMove const&) noexcept { return
> *this; }
> +          ThrowsMove& operator=(ThrowsMove &&) noexcept { return *this; }
> +        };
> +        static_assert(!std::is_nothrow_move_assignable<optional<ThrowsMove>>::value,
> "");
> +        struct ThrowsMoveAssign {
> +          ThrowsMoveAssign() noexcept {}
> +          ThrowsMoveAssign(ThrowsMoveAssign const&) noexcept {}
> +          ThrowsMoveAssign(ThrowsMoveAssign &&) noexcept {}
> +          ThrowsMoveAssign& operator=(ThrowsMoveAssign const&) noexcept {
> return *this; }
> +          ThrowsMoveAssign& operator=(ThrowsMoveAssign &&)
> noexcept(false) { return *this; }
> +        };
> +        static_assert(!std::is_nothrow_move_assignable<optional<ThrowsMoveAssign>>::value,
> "");
> +        struct NoThrowMove {
> +          NoThrowMove() noexcept(false) {}
> +          NoThrowMove(NoThrowMove const&) noexcept(false) {}
> +          NoThrowMove(NoThrowMove &&) noexcept {}
> +          NoThrowMove& operator=(NoThrowMove const&) noexcept { return
> *this; }
> +          NoThrowMove& operator=(NoThrowMove&&) noexcept { return *this; }
> +        };
> +        static_assert(std::is_nothrow_move_assignable<optional<NoThrowMove>>::value,
> "");
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/nullopt_t.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.assign/null
> opt_t.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/nullopt_t.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/nullopt_t.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,67 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// optional<T>& operator=(nullopt_t) noexcept;
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +#include "archetypes.hpp"
> +
> +using std::optional;
> +using std::nullopt_t;
> +using std::nullopt;
> +
> +int main()
> +{
> +    {
> +        optional<int> opt;
> +        static_assert(noexcept(opt = nullopt) == true, "");
> +        opt = nullopt;
> +        assert(static_cast<bool>(opt) == false);
> +    }
> +    {
> +        optional<int> opt(3);
> +        opt = nullopt;
> +        assert(static_cast<bool>(opt) == false);
> +    }
> +    using TT = TestTypes::TestType;
> +    TT::reset();
> +    {
> +        optional<TT> opt;
> +        static_assert(noexcept(opt = nullopt) == true, "");
> +        assert(TT::destroyed == 0);
> +        opt = nullopt;
> +        assert(TT::constructed == 0);
> +        assert(TT::alive == 0);
> +        assert(TT::destroyed == 0);
> +        assert(static_cast<bool>(opt) == false);
> +    }
> +    assert(TT::alive == 0);
> +    assert(TT::destroyed == 0);
> +    TT::reset();
> +    {
> +        optional<TT> opt(42);
> +        assert(TT::destroyed == 0);
> +        TT::reset_constructors();
> +        opt = nullopt;
> +        assert(TT::constructed == 0);
> +        assert(TT::alive == 0);
> +        assert(TT::destroyed == 1);
> +        assert(static_cast<bool>(opt) == false);
> +    }
> +    assert(TT::alive == 0);
> +    assert(TT::destroyed == 1);
> +    TT::reset();
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/optional_U.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.assign/opti
> onal_U.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/optional_U.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.assign/optional_U.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,268 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// From LWG2451:
> +// template <class U>
> +// optional<T>& operator=(optional<U>&& rhs);
> +
> +#include <optional>
> +#include <type_traits>
> +#include <memory>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +#include "archetypes.hpp"
> +
> +using std::optional;
> +
> +struct X
> +{
> +    static bool throw_now;
> +
> +    X() = default;
> +    X(int &&)
> +    {
> +        if (throw_now)
> +            TEST_THROW(6);
> +    }
> +};
> +
> +bool X::throw_now = false;
> +
> +struct Y1
> +{
> +    Y1() = default;
> +    Y1(const int&) {}
> +    Y1& operator=(const Y1&) = delete;
> +};
> +
> +struct Y2
> +{
> +    Y2() = default;
> +    Y2(const int&) = delete;
> +    Y2& operator=(const int&) { return *this; }
> +};
> +
> +class B {};
> +class D : public B {};
> +
> +
> +template <class T>
> +struct AssignableFrom {
> +  static int type_constructed;
> +  static int type_assigned;
> +static int int_constructed;
> +  static int int_assigned;
> +
> +  static void reset() {
> +      type_constructed = int_constructed = 0;
> +      type_assigned = int_assigned = 0;
> +  }
> +
> +  AssignableFrom() = default;
> +
> +  explicit AssignableFrom(T) { ++type_constructed; }
> +  AssignableFrom& operator=(T) { ++type_assigned; return *this; }
> +
> +  AssignableFrom(int) { ++int_constructed; }
> +  AssignableFrom& operator=(int) { ++int_assigned; return *this; }
> +private:
> +  AssignableFrom(AssignableFrom const&) = delete;
> +  AssignableFrom& operator=(AssignableFrom const&) = delete;
> +};
> +
> +template <class T> int AssignableFrom<T>::type_constructed = 0;
> +template <class T> int AssignableFrom<T>::type_assigned = 0;
> +template <class T> int AssignableFrom<T>::int_constructed = 0;
> +template <class T> int AssignableFrom<T>::int_assigned = 0;
> +
> +void test_with_test_type() {
> +    using T = TestTypes::TestType;
> +    T::reset();
> +    { // non-empty to empty
> +        T::reset_constructors();
> +        optional<T> opt;
> +        optional<int> other(42);
> +        opt = std::move(other);
> +        assert(T::alive == 1);
> +        assert(T::constructed == 1);
> +        assert(T::value_constructed == 1);
> +        assert(T::assigned == 0);
> +        assert(T::destroyed == 0);
> +        assert(static_cast<bool>(other) == true);
> +        assert(*other == 42);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(42));
> +    }
> +    assert(T::alive == 0);
> +    { // non-empty to non-empty
> +        optional<T> opt(101);
> +        optional<int> other(42);
> +        T::reset_constructors();
> +        opt = std::move(other);
> +        assert(T::alive == 1);
> +        assert(T::constructed == 0);
> +        assert(T::assigned == 1);
> +        assert(T::value_assigned == 1);
> +        assert(T::destroyed == 0);
> +        assert(static_cast<bool>(other) == true);
> +        assert(*other == 42);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == T(42));
> +    }
> +    assert(T::alive == 0);
> +    { // empty to non-empty
> +        optional<T> opt(101);
> +        optional<int> other;
> +        T::reset_constructors();
> +        opt = std::move(other);
> +        assert(T::alive == 0);
> +        assert(T::constructed == 0);
> +        assert(T::assigned == 0);
> +        assert(T::destroyed == 1);
> +        assert(static_cast<bool>(other) == false);
> +        assert(static_cast<bool>(opt) == false);
> +    }
> +    assert(T::alive == 0);
> +    { // empty to empty
> +        optional<T> opt;
> +        optional<int> other;
> +        T::reset_constructors();
> +        opt = std::move(other);
> +        assert(T::alive == 0);
> +        assert(T::constructed == 0);
> +        assert(T::assigned == 0);
> +        assert(T::destroyed == 0);
> +        assert(static_cast<bool>(other) == false);
> +        assert(static_cast<bool>(opt) == false);
> +    }
> +    assert(T::alive == 0);
> +}
> +
> +
> +void test_ambigious_assign() {
> +    using OptInt = std::optional<int>;
> +    {
> +        using T = AssignableFrom<OptInt&&>;
> +        T::reset();
> +        {
> +            OptInt a(42);
> +            std::optional<T> t;
> +            t = std::move(a);
> +            assert(T::type_constructed == 1);
> +            assert(T::type_assigned == 0);
> +            assert(T::int_constructed == 0);
> +            assert(T::int_assigned == 0);
> +        }
> +        {
> +            using Opt = std::optional<T>;
> +            static_assert(!std::is_assignable<Opt&, const
> OptInt&&>::value, "");
> +            static_assert(!std::is_assignable<Opt&, const
> OptInt&>::value, "");
> +            static_assert(!std::is_assignable<Opt&, OptInt&>::value, "");
> +        }
> +    }
> +    {
> +        using T = AssignableFrom<OptInt const&&>;
> +        T::reset();
> +        {
> +            const OptInt a(42);
> +            std::optional<T> t;
> +            t = std::move(a);
> +            assert(T::type_constructed == 1);
> +            assert(T::type_assigned == 0);
> +            assert(T::int_constructed == 0);
> +            assert(T::int_assigned == 0);
> +        }
> +        T::reset();
> +        {
> +            OptInt a(42);
> +            std::optional<T> t;
> +            t = std::move(a);
> +            assert(T::type_constructed == 1);
> +            assert(T::type_assigned == 0);
> +            assert(T::int_constructed == 0);
> +            assert(T::int_assigned == 0);
> +        }
> +        {
> +            using Opt = std::optional<T>;
> +            static_assert(std::is_assignable<Opt&, OptInt&&>::value, "");
> +            static_assert(!std::is_assignable<Opt&, const
> OptInt&>::value, "");
> +            static_assert(!std::is_assignable<Opt&, OptInt&>::value, "");
> +        }
> +    }
> +}
> +
> +
> +int main()
> +{
> +    test_with_test_type();
> +    test_ambigious_assign();
> +    {
> +        optional<int> opt;
> +        optional<short> opt2;
> +        opt = std::move(opt2);
> +        assert(static_cast<bool>(opt2) == false);
> +        assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
> +    }
> +    {
> +        optional<int> opt;
> +        optional<short> opt2(short{2});
> +        opt = std::move(opt2);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 2);
> +        assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
> +        assert(*opt == *opt2);
> +    }
> +    {
> +        optional<int> opt(3);
> +        optional<short> opt2;
> +        opt = std::move(opt2);
> +        assert(static_cast<bool>(opt2) == false);
> +        assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
> +    }
> +    {
> +        optional<int> opt(3);
> +        optional<short> opt2(short{2});
> +        opt = std::move(opt2);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 2);
> +        assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
> +        assert(*opt == *opt2);
> +    }
> +    {
> +        optional<std::unique_ptr<B>> opt;
> +        optional<std::unique_ptr<D>> other(new D());
> +        opt = std::move(other);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(static_cast<bool>(other) == true);
> +        assert(opt->get() != nullptr);
> +        assert(other->get() == nullptr);
> +    }
> +#ifndef TEST_HAS_NO_EXCEPTIONS
> +    {
> +        optional<X> opt;
> +        optional<int> opt2(42);
> +        assert(static_cast<bool>(opt2) == true);
> +        try
> +        {
> +            X::throw_now = true;
> +            opt = std::move(opt2);
> +            assert(false);
> +        }
> +        catch (int i)
> +        {
> +            assert(i == 6);
> +            assert(static_cast<bool>(opt) == false);
> +        }
> +    }
> +#endif
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/U.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.ctor/U.pass
> .cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/U.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/U.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,137 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +//
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +
> +// <optional>
> +
> +// template <class U>
> +//   constexpr EXPLICIT optional(U&& u);
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +#include "archetypes.hpp"
> +#include "test_convertible.hpp"
> +
> +
> +using std::optional;
> +
> +struct ImplicitThrow
> +{
> +    constexpr ImplicitThrow(int x) { if (x != -1) TEST_THROW(6);}
> +};
> +
> +struct ExplicitThrow
> +{
> +    constexpr explicit ExplicitThrow(int x) { if (x != -1) TEST_THROW(6);}
> +};
> +
> +
> +template <class To, class From>
> +constexpr bool implicit_conversion(optional<To>&& opt, const From& v)
> +{
> +    using O = optional<To>;
> +    static_assert(test_convertible<O, From>(), "");
> +    static_assert(!test_convertible<O, void*>(), "");
> +    static_assert(!test_convertible<O, From, int>(), "");
> +    return opt && *opt == static_cast<To>(v);
> +}
> +
> +template <class To, class Input, class Expect>
> +constexpr bool explicit_conversion(Input&& in, const Expect& v)
> +{
> +    using O = optional<To>;
> +    static_assert(std::is_constructible<O, Input>::value, "");
> +    static_assert(!std::is_convertible<Input, O>::value, "");
> +    static_assert(!std::is_constructible<O, void*>::value, "");
> +    static_assert(!std::is_constructible<O, Input, int>::value, "");
> +    optional<To> opt(std::forward<Input>(in));
> +    return opt && *opt == static_cast<To>(v);
> +}
> +
> +void test_implicit()
> +{
> +    {
> +        using T = long long;
> +        static_assert(implicit_conversion<long long>(42, 42), "");
> +    }
> +    {
> +        using T = long double;
> +        static_assert(implicit_conversion<long double>(3.14, 3.14), "");
> +    }
> +    {
> +        using T = TrivialTestTypes::TestType;
> +        static_assert(implicit_conversion<T>(42, 42), "");
> +    }
> +    {
> +        using T = TestTypes::TestType;
> +        assert(implicit_conversion<T>(3, T(3)));
> +    }
> +#ifndef TEST_HAS_NO_EXCEPTIONS
> +    {
> +        try {
> +            using T = ImplicitThrow;
> +            optional<T> t = 42;
> +            assert(false);
> +        } catch (int) {
> +        }
> +    }
> +#endif
> +}
> +
> +void test_explicit() {
> +    {
> +        using T = ExplicitTrivialTestTypes::TestType;
> +        using O = optional<T>;
> +        static_assert(explicit_conversion<T>(42, 42), "");
> +    }
> +    {
> +        using T = ExplicitConstexprTestTypes::TestType;
> +        using O = optional<T>;
> +        static_assert(explicit_conversion<T>(42, 42), "");
> +        static_assert(!std::is_convertible<int, T>::value, "");
> +    }
> +    {
> +        using T = ExplicitTestTypes::TestType;
> +        using O = optional<T>;
> +        T::reset();
> +        {
> +            assert(explicit_conversion<T>(42, 42));
> +            assert(T::alive == 0);
> +        }
> +        T::reset();
> +        {
> +            optional<T> t(42);
> +            assert(T::alive == 1);
> +            assert(T::value_constructed == 1);
> +            assert(T::move_constructed == 0);
> +            assert(T::copy_constructed == 0);
> +            assert(t.value().value == 42);
> +        }
> +        assert(T::alive == 0);
> +    }
> +#ifndef TEST_HAS_NO_EXCEPTIONS
> +    {
> +        try {
> +            using T = ExplicitThrow;
> +            optional<T> t(42);
> +            assert(false);
> +        } catch (int) {
> +        }
> +    }
> +#endif
> +}
> +
> +int main() {
> +    test_implicit();
> +    test_explicit();
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/const_T.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.ctor/const_
> T.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/const_T.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/const_T.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,123 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +//
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +
> +// <optional>
> +
> +// constexpr optional(const T& v);
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +#include "archetypes.hpp"
> +
> +using std::optional;
> +
> +int main()
> +{
> +    {
> +        typedef int T;
> +        constexpr T t(5);
> +        constexpr optional<T> opt(t);
> +        static_assert(static_cast<bool>(opt) == true, "");
> +        static_assert(*opt == 5, "");
> +
> +        struct test_constexpr_ctor
> +            : public optional<T>
> +        {
> +            constexpr test_constexpr_ctor(const T&) {}
> +        };
> +
> +    }
> +    {
> +        typedef double T;
> +        constexpr T t(3);
> +        constexpr optional<T> opt(t);
> +        static_assert(static_cast<bool>(opt) == true, "");
> +        static_assert(*opt == 3, "");
> +
> +        struct test_constexpr_ctor
> +            : public optional<T>
> +        {
> +            constexpr test_constexpr_ctor(const T&) {}
> +        };
> +
> +    }
> +    {
> +        typedef TestTypes::TestType T;
> +        T::reset();
> +        const T t(3);
> +        optional<T> opt = t;
> +        assert(T::alive == 2);
> +        assert(T::copy_constructed == 1);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(opt.value().value == 3);
> +    }
> +    {
> +        typedef ExplicitTestTypes::TestType T;
> +        static_assert(!std::is_convertible<T const&,
> optional<T>>::value, "");
> +        T::reset();
> +        const T t(3);
> +        optional<T> opt(t);
> +        assert(T::alive == 2);
> +        assert(T::copy_constructed == 1);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(opt.value().value == 3);
> +    }
> +    {
> +        typedef ConstexprTestTypes::TestType T;
> +        constexpr T t(3);
> +        constexpr optional<T> opt = {t};
> +        static_assert(static_cast<bool>(opt) == true, "");
> +        static_assert(opt.value().value == 3, "");
> +
> +        struct test_constexpr_ctor
> +            : public optional<T>
> +        {
> +            constexpr test_constexpr_ctor(const T&) {}
> +        };
> +    }
> +    {
> +        typedef ExplicitConstexprTestTypes::TestType T;
> +        static_assert(!std::is_convertible<const T&,
> optional<T>>::value, "");
> +        constexpr T t(3);
> +        constexpr optional<T> opt(t);
> +        static_assert(static_cast<bool>(opt) == true, "");
> +        static_assert(opt.value().value == 3, "");
> +
> +        struct test_constexpr_ctor
> +            : public optional<T>
> +        {
> +            constexpr test_constexpr_ctor(const T&) {}
> +        };
> +
> +    }
> +#ifndef TEST_HAS_NO_EXCEPTIONS
> +    {
> +        struct Z {
> +            Z(int) {}
> +            Z(const Z&) {throw 6;}
> +        };
> +        typedef Z T;
> +        try
> +        {
> +            const T t(3);
> +            optional<T> opt(t);
> +            assert(false);
> +        }
> +        catch (int i)
> +        {
> +            assert(i == 6);
> +        }
> +    }
> +#endif
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/const_optional_U.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.ctor/const_
> optional_U.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/const_optional_U.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/const_optional_U.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,134 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class U>
> +//   optional(const optional<U>& rhs);
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +using std::optional;
> +
> +template <class T, class U>
> +void
> +test(const optional<U>& rhs, bool is_going_to_throw = false)
> +{
> +    bool rhs_engaged = static_cast<bool>(rhs);
> +#ifndef TEST_HAS_NO_EXCEPTIONS
> +    try
> +    {
> +        optional<T> lhs = rhs;
> +        assert(is_going_to_throw == false);
> +        assert(static_cast<bool>(lhs) == rhs_engaged);
> +        if (rhs_engaged)
> +            assert(*lhs == *rhs);
> +    }
> +    catch (int i)
> +    {
> +        assert(i == 6);
> +    }
> +#else
> +    if (is_going_to_throw) return;
> +    optional<T> lhs = rhs;
> +    assert(static_cast<bool>(lhs) == rhs_engaged);
> +    if (rhs_engaged)
> +        assert(*lhs == *rhs);
> +#endif
> +}
> +
> +class X
> +{
> +    int i_;
> +public:
> +    X(int i) : i_(i) {}
> +    X(const X& x) : i_(x.i_) {}
> +    ~X() {i_ = 0;}
> +    friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
> +};
> +
> +class Y
> +{
> +    int i_;
> +public:
> +    Y(int i) : i_(i) {}
> +
> +    friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_
> == y.i_;}
> +};
> +
> +int count = 0;
> +
> +class Z
> +{
> +    int i_;
> +public:
> +    Z(int i) : i_(i) {TEST_THROW(6);}
> +
> +    friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_
> == y.i_;}
> +};
> +
> +
> +int main()
> +{
> +    {
> +        typedef short U;
> +        typedef int T;
> +        optional<U> rhs;
> +        test<T>(rhs);
> +    }
> +    {
> +        typedef short U;
> +        typedef int T;
> +        optional<U> rhs(U{3});
> +        test<T>(rhs);
> +    }
> +    {
> +        typedef X T;
> +        typedef int U;
> +        optional<U> rhs;
> +        test<T>(rhs);
> +    }
> +    {
> +        typedef X T;
> +        typedef int U;
> +        optional<U> rhs(U{3});
> +        test<T>(rhs);
> +    }
> +    {
> +        typedef Y T;
> +        typedef int U;
> +        optional<U> rhs;
> +        test<T>(rhs);
> +    }
> +    {
> +        typedef Y T;
> +        typedef int U;
> +        optional<U> rhs(U{3});
> +        test<T>(rhs);
> +    }
> +    {
> +        typedef Z T;
> +        typedef int U;
> +        optional<U> rhs;
> +        test<T>(rhs);
> +    }
> +    {
> +        typedef Z T;
> +        typedef int U;
> +        optional<U> rhs(U{3});
> +        test<T>(rhs, true);
> +    }
> +
> +    static_assert(!(std::is_constructible<optional<X>, const
> optional<Y>&>::value), "");
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/copy.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.ctor/copy.
> pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/copy.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/copy.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,150 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// optional(const optional<T>& rhs);
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +#include "archetypes.hpp"
> +
> +using std::optional;
> +
> +template <class T, class ...InitArgs>
> +void test(InitArgs&&... args)
> +{
> +    const optional<T> rhs(std::forward<InitArgs>(args)...);
> +    bool rhs_engaged = static_cast<bool>(rhs);
> +    optional<T> lhs = rhs;
> +    assert(static_cast<bool>(lhs) == rhs_engaged);
> +    if (rhs_engaged)
> +        assert(*lhs == *rhs);
> +}
> +
> +void test_throwing_ctor() {
> +#ifndef TEST_HAS_NO_EXCEPTIONS
> +    struct Z {
> +      Z() : count(0) {}
> +      Z(Z const& o) : count(o.count + 1)
> +      { if (count == 2) throw 6; }
> +      int count;
> +    };
> +    const Z z;
> +    const optional<Z> rhs(z);
> +    try
> +    {
> +        optional<Z> lhs(rhs);
> +        assert(false);
> +    }
> +    catch (int i)
> +    {
> +        assert(i == 6);
> +    }
> +#endif
> +}
> +
> +template <class T, class ...InitArgs>
> +void test_ref(InitArgs&&... args)
> +{
> +    const optional<T> rhs(std::forward<InitArgs>(args)...);
> +    bool rhs_engaged = static_cast<bool>(rhs);
> +    optional<T> lhs = rhs;
> +    assert(static_cast<bool>(lhs) == rhs_engaged);
> +    if (rhs_engaged)
> +        assert(&(*lhs) == &(*rhs));
> +}
> +
> +
> +void test_reference_extension()
> +{
> +#if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently
> disabled.
> +    using T = TestTypes::TestType;
> +    T::reset();
> +    {
> +        T t;
> +        T::reset_constructors();
> +        test_ref<T&>();
> +        test_ref<T&>(t);
> +        assert(T::alive == 1);
> +        assert(T::constructed == 0);
> +        assert(T::assigned == 0);
> +        assert(T::destroyed == 0);
> +    }
> +    assert(T::destroyed == 1);
> +    assert(T::alive == 0);
> +    {
> +        T t;
> +        const T& ct = t;
> +        T::reset_constructors();
> +        test_ref<T const&>();
> +        test_ref<T const&>(t);
> +        test_ref<T const&>(ct);
> +        assert(T::alive == 1);
> +        assert(T::constructed == 0);
> +        assert(T::assigned == 0);
> +        assert(T::destroyed == 0);
> +    }
> +    assert(T::alive == 0);
> +    assert(T::destroyed == 1);
> +    {
> +        static_assert(!std::is_copy_constructible<std::optional<T&&>>::value,
> "");
> +        static_assert(!std::is_copy_constructible<std::optional<T
> const&&>>::value, "");
> +    }
> +#endif
> +}
> +
> +int main()
> +{
> +    test<int>();
> +    test<int>(3);
> +    {
> +        using T = TestTypes::TestType;
> +        T::reset();
> +        const optional<T> rhs;
> +        assert(T::alive == 0);
> +        const optional<T> lhs(rhs);
> +        assert(lhs.has_value() == false);
> +        assert(T::alive == 0);
> +    }
> +    TestTypes::TestType::reset();
> +    {
> +        using T = TestTypes::TestType;
> +        T::reset();
> +        const optional<T> rhs(42);
> +        assert(T::alive == 1);
> +        assert(T::value_constructed == 1);
> +        assert(T::copy_constructed == 0);
> +        const optional<T> lhs(rhs);
> +        assert(lhs.has_value());
> +        assert(T::copy_constructed == 1);
> +        assert(T::alive == 2);
> +    }
> +    TestTypes::TestType::reset();
> +    {
> +        using namespace ConstexprTestTypes;
> +        test<TestType>();
> +        test<TestType>(42);
> +    }
> +    {
> +        using namespace TrivialTestTypes;
> +        test<TestType>();
> +        test<TestType>(42);
> +    }
> +    {
> +        test_throwing_ctor();
> +    }
> +    {
> +        test_reference_extension();
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/default.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.ctor/defaul
> t.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/default.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/default.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,81 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// constexpr optional() noexcept;
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +#include "archetypes.hpp"
> +
> +using std::optional;
> +
> +template <class Opt>
> +void
> +test_constexpr()
> +{
> +    static_assert(std::is_nothrow_default_constructible<Opt>::value, "");
> +    static_assert(std::is_trivially_destructible<Opt>::value, "");
> +    static_assert(std::is_trivially_destructible<typename
> Opt::value_type>::value, "");
> +
> +    constexpr Opt opt;
> +    static_assert(static_cast<bool>(opt) == false, "");
> +
> +    struct test_constexpr_ctor
> +        : public Opt
> +    {
> +        constexpr test_constexpr_ctor() {}
> +    };
> +}
> +
> +template <class Opt>
> +void
> +test()
> +{
> +    static_assert(std::is_nothrow_default_constructible<Opt>::value, "");
> +    static_assert(!std::is_trivially_destructible<Opt>::value, "");
> +    static_assert(!std::is_trivially_destructible<typename
> Opt::value_type>::value, "");
> +    {
> +        Opt opt;
> +        assert(static_cast<bool>(opt) == false);
> +    }
> +    {
> +        const Opt opt;
> +        assert(static_cast<bool>(opt) == false);
> +    }
> +
> +    struct test_constexpr_ctor
> +        : public Opt
> +    {
> +        constexpr test_constexpr_ctor() {}
> +    };
> +}
> +
> +int main()
> +{
> +    test_constexpr<optional<int>>();
> +    test_constexpr<optional<int*>>();
> +    test_constexpr<optional<ImplicitTypes::NoCtors>>();
> +    test_constexpr<optional<NonTrivialTypes::NoCtors>>();
> +    test_constexpr<optional<NonConstexprTypes::NoCtors>>();
> +    test<optional<NonLiteralTypes::NoCtors>>();
> +    // EXTENSIONS
> +#if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently
> disabled.
> +    test_constexpr<optional<int&>>();
> +    test_constexpr<optional<const int&>>();
> +    test_constexpr<optional<int&>>();
> +    test_constexpr<optional<NonLiteralTypes::NoCtors&>>();
> +    test_constexpr<optional<NonLiteralTypes::NoCtors&&>>();
> +#endif
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/explicit_const_optional_U.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.ctor/explic
> it_const_optional_U.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/explicit_const_optional_U.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/explicit_const_optional_U.pass.cpp Wed Oct 12
> 02:46:20 2016
> @@ -0,0 +1,121 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class U>
> +//   explicit optional(const optional<U>& rhs);
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +using std::optional;
> +
> +template <class T, class U>
> +void
> +test(const optional<U>& rhs, bool is_going_to_throw = false)
> +{
> +    static_assert(!(std::is_convertible<const optional<U>&,
> optional<T>>::value), "");
> +    bool rhs_engaged = static_cast<bool>(rhs);
> +#ifndef TEST_HAS_NO_EXCEPTIONS
> +    try
> +    {
> +        optional<T> lhs(rhs);
> +        assert(is_going_to_throw == false);
> +        assert(static_cast<bool>(lhs) == rhs_engaged);
> +        if (rhs_engaged)
> +            assert(*lhs == T(*rhs));
> +    }
> +    catch (int i)
> +    {
> +        assert(i == 6);
> +    }
> +#else
> +    if (is_going_to_throw) return;
> +    optional<T> lhs(rhs);
> +    assert(static_cast<bool>(lhs) == rhs_engaged);
> +    if (rhs_engaged)
> +        assert(*lhs == T(*rhs));
> +#endif
> +}
> +
> +class X
> +{
> +    int i_;
> +public:
> +    explicit X(int i) : i_(i) {}
> +    X(const X& x) : i_(x.i_) {}
> +    ~X() {i_ = 0;}
> +    friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
> +};
> +
> +class Y
> +{
> +    int i_;
> +public:
> +    explicit Y(int i) : i_(i) {}
> +
> +    friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_
> == y.i_;}
> +};
> +
> +int count = 0;
> +
> +class Z
> +{
> +    int i_;
> +public:
> +    explicit Z(int i) : i_(i) { TEST_THROW(6);}
> +
> +    friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_
> == y.i_;}
> +};
> +
> +
> +int main()
> +{
> +    {
> +        typedef X T;
> +        typedef int U;
> +        optional<U> rhs;
> +        test<T>(rhs);
> +    }
> +    {
> +        typedef X T;
> +        typedef int U;
> +        optional<U> rhs(3);
> +        test<T>(rhs);
> +    }
> +    {
> +        typedef Y T;
> +        typedef int U;
> +        optional<U> rhs;
> +        test<T>(rhs);
> +    }
> +    {
> +        typedef Y T;
> +        typedef int U;
> +        optional<U> rhs(3);
> +        test<T>(rhs);
> +    }
> +    {
> +        typedef Z T;
> +        typedef int U;
> +        optional<U> rhs;
> +        test<T>(rhs);
> +    }
> +    {
> +        typedef Z T;
> +        typedef int U;
> +        optional<U> rhs(3);
> +        test<T>(rhs, true);
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/explicit_optional_U.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.ctor/explic
> it_optional_U.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/explicit_optional_U.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/explicit_optional_U.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,84 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class U>
> +//   explicit optional(optional<U>&& rhs);
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +using std::optional;
> +
> +template <class T, class U>
> +void
> +test(optional<U>&& rhs, bool is_going_to_throw = false)
> +{
> +    static_assert(!(std::is_convertible<optional<U>&&,
> optional<T>>::value), "");
> +    bool rhs_engaged = static_cast<bool>(rhs);
> +#ifndef TEST_HAS_NO_EXCEPTIONS
> +    try
> +    {
> +        optional<T> lhs(std::move(rhs));
> +        assert(is_going_to_throw == false);
> +        assert(static_cast<bool>(lhs) == rhs_engaged);
> +    }
> +    catch (int i)
> +    {
> +        assert(i == 6);
> +    }
> +#else
> +    if (is_going_to_throw) return;
> +    optional<T> lhs(std::move(rhs));
> +    assert(static_cast<bool>(lhs) == rhs_engaged);
> +#endif
> +}
> +
> +class X
> +{
> +    int i_;
> +public:
> +    explicit X(int i) : i_(i) {}
> +    X(X&& x) : i_(std::exchange(x.i_, 0)) {}
> +    ~X() {i_ = 0;}
> +    friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
> +};
> +
> +int count = 0;
> +
> +class Z
> +{
> +public:
> +    explicit Z(int) { TEST_THROW(6); }
> +};
> +
> +int main()
> +{
> +    {
> +        optional<int> rhs;
> +        test<X>(std::move(rhs));
> +    }
> +    {
> +        optional<int> rhs(3);
> +        test<X>(std::move(rhs));
> +    }
> +    {
> +        optional<int> rhs;
> +        test<Z>(std::move(rhs));
> +    }
> +    {
> +        optional<int> rhs(3);
> +        test<Z>(std::move(rhs), true);
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/in_place_t.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.ctor/in_
> place_t.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/in_place_t.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/in_place_t.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,144 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +//
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +
> +// <optional>
> +
> +// template <class... Args>
> +//   constexpr explicit optional(in_place_t, Args&&... args);
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +using std::optional;
> +using std::in_place_t;
> +using std::in_place;
> +
> +class X
> +{
> +    int i_;
> +    int j_ = 0;
> +public:
> +    X() : i_(0) {}
> +    X(int i) : i_(i) {}
> +    X(int i, int j) : i_(i), j_(j) {}
> +
> +    ~X() {}
> +
> +    friend bool operator==(const X& x, const X& y)
> +        {return x.i_ == y.i_ && x.j_ == y.j_;}
> +};
> +
> +class Y
> +{
> +    int i_;
> +    int j_ = 0;
> +public:
> +    constexpr Y() : i_(0) {}
> +    constexpr Y(int i) : i_(i) {}
> +    constexpr Y(int i, int j) : i_(i), j_(j) {}
> +
> +    friend constexpr bool operator==(const Y& x, const Y& y)
> +        {return x.i_ == y.i_ && x.j_ == y.j_;}
> +};
> +
> +class Z
> +{
> +public:
> +    Z(int i) {TEST_THROW(6);}
> +};
> +
> +
> +int main()
> +{
> +    {
> +        constexpr optional<int> opt(in_place, 5);
> +        static_assert(static_cast<bool>(opt) == true, "");
> +        static_assert(*opt == 5, "");
> +
> +        struct test_constexpr_ctor
> +            : public optional<int>
> +        {
> +            constexpr test_constexpr_ctor(in_place_t, int i)
> +                : optional<int>(in_place, i) {}
> +        };
> +
> +    }
> +    {
> +        const optional<X> opt(in_place);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == X());
> +    }
> +    {
> +        const optional<X> opt(in_place, 5);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == X(5));
> +    }
> +    {
> +        const optional<X> opt(in_place, 5, 4);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(*opt == X(5, 4));
> +    }
> +    {
> +        constexpr optional<Y> opt(in_place);
> +        static_assert(static_cast<bool>(opt) == true, "");
> +        static_assert(*opt == Y(), "");
> +
> +        struct test_constexpr_ctor
> +            : public optional<Y>
> +        {
> +            constexpr test_constexpr_ctor(in_place_t)
> +                : optional<Y>(in_place) {}
> +        };
> +
> +    }
> +    {
> +        constexpr optional<Y> opt(in_place, 5);
> +        static_assert(static_cast<bool>(opt) == true, "");
> +        static_assert(*opt == Y(5), "");
> +
> +        struct test_constexpr_ctor
> +            : public optional<Y>
> +        {
> +            constexpr test_constexpr_ctor(in_place_t, int i)
> +                : optional<Y>(in_place, i) {}
> +        };
> +
> +    }
> +    {
> +        constexpr optional<Y> opt(in_place, 5, 4);
> +        static_assert(static_cast<bool>(opt) == true, "");
> +        static_assert(*opt == Y(5, 4), "");
> +
> +        struct test_constexpr_ctor
> +            : public optional<Y>
> +        {
> +            constexpr test_constexpr_ctor(in_place_t, int i, int j)
> +                : optional<Y>(in_place, i, j) {}
> +        };
> +
> +    }
> +#ifndef TEST_HAS_NO_EXCEPTIONS
> +    {
> +        try
> +        {
> +            const optional<Z> opt(in_place, 1);
> +            assert(false);
> +        }
> +        catch (int i)
> +        {
> +            assert(i == 6);
> +        }
> +    }
> +#endif
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/initializer_list.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.ctor/initia
> lizer_list.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/initializer_list.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/initializer_list.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,116 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class U, class... Args>
> +//     constexpr
> +//     explicit optional(in_place_t, initializer_list<U> il, Args&&...
> args);
> +
> +#include <optional>
> +#include <type_traits>
> +#include <vector>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +using std::optional;
> +using std::in_place_t;
> +using std::in_place;
> +
> +class X
> +{
> +    int i_;
> +    int j_ = 0;
> +public:
> +    X() : i_(0) {}
> +    X(int i) : i_(i) {}
> +    X(int i, int j) : i_(i), j_(j) {}
> +
> +    ~X() {}
> +
> +    friend bool operator==(const X& x, const X& y)
> +        {return x.i_ == y.i_ && x.j_ == y.j_;}
> +};
> +
> +class Y
> +{
> +    int i_;
> +    int j_ = 0;
> +public:
> +    constexpr Y() : i_(0) {}
> +    constexpr Y(int i) : i_(i) {}
> +    constexpr Y(std::initializer_list<int> il) : i_(il.begin()[0]),
> j_(il.begin()[1]) {}
> +
> +    friend constexpr bool operator==(const Y& x, const Y& y)
> +        {return x.i_ == y.i_ && x.j_ == y.j_;}
> +};
> +
> +class Z
> +{
> +    int i_;
> +    int j_ = 0;
> +public:
> +    Z() : i_(0) {}
> +    Z(int i) : i_(i) {}
> +    Z(std::initializer_list<int> il) : i_(il.begin()[0]),
> j_(il.begin()[1])
> +        {TEST_THROW(6);}
> +
> +    friend bool operator==(const Z& x, const Z& y)
> +        {return x.i_ == y.i_ && x.j_ == y.j_;}
> +};
> +
> +int main()
> +{
> +    {
> +        static_assert(!std::is_constructible<X,
> std::initializer_list<int>&>::value, "");
> +        static_assert(!std::is_constructible<optional<X>,
> std::initializer_list<int>&>::value, "");
> +    }
> +    {
> +        optional<std::vector<int>> opt(in_place, {3, 1});
> +        assert(static_cast<bool>(opt) == true);
> +        assert((*opt == std::vector<int>{3, 1}));
> +        assert(opt->size() == 2);
> +    }
> +    {
> +        optional<std::vector<int>> opt(in_place, {3, 1},
> std::allocator<int>());
> +        assert(static_cast<bool>(opt) == true);
> +        assert((*opt == std::vector<int>{3, 1}));
> +        assert(opt->size() == 2);
> +    }
> +    {
> +        static_assert(std::is_constructible<optional<Y>,
> std::initializer_list<int>&>::value, "");
> +        constexpr optional<Y> opt(in_place, {3, 1});
> +        static_assert(static_cast<bool>(opt) == true, "");
> +        static_assert(*opt == Y{3, 1}, "");
> +
> +        struct test_constexpr_ctor
> +            : public optional<Y>
> +        {
> +            constexpr test_constexpr_ctor(in_place_t,
> std::initializer_list<int> i)
> +                : optional<Y>(in_place, i) {}
> +        };
> +
> +    }
> +#ifndef TEST_HAS_NO_EXCEPTIONS
> +    {
> +        static_assert(std::is_constructible<optional<Z>,
> std::initializer_list<int>&>::value, "");
> +        try
> +        {
> +            optional<Z> opt(in_place, {3, 1});
> +            assert(false);
> +        }
> +        catch (int i)
> +        {
> +            assert(i == 6);
> +        }
> +    }
> +#endif
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/move.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.ctor/move.
> pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/move.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/move.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,196 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// optional(optional<T>&& rhs);
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +#include "archetypes.hpp"
> +
> +using std::optional;
> +
> +template <class T, class ...InitArgs>
> +void test(InitArgs&&... args)
> +{
> +    const optional<T> orig(std::forward<InitArgs>(args)...);
> +    optional<T> rhs(orig);
> +    bool rhs_engaged = static_cast<bool>(rhs);
> +    optional<T> lhs = std::move(rhs);
> +    assert(static_cast<bool>(lhs) == rhs_engaged);
> +    if (rhs_engaged)
> +        assert(*lhs == *orig);
> +}
> +
> +void test_throwing_ctor() {
> +#ifndef TEST_HAS_NO_EXCEPTIONS
> +    struct Z {
> +      Z() : count(0) {}
> +      Z(Z&& o) : count(o.count + 1)
> +      { if (count == 2) throw 6; }
> +      int count;
> +    };
> +    Z z;
> +    optional<Z> rhs(std::move(z));
> +    try
> +    {
> +        optional<Z> lhs(std::move(rhs));
> +        assert(false);
> +    }
> +    catch (int i)
> +    {
> +        assert(i == 6);
> +    }
> +#endif
> +}
> +
> +
> +template <class T, class ...InitArgs>
> +void test_ref(InitArgs&&... args)
> +{
> +    optional<T> rhs(std::forward<InitArgs>(args)...);
> +    bool rhs_engaged = static_cast<bool>(rhs);
> +    optional<T> lhs = std::move(rhs);
> +    assert(static_cast<bool>(lhs) == rhs_engaged);
> +    if (rhs_engaged)
> +        assert(&(*lhs) == &(*rhs));
> +}
> +
> +void test_reference_extension()
> +{
> +#if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently
> disabled.
> +    using T = TestTypes::TestType;
> +    T::reset();
> +    {
> +        T t;
> +        T::reset_constructors();
> +        test_ref<T&>();
> +        test_ref<T&>(t);
> +        assert(T::alive == 1);
> +        assert(T::constructed == 0);
> +        assert(T::assigned == 0);
> +        assert(T::destroyed == 0);
> +    }
> +    assert(T::destroyed == 1);
> +    assert(T::alive == 0);
> +    {
> +        T t;
> +        const T& ct = t;
> +        T::reset_constructors();
> +        test_ref<T const&>();
> +        test_ref<T const&>(t);
> +        test_ref<T const&>(ct);
> +        assert(T::alive == 1);
> +        assert(T::constructed == 0);
> +        assert(T::assigned == 0);
> +        assert(T::destroyed == 0);
> +    }
> +    assert(T::alive == 0);
> +    assert(T::destroyed == 1);
> +    {
> +        T t;
> +        T::reset_constructors();
> +        test_ref<T&&>();
> +        test_ref<T&&>(std::move(t));
> +        assert(T::alive == 1);
> +        assert(T::constructed == 0);
> +        assert(T::assigned == 0);
> +        assert(T::destroyed == 0);
> +    }
> +    assert(T::alive == 0);
> +    assert(T::destroyed == 1);
> +    {
> +        T t;
> +        const T& ct = t;
> +        T::reset_constructors();
> +        test_ref<T const&&>();
> +        test_ref<T const&&>(std::move(t));
> +        test_ref<T const&&>(std::move(ct));
> +        assert(T::alive == 1);
> +        assert(T::constructed == 0);
> +        assert(T::assigned == 0);
> +        assert(T::destroyed == 0);
> +    }
> +    assert(T::alive == 0);
> +    assert(T::destroyed == 1);
> +    {
> +        static_assert(!std::is_copy_constructible<std::optional<T&&>>::value,
> "");
> +        static_assert(!std::is_copy_constructible<std::optional<T
> const&&>>::value, "");
> +    }
> +#endif
> +}
> +
> +
> +int main()
> +{
> +    test<int>();
> +    test<int>(3);
> +    {
> +        using T = TestTypes::TestType;
> +        T::reset();
> +        optional<T> rhs;
> +        assert(T::alive == 0);
> +        const optional<T> lhs(std::move(rhs));
> +        assert(lhs.has_value() == false);
> +        assert(rhs.has_value() == false);
> +        assert(T::alive == 0);
> +    }
> +    TestTypes::TestType::reset();
> +    {
> +        using T = TestTypes::TestType;
> +        T::reset();
> +        optional<T> rhs(42);
> +        assert(T::alive == 1);
> +        assert(T::value_constructed == 1);
> +        assert(T::move_constructed == 0);
> +        const optional<T> lhs(std::move(rhs));
> +        assert(lhs.has_value());
> +        assert(rhs.has_value());
> +        assert(lhs.value().value == 42);
> +        assert(rhs.value().value == -1);
> +        assert(T::move_constructed == 1);
> +        assert(T::alive == 2);
> +    }
> +    TestTypes::TestType::reset();
> +    {
> +        using namespace ConstexprTestTypes;
> +        test<TestType>();
> +        test<TestType>(42);
> +    }
> +    {
> +        using namespace TrivialTestTypes;
> +        test<TestType>();
> +        test<TestType>(42);
> +    }
> +    {
> +        test_throwing_ctor();
> +    }
> +    {
> +        struct ThrowsMove {
> +          ThrowsMove() noexcept(false) {}
> +          ThrowsMove(ThrowsMove const&) noexcept(false) {}
> +          ThrowsMove(ThrowsMove &&) noexcept(false) {}
> +        };
> +        static_assert(!std::is_nothrow_move_constructible<optional<ThrowsMove>>::value,
> "");
> +        struct NoThrowMove {
> +          NoThrowMove() noexcept(false) {}
> +          NoThrowMove(NoThrowMove const&) noexcept(false) {}
> +          NoThrowMove(NoThrowMove &&) noexcept(true) {}
> +        };
> +        static_assert(std::is_nothrow_move_constructible<optional<NoThrowMove>>::value,
> "");
> +    }
> +    {
> +        test_reference_extension();
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/nullopt_t.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.ctor/nullop
> t_t.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/nullopt_t.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/nullopt_t.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,73 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// constexpr optional(nullopt_t) noexcept;
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "archetypes.hpp"
> +
> +using std::optional;
> +using std::nullopt_t;
> +using std::nullopt;
> +
> +template <class Opt>
> +void
> +test_constexpr()
> +{
> +    static_assert(std::is_nothrow_constructible<Opt, nullopt_t&>::value,
> "");
> +    static_assert(std::is_trivially_destructible<Opt>::value, "");
> +    static_assert(std::is_trivially_destructible<typename
> Opt::value_type>::value, "");
> +
> +    constexpr Opt opt(nullopt);
> +    static_assert(static_cast<bool>(opt) == false, "");
> +
> +    struct test_constexpr_ctor
> +        : public Opt
> +    {
> +        constexpr test_constexpr_ctor() {}
> +    };
> +}
> +
> +template <class Opt>
> +void
> +test()
> +{
> +    static_assert(std::is_nothrow_constructible<Opt, nullopt_t&>::value,
> "");
> +    static_assert(!std::is_trivially_destructible<Opt>::value, "");
> +    static_assert(!std::is_trivially_destructible<typename
> Opt::value_type>::value, "");
> +    {
> +    Opt opt(nullopt);
> +    assert(static_cast<bool>(opt) == false);
> +    }
> +    {
> +    const Opt opt(nullopt);
> +    assert(static_cast<bool>(opt) == false);
> +    }
> +    struct test_constexpr_ctor
> +        : public Opt
> +    {
> +        constexpr test_constexpr_ctor() {}
> +    };
> +}
> +
> +int main()
> +{
> +    test_constexpr<optional<int>>();
> +    test_constexpr<optional<int*>>();
> +    test_constexpr<optional<ImplicitTypes::NoCtors>>();
> +    test_constexpr<optional<NonTrivialTypes::NoCtors>>();
> +    test_constexpr<optional<NonConstexprTypes::NoCtors>>();
> +    test<optional<NonLiteralTypes::NoCtors>>();
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/optional_U.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.ctor/option
> al_U.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/optional_U.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/optional_U.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,93 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class U>
> +//   optional(optional<U>&& rhs);
> +
> +#include <optional>
> +#include <type_traits>
> +#include <memory>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +using std::optional;
> +
> +template <class T, class U>
> +void
> +test(optional<U>&& rhs, bool is_going_to_throw = false)
> +{
> +    bool rhs_engaged = static_cast<bool>(rhs);
> +#ifndef TEST_HAS_NO_EXCEPTIONS
> +    try
> +    {
> +        optional<T> lhs = std::move(rhs);
> +        assert(is_going_to_throw == false);
> +        assert(static_cast<bool>(lhs) == rhs_engaged);
> +    }
> +    catch (int i)
> +    {
> +        assert(i == 6);
> +    }
> +#else
> +    if (is_going_to_throw) return;
> +    optional<T> lhs = std::move(rhs);
> +    assert(static_cast<bool>(lhs) == rhs_engaged);
> +#endif
> +}
> +
> +class X
> +{
> +    int i_;
> +public:
> +    X(int i) : i_(i) {}
> +    X(X&& x) : i_(std::exchange(x.i_, 0)) {}
> +    ~X() {i_ = 0;}
> +    friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
> +};
> +
> +int count = 0;
> +
> +struct Z
> +{
> +    Z(int) { TEST_THROW(6); }
> +};
> +
> +int main()
> +{
> +    {
> +        optional<short> rhs;
> +        test<int>(std::move(rhs));
> +    }
> +    {
> +        optional<short> rhs(short{3});
> +        test<int>(std::move(rhs));
> +    }
> +    {
> +        optional<int> rhs;
> +        test<X>(std::move(rhs));
> +    }
> +    {
> +        optional<int> rhs(3);
> +        test<X>(std::move(rhs));
> +    }
> +    {
> +        optional<int> rhs;
> +        test<Z>(std::move(rhs));
> +    }
> +    {
> +        optional<int> rhs(3);
> +        test<Z>(std::move(rhs), true);
> +    }
> +
> +    static_assert(!(std::is_constructible<optional<X>,
> optional<Z>>::value), "");
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/rvalue_T.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.ctor/rvalue
> _T.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/rvalue_T.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.ctor/rvalue_T.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,148 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +//
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +
> +// <optional>
> +
> +// constexpr optional(T&& v);
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +#include "archetypes.hpp"
> +
> +
> +using std::optional;
> +
> +
> +class Z
> +{
> +public:
> +    Z(int) {}
> +    Z(Z&&) {TEST_THROW(6);}
> +};
> +
> +
> +int main()
> +{
> +    {
> +        typedef int T;
> +        constexpr optional<T> opt(T(5));
> +        static_assert(static_cast<bool>(opt) == true, "");
> +        static_assert(*opt == 5, "");
> +
> +        struct test_constexpr_ctor
> +            : public optional<T>
> +        {
> +            constexpr test_constexpr_ctor(T&&) {}
> +        };
> +    }
> +    {
> +        typedef double T;
> +        constexpr optional<T> opt(T(3));
> +        static_assert(static_cast<bool>(opt) == true, "");
> +        static_assert(*opt == 3, "");
> +
> +        struct test_constexpr_ctor
> +            : public optional<T>
> +        {
> +            constexpr test_constexpr_ctor(T&&) {}
> +        };
> +    }
> +    {
> +        typedef TestTypes::TestType T;
> +        T::reset();
> +        optional<T> opt = T{3};
> +        assert(T::alive == 1);
> +        assert(T::move_constructed == 1);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(opt.value().value == 3);
> +    }
> +    {
> +        typedef ExplicitTestTypes::TestType T;
> +        static_assert(!std::is_convertible<T&&, optional<T>>::value, "");
> +        T::reset();
> +        optional<T> opt(T{3});
> +        assert(T::alive == 1);
> +        assert(T::move_constructed == 1);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(opt.value().value == 3);
> +    }
> +    {
> +        typedef TestTypes::TestType T;
> +        T::reset();
> +        optional<T> opt = {3};
> +        assert(T::alive == 1);
> +        assert(T::value_constructed == 1);
> +        assert(T::copy_constructed == 0);
> +        assert(T::move_constructed == 0);
> +        assert(static_cast<bool>(opt) == true);
> +        assert(opt.value().value == 3);
> +    }
> +    {
> +        typedef ConstexprTestTypes::TestType T;
> +        constexpr optional<T> opt = {T(3)};
> +        static_assert(static_cast<bool>(opt) == true, "");
> +        static_assert(opt.value().value == 3, "");
> +
> +        struct test_constexpr_ctor
> +            : public optional<T>
> +        {
> +            constexpr test_constexpr_ctor(const T&) {}
> +        };
> +    }
> +    {
> +        typedef ConstexprTestTypes::TestType T;
> +        constexpr optional<T> opt = {3};
> +        static_assert(static_cast<bool>(opt) == true, "");
> +        static_assert(opt.value().value == 3, "");
> +
> +        struct test_constexpr_ctor
> +            : public optional<T>
> +        {
> +            constexpr test_constexpr_ctor(const T&) {}
> +        };
> +    }
> +    {
> +        typedef ExplicitConstexprTestTypes::TestType T;
> +        static_assert(!std::is_convertible<T&&, optional<T>>::value, "");
> +        constexpr optional<T> opt(T{3});
> +        static_assert(static_cast<bool>(opt) == true, "");
> +        static_assert(opt.value().value == 3, "");
> +
> +        struct test_constexpr_ctor
> +            : public optional<T>
> +        {
> +            constexpr test_constexpr_ctor(T&&) {}
> +        };
> +
> +    }
> +#ifndef TEST_HAS_NO_EXCEPTIONS
> +    {
> +        struct Z {
> +            Z(int) {}
> +            Z(Z&&) {throw 6;}
> +        };
> +        typedef Z T;
> +        try
> +        {
> +            T t(3);
> +            optional<T> opt(std::move(t));
> +            assert(false);
> +        }
> +        catch (int i)
> +        {
> +            assert(i == 6);
> +        }
> +    }
> +#endif
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.dtor/dtor.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.dtor/dtor.
> pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.dtor/dtor.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.dtor/dtor.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,68 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// ~optional();
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +using std::optional;
> +
> +struct PODType {
> +  int value;
> +  int value2;
> +};
> +
> +class X
> +{
> +public:
> +    static bool dtor_called;
> +    X() = default;
> +    ~X() {dtor_called = true;}
> +};
> +
> +bool X::dtor_called = false;
> +
> +int main()
> +{
> +    {
> +        typedef int T;
> +        static_assert(std::is_trivially_destructible<T>::value, "");
> +        static_assert(std::is_trivially_destructible<optional<T>>::value,
> "");
> +        static_assert(std::is_literal_type<optional<T>>::value, "");
> +    }
> +    {
> +        typedef double T;
> +        static_assert(std::is_trivially_destructible<T>::value, "");
> +        static_assert(std::is_trivially_destructible<optional<T>>::value,
> "");
> +        static_assert(std::is_literal_type<optional<T>>::value, "");
> +    }
> +    {
> +        typedef PODType T;
> +        static_assert(std::is_trivially_destructible<T>::value, "");
> +        static_assert(std::is_trivially_destructible<optional<T>>::value,
> "");
> +        static_assert(std::is_literal_type<optional<T>>::value, "");
> +    }
> +    {
> +        typedef X T;
> +        static_assert(!std::is_trivially_destructible<T>::value, "");
> +        static_assert(!std::is_trivially_destructible<optional<T>>::value,
> "");
> +        static_assert(!std::is_literal_type<optional<T>>::value, "");
> +        {
> +            X x;
> +            optional<X> opt{x};
> +            assert(X::dtor_called == false);
> +        }
> +        assert(X::dtor_called == true);
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.mod/reset.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.mod/reset.
> pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.mod/reset.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.mod/reset.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,61 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +
> +// <optional>
> +
> +// void reset() noexcept;
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +using std::optional;
> +
> +struct X
> +{
> +    static bool dtor_called;
> +    ~X() {dtor_called = true;}
> +};
> +
> +bool X::dtor_called = false;
> +
> +int main()
> +{
> +    {
> +        optional<int> opt;
> +        static_assert(noexcept(opt.reset()) == true, "");
> +        opt.reset();
> +        assert(static_cast<bool>(opt) == false);
> +    }
> +    {
> +        optional<int> opt(3);
> +        opt.reset();
> +        assert(static_cast<bool>(opt) == false);
> +    }
> +    {
> +        optional<X> opt;
> +        static_assert(noexcept(opt.reset()) == true, "");
> +        assert(X::dtor_called == false);
> +        opt.reset();
> +        assert(X::dtor_called == false);
> +        assert(static_cast<bool>(opt) == false);
> +    }
> +    assert(X::dtor_called == false); // TRANSITION, Clang/C2 VSO#239997
> +    {
> +        optional<X> opt(X{});
> +        X::dtor_called = false;
> +        opt.reset();
> +        assert(X::dtor_called == true);
> +        assert(static_cast<bool>(opt) == false);
> +        X::dtor_called = false;
> +    }
> +    assert(X::dtor_called == false); // TRANSITION, Clang/C2 VSO#239997
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/bool.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.observe/
> bool.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/bool.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/bool.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,37 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// constexpr explicit optional<T>::operator bool() const noexcept;
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +int main()
> +{
> +    using std::optional;
> +    {
> +        const optional<int> opt; ((void)opt);
> +        ASSERT_NOEXCEPT(bool(opt));
> +        static_assert(!std::is_convertible<optional<int>, bool>::value,
> "");
> +    }
> +    {
> +        constexpr optional<int> opt;
> +        static_assert(!opt, "");
> +    }
> +    {
> +        constexpr optional<int> opt(0);
> +        static_assert(opt, "");
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/dereference.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.observe/
> dereference.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/dereference.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/dereference.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,73 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// constexpr T& optional<T>::operator*() &;
> +
> +#ifdef _LIBCPP_DEBUG
> +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
> +#endif
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +using std::optional;
> +
> +struct X
> +{
> +    constexpr int test() const& {return 3;}
> +    int test() & {return 4;}
> +    constexpr int test() const&& {return 5;}
> +    int test() && {return 6;}
> +};
> +
> +struct Y
> +{
> +    constexpr int test() {return 7;}
> +};
> +
> +constexpr int
> +test()
> +{
> +    optional<Y> opt{Y{}};
> +    return (*opt).test();
> +}
> +
> +int main()
> +{
> +    {
> +        optional<X> opt; ((void)opt);
> +        ASSERT_SAME_TYPE(decltype(*opt), X&);
> +        // ASSERT_NOT_NOEXCEPT(*opt);
> +        // FIXME: This assertion fails with GCC because it can see that
> +        // (A) operator*() is constexpr, and
> +        // (B) there is no path through the function that throws.
> +        // It's arguable if this is the correct behavior for the noexcept
> +        // operator.
> +        // Regardless this function should still be noexcept(false)
> because
> +        // it has a narrow contract.
> +    }
> +    {
> +        optional<X> opt(X{});
> +        assert((*opt).test() == 4);
> +    }
> +    static_assert(test() == 7, "");
> +#ifdef _LIBCPP_DEBUG
> +    {
> +        optional<X> opt;
> +        assert((*opt).test() == 3);
> +        assert(false);
> +    }
> +#endif  // _LIBCPP_DEBUG
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/dereference_const.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.observe/
> dereference_const.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/dereference_const.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/dereference_const.pass.cpp Wed Oct 12 02:46:20
> 2016
> @@ -0,0 +1,69 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// constexpr const T& optional<T>::operator*() const &;
> +
> +#ifdef _LIBCPP_DEBUG
> +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
> +#endif
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +using std::optional;
> +
> +struct X
> +{
> +    constexpr int test() const& {return 3;}
> +    int test() & {return 4;}
> +    constexpr int test() const&& {return 5;}
> +    int test() && {return 6;}
> +};
> +
> +struct Y
> +{
> +    int test() const {return 2;}
> +};
> +
> +int main()
> +{
> +    {
> +        const optional<X> opt; ((void)opt);
> +        ASSERT_SAME_TYPE(decltype(*opt), X const&);
> +        // ASSERT_NOT_NOEXCEPT(*opt);
> +        // FIXME: This assertion fails with GCC because it can see that
> +        // (A) operator*() is constexpr, and
> +        // (B) there is no path through the function that throws.
> +        // It's arguable if this is the correct behavior for the noexcept
> +        // operator.
> +        // Regardless this function should still be noexcept(false)
> because
> +        // it has a narrow contract.
> +    }
> +    {
> +        constexpr optional<X> opt(X{});
> +        static_assert((*opt).test() == 3, "");
> +    }
> +    {
> +        constexpr optional<Y> opt(Y{});
> +        assert((*opt).test() == 2);
> +    }
> +#ifdef _LIBCPP_DEBUG
> +    {
> +        const optional<X> opt;
> +        assert((*opt).test() == 3);
> +        assert(false);
> +    }
> +#endif  // _LIBCPP_DEBUG
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/dereference_const_rvalue.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.observe/
> dereference_const_rvalue.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/dereference_const_rvalue.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/dereference_const_rvalue.pass.cpp Wed Oct 12
> 02:46:20 2016
> @@ -0,0 +1,69 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// constexpr T&& optional<T>::operator*() const &&;
> +
> +#ifdef _LIBCPP_DEBUG
> +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
> +#endif
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +using std::optional;
> +
> +struct X
> +{
> +    constexpr int test() const& {return 3;}
> +    int test() & {return 4;}
> +    constexpr int test() const&& {return 5;}
> +    int test() && {return 6;}
> +};
> +
> +struct Y
> +{
> +    int test() const && {return 2;}
> +};
> +
> +int main()
> +{
> +    {
> +        const optional<X> opt; ((void)opt);
> +        ASSERT_SAME_TYPE(decltype(*std::move(opt)), X const &&);
> +        // ASSERT_NOT_NOEXCEPT(*std::move(opt));
> +        // FIXME: This assertion fails with GCC because it can see that
> +        // (A) operator*() is constexpr, and
> +        // (B) there is no path through the function that throws.
> +        // It's arguable if this is the correct behavior for the noexcept
> +        // operator.
> +        // Regardless this function should still be noexcept(false)
> because
> +        // it has a narrow contract.
> +    }
> +    {
> +        constexpr optional<X> opt(X{});
> +        static_assert((*std::move(opt)).test() == 5, "");
> +    }
> +    {
> +        constexpr optional<Y> opt(Y{});
> +        assert((*std::move(opt)).test() == 2);
> +    }
> +#ifdef _LIBCPP_DEBUG
> +    {
> +        optional<X> opt;
> +        assert((*std::move(opt)).test() == 5);
> +        assert(false);
> +    }
> +#endif  // _LIBCPP_DEBUG
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/dereference_rvalue.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.observe/
> dereference_rvalue.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/dereference_rvalue.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/dereference_rvalue.pass.cpp Wed Oct 12 02:46:20
> 2016
> @@ -0,0 +1,73 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// constexpr T&& optional<T>::operator*() &&;
> +
> +#ifdef _LIBCPP_DEBUG
> +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
> +#endif
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +using std::optional;
> +
> +struct X
> +{
> +    constexpr int test() const& {return 3;}
> +    int test() & {return 4;}
> +    constexpr int test() const&& {return 5;}
> +    int test() && {return 6;}
> +};
> +
> +struct Y
> +{
> +    constexpr int test() && {return 7;}
> +};
> +
> +constexpr int
> +test()
> +{
> +    optional<Y> opt{Y{}};
> +    return (*std::move(opt)).test();
> +}
> +
> +int main()
> +{
> +    {
> +        optional<X> opt; ((void)opt);
> +        ASSERT_SAME_TYPE(decltype(*std::move(opt)), X&&);
> +        // ASSERT_NOT_NOEXCEPT(*std::move(opt));
> +        // FIXME: This assertion fails with GCC because it can see that
> +        // (A) operator*() is constexpr, and
> +        // (B) there is no path through the function that throws.
> +        // It's arguable if this is the correct behavior for the noexcept
> +        // operator.
> +        // Regardless this function should still be noexcept(false)
> because
> +        // it has a narrow contract.
> +    }
> +    {
> +        optional<X> opt(X{});
> +        assert((*std::move(opt)).test() == 6);
> +    }
> +    static_assert(test() == 7, "");
> +#ifdef _LIBCPP_DEBUG
> +    {
> +        optional<X> opt;
> +        assert((*std::move(opt)).test() == 3);
> +        assert(false);
> +    }
> +#endif  // _LIBCPP_DEBUG
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/has_value.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.observe/
> has_value.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/has_value.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/has_value.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,37 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// constexpr bool optional<T>::has_value() const noexcept;
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +int main()
> +{
> +    using std::optional;
> +    {
> +        const optional<int> opt; ((void)opt);
> +        ASSERT_NOEXCEPT(opt.has_value());
> +        ASSERT_SAME_TYPE(decltype(opt.has_value()), bool);
> +    }
> +    {
> +        constexpr optional<int> opt;
> +        static_assert(!opt.has_value(), "");
> +    }
> +    {
> +        constexpr optional<int> opt(0);
> +        static_assert(opt.has_value(), "");
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/op_arrow.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.observe/op_
> arrow.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/op_arrow.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/op_arrow.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,72 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// constexpr T* optional<T>::operator->();
> +
> +#ifdef _LIBCPP_DEBUG
> +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
> +#endif
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +using std::optional;
> +
> +struct X
> +{
> +    int test() noexcept {return 3;}
> +};
> +
> +struct Y
> +{
> +    constexpr int test() {return 3;}
> +};
> +
> +constexpr int
> +test()
> +{
> +    optional<Y> opt{Y{}};
> +    return opt->test();
> +}
> +
> +int main()
> +{
> +    {
> +        std::optional<X> opt; ((void)opt);
> +        ASSERT_SAME_TYPE(decltype(opt.operator->()), X*);
> +        // ASSERT_NOT_NOEXCEPT(opt.operator->());
> +        // FIXME: This assertion fails with GCC because it can see that
> +        // (A) operator->() is constexpr, and
> +        // (B) there is no path through the function that throws.
> +        // It's arguable if this is the correct behavior for the noexcept
> +        // operator.
> +        // Regardless this function should still be noexcept(false)
> because
> +        // it has a narrow contract.
> +    }
> +    {
> +        optional<X> opt(X{});
> +        assert(opt->test() == 3);
> +    }
> +    {
> +        static_assert(test() == 3, "");
> +    }
> +#ifdef _LIBCPP_DEBUG
> +    {
> +        optional<X> opt;
> +        assert(opt->test() == 3);
> +        assert(false);
> +    }
> +#endif  // _LIBCPP_DEBUG
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/op_arrow_const.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.observe/op_
> arrow_const.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/op_arrow_const.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/op_arrow_const.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,76 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// constexpr const T* optional<T>::operator->() const;
> +
> +#ifdef _LIBCPP_DEBUG
> +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
> +#endif
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +using std::optional;
> +
> +struct X
> +{
> +    constexpr int test() const {return 3;}
> +};
> +
> +struct Y
> +{
> +    int test() const noexcept {return 2;}
> +};
> +
> +struct Z
> +{
> +    const Z* operator&() const;
> +    constexpr int test() const {return 1;}
> +};
> +
> +int main()
> +{
> +    {
> +        const std::optional<X> opt; ((void)opt);
> +        ASSERT_SAME_TYPE(decltype(opt.operator->()), X const*);
> +        // ASSERT_NOT_NOEXCEPT(opt.operator->());
> +        // FIXME: This assertion fails with GCC because it can see that
> +        // (A) operator->() is constexpr, and
> +        // (B) there is no path through the function that throws.
> +        // It's arguable if this is the correct behavior for the noexcept
> +        // operator.
> +        // Regardless this function should still be noexcept(false)
> because
> +        // it has a narrow contract.
> +    }
> +    {
> +        constexpr optional<X> opt(X{});
> +        static_assert(opt->test() == 3, "");
> +    }
> +    {
> +        constexpr optional<Y> opt(Y{});
> +        assert(opt->test() == 2);
> +    }
> +    {
> +        constexpr optional<Z> opt(Z{});
> +        static_assert(opt->test() == 1, "");
> +    }
> +#ifdef _LIBCPP_DEBUG
> +    {
> +        const optional<X> opt;
> +        assert(opt->test() == 3);
> +        assert(false);
> +    }
> +#endif  // _LIBCPP_DEBUG
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.observe/
> value.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,73 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// constexpr T& optional<T>::value() &;
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +using std::optional;
> +using std::bad_optional_access;
> +
> +struct X
> +{
> +    X() = default;
> +    X(const X&) = delete;
> +    constexpr int test() const & {return 3;}
> +    int test() & {return 4;}
> +    constexpr int test() const && {return 5;}
> +    int test() && {return 6;}
> +};
> +
> +struct Y
> +{
> +    constexpr int test() & {return 7;}
> +};
> +
> +constexpr int
> +test()
> +{
> +    optional<Y> opt{Y{}};
> +    return opt.value().test();
> +}
> +
> +
> +int main()
> +{
> +    {
> +        optional<X> opt; ((void)opt);
> +        ASSERT_NOT_NOEXCEPT(opt.value());
> +        ASSERT_SAME_TYPE(decltype(opt.value()), X&);
> +    }
> +    {
> +        optional<X> opt;
> +        opt.emplace();
> +        assert(opt.value().test() == 4);
> +    }
> +#ifndef TEST_HAS_NO_EXCEPTIONS
> +    {
> +        optional<X> opt;
> +        try
> +        {
> +            opt.value();
> +            assert(false);
> +        }
> +        catch (const bad_optional_access&)
> +        {
> +        }
> +    }
> +#endif
> +    static_assert(test() == 7, "");
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value_const.fail.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.observe/
> value_const.fail.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value_const.fail.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value_const.fail.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,33 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// constexpr const T& optional<T>::value() const &;
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +using std::optional;
> +
> +struct X
> +{
> +    constexpr int test() const {return 3;}
> +    int test() {return 4;}
> +};
> +
> +int main()
> +{
> +    {
> +        constexpr optional<X> opt;
> +        static_assert(opt.value().test() == 3, "");
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value_const.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.observe/
> value_const.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value_const.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value_const.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,64 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// constexpr const T& optional<T>::value() const &;
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +using std::optional;
> +using std::in_place_t;
> +using std::in_place;
> +using std::bad_optional_access;
> +
> +struct X
> +{
> +    X() = default;
> +    X(const X&) = delete;
> +    constexpr int test() const & {return 3;}
> +    int test() & {return 4;}
> +    constexpr int test() const && {return 5;}
> +    int test() && {return 6;}
> +};
> +
> +int main()
> +{
> +    {
> +        const optional<X> opt; ((void)opt);
> +        ASSERT_NOT_NOEXCEPT(opt.value());
> +        ASSERT_SAME_TYPE(decltype(opt.value()), X const&);
> +    }
> +    {
> +        constexpr optional<X> opt(in_place);
> +        static_assert(opt.value().test() == 3, "");
> +    }
> +    {
> +        const optional<X> opt(in_place);
> +        assert(opt.value().test() == 3);
> +    }
> +#ifndef TEST_HAS_NO_EXCEPTIONS
> +    {
> +        const optional<X> opt;
> +        try
> +        {
> +            opt.value();
> +            assert(false);
> +        }
> +        catch (const bad_optional_access&)
> +        {
> +        }
> +    }
> +#endif
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value_const_rvalue.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.observe/
> value_const_rvalue.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value_const_rvalue.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value_const_rvalue.pass.cpp Wed Oct 12 02:46:20
> 2016
> @@ -0,0 +1,64 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// constexpr const T& optional<T>::value() const &&;
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +using std::optional;
> +using std::in_place_t;
> +using std::in_place;
> +using std::bad_optional_access;
> +
> +struct X
> +{
> +    X() = default;
> +    X(const X&) = delete;
> +    constexpr int test() const & {return 3;}
> +    int test() & {return 4;}
> +    constexpr int test() const && {return 5;}
> +    int test() && {return 6;}
> +};
> +
> +int main()
> +{
> +    {
> +        const optional<X> opt; ((void)opt);
> +        ASSERT_NOT_NOEXCEPT(std::move(opt).value());
> +        ASSERT_SAME_TYPE(decltype(std::move(opt).value()), X const&&);
> +    }
> +    {
> +        constexpr optional<X> opt(in_place);
> +        static_assert(std::move(opt).value().test() == 5, "");
> +    }
> +    {
> +        const optional<X> opt(in_place);
> +        assert(std::move(opt).value().test() == 5);
> +    }
> +#ifndef TEST_HAS_NO_EXCEPTIONS
> +    {
> +        const optional<X> opt;
> +        try
> +        {
> +            std::move(opt).value();
> +            assert(false);
> +        }
> +        catch (const bad_optional_access&)
> +        {
> +        }
> +    }
> +#endif
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value_or.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.observe/
> value_or.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value_or.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value_or.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,68 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class U> T optional<T>::value_or(U&& v) &&;
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +using std::optional;
> +using std::in_place_t;
> +using std::in_place;
> +
> +struct Y
> +{
> +    int i_;
> +
> +    Y(int i) : i_(i) {}
> +};
> +
> +struct X
> +{
> +    int i_;
> +
> +    X(int i) : i_(i) {}
> +    X(X&& x) : i_(x.i_) {x.i_ = 0;}
> +    X(const Y& y) : i_(y.i_) {}
> +    X(Y&& y) : i_(y.i_+1) {}
> +    friend constexpr bool operator==(const X& x, const X& y)
> +        {return x.i_ == y.i_;}
> +};
> +
> +int main()
> +{
> +    {
> +        optional<X> opt(in_place, 2);
> +        Y y(3);
> +        assert(std::move(opt).value_or(y) == 2);
> +        assert(*opt == 0);
> +    }
> +    {
> +        optional<X> opt(in_place, 2);
> +        assert(std::move(opt).value_or(Y(3)) == 2);
> +        assert(*opt == 0);
> +    }
> +    {
> +        optional<X> opt;
> +        Y y(3);
> +        assert(std::move(opt).value_or(y) == 3);
> +        assert(!opt);
> +    }
> +    {
> +        optional<X> opt;
> +        assert(std::move(opt).value_or(Y(3)) == 4);
> +        assert(!opt);
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value_or_const.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.observe/
> value_or_const.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value_or_const.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value_or_const.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,77 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class U> constexpr T optional<T>::value_or(U&& v) const&;
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +using std::optional;
> +
> +struct Y
> +{
> +    int i_;
> +
> +    constexpr Y(int i) : i_(i) {}
> +};
> +
> +struct X
> +{
> +    int i_;
> +
> +    constexpr X(int i) : i_(i) {}
> +    constexpr X(const Y& y) : i_(y.i_) {}
> +    constexpr X(Y&& y) : i_(y.i_+1) {}
> +    friend constexpr bool operator==(const X& x, const X& y)
> +        {return x.i_ == y.i_;}
> +};
> +
> +int main()
> +{
> +    {
> +        constexpr optional<X> opt(2);
> +        constexpr Y y(3);
> +        static_assert(opt.value_or(y) == 2, "");
> +    }
> +    {
> +        constexpr optional<X> opt(2);
> +        static_assert(opt.value_or(Y(3)) == 2, "");
> +    }
> +    {
> +        constexpr optional<X> opt;
> +        constexpr Y y(3);
> +        static_assert(opt.value_or(y) == 3, "");
> +    }
> +    {
> +        constexpr optional<X> opt;
> +        static_assert(opt.value_or(Y(3)) == 4, "");
> +    }
> +    {
> +        const optional<X> opt(2);
> +        const Y y(3);
> +        assert(opt.value_or(y) == 2);
> +    }
> +    {
> +        const optional<X> opt(2);
> +        assert(opt.value_or(Y(3)) == 2);
> +    }
> +    {
> +        const optional<X> opt;
> +        const Y y(3);
> +        assert(opt.value_or(y) == 3);
> +    }
> +    {
> +        const optional<X> opt;
> +        assert(opt.value_or(Y(3)) == 4);
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value_rvalue.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.observe/
> value_rvalue.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value_rvalue.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.observe/value_rvalue.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,72 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// constexpr T& optional<T>::value() &&;
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +using std::optional;
> +using std::bad_optional_access;
> +
> +struct X
> +{
> +    X() = default;
> +    X(const X&) = delete;
> +    constexpr int test() const & {return 3;}
> +    int test() & {return 4;}
> +    constexpr int test() const && {return 5;}
> +    int test() && {return 6;}
> +};
> +
> +struct Y
> +{
> +    constexpr int test() && {return 7;}
> +};
> +
> +constexpr int
> +test()
> +{
> +    optional<Y> opt{Y{}};
> +    return std::move(opt).value().test();
> +}
> +
> +int main()
> +{
> +    {
> +        optional<X> opt; ((void)opt);
> +        ASSERT_NOT_NOEXCEPT(std::move(opt).value());
> +        ASSERT_SAME_TYPE(decltype(std::move(opt).value()), X&&);
> +    }
> +    {
> +        optional<X> opt;
> +        opt.emplace();
> +        assert(std::move(opt).value().test() == 6);
> +    }
> +#ifndef TEST_HAS_NO_EXCEPTIONS
> +    {
> +        optional<X> opt;
> +        try
> +        {
> +            std::move(opt).value();
> +            assert(false);
> +        }
> +        catch (const bad_optional_access&)
> +        {
> +        }
> +    }
> +#endif
> +    static_assert(test() == 7, "");
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.swap/swap.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional.object.swap/swap.
> pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.swap/swap.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional.object.swap/swap.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,306 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// void swap(optional&)
> +//     noexcept(is_nothrow_move_constructible<T>::value &&
> +//              is_nothrow_swappable<T>::value)
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +#include "archetypes.hpp"
> +
> +using std::optional;
> +
> +class X
> +{
> +    int i_;
> +public:
> +    static unsigned dtor_called;
> +    X(int i) : i_(i) {}
> +    X(X&& x) = default;
> +    X& operator=(X&&) = default;
> +    ~X() {++dtor_called;}
> +
> +    friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
> +};
> +
> +unsigned X::dtor_called = 0;
> +
> +class Y
> +{
> +    int i_;
> +public:
> +    static unsigned dtor_called;
> +    Y(int i) : i_(i) {}
> +    Y(Y&&) = default;
> +    ~Y() {++dtor_called;}
> +
> +    friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_
> == y.i_;}
> +    friend void swap(Y& x, Y& y) {std::swap(x.i_, y.i_);}
> +};
> +
> +unsigned Y::dtor_called = 0;
> +
> +class Z
> +{
> +    int i_;
> +public:
> +    Z(int i) : i_(i) {}
> +    Z(Z&&) {TEST_THROW(7);}
> +
> +    friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_
> == y.i_;}
> +    friend void swap(Z& x, Z& y) {TEST_THROW(6);}
> +};
> +
> +
> +int main()
> +{
> +    {
> +        optional<int> opt1;
> +        optional<int> opt2;
> +        static_assert(noexcept(opt1.swap(opt2)) == true, "");
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == false);
> +        opt1.swap(opt2);
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == false);
> +    }
> +    {
> +        optional<int> opt1(1);
> +        optional<int> opt2;
> +        static_assert(noexcept(opt1.swap(opt2)) == true, "");
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 1);
> +        assert(static_cast<bool>(opt2) == false);
> +        opt1.swap(opt2);
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 1);
> +    }
> +    {
> +        optional<int> opt1;
> +        optional<int> opt2(2);
> +        static_assert(noexcept(opt1.swap(opt2)) == true, "");
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 2);
> +        opt1.swap(opt2);
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 2);
> +        assert(static_cast<bool>(opt2) == false);
> +    }
> +    {
> +        optional<int> opt1(1);
> +        optional<int> opt2(2);
> +        static_assert(noexcept(opt1.swap(opt2)) == true, "");
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 1);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 2);
> +        opt1.swap(opt2);
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 2);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 1);
> +    }
> +    {
> +        optional<X> opt1;
> +        optional<X> opt2;
> +        static_assert(noexcept(opt1.swap(opt2)) == true, "");
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == false);
> +        opt1.swap(opt2);
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == false);
> +        assert(X::dtor_called == 0);
> +    }
> +    {
> +        optional<X> opt1(1);
> +        optional<X> opt2;
> +        static_assert(noexcept(opt1.swap(opt2)) == true, "");
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 1);
> +        assert(static_cast<bool>(opt2) == false);
> +        X::dtor_called = 0;
> +        opt1.swap(opt2);
> +        assert(X::dtor_called == 1);
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 1);
> +    }
> +    {
> +        optional<X> opt1;
> +        optional<X> opt2(2);
> +        static_assert(noexcept(opt1.swap(opt2)) == true, "");
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 2);
> +        X::dtor_called = 0;
> +        opt1.swap(opt2);
> +        assert(X::dtor_called == 1);
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 2);
> +        assert(static_cast<bool>(opt2) == false);
> +    }
> +    {
> +        optional<X> opt1(1);
> +        optional<X> opt2(2);
> +        static_assert(noexcept(opt1.swap(opt2)) == true, "");
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 1);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 2);
> +        X::dtor_called = 0;
> +        opt1.swap(opt2);
> +        assert(X::dtor_called == 1);  // from inside std::swap
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 2);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 1);
> +    }
> +    {
> +        optional<Y> opt1;
> +        optional<Y> opt2;
> +        static_assert(noexcept(opt1.swap(opt2)) == false, "");
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == false);
> +        opt1.swap(opt2);
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == false);
> +        assert(Y::dtor_called == 0);
> +    }
> +    {
> +        optional<Y> opt1(1);
> +        optional<Y> opt2;
> +        static_assert(noexcept(opt1.swap(opt2)) == false, "");
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 1);
> +        assert(static_cast<bool>(opt2) == false);
> +        Y::dtor_called = 0;
> +        opt1.swap(opt2);
> +        assert(Y::dtor_called == 1);
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 1);
> +    }
> +    {
> +        optional<Y> opt1;
> +        optional<Y> opt2(2);
> +        static_assert(noexcept(opt1.swap(opt2)) == false, "");
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 2);
> +        Y::dtor_called = 0;
> +        opt1.swap(opt2);
> +        assert(Y::dtor_called == 1);
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 2);
> +        assert(static_cast<bool>(opt2) == false);
> +    }
> +    {
> +        optional<Y> opt1(1);
> +        optional<Y> opt2(2);
> +        static_assert(noexcept(opt1.swap(opt2)) == false, "");
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 1);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 2);
> +        Y::dtor_called = 0;
> +        opt1.swap(opt2);
> +        assert(Y::dtor_called == 0);
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 2);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 1);
> +    }
> +    {
> +        optional<Z> opt1;
> +        optional<Z> opt2;
> +        static_assert(noexcept(opt1.swap(opt2)) == false, "");
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == false);
> +        opt1.swap(opt2);
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == false);
> +    }
> +#ifndef TEST_HAS_NO_EXCEPTIONS
> +    {
> +        optional<Z> opt1;
> +        opt1.emplace(1);
> +        optional<Z> opt2;
> +        static_assert(noexcept(opt1.swap(opt2)) == false, "");
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 1);
> +        assert(static_cast<bool>(opt2) == false);
> +        try
> +        {
> +            opt1.swap(opt2);
> +            assert(false);
> +        }
> +        catch (int i)
> +        {
> +            assert(i == 7);
> +        }
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 1);
> +        assert(static_cast<bool>(opt2) == false);
> +    }
> +    {
> +        optional<Z> opt1;
> +        optional<Z> opt2;
> +        opt2.emplace(2);
> +        static_assert(noexcept(opt1.swap(opt2)) == false, "");
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 2);
> +        try
> +        {
> +            opt1.swap(opt2);
> +            assert(false);
> +        }
> +        catch (int i)
> +        {
> +            assert(i == 7);
> +        }
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 2);
> +    }
> +    {
> +        optional<Z> opt1;
> +        opt1.emplace(1);
> +        optional<Z> opt2;
> +        opt2.emplace(2);
> +        static_assert(noexcept(opt1.swap(opt2)) == false, "");
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 1);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 2);
> +        try
> +        {
> +            opt1.swap(opt2);
> +            assert(false);
> +        }
> +        catch (int i)
> +        {
> +            assert(i == 6);
> +        }
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 1);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 2);
> +    }
> +#endif
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> optional_requires_destructible_object.fail.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/optional_requires_destructi
> ble_object.fail.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/
> optional_requires_destructible_object.fail.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/
> optional_requires_destructible_object.fail.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,50 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// T shall be an object type and shall satisfy the requirements of
> Destructible
> +
> +#include <optional>
> +
> +using std::optional;
> +
> +struct X
> +{
> +private:
> +    ~X() {}
> +};
> +
> +int main()
> +{
> +    using std::optional;
> +    {
> +        // expected-error at optional:* 2 {{static_assert failed
> "instantiation of optional with a reference type is ill-formed}}
> +        optional<int&> opt1;
> +        optional<int&&> opt2;
> +    }
> +    {
> +        // expected-error at optional:* {{static_assert failed
> "instantiation of optional with a non-destructible type is ill-formed"}}
> +        optional<X> opt3;
> +    }
> +    {
> +        // expected-error at optional:* {{static_assert failed
> "instantiation of optional with a non-object type is undefined behavior"}}
> +        // expected-error at optional:* {{static_assert failed
> "instantiation of optional with a non-destructible type is ill-formed}}
> +        optional<void()> opt4;
> +    }
> +    {
> +        // expected-error at optional:* {{static_assert failed
> "instantiation of optional with a non-object type is undefined behavior"}}
> +        // expected-error at optional:* {{static_assert failed
> "instantiation of optional with a non-destructible type is ill-formed}}
> +        // expected-error at optional:* 1+ {{cannot form a reference to
> 'void'}}
> +        optional<const void> opt4;
> +    }
> +    // FIXME these are garbage diagnostics that Clang should not produce
> +    // expected-error at optional:* 0+ {{is not a base class}}
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> special_member_gen.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/special_member_gen.pass.
> cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/special_member_gen.pass.cpp
> (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/special_member_gen.pass.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,74 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "archetypes.hpp"
> +
> +template <class T>
> +struct SpecialMemberTest {
> +    using O = std::optional<T>;
> +
> +    static_assert(std::is_default_constructible_v<O>,
> +        "optional is always default constructible.");
> +    static_assert(std::is_copy_constructible_v<O> ==
> std::is_copy_constructible_v<T>,
> +        "optional<T> is copy constructible if and only if T is copy
> constructible.");
> +    static_assert(std::is_move_constructible_v<O> ==
> +        (std::is_copy_constructible_v<T> ||
> std::is_move_constructible_v<T>),
> +        "optional<T> is move constructible if and only if T is copy or
> move constructible.");
> +    static_assert(std::is_copy_assignable_v<O> ==
> +        (std::is_copy_constructible_v<T> &&
> std::is_copy_assignable_v<T>),
> +        "optional<T> is copy assignable if and only if T is both copy "
> +        "constructible and copy assignable.");
> +    static_assert(std::is_move_assignable_v<O> ==
> +        ((std::is_copy_constructible_v<T> &&
> std::is_copy_assignable_v<T>) ||
> +         (std::is_move_constructible_v<T> &&
> std::is_move_assignable_v<T>)),
> +        "optional<T> is move assignable if and only if T is both move
> assignable and "
> +        "move constructible, or both copy constructible and copy
> assignable.");
> +};
> +
> +template <class ...Args> static void sink(Args&&...) {}
> +
> +template <class ...TestTypes>
> +struct DoTestsMetafunction {
> +    DoTestsMetafunction() { sink(SpecialMemberTest<TestTypes>{}...); }
> +};
> +
> +struct TrivialMoveNonTrivialCopy {
> +    TrivialMoveNonTrivialCopy() = default;
> +    TrivialMoveNonTrivialCopy(const TrivialMoveNonTrivialCopy&) {}
> +    TrivialMoveNonTrivialCopy(TrivialMoveNonTrivialCopy&&) = default;
> +    TrivialMoveNonTrivialCopy& operator=(const
> TrivialMoveNonTrivialCopy&) { return *this; }
> +    TrivialMoveNonTrivialCopy& operator=(TrivialMoveNonTrivialCopy&&) =
> default;
> +};
> +
> +struct TrivialCopyNonTrivialMove {
> +    TrivialCopyNonTrivialMove() = default;
> +    TrivialCopyNonTrivialMove(const TrivialCopyNonTrivialMove&) =
> default;
> +    TrivialCopyNonTrivialMove(TrivialCopyNonTrivialMove&&) {}
> +    TrivialCopyNonTrivialMove& operator=(const
> TrivialCopyNonTrivialMove&) = default;
> +    TrivialCopyNonTrivialMove& operator=(TrivialCopyNonTrivialMove&&) {
> return *this; }
> +};
> +
> +int main()
> +{
> +    sink(
> +        ImplicitTypes::ApplyTypes<DoTestsMetafunction>{},
> +        ExplicitTypes::ApplyTypes<DoTestsMetafunction>{},
> +        NonLiteralTypes::ApplyTypes<DoTestsMetafunction>{},
> +        NonTrivialTypes::ApplyTypes<DoTestsMetafunction>{},
> +        DoTestsMetafunction<TrivialMoveNonTrivialCopy,
> TrivialCopyNonTrivialMove>{}
> +    );
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.object/
> types.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.object/types.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.object/types.pass.cpp
> (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.object/types.pass.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,38 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class T>
> +// class optional
> +// {
> +// public:
> +//     typedef T value_type;
> +//     ...
> +
> +#include <optional>
> +#include <type_traits>
> +
> +using std::optional;
> +
> +template <class Opt, class T>
> +void
> +test()
> +{
> +    static_assert(std::is_same<typename Opt::value_type, T>::value, "");
> +}
> +
> +int main()
> +{
> +    test<optional<int>, int>();
> +    test<optional<const int>, const int>();
> +    test<optional<double>, double>();
> +    test<optional<const double>, const double>();
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.relops/
> equal.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.relops/equal.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.relops/equal.pass.cpp
> (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.relops/equal.pass.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,74 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class T> constexpr bool operator==(const optional<T>& x,
> const optional<T>& y);
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +using std::optional;
> +
> +struct X
> +{
> +    int i_;
> +
> +    constexpr X(int i) : i_(i) {}
> +};
> +
> +constexpr bool operator == ( const X &lhs, const X &rhs )
> +    { return lhs.i_ == rhs.i_ ; }
> +
> +int main()
> +{
> +    {
> +    typedef X T;
> +    typedef optional<T> O;
> +
> +    constexpr O o1;     // disengaged
> +    constexpr O o2;     // disengaged
> +    constexpr O o3{1};  // engaged
> +    constexpr O o4{2};  // engaged
> +    constexpr O o5{1};  // engaged
> +
> +    static_assert (   o1 == o1 , "" );
> +    static_assert (   o1 == o2 , "" );
> +    static_assert ( !(o1 == o3), "" );
> +    static_assert ( !(o1 == o4), "" );
> +    static_assert ( !(o1 == o5), "" );
> +
> +    static_assert (   o2 == o1 , "" );
> +    static_assert (   o2 == o2 , "" );
> +    static_assert ( !(o2 == o3), "" );
> +    static_assert ( !(o2 == o4), "" );
> +    static_assert ( !(o2 == o5), "" );
> +
> +    static_assert ( !(o3 == o1), "" );
> +    static_assert ( !(o3 == o2), "" );
> +    static_assert (   o3 == o3 , "" );
> +    static_assert ( !(o3 == o4), "" );
> +    static_assert (   o3 == o5 , "" );
> +
> +    static_assert ( !(o4 == o1), "" );
> +    static_assert ( !(o4 == o2), "" );
> +    static_assert ( !(o4 == o3), "" );
> +    static_assert (   o4 == o4 , "" );
> +    static_assert ( !(o4 == o5), "" );
> +
> +    static_assert ( !(o5 == o1), "" );
> +    static_assert ( !(o5 == o2), "" );
> +    static_assert (   o5 == o3 , "" );
> +    static_assert ( !(o5 == o4), "" );
> +    static_assert (   o5 == o5 , "" );
> +
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.relops/
> greater_equal.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.relops/greater_equal.pass.cpp?rev=
> 283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.relops/greater_equal.pass.cpp
> (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.relops/greater_equal.pass.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,70 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class T> constexpr bool operator>= (const optional<T>& x,
> const optional<T>& y);
> +
> +#include <optional>
> +
> +using std::optional;
> +
> +struct X
> +{
> +    int i_;
> +
> +    constexpr X(int i) : i_(i) {}
> +};
> +
> +constexpr bool operator >= ( const X &lhs, const X &rhs )
> +    { return lhs.i_ >= rhs.i_ ; }
> +
> +int main()
> +{
> +    {
> +    typedef optional<X> O;
> +
> +    constexpr O o1;     // disengaged
> +    constexpr O o2;     // disengaged
> +    constexpr O o3{1};  // engaged
> +    constexpr O o4{2};  // engaged
> +    constexpr O o5{1};  // engaged
> +
> +    static_assert (  (o1 >= o1), "" );
> +    static_assert (  (o1 >= o2), "" );
> +    static_assert ( !(o1 >= o3), "" );
> +    static_assert ( !(o1 >= o4), "" );
> +    static_assert ( !(o1 >= o5), "" );
> +
> +    static_assert (  (o2 >= o1), "" );
> +    static_assert (  (o2 >= o2), "" );
> +    static_assert ( !(o2 >= o3), "" );
> +    static_assert ( !(o2 >= o4), "" );
> +    static_assert ( !(o2 >= o5), "" );
> +
> +    static_assert (  (o3 >= o1), "" );
> +    static_assert (  (o3 >= o2), "" );
> +    static_assert (  (o3 >= o3), "" );
> +    static_assert ( !(o3 >= o4), "" );
> +    static_assert (  (o3 >= o5), "" );
> +
> +    static_assert (  (o4 >= o1), "" );
> +    static_assert (  (o4 >= o2), "" );
> +    static_assert (  (o4 >= o3), "" );
> +    static_assert (  (o4 >= o4), "" );
> +    static_assert (  (o4 >= o5), "" );
> +
> +    static_assert (  (o5 >= o1), "" );
> +    static_assert (  (o5 >= o2), "" );
> +    static_assert (  (o5 >= o3), "" );
> +    static_assert ( !(o5 >= o4), "" );
> +    static_assert (  (o5 >= o5), "" );
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.relops/
> greater_than.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.relops/greater_than.pass.cpp?rev=
> 283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.relops/greater_than.pass.cpp
> (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.relops/greater_than.pass.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,70 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class T> constexpr bool operator> (const optional<T>& x,
> const optional<T>& y);
> +
> +#include <optional>
> +
> +using std::optional;
> +
> +struct X
> +{
> +    int i_;
> +
> +    constexpr X(int i) : i_(i) {}
> +};
> +
> +constexpr bool operator > ( const X &lhs, const X &rhs )
> +    { return lhs.i_ > rhs.i_ ; }
> +
> +int main()
> +{
> +    {
> +    typedef optional<X> O;
> +
> +    constexpr O o1;     // disengaged
> +    constexpr O o2;     // disengaged
> +    constexpr O o3{1};  // engaged
> +    constexpr O o4{2};  // engaged
> +    constexpr O o5{1};  // engaged
> +
> +    static_assert ( !(o1 > o1), "" );
> +    static_assert ( !(o1 > o2), "" );
> +    static_assert ( !(o1 > o3), "" );
> +    static_assert ( !(o1 > o4), "" );
> +    static_assert ( !(o1 > o5), "" );
> +
> +    static_assert ( !(o2 > o1), "" );
> +    static_assert ( !(o2 > o2), "" );
> +    static_assert ( !(o2 > o3), "" );
> +    static_assert ( !(o2 > o4), "" );
> +    static_assert ( !(o2 > o5), "" );
> +
> +    static_assert (  (o3 > o1), "" );
> +    static_assert (  (o3 > o2), "" );
> +    static_assert ( !(o3 > o3), "" );
> +    static_assert ( !(o3 > o4), "" );
> +    static_assert ( !(o3 > o5), "" );
> +
> +    static_assert (  (o4 > o1), "" );
> +    static_assert (  (o4 > o2), "" );
> +    static_assert (  (o4 > o3), "" );
> +    static_assert ( !(o4 > o4), "" );
> +    static_assert (  (o4 > o5), "" );
> +
> +    static_assert (  (o5 > o1), "" );
> +    static_assert (  (o5 > o2), "" );
> +    static_assert ( !(o5 > o3), "" );
> +    static_assert ( !(o5 > o4), "" );
> +    static_assert ( !(o5 > o5), "" );
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.relops/
> less_equal.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.relops/less_equal.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.relops/less_equal.pass.cpp
> (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.relops/less_equal.pass.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,70 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class T> constexpr bool operator<= (const optional<T>& x,
> const optional<T>& y);
> +
> +#include <optional>
> +
> +using std::optional;
> +
> +struct X
> +{
> +    int i_;
> +
> +    constexpr X(int i) : i_(i) {}
> +};
> +
> +constexpr bool operator <= ( const X &lhs, const X &rhs )
> +    { return lhs.i_ <= rhs.i_ ; }
> +
> +int main()
> +{
> +    {
> +    typedef optional<X> O;
> +
> +    constexpr O o1;     // disengaged
> +    constexpr O o2;     // disengaged
> +    constexpr O o3{1};  // engaged
> +    constexpr O o4{2};  // engaged
> +    constexpr O o5{1};  // engaged
> +
> +    static_assert (  (o1 <= o1), "" );
> +    static_assert (  (o1 <= o2), "" );
> +    static_assert (  (o1 <= o3), "" );
> +    static_assert (  (o1 <= o4), "" );
> +    static_assert (  (o1 <= o5), "" );
> +
> +    static_assert (  (o2 <= o1), "" );
> +    static_assert (  (o2 <= o2), "" );
> +    static_assert (  (o2 <= o3), "" );
> +    static_assert (  (o2 <= o4), "" );
> +    static_assert (  (o2 <= o5), "" );
> +
> +    static_assert ( !(o3 <= o1), "" );
> +    static_assert ( !(o3 <= o2), "" );
> +    static_assert (  (o3 <= o3), "" );
> +    static_assert (  (o3 <= o4), "" );
> +    static_assert (  (o3 <= o5), "" );
> +
> +    static_assert ( !(o4 <= o1), "" );
> +    static_assert ( !(o4 <= o2), "" );
> +    static_assert ( !(o4 <= o3), "" );
> +    static_assert (  (o4 <= o4), "" );
> +    static_assert ( !(o4 <= o5), "" );
> +
> +    static_assert ( !(o5 <= o1), "" );
> +    static_assert ( !(o5 <= o2), "" );
> +    static_assert (  (o5 <= o3), "" );
> +    static_assert (  (o5 <= o4), "" );
> +    static_assert (  (o5 <= o5), "" );
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.relops/
> less_than.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.relops/less_than.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.relops/less_than.pass.cpp
> (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.relops/less_than.pass.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,70 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class T> constexpr bool operator< (const optional<T>& x,
> const optional<T>& y);
> +
> +#include <optional>
> +
> +using std::optional;
> +
> +struct X
> +{
> +    int i_;
> +
> +    constexpr X(int i) : i_(i) {}
> +};
> +
> +constexpr bool operator < ( const X &lhs, const X &rhs )
> +    { return lhs.i_ < rhs.i_ ; }
> +
> +int main()
> +{
> +    {
> +    typedef optional<X> O;
> +
> +    constexpr O o1;     // disengaged
> +    constexpr O o2;     // disengaged
> +    constexpr O o3{1};  // engaged
> +    constexpr O o4{2};  // engaged
> +    constexpr O o5{1};  // engaged
> +
> +    static_assert ( !(o1 < o1), "" );
> +    static_assert ( !(o1 < o2), "" );
> +    static_assert (  (o1 < o3), "" );
> +    static_assert (  (o1 < o4), "" );
> +    static_assert (  (o1 < o5), "" );
> +
> +    static_assert ( !(o2 < o1), "" );
> +    static_assert ( !(o2 < o2), "" );
> +    static_assert (  (o2 < o3), "" );
> +    static_assert (  (o2 < o4), "" );
> +    static_assert (  (o2 < o5), "" );
> +
> +    static_assert ( !(o3 < o1), "" );
> +    static_assert ( !(o3 < o2), "" );
> +    static_assert ( !(o3 < o3), "" );
> +    static_assert (  (o3 < o4), "" );
> +    static_assert ( !(o3 < o5), "" );
> +
> +    static_assert ( !(o4 < o1), "" );
> +    static_assert ( !(o4 < o2), "" );
> +    static_assert ( !(o4 < o3), "" );
> +    static_assert ( !(o4 < o4), "" );
> +    static_assert ( !(o4 < o5), "" );
> +
> +    static_assert ( !(o5 < o1), "" );
> +    static_assert ( !(o5 < o2), "" );
> +    static_assert ( !(o5 < o3), "" );
> +    static_assert (  (o5 < o4), "" );
> +    static_assert ( !(o5 < o5), "" );
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.relops/
> not_equal.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.relops/not_equal.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.relops/not_equal.pass.cpp
> (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.relops/not_equal.pass.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,74 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class T> constexpr bool operator!=(const optional<T>& x,
> const optional<T>& y);
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +using std::optional;
> +
> +struct X
> +{
> +    int i_;
> +
> +    constexpr X(int i) : i_(i) {}
> +};
> +
> +constexpr bool operator != ( const X &lhs, const X &rhs )
> +    { return lhs.i_ != rhs.i_ ; }
> +
> +int main()
> +{
> +    {
> +    typedef X T;
> +    typedef optional<T> O;
> +
> +    constexpr O o1;     // disengaged
> +    constexpr O o2;     // disengaged
> +    constexpr O o3{1};  // engaged
> +    constexpr O o4{2};  // engaged
> +    constexpr O o5{1};  // engaged
> +
> +    static_assert ( !(o1 != o1), "" );
> +    static_assert ( !(o1 != o2), "" );
> +    static_assert (  (o1 != o3), "" );
> +    static_assert (  (o1 != o4), "" );
> +    static_assert (  (o1 != o5), "" );
> +
> +    static_assert ( !(o2 != o1), "" );
> +    static_assert ( !(o2 != o2), "" );
> +    static_assert (  (o2 != o3), "" );
> +    static_assert (  (o2 != o4), "" );
> +    static_assert (  (o2 != o5), "" );
> +
> +    static_assert (  (o3 != o1), "" );
> +    static_assert (  (o3 != o2), "" );
> +    static_assert ( !(o3 != o3), "" );
> +    static_assert (  (o3 != o4), "" );
> +    static_assert ( !(o3 != o5), "" );
> +
> +    static_assert (  (o4 != o1), "" );
> +    static_assert (  (o4 != o2), "" );
> +    static_assert (  (o4 != o3), "" );
> +    static_assert ( !(o4 != o4), "" );
> +    static_assert (  (o4 != o5), "" );
> +
> +    static_assert (  (o5 != o1), "" );
> +    static_assert (  (o5 != o2), "" );
> +    static_assert ( !(o5 != o3), "" );
> +    static_assert (  (o5 != o4), "" );
> +    static_assert ( !(o5 != o5), "" );
> +
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.specalg/
> make_optional.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.specalg/make_optional.pass.cpp?
> rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.specalg/make_optional.pass.cpp
> (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.specalg/make_optional.pass.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,51 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class T>
> +//   constexpr optional<decay_t<T>> make_optional(T&& v);
> +
> +#include <optional>
> +#include <string>
> +#include <memory>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +int main()
> +{
> +    using std::optional;
> +    using std::make_optional;
> +    {
> +        int arr[10]; ((void)arr);
> +        ASSERT_SAME_TYPE(decltype(make_optional(arr)), optional<int*>);
> +    }
> +    {
> +        constexpr auto opt = make_optional(2);
> +        ASSERT_SAME_TYPE(decltype(opt), const optional<int>);
> +        static_assert(opt.value() == 2);
> +    }
> +    {
> +        optional<int> opt = make_optional(2);
> +        assert(*opt == 2);
> +    }
> +    {
> +        std::string s("123");
> +        optional<std::string> opt = make_optional(s);
> +        assert(*opt == s);
> +    }
> +    {
> +        std::unique_ptr<int> s(new int(3));
> +        optional<std::unique_ptr<int>> opt = make_optional(std::move(s));
> +        assert(**opt == 3);
> +        assert(s == nullptr);
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.specalg/
> make_optional_explicit.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.specalg/make_optional_explicit.
> pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.specalg/
> make_optional_explicit.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.specalg/
> make_optional_explicit.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,45 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class T, class... Args>
> +//   constexpr optional<T> make_optional(Args&&... args);
> +
> +#include <optional>
> +#include <string>
> +#include <memory>
> +#include <cassert>
> +
> +int main()
> +{
> +    using std::optional;
> +    using std::make_optional;
> +
> +    {
> +        constexpr auto opt = make_optional<int>('a');
> +        static_assert(*opt == int('a'), "");
> +    }
> +    {
> +        std::string s("123");
> +        auto opt = make_optional<std::string>(s);
> +        assert(*opt == s);
> +    }
> +    {
> +        std::unique_ptr<int> s(new int(3));
> +        auto opt = make_optional<std::unique_ptr<int>>(std::move(s));
> +        assert(**opt == 3);
> +        assert(s == nullptr);
> +    }
> +    {
> +        auto opt = make_optional<std::string>(4, 'X');
> +        assert(*opt == "XXXX");
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.specalg/
> make_optional_explicit_initializer_list.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.specalg/make_optional_explicit_
> initializer_list.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.specalg/
> make_optional_explicit_initializer_list.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.specalg/
> make_optional_explicit_initializer_list.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,53 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class T, class U, class... Args>
> +//   constexpr optional<T> make_optional(initializer_list<U> il,
> Args&&... args);
> +
> +#include <optional>
> +#include <string>
> +#include <memory>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +struct TestT {
> +  int x;
> +  int size;
> +  constexpr TestT(std::initializer_list<int> il) : x(*il.begin()),
> size(il.size()) {}
> +  constexpr TestT(std::initializer_list<int> il, const int*)
> +      : x(*il.begin()), size(il.size()) {}
> +};
> +
> +int main()
> +{
> +    using std::make_optional;
> +    {
> +        constexpr auto opt = make_optional<TestT>({42, 2, 3});
> +        ASSERT_SAME_TYPE(decltype(opt), const std::optional<TestT>);
> +        static_assert(opt->x == 42, "");
> +        static_assert(opt->size == 3, "");
> +    }
> +    {
> +        constexpr auto opt = make_optional<TestT>({42, 2, 3}, nullptr);
> +        static_assert(opt->x == 42, "");
> +        static_assert(opt->size == 3, "");
> +    }
> +    {
> +        auto opt = make_optional<std::string>({'1', '2', '3'});
> +        assert(*opt == "123");
> +    }
> +    {
> +        auto opt = make_optional<std::string>({'a', 'b', 'c'},
> std::allocator<char>{});
> +        assert(*opt == "abc");
> +    }
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.specalg/
> swap.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.specalg/swap.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.specalg/swap.pass.cpp
> (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.specalg/swap.pass.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,352 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// template <class T> void swap(optional<T>& x, optional<T>& y)
> +//     noexcept(noexcept(x.swap(y)));
> +
> +#include <optional>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +#include "archetypes.hpp"
> +
> +using std::optional;
> +
> +class X
> +{
> +    int i_;
> +public:
> +    static unsigned dtor_called;
> +    X(int i) : i_(i) {}
> +    X(X&& x) = default;
> +    X& operator=(X&&) = default;
> +    ~X() {++dtor_called;}
> +
> +    friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
> +};
> +
> +unsigned X::dtor_called = 0;
> +
> +class Y
> +{
> +    int i_;
> +public:
> +    static unsigned dtor_called;
> +    Y(int i) : i_(i) {}
> +    Y(Y&&) = default;
> +    ~Y() {++dtor_called;}
> +
> +    friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_
> == y.i_;}
> +    friend void swap(Y& x, Y& y) {std::swap(x.i_, y.i_);}
> +};
> +
> +unsigned Y::dtor_called = 0;
> +
> +class Z
> +{
> +    int i_;
> +public:
> +    Z(int i) : i_(i) {}
> +    Z(Z&&) { TEST_THROW(7);}
> +
> +    friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_
> == y.i_;}
> +    friend void swap(Z& x, Z& y) { TEST_THROW(6);}
> +};
> +
> +
> +struct NonSwappable {
> +    NonSwappable(NonSwappable const&) = delete;
> +};
> +void swap(NonSwappable&, NonSwappable&) = delete;
> +
> +void test_swap_sfinae() {
> +    using std::optional;
> +    {
> +        using T = TestTypes::TestType;
> +        static_assert(std::is_swappable_v<optional<T>>, "");
> +    }
> +    {
> +        using T = TestTypes::MoveOnly;
> +        static_assert(std::is_swappable_v<optional<T>>, "");
> +    }
> +    {
> +        using T = TestTypes::Copyable;
> +        static_assert(std::is_swappable_v<optional<T>>, "");
> +    }
> +    {
> +        using T = TestTypes::NoCtors;
> +        static_assert(!std::is_swappable_v<optional<T>>, "");
> +    }
> +    {
> +        using T = NonSwappable;
> +        static_assert(!std::is_swappable_v<optional<T>>, "");
> +    }
> +    {
> +        // Even thought CopyOnly has deleted move operations, those
> operations
> +        // cause optional<CopyOnly> to have implicitly deleted move
> operations
> +        // that decay into copies.
> +        using T = TestTypes::CopyOnly;
> +        using Opt = optional<T>;
> +        T::reset();
> +        Opt L(101), R(42);
> +        T::reset_constructors();
> +        std::swap(L, R);
> +        assert(L->value == 42);
> +        assert(R->value == 101);
> +        assert(T::copy_constructed == 1);
> +        assert(T::constructed == T::copy_constructed);
> +        assert(T::assigned == 2);
> +        assert(T::assigned == T::copy_assigned);
> +    }
> +}
> +
> +int main()
> +{
> +    test_swap_sfinae();
> +    {
> +        optional<int> opt1;
> +        optional<int> opt2;
> +        static_assert(noexcept(swap(opt1, opt2)) == true, "");
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == false);
> +        swap(opt1, opt2);
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == false);
> +    }
> +    {
> +        optional<int> opt1(1);
> +        optional<int> opt2;
> +        static_assert(noexcept(swap(opt1, opt2)) == true, "");
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 1);
> +        assert(static_cast<bool>(opt2) == false);
> +        swap(opt1, opt2);
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 1);
> +    }
> +    {
> +        optional<int> opt1;
> +        optional<int> opt2(2);
> +        static_assert(noexcept(swap(opt1, opt2)) == true, "");
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 2);
> +        swap(opt1, opt2);
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 2);
> +        assert(static_cast<bool>(opt2) == false);
> +    }
> +    {
> +        optional<int> opt1(1);
> +        optional<int> opt2(2);
> +        static_assert(noexcept(swap(opt1, opt2)) == true, "");
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 1);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 2);
> +        swap(opt1, opt2);
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 2);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 1);
> +    }
> +    {
> +        optional<X> opt1;
> +        optional<X> opt2;
> +        static_assert(noexcept(swap(opt1, opt2)) == true, "");
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == false);
> +        swap(opt1, opt2);
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == false);
> +        assert(X::dtor_called == 0);
> +    }
> +    {
> +        optional<X> opt1(1);
> +        optional<X> opt2;
> +        static_assert(noexcept(swap(opt1, opt2)) == true, "");
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 1);
> +        assert(static_cast<bool>(opt2) == false);
> +        X::dtor_called = 0;
> +        swap(opt1, opt2);
> +        assert(X::dtor_called == 1);
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 1);
> +    }
> +    {
> +        optional<X> opt1;
> +        optional<X> opt2(2);
> +        static_assert(noexcept(swap(opt1, opt2)) == true, "");
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 2);
> +        X::dtor_called = 0;
> +        swap(opt1, opt2);
> +        assert(X::dtor_called == 1);
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 2);
> +        assert(static_cast<bool>(opt2) == false);
> +    }
> +    {
> +        optional<X> opt1(1);
> +        optional<X> opt2(2);
> +        static_assert(noexcept(swap(opt1, opt2)) == true, "");
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 1);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 2);
> +        X::dtor_called = 0;
> +        swap(opt1, opt2);
> +        assert(X::dtor_called == 1);  // from inside std::swap
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 2);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 1);
> +    }
> +    {
> +        optional<Y> opt1;
> +        optional<Y> opt2;
> +        static_assert(noexcept(swap(opt1, opt2)) == false, "");
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == false);
> +        swap(opt1, opt2);
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == false);
> +        assert(Y::dtor_called == 0);
> +    }
> +    {
> +        optional<Y> opt1(1);
> +        optional<Y> opt2;
> +        static_assert(noexcept(swap(opt1, opt2)) == false, "");
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 1);
> +        assert(static_cast<bool>(opt2) == false);
> +        Y::dtor_called = 0;
> +        swap(opt1, opt2);
> +        assert(Y::dtor_called == 1);
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 1);
> +    }
> +    {
> +        optional<Y> opt1;
> +        optional<Y> opt2(2);
> +        static_assert(noexcept(swap(opt1, opt2)) == false, "");
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 2);
> +        Y::dtor_called = 0;
> +        swap(opt1, opt2);
> +        assert(Y::dtor_called == 1);
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 2);
> +        assert(static_cast<bool>(opt2) == false);
> +    }
> +    {
> +        optional<Y> opt1(1);
> +        optional<Y> opt2(2);
> +        static_assert(noexcept(swap(opt1, opt2)) == false, "");
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 1);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 2);
> +        Y::dtor_called = 0;
> +        swap(opt1, opt2);
> +        assert(Y::dtor_called == 0);
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 2);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 1);
> +    }
> +    {
> +        optional<Z> opt1;
> +        optional<Z> opt2;
> +        static_assert(noexcept(swap(opt1, opt2)) == false, "");
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == false);
> +        swap(opt1, opt2);
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == false);
> +    }
> +#ifndef TEST_HAS_NO_EXCEPTIONS
> +    {
> +        optional<Z> opt1;
> +        opt1.emplace(1);
> +        optional<Z> opt2;
> +        static_assert(noexcept(swap(opt1, opt2)) == false, "");
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 1);
> +        assert(static_cast<bool>(opt2) == false);
> +        try
> +        {
> +            swap(opt1, opt2);
> +            assert(false);
> +        }
> +        catch (int i)
> +        {
> +            assert(i == 7);
> +        }
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 1);
> +        assert(static_cast<bool>(opt2) == false);
> +    }
> +    {
> +        optional<Z> opt1;
> +        optional<Z> opt2;
> +        opt2.emplace(2);
> +        static_assert(noexcept(swap(opt1, opt2)) == false, "");
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 2);
> +        try
> +        {
> +            swap(opt1, opt2);
> +            assert(false);
> +        }
> +        catch (int i)
> +        {
> +            assert(i == 7);
> +        }
> +        assert(static_cast<bool>(opt1) == false);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 2);
> +    }
> +    {
> +        optional<Z> opt1;
> +        opt1.emplace(1);
> +        optional<Z> opt2;
> +        opt2.emplace(2);
> +        static_assert(noexcept(swap(opt1, opt2)) == false, "");
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 1);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 2);
> +        try
> +        {
> +            swap(opt1, opt2);
> +            assert(false);
> +        }
> +        catch (int i)
> +        {
> +            assert(i == 6);
> +        }
> +        assert(static_cast<bool>(opt1) == true);
> +        assert(*opt1 == 1);
> +        assert(static_cast<bool>(opt2) == true);
> +        assert(*opt2 == 2);
> +    }
> +#endif // TEST_HAS_NO_EXCEPTIONS
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.syn/
> optional_in_place_t.fail.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.syn/optional_in_place_t.fail.cpp?
> rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.syn/optional_in_place_t.fail.cpp
> (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.syn/optional_in_place_t.fail.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,26 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// A program that necessitates the instantiation of template optional for
> +// (possibly cv-qualified) in_place_t is ill-formed.
> +
> +#include <optional>
> +
> +int main()
> +{
> +    using std::optional;
> +    using std::in_place_t;
> +    using std::in_place;
> +
> +    optional<in_place_t> opt; // expected-note {{requested here}}
> +    // expected-error at optional:* {{"instantiation of optional with
> in_place_t is ill-formed"}}
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.syn/
> optional_includes_initializer_list.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.syn/optional_includes_initializer_
> list.pass.cpp?rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.syn/
> optional_includes_initializer_list.pass.cpp (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.syn/
> optional_includes_initializer_list.pass.cpp Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,22 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// #include <initializer_list>
> +
> +#include <optional>
> +
> +int main()
> +{
> +    using std::optional;
> +
> +    std::initializer_list<int> list;
> +}
>
> Added: libcxx/trunk/test/std/utilities/optional/optional.syn/
> optional_nullopt_t.fail.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ut
> ilities/optional/optional.syn/optional_nullopt_t.fail.cpp?
> rev=283980&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/optional/optional.syn/optional_nullopt_t.fail.cpp
> (added)
> +++ libcxx/trunk/test/std/utilities/optional/optional.syn/optional_nullopt_t.fail.cpp
> Wed Oct 12 02:46:20 2016
> @@ -0,0 +1,29 @@
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11, c++14
> +// <optional>
> +
> +// A program that necessitates the instantiation of template optional for
> +// (possibly cv-qualified) nullopt_t is ill-formed.
> +
> +#include <optional>
> +
> +int main()
> +{
> +    using std::optional;
> +    using std::nullopt_t;
> +    using std::nullopt;
> +
> +    optional<nullopt_t> opt; // expected-note 1 {{requested here}}
> +    optional<const nullopt_t> opt1; // expected-note 1 {{requested here}}
> +    optional<nullopt_t &> opt2; // expected-note 1 {{requested here}}
> +    optional<nullopt_t &&> opt3; // expected-note 1 {{requested here}}
> +    // expected-error at optional:* 4 {{instantiation of optional with
> nullopt_t is ill-formed}}
> +}
>
> Modified: libcxx/trunk/test/support/archetypes.hpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/suppor
> t/archetypes.hpp?rev=283980&r1=283979&r2=283980&view=diff
> ============================================================
> ==================
> --- libcxx/trunk/test/support/archetypes.hpp (original)
> +++ libcxx/trunk/test/support/archetypes.hpp Wed Oct 12 02:46:20 2016
> @@ -1,10 +1,186 @@
>  #ifndef TEST_SUPPORT_ARCHETYPES_HPP
>  #define TEST_SUPPORT_ARCHETYPES_HPP
>
> +#include <type_traits>
> +#include <cassert>
> +
>  #include "test_macros.h"
>
>  #if TEST_STD_VER >= 11
>
> +namespace ArchetypeBases {
> +
> +template <bool, class T>
> +struct DepType : T {};
> +
> +struct NullBase {};
> +
> +template <class Derived, bool Explicit = false>
> +struct TestBase {
> +    static int alive;
> +    static int constructed;
> +    static int value_constructed;
> +    static int default_constructed;
> +    static int copy_constructed;
> +    static int move_constructed;
> +    static int assigned;
> +    static int value_assigned;
> +    static int copy_assigned;
> +    static int move_assigned;
> +    static int destroyed;
> +
> +    static void reset() {
> +        assert(alive == 0);
> +        alive = 0;
> +        reset_constructors();
> +    }
> +
> +    static void reset_constructors() {
> +      constructed = value_constructed = default_constructed =
> +        copy_constructed = move_constructed = 0;
> +      assigned = value_assigned = copy_assigned = move_assigned =
> destroyed = 0;
> +    }
> +
> +    TestBase() noexcept : value(0) {
> +        ++alive; ++constructed; ++default_constructed;
> +    }
> +    template <bool Dummy = true, typename std::enable_if<Dummy &&
> Explicit, bool>::type = true>
> +    explicit TestBase(int x) noexcept : value(x) {
> +        ++alive; ++constructed; ++value_constructed;
> +    }
> +    template <bool Dummy = true, typename std::enable_if<Dummy &&
> !Explicit, bool>::type = true>
> +    TestBase(int x) noexcept : value(x) {
> +        ++alive; ++constructed; ++value_constructed;
> +    }
> +    template <bool Dummy = true, typename std::enable_if<Dummy &&
> Explicit, bool>::type = true>
> +    explicit TestBase(int x, int y) noexcept : value(y) {
> +        ++alive; ++constructed; ++value_constructed;
> +    }
> +    template <bool Dummy = true, typename std::enable_if<Dummy &&
> !Explicit, bool>::type = true>
> +    TestBase(int x, int y) noexcept : value(y) {
> +        ++alive; ++constructed; ++value_constructed;
> +    }
> +    template <bool Dummy = true, typename std::enable_if<Dummy &&
> Explicit, bool>::type = true>
> +    explicit TestBase(std::initializer_list<int>& il, int y = 0) noexcept
> +      : value(il.size()) {
> +        ++alive; ++constructed; ++value_constructed;
> +    }
> +    template <bool Dummy = true, typename std::enable_if<Dummy &&
> !Explicit, bool>::type = true>
> +    TestBase(std::initializer_list<int>& il, int y = 0) noexcept :
> value(il.size()) {
> +        ++alive; ++constructed; ++value_constructed;
> +    }
> +    TestBase& operator=(int xvalue) noexcept {
> +      value = xvalue;
> +      ++assigned; ++value_assigned;
> +      return *this;
> +    }
> +protected:
> +    ~TestBase() {
> +      assert(value != -999); assert(alive > 0);
> +      --alive; ++destroyed; value = -999;
> +    }
> +    TestBase(TestBase const& o) noexcept : value(o.value) {
> +        assert(o.value != -1); assert(o.value != -999);
> +        ++alive; ++constructed; ++copy_constructed;
> +    }
> +    TestBase(TestBase && o) noexcept : value(o.value) {
> +        assert(o.value != -1); assert(o.value != -999);
> +        ++alive; ++constructed; ++move_constructed;
> +        o.value = -1;
> +    }
> +    TestBase& operator=(TestBase const& o) noexcept {
> +      assert(o.value != -1); assert(o.value != -999);
> +      ++assigned; ++copy_assigned;
> +      value = o.value;
> +      return *this;
> +    }
> +    TestBase& operator=(TestBase&& o) noexcept {
> +        assert(o.value != -1); assert(o.value != -999);
> +        ++assigned; ++move_assigned;
> +        value = o.value;
> +        o.value = -1;
> +        return *this;
> +    }
> +public:
> +    int value;
> +};
> +
> +template <class D, bool E> int TestBase<D, E>::alive = 0;
> +template <class D, bool E> int TestBase<D, E>::constructed = 0;
> +template <class D, bool E> int TestBase<D, E>::value_constructed = 0;
> +template <class D, bool E> int TestBase<D, E>::default_constructed = 0;
> +template <class D, bool E> int TestBase<D, E>::copy_constructed = 0;
> +template <class D, bool E> int TestBase<D, E>::move_constructed = 0;
> +template <class D, bool E> int TestBase<D, E>::assigned = 0;
> +template <class D, bool E> int TestBase<D, E>::value_assigned = 0;
> +template <class D, bool E> int TestBase<D, E>::copy_assigned = 0;
> +template <class D, bool E> int TestBase<D, E>::move_assigned = 0;
> +template <class D, bool E> int TestBase<D, E>::destroyed = 0;
> +
> +template <bool Explicit = false>
> +struct ValueBase {
> +    template <bool Dummy = true, typename std::enable_if<Dummy &&
> Explicit, bool>::type = true>
> +    explicit constexpr ValueBase(int x) : value(x) {}
> +    template <bool Dummy = true, typename std::enable_if<Dummy &&
> !Explicit, bool>::type = true>
> +    constexpr ValueBase(int x) : value(x) {}
> +    template <bool Dummy = true, typename std::enable_if<Dummy &&
> Explicit, bool>::type = true>
> +    explicit constexpr ValueBase(int x, int y) : value(y) {}
> +    template <bool Dummy = true, typename std::enable_if<Dummy &&
> !Explicit, bool>::type = true>
> +    constexpr ValueBase(int x, int y) : value(y) {}
> +    template <bool Dummy = true, typename std::enable_if<Dummy &&
> Explicit, bool>::type = true>
> +    explicit constexpr ValueBase(std::initializer_list<int>& il, int y =
> 0) : value(il.size()) {}
> +    template <bool Dummy = true, typename std::enable_if<Dummy &&
> !Explicit, bool>::type = true>
> +    constexpr ValueBase(std::initializer_list<int>& il, int y = 0) :
> value(il.size()) {}
> +    constexpr ValueBase& operator=(int xvalue) noexcept {
> +        value = xvalue;
> +        return *this;
> +    }
> +    //~ValueBase() { assert(value != -999); value = -999; }
> +    int value;
> +protected:
> +  constexpr ValueBase() noexcept : value(0) {}
> +    constexpr ValueBase(ValueBase const& o) noexcept : value(o.value) {
> +        assert(o.value != -1); assert(o.value != -999);
> +    }
> +    constexpr ValueBase(ValueBase && o) noexcept : value(o.value) {
> +        assert(o.value != -1); assert(o.value != -999);
> +        o.value = -1;
> +    }
> +    constexpr ValueBase& operator=(ValueBase const& o) noexcept {
> +        assert(o.value != -1); assert(o.value != -999);
> +        value = o.value;
> +        return *this;
> +    }
> +    constexpr ValueBase& operator=(ValueBase&& o) noexcept {
> +        assert(o.value != -1); assert(o.value != -999);
> +        value = o.value;
> +        o.value = -1;
> +        return *this;
> +    }
> +};
> +
> +
> +template <bool Explicit = false>
> +struct TrivialValueBase {
> +    template <bool Dummy = true, typename std::enable_if<Dummy &&
> Explicit, bool>::type = true>
> +    explicit constexpr TrivialValueBase(int x) : value(x) {}
> +    template <bool Dummy = true, typename std::enable_if<Dummy &&
> !Explicit, bool>::type = true>
> +    constexpr TrivialValueBase(int x) : value(x) {}
> +    template <bool Dummy = true, typename std::enable_if<Dummy &&
> Explicit, bool>::type = true>
> +    explicit constexpr TrivialValueBase(int x, int y) : value(y) {}
> +    template <bool Dummy = true, typename std::enable_if<Dummy &&
> !Explicit, bool>::type = true>
> +    constexpr TrivialValueBase(int x, int y) : value(y) {}
> +    template <bool Dummy = true, typename std::enable_if<Dummy &&
> Explicit, bool>::type = true>
> +    explicit constexpr TrivialValueBase(std::initializer_list<int>& il,
> int y = 0) : value(il.size()) {}
> +    template <bool Dummy = true, typename std::enable_if<Dummy &&
> !Explicit, bool>::type = true>
> +    constexpr TrivialValueBase(std::initializer_list<int>& il, int y =
> 0) : value(il.size()) {};
> +    int value;
> +protected:
> +    constexpr TrivialValueBase() noexcept : value(0) {}
> +};
> +
> +}
> +
>  //=========================================================
> ===================//
>  // Trivial Implicit Test Types
>  namespace ImplicitTypes {
> @@ -18,9 +194,18 @@ namespace ExplicitTypes {
>  #include "archetypes.ipp"
>  }
>
> +
> +//=========================================================
> ===================//
> +//
> +namespace NonConstexprTypes {
> +#define DEFINE_CONSTEXPR
> +#include "archetypes.ipp"
> +}
> +
>  //=========================================================
> ===================//
> -// Non-Trivial Implicit Test Types
> +// Non-literal implicit test types
>  namespace NonLiteralTypes {
> +#define DEFINE_ASSIGN_CONSTEXPR
>  #define DEFINE_DTOR(Name) ~Name() {}
>  #include "archetypes.ipp"
>  }
> @@ -29,9 +214,144 @@ namespace NonLiteralTypes {
>  // Non-Trivially Copyable Implicit Test Types
>  namespace NonTrivialTypes {
>  #define DEFINE_CTOR {}
> +#define DEFINE_ASSIGN { return *this; }
> +#define DEFINE_DEFAULT_CTOR = default
> +#include "archetypes.ipp"
> +}
> +
> +//=========================================================
> ===================//
> +// Implicit counting types
> +namespace TestTypes {
> +#define DEFINE_CONSTEXPR
> +#define DEFINE_BASE(Name) ::ArchetypeBases::TestBase<Name>
> +#include "archetypes.ipp"
> +
> +using TestType = AllCtors;
> +
> +// Add equality operators
> +template <class Tp>
> +constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
> +  return L.value == R.value;
> +}
> +
> +template <class Tp>
> +constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
> +  return L.value != R.value;
> +}
> +
> +}
> +
> +//=========================================================
> ===================//
> +// Implicit counting types
> +namespace ExplicitTestTypes {
> +#define DEFINE_CONSTEXPR
> +#define DEFINE_EXPLICIT explicit
> +#define DEFINE_BASE(Name) ::ArchetypeBases::TestBase<Name, true>
> +#include "archetypes.ipp"
> +
> +using TestType = AllCtors;
> +
> +// Add equality operators
> +template <class Tp>
> +constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
> +  return L.value == R.value;
> +}
> +
> +template <class Tp>
> +constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
> +  return L.value != R.value;
> +}
> +
> +}
> +
> +//=========================================================
> ===================//
> +// Implicit value types
> +namespace ConstexprTestTypes {
> +#define DEFINE_BASE(Name) ::ArchetypeBases::ValueBase<>
> +#include "archetypes.ipp"
> +
> +using TestType = AllCtors;
> +
> +// Add equality operators
> +template <class Tp>
> +constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
> +  return L.value == R.value;
> +}
> +
> +template <class Tp>
> +constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
> +  return L.value != R.value;
> +}
> +
> +} // end namespace ValueTypes
> +
> +
> +//=========================================================
> ===================//
> +//
> +namespace ExplicitConstexprTestTypes {
> +#define DEFINE_EXPLICIT explicit
> +#define DEFINE_BASE(Name) ::ArchetypeBases::ValueBase<true>
> +#include "archetypes.ipp"
> +
> +using TestType = AllCtors;
> +
> +// Add equality operators
> +template <class Tp>
> +constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
> +  return L.value == R.value;
> +}
> +
> +template <class Tp>
> +constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
> +  return L.value != R.value;
> +}
> +
> +} // end namespace ValueTypes
> +
> +
> +//=========================================================
> ===================//
> +//
> +namespace TrivialTestTypes {
> +#define DEFINE_BASE(Name) ::ArchetypeBases::TrivialValueBase<false>
> +#include "archetypes.ipp"
> +
> +using TestType = AllCtors;
> +
> +// Add equality operators
> +template <class Tp>
> +constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
> +  return L.value == R.value;
> +}
> +
> +template <class Tp>
> +constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
> +  return L.value != R.value;
> +}
> +
> +} // end namespace TrivialValueTypes
> +
> +//=========================================================
> ===================//
> +//
> +namespace ExplicitTrivialTestTypes {
> +#define DEFINE_EXPLICIT explicit
> +#define DEFINE_BASE(Name) ::ArchetypeBases::TrivialValueBase<true>
>  #include "archetypes.ipp"
> +
> +using TestType = AllCtors;
> +
> +// Add equality operators
> +template <class Tp>
> +constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
> +  return L.value == R.value;
>  }
>
> +template <class Tp>
> +constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
> +  return L.value != R.value;
> +}
> +
> +} // end namespace ExplicitTrivialTestTypes
> +
>  #endif // TEST_STD_VER >= 11
>
>  #endif // TEST_SUPPORT_ARCHETYPES_HPP
>
> Modified: libcxx/trunk/test/support/archetypes.ipp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/suppor
> t/archetypes.ipp?rev=283980&r1=283979&r2=283980&view=diff
> ============================================================
> ==================
> --- libcxx/trunk/test/support/archetypes.ipp (original)
> +++ libcxx/trunk/test/support/archetypes.ipp Wed Oct 12 02:46:20 2016
> @@ -1,10 +1,22 @@
>
> +#ifndef DEFINE_BASE
> +#define DEFINE_BASE(Name) ::ArchetypeBases::NullBase
> +#endif
>  #ifndef DEFINE_EXPLICIT
>  #define DEFINE_EXPLICIT
>  #endif
> +#ifndef DEFINE_CONSTEXPR
> +#define DEFINE_CONSTEXPR constexpr
> +#endif
> +#ifndef DEFINE_ASSIGN_CONSTEXPR
> +#define DEFINE_ASSIGN_CONSTEXPR DEFINE_CONSTEXPR
> +#endif
>  #ifndef DEFINE_CTOR
>  #define DEFINE_CTOR = default
>  #endif
> +#ifndef DEFINE_DEFAULT_CTOR
> +#define DEFINE_DEFAULT_CTOR DEFINE_CTOR
> +#endif
>  #ifndef DEFINE_ASSIGN
>  #define DEFINE_ASSIGN = default
>  #endif
> @@ -12,78 +24,117 @@
>  #define DEFINE_DTOR(Name)
>  #endif
>
> -struct NoDefault {
> -  DEFINE_EXPLICIT NoDefault() = delete;
> +struct AllCtors : DEFINE_BASE(AllCtors) {
> +  using Base = DEFINE_BASE(AllCtors);
> +  using Base::Base;
> +  using Base::operator=;
> +  DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors() DEFINE_DEFAULT_CTOR;
> +  DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors const&) DEFINE_CTOR;
> +  DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors &&) DEFINE_CTOR;
> +  DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors const&)
> DEFINE_ASSIGN;
> +  DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors &&) DEFINE_ASSIGN;
> +  DEFINE_DTOR(AllCtors)
> +};
> +
> +struct NoCtors : DEFINE_BASE(NoCtors) {
> +  using Base = DEFINE_BASE(NoCtors);
> +  using Base::Base;
> +  DEFINE_EXPLICIT NoCtors() = delete;
> +  DEFINE_EXPLICIT NoCtors(NoCtors const&) = delete;
> +  NoCtors& operator=(NoCtors const&) = delete;
> +  DEFINE_DTOR(NoCtors)
> +};
> +
> +struct NoDefault : DEFINE_BASE(NoDefault) {
> +  using Base = DEFINE_BASE(NoDefault);
> +  using Base::Base;
> +  DEFINE_EXPLICIT DEFINE_CONSTEXPR NoDefault() = delete;
>    DEFINE_DTOR(NoDefault)
>  };
>
> -struct AllCtors {
> -  DEFINE_EXPLICIT AllCtors() DEFINE_CTOR;
> -  DEFINE_EXPLICIT AllCtors(AllCtors const&) DEFINE_CTOR;
> -  DEFINE_EXPLICIT AllCtors(AllCtors &&) DEFINE_CTOR;
> -  AllCtors& operator=(AllCtors const&) DEFINE_ASSIGN;
> -  AllCtors& operator=(AllCtors &&) DEFINE_ASSIGN;
> -  DEFINE_DTOR(AllCtors)
> +struct DefaultOnly : DEFINE_BASE(DefaultOnly) {
> +  using Base = DEFINE_BASE(DefaultOnly);
> +  using Base::Base;
> +  DEFINE_EXPLICIT DEFINE_CONSTEXPR DefaultOnly() DEFINE_DEFAULT_CTOR;
> +  DefaultOnly(DefaultOnly const&) = delete;
> +  DefaultOnly& operator=(DefaultOnly const&) = delete;
> +  DEFINE_DTOR(DefaultOnly)
>  };
>
> -struct Copyable {
> -  DEFINE_EXPLICIT Copyable() DEFINE_CTOR;
> -  DEFINE_EXPLICIT Copyable(Copyable const &) DEFINE_CTOR;
> +struct Copyable : DEFINE_BASE(Copyable) {
> +  using Base = DEFINE_BASE(Copyable);
> +  using Base::Base;
> +  DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable() DEFINE_DEFAULT_CTOR;
> +  DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable(Copyable const &) DEFINE_CTOR;
>    Copyable &operator=(Copyable const &) DEFINE_ASSIGN;
>    DEFINE_DTOR(Copyable)
>  };
>
> -struct CopyOnly {
> -  DEFINE_EXPLICIT CopyOnly() DEFINE_CTOR;
> -  DEFINE_EXPLICIT CopyOnly(CopyOnly const &) DEFINE_CTOR;
> -  DEFINE_EXPLICIT CopyOnly(CopyOnly &&) = delete;
> +struct CopyOnly : DEFINE_BASE(CopyOnly) {
> +  using Base = DEFINE_BASE(CopyOnly);
> +  using Base::Base;
> +  DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly() DEFINE_DEFAULT_CTOR;
> +  DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly const &) DEFINE_CTOR;
> +  DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly &&) = delete;
>    CopyOnly &operator=(CopyOnly const &) DEFINE_ASSIGN;
>    CopyOnly &operator=(CopyOnly &&) = delete;
>    DEFINE_DTOR(CopyOnly)
>  };
>
> -struct NonCopyable {
> -  DEFINE_EXPLICIT NonCopyable() DEFINE_CTOR;
> -  DEFINE_EXPLICIT NonCopyable(NonCopyable const &) = delete;
> +struct NonCopyable : DEFINE_BASE(NonCopyable) {
> +  using Base = DEFINE_BASE(NonCopyable);
> +  using Base::Base;
> +  DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable() DEFINE_DEFAULT_CTOR;
> +  DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable(NonCopyable const &) =
> delete;
>    NonCopyable &operator=(NonCopyable const &) = delete;
>    DEFINE_DTOR(NonCopyable)
>  };
>
> -struct MoveOnly {
> -  DEFINE_EXPLICIT MoveOnly() DEFINE_CTOR;
> -  DEFINE_EXPLICIT MoveOnly(MoveOnly &&) DEFINE_CTOR;
> +struct MoveOnly : DEFINE_BASE(MoveOnly) {
> +  using Base = DEFINE_BASE(MoveOnly);
> +  using Base::Base;
> +  DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly() DEFINE_DEFAULT_CTOR;
> +  DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly(MoveOnly &&) DEFINE_CTOR;
>    MoveOnly &operator=(MoveOnly &&) DEFINE_ASSIGN;
>    DEFINE_DTOR(MoveOnly)
>  };
>
> -struct CopyAssignable {
> -    DEFINE_EXPLICIT CopyAssignable() = delete;
> -    CopyAssignable& operator=(CopyAssignable const&) DEFINE_ASSIGN;
> -    DEFINE_DTOR(CopyAssignable)
> -};
> -
> -struct CopyAssignOnly {
> -    DEFINE_EXPLICIT CopyAssignOnly() = delete;
> -    CopyAssignOnly& operator=(CopyAssignOnly const&) DEFINE_ASSIGN;
> -    CopyAssignOnly& operator=(CopyAssignOnly &&) = delete;
> -    DEFINE_DTOR(CopyAssignOnly)
> -};
> -
> -struct MoveAssignOnly {
> -    DEFINE_EXPLICIT MoveAssignOnly() = delete;
> -    MoveAssignOnly& operator=(MoveAssignOnly const&) = delete;
> -    MoveAssignOnly& operator=(MoveAssignOnly &&) DEFINE_ASSIGN;
> -    DEFINE_DTOR(MoveAssignOnly)
> -};
> -
> -struct ConvertingType {
> -  DEFINE_EXPLICIT ConvertingType() DEFINE_CTOR;
> -  DEFINE_EXPLICIT ConvertingType(ConvertingType const&) DEFINE_CTOR;
> -  DEFINE_EXPLICIT ConvertingType(ConvertingType &&) DEFINE_CTOR;
> +struct CopyAssignable : DEFINE_BASE(CopyAssignable) {
> +  using Base = DEFINE_BASE(CopyAssignable);
> +  using Base::Base;
> +  DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyAssignable() = delete;
> +  CopyAssignable& operator=(CopyAssignable const&) DEFINE_ASSIGN;
> +  DEFINE_DTOR(CopyAssignable)
> +};
> +
> +struct CopyAssignOnly : DEFINE_BASE(CopyAssignOnly) {
> +  using Base = DEFINE_BASE(CopyAssignOnly);
> +  using Base::Base;
> +  DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyAssignOnly() = delete;
> +  CopyAssignOnly& operator=(CopyAssignOnly const&) DEFINE_ASSIGN;
> +  CopyAssignOnly& operator=(CopyAssignOnly &&) = delete;
> +  DEFINE_DTOR(CopyAssignOnly)
> +};
> +
> +struct MoveAssignOnly : DEFINE_BASE(MoveAssignOnly) {
> +  using Base = DEFINE_BASE(MoveAssignOnly);
> +  using Base::Base;
> +  DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveAssignOnly() = delete;
> +  MoveAssignOnly& operator=(MoveAssignOnly const&) = delete;
> +  MoveAssignOnly& operator=(MoveAssignOnly &&) DEFINE_ASSIGN;
> +  DEFINE_DTOR(MoveAssignOnly)
> +};
> +
> +struct ConvertingType : DEFINE_BASE(ConvertingType) {
> +  using Base = DEFINE_BASE(ConvertingType);
> +  using Base::Base;
> +  DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType() DEFINE_DEFAULT_CTOR;
> +  DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType const&)
> DEFINE_CTOR;
> +  DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType &&)
> DEFINE_CTOR;
>    ConvertingType& operator=(ConvertingType const&) DEFINE_ASSIGN;
>    ConvertingType& operator=(ConvertingType &&) DEFINE_ASSIGN;
>    template <class ...Args>
> -  DEFINE_EXPLICIT ConvertingType(Args&&...) {}
> +  DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(Args&&...) {}
>    template <class Arg>
>    ConvertingType& operator=(Arg&&) { return *this; }
>    DEFINE_DTOR(ConvertingType)
> @@ -91,8 +142,10 @@ struct ConvertingType {
>
>  template <template <class...> class List>
>  using ApplyTypes = List<
> -    NoDefault,
>      AllCtors,
> +    NoCtors,
> +    NoDefault,
> +    DefaultOnly,
>      Copyable,
>      CopyOnly,
>      NonCopyable,
> @@ -103,7 +156,11 @@ using ApplyTypes = List<
>      ConvertingType
>    >;
>
> +#undef DEFINE_BASE
>  #undef DEFINE_EXPLICIT
> +#undef DEFINE_CONSTEXPR
> +#undef DEFINE_ASSIGN_CONSTEXPR
>  #undef DEFINE_CTOR
> +#undef DEFINE_DEFAULT_CTOR
>  #undef DEFINE_ASSIGN
>  #undef DEFINE_DTOR
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20161012/658c90a3/attachment-0001.html>


More information about the cfe-commits mailing list