ivl 679
|
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