diff options
Diffstat (limited to 'system/include/libcxx/experimental')
-rw-r--r-- | system/include/libcxx/experimental/dynarray | 314 | ||||
-rw-r--r-- | system/include/libcxx/experimental/optional | 699 |
2 files changed, 1013 insertions, 0 deletions
diff --git a/system/include/libcxx/experimental/dynarray b/system/include/libcxx/experimental/dynarray new file mode 100644 index 00000000..7c5c9b3f --- /dev/null +++ b/system/include/libcxx/experimental/dynarray @@ -0,0 +1,314 @@ +// -*- C++ -*- +//===-------------------------- dynarray ----------------------------------===// +// +// The 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_DYNARRAY +#define _LIBCPP_DYNARRAY + +#include <__config> +#if _LIBCPP_STD_VER > 11 + +/* + dynarray synopsis + +namespace std { namespace experimental { + +template< typename T > +class dynarray +{ + // types: + typedef T value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T* pointer; + typedef const T* const_pointer; + typedef implementation-defined iterator; + typedef implementation-defined const_iterator; + typedef reverse_iterator<iterator> reverse_iterator; + typedef reverse_iterator<const_iterator> const_reverse_iterator; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + +public: + // construct/copy/destroy: + explicit dynarray(size_type c); + template <typename Alloc> + dynarray(size_type c, const Alloc& alloc); + dynarray(size_type c, const T& v); + template <typename Alloc> + dynarray(size_type c, const T& v, const Alloc& alloc); + dynarray(const dynarray& d); + template <typename Alloc> + dynarray(const dynarray& d, const Alloc& alloc); + dynarray(initializer_list<T>); + template <typename Alloc> + dynarray(initializer_list<T>, const Alloc& alloc); + + dynarray& operator=(const dynarray&) = delete; + ~dynarray(); + + // iterators: + iterator begin() noexcept; + const_iterator begin() const noexcept; + const_iterator cbegin() const noexcept; + iterator end() noexcept; + const_iterator end() const noexcept; + const_iterator cend() const noexcept; + + reverse_iterator rbegin() noexcept; + const_reverse_iterator rbegin() const noexcept; + const_reverse_iterator crbegin() const noexcept; + reverse_iterator rend() noexcept; + const_reverse_iterator rend() const noexcept; + const_reverse_iterator crend() const noexcept; + + // capacity: + size_type size() const noexcept; + size_type max_size() const noexcept; + bool empty() const noexcept; + + // element access: + reference operator[](size_type n); + const_reference operator[](size_type n) const; + + reference front(); + const_reference front() const; + reference back(); + const_reference back() const; + + const_reference at(size_type n) const; + reference at(size_type n); + + // data access: + T* data() noexcept; + const T* data() const noexcept; + + // mutating member functions: + void fill(const T& v); +}; + +}} // std::experimental + +*/ + +#include <__functional_base> +#include <iterator> +#include <stdexcept> +#include <initializer_list> +#include <new> +#include <algorithm> + +#if defined(_LIBCPP_NO_EXCEPTIONS) + #include <cassert> +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +namespace std { namespace experimental { inline namespace __array_extensions_v1 { + +template <class _Tp> +struct _LIBCPP_TYPE_VIS_ONLY dynarray +{ +public: + // types: + typedef dynarray __self; + typedef _Tp value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* iterator; + typedef const value_type* const_iterator; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + +private: + size_t __size_; + value_type * __base_; + _LIBCPP_ALWAYS_INLINE dynarray () noexcept : __base_(nullptr), __size_(0) {} + + static inline _LIBCPP_INLINE_VISIBILITY value_type* __allocate ( size_t count ) + { + if ( numeric_limits<size_t>::max() / sizeof (value_type) <= count ) + { +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_array_length(); +#else + assert(!"dynarray::allocation"); +#endif + } + return static_cast<value_type *> (::operator new (sizeof(value_type) * count)); + } + + static inline _LIBCPP_INLINE_VISIBILITY void __deallocate ( value_type* __ptr ) noexcept + { + ::operator delete (static_cast<void *> (__ptr)); + } + +public: + + explicit dynarray(size_type __c); + dynarray(size_type __c, const value_type& __v); + dynarray(const dynarray& __d); + dynarray(initializer_list<value_type>); + +// We're not implementing these right now. +// Waiting for the resolution of LWG issue #2235 +// template <typename _Alloc> +// dynarray(size_type __c, const _Alloc& __alloc); +// template <typename _Alloc> +// dynarray(size_type __c, const value_type& __v, const _Alloc& __alloc); +// template <typename _Alloc> +// dynarray(const dynarray& __d, const _Alloc& __alloc); +// template <typename _Alloc> +// dynarray(initializer_list<value_type>, const _Alloc& __alloc); + + dynarray& operator=(const dynarray&) = delete; + ~dynarray(); + + // iterators: + inline _LIBCPP_INLINE_VISIBILITY iterator begin() noexcept { return iterator(data()); } + inline _LIBCPP_INLINE_VISIBILITY const_iterator begin() const noexcept { return const_iterator(data()); } + inline _LIBCPP_INLINE_VISIBILITY const_iterator cbegin() const noexcept { return const_iterator(data()); } + inline _LIBCPP_INLINE_VISIBILITY iterator end() noexcept { return iterator(data() + __size_); } + inline _LIBCPP_INLINE_VISIBILITY const_iterator end() const noexcept { return const_iterator(data() + __size_); } + inline _LIBCPP_INLINE_VISIBILITY const_iterator cend() const noexcept { return const_iterator(data() + __size_); } + + inline _LIBCPP_INLINE_VISIBILITY reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } + inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } + inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } + inline _LIBCPP_INLINE_VISIBILITY reverse_iterator rend() noexcept { return reverse_iterator(begin()); } + inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); } + inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } + + // capacity: + inline _LIBCPP_INLINE_VISIBILITY size_type size() const noexcept { return __size_; } + inline _LIBCPP_INLINE_VISIBILITY size_type max_size() const noexcept { return __size_; } + inline _LIBCPP_INLINE_VISIBILITY bool empty() const noexcept { return __size_ == 0; } + + // element access: + inline _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __n) { return data()[__n]; } + inline _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __n) const { return data()[__n]; } + + inline _LIBCPP_INLINE_VISIBILITY reference front() { return data()[0]; } + inline _LIBCPP_INLINE_VISIBILITY const_reference front() const { return data()[0]; } + inline _LIBCPP_INLINE_VISIBILITY reference back() { return data()[__size_-1]; } + inline _LIBCPP_INLINE_VISIBILITY const_reference back() const { return data()[__size_-1]; } + + inline _LIBCPP_INLINE_VISIBILITY const_reference at(size_type __n) const; + inline _LIBCPP_INLINE_VISIBILITY reference at(size_type __n); + + // data access: + inline _LIBCPP_INLINE_VISIBILITY _Tp* data() noexcept { return __base_; } + inline _LIBCPP_INLINE_VISIBILITY const _Tp* data() const noexcept { return __base_; } + + // mutating member functions: + inline _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __v) { fill_n(begin(), __size_, __v); } +}; + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY +dynarray<_Tp>::dynarray(size_type __c) : dynarray () +{ + __base_ = __allocate (__c); + value_type *__data = data (); + for ( __size_ = 0; __size_ < __c; ++__size_, ++__data ) + ::new (__data) value_type; +} + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY +dynarray<_Tp>::dynarray(size_type __c, const value_type& __v) : dynarray () +{ + __base_ = __allocate (__c); + value_type *__data = data (); + for ( __size_ = 0; __size_ < __c; ++__size_, ++__data ) + ::new (__data) value_type (__v); +} + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY +dynarray<_Tp>::dynarray(initializer_list<value_type> __il) : dynarray () +{ + size_t sz = __il.size(); + __base_ = __allocate (sz); + value_type *__data = data (); + auto src = __il.begin(); + for ( __size_ = 0; __size_ < sz; ++__size_, ++__data, ++src ) + ::new (__data) value_type (*src); +} + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY +dynarray<_Tp>::dynarray(const dynarray& __d) : dynarray () +{ + size_t sz = __d.size(); + __base_ = __allocate (sz); + value_type *__data = data (); + auto src = __d.begin(); + for ( __size_ = 0; __size_ < sz; ++__size_, ++__data, ++src ) + ::new (__data) value_type (*src); +} + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY +dynarray<_Tp>::~dynarray() +{ + value_type *__data = data () + __size_; + for ( size_t i = 0; i < __size_; ++i ) + (--__data)->value_type::~value_type(); + __deallocate ( __base_ ); +} + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY +typename dynarray<_Tp>::reference +dynarray<_Tp>::at(size_type __n) +{ + if (__n >= __size_) + { +#ifndef _LIBCPP_NO_EXCEPTIONS + throw out_of_range("dynarray::at"); +#else + assert(!"dynarray::at out_of_range"); +#endif + } + return data()[__n]; +} + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY +typename dynarray<_Tp>::const_reference +dynarray<_Tp>::at(size_type __n) const +{ + if (__n >= __size_) + { +#ifndef _LIBCPP_NO_EXCEPTIONS + throw out_of_range("dynarray::at"); +#else + assert(!"dynarray::at out_of_range"); +#endif + } + return data()[__n]; +} + +}}} + + +_LIBCPP_BEGIN_NAMESPACE_STD +template <class _Tp, class _Alloc> +struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<std::experimental::dynarray<_Tp>, _Alloc> : true_type {}; +_LIBCPP_END_NAMESPACE_STD + +#endif // if _LIBCPP_STD_VER > 11 +#endif // _LIBCPP_DYNARRAY diff --git a/system/include/libcxx/experimental/optional b/system/include/libcxx/experimental/optional new file mode 100644 index 00000000..3848da87 --- /dev/null +++ b/system/include/libcxx/experimental/optional @@ -0,0 +1,699 @@ +// -*- 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 <initializer_list> + +namespace std { namespace experimental { + +// optional for object types +template <class T> +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<T>::value); + constexpr optional(const T&); + constexpr optional(T&&); + template <class... Args> constexpr explicit optional(in_place_t, Args&&...); + template <class U, class... Args> + constexpr explicit optional(in_place_t, initializer_list<U>, Args&&...); + + // destructor + ~optional(); + + // assignment + optional& operator=(nullopt_t) noexcept; + optional& operator=(const optional&); + optional& operator=(optional&&) + noexcept(is_nothrow_move_assignable<T>::value && + is_nothrow_move_constructible<T>::value); + template <class U> optional& operator=(U&&); + template <class... Args> void emplace(Args&&...); + template <class U, class... Args> void emplace(initializer_list<U>, Args&&...); + + // swap + void swap(optional&) + noexcept(is_nothrow_move_constructible<T>::value && + noexcept(swap(declval<T&>(), declval<T&>()))); + + // 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 <class U> constexpr T value_or(U&&) const&; + template <class U> 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 <class T> constexpr bool operator==(const optional<T>&, const optional<T>&); +template <class T> constexpr bool operator< (const optional<T>&, const optional<T>&); + +// Comparison with nullopt +template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept; +template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept; +template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept; +template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept; + +// Comparison with T +template <class T> constexpr bool operator==(const optional<T>&, const T&); +template <class T> constexpr bool operator==(const T&, const optional<T>&); +template <class T> constexpr bool operator<(const optional<T>&, const T&); +template <class T> constexpr bool operator<(const T&, const optional<T>&); + +// Specialized algorithms +template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below); +template <class T> constexpr optional<typename decay<T>::type> make_optional(T&&); + +// hash support +template <class T> struct hash; +template <class T> struct hash<optional<T>>; + +}} // std::experimental + +*/ + +#include <__config> +#include <functional> +#include <stdexcept> + +namespace std { namespace experimental { + +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::experimental + +#if _LIBCPP_STD_VER > 11 + +#include <initializer_list> +#include <type_traits> +#include <new> +#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 + +namespace std { namespace experimental { inline namespace __library_fundamentals_v1 { + +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 <class _Tp, bool = is_trivially_destructible<_Tp>::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_type>::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 <class... _Args> + _LIBCPP_INLINE_VISIBILITY + constexpr + explicit __optional_storage(in_place_t, _Args&&... __args) + : __val_(_VSTD::forward<_Args>(__args)...), + __engaged_(true) {} +}; + +template <class _Tp> +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_type>::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 <class... _Args> + _LIBCPP_INLINE_VISIBILITY + constexpr + explicit __optional_storage(in_place_t, _Args&&... __args) + : __val_(_VSTD::forward<_Args>(__args)...), + __engaged_(true) {} +}; + +template <class _Tp> +class optional + : private __optional_storage<_Tp> +{ + typedef __optional_storage<_Tp> __base; +public: + typedef _Tp value_type; + + static_assert(!is_reference<value_type>::value, + "Instantiation of optional with a reference type is ill-formed."); + static_assert(!is_same<typename remove_cv<value_type>::type, in_place_t>::value, + "Instantiation of optional with a in_place_t type is ill-formed."); + static_assert(!is_same<typename remove_cv<value_type>::type, nullopt_t>::value, + "Instantiation of optional with a nullopt_t type is ill-formed."); + static_assert(is_object<value_type>::value, + "Instantiation of optional with a non-object type is undefined behavior."); + static_assert(is_nothrow_destructible<value_type>::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 <class... _Args, + class = typename enable_if + < + is_constructible<value_type, _Args...>::value + >::type + > + _LIBCPP_INLINE_VISIBILITY + constexpr + explicit optional(in_place_t, _Args&&... __args) + : __base(in_place, _VSTD::forward<_Args>(__args)...) {} + + template <class _Up, class... _Args, + class = typename enable_if + < + is_constructible<value_type, initializer_list<_Up>&, _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_type>::value && + is_nothrow_move_constructible<value_type>::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 <class _Up, + class = typename enable_if + < + is_same<typename remove_reference<_Up>::type, value_type>::value && + is_constructible<value_type, _Up>::value && + is_assignable<value_type&, _Up>::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 <class... _Args, + class = typename enable_if + < + is_constructible<value_type, _Args...>::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 <class _Up, class... _Args, + class = typename enable_if + < + is_constructible<value_type, initializer_list<_Up>&, _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_type>::value && + __is_nothrow_swappable<value_type>::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<value_type>{}); + } + + _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<T>::value: not engaged"); + return this->__val_; + } + + _LIBCPP_INLINE_VISIBILITY + value_type& value() + { + if (!this->__engaged_) + throw bad_optional_access("optional<T>::value: not engaged"); + return this->__val_; + } + + template <class _Up> + _LIBCPP_INLINE_VISIBILITY + constexpr value_type value_or(_Up&& __v) const& + { + static_assert(is_copy_constructible<value_type>::value, + "optional<T>::value_or: T must be copy constructible"); + static_assert(is_convertible<_Up, value_type>::value, + "optional<T>::value_or: U must be convertible to T"); + return this->__engaged_ ? this->__val_ : + static_cast<value_type>(_VSTD::forward<_Up>(__v)); + } + + template <class _Up> + _LIBCPP_INLINE_VISIBILITY + value_type value_or(_Up&& __v) && + { + static_assert(is_move_constructible<value_type>::value, + "optional<T>::value_or: T must be move constructible"); + static_assert(is_convertible<_Up, value_type>::value, + "optional<T>::value_or: U must be convertible to T"); + return this->__engaged_ ? _VSTD::move(this->__val_) : + static_cast<value_type>(_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 <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator==(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + if (static_cast<bool>(__x) != static_cast<bool>(__y)) + return false; + if (!static_cast<bool>(__x)) + return true; + return *__x == *__y; +} + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator<(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + if (!static_cast<bool>(__y)) + return false; + if (!static_cast<bool>(__x)) + return true; + return less<_Tp>{}(*__x, *__y); +} + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator==(const optional<_Tp>& __x, nullopt_t) noexcept +{ + return !static_cast<bool>(__x); +} + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator==(nullopt_t, const optional<_Tp>& __x) noexcept +{ + return !static_cast<bool>(__x); +} + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator<(const optional<_Tp>&, nullopt_t) noexcept +{ + return false; +} + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator<(nullopt_t, const optional<_Tp>& __x) noexcept +{ + return static_cast<bool>(__x); +} + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator==(const optional<_Tp>& __x, const _Tp& __v) +{ + return static_cast<bool>(__x) ? *__x == __v : false; +} + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator==(const _Tp& __v, const optional<_Tp>& __x) +{ + return static_cast<bool>(__x) ? *__x == __v : false; +} + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator<(const optional<_Tp>& __x, const _Tp& __v) +{ + return static_cast<bool>(__x) ? less<_Tp>{}(*__x, __v) : true; +} + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator<(const _Tp& __v, const optional<_Tp>& __x) +{ + return static_cast<bool>(__x) ? less<_Tp>{}(__v, *__x) : false; +} + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY +void +swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) +{ + __x.swap(__y); +} + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY +constexpr +optional<typename decay<_Tp>::type> +make_optional(_Tp&& __v) +{ + return optional<typename decay<_Tp>::type>(_VSTD::forward<_Tp>(__v)); +} + +}}} // namespace std::experimental::__library_fundamentals_v1 + +_LIBCPP_BEGIN_NAMESPACE_STD + +template <class _Tp> +struct _LIBCPP_TYPE_VIS_ONLY hash<std::experimental::optional<_Tp> > +{ + typedef std::experimental::optional<_Tp> argument_type; + typedef size_t result_type; + + _LIBCPP_INLINE_VISIBILITY + result_type operator()(const argument_type& __opt) const _NOEXCEPT + { + return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0; + } +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 11 + +#endif // _LIBCPP_ARRAY |