[beast: 27/57] SFI: provide FriendAllocator<>



commit 6c6dc053b4391ee248071c627c7fe85ea4ccdb00
Author: Tim Janik <timj gnu org>
Date:   Sun Jul 16 20:39:03 2017 +0200

    SFI: provide FriendAllocator<>
    
    Signed-off-by: Tim Janik <timj gnu org>

 sfi/cxxaux.hh |   41 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 41 insertions(+), 0 deletions(-)
---
diff --git a/sfi/cxxaux.hh b/sfi/cxxaux.hh
index b41c102..f94435a 100644
--- a/sfi/cxxaux.hh
+++ b/sfi/cxxaux.hh
@@ -5,6 +5,7 @@
 #include <sfi/sysconfig.h>
 #include <sys/types.h>                  // uint, ssize
 #include <cstdint>                      // uint64_t
+#include <memory>
 #include <vector>
 #include <map>
 
@@ -81,6 +82,46 @@ typedef vector<String> StringVector;    ///< Convenience alias for a std::vector
 #define BSE_DECLARE_VLA(Type, var, count)          Type var[count] ///< Declare a variable length array 
(clang++ uses std::vector<>).
 #endif
 
+/**
+ * A std::make_shared<>() wrapper class to access private ctor & dtor.
+ * To call std::make_shared<T>() on a class @a T, its constructor and
+ * destructor must be public. For classes with private or protected
+ * constructor or destructor, this class can be used as follows:
+ * @code{.cc}
+ * class Type {
+ *   Type (ctor_args...);                // Private ctor.
+ *   friend class FriendAllocator<Type>; // Allow access to ctor/dtor of Type.
+ * };
+ * std::shared_ptr<Type> t = FriendAllocator<Type>::make_shared (ctor_args...);
+ * @endcode
+ */
+template<class T>
+class FriendAllocator : public std::allocator<T> {
+public:
+  /// Construct type @a C object, standard allocator requirement.
+  template<typename C, typename... Args> static inline void
+  construct (C *p, Args &&... args)
+  {
+    ::new ((void*) p) C (std::forward<Args> (args)...);
+  }
+  /// Delete type @a C object, standard allocator requirement.
+  template<typename C> static inline void
+  destroy (C *p)
+  {
+    p->~C ();
+  }
+  /**
+   * Construct an object of type @a T that is wrapped into a std::shared_ptr<T>.
+   * @param args        The list of arguments to pass into a T() constructor.
+   * @return            A std::shared_ptr<T> owning the newly created object.
+   */
+  template<typename ...Args> static inline std::shared_ptr<T>
+  make_shared (Args &&... args)
+  {
+    return std::allocate_shared<T> (FriendAllocator(), std::forward<Args> (args)...);
+  }
+};
+
 } // Bse
 
 #endif // __BSE_CXXAUX_HH__


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]