#ifdef __cplusplus
	#include <cstddef>
	#include <cstdint>
	#include <climits>
#else
	#include <stddef.h>
	#include <stdint.h>
	#include <limits.h>
#endif

#ifdef _SQ64
	typedef int64_t SQInteger;
	typedef uint64_t SQUnsignedInteger;
	typedef size_t SQHash; /*should be the same size of a pointer*/

	typedef int32_t SQInt32;
	typedef uint32_t SQUnsignedInteger32;
#else
	typedef int32_t SQInteger;
	typedef uint32_t SQUnsignedInteger;
	typedef size_t SQHash; /*should be the same size of a pointer*/

	typedef int32_t SQInt32; /*must be 32 bits(also on 64bits processors)*/
	typedef uint32_t SQUnsignedInteger32; /*must be 32 bits(also on 64bits processors)*/
#endif


#ifdef SQUSEDOUBLE
	typedef double SQFloat;
#else
	typedef float SQFloat;
#endif

#if defined(SQUSEDOUBLE) && !defined(_SQ64) || !defined(SQUSEDOUBLE) && defined(_SQ64)
	typedef int64_t SQRawObjectVal; //must be 64bits
	#define SQ_OBJECT_RAWINIT() { _unVal.raw = 0; }
#else
	typedef SQUnsignedInteger SQRawObjectVal; //is 32 bits on 32 bits builds and 64 bits otherwise
	#define SQ_OBJECT_RAWINIT()
#endif

#ifndef SQ_ALIGNMENT // SQ_ALIGNMENT shall be less than or equal to SQ_MALLOC alignments, and its value shall be power of 2.
	#if defined(SQUSEDOUBLE) || defined(_SQ64)
		#define SQ_ALIGNMENT 8
	#else
		#define SQ_ALIGNMENT 4
	#endif
#endif

typedef void* SQUserPointer;
typedef SQUnsignedInteger SQBool;
typedef SQInteger SQRESULT;

#ifdef SQUNICODE
	#ifdef __cplusplus
		#include <cwchar>
		#include <cwctype>
	#else
		#include <wchar.h>
		#include <wctype.h>
	#endif

	typedef wchar_t SQChar;

	#define scstrcmp    wcscmp

	#ifdef _WIN32
		#define scsprintf   _snwprintf
	#else
		#define scsprintf   swprintf
	#endif

	#define scstrlen    wcslen
	#define scstrtod    wcstod

	#ifdef _SQ64
		#define scstrtol    wcstoll
	#else
		#define scstrtol    wcstol
	#endif

	#define scstrtoul   wcstoul
	#define scvsprintf  vswprintf
	#define scstrstr    wcsstr
	#define scprintf    wprintf

	#ifdef _WIN32
		#define WCHAR_SIZE 2
		#define WCHAR_SHIFT_MUL 1
		#define MAX_CHAR 0xFFFF
	#else
		#define WCHAR_SIZE 4
		#define WCHAR_SHIFT_MUL 2
		#define MAX_CHAR 0xFFFFFFFF
	#endif

	#define _SC(a) L##a

	#define scisspace   iswspace
	#define scisdigit   iswdigit
	#define scisprint   iswprint
	#define scisxdigit  iswxdigit
	#define scisalpha   iswalpha
	#define sciscntrl   iswcntrl
	#define scisalnum   iswalnum

	#define sq_rsl(l) ((l)<<WCHAR_SHIFT_MUL)

#else
	typedef char SQChar;
	#define _SC(a) a
	#define scstrcmp    strcmp

	#ifdef _MSC_VER
		#define scsprintf   _snprintf
	#else
		#define scsprintf   snprintf
	#endif

	#define scstrlen    strlen
	#define scstrtod    strtod

	#ifdef _SQ64
		#ifdef _MSC_VER
			#define scstrtol    _strtoi64
		#else
			#define scstrtol    strtoll
		#endif
	#else
		#define scstrtol    strtol
	#endif

	#define scstrtoul   strtoul
	#define scvsprintf  vsnprintf
	#define scstrstr    strstr
	#define scisspace   isspace
	#define scisdigit   isdigit
	#define scisprint   isprint
	#define scisxdigit  isxdigit
	#define sciscntrl   iscntrl
	#define scisalpha   isalpha
	#define scisalnum   isalnum
	#define scprintf    printf
	#define MAX_CHAR 0xFF

	#define sq_rsl(l) (l)

#endif

#ifdef _SQ64
	#if (defined(linux) || defined(__linux) || defined(__linux__)) && (LONG_MAX == LLONG_MAX)
		#define _PRINT_INT_PREC _SC("l")
		#define _PRINT_INT_FMT _SC("%ld")
	#else
		#define _PRINT_INT_PREC _SC("ll")
		#define _PRINT_INT_FMT _SC("%lld")
	#endif
#else
	#define _PRINT_INT_FMT _SC("%d")
#endif