opdecls.hh

Go to the documentation of this file.
00001 // Copyright (C) 2001, 2002, 2003, 2004, 2006 EPITA Research and
00002 // Development Laboratory
00003 //
00004 // This file is part of the Olena Library.  This library is free
00005 // software; you can redistribute it and/or modify it under the terms
00006 // of the GNU General Public License version 2 as published by the
00007 // Free Software Foundation.
00008 //
00009 // This library is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with this library; see the file COPYING.  If not, write to
00016 // the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017 // Boston, MA 02110-1301, USA.
00018 //
00019 // As a special exception, you may use this file as part of a free
00020 // software library without restriction.  Specifically, if other files
00021 // instantiate templates or use macros or inline functions from this
00022 // file, or you compile this file and link it with other files to
00023 // produce an executable, this file does not by itself cause the
00024 // resulting executable to be covered by the GNU General Public
00025 // License.  This exception does not however invalidate any other
00026 // reasons why the executable file might be covered by the GNU General
00027 // Public License.
00028 
00029 #ifndef OLENA_ARITH_INTERNAL_OPDECLS_HH
00030 # define OLENA_ARITH_INTERNAL_OPDECLS_HH
00031 
00056 # define oln_arith_declare_binrecval_functor_(OPNAME, OPCODE)           \
00057     template<class T1, class T2, class Ret>                             \
00058     struct f_##OPNAME : std::binary_function<const T1&,                 \
00059       const T2&,                                                        \
00060       Ret>                                                              \
00061     {                                                                   \
00062       typedef f_##OPNAME self_type;                                     \
00063       typename self_type::result_type                                   \
00064       operator()(typename self_type::first_argument_type val1,          \
00065                  typename self_type::second_argument_type val2) const   \
00066       {                                                                 \
00067         return OPCODE;                                                  \
00068       }                                                                 \
00069     };                                                                  \
00070                                                                         \
00071     template <class T1, class T2 = T1>                                  \
00072     struct default_f_##OPNAME                                           \
00073       : public f_##OPNAME< T1, T2, ntg_return_type(OPNAME, T1, T2)>     \
00074     {}  /* no ; */
00075 
00076 
00077 
00086 # define oln_arith_declare_binrecvalcst_functor_(OPNAME, OPCODE_CST)    \
00087     template<class T1, class T2, class Ret>                             \
00088      struct f_##OPNAME##_cst : std::unary_function<const T1&,           \
00089       Ret>                                                              \
00090     {                                                                   \
00091       typedef f_##OPNAME##_cst self_type;                               \
00092       f_##OPNAME##_cst(T2 cst) : cst_(cst) {}                           \
00093                                                                         \
00094       typename self_type::result_type                                   \
00095       operator()(typename self_type::argument_type val) const           \
00096       {                                                                 \
00097         return OPCODE_CST;                                              \
00098       }                                                                 \
00099     private:                                                            \
00100       T2 cst_;                                                          \
00101     } /* no ; */
00102 
00103 
00112 # define oln_arith_declare_binrecval_functors_(OPNAME, OPCODE, OPCODE_CST)      \
00113     oln_arith_declare_binrecval_functor_(OPNAME, OPCODE);                       \
00114     oln_arith_declare_binrecvalcst_functor_(OPNAME, OPCODE_CST)
00115 
00122 # define oln_arith_declare_binfixedtype_functor_(OPNAME, OPCODE, TYPE)        \
00123     struct f_##OPNAME : std::binary_function< const TYPE&, const TYPE&, TYPE> \
00124     {                                                                         \
00125       const result_type                                                       \
00126       operator()(first_argument_type val1,                                    \
00127                  second_argument_type val2) const                             \
00128       {                                                                       \
00129         return OPCODE;                                                        \
00130       }                                                                       \
00131     } /* no ; */
00132 
00139 # define oln_arith_declare_binfixedtypecst_functor_(OPNAME, OPCODE_CST, TYPE) \
00140     struct f_##OPNAME##_cst: std::unary_function<const TYPE, TYPE >          \
00141     {                                                                        \
00142       f_##OPNAME##_cst(TYPE cst) : cst_(cst) {}                              \
00143                                                                              \
00144       const result_type                                                      \
00145       operator()(argument_type val) const                                    \
00146       {                                                                      \
00147         return OPCODE_CST;                                                   \
00148       }                                                                      \
00149     private:                                                                 \
00150       TYPE cst_;                                                             \
00151     } /* no ; */
00152 
00155 # define oln_arith_declare_binfixedtype_functors_(NAME, TYPE, CODE, CODE_CST)   \
00156     oln_arith_declare_binfixedtype_functor_(NAME, CODE, TYPE);                  \
00157     oln_arith_declare_binfixedtypecst_functor_(NAME, CODE_CST, TYPE)
00158 
00160 #define default_functor_return_type_(OPNAME, I1, I2)                    \
00161   typename f_##OPNAME<oln_value_type(I1),                               \
00162                       oln_value_type(I2),                               \
00163                       ntg_return_type(OPNAME,                           \
00164                                       oln_value_type(I1),               \
00165                                       oln_value_type(I2))>::result_type
00166 
00168 #define default_functor_type_cst_(OPNAME, I1, T2)       \
00169   f_##OPNAME##_cst<oln_value_type(I1),                  \
00170                    T2,                                  \
00171                    ntg_return_type(OPNAME,              \
00172                                    oln_value_type(I1),  \
00173                                    T2)>
00174 
00176 #define default_functor_return_type_cst_(OPNAME, I1, T2)                \
00177   typename default_functor_type_cst_(OPNAME, I1, T2)::result_type
00178 
00212 # define oln_arith_declare_binop_procs_(OPNAME)                                                                 \
00213     /*                                                                                                          \
00214        FIXME: this is a workaround for an odd bug of icc and como                                               \
00215        http://www.lrde.epita.fr/cgi-bin/twiki/view/Know/MysteriousTemplateFunctionOverloadingWithIccAndComo     \
00216        Remove this traits and use its content directly when this bug gets fixed.                                \
00217     */                                                                                                          \
00218     template <class I1, class I2>                                                                               \
00219     struct arith_return_type_proxy_##OPNAME##_                                                                  \
00220     {                                                                                                           \
00221       typedef typename mute<I1, default_functor_return_type_(OPNAME, I1, I2)>::ret ret;                         \
00222     };                                                                                                          \
00223                                                                                                                 \
00224     /* Standard application of OPNAME */                                                                        \
00225     template<class I1, class I2> inline                                                                         \
00226     typename arith_return_type_proxy_##OPNAME##_<I1, I2>::ret                                                   \
00227     OPNAME(const abstract::image<I1>& input1, const abstract::image<I2>& input2)                                \
00228     {                                                                                                           \
00229       typedef oln_value_type(I1) T1;                                                                            \
00230       typedef oln_value_type(I2) T2;                                                                            \
00231       /* KLUGE: Build the functor, don't pass it as a parameter as in                                           \
00232            apply2<f_##OPNAME>(input1, input2)                                                                   \
00233          otherwise GCC 2.95.x will ICE.  */                                                                     \
00234       return apply2(f_##OPNAME<T1,                                                                              \
00235                                T2,                                                                              \
00236                                ntg_return_type(OPNAME, T1, T2)>(),                                              \
00237                     input1, input2);                                                                            \
00238     }                                                                                                           \
00239                                                                                                                 \
00240     /* Same as above, plus conversion.  */                                                                      \
00241     template<class C, class B, class I1, class I2> inline                                                       \
00242     typename mute<I1,                                                                                           \
00243       typename convoutput<C, B, default_functor_return_type_(OPNAME, I1, I2)>::ret>::ret                        \
00244     OPNAME(const convert::abstract::conversion<C, B>& conv,                                                     \
00245            const abstract::image<I1>& input1, const abstract::image<I2>& input2)                                \
00246     {                                                                                                           \
00247       typedef oln_value_type(I1) T1;                                                                            \
00248       typedef oln_value_type(I2) T2;                                                                            \
00249       return apply2(convert::compconv2(conv,                                                                    \
00250                                       f_##OPNAME<T1,                                                            \
00251                                                  T2,                                                            \
00252                                                  ntg_return_type(OPNAME, T1, T2)>()),                           \
00253                     input1, input2);                                                                            \
00254     }                                                                                                           \
00255                                                                                                                 \
00256     /* Same as above, with inline conversion in the functor. */                                                 \
00257     /* This operator has a `_with_ret' suffix for disambiguation purpose */                                     \
00258     /* (see above).  */                                                                                         \
00259     template<class IRet, class I1, class I2> inline                                                             \
00260     typename mute<I1, oln_value_type(IRet)>::ret                                                                \
00261     OPNAME##_with_ret(const abstract::image<I1>& input1, const abstract::image<I2>& input2)                     \
00262     {                                                                                                           \
00263       return apply2(f_##OPNAME<oln_value_type(I1),                                                              \
00264                                oln_value_type(I2),                                                              \
00265                                oln_value_type(IRet)>(),                                                         \
00266                     input1, input2);                                                                            \
00267     }
00268 
00269 
00271 # define oln_arith_declare_binopcst_procs_(OPNAME)                                              \
00272                                                                                                 \
00273     /* FIXME: cf explications above */                                                          \
00274     template <class I, class T>                                                                 \
00275     struct arith_return_type_proxy_cst_##OPNAME##_                                              \
00276     {                                                                                           \
00277       typedef typename mute<I, default_functor_return_type_cst_(OPNAME, I, T)>::ret ret;        \
00278     };                                                                                          \
00279                                                                                                 \
00280     template<class I, class T> inline                                                           \
00281     typename arith_return_type_proxy_cst_##OPNAME##_<I, T>::ret                                 \
00282     OPNAME##_cst(const abstract::image<I>& input, T val)                                        \
00283     {                                                                                           \
00284       typedef default_functor_type_cst_(OPNAME, I, T) functor_type;                             \
00285       return apply(functor_type(val), input);                                                   \
00286     }                                                                                           \
00287                                                                                                 \
00288     /* Same as above, plus conversion.  */                                                      \
00289     template<class C, class B, class I, class T> inline                                         \
00290     typename mute<I,                                                                            \
00291       typename convoutput<C, B, default_functor_return_type_cst_(OPNAME, I, T)>::ret>::ret      \
00292     OPNAME##_cst(const convert::abstract::conversion<C, B>& conv,                               \
00293                  const abstract::image<I>& input, T val)                                        \
00294     {                                                                                           \
00295       typedef default_functor_type_cst_(OPNAME, I, T) functor_type;                             \
00296       return apply(convert::compconv1(conv, functor_type(val)), input);                         \
00297     }                                                                                           \
00298                                                                                                 \
00299     template<class IRet, class I, class T> inline                                               \
00300     typename mute<I, oln_value_type(IRet)>::ret                                                 \
00301     OPNAME##_cst(const abstract::image<I>& input, T val)                                        \
00302     {                                                                                           \
00303       return apply(f_##OPNAME##_cst<oln_value_type(I), T, oln_value_type(IRet)>(val), input);   \
00304     }
00305 
00306 # define oln_arith_declare_all_binop_procs_(OPNAME)     \
00307     oln_arith_declare_binop_procs_(OPNAME)              \
00308     oln_arith_declare_binopcst_procs_(OPNAME)
00309 
00311 # define oln_arith_declare_nongenericbinop_procs_(OPNAME)                               \
00312     /* Standard application of OPNAME */                                                \
00313     template<class I1, class I2> inline                                                 \
00314     typename mute<I1, typename f_##OPNAME::result_type>::ret                            \
00315     OPNAME(const abstract::image<I1>& input1, const abstract::image<I2>& input2)        \
00316     {                                                                                   \
00317       return apply2<f_##OPNAME >(input1, input2);                                       \
00318     }                                                                                   \
00319                                                                                         \
00320     /* Same as above, plus conversion.  */                                              \
00321     template<class C, class B, class I1, class I2> inline                               \
00322     typename mute<I1,                                                                   \
00323       typename convoutput<C, B, typename f_##OPNAME::result_type>::ret>::ret            \
00324     OPNAME(const convert::abstract::conversion<C, B>& conv,                             \
00325            const abstract::image<I1>& input1, const abstract::image<I2>& input2)        \
00326     {                                                                                   \
00327       return apply2(convert::compconv2(conv, f_##OPNAME()),                             \
00328                     input1, input2);                                                    \
00329     }
00330 
00331 /* Same as oln_arith_declare_nongenericbinopcst_procs_ but for non
00332    template functors.  */
00333 
00335 # define oln_arith_declare_nongenericbinopcst_procs_(OPNAME)            \
00336     template<class I, class T> inline                                   \
00337     typename mute<I, typename f_##OPNAME##_cst::result_type>::ret       \
00338     OPNAME##_cst(const abstract::image<I>& input, T val)                \
00339     {                                                                   \
00340       return apply(f_##OPNAME##_cst(val), input);                       \
00341     }                                                                   \
00342                                                                         \
00343     /* Same as above, plus conversion.  */                              \
00344     template<class C, class B, class I, class T> inline                 \
00345     typename mute<I,                                                    \
00346       typename convoutput<C, B,                                         \
00347         typename f_##OPNAME##_cst::result_type>::ret>::ret              \
00348     OPNAME##_cst(const convert::abstract::conversion<C, B>& conv,       \
00349                  const abstract::image<I>& input, T val)                \
00350     {                                                                   \
00351       return apply(convert::compconv1(conv, f_##OPNAME##_cst(val)),     \
00352                    input);                                              \
00353     }
00354 
00355 /* Same as oln_arith_declare_all_nongenericbinop_procs_ but for non
00356    template functors.  */
00357 # define oln_arith_declare_all_nongenericbinop_procs_(OPNAME)   \
00358     oln_arith_declare_nongenericbinop_procs_(OPNAME)            \
00359     oln_arith_declare_nongenericbinopcst_procs_(OPNAME)
00360 
00361 /*------------------.
00362 | Unary functions.  |
00363 `------------------*/
00364 
00366 # define oln_arith_declare_unfixedtype_functor_(OPNAME, TYPE, OPCODE)   \
00367     struct f_##OPNAME : std::unary_function< const TYPE&, TYPE>         \
00368     {                                                                   \
00369       const result_type operator()(argument_type val) const             \
00370       {                                                                 \
00371         return OPCODE;                                                  \
00372       }                                                                 \
00373     } /* no ; */
00374 
00375 # define oln_arith_declare_nongenericunop_procs_(OPNAME)                                        \
00376     /* Standard application of OPNAME */                                                        \
00377     template<class I> inline                                                                    \
00378     typename mute<I, typename f_##OPNAME::result_type>::ret                                     \
00379     OPNAME(const abstract::image<I>& input1)                                                    \
00380     {                                                                                           \
00381       return apply<f_##OPNAME >(input1);                                                        \
00382     }                                                                                           \
00383                                                                                                 \
00384     /* Same as above, plus conversion.  */                                                      \
00385     template<class C, class B, class I> inline                                                  \
00386     typename mute<I,                                                                            \
00387       typename convoutput<C, B, typename f_##OPNAME::result_type>::ret>::ret                    \
00388     OPNAME(const convert::abstract::conversion<C, B>& conv, const abstract::image<I>& input1)   \
00389     {                                                                                           \
00390       return apply(convert::compconv2(conv, f_##OPNAME()), input1);                             \
00391     }
00392 
00393 # define oln_arith_declare_unop_procs_(OPNAME)                                                  \
00394     /* Standard application of OPNAME */                                                        \
00395     template<class I> inline                                                                    \
00396     typename mute<I, typename f_##OPNAME<oln_value_type(I)>::result_type>::ret                  \
00397     OPNAME(const abstract::image<I>& input1)                                                    \
00398     {                                                                                           \
00399       return apply(f_##OPNAME<oln_value_type(I)>(), input1);                                    \
00400     }                                                                                           \
00401                                                                                                 \
00402     /* Same as above, plus conversion.  */                                                      \
00403     template<class C, class B, class I> inline                                                  \
00404     typename mute<I,                                                                            \
00405       typename convoutput<C, B,                                                                 \
00406         typename f_##OPNAME<oln_value_type(I)>::result_type>::ret>::ret                         \
00407     OPNAME(const convert::abstract::conversion<C>& conv, const abstract::image<I>& input1)      \
00408     {                                                                                           \
00409       return apply(convert::compconv2(conv, f_##OPNAME<oln_value_type(I)>()), input1);          \
00410     }
00411 
00412 // FIXME: this code sounds odd and isn't used anywhere.
00413 // It should be rewritten properly if we want to keep it.
00414 # if 0
00415 
00416 /* Same as oln_arith_declare_binop_procs_, for functor parametred by
00417    a single type.  */
00418 # define oln_arith_declare_semigeneric_binop_procs_(OPNAME)                             \
00419     /* Standard application of OPNAME */                                                \
00420     template<class I1, class I2> inline                                                 \
00421     typename mute<I1,                                                                   \
00422       typename f_##OPNAME<oln_value_type(I1), oln_value_type(I1)>::result_type>::ret    \
00423     OPNAME(const abstract::image<I1>& input1, const abstract::image<I2>& input2)        \
00424     {                                                                                   \
00425       return apply2<f_##OPNAME >(input1, input2);                                       \
00426     }                                                                                   \
00427                                                                                         \
00428     /* Same as above, plus conversion.  */                                              \
00429     template<class C, class B, class I1, class I2> inline                               \
00430     typename mute<I1,                                                                   \
00431       typename convoutput<C, B,                                                         \
00432         typename f_##OPNAME<oln_value_type(I1)>::result_type>::ret>::ret                \
00433     OPNAME(const convert::abstract::conversion<C, B>& conv,                             \
00434          const abstract::image<I1>& input1, const abstract::image<I2>& input2)          \
00435     {                                                                                   \
00436       return apply2(convert::compconv2(conv, f_##OPNAME<oln_value_type(I1)>()),         \
00437                     input1, input2);                                                    \
00438     }
00439 
00440 # endif
00441 
00442 #endif // ! OLENA_ARITH_INTERNAL_OPDECLS_HH

Generated on Tue Feb 20 20:20:13 2007 for Olena by  doxygen 1.5.1