diff options
Diffstat (limited to 'libcxx/include/functional')
-rw-r--r-- | libcxx/include/functional | 137 |
1 files changed, 112 insertions, 25 deletions
diff --git a/libcxx/include/functional b/libcxx/include/functional index 865a28123b97..3e9425320fc3 100644 --- a/libcxx/include/functional +++ b/libcxx/include/functional @@ -508,6 +508,10 @@ POLICY: For non-variadic implementations, the number of arguments is limited #include <__functional_base> +#if defined(_LIBCPP_HAS_BLOCKS_RUNTIME) && !defined(_LIBCPP_HAS_OBJC_ARC) +#include <Block.h> +#endif + #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif @@ -1434,7 +1438,14 @@ void __throw_bad_function_call() #endif } -template<class _Fp> class _LIBCPP_TEMPLATE_VIS function; // undefined +#if defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) && __has_attribute(deprecated) +# define _LIBCPP_DEPRECATED_CXX03_FUNCTION \ + __attribute__((deprecated("Using std::function in C++03 is not supported anymore. Please upgrade to C++11 or later, or use a different type"))) +#else +# define _LIBCPP_DEPRECATED_CXX03_FUNCTION /* nothing */ +#endif + +template<class _Fp> class _LIBCPP_DEPRECATED_CXX03_FUNCTION _LIBCPP_TEMPLATE_VIS function; // undefined namespace __function { @@ -1477,6 +1488,12 @@ template <class _Fp> _LIBCPP_INLINE_VISIBILITY bool __not_null(function<_Fp> const& __f) { return !!__f; } +#ifdef _LIBCPP_HAS_EXTENSION_BLOCKS +template <class _Rp, class ..._Args> +_LIBCPP_INLINE_VISIBILITY +bool __not_null(_Rp (^__p)(_Args...)) { return __p; } +#endif + } // namespace __function #ifndef _LIBCPP_CXX03_LANG @@ -1611,7 +1628,7 @@ public: // __base provides an abstract interface for copyable functors. -template<class _Fp> class __base; +template<class _Fp> class _LIBCPP_TEMPLATE_VIS __base; template<class _Rp, class ..._ArgTypes> class __base<_Rp(_ArgTypes...)> @@ -2238,6 +2255,72 @@ template <class _Rp, class... _ArgTypes> class __policy_func<_Rp(_ArgTypes...)> #endif // _LIBCPP_NO_RTTI }; +#if defined(_LIBCPP_HAS_BLOCKS_RUNTIME) && !defined(_LIBCPP_HAS_OBJC_ARC) + +template<class _Rp1, class ..._ArgTypes1, class _Alloc, class _Rp, class ..._ArgTypes> +class __func<_Rp1(^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)> + : public __base<_Rp(_ArgTypes...)> +{ + typedef _Rp1(^__block_type)(_ArgTypes1...); + __block_type __f_; + +public: + _LIBCPP_INLINE_VISIBILITY + explicit __func(__block_type const& __f) + : __f_(__f ? Block_copy(__f) : (__block_type)0) + { } + + // [TODO] add && to save on a retain + + _LIBCPP_INLINE_VISIBILITY + explicit __func(__block_type __f, const _Alloc& /* unused */) + : __f_(__f ? Block_copy(__f) : (__block_type)0) + { } + + virtual __base<_Rp(_ArgTypes...)>* __clone() const { + _LIBCPP_ASSERT(false, + "Block pointers are just pointers, so they should always fit into " + "std::function's small buffer optimization. This function should " + "never be invoked."); + return nullptr; + } + + virtual void __clone(__base<_Rp(_ArgTypes...)>* __p) const { + ::new (__p) __func(__f_); + } + + virtual void destroy() _NOEXCEPT { + if (__f_) + Block_release(__f_); + __f_ = 0; + } + + virtual void destroy_deallocate() _NOEXCEPT { + _LIBCPP_ASSERT(false, + "Block pointers are just pointers, so they should always fit into " + "std::function's small buffer optimization. This function should " + "never be invoked."); + } + + virtual _Rp operator()(_ArgTypes&& ... __arg) { + return __invoke(__f_, _VSTD::forward<_ArgTypes>(__arg)...); + } + +#ifndef _LIBCPP_NO_RTTI + virtual const void* target(type_info const& __ti) const _NOEXCEPT { + if (__ti == typeid(__func::__block_type)) + return &__f_; + return (const void*)nullptr; + } + + virtual const std::type_info& target_type() const _NOEXCEPT { + return typeid(__func::__block_type); + } +#endif // _LIBCPP_NO_RTTI +}; + +#endif // _LIBCPP_HAS_EXTENSION_BLOCKS && !_LIBCPP_HAS_OBJC_ARC + } // __function template<class _Rp, class ..._ArgTypes> @@ -2255,14 +2338,14 @@ class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)> template <class _Fp, bool = _And< _IsNotSame<__uncvref_t<_Fp>, function>, - __invokable<_Fp&, _ArgTypes...> + __invokable<_Fp, _ArgTypes...> >::value> struct __callable; template <class _Fp> struct __callable<_Fp, true> { static const bool value = is_same<void, _Rp>::value || - is_convertible<typename __invoke_of<_Fp&, _ArgTypes...>::type, + is_convertible<typename __invoke_of<_Fp, _ArgTypes...>::type, _Rp>::value; }; template <class _Fp> @@ -2272,7 +2355,7 @@ class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)> }; template <class _Fp> - using _EnableIfCallable = typename enable_if<__callable<_Fp>::value>::type; + using _EnableIfLValueCallable = typename enable_if<__callable<_Fp&>::value>::type; public: typedef _Rp result_type; @@ -2283,7 +2366,7 @@ public: function(nullptr_t) _NOEXCEPT {} function(const function&); function(function&&) _NOEXCEPT; - template<class _Fp, class = _EnableIfCallable<_Fp>> + template<class _Fp, class = _EnableIfLValueCallable<_Fp>> function(_Fp); #if _LIBCPP_STD_VER <= 14 @@ -2297,14 +2380,14 @@ public: function(allocator_arg_t, const _Alloc&, const function&); template<class _Alloc> function(allocator_arg_t, const _Alloc&, function&&); - template<class _Fp, class _Alloc, class = _EnableIfCallable<_Fp>> + template<class _Fp, class _Alloc, class = _EnableIfLValueCallable<_Fp>> function(allocator_arg_t, const _Alloc& __a, _Fp __f); #endif function& operator=(const function&); function& operator=(function&&) _NOEXCEPT; function& operator=(nullptr_t) _NOEXCEPT; - template<class _Fp, class = _EnableIfCallable<_Fp>> + template<class _Fp, class = _EnableIfLValueCallable<typename decay<_Fp>::type>> function& operator=(_Fp&&); ~function(); @@ -2967,14 +3050,14 @@ __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, forward_iterator_tag, forward_iterator_tag) { if (__first2 == __last2) - return make_pair(__first1, __first1); // Everything matches an empty sequence + return _VSTD::make_pair(__first1, __first1); // Everything matches an empty sequence while (true) { // Find first element in sequence 1 that matchs *__first2, with a mininum of loop checks while (true) { if (__first1 == __last1) // return __last1 if no element matches *__first2 - return make_pair(__last1, __last1); + return _VSTD::make_pair(__last1, __last1); if (__pred(*__first1, *__first2)) break; ++__first1; @@ -2985,9 +3068,9 @@ __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, while (true) { if (++__m2 == __last2) // If pattern exhausted, __first1 is the answer (works for 1 element pattern) - return make_pair(__first1, __m1); + return _VSTD::make_pair(__first1, __m1); if (++__m1 == __last1) // Otherwise if source exhaused, pattern not found - return make_pair(__last1, __last1); + return _VSTD::make_pair(__last1, __last1); if (!__pred(*__m1, *__m2)) // if there is a mismatch, restart with a new __first1 { ++__first1; @@ -3009,10 +3092,10 @@ __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, // Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern const _D2 __len2 = __last2 - __first2; if (__len2 == 0) - return make_pair(__first1, __first1); + return _VSTD::make_pair(__first1, __first1); const _D1 __len1 = __last1 - __first1; if (__len1 < __len2) - return make_pair(__last1, __last1); + return _VSTD::make_pair(__last1, __last1); const _RandomAccessIterator1 __s = __last1 - (__len2 - 1); // Start of pattern match can't go beyond here while (true) @@ -3020,7 +3103,7 @@ __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, while (true) { if (__first1 == __s) - return make_pair(__last1, __last1); + return _VSTD::make_pair(__last1, __last1); if (__pred(*__first1, *__first2)) break; ++__first1; @@ -3031,7 +3114,7 @@ __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, while (true) { if (++__m2 == __last2) - return make_pair(__first1, __first1 + __len2); + return _VSTD::make_pair(__first1, __first1 + __len2); ++__m1; // no need to check range on __m1 because __s guarantees we have enough source if (!__pred(*__m1, *__m2)) { @@ -3080,15 +3163,19 @@ using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type; #endif // > C++17 template <class _Container, class _Predicate> -inline void __libcpp_erase_if_container( _Container& __c, _Predicate __pred) -{ - for (typename _Container::iterator __iter = __c.begin(), __last = __c.end(); __iter != __last;) - { - if (__pred(*__iter)) - __iter = __c.erase(__iter); - else - ++__iter; - } +inline typename _Container::size_type +__libcpp_erase_if_container(_Container& __c, _Predicate __pred) { + typename _Container::size_type __old_size = __c.size(); + + const typename _Container::iterator __last = __c.end(); + for (typename _Container::iterator __iter = __c.begin(); __iter != __last;) { + if (__pred(*__iter)) + __iter = __c.erase(__iter); + else + ++__iter; + } + + return __old_size - __c.size(); } _LIBCPP_END_NAMESPACE_STD |