Skip to content

Instantly share code, notes, and snippets.

@joedavis
Created January 1, 2014 13:26
Show Gist options
  • Save joedavis/8208016 to your computer and use it in GitHub Desktop.
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.
// 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