ivl 679
ivl/details/array/impl/elem_func_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_DETAILS_ARRAY_BASE_ELEM_FUNC_PTR_HPP
00025 #define IVL_DETAILS_ARRAY_BASE_ELEM_FUNC_PTR_HPP
00026 
00027 // NOTE
00028 // TODO: remove this
00029 // Elem func ptr is a temporary class, before tup elem func is created
00030 // to support pointer to functions elem func
00031 
00032 namespace ivl {
00033 
00034 
00035 
00036 // ---------------------------------------------------------------
00037 // binary elem func result definition
00038 
00039 namespace array_details {
00040 
00041 struct bin_elem_func_ptr {};
00042 struct bin_scalar_r_ptr {};
00043 struct bin_scalar_l_ptr {};
00044 struct bin_val_func_ptr {};
00045 
00046 template <
00047         class T,
00048         template <typename, typename, typename> class F,
00049         class A1,
00050         class A2,
00051         class MATCH
00052 >
00053 struct bin_elem_func_result_ptr {};
00054 
00055 } /* namespace array_details */
00056 
00057 template <
00058         class T,
00059         template <typename, typename, typename> class F,
00060         class A1,
00061         class A2
00062 >
00063 class binary_elem_func_result_ptr
00064 {
00065         typedef typename types::t_if<
00066                 types::t_and<types::is_ivl_array<A1>, types::is_ivl_array<A2> >,
00067                         array_details::bin_elem_func_ptr,
00068                         typename types::t_if<types::is_ivl_array<A1>,
00069                                 array_details::bin_scalar_r_ptr,
00070                                         typename types::t_if<types::is_ivl_array<A2>,
00071                                                 array_details::bin_scalar_l_ptr,
00072                                                 array_details::bin_val_func_ptr>::type>::type>::type
00073                                                         match_type;
00074 public:
00075         typedef typename
00076                 array_details::bin_elem_func_result_ptr<T, F, A1, A2, match_type>
00077                 ::type type;
00078         typedef typename
00079                 array_details::bin_elem_func_result_ptr<T, F, A1, A2, match_type>
00080                 ::wrapper_type wrapper_type;
00081         typedef typename F<types::term, types::term, types::term>::ptr_t ptr_t;
00082 
00083         static inline
00084         typename array_details::bin_elem_func_result_ptr<T, F, A1, A2, match_type>
00085         ::type from(ptr_t p1, const A1& a1, const A2& a2)
00086         {
00087                 return array_details::bin_elem_func_result_ptr<T, F, A1, A2, match_type>
00088                         ::from(p1, a1, a2);
00089         }
00090 };
00091 
00092 // ---------------------------------------------------------------
00093 // unary elem func result definition
00094 
00095 // --------------------------------------------------------------------
00096 // elem func classes
00097 
00098 
00099 template <
00100         class T,
00101         template <typename, typename, typename> class F,
00102         class A1,
00103         class A2
00104 >
00105 class elem_func_binary_ptr : public
00106 
00107 //      types::change_data_class_set<
00108 //              typename data::binary_elem_func_traits<F, A1, A2, false>::
00109 //              type, typename A1::derived_type>::type
00110 
00111 array_details::binary_operator_result<
00112         typename binary_elem_func_result_ptr<T, F,
00113                 typename A1::elem_type, typename A2::elem_type>::type,
00114         A1, A2,
00115         data::binary_elem_func_ptr<F,
00116                 typename A1::derived_type, typename A2::derived_type, false>,
00117         data::binary_elem_func_ptr<F,
00118                 typename A2::derived_type, typename A1::derived_type, true> >::type
00119 
00120 {
00121 public:
00122         //typedef typename types::change_data_class_set<
00123         //      typename data::binary_elem_func_traits<F, A1, A2, false>::
00124         //      type, typename A1::derived_type>::type base_class;
00125         typedef typename array_details::binary_operator_result<
00126                 typename binary_elem_func_result_ptr<T, F,
00127                         typename A1::elem_type, typename A2::elem_type>::type,
00128                 A1, A2,
00129                 data::binary_elem_func_ptr<F,
00130                         typename A1::derived_type, typename A2::derived_type, false>,
00131                 data::binary_elem_func_ptr<F,
00132                         typename A2::derived_type, typename A1::derived_type, true> >::
00133                         type base_class;
00134 
00135         base_class& base()
00136                 { return static_cast<base_class&>(*this); }
00137         const base_class& base() const
00138                 { return static_cast<const base_class&>(*this); }
00139 
00140         typedef typename F<types::term, types::term, types::term>::ptr_t ptr_t;
00141 
00142         elem_func_binary_ptr(ptr_t p1, const A1& a1, const A2& a2)
00143         {
00144                 // sets the underlying array references, switching them if SWAP
00145                 this->setref(p1, ref1(a1.derived(), a2.derived()),
00146                                         ref2(a1.derived(), a2.derived()));
00147 
00148                 this->validate();
00149         }
00150 
00151         elem_func_binary_ptr(const elem_func_binary_ptr& a) : base_class(a) { }
00152 
00153         elem_func_binary_ptr& operator=(const elem_func_binary_ptr& o)
00154         { base_class::operator=(o); return *this; }
00155 
00156 };
00157 
00158 template <
00159         class T,
00160         template <typename, typename, typename> class F,
00161         class A1,
00162         class T2
00163 >
00164 class elem_func_scalar_r_ptr : public
00165         types::change_elem_type<typename
00166                         binary_elem_func_result_ptr<T, F,
00167                                 typename A1::elem_type, T2>::type,
00168                 typename types::change_data_class_set<
00169                 data::binary_elem_func_ptr<F, typename A1::derived_type,
00170                         typename array_details::scalar_to_array<T2,
00171                                 typename A1::derived_type>::type, false>,
00172                 typename A1::derived_type>::type>::type
00173 {
00174 public:
00175         typedef typename types::change_elem_type<typename
00176                         binary_elem_func_result_ptr<T, F,
00177                                 typename A1::elem_type, T2>::type,
00178                 typename types::change_data_class_set<
00179                 data::binary_elem_func_ptr<F, typename A1::derived_type,
00180                         typename array_details::scalar_to_array<T2,
00181                                 typename A1::derived_type>::type, false>,
00182                 typename A1::derived_type>::type>::type base_class;
00183 
00184         typedef typename F<types::term, types::term, types::term>::ptr_t ptr_t;
00185         base_class& base()
00186                 { return static_cast<base_class&>(*this); }
00187         const base_class& base() const
00188                 { return static_cast<const base_class&>(*this); }
00189 
00190         elem_func_scalar_r_ptr(ptr_t p1, const A1& a1, const T2& t2)
00191         {
00192                 this->setref(p1, a1.derived(),
00193                         typename array_details::scalar_to_array<T2,
00194                                 typename A1::derived_type>
00195                                 ::type(a1.derived().size()));
00196                 this->in2->setval(t2);
00197         }
00198 
00199         elem_func_scalar_r_ptr(const elem_func_scalar_r_ptr& a) : base_class(a) { }
00200 
00201         elem_func_scalar_r_ptr& operator=(const elem_func_scalar_r_ptr& o)
00202         { base_class::operator=(o); return *this; }
00203 
00204 };
00205 
00206 template <
00207         class T,
00208         template <typename, typename, typename> class F,
00209         class T1,
00210         class A2
00211 >
00212 class elem_func_scalar_l_ptr : public
00213         types::change_elem_type<typename
00214                         binary_elem_func_result_ptr<T, F,
00215                                 T1, typename A2::elem_type>::type,
00216                 typename types::change_data_class_set<
00217                 data::binary_elem_func_ptr<F, typename A2::derived_type,
00218                         typename array_details::scalar_to_array<T1,
00219                                 typename A2::derived_type>::type, true>,
00220                 typename A2::derived_type>::type>::type
00221 {
00222 public:
00223         typedef typename types::change_elem_type<typename
00224                         binary_elem_func_result_ptr<T, F,
00225                                 T1, typename A2::elem_type>::type,
00226                 typename types::change_data_class_set<
00227                 data::binary_elem_func_ptr<F, typename A2::derived_type,
00228                         typename array_details::scalar_to_array<T1,
00229                                 typename A2::derived_type>::type, true>,
00230                 typename A2::derived_type>::type>::type base_class;
00231         typedef typename F<types::term, types::term, types::term>::ptr_t ptr_t;
00232 
00233         base_class& base()
00234                 { return static_cast<base_class&>(*this); }
00235         const base_class& base() const
00236                 { return static_cast<const base_class&>(*this); }
00237 
00238         elem_func_scalar_l_ptr(ptr_t p1, const T1& t1, const A2& a2)
00239         {
00240                 this->setref(p1, a2.derived(),
00241                         typename array_details::scalar_to_array<T1,
00242                                 typename A2::derived_type>
00243                                 ::type(a2.derived().size()));
00244                 this->in2->setval(t1);
00245         }
00246 
00247         elem_func_scalar_l_ptr(const elem_func_scalar_l_ptr& a) : base_class(a) { }
00248 
00249         elem_func_scalar_l_ptr& operator=(const elem_func_scalar_l_ptr& o)
00250         { base_class::operator=(o); return *this; }
00251 
00252 };
00253 
00254 
00255 namespace array_details {
00256 
00257 // ---------------------------------------------------------------
00258 // binary elem func result implementation
00259 
00260 template <
00261         class T,
00262         template <typename, typename, typename> class F,
00263         class A1,
00264         class A2
00265 >
00266 struct bin_elem_func_result_ptr<T, F, A1, A2, bin_elem_func_ptr>
00267 {
00268         typedef typename elem_func_binary_ptr<T, F, A1, A2>::base_class type;
00269         typedef elem_func_binary_ptr<T, F, A1, A2> wrapper_type;
00270         typedef typename F<types::term, types::term, types::term>::ptr_t ptr_t;
00271 
00272         static inline type from(ptr_t p1, const A1& a1, const A2& a2)
00273         {
00274                 return elem_func_binary_ptr<T, F, A1, A2>(p1, a1, a2).base();
00275         }
00276 };
00277 
00278 template <
00279         class T,
00280         template <typename, typename, typename> class F,
00281         class A1,
00282         class T2
00283 >
00284 struct bin_elem_func_result_ptr<T, F, A1, T2, bin_scalar_r_ptr>
00285 {
00286         typedef typename elem_func_scalar_r_ptr<T, F, A1, T2>::base_class type;
00287         typedef elem_func_scalar_r_ptr<T, F, A1, T2> wrapper_type;
00288         typedef typename F<types::term, types::term, types::term>::ptr_t ptr_t;
00289 
00290         static inline type from(ptr_t p1, const A1& a1, const T2& a2)
00291         {
00292                 return elem_func_scalar_r_ptr<T, F, A1, T2>(p1, a1, a2).base();
00293         }
00294 };
00295 
00296 template <
00297         class T,
00298         template <typename, typename, typename> class F,
00299         class T1,
00300         class A2
00301 >
00302 struct bin_elem_func_result_ptr<T, F, T1, A2, bin_scalar_l_ptr>
00303 {
00304         typedef typename elem_func_scalar_l_ptr<T, F, T1, A2>::base_class type;
00305         typedef elem_func_scalar_l_ptr<T, F, T1, A2> wrapper_type;
00306         typedef typename F<types::term, types::term, types::term>::ptr_t ptr_t;
00307 
00308         static inline type from(ptr_t p1, const T1& a1, const A2& a2)
00309         {
00310                 return elem_func_scalar_l_ptr<T, F, T1, A2>(p1, a1, a2).base();
00311         }
00312 };
00313 
00314 template <
00315         class T,
00316         template <typename, typename, typename> class F,
00317         class T1,
00318         class T2
00319 >
00320 struct bin_elem_func_result_ptr<T, F, T1, T2, bin_val_func_ptr>
00321 {
00322         typedef T type;
00323         typedef T wrapper_type;
00324         typedef typename F<types::term, types::term, types::term>::ptr_t ptr_t;
00325 
00326         static inline T from(ptr_t p1, const T1& v1, const T2& v2)
00327         {
00328                 return F<T, T1, T2>::elem_op(p1, v1, v2);
00329         }
00330 };
00331 
00332 } /* namespace array_details */
00333 
00334 // classes that can be used directly to get an element function from one
00335 // (unary) or two (binary) classes and an element operation functor.
00336 // these two classes are wrappers for an according elem_func_binary or
00337 // elem_func_scalar_l or elem_func_scalar_r or elem_func_unary class which
00338 // is direct wrapper to an according array<.> or array_nd<.> or any
00339 // ivl container class with an elem_class data type.
00340 
00341 template<
00342         template <typename, typename, typename> class F,
00343         class A1, class A2
00344 >
00345 struct binary_elem_func_ptr : public binary_elem_func_result_ptr<
00346         typename F<types::term,
00347                 typename types::get_value<A1>::type,
00348                 typename types::get_value<A2>::type>::default_ret_type,
00349                 F, A1, A2>::wrapper_type
00350 {
00351 private:
00352         typedef typename binary_elem_func_result_ptr<
00353         typename F<types::term,
00354                 typename types::get_value<A1>::type,
00355                 typename types::get_value<A2>::type>::default_ret_type,
00356                 F, A1, A2>::wrapper_type prv_base;
00357         typedef typename F<types::term, types::term, types::term>::ptr_t ptr_t;
00358 public:
00359         template<class A, class B>
00360         binary_elem_func_ptr(ptr_t p1, const A& a1, const B& a2) : prv_base(p1, a1, a2) { }
00361 
00362         template<class T1, class T2>
00363         binary_elem_func_ptr(ivl::internal::tuple<T1, T2> a)
00364                 : prv_base(a.val(types::number<1>()), a.val(types::number<2>()), a.val(types::number<3>())) { }
00365 
00366         binary_elem_func_ptr(const binary_elem_func_ptr& a) : prv_base(a) { }
00367 
00368         binary_elem_func_ptr& operator=(const binary_elem_func_ptr& o)
00369         { prv_base::operator=(o); return *this; }
00370 };
00371 
00372 
00373 } /* namespace ivl */
00374 
00375 #endif // IVL_DETAILS_ARRAY_BASE_ELEM_FUNC_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations