ivl 679
ivl/details/core/loops/meta/loops_meta.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_LOOPS_META_LOOPS_META
00025 #define IVL_CORE_DETAILS_LOOPS_META_LOOPS_META
00026 
00027 namespace ivl {
00028 namespace loops {
00029 
00030 template<
00031         int STEP,
00032         class F,
00033         class OUT,
00034         class IN,
00035         class O_OPTIMAL_ACCESS,
00036         class I_OPTIMAL_ACCESS,
00037         class O_SPECIALIZED,
00038         class I_SPECIALIZED,
00039         class O_ITER_1 = types::term,
00040         class I_ITER_1 = types::term,
00041         class O_ITER_2 = types::term,
00042         class I_ITER_2 = types::term
00043 >
00044 struct loop_base { };
00045 
00046 // find the output iterator
00047 template<
00048         class F, class A1, class A2,
00049         class O_OPTIMAL_ACCESS, class I_OPTIMAL_ACCESS,
00050         class I_SPECIALIZED
00051 >
00052 struct loop_base<1, F, A1, A2,
00053         O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00054         types::t_false, I_SPECIALIZED,
00055         types::term, types::term,
00056         types::term, types::term>
00057 :
00058 public loop_base<2, F, A1, A2,
00059         O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00060         types::t_false, I_SPECIALIZED,
00061         typename A1::iterator, types::term,
00062         types::term, types::term>
00063 { };
00064 
00065 // find the input iterator
00066 template<
00067         class F, class A1, class A2,
00068         class O_OPTIMAL_ACCESS, class I_OPTIMAL_ACCESS, class O_ITER_1
00069 >
00070 struct loop_base<2, F, A1, A2,
00071         O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00072         types::t_false, types::t_false,
00073         O_ITER_1, types::term,
00074         types::term, types::term>
00075 :
00076 public loop_base<3, F, A1, A2,
00077         O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00078         types::t_false, types::t_false,
00079         O_ITER_1, typename types::best_iterator<A2>::type,
00080         types::term, types::term>
00081 { };
00082 
00083 // -- specialized iterators
00084 
00085 
00086 // case of output iterator being specialized
00087 template<
00088         class F, class A1, class A2,
00089         class O_OPTIMAL_ACCESS, class I_OPTIMAL_ACCESS,
00090         int O_SPECIALIZED, class I_SPECIALIZED
00091 >
00092 struct loop_base<1, F, A1, A2,
00093         O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00094         ivl::types::number<O_SPECIALIZED>, I_SPECIALIZED,
00095         types::term, types::term,
00096         types::term, types::term>
00097 {
00098         static
00099         inline
00100         void exec(A1& out, A2& in)
00101         {
00102                 using namespace ivl::types;
00103 
00104                 if(out.iter_specialization() == O_SPECIALIZED) {
00105                         loop_base<2, F, A1, A2,
00106                                 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00107                                 t_false, I_SPECIALIZED,
00108                                 typename types::best_iterator<A1, O_SPECIALIZED>::type, term,
00109                                 term, term>::exec(out, in);
00110                 }
00111                 else {
00112                         loop_base<1, F, A1, A2,
00113                                 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00114                                 typename t_if<t_expr<O_SPECIALIZED == 1>,
00115                                         t_false, number<O_SPECIALIZED - 1> >::type, I_SPECIALIZED,
00116                                 term, term, term, term>::exec(out, in);
00117                 }
00118         }
00119 };
00120 
00121 // case of input iterator being specialized
00122 template<
00123         class F, class A1, class A2,
00124         class O_OPTIMAL_ACCESS, class I_OPTIMAL_ACCESS,
00125         int I_SPECIALIZED, class O_ITER_1
00126 >
00127 struct loop_base<2, F, A1, A2,
00128         O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00129         types::t_false, types::number<I_SPECIALIZED>,
00130         O_ITER_1, types::term,
00131         types::term, types::term>
00132 {
00133         static
00134         inline
00135         void exec(A1& out, A2& in)
00136         {
00137                 using namespace ivl::types;
00138 
00139                 if(in.iter_specialization() == I_SPECIALIZED) {
00140                         loop_base<3, F, A1, A2,
00141                                 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00142                                 t_false, t_false,
00143                                 O_ITER_1, typename types::
00144                                         best_iterator<A2, I_SPECIALIZED>::type,
00145                                 term, term>::exec(out, in);
00146                 }
00147                 else {
00148                         loop_base<2, F, A1, A2,
00149                                 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00150                                 t_false, typename t_if<t_expr<I_SPECIALIZED == 1>,
00151                                         t_false, number<I_SPECIALIZED - 1> >::type,
00152                                 O_ITER_1, term, term, term>::exec(out, in);
00153                 }
00154         }
00155 };
00156 
00157 // cases depending on optimal access
00158 
00159 template<
00160         class F, class A1, class A2,
00161         class O_ITER_1, class I_ITER_1
00162 >
00163 struct loop_base<3,F, A1, A2,
00164         ivl::data::seq_optimal_tag, ivl::data::seq_optimal_tag,
00165         types::t_false, types::t_false,
00166         O_ITER_1, I_ITER_1, types::term, types::term>
00167 {
00168         static inline
00169         void exec(A1& out, A2& in);
00170 };
00171 
00172 template<
00173         class F, class A1, class A2,
00174         class O_ITER_1, class I_ITER_1
00175 >
00176 struct loop_base<3, F, A1, A2,
00177         ivl::data::random_optimal_tag, ivl::data::random_optimal_tag,
00178         types::t_false, types::t_false,
00179         O_ITER_1, I_ITER_1, types::term, types::term>
00180 {
00181         static inline
00182         void exec(A1& out, A2& in);
00183 };
00184 
00185 template<
00186         class F, class A1, class A2,
00187         class O_OPTIMAL_ACCESS, class I_OPTIMAL_ACCESS,
00188         class O_ITER_1, class I_ITER_1
00189 >
00190 struct loop_base<3, F, A1, A2,
00191         O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00192         types::t_false, types::t_false,
00193         O_ITER_1, I_ITER_1, types::term, types::term>
00194 : public
00195         loop_base<3, F, A1, A2,
00196         ivl::data::seq_optimal_tag, ivl::data::seq_optimal_tag,
00197         types::t_false, types::t_false,
00198         O_ITER_1, I_ITER_1, types::term, types::term>
00199 { };
00200 
00201 } /* namespace loops */
00202 } /* namespace ivl */
00203 
00204 #endif // IVL_CORE_DETAILS_LOOPS_META_LOOPS_META
 All Classes Namespaces Files Functions Variables Typedefs Enumerations