ivl 679
ivl/details/core/loops/meta/loops_nd_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_ND_META
00025 #define IVL_CORE_DETAILS_LOOPS_META_LOOPS_ND_META
00026 
00027 /*
00028 * This file contains the various template structs which lead to compile-time
00029 * decision of the right loop::exec() function to be called for the requested
00030 * operands, among the available exec loops. There is also run-time decision
00031 * when SPECIALIZED ITERATORS are involved which does a recursive loop from
00032 * 1 to max specialization to check which is the correct int template argument
00033 * to provide to the loop function.
00034 * Please you are notified that the below code is not readable but complicated.
00035 * There is no essence of time wasting in the below code except from the little
00036 * overhead of the specialized iterator decision and the lost compiled time, so
00037 * no optimizations or changes are predicted for that code.
00038 * A little hint for the code wanna understander for that code is that the
00039 * number which is the first template argument of loop_base is the step in
00040 * which the decision process is at. step 1 resolves the left-side (output)
00041 * iterator, step 2 the right-side (input) iterator and step 3 is ready to
00042 * find the correct specialization of loop_base to call the corresponding ::exec.
00043 */
00044 
00045 /* Todo:
00046 Missing cases! are specialized_nd x specialized_1d which are treated
00047 as specialized_nd x non_specialized_1d or they just dont work (not checked).
00048 */
00049 
00050 namespace ivl {
00051 namespace loops {
00052 
00053 template<
00054         int STEP,
00055         class F,
00056         class OUT,
00057         class IN,
00058         class O_OPTIMAL_ACCESS,
00059         class I_OPTIMAL_ACCESS,
00060         class O_SPECIALIZED,
00061         class I_SPECIALIZED,
00062         class O_ITER_1 = types::term,
00063         class I_ITER_1 = types::term,
00064         class O_ITER_2 = types::term,
00065         class I_ITER_2 = types::term
00066 >
00067 struct loop_base_nd { };
00068 
00069 // retrieve type for the output iterator if no specialization
00070 template<
00071         class F, class A1, class A2,
00072         class I_OPTIMAL_ACCESS, class ANY
00073 >
00074 struct loop_base_nd<1, F, A1, A2,
00075         ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS,
00076         types::t_false, ANY,
00077         types::term, types::term,
00078         types::term, types::term>
00079 :
00080 public loop_base_nd<2, F, A1, A2,
00081         ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS,
00082         types::t_false, ANY,
00083         typename A1::_fast_iterator_nd, types::term,
00084         typename A1::_fast_iterator_nd, types::term>
00085 { };
00086 
00087 template<
00088         class F, class A1, class A2,
00089         class O_OPTIMAL_ACCESS, class I_OPTIMAL_ACCESS, class ANY
00090 >
00091 struct loop_base_nd<1, F, A1, A2,
00092         O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00093         types::t_false, ANY,
00094         types::term, types::term,
00095         types::term, types::term>
00096 :
00097 public loop_base_nd<2, F, A1, A2,
00098         O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00099         types::t_false, ANY,
00100         typename A1::iterator, types::term,
00101         types::term, types::term>
00102 { };
00103 /*
00104 // state proceed after specialization has completed.
00105 template<
00106         class F, class A1, class A2,
00107         class O_OPTIMAL_ACCESS, class I_OPTIMAL_ACCESS, class ANY,
00108         class O_ITER_1, class O_ITER_2
00109 >
00110 struct loop_base_nd<11, F, A1, A2,
00111         O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00112         types::t_false, ANY,
00113         O_ITER_1, types::term,
00114         O_ITER_2, types::term>
00115 :
00116 public loop_base_nd<2, F, A1, A2,
00117         O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00118         types::t_false, ANY,
00119         O_ITER_1, types::term,
00120         O_ITER_2, types::term>
00121 { };
00122 */
00123 
00124 // retrieve type for the input iterator if no specialization
00125 template<
00126         class F, class A1, class A2,
00127         class O_OPTIMAL_ACCESS, class ANY,
00128         class O_ITER_1, class O_ITER_2
00129 >
00130 struct loop_base_nd<2, F, A1, A2,
00131         O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag,
00132         ANY, types::t_false,
00133         O_ITER_1, types::term,
00134         O_ITER_2, types::term>
00135 :
00136 public loop_base_nd<3, F, A1, A2,
00137         O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag,
00138         ANY, types::t_false,
00139         O_ITER_1, typename types::best_fast_iterator_nd<A2>::type,
00140         O_ITER_2, typename types::best_fast_iterator_nd<A2>::type>
00141 { };
00142 
00143 template<
00144         class F, class A1, class A2,
00145         class O_OPTIMAL_ACCESS, class I_OPTIMAL_ACCESS, class ANY,
00146         class O_ITER_1, class O_ITER_2
00147 >
00148 struct loop_base_nd<2, F, A1, A2,
00149         O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00150         ANY, types::t_false,
00151         O_ITER_1, types::term,
00152         O_ITER_2, types::term>
00153 :
00154 public loop_base_nd<3, F, A1, A2,
00155         O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00156         ANY, types::t_false,
00157         O_ITER_1, typename types::best_iterator<A2>::type,
00158         O_ITER_2, types::term>
00159 {
00160 };
00161 /*
00162 // state proceed after specialization has succeeded
00163 template<
00164         class F, class A1, class A2,
00165         class O_OPTIMAL_ACCESS, class I_OPTIMAL_ACCESS, class ANY,
00166         class O_ITER_1, class O_ITER_2,
00167         class I_ITER_1, class I_ITER_2
00168 >
00169 struct loop_base_nd<21, F, A1, A2,
00170         O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00171         ANY, types::t_false,
00172         O_ITER_1, I_ITER_1,
00173         O_ITER_2, I_ITER_2>
00174 :
00175 public loop_base_nd<3, F, A1, A2,
00176         O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00177         ANY, types::t_false,
00178         O_ITER_1, I_ITER_1,
00179         O_ITER_2, I_ITER_2>
00180 { };
00181 */
00182 // specialization cases are included in files in_specialized.hpp and
00183 // out_specialized.hpp
00184 
00185 // cases depending on optimal access
00186 
00188 template<
00189         class F, class A1, class A2,
00190         class O_ITER_1, class I_ITER_1, class O_ITER_2, class I_ITER_2
00191 >
00192 struct loop_base_nd<3, F, A1, A2,
00193         ivl::data::nd_seq_optimal_tag, ivl::data::nd_seq_optimal_tag,
00194         types::t_false, types::t_false,
00195         O_ITER_1, I_ITER_1, O_ITER_2, I_ITER_2>
00196 {
00197         static inline
00198         void exec(A1& out, A2& in,
00199                 int inner_dim_1, int inner_dim_2);
00200 };
00201 
00203 template<
00204         class F, class A1, class A2,
00205         class O_OPTIMAL_ACCESS,
00206         class O_ITER_1, class I_ITER_1, class I_ITER_2
00207 >
00208 struct loop_base_nd<3, F, A1, A2,
00209         O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag,
00210         types::t_false, types::t_false,
00211         O_ITER_1, I_ITER_1, types::term, I_ITER_2>
00212 {
00213         static inline
00214         void exec(A1& out, A2& in,
00215                 int inner_dim_1, int inner_dim_2);
00216 };
00217 
00219 template<
00220         class F, class A1, class A2,
00221         class I_OPTIMAL_ACCESS,
00222         class O_ITER_1, class I_ITER_1, class O_ITER_2
00223 >
00224 struct loop_base_nd<3, F, A1, A2,
00225         ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS,
00226         types::t_false, types::t_false,
00227         O_ITER_1, I_ITER_1, O_ITER_2, types::term>
00228 {
00229         static inline
00230         void exec(A1& out, A2& in,
00231                 int inner_dim_1, int inner_dim_2);
00232 };
00233 
00235 template<
00236         class F, class A1, class A2,
00237         class O_OPTIMAL_ACCESS, class I_OPTIMAL_ACCESS,
00238         class O_ITER_1, class I_ITER_1
00239 >
00240 struct loop_base_nd<3, F, A1, A2,
00241         O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00242         types::t_false, types::t_false,
00243         O_ITER_1, I_ITER_1, types::term, types::term>
00244 {
00245         static inline
00246         void exec(A1& out, const A2& in,
00247                 int inner_dim_1, int inner_dim_2)
00248                 {
00249                         ivl::loops::loop<F>(out.base(), in.base());
00250                 }
00251 };
00252 
00253 
00254 } /* namespace loops */
00255 } /* namespace ivl */
00256 
00257 #endif // IVL_CORE_DETAILS_LOOPS_META_LOOPS_ND_META
 All Classes Namespaces Files Functions Variables Typedefs Enumerations