opdecls.hh

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

Generated on Thu Apr 15 20:13:13 2004 for Olena by doxygen 1.3.6-20040222