1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef CHRE_UTIL_SINGLETON_H_ 18 #define CHRE_UTIL_SINGLETON_H_ 19 20 #include <type_traits> 21 22 #include "chre/util/non_copyable.h" 23 24 namespace chre { 25 26 /** 27 * The Singleton template provides static storage for one instance of the 28 * provided type. Initialization does not happen automatically which allows 29 * users of this API to control the order of initialization. 30 * 31 * Caution is recommended when using this class to avoid Singleton hell. In 32 * many cases there is a better solution than using a Singleton in your design. 33 * One good use of this class is for a class that owns the state of your 34 * application (the "root" of a tree of object ownership). 35 */ 36 template<typename ObjectType> 37 class Singleton : public NonCopyable { 38 public: 39 /** 40 * Constructs the object in the space provided by this container. If the 41 * object is already constructed, no operation is performed. Use the 42 * isInitialized method to determine if construction is required. 43 * 44 * @param args The constructor arguments to pass to the singleton instance. 45 */ 46 template<typename... Args> 47 static void init(Args&&... args); 48 49 /** 50 * Invokes the destructor on the underlying object if it has been constructed 51 * already. 52 */ 53 static void deinit(); 54 55 /** 56 * Returns whether or not this singleton instance has been constructed. 57 * 58 * @return Returns true if the object has already been constructed. 59 */ 60 static bool isInitialized(); 61 62 /** 63 * Returns a pointer to the underlying object. The singleton object must be 64 * constructed prior to using get to interact with it. If the object is not 65 * initialized, the behavior is undefined and the returned pointer is not 66 * initialized. 67 * 68 * @return A pointer to the singleton instance. 69 */ 70 static ObjectType *get(); 71 72 /** 73 * Returns a pointer to the underlying object. The singleton object must be 74 * constructed prior to using get to interact with it. If the object is not 75 * initialized, nullptr is returned. 76 * 77 * @return A pointer to the singleton instance or nullptr if it is not 78 * initialized. 79 */ 80 static ObjectType *safeGet(); 81 82 private: 83 //! Static storage for the type of this singleton. 84 static typename std::aligned_storage< 85 sizeof(ObjectType), alignof(ObjectType)>::type sObject; 86 87 //! Static storage for the initialized state of this singleton. 88 static bool sIsInitialized; 89 }; 90 91 } // namespace chre 92 93 #include "chre/util/singleton_impl.h" 94 95 #endif // CHRE_UTIL_SINGLETON_H_ 96