aimstil  5.0.5
TExprBasicFunctors.h
Go to the documentation of this file.
1 #ifndef TIL_TEXPR_NUMERICAL_FUNCTORS_H
2 #define TIL_TEXPR_NUMERICAL_FUNCTORS_H
3 
6 
7 // includes from STL
8 #include <functional>
9 #include <cmath>
10 
11 // includes from BOOST
12 #include "boost/type_traits.hpp"
13 #include "boost/call_traits.hpp"
14 
15 // includes from TIL
16 #include "til/cat2type.h"
17 #include "til/functors.h"
18 #include "til/labels.h"
19 
20 
21 namespace til { namespace expr { namespace functor {
22 
23  //--------------------------------------------------------------------------------------------
24 
25  //-----------------------//
26  // DetemplateOperator1 //
27  //-----------------------//
28 
38  // NB: the use of "operator" is to emphasize this functor should be
39  // stateless.
40  template < template <typename> class TOperator >
41  struct DetemplateOperator1 : public detemplated_functor_label
42  {
43  template < typename T, typename TUnused = T > struct TypeStruct
44  {
45  typedef typename TOperator<T>::result_type Type;
46  };
47 
48  template < typename T >
49  //typename boost::enable_if<
50  // boost::is_same<typename TOperator<T>::argument_type, T>
51  // ,
52  typename TOperator<T>::result_type
53  //>::type
54  operator()(const T & x) const
55  {
56  return TOperator<T>()(x);
57  }
58 
59 
60  template < typename T >
61  //typename boost::enable_if_c<
62  //boost::is_same<typename TOperator<T>::first_argument_type, T>::value
63  //&& boost::is_same<typename TOperator<T>::second_argument_type, const T &>::value
64  //,
65  typename TOperator<T>::result_type
66  //>::type
67  //operator()(const T & x, const T & y) const
68  operator()(const T & x, const T & y) const
69  {
70  return TOperator<T>()(x,y);
71  }
72 
73  /*
75  template < typename T >
76  //typename boost::enable_if_c<
77  //boost::is_same<typename TOperator<T>::first_argument_type, T&>::value
78  //&& boost::is_same<typename TOperator<T>::second_argument_type, T>::value
79  //,
80  typename TOperator<T>::result_type
81  //>::type
82  operator()(T & x, const T & y) const
83  {
84  return TOperator<T>()(x,y);
85  }
86  */
87  };
88 
89  //--------------------------------------------------------------------------------------------
90 
91  //-----------------------------//
92  // DetemplateAssignOperator1 //
93  //-----------------------------//
94 
96  template < template <typename> class TOperator >
97  struct DetemplateAssignOperator1 : public detemplated_functor_label
98  {
99  template < typename T, typename TUnused = T > struct TypeStruct
100  {
101  typedef typename TOperator<T>::result_type Type;
102  };
103 
104  template < typename T >
105  //typename boost::enable_if_c<
106  //boost::is_same<typename TOperator<T>::first_argument_type, T&>::value
107  //&& boost::is_same<typename TOperator<T>::second_argument_type, T>::value
108  //,
109  typename TOperator<T>::result_type
110  //>::type
111  operator()(T & x, const T & y) const
112  {
113  return TOperator<T>()(x,y);
114  }
115 
116  };
117 
118  //--------------------------------------------------------------------------------------------
119 
120  //-----------------------//
121  // DetemplateOperator2 //
122  //-----------------------//
123 
124 
127  template < template <typename, typename> class TOperator >
128  struct DetemplateOperator2 : public detemplated_functor_label
129  {
130  template < typename T1, typename T2 > struct TypeStruct
131  {
132  typedef typename TOperator<T1,T2>::result_type Type;
133  };
134 
135  template < typename T1, typename T2 >
136  //typename boost::enable_if_c<
137  //boost::is_same<typename TOperator<T1,T2>::first_argument_type, T1>::value &&
138  //boost::is_same<typename TOperator<T1,T2>::second_argument_type, T2>::value
139  // ,
140  typename TOperator<T1,T2>::result_type
141  //>::type
142  operator()(const T1 & x, const T2 & y) const
143  {
144  return TOperator<T1,T2>()(x,y);
145  }
146 
147  template < typename T1, typename T2 >
148  typename TOperator<T1,T2>::result_type
149  operator()(T1 & x, const T2 & y) const
150  {
151  return TOperator<T1,T2>()(x,y);
152  }
153  };
154 
155 
156  //--------------------------------------------------------------------------------------------
157 
158  //----------------//
159  // DefaultThird //
160  //----------------//
161 
162 
166  template < template <typename,typename,typename> class T >
168  {
169  template < typename T1, typename T2 >
170  struct type : public T<T1,T2,typename combine<T1,T2>::type> {};
171  };
172 
173 
174  //--------------------------------------------------------------------------------------------
175 
176  //------------------------------------//
177  // Detemplated functor declarations //
178  //------------------------------------//
179 
183 
184  /*
185  typedef DetemplateOperator2<til::functor::Add> Plus;
186  typedef DetemplateOperator2<til::functor::Sub> Minus;
187  typedef DetemplateOperator2<til::functor::Mul> Multiplies;
188  typedef DetemplateOperator2<til::functor::Div> Divides;
189  */
190 
195 
196  // NB: I think this is to be used only when the functor is itself a template expression,
197  // otherwise bind should be used (obviously, since a(expr) is likely to fail).
198  // Right now the functor is passed by value, it might be a problem, I dunno.
200 
201  //typedef DetemplateOperator2<til::functor::AddTo> AddTo;
202  //typedef DetemplateOperator2<til::functor::SubTo> SubTo;
203  //typedef DetemplateOperator2<til::functor::MulTo> MulTo;
204  //typedef DetemplateOperator2<til::functor::DivTo> DivTo;
209 
211 
218 
219  //typedef DetemplateOperator1<til::functor::Assign> Assign;
222 
223 
224 
226  template < typename TTo >
227  struct Cast
228  {
229  template < typename TFrom >
230  struct TypeStruct
231  {
232  typedef TTo Type;
233  };
234 
235  template < typename TFrom > TTo operator()(TFrom a) const
236  {
237  return TTo(a);
238  }
239  };
240 
241 
242  //--------------------------------------------------------------------------------------------
243 
244  //--------//
245  // Wrap //
246  //--------//
247 
248  namespace detail
249  {
250  template < typename T, bool b >
252  { typedef typename T::result_type type; };
253 
254  template < typename T >
255  struct WrapReturnValue<T,false>
256  { typedef void type; };
257  }
258 
267  // NB: Historical notes: Wrap inherits publicly from TFunctor to solve two problems: (1) the fact that
268  // operator() cannot be templated because if TFunctor requires a non-const reference argument, it better
269  // be that way; (2), because of the first point, to avoid having to have different Wrap functions for
270  // different number of arguments (one for unary, one for binary, etc.).
271  template < typename TFunctor >
272  class Wrap : public TFunctor
273  {
274  public: // typedefs
275  template < typename T > struct TypeStruct
276  {
278  //typedef typename TFunctor::result_type Type;
279  };
280  public: // typedefs
281  Wrap(TFunctor & f) : TFunctor(f) {}
282  };
283 
284 }}} // namespace til::expr::functor
285 
286 
287 #endif
288 
DetemplateOperator1< std::not_equal_to > Not_Equal_To
TOperator< T1, T2 >::result_type operator()(T1 &x, const T2 &y) const
DetemplateOperator2< til::functor::Call > Call
DetemplateOperator2< til::functor::SubTo > SubTo
DetemplateAssignOperator1< til::functor::Assign > Assign
DetemplateOperator2< DefaultThird< til::functor::Div >::type > Divides
DetemplateOperator2< til::functor::CastTo > CastTo
TOperator< T >::result_type operator()(const T &x, const T &y) const
DetemplateOperator1< til::functor::Sqrt > Sqrt
TTo operator()(TFrom a) const
Belongs to package Box Do not include directly, include til/Box.h instead.
Definition: Accumulator.h:10
DetemplateOperator1< std::less > Less
TOperator< T >::result_type operator()(T &x, const T &y) const
DetemplateOperator2< til::functor::MulTo > MulTo
DetemplateOperator2< DefaultThird< til::functor::Add >::type > Plus
Wrap a standard functor inside a detemplated functor.
Defines empty classes that serves as labels.
DetemplateOperator1< std::greater_equal > Greater_Equal
DetemplateOperator1< til::functor::Abs > Abs
DetemplateOperator2< DefaultThird< til::functor::Sub >::type > Minus
Detemplation of assignment functors taking one template parameter.
DetemplateOperator1< std::less_equal > Less_Equal
DetemplateOperator1< std::greater > Greater
A class to "detemplate" a stateless operator with a single template argument.
DetemplateOperator1< std::negate > Negate
A class to replace the third (result) template parameter of a functor by a default value...
DetemplateOperator1< std::equal_to > Equal_To
detail::WrapReturnValue< TFunctor, has_result_type< TFunctor >::value >::type Type
A class to "detemplate" a pure functor with two template arguments.
DetemplateOperator1< til::functor::Deref > Deref
TOperator< T >::result_type operator()(const T &x) const
DetemplateOperator2< til::functor::AddTo > AddTo
TOperator< T1, T2 >::result_type operator()(const T1 &x, const T2 &y) const
DetemplateOperator2< DefaultThird< til::functor::Mul >::type > Multiplies
DetemplateOperator2< til::functor::DivTo > DivTo