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_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