@@ -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