Created
January 1, 2014 13:26
-
-
Save joedavis/8208016 to your computer and use it in GitHub Desktop.
Singleton with statically allocated storage, useful for embedded systems, operating system kernels and driver development.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Singleton with statically allocated storage, useful for embedded systems, | |
// operating system kernels and driver development. | |
/* | |
* Written in 2014 by Joe Davis <[email protected]> | |
* | |
* To the extent possible under law, the author(s) have dedicated all copyright | |
* and related and neighboring rights to this software to the public domain | |
* worldwide. This software is distributed without any warranty. | |
* | |
* You should have received a copy of the CC0 Public Domain Dedication along | |
* with this software. | |
* | |
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. | |
*/ | |
#ifndef SINGLETON_HH_ | |
#define SINGLETON_HH_ | |
// To use it simply inherit from static_singleton<T> where T is the name of the | |
// subclass. | |
// | |
// Note that static_singleton doesn't enforce the singleton pattern for any of | |
// its subclasses, and that it will still be possible to create separate | |
// instances of the class. | |
// | |
// The main reason you would want to use static_singleton is for deterministic | |
// construction and destruction of global objects with static storage duration. | |
// This is mostly useful in kernels and embedded systems without dynamic | |
// memory management or before dynamic memory management has been set up. | |
template <typename T> | |
struct static_singleton | |
{ | |
// Because allocator is a separate class, we can refer to sizeof(T) | |
struct allocator { alignas(T) static char buffer[sizeof(T)]; }; | |
static T *instance() { return reinterpret_cast<T *>(allocator::buffer); } | |
template <typename... Args> | |
static T *init(Args... args) { return new (instance()) T(args...); } | |
static void destroy() { instance()->~T(); } | |
}; | |
template <typename T> | |
alignas(T) char static_singleton<T>::allocator::buffer[sizeof(T)]; | |
#endif // SINGLETON_HH_ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment