LLVM API Documentation

VariadicFunction.h
Go to the documentation of this file.
00001 //===--- VariadicFunctions.h - Variadic Functions ---------------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file implements compile-time type-safe variadic functions.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_ADT_VARIADICFUNCTION_H
00015 #define LLVM_ADT_VARIADICFUNCTION_H
00016 
00017 #include "llvm/ADT/ArrayRef.h"
00018 
00019 namespace llvm {
00020 
00021 // Define macros to aid in expanding a comma separated series with the index of
00022 // the series pasted onto the last token.
00023 #define LLVM_COMMA_JOIN1(x) x ## 0
00024 #define LLVM_COMMA_JOIN2(x) LLVM_COMMA_JOIN1(x), x ## 1
00025 #define LLVM_COMMA_JOIN3(x) LLVM_COMMA_JOIN2(x), x ## 2
00026 #define LLVM_COMMA_JOIN4(x) LLVM_COMMA_JOIN3(x), x ## 3
00027 #define LLVM_COMMA_JOIN5(x) LLVM_COMMA_JOIN4(x), x ## 4
00028 #define LLVM_COMMA_JOIN6(x) LLVM_COMMA_JOIN5(x), x ## 5
00029 #define LLVM_COMMA_JOIN7(x) LLVM_COMMA_JOIN6(x), x ## 6
00030 #define LLVM_COMMA_JOIN8(x) LLVM_COMMA_JOIN7(x), x ## 7
00031 #define LLVM_COMMA_JOIN9(x) LLVM_COMMA_JOIN8(x), x ## 8
00032 #define LLVM_COMMA_JOIN10(x) LLVM_COMMA_JOIN9(x), x ## 9
00033 #define LLVM_COMMA_JOIN11(x) LLVM_COMMA_JOIN10(x), x ## 10
00034 #define LLVM_COMMA_JOIN12(x) LLVM_COMMA_JOIN11(x), x ## 11
00035 #define LLVM_COMMA_JOIN13(x) LLVM_COMMA_JOIN12(x), x ## 12
00036 #define LLVM_COMMA_JOIN14(x) LLVM_COMMA_JOIN13(x), x ## 13
00037 #define LLVM_COMMA_JOIN15(x) LLVM_COMMA_JOIN14(x), x ## 14
00038 #define LLVM_COMMA_JOIN16(x) LLVM_COMMA_JOIN15(x), x ## 15
00039 #define LLVM_COMMA_JOIN17(x) LLVM_COMMA_JOIN16(x), x ## 16
00040 #define LLVM_COMMA_JOIN18(x) LLVM_COMMA_JOIN17(x), x ## 17
00041 #define LLVM_COMMA_JOIN19(x) LLVM_COMMA_JOIN18(x), x ## 18
00042 #define LLVM_COMMA_JOIN20(x) LLVM_COMMA_JOIN19(x), x ## 19
00043 #define LLVM_COMMA_JOIN21(x) LLVM_COMMA_JOIN20(x), x ## 20
00044 #define LLVM_COMMA_JOIN22(x) LLVM_COMMA_JOIN21(x), x ## 21
00045 #define LLVM_COMMA_JOIN23(x) LLVM_COMMA_JOIN22(x), x ## 22
00046 #define LLVM_COMMA_JOIN24(x) LLVM_COMMA_JOIN23(x), x ## 23
00047 #define LLVM_COMMA_JOIN25(x) LLVM_COMMA_JOIN24(x), x ## 24
00048 #define LLVM_COMMA_JOIN26(x) LLVM_COMMA_JOIN25(x), x ## 25
00049 #define LLVM_COMMA_JOIN27(x) LLVM_COMMA_JOIN26(x), x ## 26
00050 #define LLVM_COMMA_JOIN28(x) LLVM_COMMA_JOIN27(x), x ## 27
00051 #define LLVM_COMMA_JOIN29(x) LLVM_COMMA_JOIN28(x), x ## 28
00052 #define LLVM_COMMA_JOIN30(x) LLVM_COMMA_JOIN29(x), x ## 29
00053 #define LLVM_COMMA_JOIN31(x) LLVM_COMMA_JOIN30(x), x ## 30
00054 #define LLVM_COMMA_JOIN32(x) LLVM_COMMA_JOIN31(x), x ## 31
00055 
00056 /// \brief Class which can simulate a type-safe variadic function.
00057 ///
00058 /// The VariadicFunction class template makes it easy to define
00059 /// type-safe variadic functions where all arguments have the same
00060 /// type.
00061 ///
00062 /// Suppose we need a variadic function like this:
00063 ///
00064 ///   ResultT Foo(const ArgT &A_0, const ArgT &A_1, ..., const ArgT &A_N);
00065 ///
00066 /// Instead of many overloads of Foo(), we only need to define a helper
00067 /// function that takes an array of arguments:
00068 ///
00069 ///   ResultT FooImpl(ArrayRef<const ArgT *> Args) {
00070 ///     // 'Args[i]' is a pointer to the i-th argument passed to Foo().
00071 ///     ...
00072 ///   }
00073 ///
00074 /// and then define Foo() like this:
00075 ///
00076 ///   const VariadicFunction<ResultT, ArgT, FooImpl> Foo;
00077 ///
00078 /// VariadicFunction takes care of defining the overloads of Foo().
00079 ///
00080 /// Actually, Foo is a function object (i.e. functor) instead of a plain
00081 /// function.  This object is stateless and its constructor/destructor
00082 /// does nothing, so it's safe to create global objects and call Foo(...) at
00083 /// any time.
00084 ///
00085 /// Sometimes we need a variadic function to have some fixed leading
00086 /// arguments whose types may be different from that of the optional
00087 /// arguments.  For example:
00088 ///
00089 ///   bool FullMatch(const StringRef &S, const RE &Regex,
00090 ///                  const ArgT &A_0, ..., const ArgT &A_N);
00091 ///
00092 /// VariadicFunctionN is for such cases, where N is the number of fixed
00093 /// arguments.  It is like VariadicFunction, except that it takes N more
00094 /// template arguments for the types of the fixed arguments:
00095 ///
00096 ///   bool FullMatchImpl(const StringRef &S, const RE &Regex,
00097 ///                      ArrayRef<const ArgT *> Args) { ... }
00098 ///   const VariadicFunction2<bool, const StringRef&,
00099 ///                           const RE&, ArgT, FullMatchImpl>
00100 ///       FullMatch;
00101 ///
00102 /// Currently VariadicFunction and friends support up-to 3
00103 /// fixed leading arguments and up-to 32 optional arguments.
00104 template <typename ResultT, typename ArgT,
00105           ResultT (*Func)(ArrayRef<const ArgT *>)>
00106 struct VariadicFunction {
00107   ResultT operator()() const {
00108     return Func(None);
00109   }
00110 
00111 #define LLVM_DEFINE_OVERLOAD(N) \
00112   ResultT operator()(LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \
00113     const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \
00114     return Func(makeArrayRef(Args)); \
00115   }
00116   LLVM_DEFINE_OVERLOAD(1)
00117   LLVM_DEFINE_OVERLOAD(2)
00118   LLVM_DEFINE_OVERLOAD(3)
00119   LLVM_DEFINE_OVERLOAD(4)
00120   LLVM_DEFINE_OVERLOAD(5)
00121   LLVM_DEFINE_OVERLOAD(6)
00122   LLVM_DEFINE_OVERLOAD(7)
00123   LLVM_DEFINE_OVERLOAD(8)
00124   LLVM_DEFINE_OVERLOAD(9)
00125   LLVM_DEFINE_OVERLOAD(10)
00126   LLVM_DEFINE_OVERLOAD(11)
00127   LLVM_DEFINE_OVERLOAD(12)
00128   LLVM_DEFINE_OVERLOAD(13)
00129   LLVM_DEFINE_OVERLOAD(14)
00130   LLVM_DEFINE_OVERLOAD(15)
00131   LLVM_DEFINE_OVERLOAD(16)
00132   LLVM_DEFINE_OVERLOAD(17)
00133   LLVM_DEFINE_OVERLOAD(18)
00134   LLVM_DEFINE_OVERLOAD(19)
00135   LLVM_DEFINE_OVERLOAD(20)
00136   LLVM_DEFINE_OVERLOAD(21)
00137   LLVM_DEFINE_OVERLOAD(22)
00138   LLVM_DEFINE_OVERLOAD(23)
00139   LLVM_DEFINE_OVERLOAD(24)
00140   LLVM_DEFINE_OVERLOAD(25)
00141   LLVM_DEFINE_OVERLOAD(26)
00142   LLVM_DEFINE_OVERLOAD(27)
00143   LLVM_DEFINE_OVERLOAD(28)
00144   LLVM_DEFINE_OVERLOAD(29)
00145   LLVM_DEFINE_OVERLOAD(30)
00146   LLVM_DEFINE_OVERLOAD(31)
00147   LLVM_DEFINE_OVERLOAD(32)
00148 #undef LLVM_DEFINE_OVERLOAD
00149 };
00150 
00151 template <typename ResultT, typename Param0T, typename ArgT,
00152           ResultT (*Func)(Param0T, ArrayRef<const ArgT *>)>
00153 struct VariadicFunction1 {
00154   ResultT operator()(Param0T P0) const {
00155     return Func(P0, None);
00156   }
00157 
00158 #define LLVM_DEFINE_OVERLOAD(N) \
00159   ResultT operator()(Param0T P0, LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \
00160     const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \
00161     return Func(P0, makeArrayRef(Args)); \
00162   }
00163   LLVM_DEFINE_OVERLOAD(1)
00164   LLVM_DEFINE_OVERLOAD(2)
00165   LLVM_DEFINE_OVERLOAD(3)
00166   LLVM_DEFINE_OVERLOAD(4)
00167   LLVM_DEFINE_OVERLOAD(5)
00168   LLVM_DEFINE_OVERLOAD(6)
00169   LLVM_DEFINE_OVERLOAD(7)
00170   LLVM_DEFINE_OVERLOAD(8)
00171   LLVM_DEFINE_OVERLOAD(9)
00172   LLVM_DEFINE_OVERLOAD(10)
00173   LLVM_DEFINE_OVERLOAD(11)
00174   LLVM_DEFINE_OVERLOAD(12)
00175   LLVM_DEFINE_OVERLOAD(13)
00176   LLVM_DEFINE_OVERLOAD(14)
00177   LLVM_DEFINE_OVERLOAD(15)
00178   LLVM_DEFINE_OVERLOAD(16)
00179   LLVM_DEFINE_OVERLOAD(17)
00180   LLVM_DEFINE_OVERLOAD(18)
00181   LLVM_DEFINE_OVERLOAD(19)
00182   LLVM_DEFINE_OVERLOAD(20)
00183   LLVM_DEFINE_OVERLOAD(21)
00184   LLVM_DEFINE_OVERLOAD(22)
00185   LLVM_DEFINE_OVERLOAD(23)
00186   LLVM_DEFINE_OVERLOAD(24)
00187   LLVM_DEFINE_OVERLOAD(25)
00188   LLVM_DEFINE_OVERLOAD(26)
00189   LLVM_DEFINE_OVERLOAD(27)
00190   LLVM_DEFINE_OVERLOAD(28)
00191   LLVM_DEFINE_OVERLOAD(29)
00192   LLVM_DEFINE_OVERLOAD(30)
00193   LLVM_DEFINE_OVERLOAD(31)
00194   LLVM_DEFINE_OVERLOAD(32)
00195 #undef LLVM_DEFINE_OVERLOAD
00196 };
00197 
00198 template <typename ResultT, typename Param0T, typename Param1T, typename ArgT,
00199           ResultT (*Func)(Param0T, Param1T, ArrayRef<const ArgT *>)>
00200 struct VariadicFunction2 {
00201   ResultT operator()(Param0T P0, Param1T P1) const {
00202     return Func(P0, P1, None);
00203   }
00204 
00205 #define LLVM_DEFINE_OVERLOAD(N) \
00206   ResultT operator()(Param0T P0, Param1T P1, \
00207                      LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \
00208     const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \
00209     return Func(P0, P1, makeArrayRef(Args)); \
00210   }
00211   LLVM_DEFINE_OVERLOAD(1)
00212   LLVM_DEFINE_OVERLOAD(2)
00213   LLVM_DEFINE_OVERLOAD(3)
00214   LLVM_DEFINE_OVERLOAD(4)
00215   LLVM_DEFINE_OVERLOAD(5)
00216   LLVM_DEFINE_OVERLOAD(6)
00217   LLVM_DEFINE_OVERLOAD(7)
00218   LLVM_DEFINE_OVERLOAD(8)
00219   LLVM_DEFINE_OVERLOAD(9)
00220   LLVM_DEFINE_OVERLOAD(10)
00221   LLVM_DEFINE_OVERLOAD(11)
00222   LLVM_DEFINE_OVERLOAD(12)
00223   LLVM_DEFINE_OVERLOAD(13)
00224   LLVM_DEFINE_OVERLOAD(14)
00225   LLVM_DEFINE_OVERLOAD(15)
00226   LLVM_DEFINE_OVERLOAD(16)
00227   LLVM_DEFINE_OVERLOAD(17)
00228   LLVM_DEFINE_OVERLOAD(18)
00229   LLVM_DEFINE_OVERLOAD(19)
00230   LLVM_DEFINE_OVERLOAD(20)
00231   LLVM_DEFINE_OVERLOAD(21)
00232   LLVM_DEFINE_OVERLOAD(22)
00233   LLVM_DEFINE_OVERLOAD(23)
00234   LLVM_DEFINE_OVERLOAD(24)
00235   LLVM_DEFINE_OVERLOAD(25)
00236   LLVM_DEFINE_OVERLOAD(26)
00237   LLVM_DEFINE_OVERLOAD(27)
00238   LLVM_DEFINE_OVERLOAD(28)
00239   LLVM_DEFINE_OVERLOAD(29)
00240   LLVM_DEFINE_OVERLOAD(30)
00241   LLVM_DEFINE_OVERLOAD(31)
00242   LLVM_DEFINE_OVERLOAD(32)
00243 #undef LLVM_DEFINE_OVERLOAD
00244 };
00245 
00246 template <typename ResultT, typename Param0T, typename Param1T,
00247           typename Param2T, typename ArgT,
00248           ResultT (*Func)(Param0T, Param1T, Param2T, ArrayRef<const ArgT *>)>
00249 struct VariadicFunction3 {
00250   ResultT operator()(Param0T P0, Param1T P1, Param2T P2) const {
00251     return Func(P0, P1, P2, None);
00252   }
00253 
00254 #define LLVM_DEFINE_OVERLOAD(N) \
00255   ResultT operator()(Param0T P0, Param1T P1, Param2T P2, \
00256                      LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \
00257     const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \
00258     return Func(P0, P1, P2, makeArrayRef(Args)); \
00259   }
00260   LLVM_DEFINE_OVERLOAD(1)
00261   LLVM_DEFINE_OVERLOAD(2)
00262   LLVM_DEFINE_OVERLOAD(3)
00263   LLVM_DEFINE_OVERLOAD(4)
00264   LLVM_DEFINE_OVERLOAD(5)
00265   LLVM_DEFINE_OVERLOAD(6)
00266   LLVM_DEFINE_OVERLOAD(7)
00267   LLVM_DEFINE_OVERLOAD(8)
00268   LLVM_DEFINE_OVERLOAD(9)
00269   LLVM_DEFINE_OVERLOAD(10)
00270   LLVM_DEFINE_OVERLOAD(11)
00271   LLVM_DEFINE_OVERLOAD(12)
00272   LLVM_DEFINE_OVERLOAD(13)
00273   LLVM_DEFINE_OVERLOAD(14)
00274   LLVM_DEFINE_OVERLOAD(15)
00275   LLVM_DEFINE_OVERLOAD(16)
00276   LLVM_DEFINE_OVERLOAD(17)
00277   LLVM_DEFINE_OVERLOAD(18)
00278   LLVM_DEFINE_OVERLOAD(19)
00279   LLVM_DEFINE_OVERLOAD(20)
00280   LLVM_DEFINE_OVERLOAD(21)
00281   LLVM_DEFINE_OVERLOAD(22)
00282   LLVM_DEFINE_OVERLOAD(23)
00283   LLVM_DEFINE_OVERLOAD(24)
00284   LLVM_DEFINE_OVERLOAD(25)
00285   LLVM_DEFINE_OVERLOAD(26)
00286   LLVM_DEFINE_OVERLOAD(27)
00287   LLVM_DEFINE_OVERLOAD(28)
00288   LLVM_DEFINE_OVERLOAD(29)
00289   LLVM_DEFINE_OVERLOAD(30)
00290   LLVM_DEFINE_OVERLOAD(31)
00291   LLVM_DEFINE_OVERLOAD(32)
00292 #undef LLVM_DEFINE_OVERLOAD
00293 };
00294 
00295 // Cleanup the macro namespace.
00296 #undef LLVM_COMMA_JOIN1
00297 #undef LLVM_COMMA_JOIN2
00298 #undef LLVM_COMMA_JOIN3
00299 #undef LLVM_COMMA_JOIN4
00300 #undef LLVM_COMMA_JOIN5
00301 #undef LLVM_COMMA_JOIN6
00302 #undef LLVM_COMMA_JOIN7
00303 #undef LLVM_COMMA_JOIN8
00304 #undef LLVM_COMMA_JOIN9
00305 #undef LLVM_COMMA_JOIN10
00306 #undef LLVM_COMMA_JOIN11
00307 #undef LLVM_COMMA_JOIN12
00308 #undef LLVM_COMMA_JOIN13
00309 #undef LLVM_COMMA_JOIN14
00310 #undef LLVM_COMMA_JOIN15
00311 #undef LLVM_COMMA_JOIN16
00312 #undef LLVM_COMMA_JOIN17
00313 #undef LLVM_COMMA_JOIN18
00314 #undef LLVM_COMMA_JOIN19
00315 #undef LLVM_COMMA_JOIN20
00316 #undef LLVM_COMMA_JOIN21
00317 #undef LLVM_COMMA_JOIN22
00318 #undef LLVM_COMMA_JOIN23
00319 #undef LLVM_COMMA_JOIN24
00320 #undef LLVM_COMMA_JOIN25
00321 #undef LLVM_COMMA_JOIN26
00322 #undef LLVM_COMMA_JOIN27
00323 #undef LLVM_COMMA_JOIN28
00324 #undef LLVM_COMMA_JOIN29
00325 #undef LLVM_COMMA_JOIN30
00326 #undef LLVM_COMMA_JOIN31
00327 #undef LLVM_COMMA_JOIN32
00328 
00329 } // end namespace llvm
00330 
00331 #endif  // LLVM_ADT_VARIADICFUNCTION_H