LCOV - code coverage report
Current view: top level - include/llvm/ADT - VariadicFunction.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 11 11 100.0 %
Date: 2017-09-14 15:23:50 Functions: 0 0 -
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13