--- /dev/null
+// 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_