12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef BASE_MAC_SCOPED_BLOCK_H_
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define BASE_MAC_SCOPED_BLOCK_H_
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <Block.h>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/compiler_specific.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_policy.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace base {
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace mac {
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ScopedBlock<> is patterned after ScopedCFTypeRef<>, but uses Block_copy() and
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Block_release() instead of CFRetain() and CFRelease().
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template<typename B>
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ScopedBlock {
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit ScopedBlock(
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      B block = NULL,
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::scoped_policy::OwnershipPolicy policy = base::scoped_policy::ASSUME)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : block_(block) {
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (block_ && policy == base::scoped_policy::RETAIN)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      block_ = Block_copy(block);
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedBlock(const ScopedBlock<B>& that)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : block_(that.block_) {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (block_)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      block_ = Block_copy(block_);
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ~ScopedBlock() {
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (block_)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Block_release(block_);
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedBlock& operator=(const ScopedBlock<B>& that) {
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    reset(that.get(), base::scoped_policy::RETAIN);
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return *this;
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void reset(B block = NULL,
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             base::scoped_policy::OwnershipPolicy policy =
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::scoped_policy::ASSUME) {
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (block && policy == base::scoped_policy::RETAIN)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      block = Block_copy(block);
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (block_)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Block_release(block_);
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    block_ = block;
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool operator==(B that) const {
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return block_ == that;
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool operator!=(B that) const {
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return block_ != that;
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  operator B() const {
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return block_;
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  B get() const {
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return block_;
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void swap(ScopedBlock& that) {
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    B temp = that.block_;
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    that.block_ = block_;
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    block_ = temp;
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  B release() WARN_UNUSED_RESULT {
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    B temp = block_;
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    block_ = NULL;
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return temp;
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  B block_;
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace mac
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace base
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // BASE_MAC_SCOPED_BLOCK_H_
93