File: vsip/impl/fns_elementwise.hpp
    1| /* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
    2| 
    3| /** @file    vsip/impl/fns_elementwise.hpp
    4|     @author  Stefan Seefeld
    5|     @date    2005-04-21
    6|     @brief   VSIPL++ Library: [math.fns.elementwise].
    7| 
    8|     This file declares functions to be used with expression templates.
    9| */
   10| 
   11| #ifndef VSIP_IMPL_FNS_ELEMENTWISE_HPP
   12| #define VSIP_IMPL_FNS_ELEMENTWISE_HPP
   13| 
   14| /***********************************************************************
   15|   Included Files
   16| ***********************************************************************/
   17| 
   18| #include <vsip/impl/expr_functor.hpp>
   19| #include <vsip/impl/promote.hpp>
   20| #include <vsip/impl/fns_scalar.hpp>
   21| #include <vsip/impl/metaprogramming.hpp>
   22| 
   23| namespace vsip
   24| {
   25| namespace impl
   26| {
   27| 
   28| /// Macro to define a unary function on views in terms of
   29| /// its homologe on scalars.
   30| #define VSIP_IMPL_UNARY_FUNCTOR(fname)                                    \
   31| template <typename T>                                                     \
   32| struct fname##_functor                                                    \
   33| {                                                                         \
   34|   typedef T result_type;                                                  \
   35|   static char const* name() { return #fname; }                            \
   36|   static result_type apply(T t) { return fn::fname(t);}                   \
   37|   result_type operator()(T t) const { return apply(t);}                   \
   38| };
   39| 
   40| #define VSIP_IMPL_UNARY_FUNCTOR_RETN(fname, retn)                         \
   41| template <typename T>                                                     \
   42| struct fname##_functor                                                    \
   43| {                                                                         \
   44|   typedef retn result_type;                                               \
   45|   static char const* name() { return #fname; }                            \
   46|   static result_type apply(T t) { return fn::fname(t);}                   \
   47|   result_type operator()(T t) const { return apply(t);}                   \
   48| };
   49| 
   50| #define VSIP_IMPL_UNARY_DISPATCH(fname)                                   \
   51| template <typename T>                                                     \
   52| struct Dispatch_##fname :                                                 \
   53|   ITE_Type<Is_view_type<T>::value,                                        \
   54|            As_type<Unary_func_view<fname##_functor, T> >,                 \
   55|            As_type<fname##_functor<T> > >::type                           \
   56| {                                                                         \
   57| };
   58| 
   59| #define VSIP_IMPL_UNARY_FUNCTION(fname)                                   \
   60| template <typename T>                                                     \
   61| inline                                                                    \
   62| typename Dispatch_##fname<T>::result_type                                 \
   63| fname(T t) { return Dispatch_##fname<T>::apply(t);}
   64| 
   65| #define VSIP_IMPL_UNARY_FUNC(fname)                                       \
   66| VSIP_IMPL_UNARY_FUNCTOR(fname)                                            \
   67| VSIP_IMPL_UNARY_DISPATCH(fname)                                           \
   68| VSIP_IMPL_UNARY_FUNCTION(fname)
   69| 
   70| #define VSIP_IMPL_UNARY_FUNC_RETN(fname, retn)                            \
   71| VSIP_IMPL_UNARY_FUNCTOR_RETN(fname, retn)                                 \
   72| VSIP_IMPL_UNARY_DISPATCH(fname)                                           \
   73| VSIP_IMPL_UNARY_FUNCTION(fname)
   74| 
   75| // Define a unary operator. Assume the associated Dispatch 
   76| // is already defined.
   77| #define VSIP_IMPL_UNARY_OP(op, fname)                                     \
   78| template <typename T>                                                     \
   79| typename Dispatch_##fname<typename Is_view_type<T>::type>::result_type    \
   80| operator op(T t)                                                          \
   81| { return Dispatch_##fname<T>::apply(t);}
   82| 
   83| /// Macro to define a binary function on views in terms of
   84| /// its homologe on scalars.
   85| #define VSIP_IMPL_BINARY_FUNCTOR(fname)                                   \
   86| template <typename T1, typename T2>                                       \
   87| struct fname##_functor                                                    \
   88| {                                                                         \
   89|   typedef typename Promotion<T1, T2>::type result_type;                   \
   90|   static char const* name() { return #fname; }                            \
   91|   static result_type apply(T1 t1, T2 t2) { return fn::fname(t1, t2);}     \
   92|   result_type operator()(T1 t1, T2 t2) const { return apply(t1, t2);}     \
   93| };
   94| 
   95| #define VSIP_IMPL_BINARY_FUNCTOR_RETN(fname, retn)                        \
   96| template <typename T1, typename T2>                                       \
   97| struct fname##_functor                                                    \
   98| {                                                                         \
   99|   typedef retn result_type;                                               \
  100|   static char const* name() { return #fname; }                            \
  101|   static result_type apply(T1 t1, T2 t2) { return fn::fname(t1, t2);}     \
  102|   result_type operator()(T1 t1, T2 t2) const { return apply(t1, t2);}     \
  103| };
  104| 
  105| #define VSIP_IMPL_BINARY_FUNCTOR_SCALAR_RETN(fname)                       \
  106| template <typename T1, typename T2>                                       \
  107| struct fname##_functor                                                    \
  108| {                                                                         \
  109|   typedef typename Scalar_of<typename Promotion<T1, T2>::type>::type      \
  110|                 result_type;                                              \
  111|   static char const* name() { return #fname; }                            \
  112|   static result_type apply(T1 t1, T2 t2) { return fn::fname(t1, t2);}     \
  113|   result_type operator()(T1 t1, T2 t2) const { return apply(t1, t2);}     \
  114| };
  115| 
  116| #define VSIP_IMPL_BINARY_DISPATCH(fname)                                  \
  117| template <typename T1, typename T2>                                       \
  118| struct Dispatch_##fname :                                                 \
  119|   ITE_Type<Is_view_type<T1>::value || Is_view_type<T2>::value,            \
  120|            As_type<Binary_func_view<fname##_functor, T1, T2> >,           \
  121|            As_type<fname##_functor<T1, T2> > >::type                      \
  122| {                                                                         \
  123| };
  124| 
  125| // Define a dispatcher that only matches if at least one of the arguments
  126| // is a view type.
  127| #define VSIP_IMPL_BINARY_OP_DISPATCH(fname)                               \
  128| template <typename T1, typename T2,                                       \
  129|           bool P = Is_view_type<T1>::value || Is_view_type<T2>::value>    \
  130| struct Dispatch_op_##fname                                                \
  131|   : As_type<Binary_func_view<fname##_functor, T1, T2> >::type {};         \
  132| template <typename T1, typename T2>                                       \
  133| struct Dispatch_op_##fname<T1, T2, false> {};                             \
  134| 
  135| #define VSIP_IMPL_BINARY_FUNCTION(fname)                                  \
  136| template <typename T1, typename T2>                                       \
  137| inline                                                                    \
  138| typename Dispatch_##fname<T1, T2>::result_type                            \
  139| fname(T1 t1, T2 t2) { return Dispatch_##fname<T1, T2>::apply(t1, t2);}
  140| 
  141| #define VSIP_IMPL_BINARY_OPERATOR_ONE(op, fname)                          \
  142| template <typename T1, typename T2>                                       \
  143| inline                                                                    \
  144| typename Dispatch_op_##fname<T1, T2>::result_type                         \
  145| operator op(T1 t1, T2 t2) { return Dispatch_op_##fname<T1, T2>::apply(t1, t2);}
  146| 
  147| #define VSIP_IMPL_BINARY_OPERATOR_TWO(op, fname)                          \
  148| template <template <typename, typename> class View,                       \
  149|           typename T1, typename Block1, typename T2>                      \
  150| inline                                                                    \
  151| typename Dispatch_op_##fname<View<T1, Block1>, T2>::result_type           \
  152| operator op(View<T1, Block1> t1, T2 t2)                                   \
  153| { return Dispatch_op_##fname<View<T1, Block1>, T2>::apply(t1, t2);}       \
  154|                                                                           \
  155| template <template <typename, typename> class View,                       \
  156|           typename T1, typename T2, typename Block2>                      \
  157| inline                                                                    \
  158| typename Dispatch_op_##fname<T1, View<T2, Block2> >::result_type          \
  159| operator op(T1 t1, View<T2, Block2> t2)                                   \
  160| { return Dispatch_op_##fname<T1, View<T2, Block2> >::apply(t1, t2);}      \
  161|                                                                           \
  162| template <template <typename, typename> class LView,                      \
  163|           template <typename, typename> class RView,                      \
  164|           typename T1, typename Block1,                                   \
  165|           typename T2, typename Block2>                                   \
  166| inline                                                                    \
  167| typename Dispatch_op_##fname<LView<T1, Block1>,                           \
  168|                              RView<T2, Block2> >::result_type             \
  169| operator op(LView<T1, Block1> t1, RView<T2, Block2> t2)                   \
  170| { return Dispatch_op_##fname<LView<T1, Block1>,                           \
  171|                              RView<T2, Block2> >::apply(t1, t2);}
  172| 
  173| #if (defined(__GNUC__) && __GNUC__ < 4) || defined(__ghs__) || defined(__ICL)
  174| # define VSIP_IMPL_BINARY_OPERATOR(op, fname)                             \
  175| VSIP_IMPL_BINARY_OPERATOR_ONE(op, fname)
  176| #else
  177| # define VSIP_IMPL_BINARY_OPERATOR(op, fname)                             \
  178| VSIP_IMPL_BINARY_OPERATOR_TWO(op, fname)
  179| #endif
  180| 
  181| 
  182| #define VSIP_IMPL_BINARY_VIEW_FUNCTION(fname)                             \
  183| template <template <typename, typename> class V,                          \
  184|           typename T, typename B>                                         \
  185| inline                                                                    \
  186| typename Dispatch_##fname<V<T,B>, V<T,B> >::result_type                   \
  187| fname(V<T,B> t1, V<T,B> t2)                                               \
  188| { return Dispatch_##fname<V<T,B>, V<T,B> >::apply(t1, t2);}
  189| 
  190| #define VSIP_IMPL_BINARY_FUNC(fname)                                      \
  191| VSIP_IMPL_BINARY_FUNCTOR(fname)                                           \
  192| VSIP_IMPL_BINARY_DISPATCH(fname)                                          \
  193| VSIP_IMPL_BINARY_FUNCTION(fname)                                          \
  194| VSIP_IMPL_BINARY_VIEW_FUNCTION(fname)
  195| 
  196| #define VSIP_IMPL_BINARY_FUNC_RETN(fname, retn)                           \
  197| VSIP_IMPL_BINARY_FUNCTOR_RETN(fname, retn)                                \
  198| VSIP_IMPL_BINARY_DISPATCH(fname)                                          \
  199| VSIP_IMPL_BINARY_FUNCTION(fname)
  200| 
  201| #define VSIP_IMPL_BINARY_FUNC_SCALAR_RETN(fname)                          \
  202| VSIP_IMPL_BINARY_FUNCTOR_SCALAR_RETN(fname)                               \
  203| VSIP_IMPL_BINARY_DISPATCH(fname)                                          \
  204| VSIP_IMPL_BINARY_FUNCTION(fname)
  205| 
  206| #define VSIP_IMPL_BINARY_OP(op, fname)                                    \
  207| VSIP_IMPL_BINARY_OP_DISPATCH(fname)                                       \
  208| VSIP_IMPL_BINARY_OPERATOR(op, fname)
  209| 
  210| /// Macro to define a ternary function on views in terms of
  211| /// its homologe on scalars.
  212| #define VSIP_IMPL_TERNARY_FUNC(fname)                                     \
  213| template <typename T1, typename T2, typename T3>                          \
  214| struct fname##_functor                                                    \
  215| {                                                                         \
  216|   typedef typename Promotion<typename Promotion<T1, T2>::type,            \
  217|                              T3>::type result_type;                       \
  218|   static char const* name() { return #fname; }                            \
  219|   static result_type apply(T1 t1, T2 t2, T3 t3)                           \
  220|   { return fn::fname(t1, t2, t3);}                                        \
  221|   result_type operator()(T1 t1, T2 t2, T3 t3) const                       \
  222|   { return apply(t1, t2, t3);}                                            \
  223| };                                                                        \
  224|                                                                           \
  225| template <typename T1, typename T2, typename T3>                          \
  226| struct Dispatch_##fname :                                                 \
  227|   ITE_Type<Is_view_type<T1>::value ||                                     \
  228|            Is_view_type<T2>::value ||                                     \
  229|            Is_view_type<T3>::value,                                       \
  230|            As_type<Ternary_func_view<fname##_functor, T1, T2, T3> >,      \
  231|            As_type<fname##_functor<T1, T2, T3> > >::type                  \
  232| {                                                                         \
  233| };                                                                        \
  234|                                                                           \
  235| template <typename T1, typename T2, typename T3>                          \
  236| typename Dispatch_##fname<T1, T2, T3>::result_type                        \
  237| fname(T1 t1, T2 t2, T3 t3)                                                \
  238| { return Dispatch_##fname<T1, T2, T3>::apply(t1, t2, t3);}
  239| 
  240| 
  241| /***********************************************************************
  242|   Unary Functions
  243| ***********************************************************************/
  244| 
  245| VSIP_IMPL_UNARY_FUNC(acos)
  246| 
  247| template <typename T> struct arg_functor {};
  248| 
  249| template <typename T>
  250| struct arg_functor<std::complex<T> >
  251| {
  252|   typedef T result_type;
  253|   static char constname() { return "arg"; }                
  254|   static result_type apply(std::complex<T> t) { return fn::arg(t);}
  255|   result_type operator()(std::complex<T> t) const { return apply(t);}
  256| };
  257| 
  258| VSIP_IMPL_UNARY_DISPATCH(arg)
  259| VSIP_IMPL_UNARY_FUNCTION(arg)
  260| 
  261| VSIP_IMPL_UNARY_FUNC(asin)
  262| VSIP_IMPL_UNARY_FUNC(atan)
  263| VSIP_IMPL_UNARY_FUNC(bnot)
  264| VSIP_IMPL_UNARY_FUNC(ceil)
  265| VSIP_IMPL_UNARY_FUNC(conj)
  266| VSIP_IMPL_UNARY_FUNC(cos)
  267| VSIP_IMPL_UNARY_FUNC(cosh)
  268| 
  269| template <typename T>
  270| struct euler_functor
  271| {
  272|   typedef std::complex<T> result_type;
  273|   static char constname() { return "euler"; }                
  274|   static result_type apply(T t) { return fn::euler(t);}
  275|   result_type operator()(T t) const { return apply(t);}
  276| };
  277| 
  278| VSIP_IMPL_UNARY_DISPATCH(euler)
  279| VSIP_IMPL_UNARY_FUNCTION(euler)
  280| 
  281| VSIP_IMPL_UNARY_FUNC(exp)
  282| VSIP_IMPL_UNARY_FUNC(exp10)
  283| VSIP_IMPL_UNARY_FUNC(floor)
  284| 
  285| template <typename T> struct imag_functor {};
  286| 
  287| template <typename T>
  288| struct imag_functor<std::complex<T> >
  289| {
  290|   typedef T result_type;
  291|   static char constname() { return "imag"; }                
  292|   static result_type apply(std::complex<T> t) { return fn::imag(t);}
  293|   result_type operator()(std::complex<T> t) const { return apply(t);}
  294| };
  295| 
  296| VSIP_IMPL_UNARY_DISPATCH(imag)
  297| VSIP_IMPL_UNARY_FUNCTION(imag)
  298| 
  299| VSIP_IMPL_UNARY_FUNC_RETN(lnot, bool)
  300| VSIP_IMPL_UNARY_FUNC(log)
  301| VSIP_IMPL_UNARY_FUNC(log10)
  302| VSIP_IMPL_UNARY_FUNC_RETN(mag, typename impl::Scalar_of<T>::type)
  303| VSIP_IMPL_UNARY_FUNC_RETN(magsq, typename impl::Scalar_of<T>::type)
  304| VSIP_IMPL_UNARY_FUNC(neg)
  305| 
  306| template <typename T> struct real_functor {};
  307| 
  308| template <typename T>
  309| struct real_functor<std::complex<T> >
  310| {
  311|   typedef T result_type;
  312|   static char constname() { return "real"; }                
  313|   static result_type apply(std::complex<T> t) { return fn::real(t);}
  314|   result_type operator()(std::complex<T> t) const { return apply(t);}
  315| };
  316| 
  317| VSIP_IMPL_UNARY_DISPATCH(real)
  318| VSIP_IMPL_UNARY_FUNCTION(real)
  319| 
  320| VSIP_IMPL_UNARY_FUNC(recip)
  321| VSIP_IMPL_UNARY_FUNC(rsqrt)
  322| VSIP_IMPL_UNARY_FUNC(sin)
  323| VSIP_IMPL_UNARY_FUNC(sinh)
  324| VSIP_IMPL_UNARY_FUNC(sq)
  325| VSIP_IMPL_UNARY_FUNC(sqrt)
  326| VSIP_IMPL_UNARY_FUNC(tan)
  327| VSIP_IMPL_UNARY_FUNC(tanh)
  328| 
  329| VSIP_IMPL_UNARY_FUNC(impl_conj)
  330| 
  331| template <typename T>
  332| struct impl_real_functor
  333| {
  334|   typedef typename Scalar_of<T>::type result_type;
  335|   static char constname() { return "impl_real"; }                
  336|   static result_type apply(T t) { return fn::impl_real(t);}
  337|   result_type operator()(T t) const { return apply(t);}
  338| };
  339| 
  340| VSIP_IMPL_UNARY_DISPATCH(impl_real)
  341| VSIP_IMPL_UNARY_FUNCTION(impl_real)
  342| 
  343| template <typename T>
  344| struct impl_imag_functor
  345| {
  346|   typedef typename Scalar_of<T>::type result_type;
  347|   static char constname() { return "impl_imag"; }                
  348|   static result_type apply(T t) { return fn::impl_imag(t);}
  349|   result_type operator()(T t) const { return apply(t);}
  350| };
  351| 
  352| VSIP_IMPL_UNARY_DISPATCH(impl_imag)
  353| VSIP_IMPL_UNARY_FUNCTION(impl_imag)
  354| 
  355| /***********************************************************************
  356|   Binary Functions
  357| ***********************************************************************/
  358| 
  359| VSIP_IMPL_BINARY_FUNC(add)
  360| VSIP_IMPL_BINARY_FUNC(atan2)
  361| VSIP_IMPL_BINARY_FUNC(band)
  362| VSIP_IMPL_BINARY_FUNC(bor)
  363| VSIP_IMPL_BINARY_FUNC(bxor)
  364| VSIP_IMPL_BINARY_FUNC(div)
  365| VSIP_IMPL_BINARY_FUNC_RETN(eq, bool)
  366| VSIP_IMPL_BINARY_FUNC(fmod)
  367| VSIP_IMPL_BINARY_FUNC_RETN(ge, bool)
  368| VSIP_IMPL_BINARY_FUNC_RETN(gt, bool)
  369| VSIP_IMPL_BINARY_FUNC(hypot)
  370| VSIP_IMPL_BINARY_FUNC(jmul)
  371| VSIP_IMPL_BINARY_FUNC_RETN(land, bool)
  372| VSIP_IMPL_BINARY_FUNC_RETN(le, bool)
  373| VSIP_IMPL_BINARY_FUNC_RETN(lt, bool)
  374| VSIP_IMPL_BINARY_FUNC_RETN(lor, bool)
  375| VSIP_IMPL_BINARY_FUNC_RETN(lxor, bool)
  376| VSIP_IMPL_BINARY_FUNC(mul)
  377| VSIP_IMPL_BINARY_FUNC(max)
  378| VSIP_IMPL_BINARY_FUNC(maxmg)
  379| VSIP_IMPL_BINARY_FUNC_SCALAR_RETN(maxmgsq)
  380| VSIP_IMPL_BINARY_FUNC(min)
  381| VSIP_IMPL_BINARY_FUNC(minmg)
  382| VSIP_IMPL_BINARY_FUNC_SCALAR_RETN(minmgsq)
  383| VSIP_IMPL_BINARY_FUNC_RETN(ne, bool)
  384| VSIP_IMPL_BINARY_FUNC(pow)
  385| VSIP_IMPL_BINARY_FUNC(sub)
  386| 
  387| /***********************************************************************
  388|   Ternary Functions
  389| ***********************************************************************/
  390| 
  391| VSIP_IMPL_TERNARY_FUNC(am)
  392| VSIP_IMPL_TERNARY_FUNC(expoavg)
  393| VSIP_IMPL_TERNARY_FUNC(ma)
  394| VSIP_IMPL_TERNARY_FUNC(msb)
  395| VSIP_IMPL_TERNARY_FUNC(sbm)
  396| VSIP_IMPL_TERNARY_FUNC(ite)
  397| 
  398| /***********************************************************************
  399|   Unary Operators
  400| ***********************************************************************/
  401| 
  402| VSIP_IMPL_UNARY_OP(!, lnot)
  403| VSIP_IMPL_UNARY_OP(~, bnot)
  404| 
  405| /***********************************************************************
  406|   Binary Operators
  407| ***********************************************************************/
  408| 
  409| VSIP_IMPL_BINARY_OP(==, eq)
  410| VSIP_IMPL_BINARY_OP(>=, ge)
  411| VSIP_IMPL_BINARY_OP(>, gt)
  412| VSIP_IMPL_BINARY_OP(<=, le)
  413| VSIP_IMPL_BINARY_OP(<, lt)
  414| VSIP_IMPL_BINARY_OP(!=, ne)
  415| VSIP_IMPL_BINARY_OP(&&, land)
  416| VSIP_IMPL_BINARY_OP(&, band)
  417| VSIP_IMPL_BINARY_OP(||, lor)
  418| VSIP_IMPL_BINARY_OP(|, bor)
  419| 
  420| template <typename T1, typename T2>
  421| struct bxor_or_lxor_functor
  422| {
  423|   typedef typename Promotion<T1, T2>::type result_type;
  424|   static char constname() { return "bxor"; }                
  425|   static result_type apply(T1 t1, T2 t2) { return fn::bxor(t1t2);}
  426|   result_type operator()(T1 t1, T2 t2) const { return apply(t1t2);}
  427| };
  428| 
  429| template <>
  430| struct bxor_or_lxor_functor<bool, bool>
  431| {
  432|   typedef bool result_type;
  433|   static char constname() { return "lxor"; }                
  434|   static result_type apply(bool t1, bool t2) { return fn::lxor(t1t2);}
  435|   result_type operator()(bool t1, bool t2) const { return apply(t1t2);}
  436| };
  437| 
  438| VSIP_IMPL_BINARY_OP(^, bxor_or_lxor)
  439| 
  440| } // namespace vsip::impl
  441| 
  442| using impl::acos;
  443| using impl::arg;
  444| using impl::asin;
  445| using impl::atan;
  446| using impl::bnot;
  447| using impl::ceil;
  448| using impl::conj;
  449| using impl::cos;
  450| using impl::cosh;
  451| using impl::euler;
  452| using impl::exp;
  453| using impl::exp10;
  454| using impl::floor;
  455| using impl::imag;
  456| using impl::lnot;
  457| using impl::log;
  458| using impl::log10;
  459| using impl::mag;
  460| using impl::magsq;
  461| using impl::neg;
  462| using impl::real;
  463| using impl::recip;
  464| using impl::rsqrt;
  465| using impl::sin;
  466| using impl::sinh;
  467| using impl::sq;
  468| using impl::sqrt;
  469| using impl::tan;
  470| using impl::tanh;
  471| 
  472| using impl::add;
  473| using impl::atan2;
  474| using impl::band;
  475| using impl::bor;
  476| using impl::bxor;
  477| using impl::div;
  478| using impl::eq;
  479| using impl::fmod;
  480| using impl::ge;
  481| using impl::gt;
  482| using impl::hypot;
  483| using impl::jmul;
  484| using impl::land;
  485| using impl::le;
  486| using impl::lt;
  487| using impl::lor;
  488| using impl::lxor;
  489| using impl::max;
  490| using impl::maxmg;
  491| using impl::maxmgsq;
  492| using impl::min;
  493| using impl::minmg;
  494| using impl::minmgsq;
  495| using impl::mul;
  496| using impl::ne;
  497| using impl::pow;
  498| using impl::sub;
  499| 
  500| using impl::am;
  501| using impl::expoavg;
  502| using impl::ma;
  503| using impl::msb;
  504| using impl::sbm;
  505| 
  506| using impl::operator!;
  507| using impl::operator~;
  508| using impl::operator==;
  509| using impl::operator>=;
  510| using impl::operator>;
  511| using impl::operator<=;
  512| using impl::operator<;
  513| using impl::operator!=;
  514| using impl::operator&&;
  515| using impl::operator&;
  516| using impl::operator||;
  517| using impl::operator|;
  518| 
  519| // namespace vsip
  520| 
  521| #undef VSIP_IMPL_TERNARY_FUNC
  522| #undef VSIP_IMPL_BINARY_FUNC_RETN
  523| #undef VSIP_IMPL_BINARY_FUNC
  524| #undef VSIP_IMPL_UNARY_FUNC_RETN
  525| #undef VSIP_IMPL_UNARY_FUNC
  526| #undef VSIP_IMPL_BINARY_FUNCTOR_RETN
  527| #undef VSIP_IMPL_BINARY_FUNCTOR
  528| #undef VSIP_IMPL_BINARY_DISPATCH
  529| #undef VSIP_IMPL_BINARY_FUNCTION
  530| #undef VSIP_IMPL_UNARY_FUNCTOR_RETN
  531| #undef VSIP_IMPL_UNARY_FUNCTOR
  532| #undef VSIP_IMPL_UNARY_DISPATCH
  533| #undef VSIP_IMPL_UNARY_FUNCTION
  534| 
  535| #endif