diff options
author | Jacques Lucke <jacques@blender.org> | 2020-07-06 11:56:26 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2020-07-06 11:56:26 +0300 |
commit | 703a73fa846531a0888c8f99489c8e213f5c5d81 (patch) | |
tree | 00c833f690d953e825a32edbc03cf9572981cc6c /source/blender/blenlib/BLI_memory_utils.hh | |
parent | 80393a0ebadc7b8e825a6ce64204bf4424650fe5 (diff) |
BLI: refactor how buffers for small object optimization are stored
Previously, there was an error when operator-> was returning an
invalid type. See error C2839.
Diffstat (limited to 'source/blender/blenlib/BLI_memory_utils.hh')
-rw-r--r-- | source/blender/blenlib/BLI_memory_utils.hh | 67 |
1 files changed, 62 insertions, 5 deletions
diff --git a/source/blender/blenlib/BLI_memory_utils.hh b/source/blender/blenlib/BLI_memory_utils.hh index 44d25340778..1c0193e2756 100644 --- a/source/blender/blenlib/BLI_memory_utils.hh +++ b/source/blender/blenlib/BLI_memory_utils.hh @@ -218,12 +218,8 @@ template<typename T> struct DestructValueAtAddress { template<typename T> using destruct_ptr = std::unique_ptr<T, DestructValueAtAddress<T>>; /** - * An `AlignedBuffer` is simply a byte array with the given size and alignment. The buffer will + * An `AlignedBuffer` is a byte array with at least the given size and alignment. The buffer will * not be initialized by the default constructor. - * - * This can be used to reserve memory for C++ objects whose lifetime is different from the - * lifetime of the object they are embedded in. It's used by containers with small buffer - * optimization and hash table implementations. */ template<size_t Size, size_t Alignment> class alignas(Alignment) AlignedBuffer { private: @@ -231,6 +227,16 @@ template<size_t Size, size_t Alignment> class alignas(Alignment) AlignedBuffer { char buffer_[(Size > 0) ? Size : 1]; public: + operator void *() + { + return (void *)buffer_; + } + + operator const void *() const + { + return (void *)buffer_; + } + void *ptr() { return (void *)buffer_; @@ -243,6 +249,57 @@ template<size_t Size, size_t Alignment> class alignas(Alignment) AlignedBuffer { }; /** + * This can be used to reserve memory for C++ objects whose lifetime is different from the + * lifetime of the object they are embedded in. It's used by containers with small buffer + * optimization and hash table implementations. + */ +template<typename T, size_t Size = 1> class TypedBuffer { + private: + AlignedBuffer<sizeof(T) * Size, alignof(T)> buffer_; + + public: + operator T *() + { + return (T *)&buffer_; + } + + operator const T *() const + { + return (const T *)&buffer_; + } + + T &operator*() + { + return *(T *)&buffer_; + } + + const T &operator*() const + { + return *(const T *)&buffer_; + } + + T *ptr() + { + return (T *)&buffer_; + } + + const T *ptr() const + { + return (const T *)&buffer_; + } + + T &ref() + { + return *(T *)&buffer_; + } + + const T &ref() const + { + return *(const T *)&buffer_; + } +}; + +/** * This can be used by container constructors. A parameter of this type should be used to indicate * that the constructor does not construct the elements. */ |