HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_StaticInit.h
Go to the documentation of this file.
1 //
2 // Copyright 2017 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 _GUSD_UT_STATICINIT_H_
25 #define _GUSD_UT_STATICINIT_H_
26 
27 #include "pxr/pxr.h"
28 
29 #include <UT/UT_Lock.h>
30 
31 #include <type_traits>
32 
34 
35 /** Helper for creating a static value, whose construction
36  is deferred and backed by a lock.
37  This is similar to UT_SingletonWithLock, except that the value held
38  is the result of calling method, rather than constructing an object.
39 
40  Example usage:
41 
42  @code
43  T* someFn();
44  static auto staticVal(GusdUT_StaticVal(someFn));
45 
46  // Function is not exec'd until accessed.
47  // To access:
48  T* val = *staticVal;
49  // Or:
50  staticVal->method();
51  @endcode */
52 template <typename Fn>
54 {
55 public:
57  using T = decltype(std::declval<Fn&>()());
58 
60  : _val(NULL), _fn(fn), _lock() {}
61 
63  : _fn(o._fn)
64  {
65  if(_val) delete _val;
66  _val = o._val;
67  }
68 
70  { if(_val) delete _val; }
71 
72  T& operator*() { return *get(); }
73  T* operator->() { return get(); }
74 
75  T* get()
76  {
77  if(!_val) {
78  UT_AutoLock lock(_lock);
79  if(!_val) {
80  _val = new T();
81  *_val = _fn();
82  }
83  }
84  return _val;
85  }
86 
87 private:
88  Fn& _fn;
89  UT_Lock _lock;
90  T* _val;
91 };
92 
93 /** Helper for constructing static values.
94  This allows automatic template deduction of the function.*/
95 template <typename Fn>
97 GusdUT_StaticVal(const Fn& fn)
98 {
99  return GusdUT_StaticValHolder<Fn>(fn);
100 }
101 
103 
104 
105 #endif /*_GUSD_UT_STATICINIT_H_*/
decltype(std::declval< Fn & >()()) T
Definition: UT_StaticInit.h:57
GusdUT_StaticValHolder< Fn > GusdUT_StaticVal(const Fn &fn)
Definition: UT_StaticInit.h:97
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1441
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
GusdUT_StaticValHolder< Fn > This
Definition: UT_StaticInit.h:56
GusdUT_StaticValHolder(This &&o) noexcept
Definition: UT_StaticInit.h:62