Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

331 lines
11 KiB

  1. //===--- VariadicFunctions.h - Variadic Functions ---------------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file implements compile-time type-safe variadic functions.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_ADT_VARIADICFUNCTION_H
  14. #define LLVM_ADT_VARIADICFUNCTION_H
  15. #include "llvm/ADT/ArrayRef.h"
  16. namespace llvm {
  17. // Define macros to aid in expanding a comma separated series with the index of
  18. // the series pasted onto the last token.
  19. #define LLVM_COMMA_JOIN1(x) x ## 0
  20. #define LLVM_COMMA_JOIN2(x) LLVM_COMMA_JOIN1(x), x ## 1
  21. #define LLVM_COMMA_JOIN3(x) LLVM_COMMA_JOIN2(x), x ## 2
  22. #define LLVM_COMMA_JOIN4(x) LLVM_COMMA_JOIN3(x), x ## 3
  23. #define LLVM_COMMA_JOIN5(x) LLVM_COMMA_JOIN4(x), x ## 4
  24. #define LLVM_COMMA_JOIN6(x) LLVM_COMMA_JOIN5(x), x ## 5
  25. #define LLVM_COMMA_JOIN7(x) LLVM_COMMA_JOIN6(x), x ## 6
  26. #define LLVM_COMMA_JOIN8(x) LLVM_COMMA_JOIN7(x), x ## 7
  27. #define LLVM_COMMA_JOIN9(x) LLVM_COMMA_JOIN8(x), x ## 8
  28. #define LLVM_COMMA_JOIN10(x) LLVM_COMMA_JOIN9(x), x ## 9
  29. #define LLVM_COMMA_JOIN11(x) LLVM_COMMA_JOIN10(x), x ## 10
  30. #define LLVM_COMMA_JOIN12(x) LLVM_COMMA_JOIN11(x), x ## 11
  31. #define LLVM_COMMA_JOIN13(x) LLVM_COMMA_JOIN12(x), x ## 12
  32. #define LLVM_COMMA_JOIN14(x) LLVM_COMMA_JOIN13(x), x ## 13
  33. #define LLVM_COMMA_JOIN15(x) LLVM_COMMA_JOIN14(x), x ## 14
  34. #define LLVM_COMMA_JOIN16(x) LLVM_COMMA_JOIN15(x), x ## 15
  35. #define LLVM_COMMA_JOIN17(x) LLVM_COMMA_JOIN16(x), x ## 16
  36. #define LLVM_COMMA_JOIN18(x) LLVM_COMMA_JOIN17(x), x ## 17
  37. #define LLVM_COMMA_JOIN19(x) LLVM_COMMA_JOIN18(x), x ## 18
  38. #define LLVM_COMMA_JOIN20(x) LLVM_COMMA_JOIN19(x), x ## 19
  39. #define LLVM_COMMA_JOIN21(x) LLVM_COMMA_JOIN20(x), x ## 20
  40. #define LLVM_COMMA_JOIN22(x) LLVM_COMMA_JOIN21(x), x ## 21
  41. #define LLVM_COMMA_JOIN23(x) LLVM_COMMA_JOIN22(x), x ## 22
  42. #define LLVM_COMMA_JOIN24(x) LLVM_COMMA_JOIN23(x), x ## 23
  43. #define LLVM_COMMA_JOIN25(x) LLVM_COMMA_JOIN24(x), x ## 24
  44. #define LLVM_COMMA_JOIN26(x) LLVM_COMMA_JOIN25(x), x ## 25
  45. #define LLVM_COMMA_JOIN27(x) LLVM_COMMA_JOIN26(x), x ## 26
  46. #define LLVM_COMMA_JOIN28(x) LLVM_COMMA_JOIN27(x), x ## 27
  47. #define LLVM_COMMA_JOIN29(x) LLVM_COMMA_JOIN28(x), x ## 28
  48. #define LLVM_COMMA_JOIN30(x) LLVM_COMMA_JOIN29(x), x ## 29
  49. #define LLVM_COMMA_JOIN31(x) LLVM_COMMA_JOIN30(x), x ## 30
  50. #define LLVM_COMMA_JOIN32(x) LLVM_COMMA_JOIN31(x), x ## 31
  51. /// \brief Class which can simulate a type-safe variadic function.
  52. ///
  53. /// The VariadicFunction class template makes it easy to define
  54. /// type-safe variadic functions where all arguments have the same
  55. /// type.
  56. ///
  57. /// Suppose we need a variadic function like this:
  58. ///
  59. /// ResultT Foo(const ArgT &A_0, const ArgT &A_1, ..., const ArgT &A_N);
  60. ///
  61. /// Instead of many overloads of Foo(), we only need to define a helper
  62. /// function that takes an array of arguments:
  63. ///
  64. /// ResultT FooImpl(ArrayRef<const ArgT *> Args) {
  65. /// // 'Args[i]' is a pointer to the i-th argument passed to Foo().
  66. /// ...
  67. /// }
  68. ///
  69. /// and then define Foo() like this:
  70. ///
  71. /// const VariadicFunction<ResultT, ArgT, FooImpl> Foo;
  72. ///
  73. /// VariadicFunction takes care of defining the overloads of Foo().
  74. ///
  75. /// Actually, Foo is a function object (i.e. functor) instead of a plain
  76. /// function. This object is stateless and its constructor/destructor
  77. /// does nothing, so it's safe to create global objects and call Foo(...) at
  78. /// any time.
  79. ///
  80. /// Sometimes we need a variadic function to have some fixed leading
  81. /// arguments whose types may be different from that of the optional
  82. /// arguments. For example:
  83. ///
  84. /// bool FullMatch(const StringRef &S, const RE &Regex,
  85. /// const ArgT &A_0, ..., const ArgT &A_N);
  86. ///
  87. /// VariadicFunctionN is for such cases, where N is the number of fixed
  88. /// arguments. It is like VariadicFunction, except that it takes N more
  89. /// template arguments for the types of the fixed arguments:
  90. ///
  91. /// bool FullMatchImpl(const StringRef &S, const RE &Regex,
  92. /// ArrayRef<const ArgT *> Args) { ... }
  93. /// const VariadicFunction2<bool, const StringRef&,
  94. /// const RE&, ArgT, FullMatchImpl>
  95. /// FullMatch;
  96. ///
  97. /// Currently VariadicFunction and friends support up-to 3
  98. /// fixed leading arguments and up-to 32 optional arguments.
  99. template <typename ResultT, typename ArgT,
  100. ResultT (*Func)(ArrayRef<const ArgT *>)>
  101. struct VariadicFunction {
  102. ResultT operator()() const {
  103. return Func(ArrayRef<const ArgT *>());
  104. }
  105. #define LLVM_DEFINE_OVERLOAD(N) \
  106. ResultT operator()(LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \
  107. const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \
  108. return Func(makeArrayRef(Args)); \
  109. }
  110. LLVM_DEFINE_OVERLOAD(1)
  111. LLVM_DEFINE_OVERLOAD(2)
  112. LLVM_DEFINE_OVERLOAD(3)
  113. LLVM_DEFINE_OVERLOAD(4)
  114. LLVM_DEFINE_OVERLOAD(5)
  115. LLVM_DEFINE_OVERLOAD(6)
  116. LLVM_DEFINE_OVERLOAD(7)
  117. LLVM_DEFINE_OVERLOAD(8)
  118. LLVM_DEFINE_OVERLOAD(9)
  119. LLVM_DEFINE_OVERLOAD(10)
  120. LLVM_DEFINE_OVERLOAD(11)
  121. LLVM_DEFINE_OVERLOAD(12)
  122. LLVM_DEFINE_OVERLOAD(13)
  123. LLVM_DEFINE_OVERLOAD(14)
  124. LLVM_DEFINE_OVERLOAD(15)
  125. LLVM_DEFINE_OVERLOAD(16)
  126. LLVM_DEFINE_OVERLOAD(17)
  127. LLVM_DEFINE_OVERLOAD(18)
  128. LLVM_DEFINE_OVERLOAD(19)
  129. LLVM_DEFINE_OVERLOAD(20)
  130. LLVM_DEFINE_OVERLOAD(21)
  131. LLVM_DEFINE_OVERLOAD(22)
  132. LLVM_DEFINE_OVERLOAD(23)
  133. LLVM_DEFINE_OVERLOAD(24)
  134. LLVM_DEFINE_OVERLOAD(25)
  135. LLVM_DEFINE_OVERLOAD(26)
  136. LLVM_DEFINE_OVERLOAD(27)
  137. LLVM_DEFINE_OVERLOAD(28)
  138. LLVM_DEFINE_OVERLOAD(29)
  139. LLVM_DEFINE_OVERLOAD(30)
  140. LLVM_DEFINE_OVERLOAD(31)
  141. LLVM_DEFINE_OVERLOAD(32)
  142. #undef LLVM_DEFINE_OVERLOAD
  143. };
  144. template <typename ResultT, typename Param0T, typename ArgT,
  145. ResultT (*Func)(Param0T, ArrayRef<const ArgT *>)>
  146. struct VariadicFunction1 {
  147. ResultT operator()(Param0T P0) const {
  148. return Func(P0, ArrayRef<const ArgT *>());
  149. }
  150. #define LLVM_DEFINE_OVERLOAD(N) \
  151. ResultT operator()(Param0T P0, LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \
  152. const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \
  153. return Func(P0, makeArrayRef(Args)); \
  154. }
  155. LLVM_DEFINE_OVERLOAD(1)
  156. LLVM_DEFINE_OVERLOAD(2)
  157. LLVM_DEFINE_OVERLOAD(3)
  158. LLVM_DEFINE_OVERLOAD(4)
  159. LLVM_DEFINE_OVERLOAD(5)
  160. LLVM_DEFINE_OVERLOAD(6)
  161. LLVM_DEFINE_OVERLOAD(7)
  162. LLVM_DEFINE_OVERLOAD(8)
  163. LLVM_DEFINE_OVERLOAD(9)
  164. LLVM_DEFINE_OVERLOAD(10)
  165. LLVM_DEFINE_OVERLOAD(11)
  166. LLVM_DEFINE_OVERLOAD(12)
  167. LLVM_DEFINE_OVERLOAD(13)
  168. LLVM_DEFINE_OVERLOAD(14)
  169. LLVM_DEFINE_OVERLOAD(15)
  170. LLVM_DEFINE_OVERLOAD(16)
  171. LLVM_DEFINE_OVERLOAD(17)
  172. LLVM_DEFINE_OVERLOAD(18)
  173. LLVM_DEFINE_OVERLOAD(19)
  174. LLVM_DEFINE_OVERLOAD(20)
  175. LLVM_DEFINE_OVERLOAD(21)
  176. LLVM_DEFINE_OVERLOAD(22)
  177. LLVM_DEFINE_OVERLOAD(23)
  178. LLVM_DEFINE_OVERLOAD(24)
  179. LLVM_DEFINE_OVERLOAD(25)
  180. LLVM_DEFINE_OVERLOAD(26)
  181. LLVM_DEFINE_OVERLOAD(27)
  182. LLVM_DEFINE_OVERLOAD(28)
  183. LLVM_DEFINE_OVERLOAD(29)
  184. LLVM_DEFINE_OVERLOAD(30)
  185. LLVM_DEFINE_OVERLOAD(31)
  186. LLVM_DEFINE_OVERLOAD(32)
  187. #undef LLVM_DEFINE_OVERLOAD
  188. };
  189. template <typename ResultT, typename Param0T, typename Param1T, typename ArgT,
  190. ResultT (*Func)(Param0T, Param1T, ArrayRef<const ArgT *>)>
  191. struct VariadicFunction2 {
  192. ResultT operator()(Param0T P0, Param1T P1) const {
  193. return Func(P0, P1, ArrayRef<const ArgT *>());
  194. }
  195. #define LLVM_DEFINE_OVERLOAD(N) \
  196. ResultT operator()(Param0T P0, Param1T P1, \
  197. LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \
  198. const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \
  199. return Func(P0, P1, makeArrayRef(Args)); \
  200. }
  201. LLVM_DEFINE_OVERLOAD(1)
  202. LLVM_DEFINE_OVERLOAD(2)
  203. LLVM_DEFINE_OVERLOAD(3)
  204. LLVM_DEFINE_OVERLOAD(4)
  205. LLVM_DEFINE_OVERLOAD(5)
  206. LLVM_DEFINE_OVERLOAD(6)
  207. LLVM_DEFINE_OVERLOAD(7)
  208. LLVM_DEFINE_OVERLOAD(8)
  209. LLVM_DEFINE_OVERLOAD(9)
  210. LLVM_DEFINE_OVERLOAD(10)
  211. LLVM_DEFINE_OVERLOAD(11)
  212. LLVM_DEFINE_OVERLOAD(12)
  213. LLVM_DEFINE_OVERLOAD(13)
  214. LLVM_DEFINE_OVERLOAD(14)
  215. LLVM_DEFINE_OVERLOAD(15)
  216. LLVM_DEFINE_OVERLOAD(16)
  217. LLVM_DEFINE_OVERLOAD(17)
  218. LLVM_DEFINE_OVERLOAD(18)
  219. LLVM_DEFINE_OVERLOAD(19)
  220. LLVM_DEFINE_OVERLOAD(20)
  221. LLVM_DEFINE_OVERLOAD(21)
  222. LLVM_DEFINE_OVERLOAD(22)
  223. LLVM_DEFINE_OVERLOAD(23)
  224. LLVM_DEFINE_OVERLOAD(24)
  225. LLVM_DEFINE_OVERLOAD(25)
  226. LLVM_DEFINE_OVERLOAD(26)
  227. LLVM_DEFINE_OVERLOAD(27)
  228. LLVM_DEFINE_OVERLOAD(28)
  229. LLVM_DEFINE_OVERLOAD(29)
  230. LLVM_DEFINE_OVERLOAD(30)
  231. LLVM_DEFINE_OVERLOAD(31)
  232. LLVM_DEFINE_OVERLOAD(32)
  233. #undef LLVM_DEFINE_OVERLOAD
  234. };
  235. template <typename ResultT, typename Param0T, typename Param1T,
  236. typename Param2T, typename ArgT,
  237. ResultT (*Func)(Param0T, Param1T, Param2T, ArrayRef<const ArgT *>)>
  238. struct VariadicFunction3 {
  239. ResultT operator()(Param0T P0, Param1T P1, Param2T P2) const {
  240. return Func(P0, P1, P2, ArrayRef<const ArgT *>());
  241. }
  242. #define LLVM_DEFINE_OVERLOAD(N) \
  243. ResultT operator()(Param0T P0, Param1T P1, Param2T P2, \
  244. LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \
  245. const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \
  246. return Func(P0, P1, P2, makeArrayRef(Args)); \
  247. }
  248. LLVM_DEFINE_OVERLOAD(1)
  249. LLVM_DEFINE_OVERLOAD(2)
  250. LLVM_DEFINE_OVERLOAD(3)
  251. LLVM_DEFINE_OVERLOAD(4)
  252. LLVM_DEFINE_OVERLOAD(5)
  253. LLVM_DEFINE_OVERLOAD(6)
  254. LLVM_DEFINE_OVERLOAD(7)
  255. LLVM_DEFINE_OVERLOAD(8)
  256. LLVM_DEFINE_OVERLOAD(9)
  257. LLVM_DEFINE_OVERLOAD(10)
  258. LLVM_DEFINE_OVERLOAD(11)
  259. LLVM_DEFINE_OVERLOAD(12)
  260. LLVM_DEFINE_OVERLOAD(13)
  261. LLVM_DEFINE_OVERLOAD(14)
  262. LLVM_DEFINE_OVERLOAD(15)
  263. LLVM_DEFINE_OVERLOAD(16)
  264. LLVM_DEFINE_OVERLOAD(17)
  265. LLVM_DEFINE_OVERLOAD(18)
  266. LLVM_DEFINE_OVERLOAD(19)
  267. LLVM_DEFINE_OVERLOAD(20)
  268. LLVM_DEFINE_OVERLOAD(21)
  269. LLVM_DEFINE_OVERLOAD(22)
  270. LLVM_DEFINE_OVERLOAD(23)
  271. LLVM_DEFINE_OVERLOAD(24)
  272. LLVM_DEFINE_OVERLOAD(25)
  273. LLVM_DEFINE_OVERLOAD(26)
  274. LLVM_DEFINE_OVERLOAD(27)
  275. LLVM_DEFINE_OVERLOAD(28)
  276. LLVM_DEFINE_OVERLOAD(29)
  277. LLVM_DEFINE_OVERLOAD(30)
  278. LLVM_DEFINE_OVERLOAD(31)
  279. LLVM_DEFINE_OVERLOAD(32)
  280. #undef LLVM_DEFINE_OVERLOAD
  281. };
  282. // Cleanup the macro namespace.
  283. #undef LLVM_COMMA_JOIN1
  284. #undef LLVM_COMMA_JOIN2
  285. #undef LLVM_COMMA_JOIN3
  286. #undef LLVM_COMMA_JOIN4
  287. #undef LLVM_COMMA_JOIN5
  288. #undef LLVM_COMMA_JOIN6
  289. #undef LLVM_COMMA_JOIN7
  290. #undef LLVM_COMMA_JOIN8
  291. #undef LLVM_COMMA_JOIN9
  292. #undef LLVM_COMMA_JOIN10
  293. #undef LLVM_COMMA_JOIN11
  294. #undef LLVM_COMMA_JOIN12
  295. #undef LLVM_COMMA_JOIN13
  296. #undef LLVM_COMMA_JOIN14
  297. #undef LLVM_COMMA_JOIN15
  298. #undef LLVM_COMMA_JOIN16
  299. #undef LLVM_COMMA_JOIN17
  300. #undef LLVM_COMMA_JOIN18
  301. #undef LLVM_COMMA_JOIN19
  302. #undef LLVM_COMMA_JOIN20
  303. #undef LLVM_COMMA_JOIN21
  304. #undef LLVM_COMMA_JOIN22
  305. #undef LLVM_COMMA_JOIN23
  306. #undef LLVM_COMMA_JOIN24
  307. #undef LLVM_COMMA_JOIN25
  308. #undef LLVM_COMMA_JOIN26
  309. #undef LLVM_COMMA_JOIN27
  310. #undef LLVM_COMMA_JOIN28
  311. #undef LLVM_COMMA_JOIN29
  312. #undef LLVM_COMMA_JOIN30
  313. #undef LLVM_COMMA_JOIN31
  314. #undef LLVM_COMMA_JOIN32
  315. } // end namespace llvm
  316. #endif // LLVM_ADT_VARIADICFUNCTION_H