#ifndef INTERFACEBASE_H__
#define INTERFACEBASE_H__

#include "maxon/entity.h"
#include "maxon/baseref.h"
#include "maxon/datatypebase.h"

namespace maxon
{

/// @addtogroup SYSTEM
/// @{


/// @cond INTERNAL

class ClassInterface;
class ClassInfo;

using MTableBase = void;

void* PrivateSystemAlloc(Int size);
void PrivateSystemFree(void*);

//----------------------------------------------------------------------------------------
/// DataTypeInitializer functions are invoked during the initialization of interfaces to initialize their type info objects.
#ifndef MAXON_COMPILER_CLANG	// circumvent clang bug that creates false positives
/// @param[in] info								Pointer to the not-yet initialized DataType object.
/// @param[in] type								Interface identifier.
/// @param[in] impl								The interface implementation info.
#endif
//----------------------------------------------------------------------------------------
using DataTypeInitializer = Result<void>(*)(DataTypeImpl* info, Id&& type, const NonvirtualInterfaceImplementation* impl);


// used internally for the JIT assembly of Unresolved implementations to assemble the correct code depending on the return type
enum class NULL_RETURN_TYPE : UChar
{
	VOID_ZERO,
	VOID_ZERO_FREE_FUNCTION,
	INTEGRAL_ZERO,
	FLOAT_ZERO,
	DOUBLE_ZERO,
	POINTER_TO_ZERO,
	OTHER
} MAXON_ENUM_LIST(NULL_RETURN_TYPE);


//----------------------------------------------------------------------------------------
/// NonvirtualInterfaceReference is an EntityReference object which declares a non-virtual interface.
/// It is created by MAXON_INTERFACE_NONVIRTUAL together with code generated by the source processor.
/// @see NonvirtualInterfaceImplementation
/// @see MAXON_INTERFACE_NONVIRTUAL
//----------------------------------------------------------------------------------------
class NonvirtualInterfaceReference
{
public:
	using MTableInitializer = void(*)(MTableBase*);
	using UnresolvedAssembler = Bool(*)(const NonvirtualInterfaceReference*, void* table, const NULL_RETURN_TYPE* returnTypes, Int count);
	using UnresolvedInitializer = Bool(*)(UnresolvedAssembler init, MTableBase* table);

	//----------------------------------------------------------------------------------------
	/// Constructs the NonvirtualInterfaceReference object and adds it to the reference list of the current translation unit.
	/// The MAXON_INTERFACE_REGISTER macro in the register.cpp file of the current module invokes this constructor.
	/// @param[in] iid								Unique interface identifier.
	/// @param[in] mtable							Pointer to the module's MTable for this interface.
	/// @param[in] unresolvedMTable		Pointer to the module's MTable for unresolved functions of this interface.
	/// @param[in] methodIds					Pointer to the module's method id table for this interface.
	/// @param[in] methodCount				Number of methods in the table.
	/// @param[in] initUnresolved			Function to initialize mtable with function pointers of the interface's Unresolved implementation.
	/// @param[in] nullResolve				If non-null, this is invoked to use a null-implementation when no definition for the interface exists. This is non-null only if @MAXON_ANNOTATION{nullimpl=true} is set for the interface.
	/// @param[in] unit								The translation unit containing the reference.
	/// @param[in] refType						The reference type of the interface (one of the REFERENCE flags of EntityBase::FLAGS).
	//----------------------------------------------------------------------------------------
	NonvirtualInterfaceReference(const Char* iid, MTableBase* mtable, MTableBase* unresolvedMTable, const Char* methodIds, Int methodCount, UnresolvedInitializer initUnresolved, MTableInitializer nullResolve, TranslationUnit* unit, EntityBase::FLAGS refType);

	//----------------------------------------------------------------------------------------
	/// Constructs the NonvirtualInterfaceReference object and adds it to the reference list of the current translation unit.
	/// The MAXON_INTERFACE_REGISTER macro in the register.cpp file of the current module invokes this constructor.
	/// @param[in] iid								Unique interface identifier.
	/// @param[in] mtable							Pointer to the module's MTable for this interface.
	/// @param[in] unresolvedMTable		Pointer to the module's MTable for unresolved functions of this interface.
	/// @param[in] methodIds					Pointer to the module's method id table for this interface.
	/// @param[in] methodCount				Number of methods in the table.
	/// @param[in] initUnresolved			Function to initialize mtable with function pointers of the interface's Unresolved implementation.
	/// @param[in] unit								The translation unit containing the reference.
	/// @param[in] refType						The reference type of the interface (one of the REFERENCE flags of EntityBase::FLAGS).
	//----------------------------------------------------------------------------------------
	NonvirtualInterfaceReference(const Char* iid, MTableBase* mtable, MTableBase* unresolvedMTable, const Char* methodIds, Int methodCount, UnresolvedInitializer initUnresolved, TranslationUnit* unit, EntityBase::FLAGS refType);

	//----------------------------------------------------------------------------------------
	/// This is invoked by the methods of an interface's Unresolved class to trigger the resolution of the interface.
	/// If the method table can be initialized properly this will return true, and the calling method of the Unresolved class
	/// will forward the invocation to the resolved method. Otherwise, false is returned, and the calling method
	/// will return the appropriate null value.
	//----------------------------------------------------------------------------------------
	static Bool PrivateResolve(NonvirtualInterfaceReference* this_, Bool showMessage);

	//----------------------------------------------------------------------------------------
	/// Returns true if the interface reference has been initialized successfully. This means that the reference has been resolved
	/// to an implementation which itself has been initialized successfully, so that it can be used.
	/// @return												True if reference and corresponding implementation have been initialized successfully.
	//----------------------------------------------------------------------------------------
	Bool IsInitialized() const
	{
		return _super.IsInitialized();
	}

	//----------------------------------------------------------------------------------------
	/// Returns the unique identifier of the interface.
	/// @return												Identifier of the interface.
	//----------------------------------------------------------------------------------------
	const Id& GetId() const
	{
		return _super.GetBase().GetId();
	}

	/// @copydoc EntityBase::GetFlags
	EntityBase::FLAGS GetFlags() const
	{
		return _super.GetBase().GetFlags();
	}

	//----------------------------------------------------------------------------------------
	/// Returns the DataType of this interface. This is only valid after a successful initialization.
	/// @return												Data type of this interface.
	//----------------------------------------------------------------------------------------
	const DataType& GetDataType() const
	{
		return _type;
	}

	//----------------------------------------------------------------------------------------
	/// Returns a const reference to the null value of the reference class. This is only valid after a successful initialization.
	/// @return												Const reference to the null value (to be cast into the reference class).
	//----------------------------------------------------------------------------------------
	const Generic* const& GetNullValue() const
	{
		return _nullValue;
	}

	const Char* GetMethodIds() const
	{
		return _methodIds;
	}

	const MTableBase* GetMTable() const
	{
		return _mtable;
	}

	const EntityReference& GetReference() const
	{
		return _super;
	}

private:
	EntityReference _super; ///< EntityReference base object.
	MTableBase* _mtable; ///< Pointer to the method table of the current module for the interface.
	MTableBase* _unresolvedMTable; ///< Pointer to the method table for unresolved functions of the current module for the interface.
	const Char* _methodIds; ///< Pointer to the method id table of the current module for the interface.
	Int _methodCount; ///< Number of methods in the method table.
	UnresolvedInitializer _initUnresolved; ///< Initializer to set function pointers of MTable to Unresolved implementations.
	DataType _type; ///< The type of this interface.
	MTableInitializer _nullResolve; ///< If non-null, this is invoked to use a null-implementation when no definition for the interface exists.
	const Generic* _nullValue; ///< Pointer to the null value of the implementation (may be nullptr).
	friend class ObjectModel;
	friend class NonvirtualInterfaceImplementation;
};


template <typename T> class InterfaceDataTypeFunctions;

template <typename T> struct InterfaceDataTypeFunctionsTrait
{
	using Functions = InterfaceDataTypeFunctions<T>;
	static const Bool REGISTER_TYPE = true;
};

template <typename T, Bool HAS_NONSTATIC = T::MTable::HAS_NONSTATIC> struct PrivateInitInterfaceType
{
	static Result<void> Init(DataTypeImpl* info, Id&& iid, const NonvirtualInterfaceImplementation* impl)
	{
		new (info) DataTypeImpl(std::move(iid), nullptr, nullptr, (T*) nullptr, (typename InterfaceDataTypeFunctionsTrait<T>::Functions*) nullptr, VALUEKIND::NONE, impl, VALUEKIND::NONVIRTUAL_INTERFACE | VALUEKIND::ABSTRACT);
		if (!InterfaceDataTypeFunctionsTrait<T>::REGISTER_TYPE)
			return OK;
		return info->PrivateRegister();
	}

	static DataTypeInitializer Get() { return &Init; }
};

template <typename T> struct PrivateInitInterfaceType<T, false>
{
	static DataTypeInitializer Get() { return nullptr; }
};

//----------------------------------------------------------------------------------------
/// NonvirtualInterfaceImplementation is an EntityDefinition object which provides the implementation of a non-virtual interface.
/// It is defined by MAXON_IMPLEMENTATION and MAXON_IMPLEMENTATION_REGISTER.
//----------------------------------------------------------------------------------------
class NonvirtualInterfaceImplementation
{
public:
	//----------------------------------------------------------------------------------------
	/// Constructs the NonvirtualInterfaceImplementation object and adds it to the definition list of the current translation unit.
	/// This constructor is used by MAXON_IMPLEMENTATION_REGISTER.
	/// @param[in] dummy							Dummy parameter, this is only needed to determine template parameter C.
	/// @param[in] clsName						Name of the implementation class.
	/// @param[in] ref								Corresponding interface reference of the module of this definition.
	/// @param[in] init								Pointer to a function which initializes the implementation's MTable with the implemented function pointers.
	/// @param[in] flags							Additional entity property flags,
	/// @param[in] unit								The translation unit containing the implementation.
	/// @param[in] file								Source file name.
	/// @tparam C											Implementation class.
	///
	/// @see MAXON_INTERFACE_NONVIRTUAL
	//----------------------------------------------------------------------------------------
	template <typename C>
	NonvirtualInterfaceImplementation(C* dummy, const Char* clsName, const Char* cppName, const NonvirtualInterfaceReference& ref,
		NonvirtualInterfaceReference::MTableInitializer init, EntityBase::FLAGS flags, TranslationUnit* unit, const Char* file)
		: _super(ref._super, unit, file, flags),
			_implementationClass(clsName),
			_initMTable(init),
			_initType(PrivateInitInterfaceType<typename C::Interface>::Get()),
			_type(cppName, unit ? unit->GetModule() : nullptr),
			_initImplementation(&C::_PrivateInitImplementation),
			_freeImplementation(&C::_PrivateFreeImplementation),
			_nullValue(nullptr)
	{
	}

	const Generic* GetNullValue() const
	{
		return _nullValue;
	}

	const DataType& GetDataType() const
	{
		return _typeRef;
	}

private:
	EntityDefinition _super; ///< EntityDefinition base object.

	const Char* const _implementationClass; ///< Name of the implementation class (without namespace prefix).
	NonvirtualInterfaceReference::MTableInitializer const _initMTable; ///< Function to initialize the method table with the function pointers of the implementation.
	DataTypeInitializer _initType; ///< Initializer function for _type.
	DataTypeImpl::Primary _type; ///< Type info for this interface.
	DataType::Primary _typeRef;
	Result<const Generic*> (*_initImplementation) (); ///< This function is invoked to initialize the implementation before it's used the first time.
	void (*_freeImplementation) (); ///< This function is invoked after the last use of the implementation.
	const Generic* _nullValue; ///< The result of the invocation of _initImplementation, may be nullptr. This represents the null value of the implementation.
	friend class ObjectModel;
};


class ComponentPointerHandler : public PointerHandler
{
};

class SelfPointerHandler : public PointerHandler
{
public:
	static const VALUEKIND KIND = (VALUEKIND::POINTER_FLAGS | VALUEKIND::DEEP_CONSTNESS) & ~VALUEKIND::ZERO_INITIALIZED;
};

class SuperPointerHandler : public SelfPointerHandler
{
};

// This template is used for conversion operators from S to REF. Only if S matches REF regarding
// reference handling, the conversion operators shall exist.
template <typename S, typename S_HANDLER, typename HANDLER, typename REF, Bool CONST_THIS_NONCONST_PTR> struct RefConversionTarget
{
	using type = typename std::conditional<S::DIRECT_REF && STD_IS_REPLACEMENT(same, HANDLER, S_HANDLER), REF, DummyReturnType>::type;
};

// The specialization for the self-pointer always allows to convert to REF.
template <typename S, typename HANDLER, typename REF> struct RefConversionTarget<S, SelfPointerHandler, HANDLER, REF, false>
{
	using type = REF;
};

// But for the case of a const self-pointer and a REF which points to a non-const object we must not allow the conversion to REF.
template <typename S, typename HANDLER, typename REF> struct RefConversionTarget<S, SelfPointerHandler, HANDLER, REF, true>
{
	using type = DummyReturnType;
};


template <typename T, typename HANDLER, typename REFCLASS> struct DirectRefReferenceClassInfo
{
	using type = REFCLASS;
	using Component = T;

	template <typename TO> using HasBaseDetector = maxon::HasBaseDetector<T, TO>;
};

template <typename T, typename HANDLER> struct DirectRefReferenceClassInfo<T, HANDLER, void>
{
	using type = typename std::conditional<STD_IS_REPLACEMENT(const, T), typename T::ConstPtr, typename T::Ptr>::type;
	using Component = T;

	template <typename TO> using HasBaseDetector = maxon::HasBaseDetector<T, TO>;
};

template <typename T, typename C> struct DirectRefReferenceClassInfo<T, ComponentPointerHandler, C>
{
	using type = typename std::conditional<STD_IS_REPLACEMENT(const, T), typename C::ConstPtr, typename C::Ptr>::type;
	using Component = C;

	template <typename TO> using HasBaseDetector = typename C::template ComponentHasBase<typename std::remove_const<TO>::type>;
};

template <typename T, typename C> struct DirectRefReferenceClassInfo<T, SelfPointerHandler, C>
{
	using type = typename C::SelfPtr;
	using Component = C;

	template <typename TO> using HasBaseDetector = typename C::template ComponentHasBase<typename std::remove_const<TO>::type>;
};

template <typename C, typename BASE> struct SuperPtrComponentInfo;

template <typename T, typename C, typename BASE> struct DirectRefReferenceClassInfo<T, SuperPointerHandler, SuperPtrComponentInfo<C, BASE>>
{
	using type = typename BASE::SelfPtr;
	using Component = C;

	template <typename TO> using HasBaseDetector = typename BASE::template ComponentHasBase<typename std::remove_const<TO>::type>;
};


// used for RefBaseFunctions
template <typename T, typename HANDLER, typename REFCLASS_INFO> class DirectRef
{
public:
	using Info = DirectRefReferenceClassInfo<T, HANDLER, REFCLASS_INFO>;
	using ReferenceClass = typename Info::type;
	using Component = typename Info::Component;
	using ReferencedType = T;
	using ConstReferencedType = typename ConstIf<T, Bool(HANDLER::KIND & VALUEKIND::DEEP_CONSTNESS)>::type;
	using DirectlyReferencedType = T;
	using Handler = HANDLER;
	using BaseRefType = BaseRef<T, HANDLER>;
	static const Bool DIRECT_REF = true;
	static const Bool HAS_ERROR = false;
	using type = DirectRef;

	template <typename D> using IsGenericBaseOf = std::true_type;

	const ReferenceClass& PrivateGetRefMember() const
	{
		static_assert(ReferenceClass::DIRECT_REF && ReferenceClass::Handler::KIND == HANDLER::KIND
									&& STD_IS_REPLACEMENT(const, ConstReferencedType) <= STD_IS_REPLACEMENT(const, typename ReferenceClass::ReferencedType),
									"Invalid reinterpret_cast.");
		return *reinterpret_cast<const ReferenceClass*>(this);
	}

	ReferenceClass& PrivateGetRefMember()
	{
		static_assert(ReferenceClass::DIRECT_REF && ReferenceClass::Handler::KIND == HANDLER::KIND
									&& STD_IS_REPLACEMENT(const, ReferencedType) <= STD_IS_REPLACEMENT(const, typename ReferenceClass::ReferencedType),
									"Invalid reinterpret_cast.");
		return *reinterpret_cast<ReferenceClass*>(this);
	}

	T* GetPointer() { return *(T**) this; }
	ConstReferencedType* GetPointer() const { return *(T**) this; }
	const BaseRefType& GetBaseRef() const { return *reinterpret_cast<const BaseRefType*>(this); }
	BaseRefType& GetBaseRef() { return *reinterpret_cast<BaseRefType*>(this); }

	template <typename TO> using HasBaseDetector = typename Info::template HasBaseDetector<TO>;

	DirectRef& operator =(std::nullptr_t) { ResetReference(); return *this; }

	const ThreadReferencedError& GetErrorStorage() const
	{
		return *(const ThreadReferencedError*) this;
	}

	static std::nullptr_t GetWrapper()
	{
		return nullptr;
	}

	ResultRef<typename std::remove_const<T>::type> MakeWritable(Bool resetOnError = true)
	{
		return reinterpret_cast<BaseRefType*>(this)->MakeWritable(resetOnError);
	}

	void PrivateSetPointer(T* ptr) { *(T**) this = ptr; }

protected:
	void ResetReference() { *reinterpret_cast<BaseRefType*>(this) = nullptr; }
};

template <typename REF> using RefMemberType = typename InheritConst<typename REF::ReferenceClass, REF>::type&;

template <typename SUPER> class ReferenceResultBase : public SUPER
{
public:
	using ReferenceClass = typename std::decay<typename SUPER::ValueType>::type;

	using SUPER::SUPER;

	using Handler = typename ReferenceClass::Handler;
	// We don't add a ReferencedType alias here to that a Result<SomeReference> isn't recognized as a reference.
	using PrivateReferencedType = typename ReferenceClass::ReferencedType;
	using type = ReferenceResultBase;
	using Component = PrivateReferencedType;
	static const Bool DIRECT_REF = false;
	static std::false_type GenericVarianceCheck(const void*);

	ReferenceClass& PrivateGetRefMember()
	{
		return this->GetValue();
	}

	const ReferenceClass& PrivateGetRefMember() const
	{
		return this->GetValue();
	}

	/// @note Required for result chaining.
	static std::nullptr_t GetWrapper()
	{
		return nullptr;
	}

	/// @note Required for result chaining.
	PrivateReferencedType* GetPointer() const
	{
		return this->UncheckedGetValue().GetPointer();
	}

	/// @note Required for result chaining.
	ResultRef<typename std::remove_const<PrivateReferencedType>::type> MakeWritable(Bool resetOnError = true)
	{
		static_assert(MAXON_IS_COW_KIND(Handler::KIND), "MakeWritable must not be invoked for non-COW references.");
		return std::move(this->GetValue()).MakeWritable(resetOnError);
	}
};


namespace details
{
template <typename T> typename SFINAEHelper<std::true_type, decltype(std::declval<T>().IsPopulated())>::type TestForIsPopulatedOrIsEmptyFunction(OverloadRank2);
template <typename T> typename SFINAEHelper<std::true_type, decltype(std::declval<T>().IsEmpty())>::type TestForIsPopulatedOrIsEmptyFunction(OverloadRank1);
template <typename T> std::false_type TestForIsPopulatedOrIsEmptyFunction(OverloadRank0);
}

//----------------------------------------------------------------------------------------
/// RefBaseFunctions is used internally as base class for reference classes for interfaces.
/// RefBaseFunctions itself is just a class without any data members. Its subclasses have to add suitable data members.
/// RefBaseFunctions uses SUPER as base class, SUPER has to declare the function GetPointer() to obtain the pointer to the referenced object.
/// For example, if you use DirectRef for SUPER, then the reference class stores a pointer as its
/// first member which directly points to the referenced object. But you can also use
/// classes for SUPER which follow several indirections to reach the referenced object.
//----------------------------------------------------------------------------------------
template <typename SUPER> class RefBaseFunctions : public SUPER
{
public:
	const ThreadReferencedError& GetErrorStorage() const
	{
		return *(const ThreadReferencedError*) this;
	}

	template <typename S> using ResultFunctions = typename ReferenceResultBase<S>::PrivateReferencedType::template ReferenceFunctions<ReferenceResultBase<S>>::type;

	using Handler = typename SUPER::Handler;
	using ReferencedType = typename SUPER::ReferencedType;
	using ConstReferencedType = typename ConstIf<ReferencedType, Bool(Handler::KIND & VALUEKIND::DEEP_CONSTNESS)>::type;
	using PrivateReferencedType = ReferencedType;
	using type = RefBaseFunctions;
	static std::false_type GenericVarianceCheck(const void*);
	static const Bool COW = MAXON_IS_COW_KIND(Handler::KIND);

	Bool operator ==(const ReferencedType* ptr) const { return RefCompare<COW, true>::IsEqual(this->GetPointer(), ptr); }
	Bool operator !=(const ReferencedType* ptr) const { return !RefCompare<COW, true>::IsEqual(this->GetPointer(), ptr); }
	Bool operator <(const ReferencedType* ptr) const { return RefCompare<COW, true>::LessThan(this->GetPointer(), ptr); }
	Bool operator >(const ReferencedType* ptr) const { return RefCompare<COW, true>::LessThan(ptr, this->GetPointer()); }
	Bool operator <=(const ReferencedType* ptr) const { return !RefCompare<COW, true>::LessThan(ptr, this->GetPointer()); }
	Bool operator >=(const ReferencedType* ptr) const { return !RefCompare<COW, true>::LessThan(this->GetPointer(), ptr); }

	Bool operator ==(typename std::remove_const<ReferencedType>::type* ptr) const { return this->operator ==(static_cast<const ReferencedType*>(ptr)); }
	Bool operator !=(typename std::remove_const<ReferencedType>::type* ptr) const { return this->operator !=(static_cast<const ReferencedType*>(ptr)); }
	Bool operator <(typename std::remove_const<ReferencedType>::type* ptr) const { return this->operator <(static_cast<const ReferencedType*>(ptr)); }
	Bool operator >(typename std::remove_const<ReferencedType>::type* ptr) const { return this->operator >(static_cast<const ReferencedType*>(ptr)); }
	Bool operator <=(typename std::remove_const<ReferencedType>::type* ptr) const { return this->operator <=(static_cast<const ReferencedType*>(ptr)); }
	Bool operator >=(typename std::remove_const<ReferencedType>::type* ptr) const { return this->operator >=(static_cast<const ReferencedType*>(ptr)); }

	Bool operator ==(std::nullptr_t) const { return this->operator ==((const ReferencedType*) nullptr); }
	Bool operator !=(std::nullptr_t) const { return this->operator !=((const ReferencedType*) nullptr); }

	HashInt GetHashCode() const { return RefCompare<COW, true>::GetHashCode(this->GetPointer()); }

	template <typename T, typename = typename std::enable_if<!STD_IS_REPLACEMENT(same, const T, const ObjectInterface) && !STD_IS_REPLACEMENT(same, const T, const ReferencedType)
																													 && SUPER::template HasBaseDetector<T>::value && STD_IS_REPLACEMENT(const, T) >= STD_IS_REPLACEMENT(const, ReferencedType)>::type>
	operator T*() { return reinterpret_cast<T*>(this->GetPointer()); }

	template <typename T, typename = typename std::enable_if<!STD_IS_REPLACEMENT(same, const T, const ObjectInterface) && !STD_IS_REPLACEMENT(same, const T, const ReferencedType)
																													 && SUPER::template HasBaseDetector<T>::value && STD_IS_REPLACEMENT(const, T) >= STD_IS_REPLACEMENT(const, ConstReferencedType)>::type>
	operator T*() const { return reinterpret_cast<T*>(this->GetPointer()); }

	operator ReferencedType*() { return this->GetPointer(); }

	operator ConstReferencedType*() const { return this->GetPointer(); }

	static const Bool DERIVED_FROM_OBJECT = !STD_IS_REPLACEMENT(same, const ObjectInterface, const ReferencedType) && IsVirtualInterfaceType<ReferencedType>::value;

	operator typename std::conditional<DERIVED_FROM_OBJECT, typename InheritConst<ObjectInterface, ReferencedType>::type*, const DummyReturnType&&>::type() { return this->GetPointer(); }

	operator typename std::conditional<DERIVED_FROM_OBJECT, typename InheritConst<ObjectInterface, ConstReferencedType>::type*, const DummyReturnType&&>::type() const { return this->GetPointer(); }

	explicit operator Bool() const
	{
		static_assert(!(COW && decltype(maxon::details::TestForIsPopulatedOrIsEmptyFunction<typename SUPER::ReferenceClass>(OVERLOAD_MAX_RANK))::value),
									"For a copy-on-write reference with IsPopulated()- or IsEmpty()-function, conversion to Bool is not allowed as it would only check the pointer. You have to use IsPopulated() or IsEmpty().");
		return MAXON_LIKELY(this->GetPointer() != nullptr);
	}

	explicit operator Bool()
	{
		static_assert(!(COW && decltype(maxon::details::TestForIsPopulatedOrIsEmptyFunction<typename SUPER::ReferenceClass>(OVERLOAD_MAX_RANK))::value),
									"For a copy-on-write reference with IsPopulated()- or IsEmpty()-function, conversion to Bool is not allowed as it would only check the pointer. You have to use IsPopulated() or IsEmpty().");
		return MAXON_LIKELY(this->GetPointer() != nullptr);
	}

private:
	operator void*() = delete;
	operator void*() const = delete;
	ReferencedType& operator *() = delete;
	ConstReferencedType& operator *() const = delete;
	ReferencedType* operator ->() = delete;
	ConstReferencedType* operator ->() const = delete;

	// prevent pointer arithmetic on reference class
	void operator +(Int) = delete;
	void operator +(Int) const = delete;
	void operator -(Int) = delete;
	void operator -(Int) const = delete;
	void operator [](Int) = delete;
	void operator [](Int) const = delete;
};



template <typename S, VALUEKIND PTR_DEEP_ZERO> class ReferenceBaseCtorDtor : public S
{
public:
	using BaseRefType = typename S::BaseRefType;

	ReferenceBaseCtorDtor() : _object(nullptr)
	{
	}

	explicit ReferenceBaseCtorDtor(ENUM_DONT_INITIALIZE)
	{
	}

	ReferenceBaseCtorDtor(const ReferenceBaseCtorDtor& src)
	{
		static_assert(!(PTR_DEEP_ZERO & VALUEKIND::DEEP_CONSTNESS), "Can't copy a reference with deep constness.");
		new (this) BaseRefType(reinterpret_cast<const BaseRefType&>(src));
	}

	ReferenceBaseCtorDtor& operator =(const ReferenceBaseCtorDtor& src)
	{
		static_assert(!(PTR_DEEP_ZERO & VALUEKIND::DEEP_CONSTNESS), "Can't copy a reference with deep constness.");
		reinterpret_cast<BaseRefType*>(this)->operator =(reinterpret_cast<const BaseRefType&>(src));
		return *this;
	}

	ReferenceBaseCtorDtor(ReferenceBaseCtorDtor&& src) : _object(src._object)
	{
		src._object = nullptr;
	}

	ReferenceBaseCtorDtor& operator =(ReferenceBaseCtorDtor&& src)
	{
		reinterpret_cast<BaseRefType*>(this)->operator =(std::move(reinterpret_cast<BaseRefType&>(src)));
		return *this;
	}

	~ReferenceBaseCtorDtor()
	{
		reinterpret_cast<BaseRefType*>(this)->~BaseRefType();
	}

private:
	typename S::ReferencedType* _object;
};


template <typename S> class ReferenceBaseCtorDtor<S, VALUEKIND::POINTER | VALUEKIND::ZERO_INITIALIZED> : public S
{
public:
	ReferenceBaseCtorDtor() : _object(nullptr)
	{
	}

	explicit ReferenceBaseCtorDtor(ENUM_DONT_INITIALIZE)
	{
	}

private:
	typename S::ReferencedType* _object;
};

template <typename S> class ReferenceBaseCtorDtor<S, VALUEKIND::POINTER | VALUEKIND::DEEP_CONSTNESS> : public S
{
public:
	ReferenceBaseCtorDtor() = default;

	explicit ReferenceBaseCtorDtor(ENUM_DONT_INITIALIZE)
	{
	}

	ReferenceBaseCtorDtor(const ReferenceBaseCtorDtor& src) = delete;
	ReferenceBaseCtorDtor& operator =(const ReferenceBaseCtorDtor& src) = delete;

private:
	typename S::ReferencedType* _object;
};

template <Bool DELETE, typename SELF, typename T, typename DST, typename SRC, Bool = !STD_IS_REPLACEMENT(base_of, SELF, SRC) && maxon::HasErasedBase<T, typename SELF::ReferencedType>::value> struct ReferenceConversionHelper
{
	static const Bool value = false;
};

template <Bool DELETE, typename SELF, typename T, typename DST, typename SRC> struct ReferenceConversionHelper<DELETE, SELF, T, DST, SRC, true>
{
#ifndef MAXON_COMPILER_MSVC // workaround for MSVC, the test for a valid generic conversion is moved to constructor and assignment operator below
	static const Bool value = DST::template IsGenericBaseOf<SRC>::value != DELETE;
#else
	static const Bool value = true;
#endif
};

template <typename ST> class ReferenceBase : public ReferenceBaseCtorDtor<typename ST::type, ST::type::Handler::KIND & (VALUEKIND::POINTER | VALUEKIND::DEEP_CONSTNESS | VALUEKIND::ZERO_INITIALIZED)>
{
public:
	ReferenceBase() = default;
	ReferenceBase(const ReferenceBase&) = default;
	ReferenceBase& operator =(const ReferenceBase&) = default;
	ReferenceBase(ReferenceBase&&) = default;
	ReferenceBase& operator =(ReferenceBase&&) = default;

	using ReferenceBaseSuper = typename ST::type;
	using Super = ReferenceBaseCtorDtor<ReferenceBaseSuper, ReferenceBaseSuper::Handler::KIND & (VALUEKIND::POINTER | VALUEKIND::DEEP_CONSTNESS | VALUEKIND::ZERO_INITIALIZED)>;
	using ReferencedType = typename ReferenceBaseSuper::ReferencedType;

	MAXON_IMPLICIT ReferenceBase(ReferencedType* ptr) : Super(DONT_INITIALIZE)
	{
		new (this) typename ReferenceBaseSuper::BaseRefType(ptr);
	}

	//----------------------------------------------------------------------------------------
	/// Constructs a reference with a pointer forwarded from a memory allocation. The template
	/// parameter is used to avoid unnecessary conversion from ResultPtr<X> to ResultPtr<const X>.
	//----------------------------------------------------------------------------------------
	template <typename PTR> explicit ReferenceBase(ForwardResultPtr<PTR> ptr) : Super(DONT_INITIALIZE)
	{
		new (this) typename ReferenceBaseSuper::BaseRefType(ptr);
	}

	MAXON_IMPLICIT ReferenceBase(std::nullptr_t) = delete;

	template <typename REF, typename = typename std::enable_if<ReferenceConversionHelper<false, ReferenceBase, typename std::decay<REF>::type::ReferencedType, ReferenceBaseSuper, typename std::decay<REF>::type>::value>::type>
	MAXON_IMPLICIT ReferenceBase(REF&& src) : Super(DONT_INITIALIZE)
	{
#ifdef MAXON_COMPILER_MSVC
		static_assert(ReferenceBaseSuper::template IsGenericBaseOf<typename std::decay<REF>::type>::value, "Generic conversion not possible.");
#endif
		new (this) typename ReferenceBaseSuper::BaseRefType(std::forward<REF>(src));
	}

#ifndef MAXON_COMPILER_MSVC
	template <typename REF, typename = typename std::enable_if<ReferenceConversionHelper<true, ReferenceBase, typename std::decay<REF>::type::ReferencedType, ReferenceBaseSuper, typename std::decay<REF>::type>::value>::type, typename = void>
	MAXON_IMPLICIT ReferenceBase(REF&& src) = delete;
#endif

	ReferenceBase& operator =(ReferencedType* ptr)
	{
		reinterpret_cast<typename ReferenceBaseSuper::BaseRefType*>(this)->operator =(ptr);
		return *this;
	}

	template <typename REF, typename = typename std::enable_if<ReferenceConversionHelper<false, ReferenceBase, typename std::decay<REF>::type::ReferencedType, ReferenceBaseSuper, typename std::decay<REF>::type>::value>::type>
	ReferenceBase& operator =(REF&& src)
	{
#ifdef MAXON_COMPILER_MSVC
		static_assert(ReferenceBaseSuper::template IsGenericBaseOf<typename std::decay<REF>::type>::value, "Generic conversion not possible.");
#endif
		reinterpret_cast<typename ReferenceBaseSuper::BaseRefType*>(this)->operator =(std::forward<REF>(src));
		return *this;
	}

#ifndef MAXON_COMPILER_MSVC
	template <typename REF, typename = typename std::enable_if<ReferenceConversionHelper<true, ReferenceBase, typename std::decay<REF>::type::ReferencedType, ReferenceBaseSuper, typename std::decay<REF>::type>::value>::type, typename = void>
	ReferenceBase& operator =(REF&& src) = delete;
#endif

	ReferenceBase& operator =(std::nullptr_t)
	{
		this->ResetReference();
		return *this;
	}

	static const typename ReferenceBaseSuper::ReferenceClass& NullValue()
	{
		return GetPtrSizedZeroRef<typename ReferenceBaseSuper::ReferenceClass>();
	}

	ResultRef<typename std::remove_const<ReferencedType>::type> MakeWritable(Bool resetOnError = !maxon::HasBaseDetector<ReferencedType, ErrorInterface>::value) { return this->GetBaseRef().MakeWritable(resetOnError); }
};


template <Bool HAS_ERROR, Bool NEVER_NULLPTR, Bool RETURNS_THIS, typename T> struct ReferenceFunctionErrorReturnHelper;

template <typename T> struct ReferenceFunctionErrorReturnHelper<false, true, false, T>
{
	using ReturnType = T;

	template <typename REF> static T ReturnErrorOf(REF* ref)
	{
		return std::forward<T>(reinterpret_cast<typename std::add_lvalue_reference<T>::type>(g_writableMemory[0]));
	}

	template <typename REF> static T Return(REF* ref, const ThreadReferencedError& err)
	{
		return std::forward<T>(reinterpret_cast<typename std::add_lvalue_reference<T>::type>(g_writableMemory[0]));
	}
};

template <> struct ReferenceFunctionErrorReturnHelper<false, true, false, void>
{
	using ReturnType = void;

	template <typename REF> static void ReturnErrorOf(REF* ref)
	{
	}

	template <typename REF> static void Return(REF* ref, const ThreadReferencedError& err)
	{
	}
};

template <typename T> struct ReferenceFunctionErrorReturnHelper<false, false, false, T>
{
	using ReturnType = T;

	template <typename REF> static T ReturnErrorOf(REF* ref)
	{
		return NullValue<T>();
	}

	template <typename REF> static T Return(REF* ref, const ThreadReferencedError& err)
	{
		return NullValue<T>();
	}
};

template <typename T> struct ReferenceFunctionErrorReturnHelper<false, false, false, Result<T>>
{
	using ReturnType = Result<T>;

	template <typename REF> static ReturnType ReturnErrorOf(REF* ref)
	{
		return ReturnType();
	}

	template <typename REF> static const ThreadReferencedError& Return(REF* ref, const ThreadReferencedError& err)
	{
		return err;
	}
};

template <typename T> struct ReferenceFunctionErrorReturnHelper<true, false, false, T>
{
	using ReturnType = T;

	template <typename REF> static const ThreadReferencedError& ReturnErrorOf(REF* ref)
	{
		return ref->GetErrorStorage();
	}

	template <typename REF> static const ThreadReferencedError& Return(REF* ref, const ThreadReferencedError& err)
	{
		return err;
	}
};


template <Bool HAS_ERROR, Bool NEVER_NULLPTR, typename T> struct ReferenceFunctionErrorReturnHelper<HAS_ERROR, NEVER_NULLPTR, true, T>
{
	using ReturnType = T;

	template <typename REF> static T ReturnErrorOf(REF* ref)
	{
		return ref->PrivateGetRefMember();
	}

	template <typename REF> static T Return(REF* ref, const ThreadReferencedError& err)
	{
		return ref->PrivateGetRefMember();
	}

	template <typename REF> static T Return(REF* ref, const typename std::decay<T>::type&)
	{
		return ref->PrivateGetRefMember();
	}
};

template <Bool HAS_ERROR, Bool NEVER_NULLPTR, typename T> struct ReferenceFunctionErrorReturnHelper<HAS_ERROR, NEVER_NULLPTR, true, Result<T>>
{
	using ReturnType = Result<T>;

	template <typename REF> static ReturnType ReturnErrorOf(REF* ref)
	{
		return ReturnType(ref->PrivateGetRefMember(), Result<void>(ref->GetErrorStorage()));
	}

	template <typename REF> static ReturnType Return(REF* ref, const ThreadReferencedError& err)
	{
		return ReturnType(ref->PrivateGetRefMember(), Result<void>(err));
	}
};


/// @endcond

//----------------------------------------------------------------------------------------
/// This macro can be used within non-static member functions to statically assert that the given parameter Name
/// matches the surrounding class.
/// @param[in] Name								Unqualified name of the class.
//----------------------------------------------------------------------------------------
#define MAXON_CHECK_CLASS(Name) \
	static_assert(STD_IS_REPLACEMENT(same, const Name, const PRIVATE_MAXON_ALLOC_TYPENAME std::remove_pointer<decltype(this)>::type), "Macro parameter " #Name " doesn't match class.")


//----------------------------------------------------------------------------------------
/// Use this macro to mark a member function of an interface as an interface method.
/// For simple virtual interfaces, only non-static member functions can be used as interface methods.
/// Example:
/// @code
/// MAXON_METHOD Int GetLength() const;
/// @endcode
/// @see MAXON_INTERFACE_NONVIRTUAL
/// @see MAXON_INTERFACE_SIMPLE_VIRTUAL
/// @see MAXON_INTERFACE
//----------------------------------------------------------------------------------------
#define MAXON_METHOD

//----------------------------------------------------------------------------------------
/// Use this macro to mark a member function of an interface as a function which shall be added
/// to the reference classes. Unlike MAXON_METHOD, the function invocation will not be routed
/// through the interface; you have to provide a normal C++ function definition.
/// All kinds of interfaces allow both static and non-static functions.
///
/// MAXON_FUNCTION is very useful if you need a function pair of which one function is const and the other non-const,
/// but besides constness they do the same so that a single method suffices:
/// @code
/// MAXON_METHOD const MyElement& GetElement() const;
/// MAXON_FUNCTION MyElement& GetElement() { return MAXON_NONCONST_COUNTERPART(GetElement()); }
/// @endcode
/// @see MAXON_INTERFACE_NONVIRTUAL
/// @see MAXON_INTERFACE_SIMPLE_VIRTUAL
/// @see MAXON_INTERFACE
//----------------------------------------------------------------------------------------
#define MAXON_FUNCTION

#define MAXON_METHOD_RESERVE

//----------------------------------------------------------------------------------------
/// Use this as argument to MAXON_INTERFACE_NONVIRTUAL to indicate that the interface should not have automatic
/// reference counting, and that no reference class shall be created for the interface.
/// This can be used for interfaces which shall be accessed
/// through custom-coded wrapper classes which are then also responsible for the proper release of the objects.
/// MAXON_REFERENCE_NONE cannot be used for virtual interfaces.
/// @see MAXON_INTERFACE_NONVIRTUAL
//----------------------------------------------------------------------------------------
#define MAXON_REFERENCE_NONE(DUMMY) \
	public: \
		void AddReference() const { } \
		void RemoveReference() const { } \
		template <typename FREE, typename CAST> void PrivateRemoveReference() const { } \
	private:

#define PRIVATE_MAXON_REFERENCE_NONE_FLAGS maxon::EntityBase::FLAGS::REFERENCE_NONE
#define PRIVATE_MAXON_REFERENCE_NONE_COPY(Name) \
	protected: \
		Name() { MAXON_CHECK_CLASS(Name); } \
		~Name() = default; \
	private: \
		void operator =(const volatile Name&); \
		Name(const Name&); \


//----------------------------------------------------------------------------------------
/// Use this as argument to MAXON_INTERFACE_NONVIRTUAL to indicate that the interface has
/// only static methods. MAXON_REFERENCE_NONE cannot be used for virtual interfaces.
/// @see MAXON_INTERFACE_NONVIRTUAL
//----------------------------------------------------------------------------------------
#define MAXON_REFERENCE_STATIC(DUMMY) MAXON_REFERENCE_NONE(DUMMY)

#define PRIVATE_MAXON_REFERENCE_STATIC_FLAGS maxon::EntityBase::FLAGS::REFERENCE_NONE
#define PRIVATE_MAXON_REFERENCE_STATIC_COPY(Name) private:


//----------------------------------------------------------------------------------------
/// Use this as argument to MAXON_INTERFACE_NONVIRTUAL to indicate that the interface should not have automatic
/// reference counting, but that a reference class shall be created for the interface. The reference
/// class will behave like an ordinary pointer. For the interface design and its usage, one has to
/// take care of the proper release of the objects.
/// MAXON_REFERENCE_POINTER cannot be used for virtual interfaces.
/// @see MAXON_INTERFACE_NONVIRTUAL
//----------------------------------------------------------------------------------------
#define MAXON_REFERENCE_POINTER(DUMMY) \
	public: \
		template <typename ST> struct ReferenceFunctions : public maxon::SFINAEHelper<Hxx1, ST>::type::template ReferenceFunctionsHelper<ST> { }; \
		class Reference; \
		using Ptr = maxon::ReferenceBase<ReferenceFunctions<maxon::RefBaseFunctions<maxon::DirectRef<Interface, maxon::PointerHandler, void>>>>; \
		using ConstPtr = maxon::ReferenceBase<ReferenceFunctions<maxon::RefBaseFunctions<maxon::DirectRef<const Interface, maxon::PointerHandler, void>>>>; \
		void AddReference() const { } \
		void RemoveReference() const { } \
		template <typename FREE, typename CAST> void PrivateRemoveReference() const { } \
	private:

#define PRIVATE_MAXON_REFERENCE_POINTER_FLAGS maxon::EntityBase::FLAGS::REFERENCE_POINTER
#define PRIVATE_MAXON_REFERENCE_POINTER_COPY(Name) PRIVATE_MAXON_REFERENCE_NONE_COPY(Name)

//----------------------------------------------------------------------------------------
/// Use this as argument to MAXON_INTERFACE_NONVIRTUAL to indicate that the interface should not have automatic
/// reference counting, but that a reference class shall be created for the interface. The reference
/// class will behave like an ordinary pointer to a const object. For the interface design and its usage, one has to
/// take care of the proper release of the objects.
/// MAXON_REFERENCE_CONST_POINTER cannot be used for virtual interfaces.
/// @see MAXON_INTERFACE_NONVIRTUAL
//----------------------------------------------------------------------------------------
#define MAXON_REFERENCE_CONST_POINTER(DUMMY) MAXON_REFERENCE_POINTER(DUMMY)

#define PRIVATE_MAXON_REFERENCE_CONST_POINTER_FLAGS maxon::EntityBase::FLAGS::REFERENCE_CONST_POINTER
#define PRIVATE_MAXON_REFERENCE_CONST_POINTER_COPY(Name) PRIVATE_MAXON_REFERENCE_NONE_COPY(Name)

//----------------------------------------------------------------------------------------
/// Use this as argument to MAXON_INTERFACE_NONVIRTUAL or MAXON_INTERFACE if the interface shall
/// use automatic reference counting, and if non-const methods shall operate on the original object
/// instead of making a copy. This is usually used for first-class objects which have an identity
/// rather than just a value. The corresponding reference class is assumed to be the name of the interface
/// with the Interface postfix replaced by Ref (e.g., InputStreamRef for the interface InputStreamInterface).
/// @see MAXON_INTERFACE_NONVIRTUAL
/// @see MAXON_INTERFACE
//----------------------------------------------------------------------------------------
#define MAXON_REFERENCE_NORMAL(DUMMY) \
	public: \
		template <typename ST> struct ReferenceFunctions : public maxon::SFINAEHelper<Hxx1, ST>::type::template ReferenceFunctionsHelper<ST> { }; \
		class Reference; \
		using Ptr = maxon::ReferenceBase<ReferenceFunctions<maxon::RefBaseFunctions<maxon::DirectRef<Interface, maxon::PointerHandler, void>>>>; \
		using ConstPtr = maxon::ReferenceBase<ReferenceFunctions<maxon::RefBaseFunctions<maxon::DirectRef<const Interface, maxon::PointerHandler, void>>>>; \
		static inline void Free(const Interface* object); \
		template <typename FREE, typename CAST> void PrivateRemoveReference() const \
		{ \
			if (MAXON_UNLIKELY(maxon::System::GetReferenceCounter(this).Dec() == true)) \
					FREE::Free(static_cast<const CAST*>(this)); \
		} \
		friend class maxon::StrongRefHandler; \
		friend class maxon::StrongCOWRefHandler; \
	protected:	\
		void RemoveReference() const \
		{ \
			if (MAXON_UNLIKELY(maxon::System::GetReferenceCounter(this).Dec() == true)) \
				Free(this); \
		} \
	private:

#define PRIVATE_MAXON_REFERENCE_NORMAL_FLAGS maxon::EntityBase::FLAGS::REFERENCE_NORMAL
#define PRIVATE_MAXON_REFERENCE_NORMAL_COPY(Name) PRIVATE_MAXON_REFERENCE_NONE_COPY(Name)

//----------------------------------------------------------------------------------------
/// This reference type is similar to MAXON_REFERENCE_NORMAL, with the difference that references
/// can only be moved and not copied. Note that while semantically this is equivalent to a @c UniqueRef,
/// internally the object still uses the reference-counted implementation, with copying disabled.
/// Hence, conversions from/to UniqueRef are not possible.
///
/// @see MAXON_INTERFACE_NONVIRTUAL
/// @see MAXON_INTERFACE
//----------------------------------------------------------------------------------------
#define MAXON_REFERENCE_UNIQUE(DUMMY) \
	public: \
		template <typename ST> struct ReferenceFunctions : public maxon::SFINAEHelper<Hxx1, ST>::type::template ReferenceFunctionsHelper<ST> { }; \
		class Reference; \
		using Ptr = maxon::ReferenceBase<ReferenceFunctions<maxon::RefBaseFunctions<maxon::DirectRef<Interface, maxon::PointerHandler, void>>>>; \
		using ConstPtr = maxon::ReferenceBase<ReferenceFunctions<maxon::RefBaseFunctions<maxon::DirectRef<const Interface, maxon::PointerHandler, void>>>>; \
		static inline void Free(const Interface* object); \
		template <typename FREE, typename CAST> void PrivateRemoveReference() const \
		{ \
			if (MAXON_UNLIKELY(maxon::System::GetReferenceCounter(this).Dec() == true)) \
					FREE::Free(static_cast<const CAST*>(this)); \
		} \
		friend class maxon::StrongRefHandler; \
		friend class maxon::StrongCOWRefHandler; \
	protected:	\
		void RemoveReference() const \
		{ \
			if (MAXON_UNLIKELY(maxon::System::GetReferenceCounter(this).Dec() == true)) \
				Free(this); \
		} \
	private:

#define PRIVATE_MAXON_REFERENCE_UNIQUE_FLAGS maxon::EntityBase::FLAGS::REFERENCE_NORMAL
#define PRIVATE_MAXON_REFERENCE_UNIQUE_COPY(Name) PRIVATE_MAXON_REFERENCE_NONE_COPY(Name)

//----------------------------------------------------------------------------------------
/// Use this as argument to MAXON_INTERFACE_NONVIRTUAL or MAXON_INTERFACE if the interface shall
/// use automatic reference counting, and if only const methods of the interface shall be carried over
/// to the reference class. This is usually used for stateless objects which, once initialized,
/// provide their relevant functionality through const methods (e.g., IoHandlerInterface).
/// The corresponding reference class is assumed to be the name of the interface
/// with the Interface postfix removed (e.g., IoHandler for the interface IoHandlerInterface).
/// @see MAXON_INTERFACE_NONVIRTUAL
/// @see MAXON_INTERFACE
//----------------------------------------------------------------------------------------
#define MAXON_REFERENCE_CONST(DUMMY) MAXON_REFERENCE_NORMAL(DUMMY)

#define PRIVATE_MAXON_REFERENCE_CONST_FLAGS maxon::EntityBase::FLAGS::REFERENCE_CONST
#define PRIVATE_MAXON_REFERENCE_CONST_COPY(Name) PRIVATE_MAXON_REFERENCE_NONE_COPY(Name)

//----------------------------------------------------------------------------------------
/// Use this as argument to MAXON_INTERFACE_NONVIRTUAL or MAXON_INTERFACE if the interface shall
/// use automatic reference counting, and if the reference class shall have copy-on-write semantics.
/// This means that when a non-const method is invoked through a reference and there are further references,
/// a copy of the original object is made, and the non-const method is invoked on the copy.
/// Thus, the further references aren't affected by potential modifications of the non-const method.
/// This is usually used for value types (second-class objects) where only the value is important such as String.
/// The corresponding reference class is assumed to be the name of the interface
/// without the Interface postfix (e.g., String for the interface StringInterface).
/// @see MAXON_INTERFACE_NONVIRTUAL
/// @see MAXON_INTERFACE
//----------------------------------------------------------------------------------------
#define MAXON_REFERENCE_COPY_ON_WRITE(DUMMY) MAXON_REFERENCE_NORMAL(DUMMY)

#define PRIVATE_MAXON_REFERENCE_COPY_ON_WRITE_FLAGS maxon::EntityBase::FLAGS::REFERENCE_COPY_ON_WRITE
#define PRIVATE_MAXON_REFERENCE_COPY_ON_WRITE_COPY(Name) static inline Interface* Alloc(MAXON_SOURCE_LOCATION_DECLARATION); static inline Interface* Alloc(MAXON_SOURCE_LOCATION_DECLARATION, const Interface& o); PRIVATE_MAXON_REFERENCE_NONE_COPY(Name)

//----------------------------------------------------------------------------------------
/// Use this as argument to MAXON_INTERFACE_NONVIRTUAL or MAXON_INTERFACE if the interface shall
/// use automatic reference counting, and if the reference class shall have always-copy-on-write semantics.
/// In contrast to MAXON_REFERENCE_COPY_ON_WRITE, this also makes a copy of the object if there is no other
/// reference to the object, so that non-const methods, invoked through the reference class,
/// will never modify an existing object.
/// In other words: If the refcount == 1 then a call to a set function will always duplicate the object.
/// The corresponding reference class is assumed to be the name of the interface
/// without the Interface postfix (e.g., String for the interface StringInterface).
/// @see MAXON_INTERFACE_NONVIRTUAL
/// @see MAXON_INTERFACE
//----------------------------------------------------------------------------------------
#define MAXON_REFERENCE_ALWAYS_COPY_ON_WRITE(DUMMY) MAXON_REFERENCE_NORMAL(DUMMY)

#define PRIVATE_MAXON_REFERENCE_ALWAYS_COPY_ON_WRITE_FLAGS maxon::EntityBase::FLAGS::REFERENCE_ALWAYS_COPY_ON_WRITE
#define PRIVATE_MAXON_REFERENCE_ALWAYS_COPY_ON_WRITE_COPY(Name) PRIVATE_MAXON_REFERENCE_COPY_ON_WRITE_COPY(Name)


//----------------------------------------------------------------------------------------
/// Use MAXON_ADD_TO_REFERENCE_CLASS if you want to add further code to the automatically
/// generated non-const reference class of an interface. The source processor adds the arguments of the macro
/// to the public part of the generated reference class. The added function will not be part
/// of the generated const reference class or of the generated copy-on-write reference class.
/// Example:
/// @code
///	class DataFormatBaseReaderInterface : MAXON_INTERFACE_BASES(DataDictionaryObjectInterface)
///	{
///		MAXON_INTERFACE(DataFormatBaseReaderInterface, MAXON_REFERENCE_NORMAL, "net.maxon.interface.dataformatbasereader");
///
///	public:
///		MAXON_METHOD Result<void> CloseInput();
///
///		MAXON_ADD_TO_REFERENCE_CLASS(
///		Result<void> ResetMaybeCloseInput()
///		{
///			Result<void> res = OK;
///			if (this->GetPointer())
///			{
///				if (System::GetReferenceCounter(this->GetPointer()) == 1)
///					res = this->GetPointer()->CloseInput();
///				this->ResetReference();
///			}
///			return res;
///		}
///		);
///		...
///	};
/// @endcode
///
/// @param[in] ...								Code which shall be added to the generated reference class.
/// @see MAXON_ADD_TO_CONST_REFERENCE_CLASS
/// @see MAXON_ADD_TO_COPY_ON_WRITE_REFERENCE_CLASS
//----------------------------------------------------------------------------------------
#define MAXON_ADD_TO_REFERENCE_CLASS(...)

//----------------------------------------------------------------------------------------
/// Use MAXON_ADD_TO_COPY_ON_WRITE_REFERENCE_CLASS if you want to add further code to the automatically
/// generated copy-on-write reference class of an interface. The source processor adds the arguments of the macro
/// to the public part of the generated reference class. The added function will not be part
/// of the generated const reference class or of the generated non-const reference class.
/// For an example see MAXON_ADD_TO_REFERENCE_CLASS.
///
/// @param[in] ...								Code which shall be added to the generated reference class.
/// @see MAXON_ADD_TO_REFERENCE_CLASS
/// @see MAXON_ADD_TO_CONST_REFERENCE_CLASS
//----------------------------------------------------------------------------------------
#define MAXON_ADD_TO_COPY_ON_WRITE_REFERENCE_CLASS(...)

//----------------------------------------------------------------------------------------
/// Use MAXON_ADD_TO_CONST_REFERENCE_CLASS if you want to add further code to the automatically
/// generated const reference class of an interface. The source processor adds the arguments of the macro
/// to the public part of the generated reference class. The added function will also be part
/// of the generated non-const reference class and the generated copy-on-write reference class.
/// For an example see MAXON_ADD_TO_REFERENCE_CLASS.
///
/// @param[in] ...								Code which shall be added to the generated reference class.
/// @see MAXON_ADD_TO_REFERENCE_CLASS
/// @see MAXON_ADD_TO_COPY_ON_WRITE_REFERENCE_CLASS
//----------------------------------------------------------------------------------------
#define MAXON_ADD_TO_CONST_REFERENCE_CLASS(...)

#define MAXON_ADD_TO_INTERFACE_TEMPLATE_CLASS(...)

//----------------------------------------------------------------------------------------
/// MAXON_INTERFACE_NONVIRTUAL marks a class declaration as a non-virtual interface declaration. Non-virtual
/// interfaces are used to separate code into a published interface and its internal implementation.
/// The implementation may reside in a different module as code which makes use of the interface,
/// and the whole mechanism is compatible among different compilers.
///
/// @ref nvinterfaces describes the declaration and implementation of non-virtual interfaces in detail.
/// An example is the declaration of StringInterface:
/// @code
/// class Application
/// {
/// 	MAXON_INTERFACE_NONVIRTUAL(Application, MAXON_REFERENCE_NONE, "net.maxon.interface.application");
/// public:
/// 	static MAXON_METHOD Result<Url> GetUrl(APPLICATION_URLTYPE urlType);
/// 	...
/// };
/// @endcode
/// Non-virtual interfaces must not specify a base class unless you use MAXON_INTERFACE_NONVIRTUAL_DERIVED
/// instead of MAXON_INTERFACE_NONVIRTUAL.
/// Non-virtual interfaces have to be implemented by another class using MAXON_IMPLEMENTATION.
///
/// @param[in] Name								Name of the interface (has to be the same as the surrounding class name).
/// @param[in] REFKIND						One of MAXON_REFERENCE_NONE, MAXON_REFERENCE_STATIC, MAXON_REFERENCE_POINTER, MAXON_REFERENCE_CONST_POINTER, MAXON_REFERENCE_NORMAL, MAXON_REFERENCE_CONST, MAXON_REFERENCE_COPY_ON_WRITE, MAXON_REFERENCE_ALWAYS_COPY_ON_WRITE.
/// @param[in] ID									The unique identifier of the interface.
/// @see @ref nvinterfaces
/// @see MAXON_METHOD
/// @see MAXON_FUNCTION
/// @see MAXON_INTERFACE_NONVIRTUAL_DERIVED
/// @see MAXON_INTERFACE
///
/// @note It is recommended to use virtual interfaces (MAXON_INTERFACE) instead of non-virtual ones unless
/// the interface consists only of static methods.
///
/// @note The macro itself leaves incomplete code which is completed by the source processor.
/// So you have to place the macro in a header file, because the source processor only scans
/// header files, and you have to include the generated hxx files in the header file.
/// MAXON_INTERFACE_NONVIRTUAL must be placed somewhere before the \#include of the first hxx file.
//----------------------------------------------------------------------------------------
#define MAXON_INTERFACE_NONVIRTUAL(Name, REFKIND, ID) \
	public: \
		using Interface = Name; \
		using BaseInterface = Name; \
		static maxon::NonvirtualInterfaceReference _interface; \
		struct MTable; \
		struct Hxx1; \
		struct Hxx2; \
		using NonvirtualInterfaceMarker = std::true_type; \
		using IsAllocType = std::true_type; \
		static const Name* NullValuePtr() { MAXON_ASSERT_STANDARD_LAYOUT(Name); return (const Name*) _interface.GetNullValue(); } \
		template <typename DUMMY> static inline maxon::Int PrivateInstantiateNullValueHelper(); \
		static constexpr const maxon::Char* PrivateGetCppName(); \
		static const maxon::EntityBase::FLAGS REFERENCE_KIND = PRIVATE_##REFKIND##_FLAGS; \
		PRIVATE_##REFKIND##_COPY(Name) \
		template <typename T> friend void maxon::Destruct(T* object); \
		REFKIND(DUMMY)

//----------------------------------------------------------------------------------------
/// MAXON_INTERFACE_NONVIRTUAL_DERIVED marks a class declaration as a non-virtual interface declaration
/// which is derived from another such declaration (i.e., either MAXON_INTERFACE_NONVIRTUAL or MAXON_INTERFACE_NONVIRTUAL_DERIVED).
/// You have to use the base interface as base class in the class declaration.
/// The derived interface inherits all methods from its base interface. You cannot use more than
/// one direct base interface. Example:
/// @code
/// class MacroPortInterface : public AttributedObjectInterface
/// {
/// 	MAXON_INTERFACE_NONVIRTUAL_DERIVED(MacroPortInterface, MAXON_REFERENCE_NORMAL, "net.maxon.interface.macroport");
///   ...
/// };
/// @endcode
/// Derived non-virtual interfaces have to be implemented by another class using MAXON_IMPLEMENTATION_DERIVED.
///
/// @param[in] Name								Name of the interface (has to be the same as the surrounding class name).
/// @param[in] REFKIND						One of MAXON_REFERENCE_NONE, MAXON_REFERENCE_POINTER, MAXON_REFERENCE_CONST_POINTER, MAXON_REFERENCE_NORMAL, MAXON_REFERENCE_CONST, MAXON_REFERENCE_COPY_ON_WRITE, MAXON_REFERENCE_ALWAYS_COPY_ON_WRITE.
/// @param[in] ID									The unique identifier of the interface.
/// @see @ref nvinterfaces
/// @see MAXON_INTERFACE_NONVIRTUAL
///
/// @warning As one can act (through an upcasted pointer to the base interface) on the implementation
/// of the derived interface as if it was the implementation of the base interface, the
/// implementation of the derived interface should derive from the implementation of the base interface
/// (at least both have to be compatible).
//----------------------------------------------------------------------------------------
#define MAXON_INTERFACE_NONVIRTUAL_DERIVED(Name, REFKIND, ID) \
	public: \
		using Interface = Name; \
		static NonvirtualInterfaceReference _interface; \
		struct MTable; \
		struct Hxx1; \
		struct Hxx2; \
		using NonvirtualInterfaceMarker = std::true_type; \
		template <typename ST> struct ReferenceFunctions : public maxon::SFINAEHelper<Hxx1, ST>::type::template ReferenceFunctionsHelper<ST> { }; \
		class Reference; \
		using Ptr = maxon::ReferenceBase<ReferenceFunctions<maxon::RefBaseFunctions<maxon::DirectRef<Interface, maxon::PointerHandler, void>>>>; \
		using ConstPtr = maxon::ReferenceBase<ReferenceFunctions<maxon::RefBaseFunctions<maxon::DirectRef<const Interface, maxon::PointerHandler, void>>>>; \
		static const Name* NullValuePtr() { return (const Name*) _interface.GetNullValue(); } \
		template <typename DUMMY> static inline maxon::Int PrivateInstantiateNullValueHelper(); \
		static constexpr const maxon::Char* PrivateGetCppName(); \
		static inline void Free(const Name*); \
		void RemoveReference() const { PrivateRemoveReference<Name, Name>(); } \
		static const maxon::EntityBase::FLAGS REFERENCE_KIND = PRIVATE_##REFKIND##_FLAGS; \
		PRIVATE_##REFKIND##_COPY(Name)

#define _MAXON_IMPLEMENTATION_BASICS(C) \
	public: \
		using MTable = std::false_type; /* for the IsInterfaceType detection */ \
		static C* Get(Interface* object) { return (C*) object; } \
		static const C* Get(const Interface* object) { return (const C*) object; } \
		static const C* GetOrNullValue(const Interface* object) { return object ? (const C*) object : _nullValue; } \
	private: \
		using Implementation = C; \
		template <typename T> friend void maxon::Destruct(T* object); \
		static maxon::Result<const maxon::Generic*> _PrivateInitImplementation(); \
		static void _PrivateFreeImplementation(); \
		friend class maxon::NonvirtualInterfaceImplementation; \
		friend class maxon::StrongRefHandler; \
		template <typename D, typename B, maxon::Int HAS_BASE_OR_SAME> friend class maxon::details::HasBaseHelper; \
		class _Wrapper; \
		static C* _nullValue;

#define MAXON_IMPLEMENTATION_BASICS(C, I) \
	public: \
		using Interface = I; \
		using PrivateInterface = I; \
		Interface* ToInterface() { MAXON_CHECK_CLASS(C); return (Interface*) this; } \
		const Interface* ToInterface() const { return (const Interface*) this; } \
		_MAXON_IMPLEMENTATION_BASICS(C)

#define _MAXON_IMPLEMENTATION(C, cast) \
		_MAXON_IMPLEMENTATION_BASICS(C) \
	public: \
		Interface* ToInterface() { MAXON_CHECK_CLASS(C); return cast<Interface*>(this); } \
		const Interface* ToInterface() const { return cast<const Interface*>(this); } \
		using NonvirtualInterfaceMarker = std::false_type; \
		using IsAllocType = std::false_type; \
		using IsImplementationType = std::true_type; \
		static void Free(const volatile BaseInterface* object) { maxon::System::FreeWithDestructor((const C*) object, &maxon::Destruct<const C>); } \
		template <typename D> static typename maxon::SFINAEHelper<Interface*, typename D::SourceLocationMarker>::type Alloc(const D& allocLocation) { return cast<Interface*>(MAXON_SAFE_PLACEMENT_NEW (maxon::DefaultAllocator::Alloc(SIZEOF(C), MAXON_SOURCE_LOCATION_FORWARD)) typename maxon::SFINAEHelper<C, D>::type); } \
		template <typename A1> static Interface* Alloc(MAXON_SOURCE_LOCATION_DECLARATION, A1&& a1) { return cast<Interface*>(maxon::ObjectConstructor<C, maxon::TestForCopyFromMember<C>::isSupported>::Alloc(maxon::DefaultAllocator::Alloc(SIZEOF(C), MAXON_SOURCE_LOCATION_FORWARD), std::forward<A1>(a1))); } \
		template <typename A1, typename A2, typename... ARGS> static Interface* Alloc(MAXON_SOURCE_LOCATION_DECLARATION, A1&& a1, A2&& a2, ARGS&&... args) { return cast<Interface*>(MAXON_SAFE_PLACEMENT_NEW(maxon::DefaultAllocator::Alloc(SIZEOF(C), MAXON_SOURCE_LOCATION_FORWARD)) C(std::forward<A1>(a1), std::forward<A2>(a2), std::forward<ARGS>(args)...)); } \
		using BaseInterface::NullValuePtr;


//----------------------------------------------------------------------------------------
/// MAXON_IMPLEMENTATION has to be used within an implementation class for a non-virtual interface
/// (declared with MAXON_INTERFACE_NONVIRTUAL). For more details, see @ref nvinterfaces.
/// An example is the implementation of StringInterface by a class XStringImpl:
/// @code
/// class XStringImpl : private StringInterface
/// {
///   MAXON_IMPLEMENTATION(XStringImpl);
/// public:
///   XStringImpl() { }
///   XStringImpl(const XStringImpl& str) { Insert(0, &str); }
///   Int GetLength() const { return _txt.GetCount(); }
///   ...
/// };
/// MAXON_IMPLEMENTATION_REGISTER(XStringImpl);
/// @endcode
/// Don't forget to add MAXON_IMPLEMENTATION_REGISTER below the implementation class.
///
/// @param[in] C									Name of the implementation class (has to be the same as the surrounding class name).
/// @see @ref nvinterfaces
//----------------------------------------------------------------------------------------
#define MAXON_IMPLEMENTATION(C) \
	public: \
		using PrivateInterface = Interface; \
		_MAXON_IMPLEMENTATION(C, static_cast)
// the PrivateInterface type alias above is needed because C::Interface is inaccessible from the outside when C doesn't inherit publicly from Interface, and a using Interface::Interface doesn't work

//----------------------------------------------------------------------------------------
/// MAXON_IMPLEMENTATION_DERIVED has to be used within an implementation class for a derived non-virtual interface
/// (declared with MAXON_INTERFACE_NONVIRTUAL_DERIVED). The implementation class should derive from the implementation
/// class of the base interface. For more details, see @ref nvinterfaces.
/// An example is the implementation of MacroPortInterface by a class Port (AttributedObject implements
/// the base interface AttributedObjectInterface):
/// @code
/// class Port : public AttributedObject
/// {
/// 	MAXON_IMPLEMENTATION_DERIVED(Port, MacroPortInterface);
/// public:
///   ...
/// };
/// MAXON_IMPLEMENTATION_REGISTER(Port);
/// @endcode
/// Don't forget to add MAXON_IMPLEMENTATION_REGISTER below the implementation class.
///
/// @param[in] C									Name of the implementation class (has to be the same as the surrounding class name).
/// @param[in] I									Name of the derived interface which C implements.
/// @see @ref nvinterfaces
//----------------------------------------------------------------------------------------
#define MAXON_IMPLEMENTATION_DERIVED(C, I) \
	public: \
		using Interface = I; \
		using PrivateInterface = I; \
		_MAXON_IMPLEMENTATION(C, reinterpret_cast)

// TODO: (Ole) in the *.dox docu it should be mentioned how return values work (that there needs to be a NullValue implementation) and how to add those if you're not using the basic datatypes
// TODO: (Ole) it should be mentioned that in interface headers "Int* bla" works, but "Int *bla" doesn't
// TODO: (Ole) also it should be mentioned that commenting out lines doesn't work in interface headers - however #if 0 / #endif works
// TODO: (Ole) it should also be mentioned that includes in interface headers need to be chosen extremely carefully as otherwise unnecessary or unwanted dependencies are generated; forwards should be used whereever possible

// if an interface implementation has a NullValue function, use this
template <typename C> inline typename NullValueDetector<C*, &C::NullValue>::type ImplementationCreateNullValue(OverloadRank3)
{
	return C::NullValue();
}

#define COW_KIND_SFINAE typename std::enable_if<MAXON_IS_COW_KIND(C::PrivateInterface::Hxx1::ReferenceClass::Handler::KIND), C*>::type

// otherwise, use a default-constructed object if the interface has a COW reference class
template <typename C> inline COW_KIND_SFINAE ImplementationCreateNullValue(OverloadRank2)
{
	static_assert(MAXON_IS_COW_KIND(C::PrivateInterface::Hxx1::ReferenceClass::Handler::KIND), "Compiler bug, non-COW references shouldn't use this overload");
	C* o = (C*) PrivateSystemAlloc(SIZEOF(C));
	if (o)
	{
		new (o) C();
		StrongRefHandler::AddReference(o->ToInterface());
	}
	return o;
}

// otherwise, return nullptr if there is a non-COW reference class
template <typename C> inline typename SFINAEHelper<C*, typename C::PrivateInterface::Hxx1::ReferenceClass::Handler>::type ImplementationCreateNullValue(OverloadRank1)
{
	static_assert(!MAXON_IS_COW_KIND(C::PrivateInterface::Hxx1::ReferenceClass::Handler::KIND), "Compiler bug, COW references shouldn't use this overload");
	return nullptr;
}

// otherwise, use nullptr as null value for interfaces without reference class
template <typename C> inline C* ImplementationCreateNullValue(OverloadRank0)
{
	return nullptr;
}

// now the same for the proper destruction of the null value
template <typename C> inline typename NullValueDetector<C*, &C::NullValue>::type ImplementationDestroyNullValue(const C*, OverloadRank3)
{
	return nullptr;
}

class PrivateDummyFree
{
public:
	static void Free(const void*) { }
};

template <typename C> inline COW_KIND_SFINAE ImplementationDestroyNullValue(const C* o, OverloadRank2)
{
	o->ToInterface()->template PrivateRemoveReference<PrivateDummyFree, const void>();
	o->~C();
	PrivateSystemFree(const_cast<C*>(o));
	return nullptr;
}

template <typename C> inline void ImplementationDestroyNullValue(const C*, OverloadRank0)
{
}

//----------------------------------------------------------------------------------------
/// MAXON_IMPLEMENTATION_REGISTER completes the implementation of a non-virtual interface.
/// It has to be used below the declaration of the implementation class (see MAXON_IMPLEMENTATION).
///
/// @param[in] C									Name of the implementation class.
/// @param[in] ...								Additional flags for the NonvirtualInterfaceImplementation such as EntityBase::FLAGS::EXPLICIT.
/// @see @ref nvinterfaces
//----------------------------------------------------------------------------------------
#define MAXON_IMPLEMENTATION_REGISTER(C, ...) \
	PRIVATE_MAXON_REGISTER_CHECK("MAXON_IMPLEMENTATION_REGISTER"); \
	class C::_Wrapper : public C::Interface::Hxx2::Wrapper<C> \
	{ \
		static maxon::NonvirtualInterfaceImplementation _implementation; \
		friend class ObjectModel; \
	}; \
  maxon::NonvirtualInterfaceImplementation C::_Wrapper::_implementation((C*) nullptr, #C, C::Interface::PrivateGetCppName(), C::Interface::_interface, (maxon::NonvirtualInterfaceReference::MTableInitializer) &maxon::details::InitMTable<typename C::Interface::MTable, typename C::_Wrapper>, C::Interface::REFERENCE_KIND | maxon::EntityBase::FLAGS(__VA_ARGS__), &maxon::g_translationUnit, __FILE__); \
	C* C::_nullValue; \
	maxon::Result<const maxon::Generic*> C::_PrivateInitImplementation() \
	{ \
		_nullValue = maxon::ImplementationCreateNullValue<C>( OVERLOAD_MAX_RANK); \
		using namespace maxon::defaultimplementation; \
		maxon::Result<void> res = InitImplementation(); \
		if (res == maxon::FAILED) return maxon::Result<const maxon::Generic*>(nullptr, std::move(res)); \
		return (const maxon::Generic*) _nullValue; \
	} \
	void C::_PrivateFreeImplementation() \
	{ \
		using namespace maxon::defaultimplementation; FreeImplementation(); \
		maxon::ImplementationDestroyNullValue<C>(_nullValue, OVERLOAD_MAX_RANK); \
	}

//----------------------------------------------------------------------------------------
/// MAXON_INTERFACE_SIMPLE_VIRTUAL marks a class declaration as a simple virtual interface declaration.
/// Unlike true virtual interfaces (MAXON_INTERFACE), simple virtual interfaces only
/// support tree-like inheritance (no multiple inheritance), and they don't support adapters between different versions.
/// They have less overhead for method invocations, so you should use simple virtual interfaces
/// for performance-critical low-level purposes, where the interface is unlikely to change often.
///
/// @ref svinterfaces describes the declaration and implementation of simple virtual interfaces in detail.
/// As an example, consider:
/// @code
/// class SimpleInterface
/// {
/// 	MAXON_INTERFACE_SIMPLE_VIRTUAL(SimpleInterface, MAXON_REFERENCE_NORMAL);
/// public:
/// 	MAXON_METHOD void DoSomething(Int index);
/// };
/// @endcode
/// You can derive from simple virtual interfaces using MAXON_INTERFACE_SIMPLE_VIRTUAL_DERIVED.
///
/// Simple virtual interfaces can be implemented by several classes.
/// An implementation class has to derive from the interface and to contain MAXON_IMPLEMENTATION_SIMPLE,
/// and in its constructors it has to pass the static @c _clsMTable member declared by MAXON_IMPLEMENTATION_SIMPLE to the constructor
/// of the base interface. Finally you have to use MAXON_IMPLEMENTATION_REGISTER_SIMPLE behind the
/// class declaration to construct the vtable:
/// @code
/// class SimpleImpl : private SimpleInterface
/// {
/// 	MAXON_IMPLEMENTATION_SIMPLE(SimpleImpl);
/// public:
/// 	SimpleImpl() : SimpleInterface(_clsMTable) { }
/// 	void DoSomething(Int index) { }
/// };
///
/// MAXON_IMPLEMENTATION_REGISTER_SIMPLE(SimpleImpl);
/// @endcode
/// Simple virtual interfaces can be class templates (all other kinds of interfaces can't).
/// In this case you have to prefix the registration as in
/// @code
/// template <typename ARRAY> MAXON_IMPLEMENTATION_REGISTER_SIMPLE(ArrayImpl<ARRAY>);
/// @endcode
///
/// Simple virtual interfaces can't have static methods, but they may have static functions
/// (marked with MAXON_FUNCTION).
///
/// @param[in] Name								Name of the interface (has to be the same as the surrounding class name).
/// @param[in] REFKIND						One of MAXON_REFERENCE_NONE, MAXON_REFERENCE_POINTER, MAXON_REFERENCE_CONST_POINTER, MAXON_REFERENCE_NORMAL, MAXON_REFERENCE_CONST, MAXON_REFERENCE_COPY_ON_WRITE, MAXON_REFERENCE_ALWAYS_COPY_ON_WRITE.
/// @see @ref svinterfaces
/// @see MAXON_METHOD
/// @see MAXON_FUNCTION
/// @see MAXON_INTERFACE_SIMPLE_VIRTUAL_DERIVED
/// @see MAXON_IMPLEMENTATION_SIMPLE
/// @see MAXON_IMPLEMENTATION_REGISTER_SIMPLE
/// @see MAXON_INTERFACE
///
/// @note The macro itself leaves incomplete code which is completed by the source processor.
/// So you have to place the macro in a header file, because the source processor only scans
/// header files, and you have to include the generated hxx files in the header file.
/// MAXON_INTERFACE_SIMPLE_VIRTUAL must be placed somewhere before the \#include of the first hxx file.
//----------------------------------------------------------------------------------------
#define MAXON_INTERFACE_SIMPLE_VIRTUAL(Name, REFKIND) \
	public: \
		using Interface = Name; \
		using BaseInterface = Name; \
		struct MTable; \
		using HasBaseDetector = maxon::details::DefaultHasBase<Interface>; \
		struct Hxx1; \
		struct Hxx2; \
		static std::nullptr_t NullValuePtr() { return nullptr; } \
		template <typename DUMMY> static inline maxon::Int PrivateInstantiateNullValueHelper(); \
		using IsAllocType = std::true_type; \
		static const maxon::EntityBase::FLAGS REFERENCE_KIND = PRIVATE_##REFKIND##_FLAGS; \
		static maxon::InterfaceReference* PrivateGetInterface() { return nullptr; } \
	protected: \
		inline Name(const MTable& vtable); \
		~Name() { MAXON_CHECK_CLASS(Name); } \
		REFKIND(DUMMY) \
	PRIVATE_MAXON_INTERFACE_SIMPLE_VIRTUAL_VTABLE_ACCESS: \
		const maxon::ClassInterface* const* MAXON_INTERFACE_SIMPLE_VIRTUAL_CONST_VTABLE_POINTER _vtableCls; \
	private: \
		MAXON_DISALLOW_COPY_AND_ASSIGN(Name);

#ifdef MAXON_COMPILER_MSVC
	#define PRIVATE_MAXON_INTERFACE_SIMPLE_VIRTUAL_VTABLE_ACCESS public
#else
	#define PRIVATE_MAXON_INTERFACE_SIMPLE_VIRTUAL_VTABLE_ACCESS protected
#endif


// needed for the array, set and map interfaces
#if defined(MAXON_COMPILER_MSVC) && MAXON_COMPILER_MSVC >= 1914
	#define CPP_853_HACK // MSVC has a bug regarding C++11 8.5.3. GCC < 5.1 had one, see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57610.

	#define CPP_853_HACK_MAXON_INTERFACE_SIMPLE_VIRTUAL(Name, REFKIND) \
		public: \
			using Interface = Name; \
			using BaseInterface = Name; \
			struct MTable; \
			struct Hxx1; \
			struct Hxx2; \
			static std::nullptr_t NullValuePtr() { return nullptr; } \
			template <typename DUMMY> static inline maxon::Int PrivateInstantiateNullValueHelper(); \
			using IsAllocType = std::true_type; \
			static const maxon::EntityBase::FLAGS REFERENCE_KIND = PRIVATE_##REFKIND##_FLAGS; \
		protected: \
			inline Name(const MTable& vtable); \
			const maxon::ClassInterface* const* MAXON_INTERFACE_SIMPLE_VIRTUAL_CONST_VTABLE_POINTER _vtableCls; \
			REFKIND(DUMMY) \
		private: \
			void operator =(const Name&);
#endif


#define MAXON_INTERFACE_SIMPLE_VIRTUAL_CONST_VTABLE_POINTER const

//----------------------------------------------------------------------------------------
/// MAXON_INTERFACE_SIMPLE_VIRTUAL_DERIVED marks a class declaration as a simple virtual interface declaration
/// which is derived from another such declaration (i.e., declared with MAXON_INTERFACE_SIMPLE_VIRTUAL
/// or MAXON_INTERFACE_SIMPLE_VIRTUAL_DERIVED).
/// You have to use the base interface as base class in the class declaration.
/// The derived interface inherits all methods from its base interface. You cannot use more than
/// one direct base interface. Example:
/// @code
/// class DerivedSimpleInterface : private SimpleInterface
/// {
/// 	MAXON_INTERFACE_SIMPLE_VIRTUAL_DERIVED(DerivedSimpleInterface, MAXON_REFERENCE_NORMAL);
/// public:
/// 	MAXON_METHOD void DoSomethingElse();
/// };
/// @endcode
/// The implementation of a derived simple virtual interface is the same as for a
/// non-derived simple virtual interface.
///
/// @param[in] Name								Name of the interface (has to be the same as the surrounding class name).
/// @param[in] REFKIND						One of MAXON_REFERENCE_NONE, MAXON_REFERENCE_POINTER, MAXON_REFERENCE_CONST_POINTER, MAXON_REFERENCE_NORMAL, MAXON_REFERENCE_CONST, MAXON_REFERENCE_COPY_ON_WRITE, MAXON_REFERENCE_ALWAYS_COPY_ON_WRITE.
/// @see @ref svinterfaces
/// @see MAXON_INTERFACE_SIMPLE_VIRTUAL
//----------------------------------------------------------------------------------------
#define MAXON_INTERFACE_SIMPLE_VIRTUAL_DERIVED(Name, REFKIND) \
	public: \
		using Interface = Name; \
		struct MTable; \
		using HasBaseDetector = maxon::details::DefaultHasBase<Interface>; \
		struct Hxx1; \
		struct Hxx2; \
		template <typename ST> struct ReferenceFunctions : public maxon::SFINAEHelper<Hxx1, ST>::type::template ReferenceFunctionsHelper<ST> { }; \
		class Reference; \
		using Ptr = maxon::ReferenceBase<ReferenceFunctions<maxon::RefBaseFunctions<maxon::DirectRef<Interface, maxon::PointerHandler, void>>>>; \
		using ConstPtr = maxon::ReferenceBase<ReferenceFunctions<maxon::RefBaseFunctions<maxon::DirectRef<const Interface, maxon::PointerHandler, void>>>>; \
		template <typename DUMMY> static inline maxon::Int PrivateInstantiateNullValueHelper(); \
		static const maxon::EntityBase::FLAGS REFERENCE_KIND = PRIVATE_##REFKIND##_FLAGS; \
		static maxon::InterfaceReference* PrivateGetInterface() { return nullptr; } \
	protected: \
		inline Name(const MTable& vtable); \
		~Name() { MAXON_CHECK_CLASS(Name); } \
	private: \
		MAXON_DISALLOW_COPY_AND_ASSIGN(Name);

#ifdef CPP_853_HACK

	#define CPP_853_HACK_MAXON_INTERFACE_SIMPLE_VIRTUAL_DERIVED(Name, REFKIND) \
		public: \
			using Interface = Name; \
			struct MTable; \
			struct Hxx1; \
			struct Hxx2; \
			template <typename ST> struct ReferenceFunctions : public maxon::SFINAEHelper<Hxx1, ST>::type::template ReferenceFunctionsHelper<ST> { }; \
			class Reference; \
			using Ptr = maxon::ReferenceBase<ReferenceFunctions<maxon::RefBaseFunctions<maxon::DirectRef<Interface, maxon::PointerHandler, void>>>>; \
			using ConstPtr = maxon::ReferenceBase<ReferenceFunctions<maxon::RefBaseFunctions<maxon::DirectRef<const Interface, maxon::PointerHandler, void>>>>; \
			template <typename DUMMY> static inline maxon::Int PrivateInstantiateNullValueHelper(); \
			static const maxon::EntityBase::FLAGS REFERENCE_KIND = PRIVATE_##REFKIND##_FLAGS; \
		protected: \
			inline Name(const MTable& vtable); \
		private: \
			void operator =(const Name&);
#endif

//----------------------------------------------------------------------------------------
/// MAXON_IMPLEMENTATION_SIMPLE has to be used in the implementation of a simple
/// virtual interface. It defines the necessary members for such an implementation.
/// For an example, see MAXON_INTERFACE_SIMPLE_VIRTUAL.
///
/// Don't forget to add MAXON_IMPLEMENTATION_REGISTER_SIMPLE below the implementation class.
///
/// @param[in] C									Name of the implementation class (has to be the same as the surrounding class name).
/// @see @ref svinterfaces
/// @see MAXON_INTERFACE_SIMPLE_VIRTUAL
//----------------------------------------------------------------------------------------
#define MAXON_IMPLEMENTATION_SIMPLE(C, ...) \
	public: \
		using IsAllocType = std::false_type; \
		using MTable = std::false_type; /* for the IsInterfaceType detection */ \
		static void Free(const C* o) { DeleteObj(o); } \
		static const __VA_ARGS__ Interface::MTable _clsMTable; \
		Interface* ToInterface() { MAXON_CHECK_CLASS(C); return this; } \
		const Interface* ToInterface() const { return this; } \
		static C* Get(typename Interface::BaseInterface* object) { return (C*) object; } \
		static const C* Get(const typename Interface::BaseInterface* object) { return (const C*) object; }

// TODO: (Ole) remove __VA_ARGS__ hack when MSVC allows typename outside of templates

//----------------------------------------------------------------------------------------
/// MAXON_IMPLEMENTATION_REGISTER_SIMPLE completes the implementation of a simple virtual interface.
/// It has to be used below the declaration of the implementation class (see MAXON_INTERFACE_SIMPLE_VIRTUAL).
///
/// @param[in] C									Name of the implementation class.
/// @see @ref svinterfaces
//----------------------------------------------------------------------------------------
#define MAXON_IMPLEMENTATION_REGISTER_SIMPLE(C, ...) \
	const __VA_ARGS__ C::Interface::MTable C::_clsMTable = __VA_ARGS__ C::Interface::MTable((C*) nullptr);


#define MAXON_GENERIC(...) PRIVATE_MAXON_GENERIC_A(PRIVATE_MAXON_GENERIC_REMOVE_VARIANCE __VA_ARGS__)
#define MAXON_GENERIC_BASE(...)

#define PRIVATE_MAXON_GENERIC_REMOVE_VARIANCE(...) PRIVATE_MAXON_GENERIC_REMOVE_VARIANCE
#define PRIVATE_PRIVATE_MAXON_GENERIC_REMOVE_VARIANCE

#define PRIVATE_MAXON_GENERIC_A(...) PRIVATE_MAXON_GENERIC_B(__VA_ARGS__)

#ifdef MAXON_COMPILER_INTEL
	#define PRIVATE_MAXON_GENERIC_B(X) PRIVATE_MAXON_GENERIC_C(PRIVATE_##X)
#else
	#define PRIVATE_MAXON_GENERIC_B(...) PRIVATE_MAXON_GENERIC_C(PRIVATE_##__VA_ARGS__)
#endif

#define PRIVATE_MAXON_GENERIC_C(...) PRIVATE_MAXON_GENERIC_D(PRIVATE_MAXON_GENERIC_SWITCH_A(__VA_ARGS__), __VA_ARGS__)
#define PRIVATE_MAXON_GENERIC_D(SWITCH, ...) SWITCH(__VA_ARGS__)

#define PRIVATE_MAXON_GENERIC_SWITCH_A(...) PRIVATE_MAXON_GENERIC_SWITCH_B(PRIVATE_MAXON_GENERIC_TYPENAME_TEST_##__VA_ARGS__)
#define PRIVATE_MAXON_GENERIC_SWITCH_B(...) MAXON_EXPAND(PRIVATE_MAXON_GENERIC_SWITCH_C(__VA_ARGS__))
#define PRIVATE_MAXON_GENERIC_SWITCH_C(X, ...) PRIVATE_MAXON_GENERIC_SWITCH_D(MAXON_VA_NARGS(X))
#define PRIVATE_MAXON_GENERIC_SWITCH_D(N) PRIVATE_MAXON_GENERIC_SWITCH_E(N)
#define PRIVATE_MAXON_GENERIC_SWITCH_E(N) PRIVATE_MAXON_GENERIC_SWITCH_F(N)
#define PRIVATE_MAXON_GENERIC_SWITCH_F(N) PRIVATE_MAXON_GENERIC_SWITCH_##N

#define PRIVATE_MAXON_GENERIC_SWITCH_0(...) MAXON_EXPAND(PRIVATE_MAXON_GENERIC_SWITCH_TYPENAME(__VA_ARGS__))
#define PRIVATE_MAXON_GENERIC_SWITCH_1(...) static constexpr __VA_ARGS__

#define PRIVATE_MAXON_GENERIC_SWITCH_TYPENAME(...) PRIVATE_MAXON_GENERIC_USING_##__VA_ARGS__

#define PRIVATE_MAXON_GENERIC_TYPENAME_TEST_typename ,
#define PRIVATE_MAXON_GENERIC_USING_typename using

namespace details
{

struct DirectInstanceHandler
{
	static const VALUEKIND KIND = VALUEKIND::DEEP_CONSTNESS | VALUEKIND::NEVER_NULLPTR;
};

template <typename REFERENCED, typename ERASED> class DirectInstance : public ERASED
{
public:
	using PrivateReferencedType = REFERENCED;
	static std::false_type GenericVarianceCheck(const void*);
	using Handler = DirectInstanceHandler;

	static const Bool DIRECT_REF = false;
	static const Bool HAS_ERROR = false;
	using type = DirectInstance;

	REFERENCED* GetPointer()
	{
		return static_cast<REFERENCED*>(this);
	}

	const REFERENCED* GetPointer() const
	{
		return static_cast<const REFERENCED*>(this);
	}

	const ThreadReferencedError& GetErrorStorage() const
	{
		return *(const ThreadReferencedError*) this;
	}

	ResultRef<REFERENCED> MakeWritable(Bool resetOnError = true)
	{
		return *static_cast<REFERENCED*>(this);
	}
};

template <typename MTABLE, typename WRAPPER> inline void InitMTable(MTABLE* tbl)
{
	tbl->template Init<WRAPPER>();
}

template <typename T> using GetReferenceClass = typename T::ReferenceClass;
template <typename T> using GetPrivateReferencedType = typename T::PrivateReferencedType;

template <typename T1, typename T2, typename = void> struct HasCommonType
{
	static const Bool value = false;
};

template <typename T1, typename T2> struct HasCommonType<T1, T2, typename SFINAEHelper<void, typename std::common_type<T1, T2>::type>::type>
{
	static const Bool value = true;
};

}

template <typename TO, typename FROM, Bool SAFE> struct GenericCastMemberTrait<TO, FROM, SAFE, typename SFINAEHelper<void, typename TO::DirectlyReferencedType, typename FROM::DirectlyReferencedType>::type>
{
	static const Bool value = SAFE ? STD_IS_REPLACEMENT(constructible, TO, const FROM&)
		: ((STD_IS_REPLACEMENT(const, typename TO::DirectlyReferencedType) >= STD_IS_REPLACEMENT(const, typename FROM::DirectlyReferencedType))
			 && (maxon::details::HasCommonType<const typename TO::DirectlyReferencedType*, const typename FROM::DirectlyReferencedType*>::value
					 || (STD_IS_REPLACEMENT(base_of, ObjectInterface, typename TO::DirectlyReferencedType) && STD_IS_REPLACEMENT(base_of, ObjectInterface, typename FROM::DirectlyReferencedType))));
};

/// @cond INTERNAL

//----------------------------------------------------------------------------------------
// Default implementation of some basic interface methods.
//----------------------------------------------------------------------------------------
namespace defaultimplementation
{
inline Result<void> InitImplementation() { return OK; }

inline void FreeImplementation() { }
}

/// @endcond

/// @}

} // namespace maxon

#endif // INTERFACEBASE_H__
