libqi-api  2.8.7.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
bindtype.hxx
Go to the documentation of this file.
1 #pragma once
2 /*
3 ** Copyright (C) 2013, 2014 Aldebaran Robotics
4 ** See COPYING for the license
5 */
6 
7 #ifndef _QITYPE_DETAIL_BINDTYPE_HXX_
8 #define _QITYPE_DETAIL_BINDTYPE_HXX_
9 
10 #include <boost/mpl/find_if.hpp>
11 #include <boost/mpl/vector.hpp>
12 #include <boost/mpl/at.hpp>
13 #include <boost/mpl/placeholders.hpp>
14 #include <boost/mpl/max_element.hpp>
15 #include <boost/mpl/transform.hpp>
16 #include <boost/function_types/parameter_types.hpp>
17 #include <boost/function_types/function_type.hpp>
18 #include <boost/function_types/function_pointer.hpp>
19 #include <boost/bind.hpp>
20 #include <boost/any.hpp>
21 
22 namespace qi
23 {
24  namespace detail
25  {
26  // Support stuff for boost_bind_function_type
27 
28  class ignore{};
29 
30  // Just store an int and a type
31  template<int I, typename P>
32  struct MappingItem {};
33 
34  // IntFromMappingItem: Extract int from MappingItem or something else
35 
36  template<typename T>
38  {
39  static const long value = 0;
40  };
41 
42  template<int I, typename P>
44  {
45  static const long value = I;
46  };
47 
48 
49  // ArgResolver: Take a function, an index, and a boost::_bi::list element
50  // return ignore, or a MappingItem
51 
52  template<typename F, int P, typename bilistarg>
53  struct ArgResolver
54  {
55  };
56 
57  template<typename F, int P, typename V>
58  struct ArgResolver<F, P, boost::_bi::value<V> >
59  {
60  using type = ignore;
61  };
62 
63  template<typename F, int P, int I>
64  struct ArgResolver<F, P, boost::arg<I> >
65  {
66  using type = MappingItem<I,
67  typename boost::mpl::at_c<
68  typename boost::function_types::parameter_types<F>::type,
69  P
70  >::type
71  >;
72  };
73 
74 
75  // ArgLess: Index comparison between MappingItems
76 
77  template<typename A, typename B>
78  struct ArgLess
79  {
80  using type = boost::true_type;
81  };
82 
83  template<typename A, int I, typename B>
84  struct ArgLess<A, MappingItem<I, B> >
85  {
86  using type = boost::true_type;
87  };
88 
89  template<typename A, int I, typename B>
90  struct ArgLess<MappingItem<I, B>, A>
91  {
92  using type = boost::false_type;
93  };
94 
95  template<int I1, typename V1, int I2, typename V2>
96  struct ArgLess<MappingItem<I1, V1>, MappingItem<I2, V2> >
97  {
98  using type = typename boost::mpl::less<boost::mpl::long_<I1>, boost::mpl::long_<I2> >::type;
99  };
100 
101 
102  // MapItemIndexIs: By-index MappingItem find helper
103 
104  template<typename A, typename B>
105  struct MapItemIndexIs
106  {
107  using type = boost::false_type;
108  };
109 
110  template<typename T, int B>
111  struct MapItemIndexIs<MappingItem<B, T>, boost::mpl::long_<B> >
112  {
113  using type = boost::true_type;
114  };
115 
116 
117  // ReorderMapping: Reorder a sequence of MappingItems by their id
118 
119  template<int I, typename Map>
121  {
122  using type = typename boost::mpl::push_back<
123  typename ReorderMapping<I-1, Map>::type,
124  typename boost::mpl::deref<typename boost::mpl::find_if<
125  Map,
126  MapItemIndexIs<boost::mpl::_1, boost::mpl::long_<I> >
127  >::type
129  };
130 
131  template<typename Map>
132  struct ReorderMapping<1, Map>
133  {
134  using type = boost::mpl::vector<
135  typename boost::mpl::deref<typename boost::mpl::find_if<
136  Map,
137  MapItemIndexIs<boost::mpl::_1, boost::mpl::long_<1> >
139  };
140 
141  template<typename Map>
142  struct ReorderMapping<0, Map>
143  {
144  using type = boost::mpl::vector<>;
145  };
146 
147 
148  // MappingToType: get type of MappingItem, or boost::any
149 
150  template<typename T>
152  {
153  using type = boost::any;
154  };
155 
156  template<typename T, int I>
157  struct MappingToType<MappingItem<I, T> >
158  {
159  using type = T;
160  };
161 
162 
163  // MappingBuilder: Invoke ArgResolver on all elements of a sequence
164 
165  template<int idx, typename F, typename V>
167  {
168  using type = typename boost::mpl::push_back<
169  typename MappingBuilder<idx - 1, F, V>::type,
172  };
173 
174  template<typename F, typename V>
175  struct MappingBuilder<0, F, V>
176  {
177  using type = typename boost::mpl::vector<
179  >;
180  };
181 
182  template<typename F, typename S>
184  {
186  };
187 
188  template<typename T> struct BilistToSeq
189  {
190  using type = boost::mpl::vector<>;
191  };
192 
193  template<typename P1>
194  struct BilistToSeq<boost::_bi::list1<P1> >
195  {
196  using type = typename boost::mpl::vector<P1>;
197  };
198 
199  template<typename P1, typename P2>
200  struct BilistToSeq<boost::_bi::list2<P1, P2> >
201  {
202  using type = typename boost::mpl::vector<P1, P2>;
203  };
204 
205  template<typename P1, typename P2, typename P3>
206  struct BilistToSeq<boost::_bi::list3<P1, P2, P3> >
207  {
208  using type = typename boost::mpl::vector<P1, P2, P3>;
209  };
210 
211  template<typename P1, typename P2, typename P3, typename P4>
212  struct BilistToSeq<boost::_bi::list4<P1, P2, P3, P4> >
213  {
214  using type = typename boost::mpl::vector<P1, P2, P3, P4>;
215  };
216 
217  template<typename P1, typename P2, typename P3, typename P4, typename P5>
218  struct BilistToSeq<boost::_bi::list5<P1, P2, P3, P4, P5> >
219  {
220  using type = typename boost::mpl::vector<P1, P2, P3, P4, P5>;
221  };
222 
223  template<typename F, typename BL>
225  {
226  using BLSeq = typename BilistToSeq<BL>::type;
228  // Mapping is a vector of nothing or pair<index, type>
229  // Get max value
230  using MaxArg = typename boost::mpl::deref<typename boost::mpl::max_element<Mapping, ArgLess<boost::mpl::_1, boost::mpl::_2> >::type>::type;
231  // Reorder it
233  //using Reordered = typename Reorder<Mapping, MaxArg>::type;
234  // Replace MappingItem with the type, and void with any
235  using type = typename boost::mpl::transform<Reordered, MappingToType<boost::mpl::_1> >::type;
236  };
237  }
238 
239  template<typename T> struct boost_bind_result_type {};
240  template<typename R, typename A, typename B>
241  struct boost_bind_result_type<boost::_bi::bind_t<R, A, B> >
242  {
243  using type = R;
244  };
245 
246  template<typename T> struct boost_bind_parameter_types {};
247  template<typename R, typename F, typename B>
248  struct boost_bind_parameter_types<boost::_bi::bind_t<R, F, B> >
249  {
250  using type = typename detail::parameter_types<F, B>::type;
251  };
252 
256  template<typename T> struct boost_bind_function_type
257  {
258  using type = typename boost::function_types::function_type<
259  typename boost::mpl::push_front<
262  >::type
264  using pointer_type = typename boost::function_types::function_pointer<
265  typename boost::mpl::push_front<
268  >::type
270  };
271 }
272 
273 #endif // _QITYPE_DETAIL_BINDTYPE_HXX_
typename boost::mpl::push_back< typename MappingBuilder< idx-1, F, V >::type, typename ArgResolver< F, idx, typename boost::mpl::at_c< V, idx >::type >::type >::type type
Definition: bindtype.hxx:171
typename boost::function_types::function_type< typename boost::mpl::push_front< typename boost_bind_parameter_types< T >::type, typename boost_bind_result_type< T >::type >::type >::type type
Definition: bindtype.hxx:263
typename parameter_types_from_bilist_seq< F, BLSeq >::type Mapping
Definition: bindtype.hxx:227
typename boost::mpl::deref< typename boost::mpl::max_element< Mapping, ArgLess< boost::mpl::_1, boost::mpl::_2 > >::type >::type MaxArg
Definition: bindtype.hxx:230
static const long value
Definition: bindtype.hxx:39
typename ReorderMapping< IntFromMappingItem< MaxArg >::value, Mapping >::type Reordered
Definition: bindtype.hxx:232
typename MappingBuilder< boost::mpl::size< S >::type::value-1, F, S >::type type
Definition: bindtype.hxx:185
typename boost::mpl::transform< Reordered, MappingToType< boost::mpl::_1 > >::type type
Definition: bindtype.hxx:235
typename boost::mpl::push_back< typename ReorderMapping< I-1, Map >::type, typename boost::mpl::deref< typename boost::mpl::find_if< Map, MapItemIndexIs< boost::mpl::_1, boost::mpl::long_< I > > >::type >::type >::type type
Definition: bindtype.hxx:128
typename boost::mpl::vector< typename ArgResolver< F, 0, typename boost::mpl::at_c< V, 0 >::type >::type > type
Definition: bindtype.hxx:179
boost::mpl::vector< typename boost::mpl::deref< typename boost::mpl::find_if< Map, MapItemIndexIs< boost::mpl::_1, boost::mpl::long_< 1 > > >::type >::type > type
Definition: bindtype.hxx:138
typename BilistToSeq< BL >::type BLSeq
Definition: bindtype.hxx:226
typename boost::function_types::function_pointer< typename boost::mpl::push_front< typename boost_bind_parameter_types< T >::type, typename boost_bind_result_type< T >::type >::type >::type pointer_type
Definition: bindtype.hxx:269