#include <functional> #include <type_traits> namespace sprawl { namespace memory { template<size_t size, size_t align = 8> class OpaqueType; template<typename T> struct CreateAs{}; } } #if (defined(_WIN32) && _MSC_VER < 1900) # define alignof __alignof #endif template<size_t size, size_t align> class sprawl::memory::OpaqueType { public: class Deleter { public: virtual void Delete(void*) = 0; }; template<typename T> class TypeDeleter : public Deleter { public: virtual void Delete(void* ptr) { reinterpret_cast<T*>(ptr)->~T(); } }; template<typename T, typename... Params> OpaqueType(CreateAs<T> const&, Params&&... params) : m_ptr() , m_deleter() { static_assert(sizeof(T) == size, "Opaque pointer delcared with size that does not match the type used to construct it."); static_assert(align >= alignof(T) && (align % alignof(T) == 0), "Opaque pointer definition does not match alignment requirements of the type used to construct it."); new(&m_ptr) T(std::forward<Params>(params)...); new(&m_deleter) TypeDeleter<T>(); } ~OpaqueType() { reinterpret_cast<Deleter*>(&m_deleter)->Delete(&m_ptr); } template<typename T> T& As() { static_assert(sizeof(T) == size, "Opaque pointer delcared with size that does not match the type used to access it."); static_assert(align >= alignof(T) && (align % alignof(T) == 0), "Opaque pointer definition does not match alignment requirements of the type used to access it."); return *reinterpret_cast<T*>(&m_ptr); } template<typename T> T const& As() const { static_assert(sizeof(T) == size, "Opaque pointer delcared with size that does not match the type used to access it."); static_assert(align >= alignof(T) && (align % alignof(T) == 0), "Opaque pointer definition does not match alignment requirements of the type used to access it."); return *reinterpret_cast<T*>(&m_ptr); } template<typename T> operator T&() { static_assert(sizeof(T) == size, "Opaque pointer delcared with size that does not match the type used to access it."); static_assert(align >= alignof(T) && (align % alignof(T) == 0), "Opaque pointer definition does not match alignment requirements of the type used to access it."); return *reinterpret_cast<T*>(&m_ptr); } template<typename T> operator T const&() const { static_assert(sizeof(T) == size, "Opaque pointer delcared with size that does not match the type used to access it."); static_assert(align >= alignof(T) && (align % alignof(T) == 0), "Opaque pointer definition does not match alignment requirements of the type used to access it."); return *reinterpret_cast<T*>(&m_ptr); } private: typename std::aligned_storage<size, align>::type m_ptr; typename std::aligned_storage<sizeof(Deleter), alignof(Deleter)>::type m_deleter; };
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#7 | 19906 | ShadauxCat |
- Added tag, compile time string type - Since tag requires visual studio 2015, removed compatibility code for earlier versions of visual studio - Improved compiler detection - Added endianness detection - Added template if/else helper - Fixed bug with murmur3 64 bit - Added seed argument for murmur3 #review-19907 |
||
#6 | 16257 | ShadauxCat |
Compile fix #review-16258 |
||
#5 | 16255 | ShadauxCat |
Fixed some issues with the size calculation for OpaqueTypeLiast. #review-16256 |
||
#4 | 16246 | ShadauxCat |
- Fixed size and type computation for OpaqueTypeList, which was incorrect because it was building the struct in reverse order - and windows x86 also seems to have strange behavior with inheritance or including structs as class members when it comes to size calculation. So I'm now calculating the size manually. (Yay recursive compile-time math...) - Added function in logging to get the file object corresponding with a PrintToFile handler. #review-16247 |
||
#3 | 16242 | ShadauxCat |
Added OpaqueTypeList, an alias that enables creation of opaque types via a list of member types. #review-16243 |
||
#2 | 16231 | ShadauxCat |
Fixed a wording issue in OpaqueType static asserts. #review-16232 |
||
#1 | 16225 | ShadauxCat |
- Renamed OpaquePtr to OpaqueType, which is more correct as it isn't a pointer. - Added alignment restriction to OpaqueType - Changed Mutex implementation on Windows to use faster SRWLOCK instead of CRITICAL_SECTION (cannot mirror this change on Linux because pthread_cond_wait can't accept a pthread_rwlock_t) #review-16226 |
||
//guest/ShadauxCat/Sprawl/Mainline/memory/opaque_ptr.hpp | |||||
#1 | 16223 | ShadauxCat |
Added opaque pointer. Maybe this should really be called OpaqueData, since it's not really a pointer. #review-16224 |