Nugget
eastdarg.h
1 /*-----------------------------------------------------------------------------
2  * eastdarg.h
3  *
4  * Copyright (c) Electronic Arts Inc. All rights reserved.
5  *---------------------------------------------------------------------------*/
6 
7 
8 #ifndef INCLUDED_eastdarg_H
9 #define INCLUDED_eastdarg_H
10 
11 
12 #include <EABase/eabase.h>
13 #include <stdarg.h>
14 
15 
16 // VA_ARG_COUNT
17 //
18 // Returns the number of arguments passed to a macro's ... argument.
19 // This applies to macros only and not functions.
20 //
21 // Example usage:
22 // assert(VA_ARG_COUNT() == 0);
23 // assert(VA_ARG_COUNT(a) == 1);
24 // assert(VA_ARG_COUNT(a, b) == 2);
25 // assert(VA_ARG_COUNT(a, b, c) == 3);
26 //
27 #if !defined(VA_ARG_COUNT)
28  #define VA_ARG_COUNT(...) VA_ARG_COUNT_II((VA_ARG_COUNT_PREFIX_ ## __VA_ARGS__ ## _VA_ARG_COUNT_POSTFIX,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0))
29  #define VA_ARG_COUNT_II(__args) VA_ARG_COUNT_I __args
30  #define VA_ARG_COUNT_PREFIX__VA_ARG_COUNT_POSTFIX ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0
31  #define VA_ARG_COUNT_I(_0,_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,N,...) N
32 #endif
33 
34 
35 // va_copy
36 //
37 // va_copy is required by C++11
38 // C++11 and C99 require va_copy to be #defined and implemented.
39 // http://en.cppreference.com/w/cpp/utility/variadic/va_copy
40 //
41 // Example usage:
42 // void Func(char* p, ...){
43 // va_list args, argsCopy;
44 // va_start(args, p);
45 // va_copy(argsCopy, args);
46 // (use args)
47 // (use argsCopy, which acts the same as args)
48 // va_end(args);
49 // va_end(argsCopy);
50 // }
51 //
52 #ifndef va_copy
53  #if defined(__va_copy) // GCC and others define this for non-C99 compatibility.
54  #define va_copy(dest, src) __va_copy((dest), (src))
55  #else
56  // This may not work for some platforms, depending on their ABI.
57  // It works for Microsoft x86,x64, and PowerPC-based platforms.
58  #define va_copy(dest, src) memcpy(&(dest), &(src), sizeof(va_list))
59  #endif
60 #endif
61 
62 
63 
64 // va_list_reference
65 //
66 // va_list_reference is not part of the C or C++ standards.
67 // It allows you to pass a va_list by reference to another
68 // function instead of by value. You cannot simply use va_list&
69 // as that won't work with many va_list implementations because
70 // they are implemented as arrays (which can't be passed by
71 // reference to a function without decaying to a pointer).
72 //
73 // Example usage:
74 // void Test(va_list_reference args){
75 // printf("%d", va_arg(args, int));
76 // }
77 // void Func(char* p, ...){
78 // va_list args;
79 // va_start(args, p);
80 // Test(args); // Upon return args will be modified.
81 // va_end(args);
82 // }
83 #ifndef va_list_reference
84  #if defined(EA_PLATFORM_MICROSOFT) || (EA_PLATFORM_PTR_SIZE == 4) || (defined(EA_PLATFORM_APPLE) && defined(EA_PROCESSOR_ARM64)) || defined(CS_UNDEFINED_STRING) || (defined(EA_PLATFORM_ANDROID) && defined(EA_PROCESSOR_ARM64))
85  // This is required for platform ABIs in which va_list is a struct or pointer.
86  #define va_list_reference va_list&
87  #else
88  // This is required for platform ABIs in which va_list is defined to be an array.
89  #define va_list_reference va_list
90  #endif
91 #endif
92 
93 
94 
95 
96 #endif /* Header include guard */
97 
98 
99