// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef BASE_MAC_SCOPED_BLOCK_H_ #define BASE_MAC_SCOPED_BLOCK_H_ #include #include "base/mac/scoped_typeref.h" #if defined(__has_feature) && __has_feature(objc_arc) #define BASE_MAC_BRIDGE_CAST(TYPE, VALUE) (__bridge TYPE)(VALUE) #else #define BASE_MAC_BRIDGE_CAST(TYPE, VALUE) VALUE #endif namespace base { namespace mac { namespace internal { template struct ScopedBlockTraits { static B InvalidValue() { return nullptr; } static B Retain(B block) { return BASE_MAC_BRIDGE_CAST( B, Block_copy(BASE_MAC_BRIDGE_CAST(const void*, block))); } static void Release(B block) { Block_release(BASE_MAC_BRIDGE_CAST(const void*, block)); } }; } // namespace internal // ScopedBlock<> is patterned after ScopedCFTypeRef<>, but uses Block_copy() and // Block_release() instead of CFRetain() and CFRelease(). template class ScopedBlock : public ScopedTypeRef> { public: using Traits = internal::ScopedBlockTraits; #if !defined(__has_feature) || !__has_feature(objc_arc) explicit ScopedBlock( B block = Traits::InvalidValue(), base::scoped_policy::OwnershipPolicy policy = base::scoped_policy::ASSUME) : ScopedTypeRef(block, policy) {} #else explicit ScopedBlock(B block = Traits::InvalidValue()) : ScopedTypeRef(block, base::scoped_policy::RETAIN) {} #endif #if !defined(__has_feature) || !__has_feature(objc_arc) void reset(B block = Traits::InvalidValue(), base::scoped_policy::OwnershipPolicy policy = base::scoped_policy::ASSUME) { ScopedTypeRef::reset(block, policy); } #else void reset(B block = Traits::InvalidValue()) { ScopedTypeRef::reset(block, base::scoped_policy::RETAIN); } #endif }; } // namespace mac } // namespace base #undef BASE_MAC_BRIDGE_CAST #endif // BASE_MAC_SCOPED_BLOCK_H_