OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef BASE_MAC_SCOPED_BLOCK_H_ | 5 #ifndef BASE_MAC_SCOPED_BLOCK_H_ |
6 #define BASE_MAC_SCOPED_BLOCK_H_ | 6 #define BASE_MAC_SCOPED_BLOCK_H_ |
7 | 7 |
8 #include <Block.h> | 8 #include <Block.h> |
9 | 9 |
10 #include "base/compiler_specific.h" | 10 #include "base/mac/scoped_typeref.h" |
11 #include "base/memory/scoped_policy.h" | |
12 | 11 |
13 namespace base { | 12 namespace base { |
14 namespace mac { | 13 namespace mac { |
15 | 14 |
| 15 namespace internal { |
| 16 |
| 17 template <typename B> |
| 18 struct ScopedBlockTraits { |
| 19 static B InvalidValue() { return nullptr; } |
| 20 static B Retain(B block) { return Block_copy(block); } |
| 21 static void Release(B block) { Block_release(block); } |
| 22 }; |
| 23 |
| 24 } // namespace internal |
| 25 |
16 // ScopedBlock<> is patterned after ScopedCFTypeRef<>, but uses Block_copy() and | 26 // ScopedBlock<> is patterned after ScopedCFTypeRef<>, but uses Block_copy() and |
17 // Block_release() instead of CFRetain() and CFRelease(). | 27 // Block_release() instead of CFRetain() and CFRelease(). |
18 | 28 |
19 template<typename B> | 29 template <typename B> |
20 class ScopedBlock { | 30 using ScopedBlock = ScopedTypeRef<B, internal::ScopedBlockTraits<B>>; |
21 public: | |
22 explicit ScopedBlock( | |
23 B block = nullptr, | |
24 base::scoped_policy::OwnershipPolicy policy = base::scoped_policy::ASSUME) | |
25 : block_(block) { | |
26 if (block_ && policy == base::scoped_policy::RETAIN) | |
27 block_ = Block_copy(block); | |
28 } | |
29 | |
30 ScopedBlock(const ScopedBlock<B>& that) | |
31 : block_(that.block_) { | |
32 if (block_) | |
33 block_ = Block_copy(block_); | |
34 } | |
35 | |
36 ~ScopedBlock() { | |
37 if (block_) | |
38 Block_release(block_); | |
39 } | |
40 | |
41 ScopedBlock& operator=(const ScopedBlock<B>& that) { | |
42 reset(that.get(), base::scoped_policy::RETAIN); | |
43 return *this; | |
44 } | |
45 | |
46 void reset(B block = nullptr, | |
47 base::scoped_policy::OwnershipPolicy policy = | |
48 base::scoped_policy::ASSUME) { | |
49 if (block && policy == base::scoped_policy::RETAIN) | |
50 block = Block_copy(block); | |
51 if (block_) | |
52 Block_release(block_); | |
53 block_ = block; | |
54 } | |
55 | |
56 bool operator==(B that) const { | |
57 return block_ == that; | |
58 } | |
59 | |
60 bool operator!=(B that) const { | |
61 return block_ != that; | |
62 } | |
63 | |
64 operator B() const { | |
65 return block_; | |
66 } | |
67 | |
68 B get() const { | |
69 return block_; | |
70 } | |
71 | |
72 void swap(ScopedBlock& that) { | |
73 B temp = that.block_; | |
74 that.block_ = block_; | |
75 block_ = temp; | |
76 } | |
77 | |
78 B release() WARN_UNUSED_RESULT { | |
79 B temp = block_; | |
80 block_ = nullptr; | |
81 return temp; | |
82 } | |
83 | |
84 private: | |
85 B block_; | |
86 }; | |
87 | 31 |
88 } // namespace mac | 32 } // namespace mac |
89 } // namespace base | 33 } // namespace base |
90 | 34 |
91 #endif // BASE_MAC_SCOPED_BLOCK_H_ | 35 #endif // BASE_MAC_SCOPED_BLOCK_H_ |
OLD | NEW |