1 ////////////////////////////////////////////////////////////////////////////
2 // lazy_signature.hpp
3 //
4 // Build signature structs for Phoenix equivalents for FC++
5 // which are located in lazy_prelude.hpp
6 //
7 // These are not direct equivalents of the Boost FC++ structs.
8 // This file has to be included after lazy_list.hpp
9 //
10 // Implemented so far:
11 //
12 //   RTEFH    == ReturnTypeEnumFromHelper    (used in enum_from, enum_from_to)
13 //   RTFD     == ReturnTypeFunctionDelay     (used in repeat)
14 //   RTFFX    == ReturnTypeFunctoidFwithX     (used in thunk1)
15 //   RTFFXY   == ReturnTypeFunctoidFwithXandY (used in thunk2)
16 //   RTFFXYZ  == ReturnTypeFunctoidFwithXandYandZ (used in thunk3)
17 //   RTF      == ReturnTypeF                  (used in ptr_to_fun0)
18 //   RTFX     == ReturnTypeFwithX          (used in ptr_to_fun, ptr_to_mem_fun)
19 //   RTFXY    == ReturnTypeFwithXandY      (used in ptr_to_fun, ptr_to_mem_fun)
20 //   RTFXYZ   == ReturnTypeFwithXandYandZ  (used in ptr_to_fun, ptr_to_mem_fun)
21 //   RTFWXYZ  == ReturnTypeFwithWandXandYandZ (used in ptr_to_fun)
22 //   RTFGHX   == ReturnTypeFandGandHwithX    (used in compose)
23 //   RTFGHXY  == ReturnTypeFandGandHwithXY   (used in compose)
24 //   RTFGHXYZ == ReturnTypeFandGandHwithXYZ  (used in compose)
25 //   RTFGX    == ReturnTypeFandGwithX        (used in compose)
26 //   RTFGXY   == ReturnTypeFandGwithXY       (used in compose)
27 //   RTFGXYZ  == ReturnTypeFandGwithXYZ      (used in compose)
28 //   RTFL     == ReturnTypeFunctionList      (used in map)
29 //   RTAB     == ReturnTypeListAListB        (used in zip)
30 //   RTZAB    == ReturnTypeZipListAListB     (used in zip_with)
31 //
32 ////////////////////////////////////////////////////////////////////////////
33 /*=============================================================================
34     Copyright (c) 2000-2003 Brian McNamara and Yannis Smaragdakis
35     Copyright (c) 2001-2007 Joel de Guzman
36     Copyright (c) 2015 John Fletcher
37 
38     Distributed under the Boost Software License, Version 1.0. (See accompanying
39     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
40 ==============================================================================*/
41 
42 #ifndef BOOST_PHOENIX_FUNCTION_LAZY_SIGNATURE
43 #define BOOST_PHOENIX_FUNCTION_LAZY_SIGNATURE
44 
45 namespace boost {
46 
47   namespace phoenix {
48 
49     namespace impl {
50 
51       //template <class T> struct remove_RC; in lazy_operator.hpp
52 
53       // RTEFH == ReturnTypeEnumFromHelper
54       template <class T>
55       struct RTEFH
56       {
57           typedef typename UseList::template List<T>::type LType;
58           typedef typename result_of::ListType<LType>::
59                            delay_result_type type;
60       };
61 
62       // RTFD == ReturnTypeFunctionDelay (used in repeat)
63       template <class T>
64       struct RTFD {
65           typedef typename remove_RC<T>::type TTT;
66           typedef typename UseList::template List<TTT>::type LType;
67           typedef typename result_of::ListType<LType>::
68                            delay_result_type type;
69       };
70 
71 
72       //   RTFFX   == ReturnTypeFunctoidFwithX   (used in thunk1)
73       template <class F,class X>
74       struct RTFFX {
75           typedef typename remove_RC<F>::type FType;
76           typedef typename remove_RC<X>::type XType;
77           typedef typename boost::result_of<FType(XType)>::type FR;
78           typedef typename boost::result_of<FR()>::type RR;
79           typedef typename remove_RC<RR>::type RType;
80           typedef RType type;
81       };
82 
83       //   RTFFXY   == ReturnTypeFunctoidFwithXandY   (used in thunk2)
84       template <class F,class X,class Y>
85       struct RTFFXY {
86           typedef typename remove_RC<F>::type FType;
87           typedef typename remove_RC<X>::type XType;
88           typedef typename remove_RC<Y>::type YType;
89           typedef typename boost::result_of<FType(XType,YType)>::type FR;
90           typedef typename boost::result_of<FR()>::type RR;
91           typedef typename remove_RC<RR>::type RType;
92           typedef RType type;
93       };
94 
95       //   RTFFXYZ  == ReturnTypeFunctoidFwithXandYandZ  (used in thunk3)
96       template <class F,class X,class Y,class Z>
97       struct RTFFXYZ {
98           typedef typename remove_RC<F>::type FType;
99           typedef typename remove_RC<X>::type XType;
100           typedef typename remove_RC<Y>::type YType;
101           typedef typename remove_RC<Z>::type ZType;
102           typedef typename boost::result_of<FType(XType,YType,ZType)>::type FR;
103           typedef typename boost::result_of<FR()>::type RR;
104           typedef typename remove_RC<RR>::type RType;
105           typedef RType type;
106       };
107 
108       //   RTF   == ReturnTypeF     (used in ptr_to_fun0)
109       template <class F>
110       struct RTF {
111           typedef typename remove_RC<F>::type FType;
112           typedef typename boost::result_of<FType()>::type FR;
113           typedef typename remove_RC<FR>::type RType;
114           typedef RType type;
115       };
116 
117       //   RTFX   == ReturnTypeFwithX     (used in ptr_to_fun)
118       template <class F,class X>
119       struct RTFX {
120           typedef typename remove_RC<F>::type FType;
121           typedef typename remove_RC<X>::type XType;
122           typedef typename boost::result_of<FType(XType)>::type FR;
123           typedef typename remove_RC<FR>::type RType;
124           typedef RType type;
125       };
126 
127       //   RTFXY  == ReturnTypeFwithXandY     (used in ptr_to_fun)
128       template <class F,class X,class Y>
129       struct RTFXY {
130           typedef typename remove_RC<F>::type FType;
131           typedef typename remove_RC<X>::type XType;
132           typedef typename remove_RC<Y>::type YType;
133           typedef typename boost::result_of<FType(XType,YType)>::type FR;
134           typedef typename remove_RC<FR>::type RType;
135           typedef RType type;
136       };
137 
138       //   RTFXYZ  == ReturnTypeFwithXandYandZ  (used in ptr_to_fun)
139       template <class F,class X,class Y,class Z>
140       struct RTFXYZ {
141           typedef typename remove_RC<F>::type FType;
142           typedef typename remove_RC<X>::type XType;
143           typedef typename remove_RC<Y>::type YType;
144           typedef typename remove_RC<Z>::type ZType;
145           typedef typename boost::result_of<FType(XType,YType,ZType)>::type FR;
146           typedef typename remove_RC<FR>::type RType;
147           typedef RType type;
148       };
149 
150       //   RTFWXYZ  == ReturnTypeFwithWandXandYandZ  (used in ptr_to_fun)
151       template <class F,class W,class X,class Y,class Z>
152       struct RTFWXYZ {
153           typedef typename remove_RC<F>::type FType;
154           typedef typename remove_RC<W>::type WType;
155           typedef typename remove_RC<X>::type XType;
156           typedef typename remove_RC<Y>::type YType;
157           typedef typename remove_RC<Z>::type ZType;
158           typedef typename boost::result_of<FType(WType,XType,YType,ZType)>::
159                   type FR;
160           typedef typename remove_RC<FR>::type RType;
161           typedef RType type;
162       };
163 
164       //   RTFGHX  == ReturnTypeFandGandHwithX (used in compose)
165       template <class F,class G,class H,class X>
166       struct RTFGHX {
167           typedef typename remove_RC<F>::type FType;
168           typedef typename remove_RC<G>::type GType;
169           typedef typename remove_RC<H>::type HType;
170           typedef typename remove_RC<X>::type XType;
171           typedef typename boost::result_of<GType(XType)>::type GR;
172           typedef typename boost::result_of<GR()>::type GRR;
173           typedef typename remove_RC<GRR>::type GRType;
174           typedef typename boost::result_of<HType(XType)>::type HR;
175           typedef typename boost::result_of<HR()>::type HRR;
176           typedef typename remove_RC<HRR>::type HRType;
177           typedef typename boost::result_of<FType(GRType,HRType)>::type FR;
178           typedef typename boost::result_of<FR()>::type RR;
179           typedef typename remove_RC<RR>::type RType;
180           typedef RType type;
181       };
182 
183       //   RTFGHXY == ReturnTypeFandGandHwithXY (used in compose)
184       template <class F,class G,class H,class X,class Y>
185       struct RTFGHXY {
186           typedef typename remove_RC<F>::type FType;
187           typedef typename remove_RC<G>::type GType;
188           typedef typename remove_RC<H>::type HType;
189           typedef typename remove_RC<X>::type XType;
190           typedef typename remove_RC<Y>::type YType;
191           typedef typename boost::result_of<GType(XType,YType)>::type GR;
192           typedef typename boost::result_of<GR()>::type GRR;
193           typedef typename remove_RC<GRR>::type GRType;
194           typedef typename boost::result_of<HType(XType,YType)>::type HR;
195           typedef typename boost::result_of<HR()>::type HRR;
196           typedef typename remove_RC<HRR>::type HRType;
197           typedef typename boost::result_of<FType(GRType,HRType)>::type FR;
198           typedef typename boost::result_of<FR()>::type RR;
199           typedef typename remove_RC<RR>::type RType;
200           typedef RType type;
201       };
202 
203       //   RTFGHXYZ == ReturnTypeFandGandHwithXYZ (used in compose)
204       template <class F,class G,class H,class X,class Y,class Z>
205       struct RTFGHXYZ {
206           typedef typename remove_RC<F>::type FType;
207           typedef typename remove_RC<G>::type GType;
208           typedef typename remove_RC<H>::type HType;
209           typedef typename remove_RC<X>::type XType;
210           typedef typename remove_RC<Y>::type YType;
211           typedef typename remove_RC<Z>::type ZType;
212           typedef typename boost::result_of<GType(XType,YType,ZType)>::type GR;
213           typedef typename boost::result_of<GR()>::type GRR;
214           typedef typename remove_RC<GRR>::type GRType;
215           typedef typename boost::result_of<HType(XType,YType,ZType)>::type HR;
216           typedef typename boost::result_of<HR()>::type HRR;
217           typedef typename remove_RC<HRR>::type HRType;
218           typedef typename boost::result_of<FType(GRType,HRType)>::type FR;
219           typedef typename boost::result_of<FR()>::type RR;
220           typedef typename remove_RC<RR>::type RType;
221           typedef RType type;
222       };
223 
224       //   RTFGX   == ReturnTypeFandGwithX     (used in compose)
225       template <class F,class G,class X>
226       struct RTFGX {
227           typedef typename remove_RC<F>::type FType;
228           typedef typename remove_RC<G>::type GType;
229           typedef typename remove_RC<X>::type XType;
230           typedef typename boost::result_of<GType(XType)>::type GR;
231           typedef typename boost::result_of<GR()>::type GRR;
232           typedef typename remove_RC<GRR>::type GRType;
233           typedef typename boost::result_of<FType(GRType)>::type FR;
234           typedef typename boost::result_of<FR()>::type RR;
235           typedef typename remove_RC<RR>::type RType;
236           typedef RType type;
237       };
238 
239       //   RTFGXY  == ReturnTypeFandGwithXY    (used in compose)
240       template <class F,class G,class X,class Y>
241       struct RTFGXY {
242           typedef typename remove_RC<F>::type FType;
243           typedef typename remove_RC<G>::type GType;
244           typedef typename remove_RC<X>::type XType;
245           typedef typename remove_RC<Y>::type YType;
246           typedef typename boost::result_of<GType(XType,YType)>::type GR;
247           typedef typename boost::result_of<GR()>::type GRR;
248           typedef typename remove_RC<GRR>::type GRType;
249           typedef typename boost::result_of<FType(GRType)>::type FR;
250           typedef typename boost::result_of<FR()>::type RR;
251           typedef typename remove_RC<RR>::type RType;
252           typedef RType type;
253       };
254 
255       //   RTFGXYZ == ReturnTypeFandGwithXYZ   (used in compose)
256       template <class F,class G,class X,class Y,class Z>
257       struct RTFGXYZ {
258           typedef typename remove_RC<F>::type FType;
259           typedef typename remove_RC<G>::type GType;
260           typedef typename remove_RC<X>::type XType;
261           typedef typename remove_RC<Y>::type YType;
262           typedef typename remove_RC<Z>::type ZType;
263           typedef typename boost::result_of<GType(XType,YType,ZType)>::type GR;
264           typedef typename boost::result_of<GR()>::type GRR;
265           typedef typename remove_RC<GRR>::type GRType;
266           typedef typename boost::result_of<FType(GRType)>::type FR;
267           typedef typename boost::result_of<FR()>::type RR;
268           typedef typename remove_RC<RR>::type RType;
269           typedef RType type;
270       };
271 
272       // This is the way to make the return type for
273       // map(f,l). It is used four times in the code
274       // so I have made it a separate struct.
275       // RTFL == ReturnTypeFunctionList
276       template <class F,class L>
277       struct RTFL {
278            typedef typename remove_RC<F>::type Ftype;
279            typedef typename result_of::ListType<L>::tail_result_type
280                                    Ttype;
281            typedef typename result_of::ListType<L>::value_type Vtype;
282            // NOTE: FR is the type of the functor.
283            typedef typename boost::result_of<Ftype(Vtype)>::type FR;
284            // NOTE: RR is the type returned, which then needs
285            // reference and const removal.
286            typedef typename boost::result_of<FR()>::type RR;
287            typedef typename remove_RC<RR>::type Rtype;
288            typedef typename boost::remove_reference<L>::type LL;
289            typedef typename LL::template cons_rebind<Rtype>::delay_type
290                    type;
291       };
292 
293       // RTAB == ReturnTypeListAListB
294       template <typename LA, typename LB>
295       struct RTAB {
296                   typedef typename result_of::ListType<LA>::tail_result_type
297                                    LAtype;
298                   typedef typename result_of::ListType<LB>::tail_result_type
299                                    LBtype;
300                   typedef typename result_of::ListType<LA>::value_type VAA;
301                   typedef typename boost::remove_const<VAA>::type VAtype;
302                   typedef typename result_of::ListType<LB>::value_type VBB;
303                   typedef typename boost::remove_const<VBB>::type VBtype;
304                   typedef typename boost::result_of<Make_pair(VAtype,VBtype)>
305                                   ::type FR;
306                   typedef typename boost::result_of<FR()>::type RR;
307                   typedef typename remove_RC<RR>::type Rtype;
308                   typedef typename boost::remove_reference<LA>::type LLA;
309                   typedef typename LLA::template cons_rebind<Rtype>::type type;
310       };
311 
312 
313       // RTZAB == ReturnTypeZipListAListB
314       template <typename Z, typename LA, typename LB>
315       struct RTZAB {
316                   typedef typename remove_RC<Z>::type Ztype;
317                   typedef typename result_of::ListType<LA>::tail_result_type
318                                    LAtype;
319                   typedef typename result_of::ListType<LB>::tail_result_type
320                                    LBtype;
321                   typedef typename result_of::ListType<LA>::value_type VAtype;
322                   typedef typename result_of::ListType<LB>::value_type VBtype;
323                   typedef typename boost::result_of<Ztype(VAtype,VBtype)>::type
324                                    FR;
325                   typedef typename boost::result_of<FR()>::type RR;
326                   typedef typename remove_RC<RR>::type Rtype;
327                   typedef typename boost::remove_reference<LA>::type LLA;
328                   typedef typename LLA::template cons_rebind<Rtype>::type type;
329       };
330 
331     }
332   }
333 }
334 
335 #endif
336