1 // { dg-options "-std=gnu++0x" }
2 
3 #define ONE
4 #define TWO
5 #define THREE
6 
7 struct Something {};
8 Something ___;
9 
10 template <class F>
11 struct Trial
12 {
13  F f;
14 public:
TrialTrial15  Trial() : f() {}
TrialTrial16  Trial( const F& ff ) : f(ff) { }
17  template <typename... Args>
18  struct Sig { typedef int ResultType; };
19 
20  template <typename... Args>
21  struct Sig<Something,Args...> { typedef int ResultType;  };
22 
23 #ifdef ONE
24 
25 template <typename... Args>
26 typename Sig<Something,Args...>::ResultType operator()(const Something& s, const Args&... args) const
27 {
28  return f(args...);
29 }
30 #endif
31 #ifdef TWO
32 template <typename... Args>
33 typename Sig<Args...>::ResultType operator()(const Args&... args) const
34 {
35  return f(args...);
36 }
37 #endif
38 };
39 
40 struct Internal
41 {
42 
43 template <typename... Args>
44 struct Sig { typedef int ResultType; };
45 
46 template <typename... Args>
47 struct Sig<Something,Args...> { typedef int ResultType;  };
48 
49 template <typename... Args>
50 int operator()(const Args&... args) const
51 {
52  int n = sizeof...(Args);
53  return n;
54 }
55 
56  static Trial<Internal>& full() { static Trial<Internal> f; return f; }
57 };
58 
59 static Trial<Internal>& internal = Internal::full();
60 
61 int main()
62 {
63  int n = 0;
64 #ifdef ONE
65  n = internal(___,1,2);
66 #endif
67 #ifdef THREE
68  n = internal(___,1,2,3);
69  n = internal(___,1,2,3,4);
70 #endif
71  return 0;
72 }
73