diff --git a/include/optional b/include/optional new file mode 100644 index 000000000..a8e6a9911 --- /dev/null +++ b/include/optional @@ -0,0 +1,697 @@ +// -*- 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++1y + +#include + +namespace std +{ + +// optional for object types +template +class optional +{ +public: + typedef T value_type; + + // constructors + constexpr optional() noexcept; + constexpr optional(nullopt_t) noexcept; + optional(const optional&); + optional(optional&&) noexcept(is_nothrow_move_constructible::value); + 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&&...); + + // destructor + ~optional(); + + // assignment + optional& operator=(nullopt_t) noexcept; + optional& operator=(const optional&); + optional& operator=(optional&&) + noexcept(is_nothrow_move_assignable::value && + is_nothrow_move_constructible::value); + template optional& operator=(U&&); + template void emplace(Args&&...); + template void emplace(initializer_list, Args&&...); + + // swap + void swap(optional&) + noexcept(is_nothrow_move_constructible::value && + noexcept(swap(declval(), declval()))); + + // observers + constexpr T const* operator->() const; + T* operator->(); + constexpr T const& operator*() const; + T& operator*(); + constexpr explicit operator bool() const noexcept; + constexpr T const& value() const; + T& value(); + template constexpr T value_or(U&&) const&; + template T value_or(U&&) &&; +}; + +// In-place construction +struct in_place_t{}; +constexpr in_place_t in_place{}; + +// Disengaged state indicator +struct nullopt_t{see below}; +constexpr nullopt_t nullopt(unspecified); + +// class bad_optional_access +class bad_optional_access + : public logic_error +{ +public: + explicit bad_optional_access(const string& what_arg); + explicit bad_optional_access(const char* what_arg); +}; + +// Relational operators +template constexpr bool operator==(const optional&, const optional&); +template constexpr bool operator< (const optional&, const optional&); + +// Comparison with nullopt +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; + +// 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&); + +// Specialized algorithms +template void swap(optional&, optional&) noexcept(see below); +template constexpr optional::type> make_optional(T&&); + +// hash support +template struct hash; +template struct hash>; + +} // std + +*/ + +#include <__config> +#include +#include + +namespace std // purposefully not using versioning namespace +{ + +class _LIBCPP_EXCEPTION_ABI bad_optional_access + : public logic_error +{ +public: +#if _LIBCPP_STD_VER > 11 + _LIBCPP_INLINE_VISIBILITY explicit bad_optional_access(const string& __arg) + : logic_error(__arg) {} + _LIBCPP_INLINE_VISIBILITY explicit bad_optional_access(const char* __arg) + : logic_error(__arg) {} + _LIBCPP_INLINE_VISIBILITY bad_optional_access(const bad_optional_access&) noexcept = default; + _LIBCPP_INLINE_VISIBILITY bad_optional_access& operator=(const bad_optional_access&) noexcept = default; +#else +private: + bad_optional_access(const bad_optional_access&); + bad_optional_access& operator=(const bad_optional_access&); +public: +#endif // _LIBCPP_STD_VER > 11 + // Get the key function ~bad_optional_access() into the dylib even if not compiling for C++1y + virtual ~bad_optional_access() _NOEXCEPT; +}; + +} // std + +#if _LIBCPP_STD_VER > 11 + +#include +#include +#include +#include <__functional_base> + +#include <__undef_min_max> + +#ifdef _LIBCPP_DEBUG +# include <__debug> +#else +# define _LIBCPP_ASSERT(x, m) ((void)0) +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +struct in_place_t {}; +constexpr in_place_t in_place{}; + +struct nullopt_t +{ + explicit constexpr nullopt_t(int) noexcept {} +}; + +constexpr nullopt_t nullopt{0}; + +template ::value> +class __optional_storage +{ +protected: + 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) {} +}; + +template +class __optional_storage<_Tp, true> +{ +protected: + 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) {} +}; + +template +class optional + : private __optional_storage<_Tp> +{ + 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, in_place_t>::value, + "Instantiation of optional with a in_place_t 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_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 ::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 + { + if (this->__engaged_) + { + this->__val_.~value_type(); + this->__engaged_ = false; + } + 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; + } + + template ::type, value_type>::value && + 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; + } + + template ::value + >::type + > + _LIBCPP_INLINE_VISIBILITY + void + emplace(_Args&&... __args) + { + *this = nullopt; + ::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) + { + *this = nullopt; + ::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"); + return __operator_arrow(__has_operator_addressof{}); + } + + _LIBCPP_INLINE_VISIBILITY + value_type* + operator->() + { + _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value"); + return _VSTD::addressof(this->__val_); + } + + _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 + value_type& + operator*() + { + _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value"); + return this->__val_; + } + + _LIBCPP_INLINE_VISIBILITY + constexpr explicit operator bool() const noexcept {return this->__engaged_;} + + _LIBCPP_INLINE_VISIBILITY + constexpr value_type const& value() const + { + if (!this->__engaged_) + throw bad_optional_access("optional::value: not engaged"); + return this->__val_; + } + + _LIBCPP_INLINE_VISIBILITY + value_type& value() + { + if (!this->__engaged_) + throw bad_optional_access("optional::value: not engaged"); + return 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)); + } + +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_; + } +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +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 +bool +operator<(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + if (!static_cast(__y)) + return false; + if (!static_cast(__x)) + return true; + return less<_Tp>{}(*__x, *__y); +} + +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, const _Tp& __v) +{ + return static_cast(__x) ? *__x == __v : false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator==(const _Tp& __v, const optional<_Tp>& __x) +{ + return static_cast(__x) ? *__x == __v : false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator<(const optional<_Tp>& __x, const _Tp& __v) +{ + return static_cast(__x) ? less<_Tp>{}(*__x, __v) : true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator<(const _Tp& __v, const optional<_Tp>& __x) +{ + return static_cast(__x) ? less<_Tp>{}(__v, *__x) : false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +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 +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 > 11 + +#endif // _LIBCPP_ARRAY diff --git a/include/type_traits b/include/type_traits index 5e4d1550a..47cf29590 100644 --- a/include/type_traits +++ b/include/type_traits @@ -1378,8 +1378,10 @@ template using common_type_t = typename common_type<_Tp...>::type // is_assignable +template struct __select_2nd { typedef T type; }; + template -decltype((_VSTD::declval<_Tp>() = _VSTD::declval<_Arg>(), true_type())) +typename __select_2nd() = _VSTD::declval<_Arg>())), true_type>::type #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES __is_assignable_test(_Tp&&, _Arg&&); #else @@ -1969,8 +1971,6 @@ class _LIBCPP_TYPE_VIS_ONLY result_of<_Fn(_A0, _A1, _A2)> // main is_constructible test -template struct __select_2nd { typedef T type; }; - template typename __select_2nd()...))), true_type>::type __is_constructible_test(_Tp&&, _Args&& ...); @@ -3258,6 +3258,27 @@ struct underlying_type #endif // _LIBCXX_UNDERLYING_TYPE +#ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE + +template +struct __has_operator_addressof_imp +{ + template + static auto __test(__any) -> false_type; + template + static auto __test(_Up* __u) + -> typename __select_2ndoperator&()), true_type>::type; + + static const bool value = decltype(__test<_Tp>(nullptr))::value; +}; + +template +struct __has_operator_addressof + : public integral_constant::value> +{}; + +#endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_TYPE_TRAITS diff --git a/src/optional.cpp b/src/optional.cpp new file mode 100644 index 000000000..0805ca537 --- /dev/null +++ b/src/optional.cpp @@ -0,0 +1,25 @@ +//===------------------------ optional.cpp --------------------------------===// +// +// 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 "optional" + +namespace std // purposefully not using versioning namespace +{ + +#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS + +bad_optional_access::~bad_optional_access() {} + +#else + +bad_optional_access::~bad_optional_access() = default; + +#endif + +} // std diff --git a/test/utilities/meta/meta.unary/meta.unary.prop/__has_operator_addressof.pass.cpp b/test/utilities/meta/meta.unary/meta.unary.prop/__has_operator_addressof.pass.cpp new file mode 100644 index 000000000..de27b9820 --- /dev/null +++ b/test/utilities/meta/meta.unary/meta.unary.prop/__has_operator_addressof.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. +// +//===----------------------------------------------------------------------===// + +// type_traits + +// extension + +// template struct __has_operator_addressof + + +#include + +#ifndef _LIBCPP_HAS_NO_CONSTEXPR + +struct A +{ +}; + +struct B +{ + constexpr B* operator&() const; +}; + +struct D; + +struct C +{ + template + D operator,(U&&); +}; + +struct E +{ + constexpr C operator&() const; +}; + +#endif // _LIBCPP_HAS_NO_CONSTEXPR + +int main() +{ +#ifndef _LIBCPP_HAS_NO_CONSTEXPR + static_assert(std::__has_operator_addressof::value == false, ""); + static_assert(std::__has_operator_addressof::value == false, ""); + static_assert(std::__has_operator_addressof::value == true, ""); + static_assert(std::__has_operator_addressof::value == true, ""); +#endif // _LIBCPP_HAS_NO_CONSTEXPR +} diff --git a/test/utilities/meta/meta.unary/meta.unary.prop/is_assignable.pass.cpp b/test/utilities/meta/meta.unary/meta.unary.prop/is_assignable.pass.cpp index 8c21c759f..e4af6de1c 100644 --- a/test/utilities/meta/meta.unary/meta.unary.prop/is_assignable.pass.cpp +++ b/test/utilities/meta/meta.unary/meta.unary.prop/is_assignable.pass.cpp @@ -34,6 +34,19 @@ void test_is_not_assignable() static_assert((!std::is_assignable::value), ""); } +struct D; + +struct C +{ + template + D operator,(U&&); +}; + +struct E +{ + C operator=(int); +}; + int main() { test_is_assignable (); @@ -41,6 +54,7 @@ int main() test_is_assignable (); test_is_assignable (); test_is_assignable (); + test_is_assignable (); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES test_is_not_assignable (); diff --git a/test/utilities/optional/optional.bad_optional_access/char_pointer.pass.cpp b/test/utilities/optional/optional.bad_optional_access/char_pointer.pass.cpp new file mode 100644 index 000000000..f321da6c4 --- /dev/null +++ b/test/utilities/optional/optional.bad_optional_access/char_pointer.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. +// +//===----------------------------------------------------------------------===// + +// + +// class bad_optional_access; +// explicit bad_optional_access(const char* what_arg); + +#include +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + const char* s = "message"; + std::bad_optional_access e(s); + assert(std::strcmp(e.what(), s) == 0); +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.bad_optional_access/copy_assign.pass.cpp b/test/utilities/optional/optional.bad_optional_access/copy_assign.pass.cpp new file mode 100644 index 000000000..353bbe438 --- /dev/null +++ b/test/utilities/optional/optional.bad_optional_access/copy_assign.pass.cpp @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// class bad_optional_access; +// bad_optional_access& operator=(const bad_optional_access&); + +#include +#include +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + static_assert(std::is_nothrow_copy_assignable::value, ""); + const std::string s1("one message"); + const std::string s2("another message"); + std::bad_optional_access e1(s1); + std::bad_optional_access e2(s2); + assert(std::strcmp(e1.what(), e2.what()) != 0); + e1 = e2; + assert(std::strcmp(e1.what(), e2.what()) == 0); +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.bad_optional_access/copy_ctor.pass.cpp b/test/utilities/optional/optional.bad_optional_access/copy_ctor.pass.cpp new file mode 100644 index 000000000..cab8aed4f --- /dev/null +++ b/test/utilities/optional/optional.bad_optional_access/copy_ctor.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// + +// class bad_optional_access; +// bad_optional_access(const bad_optional_access&); + +#include +#include +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + static_assert(std::is_nothrow_copy_constructible::value, ""); + const std::string s("another message"); + std::bad_optional_access e1(s); + std::bad_optional_access e2 = e1; + assert(std::strcmp(e1.what(), e2.what()) == 0); +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.bad_optional_access/default.pass.cpp b/test/utilities/optional/optional.bad_optional_access/default.pass.cpp new file mode 100644 index 000000000..96ff10449 --- /dev/null +++ b/test/utilities/optional/optional.bad_optional_access/default.pass.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// class bad_optional_access is not default constructible + +#include +#include + +#if _LIBCPP_STD_VER > 11 + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + static_assert(!std::is_default_constructible::value, ""); +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.bad_optional_access/derive.pass.cpp b/test/utilities/optional/optional.bad_optional_access/derive.pass.cpp new file mode 100644 index 000000000..87d5cb640 --- /dev/null +++ b/test/utilities/optional/optional.bad_optional_access/derive.pass.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. +// +//===----------------------------------------------------------------------===// + +// + +// class bad_optional_access : public logic_error + +#include +#include + +#if _LIBCPP_STD_VER > 11 + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + static_assert(std::is_base_of::value, ""); + static_assert(std::is_convertible::value, ""); +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.bad_optional_access/string.pass.cpp b/test/utilities/optional/optional.bad_optional_access/string.pass.cpp new file mode 100644 index 000000000..865890649 --- /dev/null +++ b/test/utilities/optional/optional.bad_optional_access/string.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. +// +//===----------------------------------------------------------------------===// + +// + +// class bad_optional_access; +// explicit bad_optional_access(const string& what_arg); + +#include +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + const std::string s("message"); + std::bad_optional_access e(s); + assert(std::strcmp(e.what(), s.c_str()) == 0); +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.comp_with_t/equal.pass.cpp b/test/utilities/optional/optional.comp_with_t/equal.pass.cpp new file mode 100644 index 000000000..b1865fafe --- /dev/null +++ b/test/utilities/optional/optional.comp_with_t/equal.pass.cpp @@ -0,0 +1,42 @@ +//===----------------------------------------------------------------------===// +// +// 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, const T& v); +// template constexpr bool operator==(const T& v, const optional& x); + +#include + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + typedef int T; + typedef std::optional O; + + constexpr T val(2); + constexpr O o1; // disengaged + constexpr O o2{1}; // engaged + constexpr O o3{val}; // engaged + + static_assert ( !(o1 == 1), "" ); + static_assert ( o2 == 1, "" ); + static_assert ( !(o3 == 1), "" ); + static_assert ( o3 == 2 , "" ); + static_assert ( o3 == val, "" ); + + static_assert ( !(1 == o1), "" ); + static_assert ( 1 == o2, "" ); + static_assert ( !(1 == o3), "" ); + static_assert ( 2 == o3 , "" ); + static_assert ( val == o3 , "" ); + } +#endif +} diff --git a/test/utilities/optional/optional.comp_with_t/less_than.pass.cpp b/test/utilities/optional/optional.comp_with_t/less_than.pass.cpp new file mode 100644 index 000000000..ffc4441ce --- /dev/null +++ b/test/utilities/optional/optional.comp_with_t/less_than.pass.cpp @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template constexpr bool operator<(const optional& x, const T& v); +// template constexpr bool operator<(const T& v, const optional& x); + +#include + +#if _LIBCPP_STD_VER > 11 + +struct X +{ + int i_; + + constexpr X(int i) : i_(i) {} +}; + +namespace std +{ + +template <> +struct less +{ + constexpr + bool + operator()(const X& x, const X& y) const + { + return x.i_ < y.i_; + } +}; + +} + +#endif + +int main() +{ +#if _LIBCPP_STD_VER > 11 + + { + typedef X T; + typedef std::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 ( o2 < T(2) , "" ); + static_assert ( o2 < T(val), "" ); + static_assert ( o3 < T(3) , "" ); + + static_assert ( !(T(1) < o1), "" ); + static_assert ( !(T(1) < o2), "" ); + static_assert ( T(1) < o3 , "" ); + static_assert ( !(T(2) < o2), "" ); + static_assert (!(T(val) < o2), "" ); + static_assert ( !(T(3) < o3), "" ); + } +#endif +} diff --git a/test/utilities/optional/optional.defs/tested_elsewhere.pass.cpp b/test/utilities/optional/optional.defs/tested_elsewhere.pass.cpp new file mode 100644 index 000000000..b58f5c55b --- /dev/null +++ b/test/utilities/optional/optional.defs/tested_elsewhere.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/utilities/optional/optional.general/nothing_to_do.pass.cpp b/test/utilities/optional/optional.general/nothing_to_do.pass.cpp new file mode 100644 index 000000000..b58f5c55b --- /dev/null +++ b/test/utilities/optional/optional.general/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/utilities/optional/optional.hash/hash.pass.cpp b/test/utilities/optional/optional.hash/hash.pass.cpp new file mode 100644 index 000000000..406632ae1 --- /dev/null +++ b/test/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. +// +//===----------------------------------------------------------------------===// + +// + +// template struct hash>; + +#include +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + typedef int T; + std::optional opt; + assert(std::hash>{}(opt) == 0); + opt = 2; + assert(std::hash>{}(opt) == std::hash{}(*opt)); + } + { + typedef std::string T; + std::optional opt; + assert(std::hash>{}(opt) == 0); + opt = std::string("123"); + assert(std::hash>{}(opt) == std::hash{}(*opt)); + } + { + typedef std::unique_ptr T; + std::optional opt; + assert(std::hash>{}(opt) == 0); + opt = std::unique_ptr(new int(3)); + assert(std::hash>{}(opt) == std::hash{}(*opt)); + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.inplace/in_place_t.pass.cpp b/test/utilities/optional/optional.inplace/in_place_t.pass.cpp new file mode 100644 index 000000000..ef9ee49b8 --- /dev/null +++ b/test/utilities/optional/optional.inplace/in_place_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. +// +//===----------------------------------------------------------------------===// + +// + +// struct in_place_t{}; +// constexpr in_place_t in_place{}; + +#include +#include + +#if _LIBCPP_STD_VER > 11 + +constexpr +int +test(const std::in_place_t&) +{ + return 3; +} + +#endif + +int main() +{ +#if _LIBCPP_STD_VER > 11 + + static_assert((std::is_class::value), ""); + static_assert((std::is_empty::value), ""); + + static_assert(test(std::in_place) == 3, ""); +#endif +} diff --git a/test/utilities/optional/optional.nullops/eqaul.pass.cpp b/test/utilities/optional/optional.nullops/eqaul.pass.cpp new file mode 100644 index 000000000..bfc8e16e3 --- /dev/null +++ b/test/utilities/optional/optional.nullops/eqaul.pass.cpp @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + + +// + +// 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 + { + typedef int T; + typedef std::optional O; + + constexpr O o1; // disengaged + constexpr O o2{1}; // engaged + + static_assert ( std::nullopt == o1 , "" ); + static_assert ( !(std::nullopt == o2), "" ); + static_assert ( o1 == std::nullopt , "" ); + static_assert ( !(o2 == std::nullopt), "" ); + + static_assert (noexcept(std::nullopt == o1), ""); + static_assert (noexcept(o1 == std::nullopt), ""); + } +#endif +} diff --git a/test/utilities/optional/optional.nullops/less_than.pass.cpp b/test/utilities/optional/optional.nullops/less_than.pass.cpp new file mode 100644 index 000000000..ea297ca7e --- /dev/null +++ b/test/utilities/optional/optional.nullops/less_than.pass.cpp @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + + +// + +// 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 + { + typedef int T; + typedef std::optional O; + + constexpr O o1; // disengaged + constexpr O o2{1}; // engaged + + static_assert ( !(std::nullopt < o1), "" ); + static_assert ( std::nullopt < o2 , "" ); + static_assert ( !(o1 < std::nullopt), "" ); + static_assert ( !(o2 < std::nullopt), "" ); + + static_assert (noexcept(std::nullopt < o1), ""); + static_assert (noexcept(o1 < std::nullopt), ""); + } +#endif +} diff --git a/test/utilities/optional/optional.nullopt/nullopt_t.pass.cpp b/test/utilities/optional/optional.nullopt/nullopt_t.pass.cpp new file mode 100644 index 000000000..22bf34b7c --- /dev/null +++ b/test/utilities/optional/optional.nullopt/nullopt_t.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. +// +//===----------------------------------------------------------------------===// + +// + +// struct nullopt_t{see below}; +// constexpr nullopt_t nullopt(unspecified); + +#include +#include + +#if _LIBCPP_STD_VER > 11 + +constexpr +int +test(const std::nullopt_t&) +{ + return 3; +} + +#endif + +int main() +{ +#if _LIBCPP_STD_VER > 11 + 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(std::nullopt) == 3, ""); +#endif +} diff --git a/test/utilities/optional/optional.object/optional.object.assign/assign_value.pass.cpp b/test/utilities/optional/optional.object/optional.object.assign/assign_value.pass.cpp new file mode 100644 index 000000000..ee3b15444 --- /dev/null +++ b/test/utilities/optional/optional.object/optional.object.assign/assign_value.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. +// +//===----------------------------------------------------------------------===// + +// + +// template optional& operator=(U&& v); + +#include +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +struct X +{ +}; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + 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, ""); + { + std::optional opt; + opt = 1; + assert(static_cast(opt) == true); + assert(*opt == 1); + } + { + std::optional opt; + const int i = 2; + opt = i; + assert(static_cast(opt) == true); + assert(*opt == i); + } + { + std::optional opt(3); + const int i = 2; + opt = i; + assert(static_cast(opt) == true); + assert(*opt == i); + } + { + std::optional> opt; + opt = std::unique_ptr(new int(3)); + assert(static_cast(opt) == true); + assert(**opt == 3); + } + { + std::optional> opt(std::unique_ptr(new int(2))); + opt = std::unique_ptr(new int(3)); + assert(static_cast(opt) == true); + assert(**opt == 3); + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp b/test/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp new file mode 100644 index 000000000..f6d365ae1 --- /dev/null +++ b/test/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// optional& operator=(const optional& rhs); + +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +struct X +{ + static bool throw_now; + + X() = default; + X(const X&) + { + if (throw_now) + throw 6; + } +}; + +bool X::throw_now = false; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + std::optional opt; + constexpr std::optional opt2; + opt = opt2; + static_assert(static_cast(opt2) == false, ""); + assert(static_cast(opt) == static_cast(opt2)); + } + { + std::optional opt; + constexpr std::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); + } + { + std::optional opt(3); + constexpr std::optional opt2; + opt = opt2; + static_assert(static_cast(opt2) == false, ""); + assert(static_cast(opt) == static_cast(opt2)); + } + { + std::optional opt(3); + constexpr std::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); + } + { + std::optional opt; + std::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); + } + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp b/test/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp new file mode 100644 index 000000000..e43e88006 --- /dev/null +++ b/test/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp @@ -0,0 +1,146 @@ +//===----------------------------------------------------------------------===// +// +// 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 void optional::emplace(Args&&... args); + +#include +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +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() {dtor_called = true;} +}; + +bool Y::dtor_called = false; + +class Z +{ +public: + static bool dtor_called; + Z() = default; + Z(int) {throw 6;} + ~Z() {dtor_called = true;} +}; + +bool Z::dtor_called = false; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + std::optional opt; + opt.emplace(); + assert(static_cast(opt) == true); + assert(*opt == 0); + } + { + std::optional opt; + opt.emplace(1); + assert(static_cast(opt) == true); + assert(*opt == 1); + } + { + std::optional opt(2); + opt.emplace(); + assert(static_cast(opt) == true); + assert(*opt == 0); + } + { + std::optional opt(2); + opt.emplace(1); + assert(static_cast(opt) == true); + assert(*opt == 1); + } + { + std::optional opt; + opt.emplace(); + assert(static_cast(opt) == true); + assert(*opt == X()); + } + { + std::optional opt; + opt.emplace(1); + assert(static_cast(opt) == true); + assert(*opt == X(1)); + } + { + std::optional opt; + opt.emplace(1, 2); + assert(static_cast(opt) == true); + assert(*opt == X(1, 2)); + } + { + std::optional opt(X{3}); + opt.emplace(); + assert(static_cast(opt) == true); + assert(*opt == X()); + } + { + std::optional opt(X{3}); + opt.emplace(1); + assert(static_cast(opt) == true); + assert(*opt == X(1)); + } + { + std::optional opt(X{3}); + opt.emplace(1, 2); + assert(static_cast(opt) == true); + assert(*opt == X(1, 2)); + } + { + Y y; + { + std::optional opt(y); + assert(Y::dtor_called == false); + opt.emplace(); + assert(Y::dtor_called == true); + } + } + { + Z z; + std::optional opt(z); + try + { + assert(static_cast(opt) == true); + assert(Z::dtor_called == false); + opt.emplace(1); + } + catch (int i) + { + assert(i == 6); + assert(static_cast(opt) == false); + assert(Z::dtor_called == true); + } + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional.object.assign/emplace_initializer_list.pass.cpp b/test/utilities/optional/optional.object/optional.object.assign/emplace_initializer_list.pass.cpp new file mode 100644 index 000000000..db4fb4959 --- /dev/null +++ b/test/utilities/optional/optional.object/optional.object.assign/emplace_initializer_list.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. +// +//===----------------------------------------------------------------------===// + +// + +// template +// void optional::emplace(initializer_list il, Args&&... args); + +#include +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +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; + constexpr Z() : i_(0) {} + constexpr Z(int i) : i_(i) {} + constexpr Z(std::initializer_list il) : i_(il.begin()[0]), j_(il.begin()[1]) + {throw 6;} + ~Z() {dtor_called = true;} + + friend constexpr bool operator==(const Z& x, const Z& y) + {return x.i_ == y.i_ && x.j_ == y.j_;} +}; + +bool Z::dtor_called = false; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + X x; + { + std::optional opt(x); + assert(X::dtor_called == false); + opt.emplace({1, 2}); + assert(X::dtor_called == true); + assert(*opt == X({1, 2})); + } + } + { + std::optional> opt; + opt.emplace({1, 2, 3}, std::allocator()); + assert(static_cast(opt) == true); + assert(*opt == std::vector({1, 2, 3})); + } + { + std::optional opt; + opt.emplace({1, 2}); + assert(static_cast(opt) == true); + assert(*opt == Y({1, 2})); + } + { + Z z; + std::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); + } + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional.object.assign/move.pass.cpp b/test/utilities/optional/optional.object/optional.object.assign/move.pass.cpp new file mode 100644 index 000000000..a1574d6bb --- /dev/null +++ b/test/utilities/optional/optional.object/optional.object.assign/move.pass.cpp @@ -0,0 +1,101 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// optional& operator=(optional&& rhs) +// noexcept(is_nothrow_move_assignable::value && +// is_nothrow_move_constructible::value); + +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +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; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + static_assert(std::is_nothrow_move_assignable>::value, ""); + std::optional opt; + constexpr std::optional opt2; + opt = std::move(opt2); + static_assert(static_cast(opt2) == false, ""); + assert(static_cast(opt) == static_cast(opt2)); + } + { + std::optional opt; + constexpr std::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); + } + { + std::optional opt(3); + constexpr std::optional opt2; + opt = std::move(opt2); + static_assert(static_cast(opt2) == false, ""); + assert(static_cast(opt) == static_cast(opt2)); + } + { + std::optional opt(3); + constexpr std::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, ""); + std::optional opt; + std::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, ""); + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional.object.assign/nullopt_t.pass.cpp b/test/utilities/optional/optional.object/optional.object.assign/nullopt_t.pass.cpp new file mode 100644 index 000000000..2c87fe9b1 --- /dev/null +++ b/test/utilities/optional/optional.object/optional.object.assign/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. +// +//===----------------------------------------------------------------------===// + +// + +// optional& operator=(nullopt_t) noexcept; + +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +struct X +{ + static bool dtor_called; + ~X() {dtor_called = true;} +}; + +bool X::dtor_called = false; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + std::optional opt; + static_assert(noexcept(opt = std::nullopt) == true, ""); + opt = std::nullopt; + assert(static_cast(opt) == false); + } + { + std::optional opt(3); + opt = std::nullopt; + assert(static_cast(opt) == false); + } + { + std::optional opt; + static_assert(noexcept(opt = std::nullopt) == true, ""); + assert(X::dtor_called == false); + opt = std::nullopt; + assert(X::dtor_called == false); + assert(static_cast(opt) == false); + } + { + X x; + { + std::optional opt(x); + assert(X::dtor_called == false); + opt = std::nullopt; + assert(X::dtor_called == true); + assert(static_cast(opt) == false); + } + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp b/test/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp new file mode 100644 index 000000000..2e69b3058 --- /dev/null +++ b/test/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp @@ -0,0 +1,115 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// + +// constexpr optional(const T& v); + +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +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 +{ + int i_; +public: + Z(int i) : i_(i) {} + Z(const Z&) {throw 6;} +}; + + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + typedef int T; + constexpr T t(5); + constexpr std::optional opt(t); + static_assert(static_cast(opt) == true, ""); + static_assert(*opt == 5, ""); + + struct test_constexpr_ctor + : public std::optional + { + constexpr test_constexpr_ctor(const T&) {} + }; + + } + { + typedef double T; + constexpr T t(3); + constexpr std::optional opt(t); + static_assert(static_cast(opt) == true, ""); + static_assert(*opt == 3, ""); + + struct test_constexpr_ctor + : public std::optional + { + constexpr test_constexpr_ctor(const T&) {} + }; + + } + { + typedef X T; + const T t(3); + std::optional opt(t); + assert(static_cast(opt) == true); + assert(*opt == 3); + } + { + typedef Y T; + constexpr T t(3); + constexpr std::optional opt(t); + static_assert(static_cast(opt) == true, ""); + static_assert(*opt == 3, ""); + + struct test_constexpr_ctor + : public std::optional + { + constexpr test_constexpr_ctor(const T&) {} + }; + + } + { + typedef Z T; + try + { + const T t(3); + std::optional opt(t); + assert(false); + } + catch (int i) + { + assert(i == 6); + } + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp b/test/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp new file mode 100644 index 000000000..84319ad15 --- /dev/null +++ b/test/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp @@ -0,0 +1,122 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// optional(const optional& rhs); + +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +template +void +test(const std::optional& rhs, bool is_going_to_throw = false) +{ + bool rhs_engaged = static_cast(rhs); + try + { + std::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_;} +}; + + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + typedef int T; + std::optional rhs; + test(rhs); + } + { + typedef int T; + std::optional rhs(3); + test(rhs); + } + { + typedef X T; + std::optional rhs; + test(rhs); + } + { + typedef X T; + std::optional rhs(X(3)); + test(rhs); + } + { + typedef Y T; + std::optional rhs; + test(rhs); + } + { + typedef Y T; + std::optional rhs(Y(3)); + test(rhs); + } + { + typedef Z T; + std::optional rhs; + test(rhs); + } + { + typedef Z T; + std::optional rhs(Z(3)); + test(rhs, true); + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional.object.ctor/default.pass.cpp b/test/utilities/optional/optional.object/optional.object.ctor/default.pass.cpp new file mode 100644 index 000000000..5f9c5af5a --- /dev/null +++ b/test/utilities/optional/optional.object/optional.object.ctor/default.pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// + +// constexpr optional() noexcept; + +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +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(); +}; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + test_constexpr>(); + test_constexpr>(); + test>(); +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp b/test/utilities/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp new file mode 100644 index 000000000..db1b62970 --- /dev/null +++ b/test/utilities/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp @@ -0,0 +1,141 @@ +//===----------------------------------------------------------------------===// +// +// 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 explicit optional(in_place_t, Args&&... args); + +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +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 +{ + int i_; +public: + Z(int i) : i_(i) {throw 6;} +}; + + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + constexpr std::optional opt(std::in_place, 5); + static_assert(static_cast(opt) == true, ""); + static_assert(*opt == 5, ""); + + struct test_constexpr_ctor + : public std::optional + { + constexpr test_constexpr_ctor(std::in_place_t, int i) + : std::optional(std::in_place, i) {} + }; + + } + { + const std::optional opt(std::in_place); + assert(static_cast(opt) == true); + assert(*opt == X()); + } + { + const std::optional opt(std::in_place, 5); + assert(static_cast(opt) == true); + assert(*opt == X(5)); + } + { + const std::optional opt(std::in_place, 5, 4); + assert(static_cast(opt) == true); + assert(*opt == X(5, 4)); + } + { + constexpr std::optional opt(std::in_place); + static_assert(static_cast(opt) == true, ""); + static_assert(*opt == Y(), ""); + + struct test_constexpr_ctor + : public std::optional + { + constexpr test_constexpr_ctor(std::in_place_t) + : std::optional(std::in_place) {} + }; + + } + { + constexpr std::optional opt(std::in_place, 5); + static_assert(static_cast(opt) == true, ""); + static_assert(*opt == Y(5), ""); + + struct test_constexpr_ctor + : public std::optional + { + constexpr test_constexpr_ctor(std::in_place_t, int i) + : std::optional(std::in_place, i) {} + }; + + } + { + constexpr std::optional opt(std::in_place, 5, 4); + static_assert(static_cast(opt) == true, ""); + static_assert(*opt == Y(5, 4), ""); + + struct test_constexpr_ctor + : public std::optional + { + constexpr test_constexpr_ctor(std::in_place_t, int i, int j) + : std::optional(std::in_place, i, j) {} + }; + + } + { + try + { + const std::optional opt(std::in_place, 1); + assert(false); + } + catch (int i) + { + assert(i == 6); + } + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp b/test/utilities/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp new file mode 100644 index 000000000..076554a40 --- /dev/null +++ b/test/utilities/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp @@ -0,0 +1,122 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// explicit optional(in_place_t, initializer_list il, Args&&... args); + +#include +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +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: + constexpr Z() : i_(0) {} + constexpr Z(int i) : i_(i) {} + constexpr Z(std::initializer_list il) : i_(il.begin()[0]), j_(il.begin()[1]) + {throw 6;} + + friend constexpr bool operator==(const Z& x, const Z& y) + {return x.i_ == y.i_ && x.j_ == y.j_;} +}; + + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + static_assert(!std::is_constructible&>::value, ""); + static_assert(!std::is_constructible, std::initializer_list&>::value, ""); + } + { + std::optional> opt(std::in_place, {3, 1}); + assert(static_cast(opt) == true); + assert((*opt == std::vector{3, 1})); + assert(opt->size() == 2); + } + { + std::optional> opt(std::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 std::optional opt(std::in_place, {3, 1}); + static_assert(static_cast(opt) == true, ""); + static_assert(*opt == Y{3, 1}, ""); + + struct test_constexpr_ctor + : public std::optional + { + constexpr test_constexpr_ctor(std::in_place_t, std::initializer_list i) + : std::optional(std::in_place, i) {} + }; + + } + { + static_assert(std::is_constructible, std::initializer_list&>::value, ""); + try + { + std::optional opt(std::in_place, {3, 1}); + assert(false); + } + catch (int i) + { + assert(i == 6); + } + + struct test_constexpr_ctor + : public std::optional + { + constexpr test_constexpr_ctor(std::in_place_t, std::initializer_list i) + : std::optional(std::in_place, i) {} + }; + + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp b/test/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp new file mode 100644 index 000000000..70004fd86 --- /dev/null +++ b/test/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp @@ -0,0 +1,122 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// optional(optional&& rhs) noexcept(is_nothrow_move_constructible::value); + +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +template +void +test(std::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 + { + std::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_;} +}; + + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + typedef int T; + std::optional rhs; + test(rhs); + } + { + typedef int T; + std::optional rhs(3); + test(rhs); + } + { + typedef X T; + std::optional rhs; + test(rhs); + } + { + typedef X T; + std::optional rhs(X(3)); + test(rhs); + } + { + typedef Y T; + std::optional rhs; + test(rhs); + } + { + typedef Y T; + std::optional rhs(Y(3)); + test(rhs); + } + { + typedef Z T; + std::optional rhs; + test(rhs); + } + { + typedef Z T; + std::optional rhs(Z(3)); + test(rhs, true); + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp b/test/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp new file mode 100644 index 000000000..0d0f1e9a2 --- /dev/null +++ b/test/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// constexpr optional(nullopt_t) noexcept; + +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +template +void +test_constexpr() +{ + static_assert(noexcept(Opt(std::nullopt)), ""); + constexpr Opt opt(std::nullopt); + static_assert(static_cast(opt) == false, ""); + + struct test_constexpr_ctor + : public Opt + { + constexpr test_constexpr_ctor() {} + }; +} + +template +void +test() +{ + static_assert(noexcept(Opt(std::nullopt)), ""); + Opt opt(std::nullopt); + assert(static_cast(opt) == false); + + struct test_constexpr_ctor + : public Opt + { + constexpr test_constexpr_ctor() {} + }; +} + +struct X +{ + X(); +}; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + test_constexpr>(); + test_constexpr>(); + test>(); +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp b/test/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp new file mode 100644 index 000000000..c07dd6343 --- /dev/null +++ b/test/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp @@ -0,0 +1,108 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// + +// constexpr optional(T&& v); + +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +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 +{ + int i_; +public: + Z(int i) : i_(i) {} + Z(Z&&) {throw 6;} +}; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + typedef int T; + constexpr std::optional opt(T(5)); + static_assert(static_cast(opt) == true, ""); + static_assert(*opt == 5, ""); + + struct test_constexpr_ctor + : public std::optional + { + constexpr test_constexpr_ctor(T&&) {} + }; + } + { + typedef double T; + constexpr std::optional opt(T(3)); + static_assert(static_cast(opt) == true, ""); + static_assert(*opt == 3, ""); + + struct test_constexpr_ctor + : public std::optional + { + constexpr test_constexpr_ctor(T&&) {} + }; + } + { + typedef X T; + std::optional opt(T(3)); + assert(static_cast(opt) == true); + assert(*opt == 3); + } + { + typedef Y T; + constexpr std::optional opt(T(3)); + static_assert(static_cast(opt) == true, ""); + static_assert(*opt == 3, ""); + + struct test_constexpr_ctor + : public std::optional + { + constexpr test_constexpr_ctor(T&&) {} + }; + } + { + typedef Z T; + try + { + std::optional opt(T(3)); + assert(false); + } + catch (int i) + { + assert(i == 6); + } + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp b/test/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp new file mode 100644 index 000000000..428e67436 --- /dev/null +++ b/test/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// ~optional(); + +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +class X +{ +public: + static bool dtor_called; + X() = default; + ~X() {dtor_called = true;} +}; + +bool X::dtor_called = false; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + 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; + std::optional opt{x}; + assert(X::dtor_called == false); + } + assert(X::dtor_called == true); + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional.object.observe/bool.pass.cpp b/test/utilities/optional/optional.object/optional.object.observe/bool.pass.cpp new file mode 100644 index 000000000..657af2c5d --- /dev/null +++ b/test/utilities/optional/optional.object/optional.object.observe/bool.pass.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// + +// constexpr explicit optional::operator bool() const noexcept; + +#include +#include +#include + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + constexpr std::optional opt; + static_assert(!opt, ""); + } + { + constexpr std::optional opt(0); + static_assert(opt, ""); + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional.object.observe/dereference.pass.cpp b/test/utilities/optional/optional.object/optional.object.observe/dereference.pass.cpp new file mode 100644 index 000000000..5ef4245fe --- /dev/null +++ b/test/utilities/optional/optional.object/optional.object.observe/dereference.pass.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// + +// T& optional::operator*(); + +#ifdef _LIBCPP_DEBUG +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +struct X +{ + constexpr int test() const {return 3;} + int test() {return 4;} +}; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + std::optional opt(X{}); + assert((*opt).test() == 4); + } +#ifdef _LIBCPP_DEBUG + { + std::optional opt; + assert((*opt).test() == 3); + assert(false); + } +#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional.object.observe/dereference_const.pass.cpp b/test/utilities/optional/optional.object/optional.object.observe/dereference_const.pass.cpp new file mode 100644 index 000000000..6ea5e1188 --- /dev/null +++ b/test/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. +// +//===----------------------------------------------------------------------===// + +// + +// constexpr const T& optional::operator*() const; + +#ifdef _LIBCPP_DEBUG +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +struct X +{ + constexpr int test() const {return 3;} +}; + +struct Y +{ + int test() const {return 2;} +}; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + constexpr std::optional opt(X{}); + static_assert((*opt).test() == 3, ""); + } + { + constexpr std::optional opt(Y{}); + assert((*opt).test() == 2); + } +#ifdef _LIBCPP_DEBUG + { + const std::optional opt; + assert((*opt).test() == 3); + assert(false); + } +#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional.object.observe/op_arrow.pass.cpp b/test/utilities/optional/optional.object/optional.object.observe/op_arrow.pass.cpp new file mode 100644 index 000000000..54c19e716 --- /dev/null +++ b/test/utilities/optional/optional.object/optional.object.observe/op_arrow.pass.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// + +// T* optional::operator->(); + +#ifdef _LIBCPP_DEBUG +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +struct X +{ + int test() const {return 2;} + int test() {return 3;} +}; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + std::optional opt(X{}); + assert(opt->test() == 3); + } +#ifdef _LIBCPP_DEBUG + { + std::optional opt; + assert(opt->test() == 3); + assert(false); + } +#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp b/test/utilities/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp new file mode 100644 index 000000000..94f62e29b --- /dev/null +++ b/test/utilities/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// + +// constexpr const T* optional::operator->() const; + +#ifdef _LIBCPP_DEBUG +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +struct X +{ + constexpr int test() const {return 3;} +}; + +struct Y +{ + int test() const {return 2;} +}; + +struct Z +{ + const Z* operator&() const {return this;} + constexpr int test() const {return 1;} +}; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + constexpr std::optional opt(X{}); + static_assert(opt->test() == 3, ""); + } + { + constexpr std::optional opt(Y{}); + assert(opt->test() == 2); + } + { + constexpr std::optional opt(Z{}); + assert(opt->test() == 1); + } +#ifdef _LIBCPP_DEBUG + { + const std::optional opt; + assert(opt->test() == 3); + assert(false); + } +#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional.object.observe/value.pass.cpp b/test/utilities/optional/optional.object/optional.object.observe/value.pass.cpp new file mode 100644 index 000000000..245070c6c --- /dev/null +++ b/test/utilities/optional/optional.object/optional.object.observe/value.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// T& optional::value(); + +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +struct X +{ + X() = default; + X(const X&) = delete; + constexpr int test() const {return 3;} + int test() {return 4;} +}; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + std::optional opt; + opt.emplace(); + assert(opt.value().test() == 4); + } + { + std::optional opt; + try + { + opt.value(); + assert(false); + } + catch (const std::bad_optional_access&) + { + } + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional.object.observe/value_const.fail.cpp b/test/utilities/optional/optional.object/optional.object.observe/value_const.fail.cpp new file mode 100644 index 000000000..f22220c3e --- /dev/null +++ b/test/utilities/optional/optional.object/optional.object.observe/value_const.fail.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. +// +//===----------------------------------------------------------------------===// + +// + +// constexpr const T& optional::value() const; + +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +struct X +{ + constexpr int test() const {return 3;} + int test() {return 4;} +}; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + constexpr std::optional opt; + static_assert(opt.value().test() == 3, ""); + } +#else +#error +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional.object.observe/value_const.pass.cpp b/test/utilities/optional/optional.object/optional.object.observe/value_const.pass.cpp new file mode 100644 index 000000000..1c6776524 --- /dev/null +++ b/test/utilities/optional/optional.object/optional.object.observe/value_const.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. +// +//===----------------------------------------------------------------------===// + +// + +// constexpr const T& optional::value() const; + +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +struct X +{ + X() = default; + X(const X&) = delete; + constexpr int test() const {return 3;} + int test() {return 4;} +}; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + constexpr std::optional opt(std::in_place); + static_assert(opt.value().test() == 3, ""); + } + { + const std::optional opt(std::in_place); + assert(opt.value().test() == 3); + } + { + const std::optional opt; + try + { + opt.value(); + assert(false); + } + catch (const std::bad_optional_access&) + { + } + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional.object.observe/value_or.pass.cpp b/test/utilities/optional/optional.object/optional.object.observe/value_or.pass.cpp new file mode 100644 index 000000000..52a3f5d4d --- /dev/null +++ b/test/utilities/optional/optional.object/optional.object.observe/value_or.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. +// +//===----------------------------------------------------------------------===// + +// + +// template T optional::value_or(U&& v) &&; + +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +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_;} +}; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + std::optional opt(std::in_place, 2); + Y y(3); + assert(std::move(opt).value_or(y) == 2); + assert(*opt == 0); + } + { + std::optional opt(std::in_place, 2); + assert(std::move(opt).value_or(Y(3)) == 2); + assert(*opt == 0); + } + { + std::optional opt; + Y y(3); + assert(std::move(opt).value_or(y) == 3); + assert(!opt); + } + { + std::optional opt; + assert(std::move(opt).value_or(Y(3)) == 4); + assert(!opt); + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional.object.observe/value_or_const.pass.cpp b/test/utilities/optional/optional.object/optional.object.observe/value_or_const.pass.cpp new file mode 100644 index 000000000..e95ab2d25 --- /dev/null +++ b/test/utilities/optional/optional.object/optional.object.observe/value_or_const.pass.cpp @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// +// 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 T optional::value_or(U&& v) const&; + +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +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_;} +}; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + constexpr std::optional opt(2); + constexpr Y y(3); + static_assert(opt.value_or(y) == 2, ""); + } + { + constexpr std::optional opt(2); + static_assert(opt.value_or(Y(3)) == 2, ""); + } + { + constexpr std::optional opt; + constexpr Y y(3); + static_assert(opt.value_or(y) == 3, ""); + } + { + constexpr std::optional opt; + static_assert(opt.value_or(Y(3)) == 4, ""); + } + { + const std::optional opt(2); + const Y y(3); + assert(opt.value_or(y) == 2); + } + { + const std::optional opt(2); + assert(opt.value_or(Y(3)) == 2); + } + { + const std::optional opt; + const Y y(3); + assert(opt.value_or(y) == 3); + } + { + const std::optional opt; + assert(opt.value_or(Y(3)) == 4); + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp b/test/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp new file mode 100644 index 000000000..5672332bb --- /dev/null +++ b/test/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp @@ -0,0 +1,304 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// + +// void swap(optional&) +// noexcept(is_nothrow_move_constructible::value && +// noexcept(swap(declval(), declval()))); + +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +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;} +}; + + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + std::optional opt1; + std::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); + } + { + std::optional opt1(1); + std::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); + } + { + std::optional opt1; + std::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); + } + { + std::optional opt1(1); + std::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); + } + { + std::optional opt1; + std::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); + } + { + std::optional opt1(1); + std::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); + } + { + std::optional opt1; + std::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); + } + { + std::optional opt1(1); + std::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); + } + { + std::optional opt1; + std::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); + } + { + std::optional opt1(1); + std::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); + } + { + std::optional opt1; + std::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); + } + { + std::optional opt1(1); + std::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); + } + { + std::optional opt1; + std::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); + } + { + std::optional opt1; + opt1.emplace(1); + std::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); + } + { + std::optional opt1; + std::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); + } + { + std::optional opt1; + opt1.emplace(1); + std::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); + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional_const_void.fail.cpp b/test/utilities/optional/optional.object/optional_const_void.fail.cpp new file mode 100644 index 000000000..a471fb55e --- /dev/null +++ b/test/utilities/optional/optional.object/optional_const_void.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. +// +//===----------------------------------------------------------------------===// + +// + +// T shall be an object type and shall satisfy the requirements of Destructible + +#include + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::optional opt; +#else +#error +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional_not_destructible.fail.cpp b/test/utilities/optional/optional.object/optional_not_destructible.fail.cpp new file mode 100644 index 000000000..19b037e14 --- /dev/null +++ b/test/utilities/optional/optional.object/optional_not_destructible.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. +// +//===----------------------------------------------------------------------===// + +// + +// T shall be an object type and shall satisfy the requirements of Destructible + +#include + +#if _LIBCPP_STD_VER > 11 + +struct X +{ +private: + ~X() {} +}; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::optional opt; +#else +#error +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional_not_noexcept_destructible.fail.cpp b/test/utilities/optional/optional.object/optional_not_noexcept_destructible.fail.cpp new file mode 100644 index 000000000..da4d8c1ed --- /dev/null +++ b/test/utilities/optional/optional.object/optional_not_noexcept_destructible.fail.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// + +// T shall be an object type and shall satisfy the requirements of Destructible + +#include + +#if _LIBCPP_STD_VER > 11 + +struct X +{ + ~X() noexcept(false) {} +}; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::optional opt; +#else +#error +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/optional_void.fail.cpp b/test/utilities/optional/optional.object/optional_void.fail.cpp new file mode 100644 index 000000000..950043a26 --- /dev/null +++ b/test/utilities/optional/optional.object/optional_void.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. +// +//===----------------------------------------------------------------------===// + +// + +// T shall be an object type and shall satisfy the requirements of Destructible + +#include + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::optional opt; +#else +#error +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.object/types.pass.cpp b/test/utilities/optional/optional.object/types.pass.cpp new file mode 100644 index 000000000..ae3f7d7d3 --- /dev/null +++ b/test/utilities/optional/optional.object/types.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 +// class optional +// { +// public: +// typedef T value_type; +// ... + +#include +#include + +#if _LIBCPP_STD_VER > 11 + +template +void +test() +{ + static_assert(std::is_same::value, ""); +} + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + test, int>(); + test, const int>(); + test, double>(); + test, const double>(); +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.relops/equal.pass.cpp b/test/utilities/optional/optional.relops/equal.pass.cpp new file mode 100644 index 000000000..ec0503c39 --- /dev/null +++ b/test/utilities/optional/optional.relops/equal.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. +// +//===----------------------------------------------------------------------===// + +// + +// template constexpr bool operator==(const optional& x, const optional& y); + +#include +#include +#include + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + typedef int T; + typedef std::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 , "" ); + + } +#endif +} diff --git a/test/utilities/optional/optional.relops/less_than.pass.cpp b/test/utilities/optional/optional.relops/less_than.pass.cpp new file mode 100644 index 000000000..a1f602148 --- /dev/null +++ b/test/utilities/optional/optional.relops/less_than.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. +// +//===----------------------------------------------------------------------===// + +// + +// template constexpr bool operator< (const optional& x, const optional& y); + +#include + +#if _LIBCPP_STD_VER > 11 + +struct X +{ + int i_; + + constexpr X(int i) : i_(i) {} +}; + +namespace std +{ + +template <> +struct less +{ + constexpr + bool + operator()(const X& x, const X& y) const + { + return x.i_ < y.i_; + } +}; + +} + +#endif + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + typedef std::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), "" ); + } +#endif +} diff --git a/test/utilities/optional/optional.specalg/make_optional.pass.cpp b/test/utilities/optional/optional.specalg/make_optional.pass.cpp new file mode 100644 index 000000000..afd735a63 --- /dev/null +++ b/test/utilities/optional/optional.specalg/make_optional.pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// constexpr +// optional::type> +// make_optional(T&& v); + +#include +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + std::optional opt = std::make_optional(2); + assert(*opt == 2); + } + { + std::string s("123"); + std::optional opt = std::make_optional(s); + assert(*opt == s); + } + { + std::string s("123"); + std::optional opt = std::make_optional(std::move(s)); + assert(*opt == "123"); + assert(s.empty()); + } + { + std::unique_ptr s(new int(3)); + std::optional> opt = std::make_optional(std::move(s)); + assert(**opt == 3); + assert(s == nullptr); + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.specalg/swap.pass.cpp b/test/utilities/optional/optional.specalg/swap.pass.cpp new file mode 100644 index 000000000..d98dd40ec --- /dev/null +++ b/test/utilities/optional/optional.specalg/swap.pass.cpp @@ -0,0 +1,303 @@ +//===----------------------------------------------------------------------===// +// +// 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 void swap(optional& x, optional& y) +// noexcept(noexcept(x.swap(y))); + +#include +#include +#include + +#if _LIBCPP_STD_VER > 11 + +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;} +}; + + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + std::optional opt1; + std::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); + } + { + std::optional opt1(1); + std::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); + } + { + std::optional opt1; + std::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); + } + { + std::optional opt1(1); + std::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); + } + { + std::optional opt1; + std::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); + } + { + std::optional opt1(1); + std::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); + } + { + std::optional opt1; + std::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); + } + { + std::optional opt1(1); + std::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); + } + { + std::optional opt1; + std::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); + } + { + std::optional opt1(1); + std::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); + } + { + std::optional opt1; + std::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); + } + { + std::optional opt1(1); + std::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); + } + { + std::optional opt1; + std::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); + } + { + std::optional opt1; + opt1.emplace(1); + std::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); + } + { + std::optional opt1; + std::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); + } + { + std::optional opt1; + opt1.emplace(1); + std::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); + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.syn/optional_const_in_place_t.fail.cpp b/test/utilities/optional/optional.syn/optional_const_in_place_t.fail.cpp new file mode 100644 index 000000000..fc661f0ea --- /dev/null +++ b/test/utilities/optional/optional.syn/optional_const_in_place_t.fail.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// + +// A program that necessitates the instantiation of template optional for +// (possibly cv-qualified) in_place_t is ill-formed. + +#include + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::optional opt; +#else +#error +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.syn/optional_const_lvalue_ref.fail.cpp b/test/utilities/optional/optional.syn/optional_const_lvalue_ref.fail.cpp new file mode 100644 index 000000000..8836ee671 --- /dev/null +++ b/test/utilities/optional/optional.syn/optional_const_lvalue_ref.fail.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// + +// A program that necessitates the instantiation of template optional for a +// reference type is ill-formed. + +#include + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::optional opt; +#else +#error +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.syn/optional_const_nullopt_t.fail.cpp b/test/utilities/optional/optional.syn/optional_const_nullopt_t.fail.cpp new file mode 100644 index 000000000..82aa4c122 --- /dev/null +++ b/test/utilities/optional/optional.syn/optional_const_nullopt_t.fail.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// + +// A program that necessitates the instantiation of template optional for +// (possibly cv-qualified) null_opt_t is ill-formed. + +#include + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::optional opt; +#else +#error +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.syn/optional_in_place_t.fail.cpp b/test/utilities/optional/optional.syn/optional_in_place_t.fail.cpp new file mode 100644 index 000000000..eb1146015 --- /dev/null +++ b/test/utilities/optional/optional.syn/optional_in_place_t.fail.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// + +// A program that necessitates the instantiation of template optional for +// (possibly cv-qualified) in_place_t is ill-formed. + +#include + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::optional opt; +#else +#error +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.syn/optional_includes_initializer_list.pass.cpp b/test/utilities/optional/optional.syn/optional_includes_initializer_list.pass.cpp new file mode 100644 index 000000000..df5d246ce --- /dev/null +++ b/test/utilities/optional/optional.syn/optional_includes_initializer_list.pass.cpp @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +#include + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::initializer_list list; +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.syn/optional_lvalue_ref.fail.cpp b/test/utilities/optional/optional.syn/optional_lvalue_ref.fail.cpp new file mode 100644 index 000000000..bc143fc6c --- /dev/null +++ b/test/utilities/optional/optional.syn/optional_lvalue_ref.fail.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// + +// A program that necessitates the instantiation of template optional for a +// reference type is ill-formed. + +#include + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::optional opt; +#else +#error +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.syn/optional_nullopt_t.fail.cpp b/test/utilities/optional/optional.syn/optional_nullopt_t.fail.cpp new file mode 100644 index 000000000..bcb152e55 --- /dev/null +++ b/test/utilities/optional/optional.syn/optional_nullopt_t.fail.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// + +// A program that necessitates the instantiation of template optional for +// (possibly cv-qualified) null_opt_t is ill-formed. + +#include + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::optional opt; +#else +#error +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/optional.syn/optional_rvalue_ref.fail.cpp b/test/utilities/optional/optional.syn/optional_rvalue_ref.fail.cpp new file mode 100644 index 000000000..a0ba2f006 --- /dev/null +++ b/test/utilities/optional/optional.syn/optional_rvalue_ref.fail.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// + +// A program that necessitates the instantiation of template optional for a +// reference type is ill-formed. + +#include + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::optional opt; +#else +#error +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/utilities/optional/version.pass.cpp b/test/utilities/optional/version.pass.cpp new file mode 100644 index 000000000..e7581b543 --- /dev/null +++ b/test/utilities/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() +{ +} diff --git a/www/cxx1y_status.html b/www/cxx1y_status.html index da920a5b7..ed0955f8b 100644 --- a/www/cxx1y_status.html +++ b/www/cxx1y_status.html @@ -87,7 +87,7 @@ 3642LWGUser-defined LiteralsBristolComplete3.4 3655LWGTransformationTraits Redux (excluding part 4)BristolComplete3.4 3657LWGAdding heterogeneous comparison lookup to associative containersBristolComplete3.4 - 3672LWGA proposal to add a utility class to represent optional objectsBristol + 3672LWGA proposal to add a utility class to represent optional objectsBristolComplete 3669LWGFixing constexpr member functions without constBristolComplete3.4 3662LWGC++ Dynamic Arrays (dynarray)Bristol