diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-04-03 16:50:08 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-04-03 16:52:25 +0200 |
commit | c02c9880b61569455eeea1dacaa15d29c33021ea (patch) | |
tree | 35580c7110f28edd9ef5b41a043f38619c0f96f1 /AK | |
parent | 528054d192448f93789fedc3782550b3a80bee27 (diff) | |
download | serenity-c02c9880b61569455eeea1dacaa15d29c33021ea.zip |
AK: Add Eternal<T> and use it in various places.
This is useful for static locals that never need to be destroyed:
Thing& Thing::the()
{
static Eternal<Thing> the;
return the;
}
The object will be allocated in data segment memory and will never have
its destructor invoked.
Diffstat (limited to 'AK')
-rw-r--r-- | AK/Eternal.h | 30 | ||||
-rw-r--r-- | AK/kmalloc.h | 1 |
2 files changed, 31 insertions, 0 deletions
diff --git a/AK/Eternal.h b/AK/Eternal.h new file mode 100644 index 0000000000..6db63a300f --- /dev/null +++ b/AK/Eternal.h @@ -0,0 +1,30 @@ +#pragma once + +#include <AK/StdLibExtras.h> + +namespace AK { + +template<typename T> +class Eternal { +public: + template<typename... Args> + Eternal(Args&&... args) + { + new (m_slot) T(forward<Args>(args)...); + } + + T& get() { return *reinterpret_cast<T*>(&m_slot); } + const T& get() const { return *reinterpret_cast<T*>(&m_slot); } + T* operator->() { return &get(); } + const T* operator->() const { return &get(); } + operator T&() { return get(); } + operator const T&() const { return get(); } + + +private: + [[gnu::aligned(alignof(T))]] char m_slot[sizeof(T)]; +}; + +} + +using AK::Eternal; diff --git a/AK/kmalloc.h b/AK/kmalloc.h index 3b28b0a4f4..d6a5966e3d 100644 --- a/AK/kmalloc.h +++ b/AK/kmalloc.h @@ -8,6 +8,7 @@ #define AK_MAKE_ETERNAL \ public: \ void* operator new(size_t size) { return kmalloc_eternal(size); } \ + void* operator new(size_t, void* ptr) { return ptr; } \ private: #else #define AK_MAKE_ETERNAL |