[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