forked from livecode/livecode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfoundation.h
More file actions
executable file
·3770 lines (2967 loc) · 151 KB
/
foundation.h
File metadata and controls
executable file
·3770 lines (2967 loc) · 151 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* Copyright (C) 2003-2015 LiveCode Ltd.
This file is part of LiveCode.
LiveCode is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License v3 as published by the Free
Software Foundation.
LiveCode is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
#ifndef __MC_FOUNDATION__
#define __MC_FOUNDATION__
////////////////////////////////////////////////////////////////////////////////
#ifdef __ANDROID__
#define __PLATFORM_IS_ANDROID__
#endif
#ifdef __APPLE__
#include "TargetConditionals.h"
#endif
////////////////////////////////////////////////////////////////////////////////
//
// MACRO UNDEFINITIONS
//
// __VISUALC__ will be defined if the compiler being used is MS Visual C.
#undef __VISUALC__
// __GCC__ will be defined if the compiler being used is GCC
#undef __GCC__
// __WINDOWS__ will be defined if the Windows platform is the target.
#undef __WINDOWS__
// __MAC__ will be defined if the Mac platform is the target.
#undef __MAC__
// __LINUX__ will be defined if the Linux platform is the target.
#undef __LINUX__
// __SOLARIS__ will be defined if the Solaris platform is the target.
#undef __SOLARIS__
// __IOS__ will be defined if the iOS platform is the target.
#undef __IOS__
// __ANDROID__ will be defined if the Android platform is the target.
#undef __ANDROID__
// __WINDOWS_MOBILE__ will be defined if the WindowsCE platform is the target.
#undef __WINDOWS_MOBILE__
// __LINUX_MOBILE__ will be defined if the Linux mobile platform is the target.
#undef __LINUX_MOBILE__
// __EMSCRIPTEN__ will be defined if Emscripten JavaScript is the target
//#undef __EMSCRIPTEN__ // It will be defined by the compiler
// __32_BIT__ will be defined if the target processor is 32-bit.
#undef __32_BIT__
// __64_BIT__ will be defined if the target processor is 64-bit.
#undef __64_BIT__
// __LITTLE_ENDIAN__ will be defined if the target processor uses LE byte-order.
#undef __LITTLE_ENDIAN__
// __LITTLE_ENDIAN__ will be defined if the target processor uses BE byte-order.
#undef __BIG_ENDIAN__
// __i386__ will be defined if the target processor is i386.
#undef __i386__
// __X86_64__ will be defined if the target processor is x86-64.
#undef __X86_64__
// __PPC__ will be defined if the target processor is PowerPC.
#undef __PPC__
// __PPC_64__ will be defined if the target processor is PowerPC-64.
#undef __PPC_64__
// __SPARC__ will be defined if the target processor is Sparc.
#undef __SPARC__
// __SPARC_64__ will be defined if the target processor is Sparc-64.
#undef __SPARC_64__
// __ARM__ will be defined if the target processor is 32-bit ARM.
#undef __ARM__
// __ARM64__ will be defined if the target processor is 64-bit ARM.
#undef __ARM64__
// __SMALL__ will be defined if pointers are 32-bit and indicies are 32-bit.
#undef __SMALL__
// __MEDIUM__ will be defined if pointers are 64-bit and indicies are 32-bit.
#undef __MEDIUM__
// __LARGE__ will be defined if pointers are 64-bit and indicies are 64-bit.
#undef __LARGE__
// __WINDOWS_1252__ will be defined if it is the native charset of the platform.
#undef __WINDOWS_1252__
// __MACROMAN__ will be defined if it is the native charset of the platform.
#undef __MACROMAN__
// __ISO_8859_1__ will be defined if it is the native charset of the platform.
#undef __ISO_8859_1__
// __CRLF__ will be defined if the native line ending is CR LF.
#undef __CRLF__
// __CR__ will be defined if the native line ending is CR.
#undef __CR__
// __LF__ will be defined if the native line ending is LF.
#undef __LF__
// __LP64__ will be defined if longs and pointers are 64 bits.
#undef __LP64__
// __HAS_CORE_FOUNDATION__ will be defined if the platform has the CF libraries.
#undef __HAS_CORE_FOUNDATION__
// __HAS_MULTIPLE_ABIS__ will be defined if the platform has more than one
// function ABI
#undef __HAS_MULTIPLE_ABIS__
////////////////////////////////////////////////////////////////////////////////
//
// CONFIGURE DEFINITIONS FOR WINDOWS
//
#if defined(_MSC_VER) && !defined(WINCE)
// Compiler
#define __VISUALC__ 1
// Platform
#define __WINDOWS__ 1
// Architecture
#if defined(_M_IX86)
#define __32_BIT__ 1
#define __LITTLE_ENDIAN__ 1
#define __i386__ 1
#define __LP32__ 1
#define __SMALL__ 1
#define __HAS_MULTIPLE_ABIS__ 1
#elif defined(_M_X64)
#define __64_BIT__ 1
#define __LITTLE_ENDIAN__ 1
#define __X86_64__ 1
#define __LLP64__ 1
#define __MEDIUM__ 1
#else
#error Unknown target architecture
#endif
// Native char set
#define __WINDOWS_1252__ 1
// Native line endings
#define __CRLF__ 1
#endif
////////////////////////////////////////////////////////////////////////////////
//
// CONFIGURE DEFINITIONS FOR MAC
//
#if defined(__GNUC__) && defined(__APPLE__) && !TARGET_OS_IPHONE
// Compiler
#define __GCC__ 1
// Platform
#define __MAC__ 1
// Architecture
#if defined(__i386)
#define __32_BIT__ 1
#define __LITTLE_ENDIAN__ 1
#define __i386__ 1
#define __LP32__ 1
#define __SMALL__ 1
#elif defined(__ppc__)
#define __32_BIT__ 1
#define __BIG_ENDIAN__ 1
#define __PPC__ 1
#define __LP32__ 1
#define __SMALL__ 1
#elif defined(__x86_64__)
#define __64_BIT__ 1
#define __LITTLE_ENDIAN__ 1
#define __X86_64__ 1
#define __LP64__ 1
#define __MEDIUM__ 1
#endif
// Native char set
#define __MACROMAN__ 1
// Native line endings
#define __CR__ 1
// Presence of CoreFoundation
#define __HAS_CORE_FOUNDATION__ (1)
#endif
////////////////////////////////////////////////////////////////////////////////
//
// CONFIGURE DEFINITIONS FOR LINUX
//
#if defined(__GNUC__) && !defined(__APPLE__) && !defined(__PLATFORM_IS_ANDROID__) && !defined(__EMSCRIPTEN__)
// Compiler
#define __GCC__ 1
// Platform
#define __LINUX__ 1
// Architecture
#if defined(__i386)
#define __32_BIT__ 1
#define __LITTLE_ENDIAN__ 1
#define __i386__ 1
#define __LP32__ 1
#define __SMALL__
#elif defined(__x86_64__)
#define __64_BIT__ 1
#define __LITTLE_ENDIAN__ 1
#define __X86_64__ 1
#define __LP64__ 1
#define __MEDIUM__ 1
#elif defined(__arm__)
#define __32_BIT__ 1
#define __LITTLE_ENDIAN__ 1
#define __ARM__ 1
#define __LP32__ 1
#define __SMALL__ 1
#elif defined(__aarch64__)
#define __64_BIT__ 1
#define __LITTLE_ENDIAN__ 1
#define __ARM64__ 1
#define __LP64__ 1
#define __MEDIUM__ 1
#endif
// Native char set
#define __ISO_8859_1__ 1
// Native line endings
#define __LF__ 1
#endif
////////////////////////////////////////////////////////////////////////////////
//
// CONFIGURE DEFINITIONS FOR IOS
//
#if defined(__GNUC__) && defined(__APPLE__) && TARGET_OS_IPHONE
// Compiler
#define __GCC__ 1
// Platform
#define __IOS__ 1
// Architecture
#if defined(__i386)
#define __32_BIT__ 1
#define __LITTLE_ENDIAN__ 1
#define __i386__ 1
#define __LP32__ 1
#define __SMALL__ 1
#elif defined(__ppc__)
#define __32_BIT__ 1
#define __BIG_ENDIAN__ 1
#define __PPC__ 1
#define __LP32__ 1
#define __SMALL__ 1
#elif defined(__x86_64__)
#define __64_BIT__ 1
#define __LITTLE_ENDIAN__ 1
#define __X86_64__ 1
#define __LP64__ 1
#define __MEDIUM__ 1
#elif defined(__arm__)
#define __32_BIT__ 1
#define __LITTLE_ENDIAN__ 1
#define __ARM__ 1
#define __LP32__ 1
#define __SMALL__ 1
#elif defined(__arm64__)
#define __64_BIT__ 1
#define __LITTLE_ENDIAN__ 1
#define __ARM64__
#define __LP64__ 1
#define __MEDIUM__ 1
#endif
// Native char set
#define __MACROMAN__ 1
// Native line endings
#define __CR__ 1
// Presence of CoreFoundation
#define __HAS_CORE_FOUNDATION__ (1)
#endif
////////////////////////////////////////////////////////////////////////////////
//
// CONFIGURE DEFINITIONS FOR ANDROID
//
#if defined(__GNUC__) && !defined(__APPLE__) && defined(__PLATFORM_IS_ANDROID__)
// Compiler
#define __GCC__ (1)
// Platform
#define __ANDROID__ (1)
// Architecture
#if defined(__i386)
#define __32_BIT__ (1)
#define __LITTLE_ENDIAN__ (1)
#define __i386__ (1)
#define __LP32__ (1)
#define __SMALL__ (1)
#elif defined(__x86_64__)
#define __64_BIT__ (1)
#define __LITTLE_ENDIAN__ (1)
#define __X86_64__ (1)
#define __LP64__ (1)
#define __MEDIUM__ (1)
#elif defined(__arm__)
#define __32_BIT__ (1)
#define __LITTLE_ENDIAN__ (1)
#define __ARM__ (1)
#define __LP32__ (1)
#define __SMALL__ (1)
#elif defined(__aarch64__)
#define __64_BIT__ 1
#define __LITTLE_ENDIAN__ 1
#define __ARM64__ 1
#define __LP64__ 1
#define __MEDIUM__ 1
#endif
// Native char set
#define __ISO_8859_1__ (1)
// Native line endings
#define __LF__ (1)
#endif
////////////////////////////////////////////////////////////////////////////////
//
// CONFIGURE DEFINITIONS FOR EMSCRIPTEN JS
#if defined(__EMSCRIPTEN__)
// Nasty, evil hack -- remove me
#define __LITTLE_ENDIAN__ 1
// Compiler
#define __GCC__ (1)
// Architecture
#define __32_BIT__ (1)
#define __LP32__ (1)
#define __SMALL__ (1)
// Native char set
#define __ISO_8859_1__ (1)
// Native line endings
#define __LF__ (1)
#endif
////////////////////////////////////////////////////////////////////////////////
//
// CONFIGURE DEFINITIONS FOR WINDOWS MOBILE
//
////////////////////////////////////////////////////////////////////////////////
//
// CONFIGURE DEFINITIONS FOR LINUX MOBILE
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
// COMPILER HINT MACROS
//
// If we are using GCC or Clang, we can give the compiler various
// hints. This is particularly useful for Clang's static analysis
// feature.
#if defined(__GNUC__) || defined (__clang__) || defined (__llvm__)
# define ATTRIBUTE_NORETURN __attribute__((__noreturn__))
# define ATTRIBUTE_UNUSED __attribute__((__unused__))
# define ATTRIBUTE_PURE __attribute__((__pure__))
#else
# define ATTRIBUTE_NORETURN
# define ATTRIBUTE_UNUSED
# define ATTRIBUTE_PURE
#endif
////////////////////////////////////////////////////////////////////////////////
//
// SYMBOL EXPORTS
//
/* MC_DLLEXPORT should be applied to declarations. MC_DLLEXPORT_DEF
* should be applied to definitions. */
#ifdef _WIN32
/* On Windows, declaring something as having "dllexport" storage
* modifies the naming of the corresponding symbol, so the export
* attribute must be attached to declarations (and possibly to the
* definition *as well* if no separate declaration appears) */
# ifdef _MSC_VER
# define MC_DLLEXPORT __declspec(dllexport)
# else
# define MC_DLLEXPORT __attribute__((dllexport))
# endif
# define MC_DLLEXPORT_DEF MC_DLLEXPORT
#else
/* On non-Windows platforms, the external visibility of a symbol is
* simply a property of its definition (i.e. whether or not it should
* appear in the list of exported symbols). */
# define MC_DLLEXPORT
# define MC_DLLEXPORT_DEF __attribute__((__visibility__("default"), __used__))
#endif
////////////////////////////////////////////////////////////////////////////////
//
// C++ COMPATIBILITY
//
#ifndef __has_feature
# define __has_feature(x) 0
#endif
#ifndef __has_extension
# define __has_extension(x) __has_feature(x)
#endif
// Ensure we have alignof(...) available
#if defined(__cplusplus) && !__has_feature(cxx_alignof)
// Testing __cplusplus isn't sufficient as some compilers changed the value before being fully-conforming
# if defined(__clang__)
// No need for a version check; Clang supports __has_feature as a built-in
// so if we get here, it isn't supported
# define alignof(x) __alignof__(x)
# elif defined(__GNUC__)
// GCC added C++11 alignof(x) in GCC 4.8
# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8)
# define alignof(x) __alignof__(x)
# endif
# elif defined(_MSC_VER)
// MSVC added C++11 alignof(x) in Visual Studio 2012 (compiler version 11.0, _MSC_VER 1700)
# if (_MSC_VER < 1700)
# define alignof(x) __alignof(x)
# endif
# else
# error Do not know how to get alignof(x) on this compiler
# endif
#endif
////////////////////////////////////////////////////////////////////////////////
//
// FIXED WIDTH INTEGER TYPES
//
#if !defined(__STDC_LIMIT_MACROS)
# define __STDC_LIMIT_MACROS 1
#endif
#include <stddef.h>
#include <stdint.h>
#include <stddef.h>
#include <limits.h>
#ifndef UINT8_MIN
#define UINT8_MIN (0U)
#endif
#ifndef UINT16_MIN
#define UINT16_MIN (0U)
#endif
#ifndef UINT32_MIN
#define UINT32_MIN (0U)
#endif
#ifndef UINT64_MIN
#define UINT64_MIN (0ULL)
#endif
////////////////////////////////////////////////////////////////////////////////
//
// DERIVED INTEGER TYPES
//
#undef __HAVE_SSIZE_T__
#if !defined(__VISUALC__)
# define __HAVE_SSIZE_T__ 1
#endif /* !__VISUALC__ */
#ifdef __32_BIT__
typedef int32_t integer_t;
typedef uint32_t uinteger_t;
typedef int32_t intenum_t;
typedef uint32_t intset_t;
#define INTEGER_MIN INT32_MIN
#define INTEGER_MAX INT32_MAX
#define UINTEGER_MIN UINT32_MIN
#define UINTEGER_MAX UINT32_MAX
#define UINTPTR_MIN UINT32_MIN
#else /* !__32_BIT__ */
typedef int32_t integer_t;
typedef uint32_t uinteger_t;
typedef int32_t intenum_t;
typedef uint32_t intset_t;
#define INTEGER_MIN INT32_MIN
#define INTEGER_MAX INT32_MAX
#define UINTEGER_MIN UINT32_MIN
#define UINTEGER_MAX UINT32_MAX
#define UINTPTR_MIN UINT64_MIN
#endif /* !__32_BIT__ */
#if defined(__SMALL__) || defined(__MEDIUM__)
typedef uint32_t uindex_t;
typedef int32_t index_t;
typedef uint32_t hash_t;
typedef int32_t compare_t;
#define UINDEX_MIN UINT32_MIN
#define UINDEX_MAX UINT32_MAX
#define INDEX_MIN INT32_MIN
#define INDEX_MAX INT32_MAX
#elif defined(__LARGE__)
// This memory model would allow 64-bit indicies in Foundation types. This,
// however, has never been tested and so is only here for completeness at
// this time.
typedef uint64_t uindex_t;
typedef int64_t index_t;
typedef uint64_t hash_t;
typedef int64_t compare_t;
#define UINDEX_MIN UINT64_MIN
#define UINDEX_MAX UINT64_MAX
#define INDEX_MIN INT64_MIN
#define INDEX_MAX INT64_MAX
#else
#error No memory model defined for this platform and architecture combination
#endif
#if !defined(__HAVE_SSIZE_T__)
typedef intptr_t ssize_t;
# define SSIZE_MAX INTPTR_MAX
#endif
#define SIZE_MIN UINTPTR_MIN
#define SSIZE_MIN INTPTR_MIN
typedef int64_t filepos_t;
////////////////////////////////////////////////////////////////////////////////
//
// FLOATING-POINT TYPES
//
typedef double real64_t;
typedef float real32_t;
typedef double float64_t;
typedef float float32_t;
////////////////////////////////////////////////////////////////////////////////
// SN-2014-06-25 [[ FieldCoordinates ]] typedef moved here
//
// COORDINATES
//
typedef float32_t coord_t;
////////////////////////////////////////////////////////////////////////////////
//
// CHAR AND STRING TYPES
//
// The 'char_t' type is used to hold a native encoded char.
typedef unsigned char char_t;
// The 'byte_t' type is used to hold a char in a binary string
// (native). This cannot be anything other than to be "unsigned char"
// because we require the "sizeof" C++ operator to return sizes in
// units of byte_t, and because we require it to be valid to cast to a
// "byte_t*" in order to examine the object representation of a value.
typedef unsigned char byte_t;
// Constants used to represent the minimum and maximum values of a byte_t.
// We require bytes to be 8 bits in size.
static_assert(CHAR_BIT == 8, "Byte size is not 8 bits");
#define BYTE_MIN (0)
#define BYTE_MAX (255)
// The 'codepoint_t' type is used to hold a single Unicode codepoint (20-bit
// value).
typedef uint32_t codepoint_t;
// Constant to be used to represent an invalid codepoint (e.g. "no
// further characters)
#define CODEPOINT_NONE UINT32_MAX
// Constants used to represent the minimum and maximum values of a codepoint_t.
#define CODEPOINT_MIN 0
#define CODEPOINT_MAX 0x10ffff
// The 'unichar_t' type is used to hold a UTF-16 codeunit.
#ifdef __WINDOWS__
typedef wchar_t unichar_t;
#else
typedef uint16_t unichar_t;
#endif
// Constants used to represent the minimum and maximum values of a unichar_t.
#define UNICHAR_MIN UINT16_MIN
#define UNICHAR_MAX UINT16_MAX
#ifdef __WINDOWS__
typedef wchar_t *BSTR;
#endif
#if defined(__HAS_CORE_FOUNDATION__)
typedef const void *CFTypeRef;
typedef const struct __CFBoolean *CFBooleanRef;
typedef const struct __CFNumber *CFNumberRef;
typedef const struct __CFString *CFStringRef;
typedef const struct __CFData *CFDataRef;
typedef const struct __CFArray *CFArrayRef;
typedef const struct __CFDictionary *CFDictionaryRef;
#endif
////////////////////////////////////////////////////////////////////////////////
//
// POINTER TYPES
//
#if defined(__cplusplus) /* C++ */
# define nil nullptr
#else /* C */
# if defined(__GCC__)
# define nil __null
# else
# define nil ((void*)0)
# endif
#endif
////////////////////////////////////////////////////////////////////////////////
//
// STRUCTURE TYPES
//
struct MCRange
{
uindex_t offset;
uindex_t length;
};
////////////////////////////////////////////////////////////////////////////////
//
// VALUE TYPES
//
typedef void *MCValueRef;
typedef struct __MCTypeInfo *MCTypeInfoRef;
typedef struct __MCNull *MCNullRef;
typedef struct __MCBoolean *MCBooleanRef;
typedef struct __MCNumber *MCNumberRef;
typedef struct __MCString *MCStringRef;
typedef struct __MCName *MCNameRef;
typedef struct __MCData *MCDataRef;
typedef struct __MCArray *MCArrayRef;
typedef struct __MCHandler *MCHandlerRef;
typedef struct __MCList *MCListRef;
typedef struct __MCSet *MCSetRef;
typedef struct __MCRecord *MCRecordRef;
typedef struct __MCError *MCErrorRef;
typedef struct __MCStream *MCStreamRef;
typedef struct __MCProperList *MCProperListRef;
typedef struct __MCForeignValue *MCForeignValueRef;
typedef struct __MCJavaObject *MCJavaObjectRef;
typedef struct __MCObjcObject *MCObjcObjectRef;
// Forward declaration
typedef struct __MCLocale* MCLocaleRef;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
// REQUIRED STANDARD INCLUDES
//
// Required so that MSVC's <math.h> defines non-standard mathematical constants
#define _USE_MATH_DEFINES
#include <foundation-stdlib.h>
#include <math.h>
////////////////////////////////////////////////////////////////////////////////
//
// NEW AND DELETE OPERATORS
//
#ifdef __cplusplus
# include <new>
using std::nothrow;
#endif
////////////////////////////////////////////////////////////////////////////////
//
// NARROWING CONVERSIONS
//
#include <utility>
#include <type_traits>
/* A searchable way to do narrowing casts of numeric values (e.g. from
* uint32_t to uint8_t or from uindex_t to std::ptrdiff_t). Use in
* preference to a C-style cast or a raw static_cast. Should be used
* when you're totally certain that overflow/underflow has been
* logically ruled out elsewhere. */
template <typename To, typename From>
inline constexpr To MCNarrowCast(From p_from) noexcept
{
return static_cast<To>(std::forward<From>(p_from));
}
/* Checked narrowing conversion of numeric values. Use when there's a
* possibility that the input value might not fit into the output
* type, and you want to check. Note that this is safe to use in
* generic/template code; if To can represent all values of From, it
* optimises to nothing.*/
template <typename To, typename From>
inline bool MCNarrow(From p_from, To& r_result)
{
To t_to = static_cast<To>(p_from);
if (static_cast<From>(t_to) != p_from)
return false;
if ((std::is_signed<From>::value != std::is_signed<To>::value) &&
((t_to < To{}) != (p_from < From{})))
return false;
r_result = t_to;
return true;
}
////////////////////////////////////////////////////////////////////////////////
//
// MINIMUM FUNCTIONS
//
// TODO: re-write when we adopt C++11
template <class T, class U> inline T MCMin(T a, U b) { return a < b ? a : T(b); }
////////////////////////////////////////////////////////////////////////////////
//
// MAXIMUM FUNCTIONS
//
// TODO: re-write when we adopt C++11
template <class T, class U> inline T MCMax(T a, U b) { return a > b ? a : T(b); }
////////////////////////////////////////////////////////////////////////////////
//
// ABSOLUTE VALUE FUNCTIONS
//
inline uint32_t MCAbs(int32_t a) { return uint32_t(a < 0 ? -a : a); }
inline uint64_t MCAbs(int64_t a) { return uint64_t(a < 0 ? -a : a); }
inline float MCAbs(float a) { return fabsf(a); }
inline double MCAbs(double a) { return fabs(a); }
////////////////////////////////////////////////////////////////////////////////
//
// SIGN FUNCTIONS
//
template <class T> inline compare_t MCSgn(T a) { return a < 0 ? -1 : (a > 0 ? 1 : 0); }
////////////////////////////////////////////////////////////////////////////////
//
// COMPARE FUNCTIONS
//
template <typename T> inline compare_t MCCompare(T a, T b) { return ((a < b) ? -1 : ((a > b) ? 1 : 0)); }
////////////////////////////////////////////////////////////////////////////////
//
// COMPARE FUNCTIONS
//
template <typename T> inline bool MCIsPowerOfTwo(T x) { return (x & (x - 1)) == 0; }
template <typename T, typename U, typename V>
inline T MCClamp(T value, U min, V max) {
return MCMax(MCMin(value, max), min);
}
////////////////////////////////////////////////////////////////////////////////
//
// BYTE ORDER FUNCTIONS
//
enum MCByteOrder
{
kMCByteOrderUnknown,
kMCByteOrderLittleEndian,
kMCByteOrderBigEndian,
};
#ifdef __LITTLE_ENDIAN__
const MCByteOrder kMCByteOrderHost = kMCByteOrderLittleEndian;
#else
const MCByteOrder kMCByteOrderHost = kMCByteOrderBigEndian;
#endif
constexpr MCByteOrder MCByteOrderGetCurrent(void)
{
return kMCByteOrderHost;
}
constexpr uint8_t MCSwapInt(uint8_t x) { return x; }
constexpr int8_t MCSwapInt(int8_t x) { return x; }
constexpr uint16_t MCSwapInt(uint16_t x)
{
return (uint16_t)(x >> 8) | (uint16_t)(x << 8);
}
constexpr int16_t MCSwapInt(int16_t x) { return int16_t(MCSwapInt(uint16_t(x))); }
constexpr uint32_t MCSwapInt(uint32_t x)
{
return (x >> 24) | ((x >> 8) & 0xff00) | ((x & 0xff00) << 8) | (x << 24);
}
constexpr int32_t MCSwapInt(int32_t x) { return int32_t(MCSwapInt(uint32_t(x))); }
constexpr uint64_t MCSwapInt(uint64_t x)
{
return (x >> 56) | ((x >> 40) & 0xff00) | ((x >> 24) & 0xff0000) | ((x >> 8) & 0xff000000) |
((x & 0xff000000) << 8) | ((x & 0xff0000) << 24) | ((x & 0xff00) << 40) | (x << 56);
}
constexpr int64_t MCSwapInt(int64_t x) { return int16_t(MCSwapInt(uint64_t(x))); }
constexpr uint16_t MCSwapInt16(uint16_t x) { return MCSwapInt(x); }
constexpr uint32_t MCSwapInt32(uint32_t x) { return MCSwapInt(x); }
constexpr uint64_t MCSwapInt64(uint64_t x) { return MCSwapInt(x); }
template <typename T>
constexpr T MCSwapIntBigToHost(T x)
{
return (kMCByteOrderHost == kMCByteOrderBigEndian) ? x : MCSwapInt(x);
}
template <typename T>
constexpr T MCSwapIntHostToBig(T x) { return MCSwapIntBigToHost(x); }
template <typename T>
constexpr T MCSwapIntNetworkToHost(T x) { return MCSwapIntBigToHost(x); }
template <typename T>
constexpr T MCSwapIntHostToNetwork(T x) { return MCSwapIntHostToBig(x); }
template <typename T>
constexpr T MCSwapIntLittleToHost(T x)
{
return (kMCByteOrderHost == kMCByteOrderLittleEndian) ? x : MCSwapInt(x);
}
template <typename T>
constexpr T MCSwapIntHostToLittle(T x) { return MCSwapIntLittleToHost(x); }
constexpr uint16_t MCSwapInt16BigToHost(uint16_t x) {return MCSwapIntBigToHost(x);}
constexpr uint32_t MCSwapInt32BigToHost(uint32_t x) {return MCSwapIntBigToHost(x);}
constexpr uint64_t MCSwapInt64BigToHost(uint64_t x) {return MCSwapIntBigToHost(x);}
constexpr uint16_t MCSwapInt16HostToBig(uint16_t x) {return MCSwapIntHostToBig(x);}
constexpr uint32_t MCSwapInt32HostToBig(uint32_t x) {return MCSwapIntHostToBig(x);}
constexpr uint64_t MCSwapInt64HostToBig(uint64_t x) {return MCSwapIntHostToBig(x);}
constexpr uint16_t MCSwapInt16LittleToHost(uint16_t x) {return MCSwapIntLittleToHost(x);}
constexpr uint32_t MCSwapInt32LittleToHost(uint32_t x) {return MCSwapIntLittleToHost(x);}
constexpr uint64_t MCSwapInt64LittleToHost(uint64_t x) {return MCSwapIntLittleToHost(x);}
constexpr uint16_t MCSwapInt16HostToLittle(uint16_t x) {return MCSwapIntHostToLittle(x);}
constexpr uint32_t MCSwapInt32HostToLittle(uint32_t x) {return MCSwapIntHostToLittle(x);}
constexpr uint64_t MCSwapInt64HostToLittle(uint64_t x) {return MCSwapIntHostToLittle(x);}
constexpr uint16_t MCSwapInt16NetworkToHost(uint16_t x) {return MCSwapIntNetworkToHost(x);}
constexpr uint32_t MCSwapInt32NetworkToHost(uint32_t x) {return MCSwapIntNetworkToHost(x);}
constexpr uint64_t MCSwapInt64NetworkToHost(uint64_t x) {return MCSwapIntNetworkToHost(x);}
constexpr uint16_t MCSwapInt16HostToNetwork(uint16_t x) {return MCSwapIntHostToNetwork(x);}
constexpr uint32_t MCSwapInt32HostToNetwork(uint32_t x) {return MCSwapIntHostToNetwork(x);}
constexpr uint64_t MCSwapInt64HostToNetwork(uint64_t x) {return MCSwapIntHostToNetwork(x);}
////////////////////////////////////////////////////////////////////////////////
//
// RANGE FUNCTIONS
//
inline MCRange MCRangeMake(uindex_t p_offset, uindex_t p_length)
{
MCRange t_range;
t_range . offset = p_offset;
t_range . length = p_length;
return t_range;
}
inline MCRange MCRangeMakeMinMax(uindex_t p_min, uindex_t p_max)
{
if (p_min > p_max)
return MCRangeMake(p_max, 0);
return MCRangeMake(p_min, p_max - p_min);
}
inline MCRange MCRangeSetMinimum(const MCRange &p_range, uindex_t p_min)
{
return MCRangeMakeMinMax(p_min, p_range.offset + p_range.length);
}
inline MCRange MCRangeSetMaximum(const MCRange &p_range, uindex_t p_max)
{
return MCRangeMakeMinMax(p_range.offset, p_max);
}
inline MCRange MCRangeIncrementOffset(const MCRange &p_range, uindex_t p_increment)
{
return MCRangeSetMinimum(p_range, p_range.offset + p_increment);
}
inline bool MCRangeIsEqual(const MCRange &p_left, const MCRange &p_right)
{
return p_left.offset == p_right.offset && p_left.length == p_right.length;
}
inline bool MCRangeIsEmpty(const MCRange &p_range)
{
return p_range.length == 0;
}
inline MCRange MCRangeIntersection(const MCRange &p_left, const MCRange &p_right)
{
uindex_t t_start, t_end;
t_start = MCMax(p_left.offset, p_right.offset);
t_end = MCMin(p_left.offset + p_left.length, p_right.offset + p_right.length);
return MCRangeMakeMinMax(t_start, t_end);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
// STARTUP / SHUTDOWN HANDLING
//
bool MCInitialize(void);
void MCFinalize(void);
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
// DEBUG HANDLING
//
#if defined(_DEBUG)
# define DEBUG_LOG 1
#endif