#include <cdefs.h>
#include <functional>
#include <tuple>

/**
 * Base template for `FunctionWrapper`, never used.
 */
template<typename FnType>
class FunctionWrapper;

/**
 * A non-owning type-erased reference to a callable object.  This is used
 * to pass lambdas (and similar) down the stack without increasing code
 * size by template specialisation.  Instances of this class must not be
 * stored, they should be used only for passing type-erased callable objects
 * down the stack.
 *
 * Instances of this class are two words: a reference to the lambda, and a
 * wrapper callback that invokes the lambda.
 *
 * This is similar to `std::function` but is non-owning and so is guaranteed
 * not to allocate memory (the called function may capture memory).
 */
template<class R, class... Args>
class FunctionWrapper<R(Args...)>
{
	/**
	 * Storage for the type-erased function.  This holds the reference to
	 * lambda and to the invoke function.
	 */
	alignas(void *) char storage[2 * sizeof(void *)];

	/**
	 * Base type for the type-erased function.  This defines the virtual
	 * function that is used to invoke the captured lambda.
	 */
	struct ErasedFunctionWrapperBase
	{
		virtual R operator()(Args... args) = 0;
	};

	/**
	 * Returns a pointer to the storage, cast to the type-erased function
	 * type.
	 */
	ErasedFunctionWrapperBase &stored_function()
	{
		return *reinterpret_cast<ErasedFunctionWrapperBase *>(storage);
	}

	/**
	 * Templated subclass that is specialised for each concrete callable
	 * type `T` that is passed.  One instance of this will be created for
	 * each lambda type, with a single method in its vtable that invokes
	 * the lambda.
	 */
	template<typename T>
	class ErasedFunctionWrapper : public ErasedFunctionWrapperBase
	{
		/// Pointer to the captured lambda.
		T &&fn;

		public:
		/**
		 * Invoke function.  This is virtual and overrides the version in
		 * the parent class, allowing this to be called from code that does
		 * not know the cocrete type of the lambda.
		 */
		R operator()(Args... args) override
		{
			return fn(std::forward<Args>(args)...);
		}

		/**
		 * Construct the type-erased function wrapper, capturing the
		 * lambda.
		 */
		ErasedFunctionWrapper(T &&fn) : fn{std::forward<T>(fn)} {}
	};

	public:
	/**
	 * This is a non-owning reference, delete its copy and move
	 * constructors to avoid accidental copies.
	 */
	FunctionWrapper(FunctionWrapper &)  = delete;
	FunctionWrapper(FunctionWrapper &&) = delete;
	FunctionWrapper &operator=(FunctionWrapper &&) = delete;

	/**
	 * Construct the type-erased function wrapper, capturing the lambda.
	 */
	template<typename T>
	__always_inline FunctionWrapper(T &&fn)
	{
		// Make sure that we got the size for the storage right!
		static_assert(sizeof(storage) >= sizeof(ErasedFunctionWrapper<T>));
		// Construct the type-erased function in place.
		new (storage) ErasedFunctionWrapper<T>(std::forward<T>(fn));
	}

	/**
	 * Invoke the captured lambda.
	 */
	__always_inline R operator()(Args... args)
	{
		return stored_function()(std::forward<Args>(args)...);
	}
};
