summaryrefslogtreecommitdiff
path: root/libcxx/include/functional
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx/include/functional')
-rw-r--r--libcxx/include/functional137
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