//---------------------------------------------------------------------------
// Copyright 1997-2025 Joe Lowe
//
// Permission is granted to any person obtaining a copy of this Software,
// to deal in the Software without restriction, including the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and sell copies of
// the Software.
//
// The above copyright and permission notice must be left intact in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS WITHOUT WARRANTY.
//---------------------------------------------------------------------------
// filename:   ptpublic.h
// created:    2013.01.17
//
// Definitions for creating compiler, language (C/C++), and platform
// portable interfaces and definitions. Implementation code is not expected
// to use these definitions.
//---------------------------------------------------------------------------
#ifndef PTPUBLIC_H
#define PTPUBLIC_H

#ifndef PT_EXPAND
#define PT_EXPAND_(a) a
#define PT_EXPAND(a) PT_EXPAND_(a)
#endif
#ifndef PT_CAT
#define PT_CAT_(a,b) a##b
#define PT_CAT(a,b) PT_CAT_(a,b)
#endif
#ifndef PT_QUOTE
#define PT_QUOTE_(s) #s
#define PT_QUOTE(s) PT_QUOTE_(s)
#endif
#ifndef PT_LQUOTE
#define PT_LQUOTE(s) PT_CAT(L,PT_QUOTE_(s))
#endif

#if !defined(RC_INVOKED) && !defined(RC_PLIST)

#if (defined(INT_MAX) && LONG_MAX > INT_MAX) || defined(_WIN64) || defined(__x86_64__) || defined(__powerpc64__) || defined(__ppc64__) || defined(__mips64__) || defined(__arm64__) || defined(__aarch64__) || defined(__riscv64__)
 #define PT_SIZEOF_PTR 8
#else
 #define PT_SIZEOF_PTR 4
#endif
#if defined(LITTLEENDIAN) || defined(__LITTLE_ENDIAN__) || defined(WORDS_LITTLEENDIAN) || defined(_WIN32)
 #define PT_LITTLEENDIAN
#elif defined(BIGENDIAN) || defined(__BIG_ENDIAN__) || defined(WORDS_BIGENDIAN)
 #define PT_BIGENDIAN
#elif defined(__powerpc__) || defined(__ppc__) || defined(__powerpc64__) || defined(__ppc64__)
 #define PT_BIGENDIAN
#else
 #define PT_LITTLEENDIAN
#endif
#if PT_SIZEOF_PTR == 8 && !defined(_WIN32)
 #define PT_SIZEOF_LONG 8
#else
 #define PT_SIZEOF_LONG 4
#endif
#ifdef __arm64e__
 #define PT_PTRAUTH
#endif

#define PT_CHAR8 char
#define PT_INT32 int
#define PT_UINT32 unsigned
#define PT_BOOLW int
#ifdef INT64_C
 #define PT_BOOL8 uint8_t
 #define PT_INT8 int8_t
 #define PT_UINT8 uint8_t
 #define PT_INT16 int16_t
 #define PT_UINT16 uint16_t
 #define PT_INT64 int64_t
 #define PT_UINT64 uint64_t
#else
 #define PT_BOOL8 unsigned char
 #define PT_INT8 signed char
 #define PT_UINT8 unsigned char
 #define PT_INT16 short
 #define PT_UINT16 unsigned short
 #ifdef _MSC_VER
  #define PT_INT64 __int64
  #define PT_UINT64 unsigned __int64
  #define PT_INT64_MIN  (-9223372036854775807i64 - 1)
  #define PT_INT64_MAX  9223372036854775807i64
  #define PT_UINT64_MAX 0xffffffffffffffffui64
 #elif PT_SIZEOF_LONG == 8
  #define PT_INT64 long
  #define PT_UINT64 unsigned long
  #define PT_INT64_MIN  (-9223372036854775807L - 1)
  #define PT_INT64_MAX  9223372036854775807L
  #define PT_UINT64_MAX 0xffffffffffffffffL
 #else
  #define PT_INT64 long long
  #define PT_UINT64 unsigned long long
  #define PT_INT64_MIN  (-9223372036854775807LL - 1)
  #define PT_INT64_MAX  9223372036854775807LL
  #define PT_UINT64_MAX 0xffffffffffffffffLL
 #endif
#endif
#ifdef NULL
 #define PT_SIZE_T size_t
#elif PT_SIZEOF_PTR == 4
 #define PT_SIZE_T unsigned
#else
 #define PT_SIZE_T PT_UINT64
#endif
#ifdef SIZE_MAX
 #define PT_SIZE_MAX SIZE_MAX
#elif PT_SIZEOF_PTR == 4
 #define PT_SIZE_MAX 0xffffffffu
#else
 #define PT_SIZE_MAX PT_UINT64_MAX
#endif
#ifdef __cplusplus
 #define PT_BOOL bool
 #define PT_SIZEOF_BOOL 1
#elif defined _MSC_VER && _MSC_VER < 1800
 #define PT_BOOL int
 #define PT_SIZEOF_BOOL 4
#else
 #define PT_BOOL _Bool
 #define PT_SIZEOF_BOOL 1
#endif
#if PT_SIZEOF_BOOL == 1
 #undef PT_BOOL8
 #define PT_BOOL8 PT_BOOL
#else
 #undef PT_BOOLW
 #define PT_BOOLW PT_BOOL
#endif

#ifdef __cplusplus
 #define PT_INLINE2 inline
 #ifdef _MSC_VER
  #define PT_FORCEINLINE __forceinline
 #else
  #define PT_FORCEINLINE inline __attribute__((__always_inline__))
 #endif
#else
 #if defined LINUX_VER
  #define PT_INLINE2 static
 #else
  #define PT_INLINE2 static __inline
 #endif
 #ifdef _MSC_VER
  #define PT_FORCEINLINE static __forceinline
 #else
  #define PT_FORCEINLINE static __inline __attribute__((__always_inline__))
 #endif
#endif
#define PT_INLINE PT_FORCEINLINE
#ifdef _MSC_VER
 #define PT_NOINLINE __declspec(noinline)
#else
 #define PT_NOINLINE __attribute__((__noinline__))
#endif
#define PT_INLINE_BOOL PT_INLINE PT_BOOL

#ifdef _WIN32
 #define PT_CCALL __cdecl
 #define PT_STDCALL __stdcall
 #define PT_PUBLIC
 #define PT_PRIVATE
 #define PT_IMPORT __declspec(dllimport)
 #define PT_EXPORT __declspec(dllexport)
 #define PT_RESTRICT __restrict
 #ifdef _INC_WINDOWS
  #define PT_FD_T HANDLE
  #define PT_FD_INVALID INVALID_HANDLE_VALUE
 #else
  typedef void* pt_fd_t;
  #define PT_FD_T pt_fd_t
  #define PT_FD_INVALID ((void*)(ptrdiff_t)(-1))
 #endif
#else
 #define PT_CCALL
 #define PT_STDCALL
 #define PT_PUBLIC __attribute__((__visibility__("default")))
 #define PT_PRIVATE __attribute__((__visibility__("hidden")))
 #define PT_IMPORT
 #define PT_EXPORT __attribute__((__visibility__("default")))
 #define PT_RESTRICT __restrict__
 #define PT_FD_T int
 #define PT_FD_INVALID -1
#endif

#define PT_CAST(t,e) ((t)(e))
#define PT_TYPE_DECLARE(t) typedef struct t t
#define PT_TYPE_DEFINE2(t) struct t
#define PT_TYPE_DEFINE(t) typedef struct t t; struct t
#define PT_TYPEUNION_DECLARE(t) typedef union t t
#define PT_TYPEUNION_DEFINE2(t) union t
#define PT_TYPEUNION_DEFINE(t) typedef union t t; union t
#ifdef __cplusplus
 #define PT_SCAST(t,e) static_cast<t>(e)
 #define PT_SCASTP(t,e) static_cast<t>(e)
 #define PT_CCAST(t,e) const_cast<t>(e)
 #define PT_CCAST2(t,e) const_cast<t>(e)
 #define PT_CCAST3(t,e) const_cast<t>(e)
 #define PT_CCASTV(t,e) const_cast<t>(e)
 #define PT_CCASTV2(t,e) const_cast<t>(e)
 #define PT_CCASTV3(t,e) const_cast<t>(e)
 #define PT_RCAST(t,e) reinterpret_cast<t>(e)
 #define PT_EXTERN extern "C"
 #define PT_EXTERNC extern "C"
 #define PT_EXTERNC_START extern "C" {
 #define PT_EXTERNC_END }
 #define PT_STATIC_CONST(t,n,v) static const t n = v
#else
 #define PT_SCAST(t,e) ((t)(e))
 #define PT_SCASTP(t,e) ((t)(e))
 #define PT_CCAST(t,e) ((t)(e))
 #define PT_CCAST2(t,e) ((t)(e))
 #define PT_CCAST3(t,e) ((t)(e))
 #define PT_CCASTV(t,e) ((t)(e))
 #define PT_CCASTV2(t,e) ((t)(e))
 #define PT_CCASTV3(t,e) ((t)(e))
 #define PT_RCAST(t,e) ((t)(e))
 #define PT_EXTERN extern
 #define PT_EXTERNC
 #define PT_EXTERNC_START
 #define PT_EXTERNC_END
 #define PT_STATIC_CONST(t,n,v) enum { n = v }
#endif

#define _PT_C_ASSERT_2(l) compile_time_assert_##l
#define _PT_C_ASSERT_1(e,l) typedef int _PT_C_ASSERT_2(l)[(e)?1:-1]
#define PT_C_ASSERT(e) _PT_C_ASSERT_1(e,__LINE__)
#define PT_C_ASSERT1(e) PT_EXTERN int compile_time_assert[(e)?1:-1]
#define PT_C_ASSERT2(e) do { PT_C_ASSERT(e); } while(0)
#ifndef PT_ASSERT
 #ifdef ASSERT
  #define PT_ASSERT(e) ASSERT(e)
 #else
  #define PT_ASSERT(e)
 #endif
#endif
#define PT_C_ASSERT_STRUCT_PACKING(tag) struct pt_struct_packing_check_##tag##_struct_t { PT_UINT8 a; PT_UINT64 b; }; typedef int pt_struct_packing_check_##tag##_t[sizeof(struct pt_struct_packing_check_##tag##_struct_t) == 16 ? 1 : -1]

#if !defined PT_C_INTERFACES && (defined PT_PTRAUTH || !defined __cplusplus)
 #define PT_C_INTERFACES
#endif
#undef PT_CXX_INTERFACES
#ifndef PT_C_INTERFACES
 #define  PT_CXX_INTERFACES
#endif
#ifdef PT_CXX_INTERFACES
 #define PT_INTERFACE_DECLARE(t) struct PT_CAT(t,_vtbl_t); struct t
 #define PT_INTERFACE_DEFINE2 struct INTERFACE_NAME
 #define PT_INTERFACE_DEFINE struct PT_CAT(INTERFACE_NAME,_vtbl_t); struct INTERFACE_NAME
 #define PT_INTERFACE_FUN0(r,m) virtual r PT_CCALL m() = 0
 #define PT_INTERFACE_FUNC(r,m,...) virtual r PT_CCALL m(__VA_ARGS__) = 0
 #define PT_VCAL0(o,m) ((o)->m())
 #define PT_VCALL(o,m,...) ((o)->m(__VA_ARGS__))
 #define PT_VCALLBASE(o,b,m,...) (PT_SCAST(b*,o)->m(__VA_ARGS__))
#endif
#ifdef PT_C_INTERFACES
 #define PT_INTERFACE_DECLARE(t) typedef struct PT_CAT(t,_vtbl_t) PT_CAT(t,_vtbl_t); typedef PT_CAT(t,_vtbl_t)* t
 #define PT_INTERFACE_DEFINE2 struct PT_CAT(INTERFACE_NAME,_vtbl_t)
 #define PT_INTERFACE_DEFINE typedef struct PT_CAT(INTERFACE_NAME,_vtbl_t) PT_CAT(INTERFACE_NAME,_vtbl_t); typedef PT_CAT(INTERFACE_NAME,_vtbl_t)* INTERFACE_NAME; struct PT_CAT(INTERFACE_NAME,_vtbl_t)
 #define PT_INTERFACE_FUN0(r,m) r (PT_CCALL*m)(INTERFACE_NAME*)
 #define PT_INTERFACE_FUNC(r,m,...) r (PT_CCALL*m)(PT_EXPAND(INTERFACE_NAME)*,__VA_ARGS__)
 #define PT_VCAL0(o,m) ((*(o))->m(o))
 #define PT_VCALL(o,m,...) ((*(o))->m(o,__VA_ARGS__))
 #define PT_VCALLBASE(o,b,m,...) ((*(o))->m(o,__VA_ARGS__))
#endif

PT_TYPE_DEFINE(pt_uuid_t) { PT_UINT32 Part1; PT_UINT16 Part2; PT_UINT16 Part3; PT_UINT8 Part4[8]; };
#define PT_UUID pt_uuid_t
PT_TYPE_DEFINE( pt_int16u_t) { PT_UINT8 d[2]; };
PT_TYPE_DEFINE( pt_int32u_t) { PT_UINT8 d[4]; };
PT_TYPE_DEFINE( pt_int64u_t) { PT_UINT8 d[8]; };
PT_TYPE_DEFINE(pt_uint16u_t) { PT_UINT8 d[2]; };
PT_TYPE_DEFINE(pt_uint32u_t) { PT_UINT8 d[4]; };
PT_TYPE_DEFINE(pt_uint64u_t) { PT_UINT8 d[8]; };
PT_TYPEUNION_DEFINE( pt_int16oe_t) {  PT_INT16 oe;  pt_int16u_t u; };
PT_TYPEUNION_DEFINE( pt_int32oe_t) {  PT_INT32 oe;  pt_int32u_t u; };
PT_TYPEUNION_DEFINE( pt_int64oe_t) {  PT_INT64 oe;  pt_int64u_t u; };
PT_TYPEUNION_DEFINE(pt_uint16oe_t) { PT_UINT16 oe; pt_uint16u_t u; };
PT_TYPEUNION_DEFINE(pt_uint32oe_t) { PT_UINT32 oe; pt_uint32u_t u; };
PT_TYPEUNION_DEFINE(pt_uint64oe_t) { PT_UINT64 oe; pt_uint64u_t u; };
PT_TYPE_DEFINE( pt_int16oeu_t) {  pt_int16u_t u; };
PT_TYPE_DEFINE( pt_int32oeu_t) {  pt_int32u_t u; };
PT_TYPE_DEFINE( pt_int64oeu_t) {  pt_int64u_t u; };
PT_TYPE_DEFINE(pt_uint16oeu_t) { pt_uint16u_t u; };
PT_TYPE_DEFINE(pt_uint32oeu_t) { pt_uint32u_t u; };
PT_TYPE_DEFINE(pt_uint64oeu_t) { pt_uint64u_t u; };
PT_TYPE_DEFINE(pt_uuidu_t  ) { pt_uint32u_t   data1; pt_uint16u_t   data2;   pt_uint16u_t data3; PT_UINT8 data4[8]; };
PT_TYPE_DEFINE(pt_uuidoe_t ) { pt_uint32oe_t  data1; pt_uint16oe_t  data2;  pt_uint16oe_t data3; PT_UINT8 data4[8]; };
PT_TYPE_DEFINE(pt_uuidoeu_t) { pt_uint32oeu_t data1; pt_uint16oeu_t data2; pt_uint16oeu_t data3; PT_UINT8 data4[8]; };
#ifdef PT_LITTLEENDIAN
 #define PT_INT16LE   PT_INT16
 #define PT_UINT16LE  PT_UINT16
 #define PT_INT32LE   PT_INT32
 #define PT_UINT32LE  PT_UINT32
 #define PT_INT64LE   PT_INT64
 #define PT_UINT64LE  PT_UINT64
 #define PT_INT16LEU  pt_int16u_t
 #define PT_UINT16LEU pt_uint16u_t
 #define PT_INT32LEU  pt_int32u_t
 #define PT_UINT32LEU pt_uint32u_t
 #define PT_INT64LEU  pt_int64u_t
 #define PT_UINT64LEU pt_uint64u_t
 #define PT_UUIDLE    pt_uuid_t
 #define PT_UUIDLEU   pt_uuidu_t
 #define PT_INT16BE   pt_int16oe_t
 #define PT_UINT16BE  pt_uint16oe_t
 #define PT_INT32BE   pt_int32oe_t
 #define PT_UINT32BE  pt_uint32oe_t
 #define PT_INT64BE   pt_int64oe_t
 #define PT_UINT64BE  pt_uint64oe_t
 #define PT_INT16BEU  pt_int16oeu_t
 #define PT_UINT16BEU pt_uint16oeu_t
 #define PT_INT32BEU  pt_int32oeu_t
 #define PT_UINT32BEU pt_uint32oeu_t
 #define PT_INT64BEU  pt_int64oeu_t
 #define PT_UINT64BEU pt_uint64oeu_t
 #define PT_UUIDBE    pt_uuidoe_t
 #define PT_UUIDBEU   pt_uuidoeu_t
#else
 #define PT_INT16BE   PT_INT16
 #define PT_UINT16BE  PT_UINT16
 #define PT_INT32BE   PT_INT32
 #define PT_UINT32BE  PT_UINT32
 #define PT_INT64BE   PT_INT64
 #define PT_UINT64BE  PT_UINT64
 #define PT_INT16BEU  pt_int16u_t
 #define PT_UINT16BEU pt_uint16u_t
 #define PT_INT32BEU  pt_int32u_t
 #define PT_UINT32BEU pt_uint32u_t
 #define PT_INT64BEU  pt_int64u_t
 #define PT_UINT64BEU pt_uint64u_t
 #define PT_UUIDBE    pt_uuid_t
 #define PT_UUIDBEU   pt_uuidu_t
 #define PT_INT16LE   pt_int16oe_t
 #define PT_UINT16LE  pt_uint16oe_t
 #define PT_INT32LE   pt_int32oe_t
 #define PT_UINT32LE  pt_uint32oe_t
 #define PT_INT64LE   pt_int64oe_t
 #define PT_UINT64LE  pt_uint64oe_t
 #define PT_INT16LEU  pt_int16oeu_t
 #define PT_UINT16LEU pt_uint16oeu_t
 #define PT_INT32LEU  pt_int32oeu_t
 #define PT_UINT32LEU pt_uint32oeu_t
 #define PT_INT64LEU  pt_int64oeu_t
 #define PT_UINT64LEU pt_uint64oeu_t
 #define PT_UUIDLE    pt_uuidoe_t
 #define PT_UUIDLEU   pt_uuidoeu_t
#endif
PT_TYPE_DEFINE( pt_uint24leu_t) { PT_UINT16LEU low;      PT_UINT8  hi; };
PT_TYPE_DEFINE( pt_uint24beu_t) { PT_UINT8      hi; PT_UINT16BEU  low; };
#define PT_UINT24LEU pt_uint24leu_t
#define PT_UINT24BEU pt_uint24beu_t
#ifdef PT_LITTLEENDIAN
 #define PT_UINT24U pt_uint24leu_t
#else
 #define PT_UINT24U pt_uint24beu_t
#endif

#ifdef _WIN32
 #define PT_PATHSEPA      "\\"
 #define PT_LISTSEPA      ";"
 #define PT_EXESUFFIXA    ".exe"
 #define PT_SHAREDPREFIXA ""
 #define PT_SHAREDEXTA    "dll"
 #define PT_PLUGINEXTA    "dll"
#else
 #define PT_PATHSEPA      "/"
 #define PT_LISTSEPA      ":"
 #define PT_EXESUFFIXA    ""
 #ifdef __APPLE__
  #define PT_SHAREDPREFIXA "lib"
  #define PT_SHAREDEXTA    "dylib"
  #define PT_PLUGINEXTA    "bundle"
 #else
  #define PT_SHAREDPREFIXA "lib"
  #define PT_SHAREDEXTA    "so"
  #define PT_PLUGINEXTA    "so"
 #endif
#endif
#define PT_PATHSEPW      PT_CAT(L,PT_PATHSEPA)
#define PT_LISTSEPW      PT_CAT(L,PT_LISTSEPA)
#define PT_EXESUFFIXW    PT_CAT(L,PT_EXESUFFIXA)
#define PT_SHAREDPREFIXW PT_CAT(L,PT_SHAREDPREFIXA)
#define PT_SHAREDEXTW    PT_CAT(L,PT_SHAREDEXTA)
#define PT_PLUGINEXTW    PT_CAT(L,PT_PLUGINEXTA)

#define PT_SZ_T char*
#define PT_SZC_T const char*
#define PT_WSZ_T wchar_t*
#define PT_WSZC_T const wchar_t*
#define PT_SZ_RET_T char*
#define PT_SZC_RET_T const char*
#define PT_WSZ_RET_T wchar_t*
#define PT_WSZC_RET_T const wchar_t*

PT_C_ASSERT1( sizeof(char) == 1);
PT_C_ASSERT1( sizeof(short) == 2);
PT_C_ASSERT1( sizeof(int) == 4);
PT_C_ASSERT1( sizeof(long) == PT_SIZEOF_LONG);
PT_C_ASSERT1( sizeof(void*) == PT_SIZEOF_PTR);
PT_C_ASSERT1( sizeof(PT_BOOL) == PT_SIZEOF_BOOL);
PT_C_ASSERT1( sizeof(PT_BOOLW) == 4);

#endif

#endif
