Clean up Conv.cpp / Conv.h
[folly.git] / folly / Preprocessor.h
1 /*
2  * Copyright 2016 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 // @author: Andrei Alexandrescu
18
19 #pragma once
20
21 /**
22  * Necessarily evil preprocessor-related amenities.
23  */
24
25 /**
26  * FB_ONE_OR_NONE(hello, world) expands to hello and
27  * FB_ONE_OR_NONE(hello) expands to nothing. This macro is used to
28  * insert or eliminate text based on the presence of another argument.
29  */
30 #ifdef _MSC_VER
31
32 #define VA_NARGS_IMPL(_1, _2, _3, _4, _5, N, ...) N
33 #define VA_NARGS(...) VA_NARGS_IMPL(X,##__VA_ARGS__, 4, 3, 2, 1, 0)
34 #define VARARG_IMPL2(base, count, ...) base##count(__VA_ARGS__)
35 #define VARARG_IMPL(base, count, ...) VARARG_IMPL2(base, count, __VA_ARGS__)
36 #define VARARG(base, ...) VARARG_IMPL(base, VA_NARGS(__VA_ARGS__), __VA_ARGS__)
37
38 #define FB_ONE_OR_NONE0() /* */
39 #define FB_ONE_OR_NONE1(x) /* */
40 #define FB_ONE_OR_NONE2(x, y) x
41 #define FB_ONE_OR_NONE3(x, y, z) x
42 #define FB_ONE_OR_NONE(...) VARARG(FB_ONE_OR_NONE, __VA_ARGS__)
43
44 #else
45 #define FB_ONE_OR_NONE(a, ...) FB_THIRD(a, ## __VA_ARGS__, a)
46 #define FB_THIRD(a, b, ...) __VA_ARGS__
47 #endif
48
49 // MSVC's preprocessor is a pain, so we have to
50 // forcefully expand the VA args in some places.
51 #define FB_VA_GLUE(a, b) a b
52
53 /**
54  * Helper macro that extracts the first argument out of a list of any
55  * number of arguments.
56  */
57 #define FB_ARG_1(a, ...) a
58
59 /**
60  * Helper macro that extracts the second argument out of a list of any
61  * number of arguments. If only one argument is given, it returns
62  * that.
63  */
64 #ifdef _MSC_VER
65 // GCC refuses to expand this correctly if this macro itself was
66 // called with FB_VA_GLUE :(
67 #define FB_ARG_2_OR_1(...) \
68   FB_VA_GLUE(FB_ARG_2_OR_1_IMPL, (__VA_ARGS__, __VA_ARGS__))
69 #else
70 #define FB_ARG_2_OR_1(...) FB_ARG_2_OR_1_IMPL(__VA_ARGS__, __VA_ARGS__)
71 #endif
72 // Support macro for the above
73 #define FB_ARG_2_OR_1_IMPL(a, b, ...) b
74
75 /**
76  * Helper macro that provides a way to pass argument with commas in it to
77  * some other macro whose syntax doesn't allow using extra parentheses.
78  * Example:
79  *
80  *   #define MACRO(type, name) type name
81  *   MACRO(FB_SINGLE_ARG(std::pair<size_t, size_t>), x);
82  *
83  */
84 #define FB_SINGLE_ARG(...) __VA_ARGS__
85
86 /**
87  * Helper macro that just ignores its parameters.
88  */
89 #define FOLLY_IGNORE(...)
90
91 /**
92  * Helper macro that just ignores its parameters and inserts a semicolon.
93  */
94 #define FOLLY_SEMICOLON(...) ;
95
96 /**
97  * FB_ANONYMOUS_VARIABLE(str) introduces an identifier starting with
98  * str and ending with a number that varies with the line.
99  */
100 #ifndef FB_ANONYMOUS_VARIABLE
101 #define FB_CONCATENATE_IMPL(s1, s2) s1##s2
102 #define FB_CONCATENATE(s1, s2) FB_CONCATENATE_IMPL(s1, s2)
103 #ifdef __COUNTER__
104 #define FB_ANONYMOUS_VARIABLE(str) FB_CONCATENATE(str, __COUNTER__)
105 #else
106 #define FB_ANONYMOUS_VARIABLE(str) FB_CONCATENATE(str, __LINE__)
107 #endif
108 #endif
109
110 /**
111  * Use FB_STRINGIZE(x) when you'd want to do what #x does inside
112  * another macro expansion.
113  */
114 #define FB_STRINGIZE(x) #x