HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
scoped.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_BASE_TF_SCOPED_H
25 #define PXR_BASE_TF_SCOPED_H
26 
27 #include "pxr/pxr.h"
28 
29 #include <functional>
30 
32 
33 /// \class TfScoped
34 /// \ingroup group_tf_Multithreading
35 ///
36 /// Execute code on exiting scope.
37 ///
38 /// A \c TfScoped executes code when destroyed. It's useful when cleanup code
39 /// should be executed when exiting the scope because it gets executed no
40 /// matter how the scope is exited (e.g. normal execution, return, exceptions,
41 /// etc).
42 ///
43 /// \code
44 /// int func(bool x) {
45 /// TfScoped scope(cleanup);
46 /// return func2(x); // call cleanup after calling func2
47 /// }
48 /// \endcode
49 ///
50 template <typename T = std::function<void ()> >
51 class TfScoped {
52  TfScoped(TfScoped const &) = delete;
53  TfScoped &operator=(TfScoped const &) = delete;
54 public:
55  /// The type of the function executed on destruction.
56  typedef T Procedure;
57 
58  /// Execute \p leave when this object goes out of scope.
59  explicit TfScoped(const Procedure& leave) : _onExit(leave) { }
60 
61  ~TfScoped() { _onExit(); }
62 
63 private:
64  // Can't put these on the heap. No implementation needed.
65  static void *operator new(::std::size_t size);
66 
67 private:
68  Procedure _onExit;
69 };
70 
71 // Specialization of TfScoped for member functions.
72 template <typename T>
73 class TfScoped<void (T::*)()> {
74  TfScoped(TfScoped const &) = delete;
75  TfScoped &operator=(TfScoped const &) = delete;
76 public:
77  /// The type of the function executed on destruction.
78  typedef void (T::*Procedure)();
79 
80  /// Execute \p leave on \p obj when this object goes out of scope.
81  explicit TfScoped(T* obj, const Procedure& leave) :
82  _obj(obj), _onExit(leave) { }
83 
84  ~TfScoped() { (_obj->*_onExit)(); }
85 
86 private:
87  // Can't put these on the heap. No implementation needed.
88  static void *operator new(::std::size_t size);
89 
90 private:
91  T* _obj;
92  Procedure _onExit;
93 };
94 
95 // Specialization of TfScoped for functions taking one pointer argument.
96 template <typename T>
97 class TfScoped<void (*)(T*)> {
98  TfScoped(TfScoped const &) = delete;
99  TfScoped &operator=(TfScoped const &) = delete;
100 public:
101  /// The type of the function executed on destruction.
102  typedef void (*Procedure)(T*);
103 
104  /// Execute \p leave, passing \p obj, when this object goes out of scope.
105  explicit TfScoped(const Procedure& leave, T* obj) :
106  _obj(obj), _onExit(leave) { }
107 
108  ~TfScoped() { _onExit(_obj); }
109 
110 private:
111  // Can't put these on the heap. No implementation needed.
112  static void *operator new(::std::size_t size);
113 
114 private:
115  T* _obj;
116  Procedure _onExit;
117 };
118 
119 /// \class TfScopedVar
120 ///
121 /// Reset variable on exiting scope.
122 ///
123 /// A \c TfScopedVar sets a variable to a value when created then restores its
124 /// original value when destroyed. For example:
125 ///
126 /// \code
127 /// int func(bool x) {
128 /// TfScopedVar<bool> scope(x, true); // set x to true
129 /// return func2(x); // restore x after calling func2
130 /// }
131 /// \endcode
132 template <typename T>
133 class TfScopedVar {
134  TfScopedVar(TfScopedVar const &) = delete;
135  TfScopedVar &operator=(TfScopedVar const &) = delete;
136 public:
137  /// Set/reset variable
138  ///
139  /// Sets \p x to \p val immediately and restores its old value when this
140  /// goes out of scope.
141  explicit TfScopedVar(T& x, const T& val) :
142  _x(&x),
143  _old(x)
144  {
145  x = val;
146  }
147 
148  ~TfScopedVar() { *_x = _old; }
149 
150 private:
151  // Can't put these on the heap. No implementation needed.
152  static void *operator new(::std::size_t size);
153 
154 private:
155  T* _x;
156  T _old;
157 };
158 
159 /// \class TfScopedAutoVar
160 ///
161 /// Reset variable on exiting scope.
162 ///
163 /// A \c TfScopedAutoVar sets a variable to a value when created then restores
164 /// its original value when destroyed.
165 ///
166 /// For example:
167 /// \code
168 /// int func(bool x) {
169 /// TfScopedAutoVar scope(x, true); // set x to true
170 /// return func2(x); // restore x after calling func2
171 /// }
172 /// \endcode
173 ///
174 /// This differs from \c TfScopedVar in that it's not a template class, the
175 /// value type is deduced automatically and it allocates memory on the heap.
176 /// If performance is critical or memory must not be allocated then use \c
177 /// TfScopedVar instead.
178 ///
179 /// \see TfScopedVar
181  TfScopedAutoVar(TfScopedAutoVar const &) = delete;
182  TfScopedAutoVar &operator=(TfScopedAutoVar const &) = delete;
183 public:
184  /// Set/reset variable
185  ///
186  /// Sets \p x to \p val immediately and restores its old value when this
187  /// goes out of scope.
188  template <typename T>
189  explicit TfScopedAutoVar(T& x, const T& val) :
190  _scope(std::bind(&TfScopedAutoVar::_Set<T>, &x, x))
191  {
192  x = val;
193  }
194 
195 private:
196  // Restore value function
197  template <typename T>
198  static void _Set(T* x, const T& val)
199  {
200  *x = val;
201  }
202 
203  // Can't put these on the heap. No implementation needed.
204  static void *operator new(::std::size_t size);
205 
206 private:
207  TfScoped<> _scope;
208 };
209 
211 
212 #endif // PXR_BASE_TF_SCOPED_H
~TfScopedVar()
Definition: scoped.h:148
void
Definition: png.h:1083
~TfScoped()
Definition: scoped.h:61
TfScoped(const Procedure &leave, T *obj)
Execute leave, passing obj, when this object goes out of scope.
Definition: scoped.h:105
TfScoped(T *obj, const Procedure &leave)
Execute leave on obj when this object goes out of scope.
Definition: scoped.h:81
GLint GLenum GLint x
Definition: glcorearb.h:409
T Procedure
The type of the function executed on destruction.
Definition: scoped.h:56
GLsizeiptr size
Definition: glcorearb.h:664
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1441
GLuint GLfloat * val
Definition: glcorearb.h:1608
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
TfScopedVar(T &x, const T &val)
Definition: scoped.h:141
TfScoped(const Procedure &leave)
Execute leave when this object goes out of scope.
Definition: scoped.h:59
TfScopedAutoVar(T &x, const T &val)
Definition: scoped.h:189