<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".h" #>
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

/*THIS FILE IS GENERATED*/
/*DO NOT EDIT BY HAND!!!*/
/*instead edit macro_utils_generated.tt here: http://www.github.com/azure/azure-macro-utils-c.git */

<#/*CHANGE BELOW 2 VARIABLES TO GET MORE / LESS */ #>
<#int nArithmetic=2048;#>
<#int nMacroParameters=124;/*127 parameters in one macro definition in C99 in chapter 5.2.4.1 Translation limits*/#>

#ifndef MACRO_UTILS_GENERATED_H
#define MACRO_UTILS_GENERATED_H

#define MU_IFCOMMA(N) MU_C2(MU_IFCOMMA_, N)
#define MU_IFCOMMA_0
#define MU_IFCOMMA_2
<#for(var i=4;i<=nMacroParameters;i+=2)#>
<#{#>
#define MU_IFCOMMA_<#=i#> ,
<#}#>

#define MU_IFCOMMALOGIC(N) MU_C2(MU_IFCOMMALOGIC_, N)
#define MU_IFCOMMALOGIC_0 
<#for(var i=1;i<=nMacroParameters;i+=1)#>
<#{#>
#define MU_IFCOMMALOGIC_<#=i#> ,
<#}#>

#define MU_IFCOMMA_NOFIRST(N) MU_C2(MU_IFCOMMA_NOFIRST, N)
#define MU_IFCOMMA_NOFIRST1 
<#for(var i=2;i<=nMacroParameters;i++)#>
<#{#>
#define MU_IFCOMMA_NOFIRST<#=i#> ,
<#}#>

#define MU_DEC(x) MU_C2(MU_DEC,x)
<#for(var i=nArithmetic;i>=1;i--)#>
<#{#>
#define MU_DEC<#=i#> <#=i-1#>
<#}#>

#define MU_INC(x) MU_C2(MU_INC,x)
<#for(var i=nArithmetic;i>=0;i--)#>
<#{#>
#define MU_INC<#=i#> <#=i+1#>
<#}#>

#define MU_DIV2(x) MU_C2(MU_DIV2_,x)

<#for(var i=nArithmetic;i>=0;i--)#>
<#{#>
#define MU_DIV2_<#=i#> <#=i/2#>
<#}#>

<#/*the below produces MOD2 for numbers*/#>
#define MU_MOD2(x) MU_C2(MU_MOD2_,x)
<#for(var i=nArithmetic;i>=0;i--)#>
<#{#>
#define MU_MOD2_<#=i#> <#=i%2#>
<#}#>

#define MU_THE_NTH_ARG(<#for(var i=1;i<=nMacroParameters;i++)#>
<#{#>P<#=i#>, <#}#> ... ) P<#=nMacroParameters#>

#ifdef _MSC_VER
#define MU_COUNT_1_OR_MORE_ARG(...) MU_THE_NTH_ARG MU_LPAREN __VA_ARGS__, \
<#for(var i=nMacroParameters-1;i>=1;i--){#><#=i.ToString()+((i>1)?", ":"")#><#}#>)
#define MU_MORE_THAN_1_ARG(...) MU_THE_NTH_ARG MU_LPAREN __VA_ARGS__, <#for(var i=nMacroParameters-2;i>=1;i--){#><#=1#>,<#}#>0)
#else
#define MU_COUNT_1_OR_MORE_ARG(...) MU_THE_NTH_ARG (__VA_ARGS__, \
<#for(var i=nMacroParameters-1;i>=1;i--){#><#=i.ToString()+((i>1)?", ":"")#><#}#>)
#define MU_MORE_THAN_1_ARG(...) MU_THE_NTH_ARG(__VA_ARGS__, <#for(var i=nMacroParameters-2;i>=1;i--){#><#=1#>,<#}#> 0)
#endif

#define MU_COUNT_ARG(...) MU_C2(MU_COUNT_ARG_, MU_ISEMPTY(__VA_ARGS__))(__VA_ARGS__)
#define MU_COUNT_ARG_1(...) 0
#define MU_COUNT_ARG_0(...) MU_C1(MU_COUNT_1_OR_MORE_ARG(__VA_ARGS__))

#define MU_ISEMPTY(...) MU_C5(MU_DISPATCH_EMPTY_, MU_MORE_THAN_1_ARG(MU_TRIGGER_PARENTHESIS __VA_ARGS__ ()), MU_MORE_THAN_1_ARG(__VA_ARGS__), MU_MORE_THAN_1_ARG(__VA_ARGS__ ()), MU_MORE_THAN_1_ARG(MU_TRIGGER_PARENTHESIS __VA_ARGS__))
#define MU_DISPATCH_EMPTY_1000 1
#define MU_DISPATCH_EMPTY_0000 0
#define MU_DISPATCH_EMPTY_1100 0
#define MU_DISPATCH_EMPTY_1111 0
#define MU_DISPATCH_EMPTY_1001 0
#define MU_DISPATCH_EMPTY_1010 0


<#for(var i=nMacroParameters;i>=2;i--)#>
<#{#>
#define MU_FOR_EACH_1_<#=i#>(X, <#for(var j=1;j<=i;j++){#>P<#=j.ToString()+((j<i)?", ":"")#><#}#>) \
X(P1) \
MU_FOR_EACH_1_<#=i-1#>(X, <#for(var j=2;j<=i;j++){#>P<#=j.ToString()+((j<i)?", ":"")#><#}#>)

<#}#>
#define MU_FOR_EACH_1_1(X, P1) \
X(P1)

#ifdef _MSC_VER
#define MU_FOR_EACH_1(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_1_,MU_C1(MU_COUNT_ARG(__VA_ARGS__))) MU_LPAREN MACRO_TO_INVOKE, __VA_ARGS__)
#else
#define MU_FOR_EACH_1(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_1_,MU_C1(MU_COUNT_ARG(__VA_ARGS__))) ( MACRO_TO_INVOKE, __VA_ARGS__)
#endif

<#for(var i=nMacroParameters;i>=2;i--)#>
<#{#>
#define MU_FOR_EACH_1_KEEP_1_<#=i#>(X, keep, <#for(var j=1;j<=i;j++){#>P<#=j.ToString()+(j<i?", ":"")#><#}#>) \
X(keep, P1) \
MU_FOR_EACH_1_KEEP_1_<#=i-1#>(X, keep, <#for(var j=2;j<=i;j++){#>P<#=(j).ToString()+(j<i?", ":"")#><#}#>)


<#}#>

#define MU_FOR_EACH_1_KEEP_1_1(X, keep, P1) \
X(keep, P1)

#ifdef _MSC_VER
#define MU_FOR_EACH_1_KEEP_1(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_1_KEEP_1_, MU_C2(MU_DEC,MU_C1(MU_COUNT_ARG(__VA_ARGS__)))) MU_LPAREN MACRO_TO_INVOKE, __VA_ARGS__)
#else
#define MU_FOR_EACH_1_KEEP_1(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_1_KEEP_1_, MU_C2(MU_DEC,MU_C1(MU_COUNT_ARG(__VA_ARGS__)))) ( MACRO_TO_INVOKE, __VA_ARGS__)
#endif

<#for(var i=nMacroParameters;i>=2;i--)#>
<#{#>
#define MU_FOR_EACH_1_KEEP_2_<#=i#>(X, keep1, keep2, <#for(var j=1;j<=i;j++){#>P<#=j.ToString()+(j<i?", ":"")#><#}#>) \
X(keep1, keep2, P1) \
MU_FOR_EACH_1_KEEP_2_<#=i-1#>(X, keep1, keep2, <#for(var j=2;j<=i;j++){#>P<#=(j).ToString()+(j<i?", ":"")#><#}#>)


<#}#>

#define MU_FOR_EACH_1_KEEP_2_1(X, keep1, keep2, P1) \
X(keep1, keep2, P1)

#define MU_FOR_EACH_1_KEEP_2_0(...)

#ifdef _MSC_VER
#define MU_FOR_EACH_1_KEEP_2(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_1_KEEP_2_, MU_C2(MU_DEC,MU_C2(MU_DEC,MU_C1(MU_COUNT_ARG(__VA_ARGS__))))) MU_LPAREN MACRO_TO_INVOKE, __VA_ARGS__)
#else
#define MU_FOR_EACH_1_KEEP_2(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_1_KEEP_2_, MU_C2(MU_DEC,MU_C2(MU_DEC,MU_C1(MU_COUNT_ARG(__VA_ARGS__))))) ( MACRO_TO_INVOKE, __VA_ARGS__)
#endif

<#for(var i=nMacroParameters;i>=4;i-=2)#>
<#{#>
#define MU_FOR_EACH_2_KEEP_1_<#=i#>(X, keep, <#for(var j=1;j<=i;j++){#>P<#=j.ToString()+(j<i?", ":"")#><#}#>) \
X(keep, P1, P2) \
MU_FOR_EACH_2_KEEP_1_<#=i-2#>(X, keep, <#for(var j=3;j<=i;j++){#>P<#=(j).ToString()+(j<i?", ":"")#><#}#>)


<#}#>

#define MU_FOR_EACH_2_KEEP_1_1(...)

#define MU_FOR_EACH_2_KEEP_1_0(...)

#define MU_FOR_EACH_2_KEEP_1_2(X, keep, P1, P2) \
    X(keep, P1, P2) \

#ifdef _MSC_VER
#define MU_FOR_EACH_2_KEEP_1(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_2_KEEP_1_, MU_C2(MU_DEC,MU_C1(MU_COUNT_ARG(__VA_ARGS__)))) MU_LPAREN MACRO_TO_INVOKE, __VA_ARGS__)
#else
#define MU_FOR_EACH_2_KEEP_1(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_2_KEEP_1_, MU_C2(MU_DEC,MU_C1(MU_COUNT_ARG(__VA_ARGS__)))) ( MACRO_TO_INVOKE, __VA_ARGS__)
#endif


<#for(var i=nMacroParameters;i>=4;i-=2)#>
<#{#>
#define MU_FOR_EACH_2_KEEP_2_<#=i#>(X, keep1, keep2, <#for(var j=1;j<=i;j++){#>P<#=j.ToString()+(j<i?", ":"")#><#}#>) \
X(keep1, keep2, P1, P2) \
MU_FOR_EACH_2_KEEP_2_<#=i-2#>(X, keep1, keep2, <#for(var j=3;j<=i;j++){#>P<#=(j).ToString()+(j<i?", ":"")#><#}#>)


<#}#>

#define MU_FOR_EACH_2_KEEP_2_1(...)

#define MU_FOR_EACH_2_KEEP_2_0(...)

#define MU_FOR_EACH_2_KEEP_2_2(X, keep1, keep2, P1, P2) \
    X(keep1, keep2, P1, P2) \

#ifdef _MSC_VER
#define MU_FOR_EACH_2_KEEP_2(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_2_KEEP_2_, MU_C2(MU_DEC,MU_C2(MU_DEC,MU_C1(MU_COUNT_ARG(__VA_ARGS__))))) MU_LPAREN MACRO_TO_INVOKE, __VA_ARGS__)
#else
#define MU_FOR_EACH_2_KEEP_2(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_2_KEEP_2_, MU_C2(MU_DEC, MU_C2(MU_DEC,MU_C1(MU_COUNT_ARG(__VA_ARGS__))))) ( MACRO_TO_INVOKE, __VA_ARGS__)
#endif


#define MU_FOR_EACH_2_0(...)

#define MU_FOR_EACH_2_2(X, P1, P2) \
X(P1, P2)

<#for(var i=4;i<=nMacroParameters;i+=2) {#>
#define MU_FOR_EACH_2_<#=i#>(X, <#for(var j=1;j<=i;j++){#>P<#=j.ToString()+((j<i)?", ":"")#><#}#>) \
X(P1, P2) \
MU_FOR_EACH_2_<#=i-2#>(X, <#for(var j=3;j<=i;j++){#>P<#=j.ToString()+((j<i)?", ":"")#><#}#>)

<#}#>

#define MU_FOR_EACH_2_REVERSE_0(...)

#define MU_FOR_EACH_2_REVERSE_2(X, P1, P2) \
X(P1, P2)

<#for(var i=4;i<=nMacroParameters;i+=2) {#>
#define MU_FOR_EACH_2_REVERSE_<#=i#>(X, <#for(var j=1;j<=i;j++){#>P<#=j.ToString()+((j<i)?", ":"")#><#}#>) \
X(P<#=i-1#>, P<#=i#>) \
MU_FOR_EACH_2_REVERSE_<#=i-2#>(X, <#for(var j=1;j<=i-2;j++){#>P<#=j.ToString()+((j<i-2)?", ":"")#><#}#>)

<#}#>

#define MU_FOR_EACH_1_COUNTED_0(...)

#define MU_FOR_EACH_1_COUNTED_1(X, P1) \
    X(1, P1)

<#for(var i=2;i<=nMacroParameters;i++) {#>
#define MU_FOR_EACH_1_COUNTED_<#=i#>(X, <#for(var j=1;j<=i;j++){#>P<#=j.ToString()+((j<i)?", ":"")#><#}#>) \
X(<#=i#>, P1) \
MU_FOR_EACH_1_COUNTED_<#=i-1#>(X, <#for(var j=2;j<=i;j++){#>P<#=j.ToString()+((j<i)?", ":"")#><#}#>)

<#}#>

#define MU_FOR_EACH_2_COUNTED_0(...)

#define MU_FOR_EACH_2_COUNTED_2(X, P1, P2) \
    X(2, P1, P2)

<#for(var i=4;i<=nMacroParameters;i+=2) {#>
#define MU_FOR_EACH_2_COUNTED_<#=i#>(X, <#for(var j=1;j<=i;j++){#>P<#=j.ToString()+((j<i)?", ":"")#><#}#>) \
X(<#=i#>, P1, P2) \
MU_FOR_EACH_2_COUNTED_<#=i-2#>(X, <#for(var j=3;j<=i;j++){#>P<#=j.ToString()+((j<i)?", ":"")#><#}#>)

<#}#>

#ifdef _MSC_VER
#define MU_FOR_EACH_2(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_2_, MU_C1(MU_COUNT_ARG(__VA_ARGS__))) MU_LPAREN MACRO_TO_INVOKE, __VA_ARGS__)
/*the COUNTED breed of MU_FOR_EACH macro invokes a macro with 3 parameters: 1st being the count of invocation. For example.
MU_FOR_EACH_2_COUNTER(MACRO, a,b,c,d,e,f) will result in 
MACRO(6, a,b)
MACRO(4, c,d)
MACRO(2, e,f)
This macro exists because we need a "stop condition" in outputting COMMA... when calling a function f(a,b,c,d) cannot be f(a,b,c,d,) <=doesn't compile (as opposed to enum definition)
*/
#define MU_FOR_EACH_2_COUNTED(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_2_COUNTED_, MU_C1(MU_COUNT_ARG(__VA_ARGS__))) MU_LPAREN MACRO_TO_INVOKE, __VA_ARGS__)
#define MU_FOR_EACH_1_COUNTED(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_1_COUNTED_, MU_C1(MU_COUNT_ARG(__VA_ARGS__))) MU_LPAREN MACRO_TO_INVOKE, __VA_ARGS__)

/*MU_FOR_EACH_2_REVERSE acts just like MU_FOR_EACH_2, but in reverse order. Example:
MU_FOR_EACH_2_REVERSE(X,a,b,c,d,e,f) => X(e,f) X(c,d) X (a, b) in this order */
#define MU_FOR_EACH_2_REVERSE(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_2_REVERSE_, MU_C1(MU_COUNT_ARG(__VA_ARGS__))) MU_LPAREN MACRO_TO_INVOKE, __VA_ARGS__)
#else
#define MU_FOR_EACH_2(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_2_, MU_C1(MU_COUNT_ARG(__VA_ARGS__))) ( MACRO_TO_INVOKE, __VA_ARGS__)
#define MU_FOR_EACH_2_COUNTED(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_2_COUNTED_, MU_C1(MU_COUNT_ARG(__VA_ARGS__))) ( MACRO_TO_INVOKE,  __VA_ARGS__)
#define MU_FOR_EACH_1_COUNTED(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_1_COUNTED_, MU_C1(MU_COUNT_ARG(__VA_ARGS__))) ( MACRO_TO_INVOKE,  __VA_ARGS__)
#define MU_FOR_EACH_2_REVERSE(MACRO_TO_INVOKE, ...) MU_C2(MU_FOR_EACH_2_REVERSE_, MU_C1(MU_COUNT_ARG(__VA_ARGS__))) ( MACRO_TO_INVOKE, __VA_ARGS__)
#endif

#ifdef _MSC_VER
#define MU_EXPAND_OR_MU_C1(x) x
#else
#define MU_EXPAND_OR_MU_C1(...) __VA_ARGS__
#endif

#define MU_EXPAND_ARGS(...) __VA_ARGS__
#define MU_EXPAND_TWICE(...) MU_EXPAND_ARGS(__VA_ARGS__)

#define MU_DO_0(MACRO, ...) \
MACRO(0, __VA_ARGS__)

<#for(var i=1;i<=nArithmetic;i++){#>
#define MU_DO_<#=i#>(MACRO, ...) \
MACRO(<#=i#>, __VA_ARGS__) \
MU_DO_<#=i-1#>(MACRO, __VA_ARGS__)


<#}#>

#define MU_DO(TIMES, MACRO, ...) MU_C2(MU_DO_, TIMES)(MACRO, __VA_ARGS__)

#endif /*MACRO_UTILS_GENERATED_H*/
