Home | History | Annotate | Download | only in mac
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef BASE_MAC_BIND_OBJC_BLOCK_H_
      6 #define BASE_MAC_BIND_OBJC_BLOCK_H_
      7 
      8 #include <Block.h>
      9 
     10 #include "base/bind.h"
     11 #include "base/callback_forward.h"
     12 #include "base/mac/scoped_block.h"
     13 
     14 // BindBlock builds a callback from an Objective-C block. Example usages:
     15 //
     16 // Closure closure = BindBlock(^{DoSomething();});
     17 //
     18 // Callback<int(void)> callback = BindBlock(^{return 42;});
     19 //
     20 // Callback<void(const std::string&, const std::string&)> callback =
     21 //     BindBlock(^(const std::string& arg0, const std::string& arg1) {
     22 //         ...
     23 //     });
     24 //
     25 // These variadic templates will accommodate any number of arguments, however
     26 // the underlying templates in bind_internal.h and callback.h are limited to
     27 // seven total arguments, and the bound block itself is used as one of these
     28 // arguments, so functionally the templates are limited to binding blocks with
     29 // zero through six arguments.
     30 
     31 namespace base {
     32 
     33 namespace internal {
     34 
     35 // Helper function to run the block contained in the parameter.
     36 template<typename R, typename... Args>
     37 R RunBlock(base::mac::ScopedBlock<R(^)(Args...)> block, Args... args) {
     38   R(^extracted_block)(Args...) = block.get();
     39   return extracted_block(args...);
     40 }
     41 
     42 }  // namespace internal
     43 
     44 // Construct a callback from an objective-C block with up to six arguments (see
     45 // note above).
     46 template<typename R, typename... Args>
     47 base::Callback<R(Args...)> BindBlock(R(^block)(Args...)) {
     48   return base::Bind(
     49       &base::internal::RunBlock<R, Args...>,
     50       base::mac::ScopedBlock<R (^)(Args...)>(
     51           base::mac::internal::ScopedBlockTraits<R (^)(Args...)>::Retain(
     52               block)));
     53 }
     54 
     55 }  // namespace base
     56 
     57 #endif  // BASE_MAC_BIND_OBJC_BLOCK_H_
     58