This header-only C++ library implements the Singleton pattern in a thread-safe and efficient way.
A great issue with singletons normally is that they make unit testing very hard. This library also makes testing relatively easy with additional interfaces that allow resetting the singleton's state to properly test its behaviour. Furthermore, it is also important to be able to test code that depends on singletons, and this implementation lets its users easily inject mock implementations of the singleton. In order to improve code security, the interfaces intended for testing are designed to be unaccessible in production code.
To start using this library, include the singleton.hpp file into your code, and inherit from the Singleton class in your code and get its instance as follows:
testable_singleton/doc/example_base_usage.cpp
Lines 1 to 18 in 4d44bd8
Note
It is recommended to define a private or protected constructor to avoid misuse of the singleton. In this case, the friend BaseType; declaration must be added to the body of the class to allow class construction for the singleton.
It is also possible to use a non-default constructor for the singleton class. In this case, initialization arguments must be provided to the Get() function at every location where the singleton is accessed, or the TryGet() function must be used, which does not initialize the singleton.
testable_singleton/doc/example_constructor.cpp
Lines 1 to 33 in 4d44bd8
For more information about its usage, see the documentation within the include/singleton.hpp file.
The singleton has an interface designed for testing only. These interfaces should not be used in production code, because the software stability and quality cannot be guaranteed.
To access the testing interfaces, test code can include the singleton_test.hpp file. This provides access for the tests to use the ::testing::SingletonTestApi class.
The following example shows the usage of the ::testing::SingletonTestApi<T>::Reconstruct() and ::testing::SingletonTestApi<T>::Inject() methods.
testable_singleton/doc/example_full_usage.cpp
Lines 1 to 60 in 4d44bd8
Note
To be able to properly use the Inject function, the production code should not cache a reference or pointer to the returned instance. Otherwise the injected mock doesn't take effect and the real instance is used, which is destroyed. This may cause a crash or an other memory corruption style issue.
For more examples and behavioral requirements, it is recommended to view this library's test code.
Tip
Earlier versions of this library used the access_private library by Gábor Márton to access the Singleton's testing-only methods through explicit template instantiation's disabled accessibility check. This method is still supported, but it is untested. In version 2.0, the Reset method's signature is changed to use universal references, so && must be added after all parameters.
This library is a header-only library, so there is no need to build it to use it. A CMake build script is provided to facilitate installation, documentation generation, and unit testing. To build the library's resources, follow the CMake tutorial's instructions. To build the documentation, run cmake --build <build-directory> --target singleton_doc. To install the library, run cmake --install <build-directory> after configuring the build system.
By default, the CMake build script:
- installs the library's header files to the system include directory,
- if the documentation is built, then it is also installed,
- creates a build target
singleton_docto builds the library's documentation, if Doxygen is found on the system, - builds and registers its unit test with CTest.
To customize any of these behaviors, the following CMake options can be used:
- Set the CMake variable SINGLETON_DO_INSTALL=OFF to disable the installation of the library's header files.
- Set the CMake variable SINGLETON_BUILD_DOC=OFF to disable the documentation build target.
- Set the CMake variable SINGLETON_BUILD_TESTS=OFF to disable the unit test for this library.
- Or set the CMake variable BUILD_TESTING=OFF to disable all tests in the CMake build system, including this library's unit test.