ivl 679
ivl/details/core/loops/meta/in_specialized.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_IN_SPECIALIZED
00025 #define IVL_CORE_DETAILS_LOOPS_META_IN_SPECIALIZED
00026 
00027 namespace ivl {
00028 namespace loops {
00029 
00030 // cancellation of all in_specialized. used for debugging or
00031 // desperation purposes
00032 #if 0
00033 // case (cancellation) of seq_nd being specialized
00034 template<
00035         class F, class A1, class A2,
00036         class O_OPTIMAL_ACCESS,
00037         int I_SPECIALIZED, class O_ITER_1, class O_ITER_2
00038 >
00039 struct loop_base_nd<2, F, A1, A2,
00040         O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag,
00041         types::t_false, types::number<I_SPECIALIZED>,
00042         O_ITER_1, types::term,
00043         O_ITER_2, types::term>
00044 :
00045 public loop_base_nd<3, F, A1, A2,
00046         O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag,
00047         types::t_false, types::t_false,
00048         O_ITER_1, typename types::best_fast_iterator_nd<A2>::type,
00049         O_ITER_2, typename types::best_fast_iterator_nd<A2>::type>
00050 { };
00051 
00052 // case (cancellation) of seq being specialized
00053 template<
00054         class F, class A1, class A2,
00055         class O_OPTIMAL_ACCESS, class I_OPTIMAL_ACCESS,
00056         int I_SPECIALIZED, class O_ITER_1, class O_ITER_2
00057 >
00058 struct loop_base_nd<2, F, A1, A2,
00059         O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00060         types::t_false, types::number<I_SPECIALIZED>,
00061         O_ITER_1, types::term,
00062         O_ITER_2, types::term>
00063 :
00064 public loop_base_nd<3, F, A1, A2,
00065         O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00066         types::t_false, types::t_false,
00067         O_ITER_1, typename A2::types::best_iterator<A2>::type,
00068         O_ITER_2, types::term>
00069 { };
00070 
00071 #else
00072 
00073 // --- first case : not nd ---------------------------------------
00074 
00075 // case of input seq iterator being specialized
00076 template<
00077         class F, class A1, class A2,
00078         class O_OPTIMAL_ACCESS, class I_OPTIMAL_ACCESS,
00079         int I_SPECIALIZED, class O_ITER_1, class O_ITER_2
00080 >
00081 struct loop_base_nd<2, F, A1, A2,
00082         O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00083         types::t_false, types::number<I_SPECIALIZED>,
00084         O_ITER_1, types::term,
00085         O_ITER_2, types::term>
00086 {
00087         static
00088         inline
00089         void exec(A1& out, A2& in,
00090                 int inner_dim_1, int inner_dim_2)
00091         {
00092                 using namespace ivl::types;
00093 
00094                 if(in.iter_specialization() == I_SPECIALIZED) {
00095                         loop_base_nd<3, F, A1, A2,
00096                                 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00097                                 t_false, t_false,
00098                                 O_ITER_1, typename
00099                                         types::best_fast_iterator_nd<A2, I_SPECIALIZED>::type,
00100                                 term, term>::exec(out, in, inner_dim_1, inner_dim_2);
00101                 }
00102                 else {
00103                         loop_base_nd<2, F, A1, A2,
00104                                 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00105                                 t_false, number<I_SPECIALIZED - 1>,
00106                                 O_ITER_1, term, term, term
00107                                 >::exec(out, in, inner_dim_1, inner_dim_2);
00108                 }
00109         }
00110 };
00111 
00112 // case (post-specialization) of input seq iterator being specialized
00113 template<
00114         class F, class A1, class A2,
00115         class O_OPTIMAL_ACCESS, class I_OPTIMAL_ACCESS,
00116         class O_ITER_1, class O_ITER_2
00117 >
00118 struct loop_base_nd<2, F, A1, A2,
00119         O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00120         types::t_false, types::number<0>,
00121         O_ITER_1, types::term,
00122         O_ITER_2, types::term>
00123 :
00124 public loop_base_nd<3, F, A1, A2,
00125         O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS,
00126         types::t_false, types::t_false,
00127         O_ITER_1, typename types::best_iterator<A2>::type,
00128         O_ITER_2, types::term>
00129 { };
00130 
00131 // --- seq_nd -----------------------------------------------------
00132 
00133 // case (detection) of input seq_nd iterator being specialized
00134 
00135 // subcase 1: both iterators still unknown
00136 template<
00137         class F, class A1, class A2,
00138         class O_OPTIMAL_ACCESS,
00139         int I_SPECIALIZED,
00140         class O_ITER_1,
00141         class O_ITER_2
00142 >
00143 struct loop_base_nd<21, F, A1, A2,
00144         O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag,
00145         types::t_false, ivl::types::number<I_SPECIALIZED>,
00146         O_ITER_1, types::term,
00147         O_ITER_2, types::term>
00148 {
00149         static
00150         inline
00151         void exec(A1& out, A2& in,
00152                 int inner_dim_1, int inner_dim_2)
00153         {
00154                 using namespace ivl::types;
00155 
00156                 if(in.iter_specialization_nd(inner_dim_1) == I_SPECIALIZED
00157                 && in.iter_specialization_nd(inner_dim_2) == I_SPECIALIZED) {
00158                         loop_base_nd<3, F, A1, A2,
00159                                 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag,
00160                                 t_false, t_false,
00161                                 O_ITER_1, typename
00162                                         types::best_fast_iterator_nd<A2, I_SPECIALIZED>::type,
00163                                 O_ITER_2, typename
00164                                         types::best_fast_iterator_nd<A2, I_SPECIALIZED>::type
00165                                 >::exec(out, in, inner_dim_1, inner_dim_2);
00166                 }
00167                 else if(in.iter_specialization_nd(inner_dim_1) == I_SPECIALIZED
00168                 && in.iter_specialization_nd(inner_dim_2) != I_SPECIALIZED) {
00169                         loop_base_nd<21, F, A1, A2,
00170                                 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag,
00171                                 t_false, number<I_SPECIALIZED - 1>,
00172                                 O_ITER_1, typename
00173                                         types::best_fast_iterator_nd<A2, I_SPECIALIZED>::type,
00174                                 O_ITER_2, term
00175                                 >::exec(out, in, inner_dim_1, inner_dim_2);
00176                 }
00177                 else if(in.iter_specialization_nd(inner_dim_1) != I_SPECIALIZED
00178                 && in.iter_specialization_nd(inner_dim_2) == I_SPECIALIZED) {
00179                         loop_base_nd<21, F, A1, A2,
00180                                 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag,
00181                                 t_false, number<I_SPECIALIZED - 1>,
00182                                 O_ITER_1, term,
00183                                 O_ITER_2, typename
00184                                         types::best_fast_iterator_nd<A2, I_SPECIALIZED>::type
00185                                 >::exec(out, in, inner_dim_1, inner_dim_2);
00186                 }
00187                 else {
00188                         loop_base_nd<21, F, A1, A2,
00189                                 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag,
00190                                 t_false, number<I_SPECIALIZED - 1>,
00191                                 O_ITER_1, term, O_ITER_2, term>::
00192                                         exec(out, in, inner_dim_1, inner_dim_2);
00193                 }
00194         }
00195 };
00196 
00197 // subcase 2: iterator 1 still unknown
00198 template<
00199         class F, class A1, class A2,
00200         class O_OPTIMAL_ACCESS,
00201         int I_SPECIALIZED,
00202         class O_ITER_1,
00203         class O_ITER_2, class I_ITER_2
00204 >
00205 struct loop_base_nd<21, F, A1, A2,
00206         O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag,
00207         types::t_false, ivl::types::number<I_SPECIALIZED>,
00208         O_ITER_1, types::term,
00209         O_ITER_2, I_ITER_2>
00210 {
00211         static
00212         inline
00213         void exec(A1& out, A2& in,
00214                 int inner_dim_1, int inner_dim_2)
00215         {
00216                 using namespace ivl::types;
00217 
00218                 if(in.iter_specialization_nd(inner_dim_1) == I_SPECIALIZED) {
00219                         loop_base_nd<3, F, A1, A2,
00220                                 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag,
00221                                 t_false, t_false,
00222                                 O_ITER_1, typename
00223                                         types::best_fast_iterator_nd<A2, I_SPECIALIZED>::type,
00224                                 O_ITER_2, I_ITER_2
00225                                 >::exec(out, in, inner_dim_1, inner_dim_2);
00226                 }
00227                 else {
00228                         loop_base_nd<21, F, A1, A2,
00229                                 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag,
00230                                 t_false, number<I_SPECIALIZED - 1>,
00231                                 O_ITER_1, term, O_ITER_2, I_ITER_2>::
00232                                         exec(out, in, inner_dim_1, inner_dim_2);
00233                 }
00234         }
00235 };
00236 
00237 // subcase 2: iterator 2 still unknown
00238 template<
00239         class F, class A1, class A2,
00240         class O_OPTIMAL_ACCESS,
00241         int I_SPECIALIZED,
00242         class O_ITER_1, class I_ITER_1,
00243         class O_ITER_2
00244 >
00245 struct loop_base_nd<21, F, A1, A2,
00246         O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag,
00247         types::t_false, ivl::types::number<I_SPECIALIZED>,
00248         O_ITER_1, I_ITER_1,
00249         O_ITER_2, types::term>
00250 {
00251         static
00252         inline
00253         void exec(A1& out, A2& in,
00254                 int inner_dim_1, int inner_dim_2)
00255         {
00256                 using namespace ivl::types;
00257 
00258                 if(in.iter_specialization_nd(inner_dim_2) == I_SPECIALIZED) {
00259                         loop_base_nd<3, F, A1, A2,
00260                                 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag,
00261                                 t_false, t_false,
00262                                 O_ITER_1, I_ITER_1,
00263                                 O_ITER_2, typename
00264                                         types::best_fast_iterator_nd<A2, I_SPECIALIZED>::type
00265                                 >::exec(out, in, inner_dim_1, inner_dim_2);
00266                 }
00267                 else {
00268                         loop_base_nd<21, F, A1, A2,
00269                                 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag,
00270                                 t_false, number<I_SPECIALIZED - 1>,
00271                                 O_ITER_1, I_ITER_1, O_ITER_2, term>::
00272                                         exec(out, in, inner_dim_1, inner_dim_2);
00273                 }
00274         }
00275 };
00276 
00277 
00278 // post-specialization fill-up of unspecialized nd_iterators with default
00279 
00280 template<
00281         class F, class A1, class A2,
00282         class O_OPTIMAL_ACCESS,
00283         class O_ITER_1,
00284         class O_ITER_2, class I_ITER_2
00285 >
00286 struct loop_base_nd<21, F, A1, A2,
00287         O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag,
00288         types::t_false, ivl::types::number<0>,
00289         O_ITER_1, types::term,
00290         O_ITER_2, I_ITER_2>
00291 :
00292 public loop_base_nd<3, F, A1, A2,
00293         O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag,
00294         types::t_false, types::t_false,
00295         O_ITER_1, typename types::best_fast_iterator_nd<A2>::type,
00296         O_ITER_2, I_ITER_2>
00297 { };
00298 
00299 template<
00300         class F, class A1, class A2,
00301         class O_OPTIMAL_ACCESS,
00302         class O_ITER_1, class I_ITER_1,
00303         class O_ITER_2
00304 >
00305 struct loop_base_nd<21, F, A1, A2,
00306         O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag,
00307         types::t_false, ivl::types::number<0>,
00308         O_ITER_1, I_ITER_1,
00309         O_ITER_2, types::term>
00310 :
00311 public loop_base_nd<3, F, A1, A2,
00312         O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag,
00313         types::t_false, types::t_false,
00314         O_ITER_1, I_ITER_1,
00315         O_ITER_2, typename types::best_fast_iterator_nd<A2>::type
00316 >
00317 { };
00318 
00319 template<
00320         class F, class A1, class A2,
00321         class O_OPTIMAL_ACCESS,
00322         class O_ITER_1,
00323         class O_ITER_2
00324 >
00325 struct loop_base_nd<21, F, A1, A2,
00326         O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag,
00327         types::t_false, ivl::types::number<0>,
00328         O_ITER_1, types::term,
00329         O_ITER_2, types::term>
00330 :
00331 public loop_base_nd<3, F, A1, A2,
00332         O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag,
00333         types::t_false, types::t_false,
00334         O_ITER_1, typename types::best_fast_iterator_nd<A2>::type,
00335         O_ITER_2, typename types::best_fast_iterator_nd<A2>::type>
00336 { };
00337 
00338 // case (initialization) of input seq_nd iterator being specialized
00339 template<
00340         class F, class A1, class A2,
00341         class O_OPTIMAL_ACCESS,
00342         int I_SPECIALIZED,
00343         class O_ITER_1, class O_ITER_2
00344 >
00345 struct loop_base_nd<2, F, A1, A2,
00346         O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag,
00347         types::t_false, ivl::types::number<I_SPECIALIZED>,
00348         O_ITER_1, types::term,
00349         O_ITER_2, types::term>
00350 :
00351 public loop_base_nd<21, F, A1, A2,
00352         O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag,
00353         types::t_false, ivl::types::number<I_SPECIALIZED>,
00354         O_ITER_1, types::term,
00355         O_ITER_2, types::term>
00356 { };
00357 
00358 #endif // end of cancellation selection branch
00359 
00360 } /* namespace loops */
00361 } /* namespace ivl */
00362 
00363 #endif // IVL_CORE_DETAILS_LOOPS_META_IN_SPECIALIZED
 All Classes Namespaces Files Functions Variables Typedefs Enumerations