// Copyright (c) 2024 Codemongous LLC. All Rights Reserved.

#pragma once

#include <memory>
#include <type_traits>

namespace Sourcify
{
	class SCW_Base : public std::enable_shared_from_this<SCW_Base>
	{
	public:
		struct Deleter
		{
			void operator()(SCW_Base* InObject) const
			{
				InObject->Release();
			}
		};

		virtual ~SCW_Base() = default;

		virtual void Release()
		{
			delete this;
		}

	protected:

		// Set of helper functions to get shared pointers to the derived classes

		// Returns a const shared pointer to the derived class from a const shared pointer to the base class
// 		template<typename T/*, std::enable_if_t<std::is_base_of_v<SCW_Base, T>&& std::is_const_v<T>, bool> = true*/>
// 		std::shared_ptr<T> GetSharedThisAs() const
// 		{
// 			return std::static_pointer_cast<T>(shared_from_this());
// 		}

		// Returns a non-const shared pointer to the derived class from a const shared pointer to the base class
		template<typename T/*, std::enable_if_t<std::is_base_of_v<SCW_Base, T> && !std::is_const_v<T>, bool> = true*/>
		std::shared_ptr<T> GetSharedThisAs() const
		{
			return std::static_pointer_cast<T>(std::const_pointer_cast<SCW_Base>(shared_from_this()));
		}

		// Returns a shared pointer to the derived class from a shared pointer to the base class
		template<typename T/*, std::enable_if_t<std::is_base_of_v<SCW_Base, T>, bool> = true*/>
		std::shared_ptr<T> GetSharedThisAs()
		{
			return std::static_pointer_cast<T>(shared_from_this());
		}
	};
} // namespace Sourcify