/****************************************************************************************************

		MCCompiler.h
		Copyright: (c) 2001 Eovia Corp. All rights reserved.

		Author:	Arnaud
		Date:	3/17/2005

****************************************************************************************************/

#ifndef __MCCompiler__
#define __MCCompiler__

#if CP_PRAGMA_ONCE
#pragma once
#endif


#include "MCOSConfig.h"


#if defined(qLeanMCCore) && !defined(qUseDefaultAllocator)
	#define qUseDefaultAllocator
#endif


// Compiler ONLY

#ifdef _MSC_VER
	#define			Debug_		(_DEBUG)

	// This pragma disables a constructor passing a this pointer to other constructors error
	#pragma warning(disable : 4355)
	
	// This pragma disables an overflow warning
	#pragma warning(disable : 4244)
	
	// This pragma disables DLLExport warnings
	#pragma warning(disable : 4273)
	
	// This pragma disables warnings when an exported classes is derived from a non-exported classes
	#pragma warning(disable : 4275)
	
	// This pragma disables warnings when non-exported objects are embedded in exported objects
	#pragma warning(disable : 4251)
	
	// This pragma disables the "unreferenced inline function has been removed" warning
	#pragma warning(disable : 4514)

	// This pragma disable the "nonstandard extension used : nameless struct/union" warning
	#pragma warning(disable : 4201)

	// This pragma disable the "assignment operator could not be generated" warning
	#pragma warning(disable : 4512)

	// This pragma generates an error for a deletion of pointer to incomplete type, no destructor called
	#pragma warning(error : 4150)

	// This pragma disables the "identifier was truncated to '255' characters in the browser information" warning
	#pragma warning( disable : 4786 )

	// This pragma disables the "template-class specialization '###' is already instantiated" warning
	#pragma warning( disable : 4660 )

	// puts no limit on the number of inlines for optimizer
	#pragma inline_depth(255)

#endif 



#if (__GNUC__ > 3)
	#define MCDLLEXPORT __attribute__ ((visibility("default")))
#else
	#define MCDLLEXPORT
#endif

#if MAC
#include <stddef.h> //Required to allow size_t on mac
#endif

//new and delete operator overload
typedef size_t					MCSize;


/// This is one of the base classes for all the objects that need to be allocated by the application's overriden memory allocator.
/// When allocating objects in an extension that uses the default allocator, 
/// only objects derived from TMCObject(N) can be passed between the application and the extension.
class TMCObject
{
public:
#ifndef qUseDefaultAllocator
	void*			operator new			(MCSize byteCount) throw();
	void			operator delete			(void* block);
	void*			operator new[]			(MCSize byteCount) throw();
	void			operator delete[]		(void* block);
	inline void*	operator new			(MCSize , void *__Pointer)		{ return (__Pointer); }
	inline void		operator delete			(void *, void *)			{ return; }
#endif
	
	//Arnaud: with visual6, the default operator is buggy (eg copies 1 byte into a counted ptr field)
	inline TMCObject& operator=(const TMCObject&)	{ return *this; }

//	Defining the constructors slows down the rendering by up to 16% (visual C++ 6)
//	And since they're not needed anyways lets comment them out (Arnaud 03-29-05)
//	inline TMCObject(const TMCObject& other)		{}
//	inline TMCObject()								{}
};


//Arnaud:
/// gcc has troubles with empty classes for example when the first member and the class both derive from TMCObject 
/// it makes the class bigger (see TTransform3D). 
/// This creates issues in parameter maps => simple types like TVector3 must derive from TMCObject0
/// Complex types might need to derive from TMCObject2 at some point...
/// If the class has other simple members (like int), putting one first will also avoid the size issue).
class TMCObject0
{
public:
#ifndef qUseDefaultAllocator
	void*			operator new			(MCSize byteCount) throw();
	void			operator delete			(void* block);
	void*			operator new[]			(MCSize byteCount) throw();
	void			operator delete[]		(void* block);
	inline void*	operator new			(MCSize , void *__Pointer)		{ return (__Pointer); }
	inline void		operator delete			(void *, void *)			{ return; }
#endif
	
	inline TMCObject0& 	operator=(const TMCObject0&)	{ return *this; }
};

/// base class for objects that contain fields derived from TMCObject0
class TMCObject1
{
public:
#ifndef qUseDefaultAllocator
	void*			operator new			(MCSize byteCount) throw();
	void			operator delete			(void* block);
	void*			operator new[]			(MCSize byteCount) throw();
	void			operator delete[]		(void* block);
	inline void*	operator new			(MCSize , void *__Pointer)		{ return (__Pointer); }
	inline void		operator delete			(void *, void *)			{ return; }
#endif
	
	inline TMCObject1& 	operator=(const TMCObject0&)	{ return *this; }
};


#ifdef __GNUC__
	#include <new.h>
#else
	//define qNoAllocators if your extension/application doesn't want to override the allocators 
	#if !defined(qUseDefaultAllocator) && !defined(qNoAllocators)
		void*  operator new					(MCSize byteCount);
		void*  operator new[]				(MCSize byteCount);
		void   operator delete				(void* block) throw();
		void   operator delete[]			(void* block) throw();
	#endif
#endif


//define UNICODE so that the Windows version will use Unicode function calls
#ifdef WIN
#define UNICODE
#define _UNICODE
#endif

#define CAN_HAVE_MMX	0

#ifdef WIN
#ifdef ARCH_X86
#undef CAN_HAVE_MMX
#define CAN_HAVE_MMX	1
#endif
#endif

#endif
