Preprocessor.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /*
  2. * Copyright 2012-present 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. // @author: Andrei Alexandrescu
  17. #pragma once
  18. /**
  19. * Necessarily evil preprocessor-related amenities.
  20. */
  21. // MSVC's preprocessor is a pain, so we have to
  22. // forcefully expand the VA args in some places.
  23. #define FB_VA_GLUE(a, b) a b
  24. /**
  25. * FB_ONE_OR_NONE(hello, world) expands to hello and
  26. * FB_ONE_OR_NONE(hello) expands to nothing. This macro is used to
  27. * insert or eliminate text based on the presence of another argument.
  28. */
  29. #define FB_ONE_OR_NONE(a, ...) FB_VA_GLUE(FB_THIRD, (a, ##__VA_ARGS__, a))
  30. #define FB_THIRD(a, b, ...) __VA_ARGS__
  31. /**
  32. * Helper macro that extracts the first argument out of a list of any
  33. * number of arguments.
  34. */
  35. #define FB_ARG_1(a, ...) a
  36. /**
  37. * Helper macro that extracts the second argument out of a list of any
  38. * number of arguments. If only one argument is given, it returns
  39. * that.
  40. */
  41. #ifdef _MSC_VER
  42. // GCC refuses to expand this correctly if this macro itself was
  43. // called with FB_VA_GLUE :(
  44. #define FB_ARG_2_OR_1(...) \
  45. FB_VA_GLUE(FB_ARG_2_OR_1_IMPL, (__VA_ARGS__, __VA_ARGS__))
  46. #else
  47. #define FB_ARG_2_OR_1(...) FB_ARG_2_OR_1_IMPL(__VA_ARGS__, __VA_ARGS__)
  48. #endif
  49. // Support macro for the above
  50. #define FB_ARG_2_OR_1_IMPL(a, b, ...) b
  51. /**
  52. * Helper macro that provides a way to pass argument with commas in it to
  53. * some other macro whose syntax doesn't allow using extra parentheses.
  54. * Example:
  55. *
  56. * #define MACRO(type, name) type name
  57. * MACRO(FB_SINGLE_ARG(std::pair<size_t, size_t>), x);
  58. *
  59. */
  60. #define FB_SINGLE_ARG(...) __VA_ARGS__
  61. #define FOLLY_PP_DETAIL_APPEND_VA_ARG(...) , ##__VA_ARGS__
  62. /**
  63. * Helper macro that just ignores its parameters.
  64. */
  65. #define FOLLY_IGNORE(...)
  66. /**
  67. * Helper macro that just ignores its parameters and inserts a semicolon.
  68. */
  69. #define FOLLY_SEMICOLON(...) ;
  70. /**
  71. * FB_ANONYMOUS_VARIABLE(str) introduces an identifier starting with
  72. * str and ending with a number that varies with the line.
  73. */
  74. #ifndef FB_ANONYMOUS_VARIABLE
  75. #define FB_CONCATENATE_IMPL(s1, s2) s1##s2
  76. #define FB_CONCATENATE(s1, s2) FB_CONCATENATE_IMPL(s1, s2)
  77. #ifdef __COUNTER__
  78. #define FB_ANONYMOUS_VARIABLE(str) FB_CONCATENATE(str, __COUNTER__)
  79. #else
  80. #define FB_ANONYMOUS_VARIABLE(str) FB_CONCATENATE(str, __LINE__)
  81. #endif
  82. #endif
  83. /**
  84. * Use FB_STRINGIZE(x) when you'd want to do what #x does inside
  85. * another macro expansion.
  86. */
  87. #define FB_STRINGIZE(x) #x
  88. #define FOLLY_PP_DETAIL_NARGS_1(dummy, _7, _6, _5, _4, _3, _2, _1, _0, ...) _0
  89. #define FOLLY_PP_DETAIL_NARGS(...) \
  90. FOLLY_PP_DETAIL_NARGS_1(dummy, ##__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0)
  91. #define FOLLY_PP_DETAIL_FOR_EACH_REC_0(fn, ...)
  92. #define FOLLY_PP_DETAIL_FOR_EACH_REC_1(fn, a, ...) \
  93. fn(a) FOLLY_PP_DETAIL_FOR_EACH_REC_0(fn, __VA_ARGS__)
  94. #define FOLLY_PP_DETAIL_FOR_EACH_REC_2(fn, a, ...) \
  95. fn(a) FOLLY_PP_DETAIL_FOR_EACH_REC_1(fn, __VA_ARGS__)
  96. #define FOLLY_PP_DETAIL_FOR_EACH_REC_3(fn, a, ...) \
  97. fn(a) FOLLY_PP_DETAIL_FOR_EACH_REC_2(fn, __VA_ARGS__)
  98. #define FOLLY_PP_DETAIL_FOR_EACH_REC_4(fn, a, ...) \
  99. fn(a) FOLLY_PP_DETAIL_FOR_EACH_REC_3(fn, __VA_ARGS__)
  100. #define FOLLY_PP_DETAIL_FOR_EACH_REC_5(fn, a, ...) \
  101. fn(a) FOLLY_PP_DETAIL_FOR_EACH_REC_4(fn, __VA_ARGS__)
  102. #define FOLLY_PP_DETAIL_FOR_EACH_REC_6(fn, a, ...) \
  103. fn(a) FOLLY_PP_DETAIL_FOR_EACH_REC_5(fn, __VA_ARGS__)
  104. #define FOLLY_PP_DETAIL_FOR_EACH_REC_7(fn, a, ...) \
  105. fn(a) FOLLY_PP_DETAIL_FOR_EACH_REC_6(fn, __VA_ARGS__)
  106. #define FOLLY_PP_DETAIL_FOR_EACH_2(fn, n, ...) \
  107. FOLLY_PP_DETAIL_FOR_EACH_REC_##n(fn, __VA_ARGS__)
  108. #define FOLLY_PP_DETAIL_FOR_EACH_1(fn, n, ...) \
  109. FOLLY_PP_DETAIL_FOR_EACH_2(fn, n, __VA_ARGS__)
  110. /**
  111. * FOLLY_PP_FOR_EACH
  112. *
  113. * Used to invoke a preprocessor macro, the name of which is passed as the
  114. * first argument, once for each subsequent variadic argument.
  115. *
  116. * At present, supports [0, 8) arguments.
  117. *
  118. * This input:
  119. *
  120. * #define DOIT(a) go_do_it(a);
  121. * FOLLY_PP_FOR_EACH(DOIT, 3, 5, 7)
  122. * #undef DOIT
  123. *
  124. * Expands to this output (with whitespace adjusted for clarity):
  125. *
  126. * go_do_it(3);
  127. * go_do_it(5);
  128. * go_do_it(7);
  129. */
  130. #define FOLLY_PP_FOR_EACH(fn, ...) \
  131. FOLLY_PP_DETAIL_FOR_EACH_1( \
  132. fn, FOLLY_PP_DETAIL_NARGS(__VA_ARGS__), __VA_ARGS__)