ivl 679
ivl/details/core/keyword_operators/elem_ptr.hpp
00001 /* This file is part of the ivl C++ library <http://image.ntua.gr/ivl>.
00002    A C++ template library extending syntax towards mathematical notation.
00003 
00004    Copyright (C) 2012 Yannis Avrithis <iavr@image.ntua.gr>
00005    Copyright (C) 2012 Kimon Kontosis <kimonas@image.ntua.gr>
00006 
00007    ivl is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU Lesser General Public License 
00009    version 3 as published by the Free Software Foundation.
00010 
00011    Alternatively, you can redistribute it and/or modify it under the terms 
00012    of the GNU General Public License version 2 as published by the Free 
00013    Software Foundation.
00014 
00015    ivl is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00018    See the GNU General Public License for more details.
00019 
00020    You should have received a copy of the GNU General Public License 
00021    and a copy of the GNU Lesser General Public License along 
00022    with ivl. If not, see <http://www.gnu.org/licenses/>. */
00023 
00024 #ifndef IVL_CORE_DETAILS_ELEM_PTR_HPP
00025 #define IVL_CORE_DETAILS_ELEM_PTR_HPP
00026 
00027 namespace ivl {
00028 
00029 
00030 template <class RT, class X1, class X2, int COST=0 >
00031 struct binary_elem_ptr
00032 {
00033         typedef typename types::bare_type<RT>::type T;
00034         typedef RT(*ptr_type)(X1, X2);
00035 
00036         ptr_type val;
00037         binary_elem_ptr() {}
00038         binary_elem_ptr(ptr_type val) : val(val) {}
00039         binary_elem_ptr(const binary_elem_ptr& o) : val(o.val) {}
00040         binary_elem_ptr& operator=(const binary_elem_ptr& o) { val = o.val; }
00041 
00042         typedef core_details::elem_details et;
00043 
00044         template <class J, class J1, class J2>
00045         struct functor
00046         {
00047                 typedef ptr_type ptr_t;
00048                 typedef types::number<COST> cost;
00049                 static inline RT elem_op(ptr_t f, X1 x1, X2 x2)
00050                 {
00051                         return f(x1, x2);
00052                 }
00053         };
00054         /*
00055         template <class A1, class A2>
00056         typename binary_elem_func_result<T, functor, A1, A2>
00057                 ::type operator()(const A1& a1, const A2& a2)
00058         {
00059                 return binary_elem_func_result<T, functor, A1, A2>
00060                         ::from(a1, a2);
00061         }
00062         */
00063 
00064         // tuple
00065         template <class TPL>
00066         typename binary_elem_func_result_ptr<T, functor, 
00067                 typename TPL::t1, typename TPL::t2>
00068                 ::type operator[](const internal::tuple_base<2, TPL>& tpl)
00069         {
00070                 return binary_elem_func_result_ptr<T, functor, 
00071                         typename TPL::t1, typename TPL::t2>
00072                         ::from(val, tpl.derived().v1, tpl.derived().v2);
00073         }
00074         // suppose array of tuples
00075 
00076         //TODO: do something more correct like a combination
00077         // of ice2 and an elem function doing a
00078         // replacer_cast<X1, scalar<X1>
00079         // this will reach inner_type of an array as well.
00080 
00081         template <class J, class S>
00082         typename binary_elem_func_result_ptr<T, functor, 
00083 
00084                 array<typename et::check<typename J::t1, X1>::type,
00085                 data::wrap_array<
00086                 member_array<const array<J, S>, typename J::t1>,
00087                 typename et::check<typename J::t1, X1>::attr> >,
00088 
00089                 array<typename et::check<typename J::t2, X2>::type,
00090                 data::wrap_array<
00091                 member_array<const array<J, S>, typename J::t2>,
00092                 typename et::check<typename J::t2, X2>::attr> >
00093 
00094                 >
00095 
00096                 ::type operator[](const array<J, S>& a)
00097         {
00098                 
00099                 return binary_elem_func_result_ptr<T, functor,
00100 
00101                         array<typename et::check<typename J::t1, X1>::type,
00102                         data::wrap_array<
00103                         member_array<const array<J, S>, typename J::t1>,
00104                         typename et::check<typename J::t1, X1>::attr> >,
00105 
00106                         array<typename et::check<typename J::t2, X2>::type,
00107                         data::wrap_array<
00108                         member_array<const array<J, S>, typename J::t2>,
00109                         typename et::check<typename J::t2, X2>::attr> >
00110 
00111                         >::from(val,
00112                         member_array<const array<J, S>, typename J::t1>(a.in(&J::v1)), 
00113                         member_array<const array<J, S>, typename J::t2>(a.in(&J::v2)));
00114         }
00115 
00116         template <class A1, class A2>
00117         typename binary_elem_func_result_ptr<T, functor,
00118                 typename et::check_2<A1, X1>::type,
00119                 typename et::check_2<A2, X2>::type
00120         >
00121                 ::type operator()(const A1& a1, const A2& a2)
00122         {
00123                 return 
00124                         binary_elem_func_result_ptr<T, functor, 
00125                         typename et::check_2<A1, X1>::type,
00126                         typename et::check_2<A2, X2>::type
00127                 >
00128                         ::from(val, a1, a2);
00129         }
00130 
00131 };
00132 
00133 
00134 } /*namespace ivl*/
00135 
00136 #endif // IVL_CORE_DETAILS_ELEM_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations