Bug 767240 - Make it easier to create type-specific scoped pointers (TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE), r=jwalden
authorBrian Smith <bsmith@mozilla.com>
Tue, 24 Jul 2012 15:36:06 -0700
changeset 114526 7faf6b82017faa0423237cbe1ccacc958ce29b4e
parent 114525 ddf584176a04d21fa0d237827b98ed3a5e59da2a
child 114527 991b5fb6c55aa99fec1cdeaf2a1ca5dba028da0b
push idunknown
push userunknown
push dateunknown
reviewersjwalden
bugs767240
milestone18.0a1
Bug 767240 - Make it easier to create type-specific scoped pointers (TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE), r=jwalden
mfbt/Scoped.h
--- a/mfbt/Scoped.h
+++ b/mfbt/Scoped.h
@@ -38,20 +38,21 @@
  *
  * - if |forget()| has not been called, the resource is always deallocated at
  *   the end of the scope;
  * - if |forget()| has been called, any control on the resource is unbound
  *   and the resource is not deallocated by the class.
  *
  * Extension:
  *
- * In addition, this header provides class |Scoped| and macro |SCOPED_TEMPLATE|
- * to simplify the definition of RAII classes for other scenarios. These macros
- * have been used to automatically close file descriptors/file handles when
- * reaching the end of the scope, graphics contexts, etc.
+ * In addition, this header provides class |Scoped| and macros |SCOPED_TEMPLATE|
+ * and |MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE|  to simplify the definition
+ * of RAII classes for other scenarios. These macros have been used to
+ * automatically close file descriptors/file handles when reaching the end of
+ * the scope, graphics contexts, etc.
  */
 
 #include "mozilla/Attributes.h"
 #include "mozilla/GuardObjects.h"
 
 namespace mozilla {
 
 /*
@@ -218,11 +219,51 @@ SCOPED_TEMPLATE(ScopedDeletePtr, ScopedD
  */
 template<typename T>
 struct ScopedDeleteArrayTraits : public ScopedFreePtrTraits<T>
 {
     static void release(T* ptr) { delete [] ptr; }
 };
 SCOPED_TEMPLATE(ScopedDeleteArray, ScopedDeleteArrayTraits)
 
+/*
+ * MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE makes it easy to create scoped
+ * pointers for types with custom deleters; just overload
+ * TypeSpecificDelete(T*) in the same namespace as T to call the deleter for
+ * type T.
+ *
+ * @param name The name of the class to define.
+ * @param Type A struct implementing clean-up. See the implementations
+ * for more details.
+ * *param Deleter The function that is used to delete/destroy/free a
+ *        non-null value of Type*.
+ *
+ * Example:
+ *
+ *   MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPRFileDesc, PRFileDesc, \
+ *                                             PR_Close)
+ *   ...
+ *   {
+ *       ScopedPRFileDesc file(PR_OpenFile(...));
+ *       ...
+ *   } // file is closed with PR_Close here
+ */
+#define MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(name, Type, Deleter) \
+inline void TypeSpecificDelete(Type * value) { Deleter(value); } \
+typedef ::mozilla::TypeSpecificScopedPointer<Type> name;
+
+template <typename T>
+struct TypeSpecificScopedPointerTraits
+{
+    typedef T* type;
+    const static type empty() { return NULL; }
+    const static void release(type value)
+    {
+      if (value)
+        TypeSpecificDelete(value);
+    }
+};
+
+SCOPED_TEMPLATE(TypeSpecificScopedPointer, TypeSpecificScopedPointerTraits)
+
 } /* namespace mozilla */
 
 #endif // mozilla_Scoped_h_