opaque_ptr.hpp #1

  • //
  • guest/
  • ShadauxCat/
  • Sprawl/
  • Mainline/
  • memory/
  • opaque_ptr.hpp
  • View
  • Commits
  • Open Download .zip Download (2 KB)
#include <functional>

namespace sprawl
{
	namespace memory
	{
		template<size_t size>
		class OpaquePtr;

		template<typename T>
		struct CreateAs{};
	}
}

template<size_t size>
class sprawl::memory::OpaquePtr
{
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>
	OpaquePtr(CreateAs<T> const&, Params&&... params)
		: m_ptr()
		, m_deleter() // Same size since no members, direct reinterpret cast should be fine.
	{
		static_assert(sizeof(T) == size, "Opaque pointer delcared with size that does not match the type used to construct it.");
		new(m_ptr) T(std::forward<Params>(params)...);
		new(m_deleter) TypeDeleter<T>();
	}

	~OpaquePtr()
	{
		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.");
		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.");
		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.");
		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.");
		return *reinterpret_cast<T*>(m_ptr);
	}

private:
	unsigned char m_ptr[size];
	unsigned char m_deleter[sizeof(Deleter)];
};
# Change User Description Committed
#2 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
#1 16223 ShadauxCat Added opaque pointer.

Maybe this should really be called OpaqueData, since it's not really a pointer.

#review-16224