Skip to content

Commit cbef869

Browse files
committed
Fixing clang breakage of makeWeak
1 parent 329215d commit cbef869

File tree

1 file changed

+45
-10
lines changed

1 file changed

+45
-10
lines changed

include/objc-helpers/BlockUtil.h

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -559,9 +559,39 @@ namespace BlockUtil
559559
}
560560

561561
#if __has_feature(objc_arc)
562+
563+
/**
564+
* A wrapper that allows transporting weak pointers
565+
* out of functions. Clang does not allow to return
566+
* a weak pointer.
567+
*/
568+
template<class T>
569+
struct WeakHolder {
570+
T * __weak obj;
571+
572+
operator T *() const { return obj; }
573+
};
574+
575+
/**
576+
* A wrapper that allows transporting weak block pointers
577+
* out of functions. Clang does not allow to return
578+
* a weak pointer.
579+
*/
580+
template<class R, class... Args>
581+
struct WeakHolder<R (Args...)> {
582+
R (^ __weak obj)(Args...);
583+
584+
using StrongType = R (^ __strong)(Args...);
585+
586+
operator StrongType() const { return obj; }
587+
};
562588

563589
/**
564-
Convert strong pointer to a weak pointer of the same type
590+
Convert strong pointer to a weak pointer (wrapper) of the same type
591+
592+
Note that Clang does not allow to return a weak pointer so a wrapper is
593+
returned instead. This wrapper can be passed to makeStrong() or converted to
594+
a normal (weak or strong) ObjC pointer
565595
566596
Usage:
567597
@code
@@ -571,15 +601,20 @@ namespace BlockUtil
571601
@endcode
572602
*/
573603
template<class T>
574-
auto makeWeak(T * __strong obj) -> T * __weak
575-
{ return obj; }
604+
auto makeWeak(T * __strong obj) -> WeakHolder<T>
605+
{ return {obj}; }
576606

577607
/**
578608
Convert strong block pointer to a weak pointer of the same type
609+
610+
Note that Clang does not allow to return a weak pointer so a wrapper is
611+
returned instead. This wrapper can be passed to makeStrong() or converted to
612+
a normal (weak or strong) ObjC pointer
613+
579614
*/
580615
template<class R, class... Args>
581-
auto makeWeak(R (^ __strong obj)(Args...)) -> R (^ __weak)(Args...)
582-
{ return obj; }
616+
auto makeWeak(R (^ __strong obj)(Args...)) -> WeakHolder<R (Args...)>
617+
{ return {obj}; }
583618

584619
/**
585620
Convert weak pointer to a strong pointer of the same type
@@ -594,15 +629,15 @@ namespace BlockUtil
594629
@endcode
595630
*/
596631
template<class T>
597-
auto makeStrong(T * __weak obj) -> T * __strong
598-
{ return obj; }
599-
632+
auto makeStrong(WeakHolder<T> holder) -> T *
633+
{ return holder.obj; }
634+
600635
/**
601636
Convert weak block pointer to a strong pointer of the same type
602637
*/
603638
template<class R, class... Args>
604-
auto makeStrong(R (^ __weak obj)(Args...)) -> R (^ __strong)(Args...)
605-
{ return obj; }
639+
auto makeStrong(WeakHolder<R (Args...)> holder) -> R (^)(Args...)
640+
{ return holder.obj; }
606641

607642
#endif
608643

0 commit comments

Comments
 (0)