Index: .gitignore =================================================================== --- .gitignore +++ .gitignore @@ -52,3 +52,6 @@ # PyBuilder target/ + +# Editor by-products +.vscode/ Index: include/experimental/optional =================================================================== --- include/experimental/optional +++ include/experimental/optional @@ -8,8 +8,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP_OPTIONAL -#define _LIBCPP_OPTIONAL +#ifndef _LIBCPP_EXP_OPTIONAL +#define _LIBCPP_EXP_OPTIONAL /* optional synopsis @@ -899,4 +899,4 @@ #endif // _LIBCPP_STD_VER > 11 -#endif // _LIBCPP_OPTIONAL +#endif // _LIBCPP_EXP_OPTIONAL Index: include/optional =================================================================== --- /dev/null +++ include/optional @@ -0,0 +1,1204 @@ +// -*- 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 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 + constexpr bool operator==(const optional&, const optional&); + template + constexpr bool operator!=(const optional&, const optional&); + template + constexpr bool operator<(const optional&, const optional&); + template + constexpr bool operator>(const optional&, const optional&); + template + constexpr bool operator<=(const optional&, const optional&); + template + constexpr bool operator>=(const optional&, const optional&); + template constexpr bool operator==(const optional&, nullopt_t) noexcept; + template constexpr bool operator==(nullopt_t, const optional&) noexcept; + template constexpr bool operator!=(const optional&, nullopt_t) noexcept; + template constexpr bool operator!=(nullopt_t, const optional&) noexcept; + template constexpr bool operator<(const optional&, nullopt_t) noexcept; + template constexpr bool operator<(nullopt_t, const optional&) noexcept; + template constexpr bool operator<=(const optional&, nullopt_t) noexcept; + template constexpr bool operator<=(nullopt_t, const optional&) noexcept; + template constexpr bool operator>(const optional&, nullopt_t) noexcept; + template constexpr bool operator>(nullopt_t, const optional&) noexcept; + template constexpr bool operator>=(const optional&, nullopt_t) noexcept; + template constexpr bool operator>=(nullopt_t, const optional&) noexcept; + + // 20.6.8, comparison with T + template constexpr bool operator==(const optional&, const T&); + template constexpr bool operator==(const T&, const optional&); + template constexpr bool operator!=(const optional&, const T&); + template constexpr bool operator!=(const T&, const optional&); + template constexpr bool operator<(const optional&, const T&); + template constexpr bool operator<(const T&, const optional&); + template constexpr bool operator<=(const optional&, const T&); + template constexpr bool operator<=(const T&, const optional&); + template constexpr bool operator>(const optional&, const T&); + template constexpr bool operator>(const T&, const optional&); + template constexpr bool operator>=(const optional&, const T&); + template constexpr bool operator>=(const T&, const optional&); + + // 20.6.9, specialized algorithms + template void swap(optional&, optional&) noexcept(see below ); + template constexpr optional make_optional(T&&); + template + constexpr optional make_optional(Args&&... args); + template + constexpr optional make_optional(initializer_list il, Args&&... args); + + // 20.6.10, hash support + template struct hash; + template struct hash>; + + template 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 ); + constexpr optional(const T &); + constexpr optional(T &&); + template constexpr explicit optional(in_place_t, Args &&...); + template + constexpr explicit optional(in_place_t, initializer_list, Args &&...); + + // 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 optional &operator=(U &&); + template void emplace(Args &&...); + template + void emplace(initializer_list, 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 constexpr T value_or(U &&) const &; + template constexpr T value_or(U &&) &&; + + // 20.6.3.6, modifiers + void reset() noexcept; + + private: + T *val; // exposition only + }; +} // namespace std + +*/ + +#include <__config> +#include +#include + +_LIBCPP_BEGIN_NAMESPACE_STD +class _LIBCPP_EXCEPTION_ABI bad_optional_access + : public std::logic_error +{ +public: + bad_optional_access() : std::logic_error("Bad optional Access") {} + + // Get the key function ~bad_optional_access() into the dylib + virtual ~bad_optional_access() _NOEXCEPT; +}; + +_LIBCPP_END_NAMESPACE_STD + + +#if _LIBCPP_STD_VER > 14 + +#include +#include +#include +#include +#include <__functional_base> +#include <__undef_min_max> +#include <__debug> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +struct nullopt_t +{ + struct __secret_tag { explicit __secret_tag() = default; }; + explicit constexpr nullopt_t(__secret_tag, __secret_tag) noexcept {} +}; + +constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}}; + +template ::value> +struct __optional_destruct_base +{ + typedef _Tp value_type; + 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 + _LIBCPP_INLINE_VISIBILITY + constexpr + explicit __optional_destruct_base(in_place_t, _Args&&... __args) + : __val_(_VSTD::forward<_Args>(__args)...), + __engaged_(true) {} +}; + +template +struct __optional_destruct_base<_Tp, true> +{ + typedef _Tp value_type; + union + { + char __null_state_; + value_type __val_; + }; + bool __engaged_; + + _LIBCPP_INLINE_VISIBILITY + ~__optional_destruct_base() = default; + + _LIBCPP_INLINE_VISIBILITY + constexpr __optional_destruct_base() noexcept + : __null_state_(), + __engaged_(false) {} + + template + _LIBCPP_INLINE_VISIBILITY + constexpr + explicit __optional_destruct_base(in_place_t, _Args&&... __args) + : __val_(_VSTD::forward<_Args>(__args)...), + __engaged_(true) {} +}; + +template ::value> +struct __optional_copy_base : __optional_destruct_base<_Tp> +{ + using __base = __optional_destruct_base<_Tp>; + using typename __base::value_type; + + using __base::__base; + + _LIBCPP_INLINE_VISIBILITY + __optional_copy_base() = default; + + _LIBCPP_INLINE_VISIBILITY + __optional_copy_base(const __optional_copy_base& __x) + { + if (__x.__engaged_) + { + ::new(_VSTD::addressof(this->__val_)) value_type(__x.__val_); + this->__engaged_ = true; + } + } + + _LIBCPP_INLINE_VISIBILITY + __optional_copy_base(__optional_copy_base&& __x) + noexcept(is_nothrow_move_constructible<_Tp>::value) + { + if (__x.__engaged_) + { + ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__x.__val_)); + this->__engaged_ = true; + } + } + + _LIBCPP_INLINE_VISIBILITY + __optional_copy_base& + operator=(const __optional_copy_base& __opt) + { + if (this->__engaged_ == __opt.__engaged_) + { + if (this->__engaged_) + this->__val_ = __opt.__val_; + } + else + { + if (this->__engaged_) + this->__val_.~value_type(); + else + ::new(_VSTD::addressof(this->__val_)) value_type(__opt.__val_); + this->__engaged_ = __opt.__engaged_; + } + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __optional_copy_base& + operator=(__optional_copy_base&& __opt) + noexcept(is_nothrow_move_assignable::value && + is_nothrow_move_constructible::value) + { + if (this->__engaged_ == __opt.__engaged_) + { + if (this->__engaged_) + this->__val_ = _VSTD::move(__opt.__val_); + } + else + { + if (this->__engaged_) + this->__val_.~value_type(); + else + ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_)); + this->__engaged_ = __opt.__engaged_; + } + return *this; + } +}; + +template +struct __optional_copy_base<_Tp, true> : __optional_destruct_base<_Tp> +{ + using __optional_destruct_base<_Tp>::__optional_destruct_base; +}; + +template +class __optional_storage : __optional_copy_base<_Tp> +{ +public: + using __base = __optional_copy_base<_Tp>; + using typename __base::value_type; + + using __base::__base; + + __optional_storage() = default; + + // LWG2451: conversion from optional<_Up>&& + template ::value, int> = 0> + _LIBCPP_INLINE_VISIBILITY + __optional_storage(__optional_storage<_Up>&& __x) + { + if (__x.has_value()) + __construct(_VSTD::move(__x.__get())); + } + + // LWG2451: conversion from const optional<_Up>& + template ::value, int> = 0> + _LIBCPP_INLINE_VISIBILITY + __optional_storage(const __optional_storage<_Up>& __x) + { + if (__x.has_value()) + __construct(__x.__get()); + } + + _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_; + } + + template + _LIBCPP_INLINE_VISIBILITY + void __construct(_Args&&... __args) + { + _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage"); + ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...); + this->__engaged_ = true; + } + + _LIBCPP_INLINE_VISIBILITY + void reset() noexcept + { + if (this->__engaged_) + { + this->__val_.~value_type(); + this->__engaged_ = false; + } + } +}; + +template class _Template> +constexpr bool _Is_specialization = false; +template class _Template> +constexpr bool _Is_specialization<_Template<_Args...>, _Template> = true; + +template +class optional + : private __optional_storage<_Tp> +{ + template friend class optional; + using __base = __optional_storage<_Tp>; +public: + using value_type = _Tp; + + static_assert(!is_reference::value, + "Instantiation of optional with a reference type is ill-formed."); + static_assert(!is_same::type, nullopt_t>::value, + "Instantiation of optional with a nullopt_t type is ill-formed."); + static_assert(is_reference::value || is_object::value, + "Instantiation of optional with a non-object type is undefined behavior."); + static_assert(is_nothrow_destructible::value, + "Instantiation of optional with an object type that is not noexcept destructible is undefined behavior."); + + _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {} + _LIBCPP_INLINE_VISIBILITY optional(const optional&) = default; + _LIBCPP_INLINE_VISIBILITY optional(optional&&) = default; + _LIBCPP_INLINE_VISIBILITY ~optional() = default; + _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {} + _LIBCPP_INLINE_VISIBILITY constexpr optional(const value_type& __v) + : __base(in_place, __v) {} + _LIBCPP_INLINE_VISIBILITY constexpr optional(value_type&& __v) + : __base(in_place, _VSTD::move(__v)) {} + + // LWG2451: conditionally explicit conversion from _Up + template + using _AllowDirectConversion = typename conjunction< + negation, _Tp>>, + is_constructible<_Tp, _Up>>::type; + template , + is_convertible<_Up, _Tp>>::value, int> = 0> + _LIBCPP_INLINE_VISIBILITY + constexpr optional(_Up&& __v) + : __base(in_place, _VSTD::forward<_Up>(__v)) {} + template , + negation>>::value, int> = 0> + _LIBCPP_INLINE_VISIBILITY + constexpr explicit optional(_Up&& __v) + : __base(in_place, _VSTD::forward<_Up>(__v)) {} + + // LWG2451 specifies the following four conversions are to be constexpr if + // the selected constructor for the contained value is constexpr; that + // requirement is not implementable. (Hence the annotation: + // "/* constexpr? */".) + + // LWG2451: conditionally explicit conversion from const optional<_Up>& + template + using _AllowConstConversion = typename conjunction< + negation, _Tp>>, + is_constructible<_Tp, const _Up&>, + negation&>>, + negation&, _Tp>>>::type; + template , + is_convertible>::value, int> = 0> + _LIBCPP_INLINE_VISIBILITY + /* constexpr? */ optional(const optional<_Up>& __v) + : __base(static_cast&>(__v)) {} + template , + negation>>::value, int> = 0> + _LIBCPP_INLINE_VISIBILITY + /* constexpr? */ explicit optional(const optional<_Up>& __v) + : __base(static_cast&>(__v)) {} + + // LWG2451: conditionally explicit conversion from optional<_Up>&& + template + using _AllowRvalueConversion = typename conjunction< + negation, _Tp>>, + is_constructible<_Tp, _Up>, + negation>>, + negation, _Tp>>>::type; + template , + is_convertible<_Up, _Tp>>::value, int> = 0> + _LIBCPP_INLINE_VISIBILITY + /* constexpr? */ optional(optional<_Up>&& __v) + : __base(static_cast<__optional_storage<_Up>&&>(__v)) {} + template , + negation>>::value, int> = 0> + _LIBCPP_INLINE_VISIBILITY + /* constexpr? */ explicit optional(optional<_Up>&& __v) + : __base(static_cast<__optional_storage<_Up>&&>(__v)) {} + + template ::value + >::type + > + _LIBCPP_INLINE_VISIBILITY + constexpr + explicit optional(in_place_t, _Args&&... __args) + : __base(in_place, _VSTD::forward<_Args>(__args)...) {} + + template &, _Args...>::value + >::type + > + _LIBCPP_INLINE_VISIBILITY + constexpr + explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args) + : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {} + + _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; + + // NB: LWG2451 changes the constraints of this signature. + template , nullopt_t>::value && + !_Is_specialization<_Up, optional> && + is_constructible::value && + is_assignable::value + >::type + > + _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; + } + + // LWG2451: converting assignment from const optional& + template , value_type>::value && + is_constructible::value && + is_assignable::value + >::type + > + _LIBCPP_INLINE_VISIBILITY + optional& + operator=(const optional<_Up>& __v) + { + if (this->has_value()) + { + if (__v.has_value()) + this->__get() = __v.__get(); + else + reset(); + } + else if (__v.has_value()) + this->__construct(__v.__get()); + return *this; + } + + // LWG2451: converting assignment from optional&& + template , value_type>::value && + is_constructible::value && + is_assignable::value + >::type + > + _LIBCPP_INLINE_VISIBILITY + optional& + operator=(optional<_Up>&& __v) + { + if (this->has_value()) + { + if (__v.has_value()) + this->__get() = _VSTD::move(__v.__get()); + else + reset(); + } + else if (__v.has_value()) + this->__construct(_VSTD::move(__v.__get())); + return *this; + } + + template ::value + >::type + > + _LIBCPP_INLINE_VISIBILITY + void + emplace(_Args&&... __args) + { + reset(); + this->__construct(_VSTD::forward<_Args>(__args)...); + } + + template &, _Args...>::value + >::type + > + _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::value && + __is_nothrow_swappable::value) + { + 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 + value_type const* + operator->() const + { + _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value"); +#if __has_builtin(__builtin_addressof) + return _VSTD::addressof(this->__get()); +#else + return __operator_arrow(__has_operator_addressof{}); +#endif + } + + _LIBCPP_INLINE_VISIBILITY + constexpr + value_type* + operator->() + { + _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value"); +#if __has_builtin(__builtin_addressof) + return _VSTD::addressof(this->__get()); +#else + return __operator_arrow(__has_operator_addressof{}); +#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; + + _LIBCPP_INLINE_VISIBILITY + constexpr value_type const& value() const& + { + if (!this->has_value()) +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_optional_access(); +#else + assert(!"bad optional access"); +#endif + return this->__get(); + } + + _LIBCPP_INLINE_VISIBILITY + constexpr value_type& value() & + { + if (!this->has_value()) +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_optional_access(); +#else + assert(!"bad optional access"); +#endif + return this->__get(); + } + + _LIBCPP_INLINE_VISIBILITY + constexpr value_type&& value() && + { + if (!this->has_value()) +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_optional_access(); +#else + assert(!"bad optional access"); +#endif + return _VSTD::move(this->__get()); + } + + _LIBCPP_INLINE_VISIBILITY + constexpr value_type const&& value() const&& + { + if (!this->has_value()) +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_optional_access(); +#else + assert(!"bad optional access"); +#endif + return _VSTD::move(this->__get()); + } + + template + _LIBCPP_INLINE_VISIBILITY + constexpr value_type value_or(_Up&& __v) const& + { + static_assert(is_copy_constructible::value, + "optional::value_or: T must be copy constructible"); + static_assert(is_convertible<_Up, value_type>::value, + "optional::value_or: U must be convertible to T"); + return this->has_value() ? this->__get() : + static_cast(_VSTD::forward<_Up>(__v)); + } + + template + _LIBCPP_INLINE_VISIBILITY + value_type value_or(_Up&& __v) && + { + static_assert(is_move_constructible::value, + "optional::value_or: T must be move constructible"); + static_assert(is_convertible<_Up, value_type>::value, + "optional::value_or: U must be convertible to T"); + return this->has_value() ? _VSTD::move(this->__get()) : + static_cast(_VSTD::forward<_Up>(__v)); + } + + using __base::reset; + +private: + _LIBCPP_INLINE_VISIBILITY + value_type const* + __operator_arrow(true_type) const + { + return _VSTD::addressof(this->__get()); + } + + _LIBCPP_INLINE_VISIBILITY + constexpr + value_type const* + __operator_arrow(false_type) const + { + return &this->__get(); + } +}; + +// Comparisons between optionals +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() == declval()), bool>::value, + bool +>::type +operator==(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + if (static_cast(__x) != static_cast(__y)) + return false; + if (!static_cast(__x)) + return true; + return *__x == *__y; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() != declval()), bool>::value, + bool +>::type +operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + if (static_cast(__x) != static_cast(__y)) + return true; + if (!static_cast(__x)) + return false; + return *__x != *__y; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() < declval()), bool>::value, + bool +>::type +operator<(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + if (!static_cast(__y)) + return false; + if (!static_cast(__x)) + return true; + return *__x < *__y; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() > declval()), bool>::value, + bool +>::type +operator>(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + if (!static_cast(__x)) + return false; + if (!static_cast(__y)) + return true; + return *__x > *__y; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() <= declval()), bool>::value, + bool +>::type +operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + if (!static_cast(__x)) + return true; + if (!static_cast(__y)) + return false; + return *__x <= *__y; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() >= declval()), bool>::value, + bool +>::type +operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + if (!static_cast(__y)) + return true; + if (!static_cast(__x)) + return false; + return *__x >= *__y; +} + + +// Comparisons with nullopt +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator==(const optional<_Tp>& __x, nullopt_t) noexcept +{ + return !static_cast(__x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator==(nullopt_t, const optional<_Tp>& __x) noexcept +{ + return !static_cast(__x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator!=(const optional<_Tp>& __x, nullopt_t) noexcept +{ + return static_cast(__x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator!=(nullopt_t, const optional<_Tp>& __x) noexcept +{ + return static_cast(__x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator<(const optional<_Tp>&, nullopt_t) noexcept +{ + return false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator<(nullopt_t, const optional<_Tp>& __x) noexcept +{ + return static_cast(__x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator<=(const optional<_Tp>& __x, nullopt_t) noexcept +{ + return !static_cast(__x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator<=(nullopt_t, const optional<_Tp>& __x) noexcept +{ + return true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator>(const optional<_Tp>& __x, nullopt_t) noexcept +{ + return static_cast(__x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator>(nullopt_t, const optional<_Tp>& __x) noexcept +{ + return false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator>=(const optional<_Tp>&, nullopt_t) noexcept +{ + return true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator>=(nullopt_t, const optional<_Tp>& __x) noexcept +{ + return !static_cast(__x); +} + +// Comparisons with T +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() == declval()), bool>::value, + bool +>::type +operator==(const optional<_Tp>& __x, const _Tp& __v) +{ + return static_cast(__x) ? *__x == __v : false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() == declval()), bool>::value, + bool +>::type +operator==(const _Tp& __v, const optional<_Tp>& __x) +{ + return static_cast(__x) ? __v == *__x : false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() != declval()), bool>::value, + bool +>::type +operator!=(const optional<_Tp>& __x, const _Tp& __v) +{ + return static_cast(__x) ? *__x != __v : true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() != declval()), bool>::value, + bool +>::type +operator!=(const _Tp& __v, const optional<_Tp>& __x) +{ + return static_cast(__x) ? __v != *__x : true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() < declval()), bool>::value, + bool +>::type +operator<(const optional<_Tp>& __x, const _Tp& __v) +{ + return static_cast(__x) ? *__x < __v : true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() < declval()), bool>::value, + bool +>::type +operator<(const _Tp& __v, const optional<_Tp>& __x) +{ + return static_cast(__x) ? __v < *__x : false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() <= declval()), bool>::value, + bool +>::type +operator<=(const optional<_Tp>& __x, const _Tp& __v) +{ + return static_cast(__x) ? *__x <= __v : true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() <= declval()), bool>::value, + bool +>::type +operator<=(const _Tp& __v, const optional<_Tp>& __x) +{ + return static_cast(__x) ? __v <= *__x : false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() > declval()), bool>::value, + bool +>::type +operator>(const optional<_Tp>& __x, const _Tp& __v) +{ + return static_cast(__x) ? *__x > __v : false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() > declval()), bool>::value, + bool +>::type +operator>(const _Tp& __v, const optional<_Tp>& __x) +{ + return static_cast(__x) ? __v > *__x : true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() >= declval()), bool>::value, + bool +>::type +operator>=(const optional<_Tp>& __x, const _Tp& __v) +{ + return static_cast(__x) ? *__x >= __v : false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() >= declval()), bool>::value, + bool +>::type +operator>=(const _Tp& __v, const optional<_Tp>& __x) +{ + return static_cast(__x) ? __v >= *__x : true; +} + + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if< + is_move_constructible<_Tp>::value && __is_swappable<_Tp>::value, + void +>::type +swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) +{ + __x.swap(__y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +optional::type> +make_optional(_Tp&& __v) +{ + return optional::type>(_VSTD::forward<_Tp>(__v)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr optional<_Tp> +make_optional(_Args&&... __args) +{ + return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...); +} + +template +inline _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 +struct _LIBCPP_TYPE_VIS_ONLY hash > +{ + 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(__opt) ? hash<_Tp>()(*__opt) : 0; + } +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP_OPTIONAL Index: optional =================================================================== --- /dev/null +++ optional @@ -0,0 +1,1210 @@ +// -*- 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 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 + constexpr bool operator==(const optional&, const optional&); + template + constexpr bool operator!=(const optional&, const optional&); + template + constexpr bool operator<(const optional&, const optional&); + template + constexpr bool operator>(const optional&, const optional&); + template + constexpr bool operator<=(const optional&, const optional&); + template + constexpr bool operator>=(const optional&, const optional&); + template constexpr bool operator==(const optional&, nullopt_t) noexcept; + template constexpr bool operator==(nullopt_t, const optional&) noexcept; + template constexpr bool operator!=(const optional&, nullopt_t) noexcept; + template constexpr bool operator!=(nullopt_t, const optional&) noexcept; + template constexpr bool operator<(const optional&, nullopt_t) noexcept; + template constexpr bool operator<(nullopt_t, const optional&) noexcept; + template constexpr bool operator<=(const optional&, nullopt_t) noexcept; + template constexpr bool operator<=(nullopt_t, const optional&) noexcept; + template constexpr bool operator>(const optional&, nullopt_t) noexcept; + template constexpr bool operator>(nullopt_t, const optional&) noexcept; + template constexpr bool operator>=(const optional&, nullopt_t) noexcept; + template constexpr bool operator>=(nullopt_t, const optional&) noexcept; + + // 20.6.8, comparison with T + template constexpr bool operator==(const optional&, const T&); + template constexpr bool operator==(const T&, const optional&); + template constexpr bool operator!=(const optional&, const T&); + template constexpr bool operator!=(const T&, const optional&); + template constexpr bool operator<(const optional&, const T&); + template constexpr bool operator<(const T&, const optional&); + template constexpr bool operator<=(const optional&, const T&); + template constexpr bool operator<=(const T&, const optional&); + template constexpr bool operator>(const optional&, const T&); + template constexpr bool operator>(const T&, const optional&); + template constexpr bool operator>=(const optional&, const T&); + template constexpr bool operator>=(const T&, const optional&); + + // 20.6.9, specialized algorithms + template void swap(optional&, optional&) noexcept(see below ); + template constexpr optional make_optional(T&&); + template + constexpr optional make_optional(Args&&... args); + template + constexpr optional make_optional(initializer_list il, Args&&... args); + + // 20.6.10, hash support + template struct hash; + template struct hash>; + + template 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 ); + constexpr optional(const T &); + constexpr optional(T &&); + template constexpr explicit optional(in_place_t, Args &&...); + template + constexpr explicit optional(in_place_t, initializer_list, Args &&...); + + // 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 optional &operator=(U &&); + template void emplace(Args &&...); + template + void emplace(initializer_list, 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 constexpr T value_or(U &&) const &; + template constexpr T value_or(U &&) &&; + + // 20.6.3.6, modifiers + void reset() noexcept; + + private: + T *val; // exposition only + }; +} // namespace std + +*/ + +#include <__config> +#include +#include + +_LIBCPP_BEGIN_NAMESPACE_STD +class _LIBCPP_EXCEPTION_ABI bad_optional_access + : public std::logic_error +{ +public: + bad_optional_access() : std::logic_error("Bad optional Access") {} + + // Get the key function ~bad_optional_access() into the dylib + virtual ~bad_optional_access() _NOEXCEPT; +}; + +_LIBCPP_END_NAMESPACE_STD + + +#if _LIBCPP_STD_VER > 14 + +#include +#include +#include +#include +#include <__functional_base> +#include <__undef_min_max> +#include <__debug> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +struct nullopt_t +{ + explicit constexpr nullopt_t(int) noexcept {} +}; + +constexpr nullopt_t nullopt{0}; + +template ::value> +class __optional_storage +{ +protected: + template friend class __optional_storage; + typedef _Tp value_type; + union + { + char __null_state_; + value_type __val_; + }; + bool __engaged_ = false; + + _LIBCPP_INLINE_VISIBILITY + ~__optional_storage() + { + if (__engaged_) + __val_.~value_type(); + } + + _LIBCPP_INLINE_VISIBILITY + constexpr __optional_storage() noexcept + : __null_state_('\0') {} + + _LIBCPP_INLINE_VISIBILITY + __optional_storage(const __optional_storage& __x) + : __engaged_(__x.__engaged_) + { + if (__engaged_) + ::new(_VSTD::addressof(__val_)) value_type(__x.__val_); + } + + _LIBCPP_INLINE_VISIBILITY + __optional_storage(__optional_storage&& __x) + noexcept(is_nothrow_move_constructible::value) + : __engaged_(__x.__engaged_) + { + if (__engaged_) + ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_)); + } + + _LIBCPP_INLINE_VISIBILITY + constexpr __optional_storage(const value_type& __v) + : __val_(__v), + __engaged_(true) {} + + _LIBCPP_INLINE_VISIBILITY + constexpr __optional_storage(value_type&& __v) + : __val_(_VSTD::move(__v)), + __engaged_(true) {} + + template + _LIBCPP_INLINE_VISIBILITY + constexpr + explicit __optional_storage(in_place_t, _Args&&... __args) + : __val_(_VSTD::forward<_Args>(__args)...), + __engaged_(true) {} + + // LWG2451: conversion from optional<_Up>&& + template ::value, int> = 0> + _LIBCPP_INLINE_VISIBILITY + __optional_storage(__optional_storage<_Up>&& __x) + : __engaged_(__x.__engaged_) + { + if (__engaged_) + ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_)); + } + + // LWG2451: conversion from const optional<_Up>& + template ::value, int> = 0> + _LIBCPP_INLINE_VISIBILITY + __optional_storage(const __optional_storage<_Up>& __x) + : __engaged_(__x.__engaged_) + { + if (__engaged_) + ::new(_VSTD::addressof(__val_)) value_type(__x.__val_); + } +}; + +template class _Template> +constexpr bool _Is_specialization = false; +template class _Template> +constexpr bool _Is_specialization<_Template<_Args...>, _Template> = true; + +template +class __optional_storage<_Tp, true> +{ +protected: + template friend class __optional_storage; + + typedef _Tp value_type; + union + { + char __null_state_; + value_type __val_; + }; + bool __engaged_ = false; + + _LIBCPP_INLINE_VISIBILITY + constexpr __optional_storage() noexcept + : __null_state_('\0') {} + + _LIBCPP_INLINE_VISIBILITY + __optional_storage(const __optional_storage& __x) + : __engaged_(__x.__engaged_) + { + if (__engaged_) + ::new(_VSTD::addressof(__val_)) value_type(__x.__val_); + } + + _LIBCPP_INLINE_VISIBILITY + __optional_storage(__optional_storage&& __x) + noexcept(is_nothrow_move_constructible::value) + : __engaged_(__x.__engaged_) + { + if (__engaged_) + ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_)); + } + + _LIBCPP_INLINE_VISIBILITY + constexpr __optional_storage(const value_type& __v) + : __val_(__v), + __engaged_(true) {} + + _LIBCPP_INLINE_VISIBILITY + constexpr __optional_storage(value_type&& __v) + : __val_(_VSTD::move(__v)), + __engaged_(true) {} + + template + _LIBCPP_INLINE_VISIBILITY + constexpr + explicit __optional_storage(in_place_t, _Args&&... __args) + : __val_(_VSTD::forward<_Args>(__args)...), + __engaged_(true) {} + + // LWG2451: conversion from optional<_Up>&& + template ::value, int> = 0> + _LIBCPP_INLINE_VISIBILITY + __optional_storage(__optional_storage<_Up>&& __x) + : __engaged_(__x.__engaged_) + { + if (__engaged_) + ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move (__x.__val_)); + } + + // LWG2451: conversion from const optional<_Up>& + template ::value, int> = 0> + _LIBCPP_INLINE_VISIBILITY + __optional_storage(const __optional_storage<_Up>& __x) + : __engaged_(__x.__engaged_) + { + if (__engaged_) + ::new(_VSTD::addressof(__val_)) value_type(__x.__val_); + } +}; + +template +class optional + : private __optional_storage<_Tp> +{ + template friend class optional; + typedef __optional_storage<_Tp> __base; +public: + typedef _Tp value_type; + + static_assert(!is_reference::value, + "Instantiation of optional with a reference type is ill-formed."); + static_assert(!is_same::type, nullopt_t>::value, + "Instantiation of optional with a nullopt_t type is ill-formed."); + static_assert(is_reference::value || is_object::value, + "Instantiation of optional with a non-object type is undefined behavior."); + static_assert(is_nothrow_destructible::value, + "Instantiation of optional with an object type that is not noexcept destructible is undefined behavior."); + + _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {} + _LIBCPP_INLINE_VISIBILITY optional(const optional&) = default; + _LIBCPP_INLINE_VISIBILITY optional(optional&&) = default; + _LIBCPP_INLINE_VISIBILITY ~optional() = default; + _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {} + _LIBCPP_INLINE_VISIBILITY constexpr optional(const value_type& __v) + : __base(__v) {} + _LIBCPP_INLINE_VISIBILITY constexpr optional(value_type&& __v) + : __base(_VSTD::move(__v)) {} + + template + using _AllowDirectConversion = typename conjunction< + negation, _Tp>>, + is_constructible<_Tp, _Up>>::type; + + // LWG2451: conditionally explicit conversion from _Up + template , + is_convertible<_Up, _Tp>>::value, int> = 0> + _LIBCPP_INLINE_VISIBILITY + constexpr optional(_Up&& __v) + : __base(in_place, _VSTD::forward<_Up>(__v)) {} + template , + negation>>::value, int> = 0> + _LIBCPP_INLINE_VISIBILITY + constexpr explicit optional(_Up&& __v) + : __base(in_place, _VSTD::forward<_Up>(__v)) {} + + // LWG2451 specifies the following four conversions are to be constexpr if + // the selected constructor for the contained value is constexpr; that + // requirement is not implementable. (Hence the annotation: + // "/* constexpr? */".) + + // LWG2451: conditionally explicit conversion from const optional<_Up>& + template + using _AllowConstConversion = typename conjunction< + negation, _Tp>>, + is_constructible<_Tp, const _Up&>, + negation&>>, + negation&, _Tp>>>::type; + template , + is_convertible>::value, int> = 0> + _LIBCPP_INLINE_VISIBILITY + /* constexpr? */ optional(const optional<_Up>& __v) + : __base(static_cast&>(__v)) {} + template , + negation>>::value, int> = 0> + _LIBCPP_INLINE_VISIBILITY + /* constexpr? */ explicit optional(const optional<_Up>& __v) + : __base(static_cast&>(__v)) {} + + // LWG2451: conditionally explicit conversion from optional<_Up>&& + template + using _AllowRvalueConversion = typename conjunction< + negation, _Tp>>, + is_constructible<_Tp, _Up>, + negation>>, + negation, _Tp>>>::type; + template , + is_convertible<_Up, _Tp>>::value, int> = 0> + _LIBCPP_INLINE_VISIBILITY + /* constexpr? */ optional(optional<_Up>&& __v) + : __base(static_cast<__optional_storage<_Up>&&>(__v)) {} + template , + negation>>::value, int> = 0> + _LIBCPP_INLINE_VISIBILITY + /* constexpr? */ explicit optional(optional<_Up>&& __v) + : __base(static_cast<__optional_storage<_Up>&&>(__v)) {} + + template ::value + >::type + > + _LIBCPP_INLINE_VISIBILITY + constexpr + explicit optional(in_place_t, _Args&&... __args) + : __base(in_place, _VSTD::forward<_Args>(__args)...) {} + + template &, _Args...>::value + >::type + > + _LIBCPP_INLINE_VISIBILITY + constexpr + explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args) + : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {} + + _LIBCPP_INLINE_VISIBILITY + optional& operator=(nullopt_t) noexcept + { + reset(); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + optional& + operator=(const optional& __opt) + { + if (this->__engaged_ == __opt.__engaged_) + { + if (this->__engaged_) + this->__val_ = __opt.__val_; + } + else + { + if (this->__engaged_) + this->__val_.~value_type(); + else + ::new(_VSTD::addressof(this->__val_)) value_type(__opt.__val_); + this->__engaged_ = __opt.__engaged_; + } + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + optional& + operator=(optional&& __opt) + noexcept(is_nothrow_move_assignable::value && + is_nothrow_move_constructible::value) + { + if (this->__engaged_ == __opt.__engaged_) + { + if (this->__engaged_) + this->__val_ = _VSTD::move(__opt.__val_); + } + else + { + if (this->__engaged_) + this->__val_.~value_type(); + else + ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_)); + this->__engaged_ = __opt.__engaged_; + } + return *this; + } + + // NB: LWG2451 changes the constraints of this signature. + template , nullopt_t>::value && + !_Is_specialization<_Up, optional> && + is_constructible::value && + is_assignable::value + >::type + > + _LIBCPP_INLINE_VISIBILITY + optional& + operator=(_Up&& __v) + { + if (this->__engaged_) + this->__val_ = _VSTD::forward<_Up>(__v); + else + { + ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Up>(__v)); + this->__engaged_ = true; + } + return *this; + } + + // LWG2451: converting assignment from const optional& + template , value_type>::value && + is_constructible::value && + is_assignable::value + >::type + > + _LIBCPP_INLINE_VISIBILITY + optional& + operator=(const optional<_Up>& __v) + { + if (this->__engaged_) + { + if (__v.__engaged_) + this->__val_ = __v.__val_; + else + reset(); + } + else if (__v.__engaged_) + { + ::new(_VSTD::addressof(this->__val_)) value_type(__v.__val_); + this->__engaged_ = true; + } + return *this; + } + + // LWG2451: converting assignment from optional&& + template , value_type>::value && + is_constructible::value && + is_assignable::value + >::type + > + _LIBCPP_INLINE_VISIBILITY + optional& + operator=(optional<_Up>&& __v) + { + if (this->__engaged_) + { + if (__v.__engaged_) + this->__val_ = _VSTD::move(__v.__val_); + else + reset(); + } + else if (__v.__engaged_) + { + ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__v.__val_)); + this->__engaged_ = true; + } + return *this; + } + + template ::value + >::type + > + _LIBCPP_INLINE_VISIBILITY + void + emplace(_Args&&... __args) + { + reset(); + ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...); + this->__engaged_ = true; + } + + template &, _Args...>::value + >::type + > + _LIBCPP_INLINE_VISIBILITY + void + emplace(initializer_list<_Up> __il, _Args&&... __args) + { + reset(); + ::new(_VSTD::addressof(this->__val_)) value_type(__il, _VSTD::forward<_Args>(__args)...); + this->__engaged_ = true; + } + + _LIBCPP_INLINE_VISIBILITY + void + swap(optional& __opt) + noexcept(is_nothrow_move_constructible::value && + __is_nothrow_swappable::value) + { + using _VSTD::swap; + if (this->__engaged_ == __opt.__engaged_) + { + if (this->__engaged_) + swap(this->__val_, __opt.__val_); + } + else + { + if (this->__engaged_) + { + ::new(_VSTD::addressof(__opt.__val_)) value_type(_VSTD::move(this->__val_)); + this->__val_.~value_type(); + } + else + { + ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_)); + __opt.__val_.~value_type(); + } + swap(this->__engaged_, __opt.__engaged_); + } + } + + _LIBCPP_INLINE_VISIBILITY + constexpr + value_type const* + operator->() const + { + _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value"); +#if __has_builtin(__builtin_addressof) + return _VSTD::addressof(this->__val_); +#else + return __operator_arrow(__has_operator_addressof{}); +#endif + } + + _LIBCPP_INLINE_VISIBILITY + constexpr + value_type* + operator->() + { + _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value"); +#if __has_builtin(__builtin_addressof) + return _VSTD::addressof(this->__val_); +#else + return __operator_arrow(__has_operator_addressof{}); +#endif + } + + _LIBCPP_INLINE_VISIBILITY + constexpr + const value_type& + operator*() const& + { + _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value"); + return this->__val_; + } + + _LIBCPP_INLINE_VISIBILITY + constexpr + value_type& + operator*() & + { + _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value"); + return this->__val_; + } + + _LIBCPP_INLINE_VISIBILITY + constexpr + value_type&& + operator*() && + { + _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value"); + return _VSTD::move(this->__val_); + } + + _LIBCPP_INLINE_VISIBILITY + constexpr + const value_type&& + operator*() const&& + { + _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value"); + return _VSTD::move(this->__val_); + } + + _LIBCPP_INLINE_VISIBILITY + constexpr explicit operator bool() const noexcept {return this->__engaged_;} + + _LIBCPP_INLINE_VISIBILITY + constexpr bool has_value() const noexcept {return static_cast(*this);} + + _LIBCPP_INLINE_VISIBILITY + constexpr value_type const& value() const& + { + if (!this->__engaged_) +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_optional_access(); +#else + assert(!"bad optional access"); +#endif + return this->__val_; + } + + _LIBCPP_INLINE_VISIBILITY + constexpr value_type& value() & + { + if (!this->__engaged_) +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_optional_access(); +#else + assert(!"bad optional access"); +#endif + return this->__val_; + } + + _LIBCPP_INLINE_VISIBILITY + constexpr value_type&& value() && + { + if (!this->__engaged_) +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_optional_access(); +#else + assert(!"bad optional access"); +#endif + return _VSTD::move(this->__val_); + } + + _LIBCPP_INLINE_VISIBILITY + constexpr value_type const&& value() const&& + { + if (!this->__engaged_) +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_optional_access(); +#else + assert(!"bad optional access"); +#endif + return _VSTD::move(this->__val_); + } + + template + _LIBCPP_INLINE_VISIBILITY + constexpr value_type value_or(_Up&& __v) const& + { + static_assert(is_copy_constructible::value, + "optional::value_or: T must be copy constructible"); + static_assert(is_convertible<_Up, value_type>::value, + "optional::value_or: U must be convertible to T"); + return this->__engaged_ ? this->__val_ : + static_cast(_VSTD::forward<_Up>(__v)); + } + + template + _LIBCPP_INLINE_VISIBILITY + value_type value_or(_Up&& __v) && + { + static_assert(is_move_constructible::value, + "optional::value_or: T must be move constructible"); + static_assert(is_convertible<_Up, value_type>::value, + "optional::value_or: U must be convertible to T"); + return this->__engaged_ ? _VSTD::move(this->__val_) : + static_cast(_VSTD::forward<_Up>(__v)); + } + + _LIBCPP_INLINE_VISIBILITY + void reset() noexcept + { + if (this->__engaged_) + { + this->__val_.~value_type(); + this->__engaged_ = false; + } + } +private: + _LIBCPP_INLINE_VISIBILITY + value_type const* + __operator_arrow(true_type) const + { + return _VSTD::addressof(this->__val_); + } + + _LIBCPP_INLINE_VISIBILITY + constexpr + value_type const* + __operator_arrow(false_type) const + { + return &this->__val_; + } +}; + +// Comparisons between optionals +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() == declval()), bool>::value, + bool +>::type +operator==(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + if (static_cast(__x) != static_cast(__y)) + return false; + if (!static_cast(__x)) + return true; + return *__x == *__y; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() != declval()), bool>::value, + bool +>::type +operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + if (static_cast(__x) != static_cast(__y)) + return true; + if (!static_cast(__x)) + return false; + return *__x != *__y; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() < declval()), bool>::value, + bool +>::type +operator<(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + if (!static_cast(__y)) + return false; + if (!static_cast(__x)) + return true; + return *__x < *__y; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() > declval()), bool>::value, + bool +>::type +operator>(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + if (!static_cast(__x)) + return false; + if (!static_cast(__y)) + return true; + return *__x > *__y; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() <= declval()), bool>::value, + bool +>::type +operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + if (!static_cast(__x)) + return true; + if (!static_cast(__y)) + return false; + return *__x <= *__y; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() >= declval()), bool>::value, + bool +>::type +operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + if (!static_cast(__y)) + return true; + if (!static_cast(__x)) + return false; + return *__x >= *__y; +} + + +// Comparisons with nullopt +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator==(const optional<_Tp>& __x, nullopt_t) noexcept +{ + return !static_cast(__x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator==(nullopt_t, const optional<_Tp>& __x) noexcept +{ + return !static_cast(__x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator!=(const optional<_Tp>& __x, nullopt_t) noexcept +{ + return static_cast(__x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator!=(nullopt_t, const optional<_Tp>& __x) noexcept +{ + return static_cast(__x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator<(const optional<_Tp>&, nullopt_t) noexcept +{ + return false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator<(nullopt_t, const optional<_Tp>& __x) noexcept +{ + return static_cast(__x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator<=(const optional<_Tp>& __x, nullopt_t) noexcept +{ + return !static_cast(__x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator<=(nullopt_t, const optional<_Tp>& __x) noexcept +{ + return true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator>(const optional<_Tp>& __x, nullopt_t) noexcept +{ + return static_cast(__x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator>(nullopt_t, const optional<_Tp>& __x) noexcept +{ + return false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator>=(const optional<_Tp>&, nullopt_t) noexcept +{ + return true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator>=(nullopt_t, const optional<_Tp>& __x) noexcept +{ + return !static_cast(__x); +} + +// Comparisons with T +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() == declval()), bool>::value, + bool +>::type +operator==(const optional<_Tp>& __x, const _Tp& __v) +{ + return static_cast(__x) ? *__x == __v : false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() == declval()), bool>::value, + bool +>::type +operator==(const _Tp& __v, const optional<_Tp>& __x) +{ + return static_cast(__x) ? __v == *__x : false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() != declval()), bool>::value, + bool +>::type +operator!=(const optional<_Tp>& __x, const _Tp& __v) +{ + return static_cast(__x) ? *__x != __v : true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() != declval()), bool>::value, + bool +>::type +operator!=(const _Tp& __v, const optional<_Tp>& __x) +{ + return static_cast(__x) ? __v != *__x : true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() < declval()), bool>::value, + bool +>::type +operator<(const optional<_Tp>& __x, const _Tp& __v) +{ + return static_cast(__x) ? *__x < __v : true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() < declval()), bool>::value, + bool +>::type +operator<(const _Tp& __v, const optional<_Tp>& __x) +{ + return static_cast(__x) ? __v < *__x : false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() <= declval()), bool>::value, + bool +>::type +operator<=(const optional<_Tp>& __x, const _Tp& __v) +{ + return static_cast(__x) ? *__x <= __v : true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() <= declval()), bool>::value, + bool +>::type +operator<=(const _Tp& __v, const optional<_Tp>& __x) +{ + return static_cast(__x) ? __v <= *__x : false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() > declval()), bool>::value, + bool +>::type +operator>(const optional<_Tp>& __x, const _Tp& __v) +{ + return static_cast(__x) ? *__x > __v : false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() > declval()), bool>::value, + bool +>::type +operator>(const _Tp& __v, const optional<_Tp>& __x) +{ + return static_cast(__x) ? __v > *__x : true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() >= declval()), bool>::value, + bool +>::type +operator>=(const optional<_Tp>& __x, const _Tp& __v) +{ + return static_cast(__x) ? *__x >= __v : false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +typename enable_if< + is_convertible() >= declval()), bool>::value, + bool +>::type +operator>=(const _Tp& __v, const optional<_Tp>& __x) +{ + return static_cast(__x) ? __v >= *__x : true; +} + + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if< + is_move_constructible<_Tp>::value && __is_swappable<_Tp>::value, + void +>::type +swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) +{ + __x.swap(__y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +optional::type> +make_optional(_Tp&& __v) +{ + return optional::type>(_VSTD::forward<_Tp>(__v)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr optional<_Tp> +make_optional(_Args&&... __args) +{ + return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...); +} + +template +inline _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 +struct _LIBCPP_TYPE_VIS_ONLY hash > +{ + 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(__opt) ? hash<_Tp>()(*__opt) : 0; + } +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP_OPTIONAL Index: src/optional.cpp =================================================================== --- src/optional.cpp +++ src/optional.cpp @@ -7,8 +7,23 @@ // //===----------------------------------------------------------------------===// +#include "optional" #include "experimental/optional" +_LIBCPP_BEGIN_NAMESPACE_STD + +#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS + +bad_optional_access::~bad_optional_access() _NOEXCEPT {} + +#else + +bad_optional_access::~bad_optional_access() _NOEXCEPT = default; + +#endif + +_LIBCPP_END_NAMESPACE_STD + _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL #ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS Index: test/libcxx/optional/version.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/optional/version.pass.cpp @@ -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. +// +//===----------------------------------------------------------------------===// + +// + +#include + +#ifndef _LIBCPP_VERSION +#error _LIBCPP_VERSION not defined +#endif + +int main() +{ +} Index: test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.pass.cpp =================================================================== --- test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.pass.cpp +++ test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.pass.cpp @@ -59,7 +59,7 @@ !std::is_nothrow_swappable_with::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::value, ""); static_assert(!std::is_nothrow_swappable_with::value && Index: test/std/utilities/optional/optional.hash/hash.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.hash/hash.pass.cpp @@ -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 +// + +// template struct hash>; + +#include +#include +#include +#include + + +int main() +{ + using std::optional; + const std::size_t nullopt_hash = + std::hash>{}(optional{}); + + { + typedef int T; + optional opt; + assert(std::hash>{}(opt) == nullopt_hash); + opt = 2; + assert(std::hash>{}(opt) == std::hash{}(*opt)); + } + { + typedef std::string T; + optional opt; + assert(std::hash>{}(opt) == nullopt_hash); + opt = std::string("123"); + assert(std::hash>{}(opt) == std::hash{}(*opt)); + } + { + typedef std::unique_ptr T; + optional opt; + assert(std::hash>{}(opt) == nullopt_hash); + opt = std::unique_ptr(new int(3)); + assert(std::hash>{}(opt) == std::hash{}(*opt)); + } +} Index: test/std/utilities/optional/optional.bad_optional_access/default.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.bad_optional_access/default.pass.cpp @@ -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 + +// + +// class bad_optional_access is default constructible + +#include +#include + +int main() +{ + using std::bad_optional_access; + bad_optional_access ex; +} Index: test/std/utilities/optional/optional.bad_optional_access/derive.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.bad_optional_access/derive.pass.cpp @@ -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 + +// + +// class bad_optional_access : public logic_error + +#include +#include + +int main() +{ + using std::bad_optional_access; + + static_assert(std::is_base_of::value, ""); + static_assert(std::is_convertible::value, ""); +} Index: test/std/utilities/optional/optional.comp_with_t/equal.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.comp_with_t/equal.pass.cpp @@ -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 +// + +// template constexpr bool operator==(const optional& x, const T& v); +// template constexpr bool operator==(const T& v, const optional& x); + +#include + +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 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), "" ); + } +} Index: test/std/utilities/optional/optional.comp_with_t/greater.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.comp_with_t/greater.pass.cpp @@ -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 +// + +// template constexpr bool operator>(const optional& x, const T& v); +// template constexpr bool operator>(const T& v, const optional& x); + +#include + +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 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), "" ); + } +} Index: test/std/utilities/optional/optional.comp_with_t/greater_equal.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.comp_with_t/greater_equal.pass.cpp @@ -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 +// + +// template constexpr bool operator>=(const optional& x, const T& v); +// template constexpr bool operator>=(const T& v, const optional& x); + +#include + +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 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), "" ); + } +} Index: test/std/utilities/optional/optional.comp_with_t/less_equal.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.comp_with_t/less_equal.pass.cpp @@ -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 +// + +// template constexpr bool operator<=(const optional& x, const T& v); +// template constexpr bool operator<=(const T& v, const optional& x); + +#include + +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 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), "" ); + } +} Index: test/std/utilities/optional/optional.comp_with_t/less_than.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.comp_with_t/less_than.pass.cpp @@ -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 +// + +// template constexpr bool operator<(const optional& x, const T& v); +// template constexpr bool operator<(const T& v, const optional& x); + +#include + +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 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), "" ); + } +} Index: test/std/utilities/optional/optional.comp_with_t/not_equal.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.comp_with_t/not_equal.pass.cpp @@ -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 +// + +// template constexpr bool operator!=(const optional& x, const T& v); +// template constexpr bool operator!=(const T& v, const optional& x); + +#include + +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 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), "" ); + } +} Index: test/std/utilities/optional/optional.nullops/equal.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.nullops/equal.pass.cpp @@ -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 +// + +// template constexpr bool operator==(const optional& x, nullopt_t) noexcept; +// template constexpr bool operator==(nullopt_t, const optional& x) noexcept; + +#include + +int main() +{ + using std::optional; + using std::nullopt_t; + using std::nullopt; + + { + typedef int T; + typedef optional 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), ""); + } +} Index: test/std/utilities/optional/optional.nullops/greater.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.nullops/greater.pass.cpp @@ -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 +// + +// template constexpr bool operator>(const optional& x, nullopt_t) noexcept; +// template constexpr bool operator>(nullopt_t, const optional& x) noexcept; + +#include + +int main() +{ + using std::optional; + using std::nullopt_t; + using std::nullopt; + + { + typedef int T; + typedef optional 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), ""); + } +} Index: test/std/utilities/optional/optional.nullops/greater_equal.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.nullops/greater_equal.pass.cpp @@ -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 +// + +// template constexpr bool operator>=(const optional& x, nullopt_t) noexcept; +// template constexpr bool operator>=(nullopt_t, const optional& x) noexcept; + +#include + +int main() +{ + using std::optional; + using std::nullopt_t; + using std::nullopt; + + { + typedef int T; + typedef optional 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), ""); + } +} Index: test/std/utilities/optional/optional.nullops/less_equal.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.nullops/less_equal.pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + + +// + +// template constexpr bool operator<=(const optional& x, nullopt_t) noexcept; +// template constexpr bool operator<=(nullopt_t, const optional& x) noexcept; + +#include + +int main() +{ +#if _LIBCPP_STD_VER > 11 + using std::optional; + using std::nullopt_t; + using std::nullopt; + + { + typedef int T; + typedef optional 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), ""); + } +#endif +} Index: test/std/utilities/optional/optional.nullops/less_than.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.nullops/less_than.pass.cpp @@ -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 +// + +// template constexpr bool operator<(const optional& x, nullopt_t) noexcept; +// template constexpr bool operator<(nullopt_t, const optional& x) noexcept; + +#include + +int main() +{ + using std::optional; + using std::nullopt_t; + using std::nullopt; + + { + typedef int T; + typedef optional 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), ""); + } +} Index: test/std/utilities/optional/optional.nullops/not_equal.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.nullops/not_equal.pass.cpp @@ -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 +// + +// template constexpr bool operator!=(const optional& x, nullopt_t) noexcept; +// template constexpr bool operator!=(nullopt_t, const optional& x) noexcept; + +#include + +int main() +{ + using std::optional; + using std::nullopt_t; + using std::nullopt; + + { + typedef int T; + typedef optional 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), ""); + } +} Index: test/std/utilities/optional/optional.nullopt/nullopt_t.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.nullopt/nullopt_t.pass.cpp @@ -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 +// + +// struct nullopt_t{see below}; +// constexpr nullopt_t nullopt(unspecified); + +#include +#include + +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::value), ""); + static_assert((std::is_empty::value), ""); + static_assert((std::is_literal_type::value), ""); + static_assert((!std::is_default_constructible::value), ""); + + static_assert(test(nullopt) == 3, ""); +} Index: test/std/utilities/optional/optional.object/optional.object.assign/assign_value.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.assign/assign_value.pass.cpp @@ -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 +// + +// template optional& operator=(U&& v); + +#include +#include +#include +#include + +using std::optional; + +struct X +{ +}; + +int main() +{ + static_assert(std::is_assignable, int>::value, ""); + static_assert(std::is_assignable, int&>::value, ""); + static_assert(std::is_assignable&, int>::value, ""); + static_assert(std::is_assignable&, int&>::value, ""); + static_assert(std::is_assignable&, const int&>::value, ""); + static_assert(!std::is_assignable&, const int&>::value, ""); + static_assert(!std::is_assignable, X>::value, ""); + { + optional opt; + opt = 1; + assert(static_cast(opt) == true); + assert(*opt == 1); + } + { + optional opt; + const int i = 2; + opt = i; + assert(static_cast(opt) == true); + assert(*opt == i); + } + { + optional opt(3); + const int i = 2; + opt = i; + assert(static_cast(opt) == true); + assert(*opt == i); + } + { + optional> opt; + opt = std::unique_ptr(new int(3)); + assert(static_cast(opt) == true); + assert(**opt == 3); + } + { + optional> opt(std::unique_ptr(new int(2))); + opt = std::unique_ptr(new int(3)); + assert(static_cast(opt) == true); + assert(**opt == 3); + } +} Index: test/std/utilities/optional/optional.object/optional.object.assign/const_optional_U.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.assign/const_optional_U.pass.cpp @@ -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 +// XFAIL: libcpp-no-exceptions +// + +// From LWG2451: +// template +// optional& operator=(const optional& rhs); + +#include +#include +#include + +using std::optional; + +struct X +{ + static bool throw_now; + + X() = default; + X(int) + { + if (throw_now) + 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; } +}; + +int main() +{ + { + optional opt; + constexpr optional opt2; + opt = opt2; + static_assert(static_cast(opt2) == false, ""); + assert(static_cast(opt) == static_cast(opt2)); + } + { + optional opt; + constexpr optional opt2(short{2}); + opt = opt2; + static_assert(static_cast(opt2) == true, ""); + static_assert(*opt2 == 2, ""); + assert(static_cast(opt) == static_cast(opt2)); + assert(*opt == *opt2); + } + { + optional opt(3); + constexpr optional opt2; + opt = opt2; + static_assert(static_cast(opt2) == false, ""); + assert(static_cast(opt) == static_cast(opt2)); + } + { + optional opt(3); + constexpr optional opt2(short{2}); + opt = opt2; + static_assert(static_cast(opt2) == true, ""); + static_assert(*opt2 == 2, ""); + assert(static_cast(opt) == static_cast(opt2)); + assert(*opt == *opt2); + } + { + optional opt; + optional opt2(42); + assert(static_cast(opt2) == true); + try + { + X::throw_now = true; + opt = opt2; + assert(false); + } + catch (int i) + { + assert(i == 6); + assert(static_cast(opt) == false); + } + } +} Index: test/std/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp @@ -0,0 +1,86 @@ +//===----------------------------------------------------------------------===// +// +// 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& operator=(const optional& rhs); + +#include +#include +#include + +using std::optional; + +struct X +{ + static bool throw_now; + + X() = default; + X(const X&) + { + if (throw_now) + throw 6; + } +}; + +bool X::throw_now = false; + +int main() +{ + { + optional opt; + constexpr optional opt2; + opt = opt2; + static_assert(static_cast(opt2) == false, ""); + assert(static_cast(opt) == static_cast(opt2)); + } + { + optional opt; + constexpr optional opt2(2); + opt = opt2; + static_assert(static_cast(opt2) == true, ""); + static_assert(*opt2 == 2, ""); + assert(static_cast(opt) == static_cast(opt2)); + assert(*opt == *opt2); + } + { + optional opt(3); + constexpr optional opt2; + opt = opt2; + static_assert(static_cast(opt2) == false, ""); + assert(static_cast(opt) == static_cast(opt2)); + } + { + optional opt(3); + constexpr optional opt2(2); + opt = opt2; + static_assert(static_cast(opt2) == true, ""); + static_assert(*opt2 == 2, ""); + assert(static_cast(opt) == static_cast(opt2)); + assert(*opt == *opt2); + } + { + optional opt; + optional opt2(X{}); + assert(static_cast(opt2) == true); + try + { + X::throw_now = true; + opt = opt2; + assert(false); + } + catch (int i) + { + assert(i == 6); + assert(static_cast(opt) == false); + } + } +} Index: test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp @@ -0,0 +1,133 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// + +// template void optional::emplace(Args&&... args); + +#include +#include +#include +#include + +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) {throw 6;} + ~Y() {dtor_called = true;} +}; + +bool Y::dtor_called = false; + +int main() +{ + { + optional opt; + opt.emplace(); + assert(static_cast(opt) == true); + assert(*opt == 0); + } + { + optional opt; + opt.emplace(1); + assert(static_cast(opt) == true); + assert(*opt == 1); + } + { + optional opt(2); + opt.emplace(); + assert(static_cast(opt) == true); + assert(*opt == 0); + } + { + optional opt(2); + opt.emplace(1); + assert(static_cast(opt) == true); + assert(*opt == 1); + } + { + optional opt; + opt.emplace(); + assert(static_cast(opt) == true); + assert(*opt == X()); + } + { + optional opt; + opt.emplace(1); + assert(static_cast(opt) == true); + assert(*opt == X(1)); + } + { + optional opt; + opt.emplace(1, 2); + assert(static_cast(opt) == true); + assert(*opt == X(1, 2)); + } + { + optional opt(X{3}); + opt.emplace(); + assert(static_cast(opt) == true); + assert(*opt == X()); + } + { + optional opt(X{3}); + opt.emplace(1); + assert(static_cast(opt) == true); + assert(*opt == X(1)); + } + { + optional opt(X{3}); + opt.emplace(1, 2); + assert(static_cast(opt) == true); + assert(*opt == X(1, 2)); + } + { + Y y; + optional opt(y); + assert(Y::dtor_called == false); + opt.emplace(); + assert(Y::dtor_called == true); + } + Y::dtor_called = false; + { + Y y; + optional opt(y); + try + { + assert(static_cast(opt) == true); + assert(Y::dtor_called == false); + opt.emplace(1); + } + catch (int i) + { + assert(i == 6); + assert(static_cast(opt) == false); + assert(Y::dtor_called == true); + } + } +} Index: test/std/utilities/optional/optional.object/optional.object.assign/emplace_initializer_list.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.assign/emplace_initializer_list.pass.cpp @@ -0,0 +1,110 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// + +// template +// void optional::emplace(initializer_list il, Args&&... args); + +#include +#include +#include +#include + +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 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 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 il) : i_(il.begin()[0]), j_(il.begin()[1]) + {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 opt(x); + assert(X::dtor_called == false); + opt.emplace({1, 2}); + assert(X::dtor_called == true); + assert(*opt == X({1, 2})); + } + { + optional> opt; + opt.emplace({1, 2, 3}, std::allocator()); + assert(static_cast(opt) == true); + assert(*opt == std::vector({1, 2, 3})); + } + { + optional opt; + opt.emplace({1, 2}); + assert(static_cast(opt) == true); + assert(*opt == Y({1, 2})); + } + { + Z z; + optional opt(z); + try + { + assert(static_cast(opt) == true); + assert(Z::dtor_called == false); + opt.emplace({1, 2}); + } + catch (int i) + { + assert(i == 6); + assert(static_cast(opt) == false); + assert(Z::dtor_called == true); + } + } +} Index: test/std/utilities/optional/optional.object/optional.object.assign/move.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.assign/move.pass.cpp @@ -0,0 +1,99 @@ +//===----------------------------------------------------------------------===// +// +// 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& operator=(optional&& rhs) +// noexcept(is_nothrow_move_assignable::value && +// is_nothrow_move_constructible::value); + +#include +#include +#include + +using std::optional; + +struct X +{ + static bool throw_now; + + X() = default; + X(X&&) + { + if (throw_now) + throw 6; + } + X& operator=(X&&) noexcept + { + return *this; + } +}; + +struct Y {}; + +bool X::throw_now = false; + +int main() +{ + { + static_assert(std::is_nothrow_move_assignable>::value, ""); + optional opt; + constexpr optional opt2; + opt = std::move(opt2); + static_assert(static_cast(opt2) == false, ""); + assert(static_cast(opt) == static_cast(opt2)); + } + { + optional opt; + constexpr optional opt2(2); + opt = std::move(opt2); + static_assert(static_cast(opt2) == true, ""); + static_assert(*opt2 == 2, ""); + assert(static_cast(opt) == static_cast(opt2)); + assert(*opt == *opt2); + } + { + optional opt(3); + constexpr optional opt2; + opt = std::move(opt2); + static_assert(static_cast(opt2) == false, ""); + assert(static_cast(opt) == static_cast(opt2)); + } + { + optional opt(3); + constexpr optional opt2(2); + opt = std::move(opt2); + static_assert(static_cast(opt2) == true, ""); + static_assert(*opt2 == 2, ""); + assert(static_cast(opt) == static_cast(opt2)); + assert(*opt == *opt2); + } + { + static_assert(!std::is_nothrow_move_assignable>::value, ""); + optional opt; + optional opt2(X{}); + assert(static_cast(opt2) == true); + try + { + X::throw_now = true; + opt = std::move(opt2); + assert(false); + } + catch (int i) + { + assert(i == 6); + assert(static_cast(opt) == false); + } + } + { + static_assert(std::is_nothrow_move_assignable>::value, ""); + } +} Index: test/std/utilities/optional/optional.object/optional.object.assign/nullopt_t.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.assign/nullopt_t.pass.cpp @@ -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& operator=(nullopt_t) noexcept; + +#include +#include +#include + +using std::optional; +using std::nullopt_t; +using std::nullopt; + +struct X +{ + static bool dtor_called; + ~X() {dtor_called = true;} +}; + +bool X::dtor_called = false; + +int main() +{ + { + optional opt; + static_assert(noexcept(opt = nullopt) == true, ""); + opt = nullopt; + assert(static_cast(opt) == false); + } + { + optional opt(3); + opt = nullopt; + assert(static_cast(opt) == false); + } + { + optional opt; + static_assert(noexcept(opt = nullopt) == true, ""); + assert(X::dtor_called == false); + opt = nullopt; + assert(X::dtor_called == false); + assert(static_cast(opt) == false); + } + assert(X::dtor_called == false); // TRANSITION, Clang/C2 VSO#239997 + { + X x; + optional opt(x); + assert(X::dtor_called == false); + opt = nullopt; + assert(X::dtor_called == true); + assert(static_cast(opt) == false); + } +} Index: test/std/utilities/optional/optional.object/optional.object.assign/optional_U.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.assign/optional_U.pass.cpp @@ -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 +// XFAIL: libcpp-no-exceptions +// + +// From LWG2451: +// template +// optional& operator=(optional&& rhs); + +#include +#include +#include + +using std::optional; + +struct X +{ + static bool throw_now; + + X() = default; + X(int &&) + { + if (throw_now) + 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; } +}; + +int main() +{ + { + optional opt; + optional opt2; + opt = std::move(opt2); + assert(static_cast(opt2) == false); + assert(static_cast(opt) == static_cast(opt2)); + } + { + optional opt; + optional opt2(short{2}); + opt = std::move(opt2); + assert(static_cast(opt2) == true); + assert(*opt2 == 2); + assert(static_cast(opt) == static_cast(opt2)); + assert(*opt == *opt2); + } + { + optional opt(3); + optional opt2; + opt = std::move(opt2); + assert(static_cast(opt2) == false); + assert(static_cast(opt) == static_cast(opt2)); + } + { + optional opt(3); + optional opt2(short{2}); + opt = std::move(opt2); + assert(static_cast(opt2) == true); + assert(*opt2 == 2); + assert(static_cast(opt) == static_cast(opt2)); + assert(*opt == *opt2); + } + { + optional opt; + optional opt2(42); + assert(static_cast(opt2) == true); + try + { + X::throw_now = true; + opt = std::move(opt2); + assert(false); + } + catch (int i) + { + assert(i == 6); + assert(static_cast(opt) == false); + } + } +} Index: test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp @@ -0,0 +1,114 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// constexpr optional(U&& u); + +#include +#include +#include + +using std::optional; + +class X +{ + int i_; +public: + X(int i) : i_(i) {} + + friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;} +}; + +class Y +{ + int i_; +public: + constexpr Y(int i) : i_(i) {} + + friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;} +}; + +struct Z +{ + Z(int) {throw 6;} +}; + +template +constexpr bool implicit_conversion(optional&& opt, const From& v) +{ + return opt && *opt == static_cast(v); +} + +int main() +{ + { + typedef int T; + typedef long long U; + constexpr T t(5); + static_assert(implicit_conversion(t, t), ""); + + struct test_constexpr_ctor + : public optional + { + constexpr test_constexpr_ctor(const T& t) + : optional(t) + {} + }; + } + { + typedef double T; + typedef long double U; + constexpr T t(3.14); + static_assert(implicit_conversion(t, t), ""); + + struct test_constexpr_ctor + : public optional + { + constexpr test_constexpr_ctor(const T& t) + : optional(t) + {} + }; + } + { + assert(implicit_conversion(3, 3)); + } + { + static_assert(implicit_conversion(3, 3), ""); + + struct test_constexpr_ctor + : public optional + { + constexpr test_constexpr_ctor(int i) + : optional(i) + {} + }; + + } + { + typedef Z T; + try + { + optional opt = 3; + (void)opt; + assert(false); + } + catch (int i) + { + assert(i == 6); + } + } + + static_assert(!(std::is_constructible, Y>::value), ""); + static_assert(!(std::is_constructible, const Y&>::value), ""); +} Index: test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp @@ -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 +// XFAIL: libcpp-no-exceptions + +// + +// constexpr optional(const T& v); + +#include +#include +#include + +using std::optional; + +class X +{ + int i_; +public: + X(int i) : i_(i) {} + + friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;} +}; + +class Y +{ + int i_; +public: + constexpr Y(int i) : i_(i) {} + + friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;} +}; + +class Z +{ +public: + Z(int) {} + Z(const Z&) {throw 6;} +}; + + +int main() +{ + { + typedef int T; + constexpr T t(5); + constexpr optional opt(t); + static_assert(static_cast(opt) == true, ""); + static_assert(*opt == 5, ""); + + struct test_constexpr_ctor + : public optional + { + constexpr test_constexpr_ctor(const T&) {} + }; + + } + { + typedef double T; + constexpr T t(3); + constexpr optional opt(t); + static_assert(static_cast(opt) == true, ""); + static_assert(*opt == 3, ""); + + struct test_constexpr_ctor + : public optional + { + constexpr test_constexpr_ctor(const T&) {} + }; + + } + { + typedef X T; + const T t(3); + optional opt(t); + assert(static_cast(opt) == true); + assert(*opt == 3); + } + { + typedef Y T; + constexpr T t(3); + constexpr optional opt(t); + static_assert(static_cast(opt) == true, ""); + static_assert(*opt == 3, ""); + + struct test_constexpr_ctor + : public optional + { + constexpr test_constexpr_ctor(const T&) {} + }; + + } + { + typedef Z T; + try + { + const T t(3); + optional opt(t); + assert(false); + } + catch (int i) + { + assert(i == 6); + } + } +} Index: test/std/utilities/optional/optional.object/optional.object.ctor/const_optional_U.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.ctor/const_optional_U.pass.cpp @@ -0,0 +1,125 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// + +// template +// optional(const optional& rhs); + +#include +#include +#include + +using std::optional; + +template +void +test(const optional& rhs, bool is_going_to_throw = false) +{ + bool rhs_engaged = static_cast(rhs); + try + { + optional lhs = rhs; + assert(is_going_to_throw == false); + assert(static_cast(lhs) == rhs_engaged); + if (rhs_engaged) + assert(*lhs == *rhs); + } + catch (int i) + { + assert(i == 6); + } +} + +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) {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 rhs; + test(rhs); + } + { + typedef short U; + typedef int T; + optional rhs(U{3}); + test(rhs); + } + { + typedef X T; + typedef int U; + optional rhs; + test(rhs); + } + { + typedef X T; + typedef int U; + optional rhs(U{3}); + test(rhs); + } + { + typedef Y T; + typedef int U; + optional rhs; + test(rhs); + } + { + typedef Y T; + typedef int U; + optional rhs(U{3}); + test(rhs); + } + { + typedef Z T; + typedef int U; + optional rhs; + test(rhs); + } + { + typedef Z T; + typedef int U; + optional rhs(U{3}); + test(rhs, true); + } + + static_assert(!(std::is_constructible, const optional&>::value), ""); +} Index: test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp @@ -0,0 +1,120 @@ +//===----------------------------------------------------------------------===// +// +// 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(const optional& rhs); + +#include +#include +#include + +using std::optional; + +template +void +test(const optional& rhs, bool is_going_to_throw = false) +{ + bool rhs_engaged = static_cast(rhs); + try + { + optional lhs = rhs; + assert(is_going_to_throw == false); + assert(static_cast(lhs) == rhs_engaged); + if (rhs_engaged) + assert(*lhs == *rhs); + } + catch (int i) + { + assert(i == 6); + } +} + +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) {} + Y(const Y& x) : i_(x.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) {} + Z(const Z&) + { + if (++count == 2) + throw 6; + } + + friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;} +}; + + +int main() +{ + { + typedef int T; + optional rhs; + test(rhs); + } + { + typedef int T; + optional rhs(3); + test(rhs); + } + { + typedef X T; + optional rhs; + test(rhs); + } + { + typedef X T; + optional rhs(X(3)); + test(rhs); + } + { + typedef Y T; + optional rhs; + test(rhs); + } + { + typedef Y T; + optional rhs(Y(3)); + test(rhs); + } + { + typedef Z T; + optional rhs; + test(rhs); + } + { + typedef Z T; + optional rhs(Z(3)); + test(rhs, true); + } +} Index: test/std/utilities/optional/optional.object/optional.object.ctor/default.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.ctor/default.pass.cpp @@ -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 +// + +// constexpr optional() noexcept; + +#include +#include +#include + +using std::optional; + +template +void +test_constexpr() +{ + static_assert(std::is_nothrow_default_constructible::value, ""); + constexpr Opt opt; + static_assert(static_cast(opt) == false, ""); + + struct test_constexpr_ctor + : public Opt + { + constexpr test_constexpr_ctor() {} + }; +} + +template +void +test() +{ + static_assert(std::is_nothrow_default_constructible::value, ""); + Opt opt; + assert(static_cast(opt) == false); + + struct test_constexpr_ctor + : public Opt + { + constexpr test_constexpr_ctor() {} + }; +} + +struct X +{ + X(); +}; + +int main() +{ + test_constexpr>(); + test_constexpr>(); + test>(); +} Index: test/std/utilities/optional/optional.object/optional.object.ctor/explicit_U.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.ctor/explicit_U.pass.cpp @@ -0,0 +1,87 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// explicit constexpr optional(U&& u); + +#include +#include +#include + +using std::optional; + +class X +{ + int i_; +public: + explicit X(int i) : i_(i) {} + + friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;} +}; + +class Y +{ + int i_; +public: + constexpr explicit Y(int i) : i_(i) {} + + friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;} +}; + +class Z +{ +public: + explicit Z(int) {throw 6;} +}; + + +int main() +{ + { + typedef X T; + static_assert(!(std::is_convertible>::value), ""); + optional opt(3); + assert(static_cast(opt) == true); + assert(*opt == T(3)); + } + { + typedef Y T; + static_assert(!(std::is_convertible>::value), ""); + constexpr optional opt(3); + static_assert(static_cast(opt) == true, ""); + static_assert(*opt == T(3), ""); + + struct test_constexpr_ctor + : public optional + { + constexpr test_constexpr_ctor(int i) + : optional(i) + {} + }; + + } + { + typedef Z T; + static_assert(!(std::is_convertible>::value), ""); + try + { + optional opt(3); + assert(false); + } + catch (int i) + { + assert(i == 6); + } + } +} Index: test/std/utilities/optional/optional.object/optional.object.ctor/explicit_const_optional_U.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.ctor/explicit_const_optional_U.pass.cpp @@ -0,0 +1,112 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// + +// template +// explicit optional(const optional& rhs); + +#include +#include +#include + +using std::optional; + +template +void +test(const optional& rhs, bool is_going_to_throw = false) +{ + bool rhs_engaged = static_cast(rhs); + try + { + static_assert(!(std::is_convertible&, optional>::value), ""); + optional lhs(rhs); + assert(is_going_to_throw == false); + assert(static_cast(lhs) == rhs_engaged); + if (rhs_engaged) + assert(*lhs == T(*rhs)); + } + catch (int i) + { + assert(i == 6); + } +} + +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) {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 rhs; + test(rhs); + } + { + typedef X T; + typedef int U; + optional rhs(3); + test(rhs); + } + { + typedef Y T; + typedef int U; + optional rhs; + test(rhs); + } + { + typedef Y T; + typedef int U; + optional rhs(3); + test(rhs); + } + { + typedef Z T; + typedef int U; + optional rhs; + test(rhs); + } + { + typedef Z T; + typedef int U; + optional rhs(3); + test(rhs, true); + } +} Index: test/std/utilities/optional/optional.object/optional.object.ctor/explicit_optional_U.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.ctor/explicit_optional_U.pass.cpp @@ -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 +// XFAIL: libcpp-no-exceptions +// + +// template +// explicit optional(optional&& rhs); + +#include +#include +#include + +using std::optional; + +template +void +test(optional&& rhs, bool is_going_to_throw = false) +{ + bool rhs_engaged = static_cast(rhs); + try + { + static_assert(!(std::is_convertible&&, optional>::value), ""); + optional lhs(std::move(rhs)); + assert(is_going_to_throw == false); + assert(static_cast(lhs) == rhs_engaged); + } + catch (int i) + { + assert(i == 6); + } +} + +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) { throw 6; } +}; + +int main() +{ + { + optional rhs; + test(std::move(rhs)); + } + { + optional rhs(3); + test(std::move(rhs)); + } + { + optional rhs; + test(std::move(rhs)); + } + { + optional rhs(3); + test(std::move(rhs), true); + } +} Index: test/std/utilities/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp @@ -0,0 +1,142 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// constexpr explicit optional(in_place_t, Args&&... args); + +#include +#include +#include + + +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) {throw 6;} +}; + + +int main() +{ + { + constexpr optional opt(in_place, 5); + static_assert(static_cast(opt) == true, ""); + static_assert(*opt == 5, ""); + + struct test_constexpr_ctor + : public optional + { + constexpr test_constexpr_ctor(in_place_t, int i) + : optional(in_place, i) {} + }; + + } + { + const optional opt(in_place); + assert(static_cast(opt) == true); + assert(*opt == X()); + } + { + const optional opt(in_place, 5); + assert(static_cast(opt) == true); + assert(*opt == X(5)); + } + { + const optional opt(in_place, 5, 4); + assert(static_cast(opt) == true); + assert(*opt == X(5, 4)); + } + { + constexpr optional opt(in_place); + static_assert(static_cast(opt) == true, ""); + static_assert(*opt == Y(), ""); + + struct test_constexpr_ctor + : public optional + { + constexpr test_constexpr_ctor(in_place_t) + : optional(in_place) {} + }; + + } + { + constexpr optional opt(in_place, 5); + static_assert(static_cast(opt) == true, ""); + static_assert(*opt == Y(5), ""); + + struct test_constexpr_ctor + : public optional + { + constexpr test_constexpr_ctor(in_place_t, int i) + : optional(in_place, i) {} + }; + + } + { + constexpr optional opt(in_place, 5, 4); + static_assert(static_cast(opt) == true, ""); + static_assert(*opt == Y(5, 4), ""); + + struct test_constexpr_ctor + : public optional + { + constexpr test_constexpr_ctor(in_place_t, int i, int j) + : optional(in_place, i, j) {} + }; + + } + { + try + { + const optional opt(in_place, 1); + assert(false); + } + catch (int i) + { + assert(i == 6); + } + } +} Index: test/std/utilities/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp @@ -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 +// XFAIL: libcpp-no-exceptions +// + +// template +// constexpr +// explicit optional(in_place_t, initializer_list il, Args&&... args); + +#include +#include +#include +#include + +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 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 il) : i_(il.begin()[0]), j_(il.begin()[1]) + {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&>::value, ""); + static_assert(!std::is_constructible, std::initializer_list&>::value, ""); + } + { + optional> opt(in_place, {3, 1}); + assert(static_cast(opt) == true); + assert((*opt == std::vector{3, 1})); + assert(opt->size() == 2); + } + { + optional> opt(in_place, {3, 1}, std::allocator()); + assert(static_cast(opt) == true); + assert((*opt == std::vector{3, 1})); + assert(opt->size() == 2); + } + { + static_assert(std::is_constructible, std::initializer_list&>::value, ""); + constexpr optional opt(in_place, {3, 1}); + static_assert(static_cast(opt) == true, ""); + static_assert(*opt == Y{3, 1}, ""); + + struct test_constexpr_ctor + : public optional + { + constexpr test_constexpr_ctor(in_place_t, std::initializer_list i) + : optional(in_place, i) {} + }; + + } + { + static_assert(std::is_constructible, std::initializer_list&>::value, ""); + try + { + optional opt(in_place, {3, 1}); + assert(false); + } + catch (int i) + { + assert(i == 6); + } + } +} Index: test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp @@ -0,0 +1,119 @@ +//===----------------------------------------------------------------------===// +// +// 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&& rhs) noexcept(is_nothrow_move_constructible::value); + +#include +#include +#include + +using std::optional; + +template +void +test(optional& rhs, bool is_going_to_throw = false) +{ + static_assert(std::is_nothrow_move_constructible>::value == + std::is_nothrow_move_constructible::value, ""); + bool rhs_engaged = static_cast(rhs); + try + { + optional lhs = std::move(rhs); + assert(is_going_to_throw == false); + assert(static_cast(lhs) == rhs_engaged); + } + catch (int i) + { + assert(i == 6); + } +} + +class X +{ + int i_; +public: + X(int i) : i_(i) {} + X(X&& x) : i_(x.i_) {x.i_ = 0;} + ~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) {} + Y(Y&& x) noexcept : i_(x.i_) {x.i_ = 0;} + + 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) {} + Z(Z&&) + { + if (++count == 2) + throw 6; + } + + friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;} +}; + +int main() +{ + { + typedef int T; + optional rhs; + test(rhs); + } + { + typedef int T; + optional rhs(3); + test(rhs); + } + { + typedef X T; + optional rhs; + test(rhs); + } + { + typedef X T; + optional rhs(X(3)); + test(rhs); + } + { + typedef Y T; + optional rhs; + test(rhs); + } + { + typedef Y T; + optional rhs(Y(3)); + test(rhs); + } + { + typedef Z T; + optional rhs; + test(rhs); + } + { + typedef Z T; + optional rhs(Z(3)); + test(rhs, true); + } +} Index: test/std/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// + +// constexpr optional(nullopt_t) noexcept; + +#include +#include +#include + +using std::optional; +using std::nullopt_t; +using std::nullopt; + +template +void +test_constexpr() +{ + static_assert(noexcept(Opt(nullopt)), ""); + constexpr Opt opt(nullopt); + static_assert(static_cast(opt) == false, ""); + + struct test_constexpr_ctor + : public Opt + { + constexpr test_constexpr_ctor() {} + }; +} + +template +void +test() +{ + static_assert(noexcept(Opt(nullopt)), ""); + Opt opt(nullopt); + assert(static_cast(opt) == false); + + struct test_constexpr_ctor + : public Opt + { + constexpr test_constexpr_ctor() {} + }; +} + +struct X +{ + X(); +}; + +int main() +{ + test_constexpr>(); + test_constexpr>(); + test>(); +} Index: test/std/utilities/optional/optional.object/optional.object.ctor/optional_U.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.ctor/optional_U.pass.cpp @@ -0,0 +1,85 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// + +// template +// optional(optional&& rhs); + +#include +#include +#include + +using std::optional; + +template +void +test(optional&& rhs, bool is_going_to_throw = false) +{ + bool rhs_engaged = static_cast(rhs); + try + { + optional lhs = std::move(rhs); + assert(is_going_to_throw == false); + assert(static_cast(lhs) == rhs_engaged); + } + catch (int i) + { + assert(i == 6); + } +} + +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) { throw 6; } +}; + +int main() +{ + { + optional rhs; + test(std::move(rhs)); + } + { + optional rhs(short{3}); + test(std::move(rhs)); + } + { + optional rhs; + test(std::move(rhs)); + } + { + optional rhs(3); + test(std::move(rhs)); + } + { + optional rhs; + test(std::move(rhs)); + } + { + optional rhs(3); + test(std::move(rhs), true); + } + + static_assert(!(std::is_constructible, optional>::value), ""); +} Index: test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp @@ -0,0 +1,107 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// constexpr optional(T&& v); + +#include +#include +#include + +using std::optional; + +class X +{ + int i_; +public: + X(int i) : i_(i) {} + X(X&& x) : i_(x.i_) {} + + friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;} +}; + +class Y +{ + int i_; +public: + constexpr Y(int i) : i_(i) {} + constexpr Y(Y&& x) : i_(x.i_) {} + + friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;} +}; + +class Z +{ +public: + Z(int) {} + Z(Z&&) {throw 6;} +}; + + +int main() +{ + { + typedef int T; + constexpr optional opt(T(5)); + static_assert(static_cast(opt) == true, ""); + static_assert(*opt == 5, ""); + + struct test_constexpr_ctor + : public optional + { + constexpr test_constexpr_ctor(T&&) {} + }; + } + { + typedef double T; + constexpr optional opt(T(3)); + static_assert(static_cast(opt) == true, ""); + static_assert(*opt == 3, ""); + + struct test_constexpr_ctor + : public optional + { + constexpr test_constexpr_ctor(T&&) {} + }; + } + { + typedef X T; + optional opt(T(3)); + assert(static_cast(opt) == true); + assert(*opt == 3); + } + { + typedef Y T; + constexpr optional opt(T(3)); + static_assert(static_cast(opt) == true, ""); + static_assert(*opt == 3, ""); + + struct test_constexpr_ctor + : public optional + { + constexpr test_constexpr_ctor(T&&) {} + }; + } + { + typedef Z T; + try + { + optional opt(T(3)); + assert(false); + } + catch (int i) + { + assert(i == 6); + } + } +} Index: test/std/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// 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 +#include +#include + +using std::optional; + +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::value, ""); + static_assert(std::is_trivially_destructible>::value, ""); + } + { + typedef double T; + static_assert(std::is_trivially_destructible::value, ""); + static_assert(std::is_trivially_destructible>::value, ""); + } + { + typedef X T; + static_assert(!std::is_trivially_destructible::value, ""); + static_assert(!std::is_trivially_destructible>::value, ""); + { + X x; + optional opt{x}; + assert(X::dtor_called == false); + } + assert(X::dtor_called == true); + } +} Index: test/std/utilities/optional/optional.object/optional.object.mod/reset.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.mod/reset.pass.cpp @@ -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 + +// + +// void reset() noexcept; + +#include +#include +#include + +using std::optional; + +struct X +{ + static bool dtor_called; + ~X() {dtor_called = true;} +}; + +bool X::dtor_called = false; + +int main() +{ + { + optional opt; + static_assert(noexcept(opt.reset()) == true, ""); + opt.reset(); + assert(static_cast(opt) == false); + } + { + optional opt(3); + opt.reset(); + assert(static_cast(opt) == false); + } + { + optional opt; + static_assert(noexcept(opt.reset()) == true, ""); + assert(X::dtor_called == false); + opt.reset(); + assert(X::dtor_called == false); + assert(static_cast(opt) == false); + } + assert(X::dtor_called == false); // TRANSITION, Clang/C2 VSO#239997 + { + X x; + optional opt(x); + assert(X::dtor_called == false); + opt.reset(); + assert(X::dtor_called == true); + assert(static_cast(opt) == false); + } +} Index: test/std/utilities/optional/optional.object/optional.object.observe/bool.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.observe/bool.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// + +// constexpr explicit optional::operator bool() const noexcept; + +#include +#include +#include + +int main() +{ + using std::optional; + + { + constexpr optional opt; + static_assert(!opt, ""); + } + { + constexpr optional opt(0); + static_assert(opt, ""); + } +} Index: test/std/utilities/optional/optional.object/optional.object.observe/dereference.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.observe/dereference.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// + +// constexpr T& optional::operator*() &; + +#ifdef _LIBCPP_DEBUG +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + +#include +#include +#include + +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;} +}; + +#if __cplusplus >= 201402 +struct Y +{ + constexpr int test() {return 7;} +}; + +constexpr int +test() +{ + optional opt{Y{}}; + return (*opt).test(); +} +#endif + +int main() +{ + { + optional opt(X{}); + assert((*opt).test() == 4); + } +#if __cplusplus >= 201402 + static_assert(test() == 7, ""); +#endif +#ifdef _LIBCPP_DEBUG + { + optional opt; + assert((*opt).test() == 3); + assert(false); + } +#endif // _LIBCPP_DEBUG +} Index: test/std/utilities/optional/optional.object/optional.object.observe/dereference_const.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.observe/dereference_const.pass.cpp @@ -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 +// + +// constexpr const T& optional::operator*() const &; + +#ifdef _LIBCPP_DEBUG +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + +#include +#include +#include + +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() +{ + { + constexpr optional opt(X{}); + static_assert((*opt).test() == 3, ""); + } + { + constexpr optional opt(Y{}); + assert((*opt).test() == 2); + } +#ifdef _LIBCPP_DEBUG + { + const optional opt; + assert((*opt).test() == 3); + assert(false); + } +#endif // _LIBCPP_DEBUG +} Index: test/std/utilities/optional/optional.object/optional.object.observe/dereference_const_rvalue.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.observe/dereference_const_rvalue.pass.cpp @@ -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 +// + +// constexpr T&& optional::operator*() const &&; + +#ifdef _LIBCPP_DEBUG +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + +#include +#include +#include + +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() +{ + { + constexpr optional opt(X{}); + static_assert((*std::move(opt)).test() == 5, ""); + } + { + constexpr optional opt(Y{}); + assert((*std::move(opt)).test() == 2); + } +#ifdef _LIBCPP_DEBUG + { + optional opt; + assert((*std::move(opt)).test() == 5); + assert(false); + } +#endif // _LIBCPP_DEBUG +} Index: test/std/utilities/optional/optional.object/optional.object.observe/dereference_rvalue.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.observe/dereference_rvalue.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// + +// constexpr T&& optional::operator*() &&; + +#ifdef _LIBCPP_DEBUG +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + +#include +#include +#include + +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;} +}; + +#if __cplusplus >= 201402 +struct Y +{ + constexpr int test() && {return 7;} +}; + +constexpr int +test() +{ + optional opt{Y{}}; + return (*std::move(opt)).test(); +} +#endif + +int main() +{ + { + optional opt(X{}); + assert((*std::move(opt)).test() == 6); + } +#if __cplusplus >= 201402 + static_assert(test() == 7, ""); +#endif +#ifdef _LIBCPP_DEBUG + { + optional opt; + assert((*std::move(opt)).test() == 3); + assert(false); + } +#endif // _LIBCPP_DEBUG +} Index: test/std/utilities/optional/optional.object/optional.object.observe/has_value.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.observe/has_value.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// + +// constexpr bool optional::has_value() const noexcept; + +#include +#include +#include + +int main() +{ + using std::optional; + + { + constexpr optional opt; + static_assert(!opt.has_value(), ""); + } + { + constexpr optional opt(0); + static_assert(opt.has_value(), ""); + } +} Index: test/std/utilities/optional/optional.object/optional.object.observe/op_arrow.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.observe/op_arrow.pass.cpp @@ -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 +// + +// constexpr T* optional::operator->(); + +#ifdef _LIBCPP_DEBUG +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + +#include +#include +#include + +using std::optional; + +struct X +{ + int test() {return 3;} +}; + +#if __cplusplus >= 201402 +struct Y +{ + constexpr int test() {return 3;} +}; + +constexpr int +test() +{ + optional opt{Y{}}; + return opt->test(); +} +#endif + +int main() +{ + { + optional opt(X{}); + assert(opt->test() == 3); + } +#if __cplusplus >= 201402 + static_assert(test() == 3, ""); +#endif +#ifdef _LIBCPP_DEBUG + { + optional opt; + assert(opt->test() == 3); + assert(false); + } +#endif // _LIBCPP_DEBUG +} Index: test/std/utilities/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// + +// constexpr const T* optional::operator->() const; + +#ifdef _LIBCPP_DEBUG +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + +#include +#include +#include + +using std::optional; + +struct X +{ + constexpr int test() const {return 3;} +}; + +struct Y +{ + int test() const {return 2;} +}; + +struct Z +{ + const Z* operator&() const; + constexpr int test() const {return 1;} +}; + +int main() +{ + { + constexpr optional opt(X{}); + static_assert(opt->test() == 3, ""); + } + { + constexpr optional opt(Y{}); + assert(opt->test() == 2); + } + { + constexpr optional opt(Z{}); + static_assert(opt->test() == 1, ""); + } +#ifdef _LIBCPP_DEBUG + { + const optional opt; + assert(opt->test() == 3); + assert(false); + } +#endif // _LIBCPP_DEBUG +} Index: test/std/utilities/optional/optional.object/optional.object.observe/value.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.observe/value.pass.cpp @@ -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 +// XFAIL: libcpp-no-exceptions +// + +// constexpr T& optional::value() &; + +#include +#include +#include + +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;} +}; + +#if __cplusplus >= 201402 +struct Y +{ + constexpr int test() & {return 7;} +}; + +constexpr int +test() +{ + optional opt{Y{}}; + return opt.value().test(); +} +#endif + +int main() +{ + { + optional opt; + opt.emplace(); + assert(opt.value().test() == 4); + } + { + optional opt; + try + { + opt.value(); + assert(false); + } + catch (const bad_optional_access&) + { + } + } +#if __cplusplus >= 201402 + static_assert(test() == 7, ""); +#endif +} Index: test/std/utilities/optional/optional.object/optional.object.observe/value_const.fail.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.observe/value_const.fail.cpp @@ -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 +// + +// constexpr const T& optional::value() const &; + +#include +#include +#include + +using std::optional; + +struct X +{ + constexpr int test() const {return 3;} + int test() {return 4;} +}; + +int main() +{ + { + constexpr optional opt; + static_assert(opt.value().test() == 3, ""); + } +} Index: test/std/utilities/optional/optional.object/optional.object.observe/value_const.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.observe/value_const.pass.cpp @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// + +// constexpr const T& optional::value() const &; + +#include +#include +#include + +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() +{ + { + constexpr optional opt(in_place); + static_assert(opt.value().test() == 3, ""); + } + { + const optional opt(in_place); + assert(opt.value().test() == 3); + } + { + const optional opt; + try + { + opt.value(); + assert(false); + } + catch (const bad_optional_access&) + { + } + } +} Index: test/std/utilities/optional/optional.object/optional.object.observe/value_const_rvalue.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.observe/value_const_rvalue.pass.cpp @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// + +// constexpr const T& optional::value() const &&; + +#include +#include +#include + +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() +{ + { + constexpr optional opt(in_place); + static_assert(std::move(opt).value().test() == 5, ""); + } + { + const optional opt(in_place); + assert(std::move(opt).value().test() == 5); + } + { + const optional opt; + try + { + std::move(opt).value(); + assert(false); + } + catch (const bad_optional_access&) + { + } + } +} Index: test/std/utilities/optional/optional.object/optional.object.observe/value_or.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.observe/value_or.pass.cpp @@ -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 +// + +// template T optional::value_or(U&& v) &&; + +#include +#include +#include + +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 opt(in_place, 2); + Y y(3); + assert(std::move(opt).value_or(y) == 2); + assert(*opt == 0); + } + { + optional opt(in_place, 2); + assert(std::move(opt).value_or(Y(3)) == 2); + assert(*opt == 0); + } + { + optional opt; + Y y(3); + assert(std::move(opt).value_or(y) == 3); + assert(!opt); + } + { + optional opt; + assert(std::move(opt).value_or(Y(3)) == 4); + assert(!opt); + } +} Index: test/std/utilities/optional/optional.object/optional.object.observe/value_or_const.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.observe/value_or_const.pass.cpp @@ -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 +// + +// template constexpr T optional::value_or(U&& v) const&; + +#include +#include +#include + +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 opt(2); + constexpr Y y(3); + static_assert(opt.value_or(y) == 2, ""); + } + { + constexpr optional opt(2); + static_assert(opt.value_or(Y(3)) == 2, ""); + } + { + constexpr optional opt; + constexpr Y y(3); + static_assert(opt.value_or(y) == 3, ""); + } + { + constexpr optional opt; + static_assert(opt.value_or(Y(3)) == 4, ""); + } + { + const optional opt(2); + const Y y(3); + assert(opt.value_or(y) == 2); + } + { + const optional opt(2); + assert(opt.value_or(Y(3)) == 2); + } + { + const optional opt; + const Y y(3); + assert(opt.value_or(y) == 3); + } + { + const optional opt; + assert(opt.value_or(Y(3)) == 4); + } +} Index: test/std/utilities/optional/optional.object/optional.object.observe/value_rvalue.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.observe/value_rvalue.pass.cpp @@ -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 +// XFAIL: libcpp-no-exceptions +// + +// constexpr T& optional::value() &&; + +#include +#include +#include + +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;} +}; + +#if __cplusplus >= 201402 +struct Y +{ + constexpr int test() && {return 7;} +}; + +constexpr int +test() +{ + optional opt{Y{}}; + return std::move(opt).value().test(); +} +#endif + +int main() +{ + { + optional opt; + opt.emplace(); + assert(std::move(opt).value().test() == 6); + } + { + optional opt; + try + { + std::move(opt).value(); + assert(false); + } + catch (const bad_optional_access&) + { + } + } +#if __cplusplus >= 201402 + static_assert(test() == 7, ""); +#endif +} Index: test/std/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp @@ -0,0 +1,301 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// + +// void swap(optional&) +// noexcept(is_nothrow_move_constructible::value && +// is_nothrow_swappable::value) + +#include +#include +#include + +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&&) {throw 7;} + + friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;} + friend void swap(Z& x, Z& y) {throw 6;} +}; + +int main() +{ + { + optional opt1; + optional opt2; + static_assert(noexcept(opt1.swap(opt2)) == true, ""); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == false); + opt1.swap(opt2); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == false); + } + { + optional opt1(1); + optional opt2; + static_assert(noexcept(opt1.swap(opt2)) == true, ""); + assert(static_cast(opt1) == true); + assert(*opt1 == 1); + assert(static_cast(opt2) == false); + opt1.swap(opt2); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == true); + assert(*opt2 == 1); + } + { + optional opt1; + optional opt2(2); + static_assert(noexcept(opt1.swap(opt2)) == true, ""); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == true); + assert(*opt2 == 2); + opt1.swap(opt2); + assert(static_cast(opt1) == true); + assert(*opt1 == 2); + assert(static_cast(opt2) == false); + } + { + optional opt1(1); + optional opt2(2); + static_assert(noexcept(opt1.swap(opt2)) == true, ""); + assert(static_cast(opt1) == true); + assert(*opt1 == 1); + assert(static_cast(opt2) == true); + assert(*opt2 == 2); + opt1.swap(opt2); + assert(static_cast(opt1) == true); + assert(*opt1 == 2); + assert(static_cast(opt2) == true); + assert(*opt2 == 1); + } + { + optional opt1; + optional opt2; + static_assert(noexcept(opt1.swap(opt2)) == true, ""); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == false); + opt1.swap(opt2); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == false); + assert(X::dtor_called == 0); + } + { + optional opt1(1); + optional opt2; + static_assert(noexcept(opt1.swap(opt2)) == true, ""); + assert(static_cast(opt1) == true); + assert(*opt1 == 1); + assert(static_cast(opt2) == false); + X::dtor_called = 0; + opt1.swap(opt2); + assert(X::dtor_called == 1); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == true); + assert(*opt2 == 1); + } + { + optional opt1; + optional opt2(2); + static_assert(noexcept(opt1.swap(opt2)) == true, ""); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == true); + assert(*opt2 == 2); + X::dtor_called = 0; + opt1.swap(opt2); + assert(X::dtor_called == 1); + assert(static_cast(opt1) == true); + assert(*opt1 == 2); + assert(static_cast(opt2) == false); + } + { + optional opt1(1); + optional opt2(2); + static_assert(noexcept(opt1.swap(opt2)) == true, ""); + assert(static_cast(opt1) == true); + assert(*opt1 == 1); + assert(static_cast(opt2) == true); + assert(*opt2 == 2); + X::dtor_called = 0; + opt1.swap(opt2); + assert(X::dtor_called == 1); // from inside std::swap + assert(static_cast(opt1) == true); + assert(*opt1 == 2); + assert(static_cast(opt2) == true); + assert(*opt2 == 1); + } + { + optional opt1; + optional opt2; + static_assert(noexcept(opt1.swap(opt2)) == false, ""); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == false); + opt1.swap(opt2); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == false); + assert(Y::dtor_called == 0); + } + { + optional opt1(1); + optional opt2; + static_assert(noexcept(opt1.swap(opt2)) == false, ""); + assert(static_cast(opt1) == true); + assert(*opt1 == 1); + assert(static_cast(opt2) == false); + Y::dtor_called = 0; + opt1.swap(opt2); + assert(Y::dtor_called == 1); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == true); + assert(*opt2 == 1); + } + { + optional opt1; + optional opt2(2); + static_assert(noexcept(opt1.swap(opt2)) == false, ""); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == true); + assert(*opt2 == 2); + Y::dtor_called = 0; + opt1.swap(opt2); + assert(Y::dtor_called == 1); + assert(static_cast(opt1) == true); + assert(*opt1 == 2); + assert(static_cast(opt2) == false); + } + { + optional opt1(1); + optional opt2(2); + static_assert(noexcept(opt1.swap(opt2)) == false, ""); + assert(static_cast(opt1) == true); + assert(*opt1 == 1); + assert(static_cast(opt2) == true); + assert(*opt2 == 2); + Y::dtor_called = 0; + opt1.swap(opt2); + assert(Y::dtor_called == 0); + assert(static_cast(opt1) == true); + assert(*opt1 == 2); + assert(static_cast(opt2) == true); + assert(*opt2 == 1); + } + { + optional opt1; + optional opt2; + static_assert(noexcept(opt1.swap(opt2)) == false, ""); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == false); + opt1.swap(opt2); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == false); + } + { + optional opt1; + opt1.emplace(1); + optional opt2; + static_assert(noexcept(opt1.swap(opt2)) == false, ""); + assert(static_cast(opt1) == true); + assert(*opt1 == 1); + assert(static_cast(opt2) == false); + try + { + opt1.swap(opt2); + assert(false); + } + catch (int i) + { + assert(i == 7); + } + assert(static_cast(opt1) == true); + assert(*opt1 == 1); + assert(static_cast(opt2) == false); + } + { + optional opt1; + optional opt2; + opt2.emplace(2); + static_assert(noexcept(opt1.swap(opt2)) == false, ""); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == true); + assert(*opt2 == 2); + try + { + opt1.swap(opt2); + assert(false); + } + catch (int i) + { + assert(i == 7); + } + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == true); + assert(*opt2 == 2); + } + { + optional opt1; + opt1.emplace(1); + optional opt2; + opt2.emplace(2); + static_assert(noexcept(opt1.swap(opt2)) == false, ""); + assert(static_cast(opt1) == true); + assert(*opt1 == 1); + assert(static_cast(opt2) == true); + assert(*opt2 == 2); + try + { + opt1.swap(opt2); + assert(false); + } + catch (int i) + { + assert(i == 6); + } + assert(static_cast(opt1) == true); + assert(*opt1 == 1); + assert(static_cast(opt2) == true); + assert(*opt2 == 2); + } +} Index: test/std/utilities/optional/optional.object/optional_const_void.fail.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional_const_void.fail.cpp @@ -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 +// + +// T shall be an object type and shall satisfy the requirements of Destructible + +#include + +int main() +{ + using std::optional; + + optional opt; +} Index: test/std/utilities/optional/optional.object/optional_not_destructible.fail.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional_not_destructible.fail.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// + +// T shall be an object type and shall satisfy the requirements of Destructible + +#include + +using std::optional; + +struct X +{ +private: + ~X() {} +}; + +int main() +{ + optional opt; +} Index: test/std/utilities/optional/optional.object/optional_not_noexcept_destructible.fail.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional_not_noexcept_destructible.fail.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// + +// T shall be an object type and shall satisfy the requirements of Destructible + +#include + +using std::optional; + +struct X +{ + ~X() noexcept(false) {} +}; + +int main() +{ + optional opt; +} Index: test/std/utilities/optional/optional.object/optional_void.fail.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/optional_void.fail.cpp @@ -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 +// + +// T shall be an object type and shall satisfy the requirements of Destructible + +#include + +int main() +{ + using std::optional; + + optional opt; +} Index: test/std/utilities/optional/optional.object/types.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.object/types.pass.cpp @@ -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 +// + +// template +// class optional +// { +// public: +// typedef T value_type; +// ... + +#include +#include + +using std::optional; + +template +void +test() +{ + static_assert(std::is_same::value, ""); +} + +int main() +{ + test, int>(); + test, const int>(); + test, double>(); + test, const double>(); +} Index: test/std/utilities/optional/optional.relops/equal.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.relops/equal.pass.cpp @@ -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 +// + +// template constexpr bool operator==(const optional& x, const optional& y); + +#include +#include +#include + +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 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 , "" ); + + } +} Index: test/std/utilities/optional/optional.relops/greater_equal.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.relops/greater_equal.pass.cpp @@ -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 +// + +// template constexpr bool operator>= (const optional& x, const optional& y); + +#include + +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 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), "" ); + } +} Index: test/std/utilities/optional/optional.relops/greater_than.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.relops/greater_than.pass.cpp @@ -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 +// + +// template constexpr bool operator> (const optional& x, const optional& y); + +#include + +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 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), "" ); + } +} Index: test/std/utilities/optional/optional.relops/less_equal.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.relops/less_equal.pass.cpp @@ -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 +// + +// template constexpr bool operator<= (const optional& x, const optional& y); + +#include + +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 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), "" ); + } +} Index: test/std/utilities/optional/optional.relops/less_than.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.relops/less_than.pass.cpp @@ -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 +// + +// template constexpr bool operator< (const optional& x, const optional& y); + +#include + +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 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), "" ); + } +} Index: test/std/utilities/optional/optional.relops/not_equal.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.relops/not_equal.pass.cpp @@ -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 +// + +// template constexpr bool operator!=(const optional& x, const optional& y); + +#include +#include +#include + +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 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), "" ); + + } +} Index: test/std/utilities/optional/optional.specalg/make_optional.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.specalg/make_optional.pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// + +// template +// constexpr optional> make_optional(T&& v); + +#include +#include +#include +#include + +int main() +{ + using std::optional; + using std::make_optional; + + { + optional opt = make_optional(2); + assert(*opt == 2); + } + { + std::string s("123"); + optional opt = make_optional(s); + assert(*opt == s); + } + { + std::unique_ptr s(new int(3)); + optional> opt = make_optional(std::move(s)); + assert(**opt == 3); + assert(s == nullptr); + } +} Index: test/std/utilities/optional/optional.specalg/make_optional_explicit.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.specalg/make_optional_explicit.pass.cpp @@ -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 +// + +// template +// constexpr optional make_optional(Args&&... args); + +#include +#include +#include +#include + +int main() +{ + using std::optional; + using std::make_optional; + + { + auto opt = make_optional(2); + assert(*opt == 2); + } + { + std::string s("123"); + auto opt = make_optional(s); + assert(*opt == s); + } + { + std::unique_ptr s(new int(3)); + auto opt = make_optional>(std::move(s)); + assert(**opt == 3); + assert(s == nullptr); + } + { + auto opt = make_optional(4, 'X'); + assert(*opt == "XXXX"); + } +} Index: test/std/utilities/optional/optional.specalg/make_optional_explicit_initializer_list.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.specalg/make_optional_explicit_initializer_list.pass.cpp @@ -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 +// + +// template +// constexpr optional make_optional(initializer_list il, Args&&... args); + +#include +#include +#include +#include + +int main() +{ + using std::make_optional; + + { + auto opt = make_optional({'1', '2', '3'}); + assert(*opt == "123"); + } + { + auto opt = make_optional({'a', 'b', 'c'}, std::allocator{}); + assert(*opt == "abc"); + } +} Index: test/std/utilities/optional/optional.specalg/swap.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.specalg/swap.pass.cpp @@ -0,0 +1,300 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// + +// template void swap(optional& x, optional& y) +// noexcept(noexcept(x.swap(y))); + +#include +#include +#include + +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&&) {throw 7;} + + friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;} + friend void swap(Z& x, Z& y) {throw 6;} +}; + +int main() +{ + { + optional opt1; + optional opt2; + static_assert(noexcept(swap(opt1, opt2)) == true, ""); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == false); + swap(opt1, opt2); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == false); + } + { + optional opt1(1); + optional opt2; + static_assert(noexcept(swap(opt1, opt2)) == true, ""); + assert(static_cast(opt1) == true); + assert(*opt1 == 1); + assert(static_cast(opt2) == false); + swap(opt1, opt2); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == true); + assert(*opt2 == 1); + } + { + optional opt1; + optional opt2(2); + static_assert(noexcept(swap(opt1, opt2)) == true, ""); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == true); + assert(*opt2 == 2); + swap(opt1, opt2); + assert(static_cast(opt1) == true); + assert(*opt1 == 2); + assert(static_cast(opt2) == false); + } + { + optional opt1(1); + optional opt2(2); + static_assert(noexcept(swap(opt1, opt2)) == true, ""); + assert(static_cast(opt1) == true); + assert(*opt1 == 1); + assert(static_cast(opt2) == true); + assert(*opt2 == 2); + swap(opt1, opt2); + assert(static_cast(opt1) == true); + assert(*opt1 == 2); + assert(static_cast(opt2) == true); + assert(*opt2 == 1); + } + { + optional opt1; + optional opt2; + static_assert(noexcept(swap(opt1, opt2)) == true, ""); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == false); + swap(opt1, opt2); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == false); + assert(X::dtor_called == 0); + } + { + optional opt1(1); + optional opt2; + static_assert(noexcept(swap(opt1, opt2)) == true, ""); + assert(static_cast(opt1) == true); + assert(*opt1 == 1); + assert(static_cast(opt2) == false); + X::dtor_called = 0; + swap(opt1, opt2); + assert(X::dtor_called == 1); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == true); + assert(*opt2 == 1); + } + { + optional opt1; + optional opt2(2); + static_assert(noexcept(swap(opt1, opt2)) == true, ""); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == true); + assert(*opt2 == 2); + X::dtor_called = 0; + swap(opt1, opt2); + assert(X::dtor_called == 1); + assert(static_cast(opt1) == true); + assert(*opt1 == 2); + assert(static_cast(opt2) == false); + } + { + optional opt1(1); + optional opt2(2); + static_assert(noexcept(swap(opt1, opt2)) == true, ""); + assert(static_cast(opt1) == true); + assert(*opt1 == 1); + assert(static_cast(opt2) == true); + assert(*opt2 == 2); + X::dtor_called = 0; + swap(opt1, opt2); + assert(X::dtor_called == 1); // from inside std::swap + assert(static_cast(opt1) == true); + assert(*opt1 == 2); + assert(static_cast(opt2) == true); + assert(*opt2 == 1); + } + { + optional opt1; + optional opt2; + static_assert(noexcept(swap(opt1, opt2)) == false, ""); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == false); + swap(opt1, opt2); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == false); + assert(Y::dtor_called == 0); + } + { + optional opt1(1); + optional opt2; + static_assert(noexcept(swap(opt1, opt2)) == false, ""); + assert(static_cast(opt1) == true); + assert(*opt1 == 1); + assert(static_cast(opt2) == false); + Y::dtor_called = 0; + swap(opt1, opt2); + assert(Y::dtor_called == 1); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == true); + assert(*opt2 == 1); + } + { + optional opt1; + optional opt2(2); + static_assert(noexcept(swap(opt1, opt2)) == false, ""); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == true); + assert(*opt2 == 2); + Y::dtor_called = 0; + swap(opt1, opt2); + assert(Y::dtor_called == 1); + assert(static_cast(opt1) == true); + assert(*opt1 == 2); + assert(static_cast(opt2) == false); + } + { + optional opt1(1); + optional opt2(2); + static_assert(noexcept(swap(opt1, opt2)) == false, ""); + assert(static_cast(opt1) == true); + assert(*opt1 == 1); + assert(static_cast(opt2) == true); + assert(*opt2 == 2); + Y::dtor_called = 0; + swap(opt1, opt2); + assert(Y::dtor_called == 0); + assert(static_cast(opt1) == true); + assert(*opt1 == 2); + assert(static_cast(opt2) == true); + assert(*opt2 == 1); + } + { + optional opt1; + optional opt2; + static_assert(noexcept(swap(opt1, opt2)) == false, ""); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == false); + swap(opt1, opt2); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == false); + } + { + optional opt1; + opt1.emplace(1); + optional opt2; + static_assert(noexcept(swap(opt1, opt2)) == false, ""); + assert(static_cast(opt1) == true); + assert(*opt1 == 1); + assert(static_cast(opt2) == false); + try + { + swap(opt1, opt2); + assert(false); + } + catch (int i) + { + assert(i == 7); + } + assert(static_cast(opt1) == true); + assert(*opt1 == 1); + assert(static_cast(opt2) == false); + } + { + optional opt1; + optional opt2; + opt2.emplace(2); + static_assert(noexcept(swap(opt1, opt2)) == false, ""); + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == true); + assert(*opt2 == 2); + try + { + swap(opt1, opt2); + assert(false); + } + catch (int i) + { + assert(i == 7); + } + assert(static_cast(opt1) == false); + assert(static_cast(opt2) == true); + assert(*opt2 == 2); + } + { + optional opt1; + opt1.emplace(1); + optional opt2; + opt2.emplace(2); + static_assert(noexcept(swap(opt1, opt2)) == false, ""); + assert(static_cast(opt1) == true); + assert(*opt1 == 1); + assert(static_cast(opt2) == true); + assert(*opt2 == 2); + try + { + swap(opt1, opt2); + assert(false); + } + catch (int i) + { + assert(i == 6); + } + assert(static_cast(opt1) == true); + assert(*opt1 == 1); + assert(static_cast(opt2) == true); + assert(*opt2 == 2); + } +} Index: test/std/utilities/optional/optional.syn/optional_const_in_place_t.fail.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.syn/optional_const_in_place_t.fail.cpp @@ -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 +// + +// A program that necessitates the instantiation of template optional for +// (possibly cv-qualified) in_place_t is ill-formed. + +#include + +int main() +{ + using std::optional; + using std::in_place_t; + using std::in_place; + + optional opt; +} Index: test/std/utilities/optional/optional.syn/optional_const_lvalue_ref.fail.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.syn/optional_const_lvalue_ref.fail.cpp @@ -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 +// + +// A program that necessitates the instantiation of template optional for a +// reference type is ill-formed. + +#include + +int main() +{ + using std::optional; + + optional opt; +} Index: test/std/utilities/optional/optional.syn/optional_const_nullopt_t.fail.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.syn/optional_const_nullopt_t.fail.cpp @@ -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 +// + +// A program that necessitates the instantiation of template optional for +// (possibly cv-qualified) nullopt_t is ill-formed. + +#include + +int main() +{ + using std::optional; + using std::nullopt_t; + using std::nullopt; + + optional opt; +} Index: test/std/utilities/optional/optional.syn/optional_in_place_t.fail.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.syn/optional_in_place_t.fail.cpp @@ -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 +// + +// A program that necessitates the instantiation of template optional for +// (possibly cv-qualified) in_place_t is ill-formed. + +#include + +int main() +{ + using std::optional; + using std::in_place_t; + using std::in_place; + + optional opt; +} Index: test/std/utilities/optional/optional.syn/optional_includes_initializer_list.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.syn/optional_includes_initializer_list.pass.cpp @@ -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 +// + +// #include + +#include + +int main() +{ + using std::optional; + + std::initializer_list list; +} Index: test/std/utilities/optional/optional.syn/optional_lvalue_ref.fail.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.syn/optional_lvalue_ref.fail.cpp @@ -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 +// + +// A program that necessitates the instantiation of template optional for a +// reference type is ill-formed. + +#include + +int main() +{ + using std::optional; + + optional opt; +} Index: test/std/utilities/optional/optional.syn/optional_nullopt_t.fail.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.syn/optional_nullopt_t.fail.cpp @@ -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 +// + +// A program that necessitates the instantiation of template optional for +// (possibly cv-qualified) nullopt_t is ill-formed. + +#include + +int main() +{ + using std::optional; + using std::nullopt_t; + using std::nullopt; + + optional opt; +} Index: test/std/utilities/optional/optional.syn/optional_rvalue_ref.fail.cpp =================================================================== --- /dev/null +++ test/std/utilities/optional/optional.syn/optional_rvalue_ref.fail.cpp @@ -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 +// + +// A program that necessitates the instantiation of template optional for a +// reference type is ill-formed. + +#include + +int main() +{ + using std::optional; + + optional opt; +}