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_ARRAY_DETAILS_ARRAY_OPERATORS_HPP 00025 #define IVL_ARRAY_DETAILS_ARRAY_OPERATORS_HPP 00026 00027 namespace ivl { 00028 00029 // this file needs removal! 00030 00031 #if 0 00032 00033 00034 //Todo: This file needs cleaning up and 00035 // the operations need to be generated and then commentized 00036 // instead of having the #defines 00037 00038 // This implementation is only temporary 00039 00040 00041 00042 // --- array-scalar 00043 00044 00045 00046 00047 00048 #define HELP3(opname, funcname, classname) \ 00049 \ 00050 template <class A1, class A2> \ 00051 inline \ 00052 typename binary_elem_func_result< \ 00053 typename types::get_value<A1>::type, \ 00054 classname, A1, A2>::type operator opname( \ 00055 const A1& a1, const A2& a2) \ 00056 { \ 00057 return funcname(a1, a2); \ 00058 };\ 00059 00060 #define HELPb(opname, funcname, classname) \ 00061 \ 00062 template <class A1, class A2> \ 00063 inline \ 00064 typename binary_elem_func_result<bool, classname, A1, A2> \ 00065 ::type operator opname( \ 00066 const A1& a1, const A2& a2) \ 00067 { \ 00068 return funcname(a1, a2); \ 00069 };\ 00070 00071 00072 00073 00074 #define HELP3__A(OP, FUNC, times_class) \ 00075 template<class T, class S, class K> \ 00076 inline \ 00077 const elem_func_scalar_l<T, times_class, T, array<T, S, K> > operator OP(const T& s, \ 00078 const array<T, S, K>& a) \ 00079 { \ 00080 return FUNC(s, a); \ 00081 } \ 00082 template<class T, class S, class K> \ 00083 inline \ 00084 const elem_func_scalar_r<T, times_class, array<T, S, K>, T> operator OP( \ 00085 const array<T, S, K>& a, const T& s) \ 00086 { \ 00087 return FUNC(a, s); \ 00088 } \ 00089 template<class T, class S1, class K1, class S2, class K2> \ 00090 inline \ 00091 const elem_func_binary<T, times_class, array<T, S1, K1>, array<T, S2, K2> > operator OP( \ 00092 const array<T, S1, K1>& a, const array<T, S2, K2>& b) \ 00093 { \ 00094 return FUNC(a, b); \ 00095 } \ 00096 00097 00098 #define HELPb__A(OP, FUNC, times_class) \ 00099 template<class T, class S, class K> \ 00100 inline \ 00101 const elem_func_scalar_l<bool, times_class, T, array<T, S, K> > operator OP(const T& s, \ 00102 const array<T, S, K>& a) \ 00103 { \ 00104 return FUNC(s, a); \ 00105 } \ 00106 template<class T, class S, class K> \ 00107 inline \ 00108 const elem_func_scalar_r<bool, times_class, array<T, S, K>, T> operator OP( \ 00109 const array<T, S, K>& a, const T& s) \ 00110 { \ 00111 return FUNC(a, s); \ 00112 } \ 00113 template<class T, class S1, class K1, class S2, class K2> \ 00114 inline \ 00115 const elem_func_binary<bool, times_class, array<T, S1, K1>, array<T, S2, K2> > operator OP( \ 00116 const array<T, S1, K1>& a, const array<T, S2, K2>& b) \ 00117 { \ 00118 return FUNC(a, b); \ 00119 } \ 00120 00121 00122 00123 // TODO: commentize before generate! 00124 00125 HELP3__A( * , ivl::times, times_class) 00126 HELP3__A( / , ivl::rdivide, rdivide_class) 00127 HELP3__A( % , ivl::rem, rem_class) 00128 HELP3__A( + , ivl::plus, plus_class) 00129 HELP3__A( - , ivl::minus, minus_class) 00130 00131 00132 template<class T, class S, class K> 00133 inline 00134 const elem_func_scalar_l<T, power_class, T, array<T, S, K> > operator^(const T& s, 00135 const array<T, S, K>& a) 00136 { 00137 return ivl::power(s, a); 00138 } 00139 template<class T, class S, class K> 00140 inline 00141 const elem_func_scalar_r<T, power_class, array<T, S, K>, T> operator^( 00142 const array<T, S, K>& a, const T& s) 00143 { 00144 return ivl::power(a, s); 00145 } 00146 template<class T, class S1, class K1, class S2, class K2> 00147 inline 00148 const elem_func_binary<T, bitxor_class, array<T, S1, K1>, array<T, S2, K2> > operator^( 00149 const array<T, S1, K1>& a, const array<T, S1, K1>& b) 00150 { 00151 return ivl::bitxor(a, b); 00152 } 00153 00154 00155 HELP3__A( & , ivl::cbitand , bitand_class ) 00156 HELP3__A( | , ivl::cbitor , bitor_class ) 00157 HELP3__A( << , ivl::bitlshift , bitlshift_class ) 00158 HELP3__A( >> , ivl::bitrshift , bitrshift_class ) 00159 00160 HELPb__A( && , ivl::logical_and , and_class ) 00161 HELPb__A( || , ivl::logical_or , or_class ) 00162 00163 00164 template<class T, class S, class K> 00165 inline 00166 const elem_func_scalar_l<bool, eq_class, T, array<T, S, K> > operator ==(const T& s, 00167 const array<T, S, K>& a) 00168 { 00169 return ivl::eq(s, a); 00170 } 00171 template<class T, class S, class K> 00172 inline 00173 const elem_func_scalar_r<bool, eq_class, array<T, S, K>, T> operator ==( 00174 const array<T, S, K>& a, const T& s) 00175 { 00176 return ivl::eq(a, s); 00177 } 00178 template<class T, class S1, class K1, class S2, class K2> 00179 inline 00180 const elem_func_binary<bool, eq_class, array<T, S1, K1>, array<T, S2, K2> > operator ==( 00181 const array<T, S1, K1>& a, const array<T, S2, K2>& b) 00182 { 00183 return ivl::eq(a, b); 00184 } 00185 00186 HELPb__A( != , ivl::ne , ne_class ) 00187 HELPb__A( < , ivl::lt , lt_class ) // note: we would like here to add op < for complex<T> 00188 HELPb__A( > , ivl::gt , gt_class ) 00189 HELPb__A( <= , ivl::le , le_class ) 00190 HELPb__A( >= , ivl::ge , ge_class ) 00191 00192 00193 00194 template<class T, class S> 00195 bool operator<(const std::complex<T>& x, const std::complex<S>& y) 00196 { 00197 return lt(x, y); 00198 } 00199 00200 template<class T, class S> 00201 bool operator>(const std::complex<T>& x, const std::complex<S>& y) 00202 { 00203 return gt(x, y); 00204 } 00205 00206 template<class T, class S> 00207 bool operator<=(const std::complex<T>& x, const std::complex<S>& y) 00208 { 00209 return le(x, y); 00210 } 00211 00212 template<class T, class S> 00213 bool operator>=(const std::complex<T>& x, const std::complex<S>& y) 00214 { 00215 return ge(x, y); 00216 } 00217 00218 00219 00220 00221 // unary (copy paste from below) 00222 //todo: make them elem-funcs 00223 00224 //-------------------------------------------------------------- 00225 // UNARY OPERATORS (templates) 00226 00227 00235 template <class T, class S, class K> 00236 typename array<T, S, K>:: 00237 create_similar operator+(const array<T, S, K>& in) 00238 { 00239 return typename array<T, S, K>::create_similar(ivl::uplus(in.derived())); 00240 } 00241 00249 template <class T, class S, class K> 00250 typename array<T, S, K>:: 00251 create_similar operator-(const array<T, S, K>& in) 00252 { 00253 return typename array<T, S, K>:: 00254 create_similar(ivl::uminus(in.derived())); 00255 } 00256 00262 template <class T, class S, class K> 00263 typename array<T, S, K>:: 00264 create_similar operator~(const array<T, S, K>& in) 00265 { 00266 return typename array<T, S, K>:: 00267 create_similar(ivl::bitcmp(in.derived())); 00268 } 00269 00279 template <class T, class S, class K> 00280 typename types::to_bool<typename array<T, S, K>::create_similar>:: 00281 type operator!(const array<T, S, K>& in) 00282 { 00283 //TODO: with elem functions! 00284 typename types::to_bool<typename array<T, S, K>::create_similar>:: 00285 type a(in.size()); 00286 00287 for (size_t i = 0; i < a.length(); ++i) 00288 a[i] = !in[i]; 00289 00290 return a; 00291 } 00292 00293 // unary assign(copied from below). need to make loop 00294 00295 00296 //-------------------------------------------------------------- 00297 // array UNARY OPERATORS 00298 00305 template <class T, class S, class K> 00306 typename array<T, S, K>::derived_type& operator++(array<T, S, K>& in) 00307 { 00308 in = ivl::plus(in, elem_cast<T>(1)); 00309 return in.derived(); 00310 } 00311 00318 template <class T, class S, class K> 00319 typename array<T, S, K>::create_similar operator++(array<T, S, K>& in, int) 00320 { 00321 typename array<T, S, K>::create_similar a(in.derived()); 00322 in = ivl::plus(in, elem_cast<T>(1)); 00323 return a; 00324 } 00325 00332 template <class T, class S, class K> 00333 typename array<T, S, K>::derived_type& operator--(array<T, S, K>& in) 00334 { 00335 in = ivl::minus(in, elem_cast<T>(1)); 00336 return in.derived(); 00337 } 00338 00345 template <class T, class S, class K> 00346 typename array<T, S, K>::create_similar operator--(array<T, S, K>& in, int) 00347 { 00348 typename array<T, S, K>::create_similar a = in.derived(); 00349 in = ivl::minus(in, elem_cast<T>(1)); 00350 return a; 00351 } 00352 00353 00354 00355 00356 00357 00358 00359 00360 00361 00362 00363 00364 00365 00366 00367 00368 00369 // The rest are only kept for comment information 00370 // and they are defined-out (like commented-out) 00371 00372 00373 00374 00375 #if 0 00376 00377 #ifdef IVL_MATLAB 00378 00388 template <class T, class S, class K> 00389 typename array<T, S, K>::derived_type& operator=(array<T, S, K>& a, const mxArray* mx) 00390 { 00391 } 00392 #endif 00393 00394 00395 //============================================================== 00396 // array SELF-assign numeric operators 00401 //-------------------------------------------------------------- 00402 // array UNARY OPERATORS 00403 00410 template <class T, class S, class K> 00411 typename array<T, S, K>::derived_type& operator++(array<T, S, K>& in) 00412 { 00413 in = ivl::plus(in, elem_cast<T>(1)); 00414 return in.derived(); 00415 } 00416 00423 template <class T, class S, class K> 00424 typename array<T, S, K>::create_similar operator++(array<T, S, K>& in, int) 00425 { 00426 typename array<T, S, K>::create_similar a(in.derived()); 00427 in = ivl::plus(in, elem_cast<T>(1)); 00428 return a; 00429 } 00430 00437 template <class T, class S, class K> 00438 typename array<T, S, K>::derived_type& operator--(array<T, S, K>& in) 00439 { 00440 in = ivl::minus(in, elem_cast<T>(1)); 00441 return in.derived(); 00442 } 00443 00450 template <class T, class S, class K> 00451 typename array<T, S, K>::create_similar operator--(array<T, S, K>& in, int) 00452 { 00453 typename array<T, S, K>::create_similar a = in.derived(); 00454 in = ivl::minus(in, elem_cast<T>(1)); 00455 return a; 00456 } 00457 00458 //-------------------------------------------------------------- 00459 // array BINARY OPERATORS 00460 00462 template<class T, class S, class K> 00463 typename array<T, S, K>::derived_type& operator*=(array<T, S, K>& in, const T& s) 00464 { 00465 in = ivl::times(in, s); 00466 return in.derived(); 00467 } 00468 00470 template<class T, class S, class K> 00471 typename array<T, S, K>::derived_type& operator/=(array<T, S, K>& in, const T& s) 00472 { 00473 in = ivl::rdivide(in, s); 00474 return in.derived(); 00475 } 00476 00478 template<class T, class S, class K> 00479 typename array<T, S, K>::derived_type& operator%=(array<T, S, K>& in, const T& s) 00480 { 00481 in = ivl::mod(in, s); 00482 return in.derived(); 00483 } 00484 00486 template<class T, class S, class K> 00487 typename array<T, S, K>::derived_type& operator+=(array<T, S, K>& in, const T& s) 00488 { 00489 in = ivl::plus(in, s); 00490 return in.derived(); 00491 } 00492 00494 template<class T, class S, class K> 00495 typename array<T, S, K>::derived_type& operator-=(array<T, S, K>& in, const T& s) 00496 { 00497 in = ivl::minus(in, s); 00498 return in.derived(); 00499 } 00500 00507 template<class T, class S, class K, class D, class P> 00508 typename array<T, S, K>::derived_type& operator+=(array<T, S, K>& in, const array<T, D, P>& a) 00509 { 00510 in = ivl::plus(in, a); 00511 return in.derived(); 00512 } 00513 00521 template<class T, class S, class K, class D, class P> 00522 typename array<T, S, K>::derived_type& operator-=(array<T, S, K>& in, const array<T, D, P>& a) 00523 { 00524 in = ivl::minus(in, a); 00525 return in.derived(); 00526 } 00527 00529 template<class T, class S, class K> 00530 typename array<T, S, K>::derived_type& operator^=(array<T, S, K>& in, const T& s) 00531 { 00532 in = ivl::bitxor(in, s); 00533 return in.derived(); 00534 } 00535 00537 template<class T, class S, class K> 00538 typename array<T, S, K>::derived_type& operator&=(array<T, S, K>& in, const T& s) 00539 { 00540 in = ivl::cbitand(in, s); 00541 return in.derived(); 00542 } 00543 00545 template<class T, class S, class K> 00546 typename array<T, S, K>::derived_type& operator|=(array<T, S, K>& in, const T& s) 00547 { 00548 in = ivl::cbitor(in, s); 00549 return in.derived(); 00550 } 00551 00555 00556 template<class T, class S, class K> 00557 typename array<T, S, K>::derived_type& operator<<=(array<T, S, K>& in, const T& s) 00558 { 00559 in = ivl::bitlshift(in, s); 00560 return in.derived(); 00561 } 00562 00564 00565 template<class T, class S, class K> 00566 typename array<T, S, K>::derived_type& operator>>=(array<T, S, K>& in, const T& s) 00567 { 00568 in = ivl::bitrshift(in, s); 00569 return in.derived(); 00570 } 00571 00572 // multiply array elements by array s elements 00573 template<class T, class S, class K, class D, class P> 00574 typename array<T, S, K>::derived_type& operator*=(array<T, S, K>& in, const array<T, D, P>& a) 00575 { 00576 in = ivl::times(in, a); 00577 return in.derived(); 00578 } 00579 00580 // divide array elements by array s elements 00581 template<class T, class S, class K, class D, class P> 00582 typename array<T, S, K>::derived_type& operator/=(array<T, S, K>& in, const array<T, D, P>& a) 00583 { 00584 in = ivl::rdivide(in, a); 00585 return in.derived(); 00586 } 00587 00588 // remainder array elements by array s elements 00589 template<class T, class S, class K, class D, class P> 00590 typename array<T, S, K>::derived_type& operator%=(array<T, S, K>& in, const array<T, D, P>& a) 00591 { 00592 in = ivl::rem(in, a); 00593 return in.derived(); 00594 } 00595 00596 // XOR array s elements into array elements 00597 template<class T, class S, class K, class D, class P> 00598 typename array<T, S, K>::derived_type& operator^=(array<T, S, K>& in, const array<T, D, P>& a) 00599 { 00600 in = ivl::bitxor(in, a); 00601 return in.derived(); 00602 } 00603 00604 // OR array s elements into array elements 00605 template<class T, class S, class K, class D, class P> 00606 typename array<T, S, K>::derived_type& operator|=(array<T, S, K>& in, const array<T, D, P>& a) 00607 { 00608 in = ivl::cbitor(in, a); 00609 return in.derived(); 00610 } 00611 00612 // AND array s elements into array elements 00613 template<class T, class S, class K, class D, class P> 00614 typename array<T, S, K>::derived_type& operator&=(array<T, S, K>& in, const array<T, D, P>& a) 00615 { 00616 in = ivl::cbitand(in, a); 00617 return in.derived(); 00618 } 00619 00620 // left shift array elements by array s elements 00621 template<class T, class S, class K, class D, class P> 00622 typename array<T, S, K>::derived_type& operator<<=(array<T, S, K>& in, const array<T, D, P>& a) 00623 { 00624 in = ivl::bitlshift(in, a); 00625 return in.derived(); 00626 } 00627 00628 // right shift array elements by array s elements 00629 template<class T, class S, class K, class D, class P> 00630 typename array<T, S, K>::derived_type& operator>>=(array<T, S, K>& in, const array<T, D, P>& a) 00631 { 00632 in = ivl::bitrshift(in, a); 00633 return in.derived(); 00634 } 00635 #endif 00636 #if 0 00637 //============================================================== 00638 // array CONST (new-type-returning) numeric operators 00639 00640 00641 //-------------------------------------------------------------- 00642 // UNARY OPERATORS (templates) 00643 00644 00652 template <class T, class S, class K> 00653 typename array<T, S, K>:: 00654 create_similar operator+(const array<T, S, K>& in) 00655 { 00656 return typename array<T, S, K>::create_similar(ivl::uplus(in.derived())); 00657 } 00658 00666 template <class T, class S, class K> 00667 typename array<T, S, K>:: 00668 create_similar operator-(const array<T, S, K>& in) 00669 { 00670 return typename array<T, S, K>:: 00671 create_similar(ivl::uminus(in.derived())); 00672 } 00673 00679 template <class T, class S, class K> 00680 typename array<T, S, K>:: 00681 create_similar operator~(const array<T, S, K>& in) 00682 { 00683 return typename array<T, S, K>:: 00684 create_similar(ivl::bitcmp(in.derived())); 00685 } 00686 00696 template <class T, class S, class K> 00697 typename types::to_bool<typename array<T, S, K>::create_similar>:: 00698 type operator!(const array<T, S, K>& in) 00699 { 00700 //TODO: with elem functions! 00701 typename types::to_bool<typename array<T, S, K>::create_similar>:: 00702 type a(in.size()); 00703 00704 for (size_t i = 0; i < a.length(); ++i) 00705 a[i] = !in[i]; 00706 00707 return a; 00708 } 00709 #endif 00710 00712 //-------------------------------------------------------------- 00713 // BINARY OPERATORS (templates) 00714 00795 #if 0 00796 00803 template<class T, class S1, class S2> 00804 inline 00805 const elem_func_binary<T, bitxor_class, T, S1, T, S2> operator^( 00806 const array_base<T, S1>& a, 00807 const array_base<T, S2>& b) 00808 { 00809 return ivl::bitxor(a, b); 00810 } 00811 00812 00813 00814 00815 00816 00818 template<class T, class S> 00819 inline 00820 const elem_func_scalar_l<T, times_class, T, S, T> operator*(const T& s, 00821 const array_base<T, S>& a) 00822 { 00823 return ivl::times(s, a); 00824 } 00825 00827 template<class T, class S> 00828 inline 00829 const elem_func_scalar_r<T, times_class, T, S, T> operator*(const array_base<T, S>& a, 00830 const T& s) 00831 { 00832 return ivl::times(a, s); 00833 } 00834 00836 template<class T, class S> 00837 inline 00838 const elem_func_scalar_l<T, rdivide_class, T, S, T> operator/(const T& s, 00839 const array_base<T, S>& a) 00840 { 00841 return ivl::rdivide(s, a); 00842 } 00843 00845 template<class T, class S> 00846 inline 00847 const elem_func_scalar_r<T, rdivide_class, T, S, T> operator/( 00848 const array_base<T, S>& a, 00849 const T& s) 00850 { 00851 return ivl::rdivide(a, s); 00852 } 00853 00854 00856 template<class T, class S> 00857 inline 00858 const elem_func_scalar_l<T, cmod_class, T, S, T> operator%( 00859 const T& s, 00860 const array_base<T, S>& a) 00861 { 00862 return ivl::cmod(s, a); 00863 } 00864 00866 template<class T, class S> 00867 inline 00868 const elem_func_scalar_r<T, cmod_class, T, S, T> operator%(const array_base<T, S>& a, 00869 const T& s) 00870 { 00871 return ivl::cmod(a, s); 00872 } 00873 00874 00876 template<class T, class S> 00877 inline 00878 const elem_func_scalar_l<T, plus_class, T, S, T> operator+(const T& s, 00879 const array_base<T, S>& a) 00880 { 00881 return ivl::plus(s, a); 00882 } 00883 00885 template<class T, class S> 00886 inline 00887 const elem_func_scalar_r<T, plus_class, T, S, T> operator+(const array_base<T, S>& a, 00888 const T& s) 00889 { 00890 return ivl::plus(a, s); 00891 } 00892 00893 00895 template<class T, class S> 00896 inline 00897 const elem_func_scalar_l<T, minus_class, T, S, T> operator-(const T& s, 00898 const array_base<T, S>& a) 00899 { 00900 return ivl::minus(s, a); 00901 } 00902 00904 template<class T, class S> 00905 inline 00906 const elem_func_scalar_r<T, minus_class, T, S, T> operator-(const array_base<T, S>& a, 00907 const T& s) 00908 { 00909 return ivl::minus(a, s); 00910 } 00911 00912 // ---array-array 00913 00920 template<class T, class S1, class S2> 00921 inline 00922 const elem_func_binary<T, times_class, T, S1, T, S2> operator*( 00923 const array_base<T, S1>& a, 00924 const array_base<T, S2>& b) 00925 { 00926 return ivl::times(a, b); 00927 } 00928 00929 00936 template<class T, class S1, class S2> 00937 inline 00938 const elem_func_binary<T, rdivide_class, T, S1, T, S2> operator/( 00939 const array_base<T, S1>& a, 00940 const array_base<T, S2>& b) 00941 { 00942 return ivl::rdivide(a, b); 00943 } 00944 00945 00952 template<class T, class S1, class S2> 00953 inline 00954 const elem_func_binary<T, cmod_class, T, S1, T, S2> operator%( 00955 const array_base<T, S1>& a, 00956 const array_base<T, S2>& b) 00957 { 00958 return ivl::cmod(a, b); 00959 } 00960 00961 00962 00969 template<class T, class S1, class S2> 00970 inline 00971 const elem_func_binary<T, plus_class, T, S1, T, S2> operator+( 00972 const array_base<T, S1>& a, 00973 const array_base<T, S2>& b) 00974 { 00975 return ivl::plus(a, b); 00976 } 00977 00978 00985 template<class T, class S1, class S2> 00986 inline 00987 const elem_func_binary<T, minus_class, T, S1, T, S2> operator-( 00988 const array_base<T, S1>& a, 00989 const array_base<T, S2>& b) 00990 { 00991 return ivl::minus(a, b); 00992 } 00993 00995 01002 //--- array-scalar 01003 01005 template<class T, class S> 01006 inline 01007 const elem_func_scalar_l<T, power_class, T, S, T> operator^(const T& s, 01008 const array_base<T, S>& a) 01009 { 01010 return ivl::power(s, a); 01011 } 01012 01014 template<class T, class S> 01015 inline 01016 const elem_func_scalar_r<T, power_class, T, S, T> operator^(const array_base<T, S>& a, 01017 const T& s) 01018 { 01019 return ivl::power(a, s); 01020 } 01021 01022 01024 template<class T, class S> 01025 inline 01026 const elem_func_scalar_l<T, bitand_class, T, S, T> operator&(const T& s, 01027 const array_base<T, S>& a) 01028 { 01029 return ivl::cbitand(s, a); 01030 } 01031 01033 template<class T, class S> 01034 inline 01035 const elem_func_scalar_r<T, bitand_class, T, S, T> operator&( 01036 const array_base<T, S>& a, 01037 const T& s) 01038 { 01039 return ivl::cbitand(a, s); 01040 } 01041 01043 template<class T, class S> 01044 inline 01045 const elem_func_scalar_l<T, bitor_class, T, S, T> operator|(const T& s, 01046 const array_base<T, S>& a) 01047 { 01048 return ivl::cbitor(s, a); 01049 } 01050 01052 template<class T, class S> 01053 inline 01054 const elem_func_scalar_r<T, bitor_class, T, S, T> operator|(const array_base<T, S>& a, 01055 const T& s) 01056 { 01057 return ivl::cbitor(a, s); 01058 } 01059 01061 template<class T, class S> 01062 inline 01063 const elem_func_scalar_l<T, bitlshift_class, T, S, T> operator<<(const T& s, 01064 const array_base<T, S>& a) 01065 { 01066 return ivl::bitlshift(s, a); 01067 } 01068 01070 template<class T, class S> 01071 inline 01072 const elem_func_scalar_r<T, bitlshift_class, T, S, T> operator<<(const array_base<T, 01073 S>& a, const T& s) 01074 { 01075 return ivl::bitlshift(a, s); 01076 } 01077 01078 01080 template<class T, class S> 01081 inline 01082 const elem_func_scalar_l<T, bitrshift_class, T, S, T> operator>>(const T& s, 01083 const array_base<T, S>& a) 01084 { 01085 return ivl::bitrshift(s, a); 01086 } 01087 01089 template<class T, class S> 01090 inline 01091 const elem_func_scalar_r<T, bitrshift_class, T, S, T> operator>>( 01092 const array_base<T, S>& a, 01093 const T& s) 01094 { 01095 return ivl::bitrshift(a, s); 01096 } 01097 01098 //--- array-array 01099 01106 template<class T, class S1, class S2> 01107 inline 01108 const elem_func_binary<T, bitxor_class, T, S1, T, S2> operator^( 01109 const array_base<T, S1>& a, 01110 const array_base<T, S2>& b) 01111 { 01112 return ivl::bitxor(a, b); 01113 } 01114 01121 template<class T, class S1, class S2> 01122 inline 01123 const elem_func_binary<T, bitand_class, T, S1, T, S2> operator&( 01124 const array_base<T, S1>& a, 01125 const array_base<T, S2>& b) 01126 { 01127 return ivl::cbitand(a, b); 01128 } 01129 01130 01137 template<class T, class S1, class S2> 01138 inline 01139 const elem_func_binary<T, bitor_class, T, S1, T, S2> operator|( 01140 const array_base<T, S1>& a, 01141 const array_base<T, S2>& b) 01142 { 01143 return ivl::cbitor(a, b); 01144 } 01145 01152 template<class T, class S1, class S2> 01153 inline 01154 const elem_func_binary<T, bitlshift_class, T, S1, T, S2> operator<<( 01155 const array_base<T, S1>& a, 01156 const array_base<T, S2>& b) 01157 { 01158 return ivl::bitlshift(a, b); 01159 } 01160 01167 template<class T, class S1, class S2> 01168 inline 01169 const elem_func_binary<T, bitrshift_class, T, S1, T, S2> operator>>( 01170 const array_base<T, S1>& a, 01171 const array_base<T, S2>& b) 01172 { 01173 return ivl::bitrshift(a, b); 01174 } 01175 01178 // ----- boolean operators 01179 01195 template<class T, class S> 01196 inline 01197 const elem_func_scalar_l<bool, and_class, T, S, T> operator&&(const T& s, 01198 const array_base<T, S>& a) 01199 { 01200 return ivl::logical_and(s, a); 01201 } 01202 01209 template<class T, class S> 01210 inline 01211 const elem_func_scalar_r<bool, and_class, T, S, T> operator&&( 01212 const array_base<T, S>& a, 01213 const T& s) 01214 { 01215 return ivl::logical_and(a, s); 01216 } 01217 01225 template<class T, class S1, class S2> 01226 inline 01227 const elem_func_binary<bool, and_class, T, S1, T, S2> operator&&( 01228 const array_base<T, S1>& a, 01229 const array_base<T, S2>& b) 01230 { 01231 return ivl::logical_and(a, b); 01232 } 01233 01240 template<class T, class S> 01241 inline 01242 const elem_func_scalar_l<bool, or_class, T, S, T> operator||(const T& s, 01243 const array_base<T, S>& a) 01244 { 01245 return ivl::logical_or(s, a); 01246 } 01247 01254 template<class T, class S> 01255 inline 01256 const elem_func_scalar_r<bool, or_class, T, S, T> operator||( 01257 const array_base<T, S>& a, 01258 const T& s) 01259 { 01260 return ivl::logical_or(a, s); 01261 } 01262 01270 template<class T, class S1, class S2> 01271 inline 01272 const elem_func_binary<bool, or_class, T, S1, T, S2> operator||( 01273 const array_base<T, S1>& a, 01274 const array_base<T, S2>& b) 01275 { 01276 return ivl::logical_or(a, b); 01277 } 01278 01286 template<class T, class S> 01287 inline 01288 const elem_func_scalar_l<bool, eq_class, T, S, T> operator==(const T& s, 01289 const array_base<T, S>& a) 01290 { 01291 return ivl::eq(s, a); 01292 } 01293 01301 template<class T, class S> 01302 inline 01303 const elem_func_scalar_r<bool, eq_class, T, S, T> operator==( 01304 const array_base<T, S>& a, 01305 const T& s) 01306 { 01307 return ivl::eq(a, s); 01308 } 01309 01318 template<class T, class S1, class S2> 01319 inline 01320 const elem_func_binary<bool, eq_class, T, S1, T, S2> operator==( 01321 const array_base<T, S1>& a, 01322 const array_base<T, S2>& b) 01323 { 01324 return ivl::eq(a, b); 01325 } 01326 01334 template<class T, class S> 01335 inline 01336 const elem_func_scalar_l<bool, ne_class, T, S, T> operator!=(const T& s, 01337 const array_base<T, S>& a) 01338 { 01339 return ivl::ne(s, a); 01340 } 01341 01349 template<class T, class S> 01350 inline 01351 const elem_func_scalar_r<bool, ne_class, T, S, T> operator!=( 01352 const array_base<T, S>& a, 01353 const T& s) 01354 { 01355 return ivl::ne(a, s); 01356 } 01357 01366 template<class T, class S1, class S2> 01367 inline 01368 const elem_func_binary<bool, ne_class, T, S1, T, S2> operator!=( 01369 const array_base<T, S1>& a, 01370 const array_base<T, S2>& b) 01371 { 01372 return ivl::ne(a, b); 01373 } 01374 01382 template<class T, class S> 01383 inline 01384 const elem_func_scalar_l<bool, lt_class, T, S, T> operator<(const T& s, 01385 const array_base<T, S>& a) 01386 { 01387 return ivl::lt(s, a); 01388 } 01389 01397 template<class T, class S> 01398 inline 01399 const elem_func_scalar_r<bool, lt_class, T, S, T> operator<( 01400 const array_base<T, S>& a, 01401 const T& s) 01402 { 01403 return ivl::lt(a, s); 01404 } 01405 01415 template<class T, class S1, class S2> 01416 inline 01417 const elem_func_binary<bool, lt_class, T, S1, T, S2> operator<( 01418 const array_base<T, S1>& a, 01419 const array_base<T, S2>& b) 01420 { 01421 return ivl::lt(a, b); 01422 } 01423 01430 template<class T, class S> 01431 inline 01432 const elem_func_scalar_l<bool, gt_class, T, S, T> operator>(const T& s, 01433 const array_base<T, S>& a) 01434 { 01435 return ivl::gt(s, a); 01436 } 01437 01445 template<class T, class S> 01446 inline 01447 const elem_func_scalar_r<bool, gt_class, T, S, T> operator>( 01448 const array_base<T, S>& a, 01449 const T& s) 01450 { 01451 return ivl::gt(a, s); 01452 } 01453 01463 template<class T, class S1, class S2> 01464 inline 01465 const elem_func_binary<bool, gt_class, T, S1, T, S2> operator>( 01466 const array_base<T, S1>& a, 01467 const array_base<T, S2>& b) 01468 { 01469 return ivl::gt(a, b); 01470 } 01471 01479 template<class T, class S> 01480 inline 01481 const elem_func_scalar_l<bool, le_class, T, S, T> operator<=(const T& s, 01482 const array_base<T, S>& a) 01483 { 01484 return ivl::le(s, a); 01485 } 01486 01494 template<class T, class S> 01495 inline 01496 const elem_func_scalar_r<bool, le_class, T, S, T> operator<=( 01497 const array_base<T, S>& a, 01498 const T& s) 01499 { 01500 return ivl::le(a, s); 01501 } 01502 01512 template<class T, class S1, class S2> 01513 inline 01514 const elem_func_binary<bool, le_class, T, S1, T, S2> operator<=( 01515 const array_base<T, S1>& a, 01516 const array_base<T, S2>& b) 01517 { 01518 return ivl::le(a, b); 01519 } 01520 01528 template<class T, class S> 01529 inline 01530 const elem_func_scalar_l<bool, ge_class, T, S, T> operator>=(const T& s, 01531 const array_base<T, S>& a) 01532 { 01533 return ivl::ge(s, a); 01534 } 01535 01544 template<class T, class S> 01545 inline 01546 const elem_func_scalar_r<bool, ge_class, T, S, T> operator>=( 01547 const array_base<T, S>& a, 01548 const T& s) 01549 { 01550 return ivl::ge(a, s); 01551 } 01552 01562 template<class T, class S1, class S2> 01563 inline 01564 const elem_func_binary<bool, ge_class, T, S1, T, S2> operator>=( 01565 const array_base<T, S1>& a, 01566 const array_base<T, S2>& b) 01567 { 01568 return ivl::ge(a, b); 01569 } 01570 01573 #endif 01574 01575 #endif 01576 01577 } // namespace ivl 01578 01579 #endif // IVL_ARRAY_DETAILS_ARRAY_OPERATORS_HPP