HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PRM_AutoDeleter.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * COMMENTS:
7  * This class provides a way to track a set of objects that were allocated
8  * and then delete them later on. It is particularly useful for deleting
9  * elements pointed to by a PRM_Template.
10  *
11  * Note that the objects will be deleted in the *same* order they are
12  * added to the PRM_AutoDeleter.
13  *
14  * Sample usage:
15  *
16  * static void
17  * deleteDefaults(PRM_Default *defaults)
18  * {
19  * for (int i=0; i<defaults->getVectorSize(); ++i)
20  * defaults[i].setString(nullptr, true);// free existing string
21  * delete defaults;
22  * }
23  *
24  * PRM_Template *
25  * newTemplate(PRM_AutoDeleter &deleter)
26  * {
27  * return deleter.append(new PRM_Template(
28  * ...,
29  * deleter.append(new PRM_Range(...)),
30  * deleter.appendCallback(
31  * deleteDefaults, new PRM_Default(...)),
32  * ...));
33  * }
34  *
35  * void
36  * foo()
37  * {
38  * PRM_AutoDeleter deleter;
39  * PRM_Template *prm_template = newTemplate(deleter);
40  *
41  * ...do something with prm_template...
42  *
43  * // When "deleter" is destroyed, it will delete the PRM_Template
44  * // and the things earlier allocated.
45  * }
46  *
47  * Note that if you want a callback to take additional arguments, you
48  * can use lambdas.
49  */
50 
51 #ifndef __PRM_AutoDeleter_h__
52 #define __PRM_AutoDeleter_h__
53 
54 #include "PRM_API.h"
55 #include <UT/UT_Array.h>
56 #include <UT/UT_NonCopyable.h>
57 #include <UT/UT_UniquePtr.h>
58 #include <type_traits>
59 #include <utility>
60 
61 
63 {
64 private:
65  // This base class exists so we can have an array of different types of
66  // deleters.
67  class prm_Deleter : UT_NonCopyable
68  {
69  public:
70  virtual ~prm_Deleter()
71  {}
72  };
73 
74  // This templated class calls delete on a pointer.
75  template <typename T>
76  class prm_ValueDeleter : public prm_Deleter
77  {
78  public:
79  prm_ValueDeleter(T *value)
80  : myPtr(value)
81  {}
82  private:
83  UT_UniquePtr<T> myPtr;
84  };
85 
86  // This templated class calls delete [] on a pointer.
87  template <typename T>
88  class prm_ArrayDeleter : public prm_Deleter
89  {
90  public:
91  prm_ArrayDeleter(T *array)
92  : myArrayPtr(array)
93  {}
94  private:
95  UT_UniquePtr<T[]> myArrayPtr;
96  };
97 
98  // This templated class runs a callback with a pointer. It is up to
99  // the callback to call delete if it wants to.
100  template <typename T, typename CB>
101  class prm_CallbackDeleter : public prm_Deleter
102  {
103  public:
104  prm_CallbackDeleter(const CB &callback, T *value)
105  : myCallback(callback)
106  , myValue(value)
107  {}
108 
109  virtual ~prm_CallbackDeleter()
110  { myCallback(myValue); }
111 
112  private:
113  CB myCallback;
114  T *myValue;
115  };
116 
117 public:
118  // Note that we want objects to be deleted in the order they're added
119  // to the std::vector, so we purposely append them to the end.
120 
121  template <typename T>
123  {
124  if (!value)
125  return nullptr;
126 
127  myDeleters.emplace_back(UTmakeUnique<prm_ValueDeleter<T>>(value));
128  return value;
129  }
130 
131  template <typename T>
132  T *appendArray(T *array)
133  {
134  if (!array)
135  return nullptr;
136 
137  myDeleters.emplace_back(UTmakeUnique<prm_ArrayDeleter<T>>(array));
138  return array;
139  }
140 
141  // Note that appendCallback does not delete the pointer. It's up to you
142  // to delete it from within the callback if that's what you want.
143  template <typename T, typename CB>
144  T *appendCallback(CB &&callback, T *pointer)
145  {
146  if (!pointer)
147  return nullptr;
148 
149  // We need to decay the CB type since it can be a REFERENCE to the
150  // intended callback and we really need to make a copy of it here.
151  using F = typename std::decay<CB>::type;
152  myDeleters.emplace_back(UTmakeUnique<prm_CallbackDeleter<T,F>>(
153  std::forward<CB>(callback), pointer));
154  return pointer;
155  }
156 
157 private:
159 };
160 
161 #endif
exint emplace_back(S &&...s)
Definition: UT_ArrayImpl.h:171
T * appendArray(T *array)
std::enable_if< !std::is_array< T >::value, UT_UniquePtr< T >>::type UTmakeUnique(REST &&...args)
Definition: UT_UniquePtr.h:83
GLsizei const GLfloat * value
Definition: glcorearb.h:823
GLenum void ** pointer
Definition: glcorearb.h:809
T * append(T *value)
T * appendCallback(CB &&callback, T *pointer)
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107