From 20109317659a314a4d14e53aad6dc2a360778536 Mon Sep 17 00:00:00 2001 From: Tomasz Iwanek Date: Fri, 9 Sep 2016 14:35:49 +0200 Subject: [PATCH] CRTP singleton 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 | 73 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 src/common/utils/singleton.h diff --git a/src/common/utils/singleton.h b/src/common/utils/singleton.h new file mode 100644 index 0000000..02fa537 --- /dev/null +++ b/src/common/utils/singleton.h @@ -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 + +#define CRTP_DECLARE_DEFAULT_CONSTRUCTOR_CLASS(CLASS) \ + friend class ::common_installer::Singleton; \ + 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 { + * // 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 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_ -- 2.7.4