- add sources.
[platform/framework/web/crosswalk.git] / src / base / mac / scoped_nsobject.h
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_SCOPED_NSOBJECT_H_
6 #define BASE_MAC_SCOPED_NSOBJECT_H_
7
8 #import <Foundation/Foundation.h>
9 #include "base/basictypes.h"
10 #include "base/compiler_specific.h"
11
12 namespace base {
13
14 // scoped_nsobject<> is patterned after scoped_ptr<>, but maintains ownership
15 // of an NSObject subclass object.  Style deviations here are solely for
16 // compatibility with scoped_ptr<>'s interface, with which everyone is already
17 // familiar.
18 //
19 // scoped_nsobject<> takes ownership of an object (in the constructor or in
20 // reset()) by taking over the caller's existing ownership claim.  The caller
21 // must own the object it gives to scoped_nsobject<>, and relinquishes an
22 // ownership claim to that object.  scoped_nsobject<> does not call -retain,
23 // callers have to call this manually if appropriate.
24 //
25 // scoped_nsprotocol<> has the same behavior as scoped_nsobject, but can be used
26 // with protocols.
27 //
28 // scoped_nsobject<> is not to be used for NSAutoreleasePools. For
29 // NSAutoreleasePools use ScopedNSAutoreleasePool from
30 // scoped_nsautorelease_pool.h instead.
31 // We check for bad uses of scoped_nsobject and NSAutoreleasePool at compile
32 // time with a template specialization (see below).
33
34 template<typename NST>
35 class scoped_nsprotocol {
36  public:
37   explicit scoped_nsprotocol(NST object = nil) : object_(object) {}
38
39   scoped_nsprotocol(const scoped_nsprotocol<NST>& that)
40       : object_([that.object_ retain]) {
41   }
42
43   ~scoped_nsprotocol() {
44     [object_ release];
45   }
46
47   scoped_nsprotocol& operator=(const scoped_nsprotocol<NST>& that) {
48     reset([that.get() retain]);
49     return *this;
50   }
51
52   void reset(NST object = nil) {
53     // We intentionally do not check that object != object_ as the caller must
54     // either already have an ownership claim over whatever it passes to this
55     // method, or call it with the |RETAIN| policy which will have ensured that
56     // the object is retained once more when reaching this point.
57     [object_ release];
58     object_ = object;
59   }
60
61   bool operator==(NST that) const { return object_ == that; }
62   bool operator!=(NST that) const { return object_ != that; }
63
64   operator NST() const {
65     return object_;
66   }
67
68   NST get() const {
69     return object_;
70   }
71
72   void swap(scoped_nsprotocol& that) {
73     NST temp = that.object_;
74     that.object_ = object_;
75     object_ = temp;
76   }
77
78   // scoped_nsprotocol<>::release() is like scoped_ptr<>::release.  It is NOT a
79   // wrapper for [object_ release].  To force a scoped_nsprotocol<> to call
80   // [object_ release], use scoped_nsprotocol<>::reset().
81   NST release() WARN_UNUSED_RESULT {
82     NST temp = object_;
83     object_ = nil;
84     return temp;
85   }
86
87   // Shift reference to the autorelease pool to be released later.
88   NST autorelease() {
89     return [release() autorelease];
90   }
91
92  private:
93   NST object_;
94 };
95
96 // Free functions
97 template <class C>
98 void swap(scoped_nsprotocol<C>& p1, scoped_nsprotocol<C>& p2) {
99   p1.swap(p2);
100 }
101
102 template <class C>
103 bool operator==(C p1, const scoped_nsprotocol<C>& p2) {
104   return p1 == p2.get();
105 }
106
107 template <class C>
108 bool operator!=(C p1, const scoped_nsprotocol<C>& p2) {
109   return p1 != p2.get();
110 }
111
112 template<typename NST>
113 class scoped_nsobject : public scoped_nsprotocol<NST*> {
114  public:
115   explicit scoped_nsobject(NST* object = nil)
116       : scoped_nsprotocol<NST*>(object) {}
117
118   scoped_nsobject(const scoped_nsobject<NST>& that)
119       : scoped_nsprotocol<NST*>(that) {
120   }
121
122   scoped_nsobject& operator=(const scoped_nsobject<NST>& that) {
123     scoped_nsprotocol<NST*>::operator=(that);
124     return *this;
125   }
126 };
127
128 // Specialization to make scoped_nsobject<id> work.
129 template<>
130 class scoped_nsobject<id> : public scoped_nsprotocol<id> {
131  public:
132   explicit scoped_nsobject(id object = nil) : scoped_nsprotocol<id>(object) {}
133
134   scoped_nsobject(const scoped_nsobject<id>& that)
135       : scoped_nsprotocol<id>(that) {
136   }
137
138   scoped_nsobject& operator=(const scoped_nsobject<id>& that) {
139     scoped_nsprotocol<id>::operator=(that);
140     return *this;
141   }
142 };
143
144 // Do not use scoped_nsobject for NSAutoreleasePools, use
145 // ScopedNSAutoreleasePool instead. This is a compile time check. See details
146 // at top of header.
147 template<>
148 class scoped_nsobject<NSAutoreleasePool> {
149  private:
150   explicit scoped_nsobject(NSAutoreleasePool* object = nil);
151   DISALLOW_COPY_AND_ASSIGN(scoped_nsobject);
152 };
153
154 }  // namespace base
155
156 #endif  // BASE_MAC_SCOPED_NSOBJECT_H_