CRTP singleton 53/87853/2
authorTomasz Iwanek <t.iwanek@samsung.com>
Fri, 9 Sep 2016 12:35:49 +0000 (14:35 +0200)
committerTomasz Iwanek <t.iwanek@samsung.com>
Mon, 12 Sep 2016 10:21:40 +0000 (12:21 +0200)
Singletons are vicious brainless test-resilient beasts.
Don't use this header unless it is really justified.

This header will be used in following changes for test
library to control execution of pkgmgr plugin while
testing. Assessor class will be required to exist only
once.

Change-Id: Ia608bfcd5fbb831a649e468e83970ff4e58a73ca

src/common/utils/singleton.h [new file with mode: 0644]

diff --git a/src/common/utils/singleton.h b/src/common/utils/singleton.h
new file mode 100644 (file)
index 0000000..02fa537
--- /dev/null
@@ -0,0 +1,73 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_UTILS_SINGLETON_H_
+#define COMMON_UTILS_SINGLETON_H_
+
+#include <type_traits>
+
+#define CRTP_DECLARE_DEFAULT_CONSTRUCTOR_CLASS(CLASS)                          \
+     friend class ::common_installer::Singleton<CLASS>;                        \
+     using singleton_implementation_control_type = std::true_type;             \
+    private:                                                                   \
+     CLASS() = default;                                                        \
+
+#define CRTP_DECLARE_DEFAULT_CONSTRUCTOR_STRUCT(STRUCT)                        \
+    CRTP_DECLARE_DEFAULT_CONSTRUCTOR_CLASS(STRUCT)                             \
+    public:                                                                    \
+// NOLINT
+
+namespace common_installer {
+
+/**
+ * This is CRTP variant of singleton. This implementation is not thread safe.
+ *
+ * NOTE: As detecting control access for member functions in SFINAE do not works
+ *   User have to create CRTP_DECLARE_DEFAULT_CONSTRUCTOR_CLASS macro in each
+ *   class.
+ *
+ *   (you cannot detect private constructor at compile time in current compiler
+ *    implementations without actual compile error)
+ *
+ * Example of defining class A as singleton:
+ *
+ *  //// A.h file
+ *
+ *  class A() : public Singleton<A> {
+ *    // at top for class declaration
+ *    CRTP_DECLARE_DEFAULT_CONSTRUCTOR_CLASS(A)
+ *    // or CRTP_DECLARE_DEFAULT_CONSTRUCTOR_STRUCT(A) for struct...
+ *
+ *    //rest of your stuff... (no constructors here)
+ *  };
+ *
+ * //// A.cc file
+ *
+ *  // your functions and other stuff...
+ */
+template<class T>
+class Singleton {
+ protected:
+  Singleton() = default;
+  using singleton_implementation_control_type = std::false_type;
+
+ public:
+  Singleton(const Singleton&) = delete;
+  Singleton(Singleton&&) = delete;
+  Singleton& operator=(const Singleton&) = delete;
+  Singleton& operator=(Singleton&&) = delete;
+
+  static T& Instance() {
+    static_assert(T::singleton_implementation_control_type::value,
+        "Define CRTP_DECLARE_DEFAULT_CONSTRUCTOR_CLASS(CLASSNAME) "
+        "macro at top of singleton class to create private constructor "
+        "declaration, don't define constructor on your own");
+    static T s_instance;
+    return s_instance;
+  }
+};
+
+}  // namespace common_installer
+
+#endif  // COMMON_UTILS_SINGLETON_H_