ivl 679
ivl/details/core/loops/loop_ops.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_LOOP_OPS_HPP
00025 #define IVL_CORE_DETAILS_LOOP_OPS_HPP
00026 
00027 namespace ivl {
00028 namespace loops {
00029 #if 0
00030 namespace loops_details {
00031 
00032 // =, assign_copy_class
00033 template <class J, class K, class IS_ARRAY>
00034 struct assign_copy_class_details
00035 {
00036         static inline void elem_op(J elem1, K elem2)
00037         {
00038                 elem1 = elem2;
00039         };
00040 };
00041 
00042 template <class J, class K>
00043 struct assign_copy_class_details<J, K, types::t_true>
00044 {
00045         static inline void elem_op(J elem1, K elem2)
00046         {
00047                 elem1.assign(elem2);
00048         };
00049 };
00050 
00051 // +=, assign_plus_class
00052 template <class J, class K, class IS_ARRAY>
00053 struct assign_plus_class_details
00054 {
00055         static inline void elem_op(J elem1, K elem2)
00056         {
00057                 elem1 += elem2;
00058         };
00059 };
00060 
00061 template <class J, class K>
00062 struct assign_plus_class_details<J, K, types::t_true>
00063 {
00064         static inline void elem_op(J elem1, K elem2)
00065         {
00066                 elem1.plus_assign(elem2);
00067         };
00068 };
00069 
00070 // -=, assign_minus_class
00071 template <class J, class K, class IS_ARRAY>
00072 struct assign_minus_class_details
00073 {
00074         static inline void elem_op(J elem1, K elem2)
00075         {
00076                 elem1 -= elem2;
00077         };
00078 };
00079 
00080 template <class J, class K>
00081 struct assign_minus_class_details<J, K, types::t_true>
00082 {
00083         static inline void elem_op(J elem1, K elem2)
00084         {
00085                 elem1.minus_assign(elem2);
00086         };
00087 };
00088 
00089 // *=, assign_times_class
00090 template <class J, class K, class IS_ARRAY>
00091 struct assign_times_class_details
00092 {
00093         static inline void elem_op(J elem1, K elem2)
00094         {
00095                 elem1 *= elem2;
00096         };
00097 };
00098 
00099 template <class J, class K>
00100 struct assign_times_class_details<J, K, types::t_true>
00101 {
00102         static inline void elem_op(J elem1, K elem2)
00103         {
00104                 elem1.times_assign(elem2);
00105         };
00106 };
00107 
00108 // /=, assign_divide_class
00109 template <class J, class K, class IS_ARRAY>
00110 struct assign_divide_class_details
00111 {
00112         static inline void elem_op(J elem1, K elem2)
00113         {
00114                 elem1 /= elem2;
00115         };
00116 };
00117 
00118 template <class J, class K>
00119 struct assign_divide_class_details<J, K, types::t_true>
00120 {
00121         static inline void elem_op(J elem1, K elem2)
00122         {
00123                 elem1.divide_assign(elem2);
00124         };
00125 };
00126 
00127 // %=, assign_mod_class
00128 template <class J, class K, class IS_ARRAY>
00129 struct assign_mod_class_details
00130 {
00131         static inline void elem_op(J elem1, K elem2)
00132         {
00133                 elem1 %= elem2;
00134         };
00135 };
00136 
00137 template <class J, class K>
00138 struct assign_mod_class_details<J, K, types::t_true>
00139 {
00140         static inline void elem_op(J elem1, K elem2)
00141         {
00142                 elem1.mod_assign(elem2);
00143         };
00144 };
00145 
00146 // &=, assign_bitand_class
00147 template <class J, class K, class IS_ARRAY>
00148 struct assign_bitand_class_details
00149 {
00150         static inline void elem_op(J elem1, K elem2)
00151         {
00152                 elem1 &= elem2;
00153         };
00154 };
00155 
00156 template <class J, class K>
00157 struct assign_bitand_class_details<J, K, types::t_true>
00158 {
00159         static inline void elem_op(J elem1, K elem2)
00160         {
00161                 elem1.bitand_assign(elem2);
00162         };
00163 };
00164 
00165 // |=, assign_bitor_class
00166 template <class J, class K, class IS_ARRAY>
00167 struct assign_bitor_class_details
00168 {
00169         static inline void elem_op(J elem1, K elem2)
00170         {
00171                 elem1 |= elem2;
00172         };
00173 };
00174 
00175 template <class J, class K>
00176 struct assign_bitor_class_details<J, K, types::t_true>
00177 {
00178         static inline void elem_op(J elem1, K elem2)
00179         {
00180                 elem1.bitor_assign(elem2);
00181         };
00182 };
00183 
00184 // <<=, assign_bitlshift_class
00185 template <class J, class K, class IS_ARRAY>
00186 struct assign_bitlshift_class_details
00187 {
00188         static inline void elem_op(J elem1, K elem2)
00189         {
00190                 elem1 <<= elem2;
00191         };
00192 };
00193 
00194 template <class J, class K>
00195 struct assign_bitlshift_class_details<J, K, types::t_true>
00196 {
00197         static inline void elem_op(J elem1, K elem2)
00198         {
00199                 elem1.bitlshift_assign(elem2);
00200         };
00201 };
00202 
00203 // >>=, assign_bitrshift_class
00204 template <class J, class K, class IS_ARRAY>
00205 struct assign_bitrshift_class_details
00206 {
00207         static inline void elem_op(J elem1, K elem2)
00208         {
00209                 elem1 >>= elem2;
00210         };
00211 };
00212 
00213 template <class J, class K>
00214 struct assign_bitrshift_class_details<J, K, types::t_true>
00215 {
00216         static inline void elem_op(J elem1, K elem2)
00217         {
00218                 elem1.bitrshift_assign(elem2);
00219         };
00220 };
00221 
00222 // ^=, assign_bitxor_class
00223 template <class J, class K, class IS_ARRAY>
00224 struct assign_bitxor_class_details
00225 {
00226         static inline void elem_op(J elem1, K elem2)
00227         {
00228                 elem1 ^= elem2;
00229         };
00230 };
00231 
00232 template <class J, class K>
00233 struct assign_bitxor_class_details<J, K, types::t_true>
00234 {
00235         static inline void elem_op(J elem1, K elem2)
00236         {
00237                 elem1.bitxor_assign(elem2);
00238         };
00239 };
00240 
00241 } /* namespace loops_details */
00242 
00243 // =, assign_copy_class
00244 template<class J, class K>
00245 struct assign_copy_class
00246 {
00247         static inline void elem_op(J elem1, K elem2)
00248         {
00249                 return loops_details::assign_copy_class_details<J, K,
00250                         typename types::is_ivl_array<J>::type>::elem_op(elem1, elem2);
00251         };
00252 };
00253 
00254 // +=, assign_plus_class
00255 template<class J, class K>
00256 struct assign_plus_class
00257 {
00258         static inline void elem_op(J elem1, K elem2)
00259         {
00260                 return loops_details::assign_plus_class_details<J, K,
00261                         typename types::is_ivl_array<J>::type>::elem_op(elem1, elem2);
00262         };
00263 };
00264 
00265 // -=, assign_minus_class
00266 template<class J, class K>
00267 struct assign_minus_class
00268 {
00269         static inline void elem_op(J elem1, K elem2)
00270         {
00271                 return loops_details::assign_minus_class_details<J, K,
00272                         typename types::is_ivl_array<J>::type>::elem_op(elem1, elem2);
00273         };
00274 };
00275 
00276 // *=, assign_times_class
00277 template<class J, class K>
00278 struct assign_times_class
00279 {
00280         static inline void elem_op(J elem1, K elem2)
00281         {
00282                 return loops_details::assign_times_class_details<J, K,
00283                         typename types::is_ivl_array<J>::type>::elem_op(elem1, elem2);
00284         };
00285 };
00286 
00287 // /=, assign_divide_class
00288 template<class J, class K>
00289 struct assign_divide_class
00290 {
00291         static inline void elem_op(J elem1, K elem2)
00292         {
00293                 return loops_details::assign_divide_class_details<J, K,
00294                         typename types::is_ivl_array<J>::type>::elem_op(elem1, elem2);
00295         };
00296 };
00297 
00298 // %=, assign_mod_class
00299 template<class J, class K>
00300 struct assign_mod_class
00301 {
00302         static inline void elem_op(J elem1, K elem2)
00303         {
00304                 return loops_details::assign_mod_class_details<J, K,
00305                         typename types::is_ivl_array<J>::type>::elem_op(elem1, elem2);
00306         };
00307 };
00308 
00309 // &=, assign_bitand_class
00310 template<class J, class K>
00311 struct assign_bitand_class
00312 {
00313         static inline void elem_op(J elem1, K elem2)
00314         {
00315                 return loops_details::assign_bitand_class_details<J, K,
00316                         typename types::is_ivl_array<J>::type>::elem_op(elem1, elem2);
00317         };
00318 };
00319 
00320 // |=, assign_bitor_class
00321 template<class J, class K>
00322 struct assign_bitor_class
00323 {
00324         static inline void elem_op(J elem1, K elem2)
00325         {
00326                 return loops_details::assign_bitor_class_details<J, K,
00327                         typename types::is_ivl_array<J>::type>::elem_op(elem1, elem2);
00328         };
00329 };
00330 
00331 // <<=, assign_bitlshift_class
00332 template<class J, class K>
00333 struct assign_bitlshift_class
00334 {
00335         static inline void elem_op(J elem1, K elem2)
00336         {
00337                 return loops_details::assign_bitlshift_class_details<J, K,
00338                         typename types::is_ivl_array<J>::type>::elem_op(elem1, elem2);
00339         };
00340 };
00341 
00342 // >>=, assign_bitrshift_class
00343 template<class J, class K>
00344 struct assign_bitrshift_class
00345 {
00346         static inline void elem_op(J elem1, K elem2)
00347         {
00348                 return loops_details::assign_bitrshift_class_details<J, K,
00349                         typename types::is_ivl_array<J>::type>::elem_op(elem1, elem2);
00350         };
00351 };
00352 
00353 // ^=, assign_bitxor_class
00354 template<class J, class K>
00355 struct assign_bitxor_class
00356 {
00357         static inline void elem_op(J elem1, K elem2)
00358         {
00359                 return loops_details::assign_bitxor_class_details<J, K,
00360                         typename types::is_ivl_array<J>::type>::elem_op(elem1, elem2);
00361         };
00362 };
00363 #else
00364 
00365 // =, assign_copy_class
00366 template<class J, class K>
00367 struct assign_copy_class
00368 {
00369         static inline void elem_op(J elem1, K elem2)
00370                 { ivl::force_assign(elem1, elem2); }
00371 };
00372 
00373 // +=, assign_plus_class
00374 template<class J, class K>
00375 struct assign_plus_class
00376 {
00377         static inline void elem_op(J elem1, K elem2)
00378                 { ivl::force(elem1) += elem2; }
00379 };
00380 
00381 // -=, assign_minus_class
00382 template<class J, class K>
00383 struct assign_minus_class
00384 {
00385         static inline void elem_op(J elem1, K elem2)
00386                 { ivl::force(elem1) -= elem2; }
00387 };
00388 
00389 // *=, assign_times_class
00390 template<class J, class K>
00391 struct assign_times_class
00392 {
00393         static inline void elem_op(J elem1, K elem2)
00394                 { ivl::force(elem1) *= elem2; }
00395 };
00396 
00397 // /=, assign_divide_class
00398 template<class J, class K>
00399 struct assign_divide_class
00400 {
00401         static inline void elem_op(J elem1, K elem2)
00402                 { ivl::force(elem1) /= elem2; }
00403 };
00404 
00405 // %=, assign_mod_class
00406 template<class J, class K>
00407 struct assign_mod_class
00408 {
00409         static inline void elem_op(J elem1, K elem2)
00410                 { ivl::force(elem1) %= elem2; }
00411 };
00412 
00413 // &=, assign_bitand_class
00414 template<class J, class K>
00415 struct assign_bitand_class
00416 {
00417         static inline void elem_op(J elem1, K elem2)
00418                 { ivl::force(elem1) &= elem2; }
00419 };
00420 
00421 // |=, assign_bitor_class
00422 template<class J, class K>
00423 struct assign_bitor_class
00424 {
00425         static inline void elem_op(J elem1, K elem2)
00426                 { ivl::force(elem1) |= elem2; }
00427 };
00428 
00429 // <<=, assign_bitlshift_class
00430 template<class J, class K>
00431 struct assign_bitlshift_class
00432 {
00433         static inline void elem_op(J elem1, K elem2)
00434                 { ivl::force(elem1) <<= elem2; }
00435 };
00436 
00437 // >>=, assign_bitrshift_class
00438 template<class J, class K>
00439 struct assign_bitrshift_class
00440 {
00441         static inline void elem_op(J elem1, K elem2)
00442                 { ivl::force(elem1) >>= elem2; }
00443 };
00444 
00445 // ^=, assign_bitxor_class
00446 template<class J, class K>
00447 struct assign_bitxor_class
00448 {
00449         static inline void elem_op(J elem1, K elem2)
00450                 { ivl::force(elem1) ^= elem2; }
00451 };
00452 
00453 #endif
00454 
00455 
00456 
00457 // -------------------------------------------------------
00458 
00459 // write-write loops
00460 
00461 
00462 namespace loops_details {
00463 
00464 // =, assign_copy_class
00465 template <class J, class K, class IS_ARRAY_1, class IS_ARRAY_2>
00466 struct write_write_swap_class_details { };
00467 
00468 template <class J, class K>
00469 struct write_write_swap_class_details<J, K, types::t_false, types::t_false>
00470 {
00471         static inline void elem_op(J elem1, K elem2)
00472                 { std::swap(elem1, elem2); }
00473 };
00474 
00475 template <class J, class K>
00476 struct write_write_swap_class_details<J, K, types::t_true, types::t_true>
00477 {
00478         static inline void elem_op(J elem1, K elem2)
00479                 { elem1.swap(elem2); }
00480 };
00481 
00482 } /* namespace loops_details */
00483 
00484 template<class J, class K>
00485 struct write_write_swap_class
00486 : public types::loop_ww_identifier
00487 {
00488         static inline void elem_op(J elem1, K elem2)
00489         {
00490                 return loops_details::write_write_swap_class_details<J, K,
00491                         typename types::is_ivl_array<J>::type,
00492                         typename types::is_ivl_array<K>::type>::elem_op(elem1, elem2);
00493         }
00494 };
00495 
00496 
00497 } /* namespace loops */
00498 } /* namespace ivl */
00499 
00500 #endif // IVL_CORE_DETAILS_LOOP_OPS_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations