1// PR ipa/63587
2// { dg-do compile { target c++11 } }
3// { dg-options "-O2" }
4
5namespace boost {
6class basic_cstring
7{
8public:
9  basic_cstring (char *);
10};
11template <typename> struct identity
12{
13};
14struct make_identity;
15struct function_buffer
16{
17};
18template <typename FunctionObj> struct function_obj_invoker0
19{
20  static int
21  invoke (function_buffer &)
22  {
23    FunctionObj f;
24    f ();
25  }
26};
27template <typename FunctionObj> struct get_function_obj_invoker0
28{
29  typedef function_obj_invoker0<FunctionObj> type;
30};
31template <typename FunctionObj> struct apply
32{
33  typedef typename get_function_obj_invoker0<FunctionObj>::type invoker_type;
34};
35struct basic_vtable0
36{
37  typedef int (*invoker_type)(function_buffer &);
38  template <typename F> void assign_to (F, function_buffer);
39  invoker_type invoker;
40};
41class function0
42{
43public:
44  template <typename Functor> function0 (Functor)
45  {
46    typedef typename apply<Functor>::invoker_type invoker_type;
47    basic_vtable0 stored_vtable { invoker_type::invoke };
48    stored_vtable.assign_to (0, functor);
49  }
50  function_buffer functor;
51};
52class function : function0
53{
54public:
55  template <typename Functor> function (Functor f) : function0 (f) {}
56};
57class test_unit_generator
58{
59};
60class test_case
61{
62public:
63  test_case (basic_cstring, basic_cstring, int, function);
64};
65struct auto_test_unit_registrar
66{
67  auto_test_unit_registrar (test_unit_generator);
68};
69template <typename F> F unwrap (F, int);
70struct for_each_impl
71{
72  template <typename Iterator, typename LastIterator, typename TransformFunc,
73	    typename F>
74  static void
75  execute (Iterator, LastIterator, TransformFunc, F f)
76  {
77    identity<char> __trans_tmp_1;
78    unwrap (f, 0)(__trans_tmp_1);
79  }
80};
81template <typename, typename, typename F>
82void
83for_each (F f)
84{
85  for_each_impl::execute (0, 0, 0, f);
86}
87template <typename TestCaseTemplate> class test_case_template_invoker
88{
89public:
90  void operator()()
91  {
92    TestCaseTemplate::run (0);
93  }
94};
95template <typename Generator, typename TestCaseTemplate>
96struct generate_test_case_4_type
97{
98  generate_test_case_4_type (basic_cstring, basic_cstring, int, Generator G)
99    : m_test_case_name (0), m_test_case_file (0), m_holder (G)
100  {
101  }
102  template <typename TestType> void operator()(identity<TestType>)
103  {
104    test_case (0, 0, 0, test_case_template_invoker<TestCaseTemplate> ());
105  }
106  basic_cstring m_test_case_name;
107  basic_cstring m_test_case_file;
108  Generator m_holder;
109};
110template <typename TestCaseTemplate>
111class template_test_case_gen : public test_unit_generator
112{
113public:
114  template_test_case_gen (basic_cstring, basic_cstring, int)
115  {
116    for_each<int, make_identity> (
117      generate_test_case_4_type<template_test_case_gen, TestCaseTemplate> (
118	0, 0, 0, *this));
119  }
120};
121class attribute_name
122{
123  int m_id;
124
125public:
126  attribute_name (char);
127};
128template <typename> struct term;
129namespace exprns_ {
130template <typename> struct expr;
131}
132using exprns_::expr;
133template <typename T> struct Trans_NS_proto_terminal
134{
135  typedef expr<term<T> > type;
136};
137namespace exprns_ {
138template <typename Arg0> struct expr<term<Arg0> >
139{
140  Arg0 child0;
141};
142}
143template <typename Expr> struct actor
144{
145  typename Trans_NS_proto_terminal<Expr>::type proto_expr_;
146};
147template <template <typename> class Actor = actor> struct terminal
148{
149  typedef Actor<int> type;
150};
151namespace log {
152struct to_log_fun
153{
154};
155class value_extractor;
156template <typename, typename = value_extractor, typename = void,
157	  template <typename> class = actor>
158class attribute_actor;
159class attribute_terminal
160{
161public:
162  attribute_name m_name;
163  attribute_name
164  get_name ()
165  {
166    return m_name;
167  }
168};
169template <typename, typename, typename, template <typename> class ActorT>
170class attribute_actor : ActorT<attribute_terminal>
171{
172public:
173  typedef int value_type;
174  attribute_name
175  get_name ()
176  {
177    return this->proto_expr_.child0.get_name ();
178  }
179};
180template <typename AttributeValueT>
181attribute_actor<AttributeValueT> attr (attribute_name);
182terminal<>::type stream;
183template <typename LeftT, typename ImplT> class attribute_output_terminal
184{
185public:
186  template <typename U>
187  attribute_output_terminal (LeftT, attribute_name, ImplT, U);
188};
189template <typename LeftT> struct make_output_expression
190{
191  typedef attribute_output_terminal<LeftT, to_log_fun> type;
192  template <typename RightT>
193  static type
194  make (LeftT left, RightT &right)
195  {
196    type (left, right.get_name (), to_log_fun (), 0);
197  }
198};
199template <typename, typename RightT, typename = typename RightT::value_type>
200struct make_output_actor;
201template <template <typename> class ActorT, typename LeftExprT,
202	  typename RightT, typename ValueT>
203struct make_output_actor<ActorT<LeftExprT>, RightT, ValueT>
204{
205  typedef make_output_expression<ActorT<LeftExprT> > make_expression;
206  typedef ActorT<typename make_expression::type> type;
207  static type
208  make (ActorT<LeftExprT> left, RightT &right)
209  {
210    type { make_expression::make (left, right) };
211  }
212};
213template <typename LeftExprT, typename T, typename FallbackPolicyT,
214	  typename TagT>
215typename make_output_actor<actor<LeftExprT>, attribute_actor<TagT> >::type
216operator<<(actor<LeftExprT> left,
217	   attribute_actor<T, FallbackPolicyT, TagT> right)
218{
219  make_output_actor<actor<LeftExprT>, attribute_actor<T> >::make (left, right);
220}
221}
222}
223namespace logging = boost::log;
224namespace expr = logging;
225namespace {
226class my_class;
227}
228template <typename> struct default_formatting
229{
230  void test_method ();
231};
232struct default_formatting_invoker
233{
234  static void
235  run (void *)
236  {
237    default_formatting<int> t;
238    t.test_method ();
239  }
240};
241boost::auto_test_unit_registrar default_formatting_registrar56 (
242  boost::template_test_case_gen<default_formatting_invoker> (0, 0, 0));
243template <typename CharT>
244void
245default_formatting<CharT>::test_method ()
246{
247  expr::stream << expr::attr<my_class> (0);
248  expr::stream << expr::attr<int> (0) << expr::attr<int> (0)
249	       << expr::attr<int> (0);
250}
251