Logo ROOT   master
Reference Guide
CocoaUtils.h
Go to the documentation of this file.
1 // @(#)root/graf2d:$Id$
2 // Author: Timur Pocheptsov 6/12/2011
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2012, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #ifndef ROOT_CocoaUtils
13 #define ROOT_CocoaUtils
14 
15 #include <cstddef>
16 #include <cassert>
17 
18 #include <Foundation/Foundation.h>
19 
20 namespace ROOT {
21 namespace MacOSX {
22 namespace Util {
23 
24 /////////////////////////////////////////////////////////////////////
25 // //
26 // NSStrongReference. Class to keep strong reference to NSObject. //
27 // //
28 /////////////////////////////////////////////////////////////////////
29 
30 template<class DerivedType>
32 public:
34  : fNSObject(nil)
35  {
36  }
37 
38  explicit NSStrongReference(NSObject *nsObject)
39  : fNSObject([nsObject retain])
40  {
41  }
42 
44  : fNSObject([rhs.fNSObject retain])
45  {
46  }
47 
48 
50  {
51  [fNSObject release];
52  }
53 
55  {
56  if (&rhs != this) {
57  //Even if both reference the same NSObject, it's ok to do release.
58  [fNSObject release];
59  fNSObject = [rhs.fNSObject retain];
60  }
61 
62  return *this;
63  }
64 
66  {
67  fNSObject = rhs.fNSObject;
68  rhs.fNSObject = nil;
69  }
70 
72  {
73  //In case you're smart enough to self assign
74  //(using std::move, for example):
75  assert(this != &rhs);
76 
77  fNSObject = rhs.fNSObject;
78  rhs.fNSObject = nil;
79 
80  return *this;
81  }
82 
83  NSStrongReference &operator = (NSObject *nsObject)
84  {
85  if (nsObject != fNSObject) {
86  [fNSObject release];
87  fNSObject = [nsObject retain];
88  }
89 
90  return *this;
91  }
92 
93  DerivedType *Get()const
94  {
95  return (DerivedType *)fNSObject;
96  }
97 
98  void Reset(NSObject *object)
99  {
100  if (fNSObject != object) {
101  NSObject *obj = [object retain];
102  [fNSObject release];
103  fNSObject = obj;
104  }
105  }
106 
107 private:
108  NSObject *fNSObject;
109 };
110 
111 ///////////////////////////////////////////////////////////////////
112 // //
113 // NSScopeGuard. //
114 // //
115 ///////////////////////////////////////////////////////////////////
116 
117 template<class DerivedType>
119 public:
121  : fNSObject(nil)
122  {
123  }
124 
125  explicit NSScopeGuard(NSObject *nsObject)
126  : fNSObject(nsObject)
127  {
128  }
130  {
131  [fNSObject release];//nothing for nil.
132  }
133 
134 public:
135 
136  DerivedType *Get()const
137  {
138  return (DerivedType *)fNSObject;
139  }
140 
141  void Reset(NSObject *object)
142  {
143  if (object != fNSObject) {
144  [fNSObject release];
145  fNSObject = object;
146  }
147  }
148 
149  NSObject *Release()
150  {
151  NSObject *ret = fNSObject;
152  fNSObject = nil;
153  return ret;
154  }
155 private:
156  NSObject *fNSObject;
157 
158  NSScopeGuard(const NSScopeGuard &rhs);
160 };
161 
162 //////////////////////////////////////
163 // //
164 // RAII class for autorelease pool. //
165 // //
166 //////////////////////////////////////
167 
169 public:
170  explicit AutoreleasePool(bool delayCreation = false);
172 
173  //Drains the previous pool (if any)
174  //and activates a new one.
175  void Reset();
176 
177 private:
178  NSAutoreleasePool *fPool;
179 
180  AutoreleasePool(const AutoreleasePool &rhs);
182 };
183 
184 ///////////////////////////////////////////////////////////
185 // //
186 // Strong reference for a Core Foundation object. //
187 // This class can have specializations for CF object //
188 // with it's own version of retain or release. //
189 // //
190 ///////////////////////////////////////////////////////////
191 
192 template<class RefType>
194 public:
196  : fRef(0)
197  {
198  }
199 
200  CFStrongReference(RefType ref, bool initRetain)
201  : fRef(ref)
202  {
203  if (initRetain && ref)
204  CFRetain(ref);
205  }
206 
208  {
209  fRef = rhs.fRef;
210  if (fRef)
211  CFRetain(fRef);
212  }
213 
215  {
216  if (this != &rhs) {
217  if (fRef)
218  CFRelease(fRef);//Ok even if rhs references the same.
219  fRef = rhs.fRef;
220  if (fRef)
221  CFRetain(fRef);
222  }
223 
224  return *this;
225  }
226 
228  {
229  fRef = rhs.fRef;
230  rhs.fRef = 0;
231  }
232 
234  {
235  // Do not: a = std::move(a) :)
236  assert(this != &rhs);
237 
238  fRef = rhs.fRef;
239  rhs.fRef = 0;
240 
241  return *this;
242  }
243 
245  {
246  if (fRef)
247  CFRelease(fRef);
248  }
249 
250  RefType Get()const
251  {
252  return fRef;
253  }
254 
255 private:
256  RefType fRef;
257 };
258 
259 ///////////////////////////////////////////////////
260 // //
261 // Scope guard for Core Foundations objects. //
262 // Specializations can be defined to call //
263 // something different from CFRetain/CFRelease. //
264 // //
265 ///////////////////////////////////////////////////
266 
267 template<class RefType>
269 public:
271  : fRef(0)
272  {
273  }
274 
275  explicit CFScopeGuard(RefType ref)
276  : fRef(ref)
277  {
278  }
279 
281  {
282  if (fRef)
283  CFRelease(fRef);
284  }
285 
286  RefType Get()const
287  {
288  return fRef;
289  }
290 
291  void Reset(RefType ref)
292  {
293  if (ref != fRef) {
294  if (fRef)
295  CFRelease(fRef);
296  fRef = ref;
297  }
298  }
299 
300  RefType Release()
301  {
302  RefType ret = fRef;
303  fRef = 0;
304  return ret;
305  }
306 
307 private:
308  RefType fRef;
309 
310  CFScopeGuard(const CFScopeGuard &rhs);
312 };
313 
314 ///////////////////////////////////////////////////
315 // //
316 // Scoped array - scope guard for an array. //
317 // Sometimes, I can not use std::vector, //
318 // for example, data is allocated in TGCocoa //
319 // and must be later freed in Objective-C code. //
320 // To make the code exception-safe, I still //
321 // have to care about memory, which is already //
322 // allocated. //
323 // //
324 ///////////////////////////////////////////////////
325 
326 template<class T>
327 class ScopedArray {
328 public:
329  explicit ScopedArray(T * p = 0)
330  : fData(p)
331  {
332  }
333 
335  {
336  delete [] fData;
337  }
338 
339  void Reset(T * p)
340  {
341  if (p != fData)
342  delete [] fData;
343  fData = p;
344  }
345 
347  {
348  T *ret = fData;
349  fData = 0;
350  return ret;
351  }
352 
353  T &operator [] (std::ptrdiff_t index)const
354  {
355  return fData[index];
356  }
357 
358  T *Get()const
359  {
360  return fData;
361  }
362 
363 private:
365 
366  ScopedArray(const ScopedArray &rhs);
367  ScopedArray &operator = (const ScopedArray &rhs);
368 };
369 
370 }//Util
371 }//MacOSX
372 }//ROOT
373 
374 #endif
NSStrongReference(NSStrongReference &&rhs)
Definition: CocoaUtils.h:65
Returns the available number of logical cores.
Definition: StringConv.hxx:21
double T(double x)
Definition: ChebyshevPol.h:34
CFScopeGuard & operator=(const CFScopeGuard &rhs)
NSStrongReference(NSObject *nsObject)
Definition: CocoaUtils.h:38
NSStrongReference & operator=(const NSStrongReference &rhs)
Definition: CocoaUtils.h:54
DerivedType * Get() const
Definition: CocoaUtils.h:136
void Reset(NSObject *object)
Definition: CocoaUtils.h:141
CFStrongReference(RefType ref, bool initRetain)
Definition: CocoaUtils.h:200
CFStrongReference & operator=(const CFStrongReference &rhs)
Definition: CocoaUtils.h:214
AutoreleasePool & operator=(const AutoreleasePool &rhs)
NSStrongReference(const NSStrongReference &rhs)
Definition: CocoaUtils.h:43
CFStrongReference(CFStrongReference &&rhs)
Definition: CocoaUtils.h:227
AutoreleasePool(bool delayCreation=false)
void Reset(NSObject *object)
Definition: CocoaUtils.h:98
NSScopeGuard & operator=(const NSScopeGuard &rhs)
NSScopeGuard(NSObject *nsObject)
Definition: CocoaUtils.h:125
CFStrongReference(const CFStrongReference &rhs)
Definition: CocoaUtils.h:207
T & operator[](std::ptrdiff_t index) const
Definition: CocoaUtils.h:353
ScopedArray & operator=(const ScopedArray &rhs)