array_funcs.hpp

Go to the documentation of this file.
00001 /****
00002 ***** Copyright 2010 Intel Corporation All Rights Reserved.
00003 *****
00004 ***** The source code, information and material contained herein are owned by Intel Corporation or its suppliers  *****
00005 ***** or licensors, and title to such Material remains with Intel Corporation or its suppliers or licensors.      *****
00006 ***** The Material contains proprietary information of Intel or its suppliers and licensors. The Material is      *****
00007 ***** protected by worldwide copyright laws and treaty provisions. No part of the Material may be used, copied,   *****
00008 ***** reproduced, modified, published, uploaded, posted, transmitted, distributed or disclosed in any way without *****
00009 ***** Intel's prior express written permission.
00010 *****
00011 ***** No license under any patent, copyright or other intellectual property rights in the material is granted to  *****
00012 ***** or conferred upon you, either expressly, by implication, inducement, estoppel or otherwise. Any license     *****
00013 ***** under such intellectual property rights must be express and approved by Intel in writing.
00014 ****/
00015 
00016 /**** Copyright Ends ****/
00017 
00018 //
00019 // This file was automatically generated and should not be edited directly.
00020 //
00021 
00022 #ifndef ARBB_CPP_ARRAY_FUNCS_HPP
00023 #define ARBB_CPP_ARRAY_FUNCS_HPP
00024 
00025 #include "namespace.hpp"
00026 #include <numeric>
00027 #include <cmath>
00028 #include "array.hpp"
00029 #include "scalar_funcs.hpp"
00030 #include "detail/proxy_value.hpp"
00031 
00032 
00033 
00034 namespace ARBB_CPP_NS {
00035 
00036 
00038 
00039 // helper functions for built-in types
00040 namespace detail {
00041 
00042 template <typename T>
00043 struct precision_type {
00044   typedef double type;
00045 };
00046 
00047 template <typename T>
00048 T exp10(const T& a)
00049 {
00050   typedef typename precision_type<T>::type precision_t;
00051   const precision_t ln10_value = 2.30258509299404568402;
00052   return static_cast<T>(std::exp(static_cast<precision_t>(a) * ln10_value));
00053 }
00054 
00055 template <typename T>
00056 T round(const T& a)
00057 {
00058   return static_cast<T>(static_cast<long long>(a));
00059 }
00060 
00061 template <typename T>
00062 T rcp(const T& a)
00063 {
00064   typedef typename precision_type<T>::type precision_t;
00065   return static_cast<T>(static_cast<precision_t>(1) / static_cast<precision_t>(a));
00066 }
00067 
00068 template <typename T>
00069 const T& select(bool condition, const T& a, const T& b)
00070 {
00071   return condition ? a : b;
00072 }
00073 
00074 template <typename T>
00075 T rsqrt(const T& a)
00076 {
00077   typedef typename precision_type<T>::type precision_t;
00078   return static_cast<T>(std::sqrt(rcp(a)));
00079 }
00080 
00081 template <typename T>
00082 typename ARBB_CPP_NS::compare_type<T>::type
00083 compare(const T& a, const T& b)
00084 {
00085   const typename ARBB_CPP_NS::compare_type<T>::type zero = 0, one = 1;
00086   return select(a < b, -one, select(a == b, zero, one));
00087 }
00088 
00089 template <typename T>
00090 T div_tan(const T& a, const T& b)
00091 {
00092   typedef typename precision_type<T>::type precision_t;
00093   return static_cast<T>(std::tan(static_cast<precision_t>(a) / static_cast<precision_t>(b)));
00094 }
00095 
00096 template <typename T>
00097 const T& clamp(const T& a, const T& min_value, const T& max_value)
00098 {
00099   return std::min(std::max(a, min_value), max_value);
00100 }
00101 
00102 template <typename S, typename T>
00103 S bitwise_cast(const T& a)
00104 {
00105   union {
00106     T input;
00107     S result;
00108   } cast = { a };
00109 
00110   return cast.result;
00111 }
00112 
00113 } // namespace detail
00114 
00116 
00119 
00123 template<typename T, std::size_t N>
00124 array<T, N>
00125 abs(const array<T, N>& value)
00126 {
00127   using std::abs;
00128   array<T, N> result = {};
00129   for (std::size_t i = 0; i != N; ++i) {
00130     result[i] = abs(value[i]);
00131   }
00132 
00133   return result;
00134 }
00135 
00139 template<typename T, std::size_t N>
00140 array<T, N>
00141 acos(const array<T, N>& value)
00142 {
00143   using std::acos;
00144   array<T, N> result = {};
00145   for (std::size_t i = 0; i != N; ++i) {
00146     result[i] = acos(value[i]);
00147   }
00148 
00149   return result;
00150 }
00151 
00155 template<typename T, std::size_t N>
00156 array<T, N>
00157 asin(const array<T, N>& value)
00158 {
00159   using std::asin;
00160   array<T, N> result = {};
00161   for (std::size_t i = 0; i != N; ++i) {
00162     result[i] = asin(value[i]);
00163   }
00164 
00165   return result;
00166 }
00167 
00171 template<typename T, std::size_t N>
00172 array<T, N>
00173 atan(const array<T, N>& value)
00174 {
00175   using std::atan;
00176   array<T, N> result = {};
00177   for (std::size_t i = 0; i != N; ++i) {
00178     result[i] = atan(value[i]);
00179   }
00180 
00181   return result;
00182 }
00183 
00189 template<typename T, std::size_t N>
00190 array<T, N>
00191 clamp(const array<T, N>& value, const array<T, N>& minimum, const array<T, N>& maximum)
00192 {
00193   using detail::clamp;
00194   array<T, N> result = {};
00195   for (std::size_t i = 0; i != N; ++i) {
00196     result[i] = clamp(value[i], minimum[i], maximum[i]);
00197   }
00198 
00199   return result;
00200 }
00201 
00207 template<typename T, std::size_t N>
00208 array<T, N>
00209 clamp(const T& value, const array<T, N>& minimum, const array<T, N>& maximum)
00210 {
00211   using detail::clamp;
00212   array<T, N> result = {};
00213   for (std::size_t i = 0; i != N; ++i) {
00214     result[i] = clamp(value, minimum[i], maximum[i]);
00215   }
00216 
00217   return result;
00218 }
00219 
00225 template<typename T, std::size_t N>
00226 array<T, N>
00227 clamp(const typename uncaptured<T>::type& value, const array<T, N>& minimum, const array<T, N>& maximum)
00228 {
00229   using detail::clamp;
00230   array<T, N> result = {};
00231   for (std::size_t i = 0; i != N; ++i) {
00232     result[i] = clamp(value, minimum[i], maximum[i]);
00233   }
00234 
00235   return result;
00236 }
00237 
00243 template<typename T, std::size_t N>
00244 array<T, N>
00245 clamp(const array<T, N>& value, const T& minimum, const array<T, N>& maximum)
00246 {
00247   using detail::clamp;
00248   array<T, N> result = {};
00249   for (std::size_t i = 0; i != N; ++i) {
00250     result[i] = clamp(value[i], minimum, maximum[i]);
00251   }
00252 
00253   return result;
00254 }
00255 
00261 template<typename T, std::size_t N>
00262 array<T, N>
00263 clamp(const array<T, N>& value, const typename uncaptured<T>::type& minimum, const array<T, N>& maximum)
00264 {
00265   using detail::clamp;
00266   array<T, N> result = {};
00267   for (std::size_t i = 0; i != N; ++i) {
00268     result[i] = clamp(value[i], minimum, maximum[i]);
00269   }
00270 
00271   return result;
00272 }
00273 
00279 template<typename T, std::size_t N>
00280 array<T, N>
00281 clamp(const T& value, const T& minimum, const array<T, N>& maximum)
00282 {
00283   using detail::clamp;
00284   array<T, N> result = {};
00285   for (std::size_t i = 0; i != N; ++i) {
00286     result[i] = clamp(value, minimum, maximum[i]);
00287   }
00288 
00289   return result;
00290 }
00291 
00297 template<typename T, std::size_t N>
00298 array<T, N>
00299 clamp(const typename uncaptured<T>::type& value, const typename uncaptured<T>::type& minimum, const array<T, N>& maximum)
00300 {
00301   using detail::clamp;
00302   array<T, N> result = {};
00303   for (std::size_t i = 0; i != N; ++i) {
00304     result[i] = clamp(value, minimum, maximum[i]);
00305   }
00306 
00307   return result;
00308 }
00309 
00315 template<typename T, std::size_t N>
00316 array<T, N>
00317 clamp(const array<T, N>& value, const array<T, N>& minimum, const T& maximum)
00318 {
00319   using detail::clamp;
00320   array<T, N> result = {};
00321   for (std::size_t i = 0; i != N; ++i) {
00322     result[i] = clamp(value[i], minimum[i], maximum);
00323   }
00324 
00325   return result;
00326 }
00327 
00333 template<typename T, std::size_t N>
00334 array<T, N>
00335 clamp(const array<T, N>& value, const array<T, N>& minimum, const typename uncaptured<T>::type& maximum)
00336 {
00337   using detail::clamp;
00338   array<T, N> result = {};
00339   for (std::size_t i = 0; i != N; ++i) {
00340     result[i] = clamp(value[i], minimum[i], maximum);
00341   }
00342 
00343   return result;
00344 }
00345 
00351 template<typename T, std::size_t N>
00352 array<T, N>
00353 clamp(const T& value, const array<T, N>& minimum, const T& maximum)
00354 {
00355   using detail::clamp;
00356   array<T, N> result = {};
00357   for (std::size_t i = 0; i != N; ++i) {
00358     result[i] = clamp(value, minimum[i], maximum);
00359   }
00360 
00361   return result;
00362 }
00363 
00369 template<typename T, std::size_t N>
00370 array<T, N>
00371 clamp(const typename uncaptured<T>::type& value, const array<T, N>& minimum, const typename uncaptured<T>::type& maximum)
00372 {
00373   using detail::clamp;
00374   array<T, N> result = {};
00375   for (std::size_t i = 0; i != N; ++i) {
00376     result[i] = clamp(value, minimum[i], maximum);
00377   }
00378 
00379   return result;
00380 }
00381 
00387 template<typename T, std::size_t N>
00388 array<T, N>
00389 clamp(const array<T, N>& value, const T& minimum, const T& maximum)
00390 {
00391   using detail::clamp;
00392   array<T, N> result = {};
00393   for (std::size_t i = 0; i != N; ++i) {
00394     result[i] = clamp(value[i], minimum, maximum);
00395   }
00396 
00397   return result;
00398 }
00399 
00405 template<typename T, std::size_t N>
00406 array<T, N>
00407 clamp(const array<T, N>& value, const typename uncaptured<T>::type& minimum, const typename uncaptured<T>::type& maximum)
00408 {
00409   using detail::clamp;
00410   array<T, N> result = {};
00411   for (std::size_t i = 0; i != N; ++i) {
00412     result[i] = clamp(value[i], minimum, maximum);
00413   }
00414 
00415   return result;
00416 }
00417 
00421 template<typename T, std::size_t N>
00422 array<T, N>
00423 cos(const array<T, N>& value)
00424 {
00425   using std::cos;
00426   array<T, N> result = {};
00427   for (std::size_t i = 0; i != N; ++i) {
00428     result[i] = cos(value[i]);
00429   }
00430 
00431   return result;
00432 }
00433 
00437 template<typename T, std::size_t N>
00438 array<T, N>
00439 cosh(const array<T, N>& value)
00440 {
00441   using std::cosh;
00442   array<T, N> result = {};
00443   for (std::size_t i = 0; i != N; ++i) {
00444     result[i] = cosh(value[i]);
00445   }
00446 
00447   return result;
00448 }
00449 
00453 template<typename T, std::size_t N>
00454 array<T, N>
00455 exp(const array<T, N>& value)
00456 {
00457   using std::exp;
00458   array<T, N> result = {};
00459   for (std::size_t i = 0; i != N; ++i) {
00460     result[i] = exp(value[i]);
00461   }
00462 
00463   return result;
00464 }
00465 
00469 template<typename T, std::size_t N>
00470 array<T, N>
00471 exp10(const array<T, N>& value)
00472 {
00473   using detail::exp10;
00474   array<T, N> result = {};
00475   for (std::size_t i = 0; i != N; ++i) {
00476     result[i] = exp10(value[i]);
00477   }
00478 
00479   return result;
00480 }
00481 
00485 template<typename T, std::size_t N>
00486 array<T, N>
00487 floor(const array<T, N>& value)
00488 {
00489   using std::floor;
00490   array<T, N> result = {};
00491   for (std::size_t i = 0; i != N; ++i) {
00492     result[i] = floor(value[i]);
00493   }
00494 
00495   return result;
00496 }
00497 
00501 template<typename T, std::size_t N>
00502 array<T, N>
00503 ceil(const array<T, N>& value)
00504 {
00505   using std::ceil;
00506   array<T, N> result = {};
00507   for (std::size_t i = 0; i != N; ++i) {
00508     result[i] = ceil(value[i]);
00509   }
00510 
00511   return result;
00512 }
00513 
00517 template<typename T, std::size_t N>
00518 array<T, N>
00519 log(const array<T, N>& value)
00520 {
00521   using std::log;
00522   array<T, N> result = {};
00523   for (std::size_t i = 0; i != N; ++i) {
00524     result[i] = log(value[i]);
00525   }
00526 
00527   return result;
00528 }
00529 
00533 template<typename T, std::size_t N>
00534 array<T, N>
00535 log10(const array<T, N>& value)
00536 {
00537   using std::log10;
00538   array<T, N> result = {};
00539   for (std::size_t i = 0; i != N; ++i) {
00540     result[i] = log10(value[i]);
00541   }
00542 
00543   return result;
00544 }
00545 
00549 template<typename T, std::size_t N>
00550 array<T, N>
00551 rcp(const array<T, N>& value)
00552 {
00553   using detail::rcp;
00554   array<T, N> result = {};
00555   for (std::size_t i = 0; i != N; ++i) {
00556     result[i] = rcp(value[i]);
00557   }
00558 
00559   return result;
00560 }
00561 
00565 template<typename T, std::size_t N>
00566 array<T, N>
00567 round(const array<T, N>& value)
00568 {
00569   using detail::round;
00570   array<T, N> result = {};
00571   for (std::size_t i = 0; i != N; ++i) {
00572     result[i] = round(value[i]);
00573   }
00574 
00575   return result;
00576 }
00577 
00581 template<typename T, std::size_t N>
00582 array<T, N>
00583 rsqrt(const array<T, N>& value)
00584 {
00585   using detail::rsqrt;
00586   array<T, N> result = {};
00587   for (std::size_t i = 0; i != N; ++i) {
00588     result[i] = rsqrt(value[i]);
00589   }
00590 
00591   return result;
00592 }
00593 
00597 template<typename T, std::size_t N>
00598 array<T, N>
00599 sin(const array<T, N>& value)
00600 {
00601   using std::sin;
00602   array<T, N> result = {};
00603   for (std::size_t i = 0; i != N; ++i) {
00604     result[i] = sin(value[i]);
00605   }
00606 
00607   return result;
00608 }
00609 
00613 template<typename T, std::size_t N>
00614 array<T, N>
00615 sinh(const array<T, N>& value)
00616 {
00617   using std::sinh;
00618   array<T, N> result = {};
00619   for (std::size_t i = 0; i != N; ++i) {
00620     result[i] = sinh(value[i]);
00621   }
00622 
00623   return result;
00624 }
00625 
00629 template<typename T, std::size_t N>
00630 array<T, N>
00631 sqrt(const array<T, N>& value)
00632 {
00633   using std::sqrt;
00634   array<T, N> result = {};
00635   for (std::size_t i = 0; i != N; ++i) {
00636     result[i] = sqrt(value[i]);
00637   }
00638 
00639   return result;
00640 }
00641 
00645 template<typename T, std::size_t N>
00646 array<T, N>
00647 tan(const array<T, N>& value)
00648 {
00649   using std::tan;
00650   array<T, N> result = {};
00651   for (std::size_t i = 0; i != N; ++i) {
00652     result[i] = tan(value[i]);
00653   }
00654 
00655   return result;
00656 }
00657 
00661 template<typename T, std::size_t N>
00662 array<T, N>
00663 tanh(const array<T, N>& value)
00664 {
00665   using std::tanh;
00666   array<T, N> result = {};
00667   for (std::size_t i = 0; i != N; ++i) {
00668     result[i] = tanh(value[i]);
00669   }
00670 
00671   return result;
00672 }
00673 
00677 template<typename T, std::size_t N>
00678 array<typename boolean_type<T>::type, N>
00679 operator!(const array<T, N>& value)
00680 {
00681   array<typename boolean_type<T>::type, N> result = {};
00682   for (std::size_t i = 0; i != N; ++i) {
00683     result[i] = !value[i];
00684   }
00685 
00686   return result;
00687 }
00688 
00692 template<typename T, std::size_t N>
00693 detail::proxy_value<array<typename boolean_type<T>::type, N> >
00694 operator!(const detail::proxy_value<array<T, N> >& value)
00695 {
00696   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(!value.base(), !value.value());
00697 }
00698 
00702 template<typename T, std::size_t N>
00703 array<T, N>
00704 operator~(const array<T, N>& value)
00705 {
00706   array<T, N> result = {};
00707   for (std::size_t i = 0; i != N; ++i) {
00708     result[i] = ~value[i];
00709   }
00710 
00711   return result;
00712 }
00713 
00717 template<typename T, std::size_t N>
00718 array<T, N>
00719 operator-(const array<T, N>& value)
00720 {
00721   array<T, N> result = {};
00722   for (std::size_t i = 0; i != N; ++i) {
00723     result[i] = -value[i];
00724   }
00725 
00726   return result;
00727 }
00728 
00733 template<typename T, std::size_t N>
00734 array<T, N>
00735 operator+(const array<T, N>& a, const array<T, N>& b)
00736 {
00737   array<T, N> result = {};
00738   for (std::size_t i = 0; i != N; ++i) {
00739     result[i] = a[i] + b[i];
00740   }
00741 
00742   return result;
00743 }
00744 
00749 template<typename T, std::size_t N>
00750 array<T, N>
00751 operator+(const T& a, const array<T, N>& b)
00752 {
00753   array<T, N> result = {};
00754   for (std::size_t i = 0; i != N; ++i) {
00755     result[i] = a + b[i];
00756   }
00757 
00758   return result;
00759 }
00760 
00765 template<typename T, std::size_t N>
00766 array<T, N>
00767 operator+(const typename uncaptured<T>::type& a, const array<T, N>& b)
00768 {
00769   array<T, N> result = {};
00770   for (std::size_t i = 0; i != N; ++i) {
00771     result[i] = a + b[i];
00772   }
00773 
00774   return result;
00775 }
00776 
00781 template<typename T, std::size_t N>
00782 array<T, N>
00783 operator+(const array<T, N>& a, const T& b)
00784 {
00785   array<T, N> result = {};
00786   for (std::size_t i = 0; i != N; ++i) {
00787     result[i] = a[i] + b;
00788   }
00789 
00790   return result;
00791 }
00792 
00797 template<typename T, std::size_t N>
00798 array<T, N>
00799 operator+(const array<T, N>& a, const typename uncaptured<T>::type& b)
00800 {
00801   array<T, N> result = {};
00802   for (std::size_t i = 0; i != N; ++i) {
00803     result[i] = a[i] + b;
00804   }
00805 
00806   return result;
00807 }
00808 
00813 template<typename T, std::size_t N>
00814 array<T, N>&
00815 operator+=(array<T, N>& value, const array<T, N>& increment)
00816 {
00817   for (std::size_t i = 0; i != N; ++i) {
00818     value[i] += increment[i];
00819   }
00820 
00821   return value;
00822 }
00823 
00828 template<typename T, std::size_t N>
00829 array<T, N>&
00830 operator+=(array<T, N>& value, const T& increment)
00831 {
00832   for (std::size_t i = 0; i != N; ++i) {
00833     value[i] += increment;
00834   }
00835 
00836   return value;
00837 }
00838 
00843 template<typename T, std::size_t N>
00844 array<T, N>&
00845 operator+=(array<T, N>& value, const typename uncaptured<T>::type& increment)
00846 {
00847   for (std::size_t i = 0; i != N; ++i) {
00848     value[i] += increment;
00849   }
00850 
00851   return value;
00852 }
00853 
00858 template<typename T, std::size_t N>
00859 array<T, N>
00860 operator&(const array<T, N>& value, const array<T, N>& mask)
00861 {
00862   array<T, N> result = {};
00863   for (std::size_t i = 0; i != N; ++i) {
00864     result[i] = value[i] & mask[i];
00865   }
00866 
00867   return result;
00868 }
00869 
00874 template<typename T, std::size_t N>
00875 array<T, N>
00876 operator&(const T& value, const array<T, N>& mask)
00877 {
00878   array<T, N> result = {};
00879   for (std::size_t i = 0; i != N; ++i) {
00880     result[i] = value & mask[i];
00881   }
00882 
00883   return result;
00884 }
00885 
00890 template<typename T, std::size_t N>
00891 array<T, N>
00892 operator&(const typename uncaptured<T>::type& value, const array<T, N>& mask)
00893 {
00894   array<T, N> result = {};
00895   for (std::size_t i = 0; i != N; ++i) {
00896     result[i] = value & mask[i];
00897   }
00898 
00899   return result;
00900 }
00901 
00906 template<typename T, std::size_t N>
00907 array<T, N>
00908 operator&(const array<T, N>& value, const T& mask)
00909 {
00910   array<T, N> result = {};
00911   for (std::size_t i = 0; i != N; ++i) {
00912     result[i] = value[i] & mask;
00913   }
00914 
00915   return result;
00916 }
00917 
00922 template<typename T, std::size_t N>
00923 array<T, N>
00924 operator&(const array<T, N>& value, const typename uncaptured<T>::type& mask)
00925 {
00926   array<T, N> result = {};
00927   for (std::size_t i = 0; i != N; ++i) {
00928     result[i] = value[i] & mask;
00929   }
00930 
00931   return result;
00932 }
00933 
00938 template<typename T, std::size_t N>
00939 array<T, N>&
00940 operator&=(array<T, N>& value, const array<T, N>& mask)
00941 {
00942   for (std::size_t i = 0; i != N; ++i) {
00943     value[i] &= mask[i];
00944   }
00945 
00946   return value;
00947 }
00948 
00953 template<typename T, std::size_t N>
00954 array<T, N>&
00955 operator&=(array<T, N>& value, const T& mask)
00956 {
00957   for (std::size_t i = 0; i != N; ++i) {
00958     value[i] &= mask;
00959   }
00960 
00961   return value;
00962 }
00963 
00968 template<typename T, std::size_t N>
00969 array<T, N>&
00970 operator&=(array<T, N>& value, const typename uncaptured<T>::type& mask)
00971 {
00972   for (std::size_t i = 0; i != N; ++i) {
00973     value[i] &= mask;
00974   }
00975 
00976   return value;
00977 }
00978 
00983 template<typename T, std::size_t N>
00984 array<T, N>
00985 atan2(const array<T, N>& x, const array<T, N>& y)
00986 {
00987   using std::atan2;
00988   array<T, N> result = {};
00989   for (std::size_t i = 0; i != N; ++i) {
00990     result[i] = atan2(x[i], y[i]);
00991   }
00992 
00993   return result;
00994 }
00995 
01000 template<typename T, std::size_t N>
01001 array<T, N>
01002 atan2(const T& x, const array<T, N>& y)
01003 {
01004   using std::atan2;
01005   array<T, N> result = {};
01006   for (std::size_t i = 0; i != N; ++i) {
01007     result[i] = atan2(x, y[i]);
01008   }
01009 
01010   return result;
01011 }
01012 
01017 template<typename T, std::size_t N>
01018 array<T, N>
01019 atan2(const typename uncaptured<T>::type& x, const array<T, N>& y)
01020 {
01021   using std::atan2;
01022   array<T, N> result = {};
01023   for (std::size_t i = 0; i != N; ++i) {
01024     result[i] = atan2(x, y[i]);
01025   }
01026 
01027   return result;
01028 }
01029 
01034 template<typename T, std::size_t N>
01035 array<T, N>
01036 atan2(const array<T, N>& x, const T& y)
01037 {
01038   using std::atan2;
01039   array<T, N> result = {};
01040   for (std::size_t i = 0; i != N; ++i) {
01041     result[i] = atan2(x[i], y);
01042   }
01043 
01044   return result;
01045 }
01046 
01051 template<typename T, std::size_t N>
01052 array<T, N>
01053 atan2(const array<T, N>& x, const typename uncaptured<T>::type& y)
01054 {
01055   using std::atan2;
01056   array<T, N> result = {};
01057   for (std::size_t i = 0; i != N; ++i) {
01058     result[i] = atan2(x[i], y);
01059   }
01060 
01061   return result;
01062 }
01063 
01068 template<typename T, std::size_t N>
01069 array<typename compare_type<T>::type, N>
01070 compare(const array<T, N>& a, const array<T, N>& b)
01071 {
01072   using detail::compare;
01073   array<typename compare_type<T>::type, N> result = {};
01074   for (std::size_t i = 0; i != N; ++i) {
01075     result[i] = compare(a[i], b[i]);
01076   }
01077 
01078   return result;
01079 }
01080 
01085 template<typename T, std::size_t N>
01086 array<typename compare_type<T>::type, N>
01087 compare(const T& a, const array<T, N>& b)
01088 {
01089   using detail::compare;
01090   array<typename compare_type<T>::type, N> result = {};
01091   for (std::size_t i = 0; i != N; ++i) {
01092     result[i] = compare(a, b[i]);
01093   }
01094 
01095   return result;
01096 }
01097 
01102 template<typename T, std::size_t N>
01103 array<typename compare_type<T>::type, N>
01104 compare(const typename uncaptured<T>::type& a, const array<T, N>& b)
01105 {
01106   using detail::compare;
01107   array<typename compare_type<T>::type, N> result = {};
01108   for (std::size_t i = 0; i != N; ++i) {
01109     result[i] = compare(a, b[i]);
01110   }
01111 
01112   return result;
01113 }
01114 
01119 template<typename T, std::size_t N>
01120 array<typename compare_type<T>::type, N>
01121 compare(const array<T, N>& a, const T& b)
01122 {
01123   using detail::compare;
01124   array<typename compare_type<T>::type, N> result = {};
01125   for (std::size_t i = 0; i != N; ++i) {
01126     result[i] = compare(a[i], b);
01127   }
01128 
01129   return result;
01130 }
01131 
01136 template<typename T, std::size_t N>
01137 array<typename compare_type<T>::type, N>
01138 compare(const array<T, N>& a, const typename uncaptured<T>::type& b)
01139 {
01140   using detail::compare;
01141   array<typename compare_type<T>::type, N> result = {};
01142   for (std::size_t i = 0; i != N; ++i) {
01143     result[i] = compare(a[i], b);
01144   }
01145 
01146   return result;
01147 }
01148 
01153 template<typename T, std::size_t N>
01154 array<T, N>
01155 operator/(const array<T, N>& numerator, const array<T, N>& denominator)
01156 {
01157   array<T, N> result = {};
01158   for (std::size_t i = 0; i != N; ++i) {
01159     result[i] = numerator[i] / denominator[i];
01160   }
01161 
01162   return result;
01163 }
01164 
01169 template<typename T, std::size_t N>
01170 array<T, N>
01171 operator/(const T& numerator, const array<T, N>& denominator)
01172 {
01173   array<T, N> result = {};
01174   for (std::size_t i = 0; i != N; ++i) {
01175     result[i] = numerator / denominator[i];
01176   }
01177 
01178   return result;
01179 }
01180 
01185 template<typename T, std::size_t N>
01186 array<T, N>
01187 operator/(const typename uncaptured<T>::type& numerator, const array<T, N>& denominator)
01188 {
01189   array<T, N> result = {};
01190   for (std::size_t i = 0; i != N; ++i) {
01191     result[i] = numerator / denominator[i];
01192   }
01193 
01194   return result;
01195 }
01196 
01201 template<typename T, std::size_t N>
01202 array<T, N>
01203 operator/(const array<T, N>& numerator, const T& denominator)
01204 {
01205   array<T, N> result = {};
01206   for (std::size_t i = 0; i != N; ++i) {
01207     result[i] = numerator[i] / denominator;
01208   }
01209 
01210   return result;
01211 }
01212 
01217 template<typename T, std::size_t N>
01218 array<T, N>
01219 operator/(const array<T, N>& numerator, const typename uncaptured<T>::type& denominator)
01220 {
01221   array<T, N> result = {};
01222   for (std::size_t i = 0; i != N; ++i) {
01223     result[i] = numerator[i] / denominator;
01224   }
01225 
01226   return result;
01227 }
01228 
01233 template<typename T, std::size_t N>
01234 array<T, N>&
01235 operator/=(array<T, N>& value, const array<T, N>& denominator)
01236 {
01237   for (std::size_t i = 0; i != N; ++i) {
01238     value[i] /= denominator[i];
01239   }
01240 
01241   return value;
01242 }
01243 
01248 template<typename T, std::size_t N>
01249 array<T, N>&
01250 operator/=(array<T, N>& value, const T& denominator)
01251 {
01252   for (std::size_t i = 0; i != N; ++i) {
01253     value[i] /= denominator;
01254   }
01255 
01256   return value;
01257 }
01258 
01263 template<typename T, std::size_t N>
01264 array<T, N>&
01265 operator/=(array<T, N>& value, const typename uncaptured<T>::type& denominator)
01266 {
01267   for (std::size_t i = 0; i != N; ++i) {
01268     value[i] /= denominator;
01269   }
01270 
01271   return value;
01272 }
01273 
01278 template<typename T, std::size_t N>
01279 array<T, N>
01280 div_tan(const array<T, N>& x, const array<T, N>& y)
01281 {
01282   using detail::div_tan;
01283   array<T, N> result = {};
01284   for (std::size_t i = 0; i != N; ++i) {
01285     result[i] = div_tan(x[i], y[i]);
01286   }
01287 
01288   return result;
01289 }
01290 
01295 template<typename T, std::size_t N>
01296 array<T, N>
01297 div_tan(const T& x, const array<T, N>& y)
01298 {
01299   using detail::div_tan;
01300   array<T, N> result = {};
01301   for (std::size_t i = 0; i != N; ++i) {
01302     result[i] = div_tan(x, y[i]);
01303   }
01304 
01305   return result;
01306 }
01307 
01312 template<typename T, std::size_t N>
01313 array<T, N>
01314 div_tan(const typename uncaptured<T>::type& x, const array<T, N>& y)
01315 {
01316   using detail::div_tan;
01317   array<T, N> result = {};
01318   for (std::size_t i = 0; i != N; ++i) {
01319     result[i] = div_tan(x, y[i]);
01320   }
01321 
01322   return result;
01323 }
01324 
01329 template<typename T, std::size_t N>
01330 array<T, N>
01331 div_tan(const array<T, N>& x, const T& y)
01332 {
01333   using detail::div_tan;
01334   array<T, N> result = {};
01335   for (std::size_t i = 0; i != N; ++i) {
01336     result[i] = div_tan(x[i], y);
01337   }
01338 
01339   return result;
01340 }
01341 
01346 template<typename T, std::size_t N>
01347 array<T, N>
01348 div_tan(const array<T, N>& x, const typename uncaptured<T>::type& y)
01349 {
01350   using detail::div_tan;
01351   array<T, N> result = {};
01352   for (std::size_t i = 0; i != N; ++i) {
01353     result[i] = div_tan(x[i], y);
01354   }
01355 
01356   return result;
01357 }
01358 
01363 template<typename T, std::size_t N>
01364 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01365 operator==(const array<T, N>& a, const array<T, N>& b)
01366 {
01367   array<typename boolean_type<T>::type, N> result = {};
01368   for (std::size_t i = 0; i != N; ++i) {
01369     result[i] = a[i] == b[i];
01370   }
01371 
01372   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(result, and_reduce(result));
01373 }
01374 
01379 template<typename T, std::size_t N>
01380 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01381 operator==(const T& a, const array<T, N>& b)
01382 {
01383   array<typename boolean_type<T>::type, N> result = {};
01384   for (std::size_t i = 0; i != N; ++i) {
01385     result[i] = a == b[i];
01386   }
01387 
01388   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(result, and_reduce(result));
01389 }
01390 
01395 template<typename T, std::size_t N>
01396 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01397 operator==(const typename uncaptured<T>::type& a, const array<T, N>& b)
01398 {
01399   array<typename boolean_type<T>::type, N> result = {};
01400   for (std::size_t i = 0; i != N; ++i) {
01401     result[i] = a == b[i];
01402   }
01403 
01404   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(result, and_reduce(result));
01405 }
01406 
01411 template<typename T, std::size_t N>
01412 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01413 operator==(const array<T, N>& a, const T& b)
01414 {
01415   array<typename boolean_type<T>::type, N> result = {};
01416   for (std::size_t i = 0; i != N; ++i) {
01417     result[i] = a[i] == b;
01418   }
01419 
01420   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(result, and_reduce(result));
01421 }
01422 
01427 template<typename T, std::size_t N>
01428 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01429 operator==(const array<T, N>& a, const typename uncaptured<T>::type& b)
01430 {
01431   array<typename boolean_type<T>::type, N> result = {};
01432   for (std::size_t i = 0; i != N; ++i) {
01433     result[i] = a[i] == b;
01434   }
01435 
01436   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(result, and_reduce(result));
01437 }
01438 
01443 template<typename T, std::size_t N>
01444 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01445 operator>=(const array<T, N>& a, const array<T, N>& b)
01446 {
01447   const detail::proxy_value<array<typename boolean_type<T>::type, N> >& intermediate = a < b;
01448   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(!intermediate.base(), !intermediate.value());
01449 }
01450 
01455 template<typename T, std::size_t N>
01456 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01457 operator>=(const T& a, const array<T, N>& b)
01458 {
01459   const detail::proxy_value<array<typename boolean_type<T>::type, N> >& intermediate = a < b;
01460   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(!intermediate.base(), !intermediate.value());
01461 }
01462 
01467 template<typename T, std::size_t N>
01468 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01469 operator>=(const typename uncaptured<T>::type& a, const array<T, N>& b)
01470 {
01471   const detail::proxy_value<array<typename boolean_type<T>::type, N> >& intermediate = a < b;
01472   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(!intermediate.base(), !intermediate.value());
01473 }
01474 
01479 template<typename T, std::size_t N>
01480 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01481 operator>=(const array<T, N>& a, const T& b)
01482 {
01483   const detail::proxy_value<array<typename boolean_type<T>::type, N> >& intermediate = a < b;
01484   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(!intermediate.base(), !intermediate.value());
01485 }
01486 
01491 template<typename T, std::size_t N>
01492 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01493 operator>=(const array<T, N>& a, const typename uncaptured<T>::type& b)
01494 {
01495   const detail::proxy_value<array<typename boolean_type<T>::type, N> >& intermediate = a < b;
01496   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(!intermediate.base(), !intermediate.value());
01497 }
01498 
01503 template<typename T, std::size_t N>
01504 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01505 operator>(const array<T, N>& a, const array<T, N>& b)
01506 {
01507   return b < a;
01508 }
01509 
01514 template<typename T, std::size_t N>
01515 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01516 operator>(const T& a, const array<T, N>& b)
01517 {
01518   return b < a;
01519 }
01520 
01525 template<typename T, std::size_t N>
01526 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01527 operator>(const typename uncaptured<T>::type& a, const array<T, N>& b)
01528 {
01529   return b < a;
01530 }
01531 
01536 template<typename T, std::size_t N>
01537 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01538 operator>(const array<T, N>& a, const T& b)
01539 {
01540   return b < a;
01541 }
01542 
01547 template<typename T, std::size_t N>
01548 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01549 operator>(const array<T, N>& a, const typename uncaptured<T>::type& b)
01550 {
01551   return b < a;
01552 }
01553 
01558 template<typename T, std::size_t N>
01559 array<T, N>
01560 operator|(const array<T, N>& value, const array<T, N>& mask)
01561 {
01562   array<T, N> result = {};
01563   for (std::size_t i = 0; i != N; ++i) {
01564     result[i] = value[i] | mask[i];
01565   }
01566 
01567   return result;
01568 }
01569 
01574 template<typename T, std::size_t N>
01575 array<T, N>
01576 operator|(const T& value, const array<T, N>& mask)
01577 {
01578   array<T, N> result = {};
01579   for (std::size_t i = 0; i != N; ++i) {
01580     result[i] = value | mask[i];
01581   }
01582 
01583   return result;
01584 }
01585 
01590 template<typename T, std::size_t N>
01591 array<T, N>
01592 operator|(const typename uncaptured<T>::type& value, const array<T, N>& mask)
01593 {
01594   array<T, N> result = {};
01595   for (std::size_t i = 0; i != N; ++i) {
01596     result[i] = value | mask[i];
01597   }
01598 
01599   return result;
01600 }
01601 
01606 template<typename T, std::size_t N>
01607 array<T, N>
01608 operator|(const array<T, N>& value, const T& mask)
01609 {
01610   array<T, N> result = {};
01611   for (std::size_t i = 0; i != N; ++i) {
01612     result[i] = value[i] | mask;
01613   }
01614 
01615   return result;
01616 }
01617 
01622 template<typename T, std::size_t N>
01623 array<T, N>
01624 operator|(const array<T, N>& value, const typename uncaptured<T>::type& mask)
01625 {
01626   array<T, N> result = {};
01627   for (std::size_t i = 0; i != N; ++i) {
01628     result[i] = value[i] | mask;
01629   }
01630 
01631   return result;
01632 }
01633 
01638 template<typename T, std::size_t N>
01639 array<T, N>&
01640 operator|=(array<T, N>& value, const array<T, N>& mask)
01641 {
01642   for (std::size_t i = 0; i != N; ++i) {
01643     value[i] |= mask[i];
01644   }
01645 
01646   return value;
01647 }
01648 
01653 template<typename T, std::size_t N>
01654 array<T, N>&
01655 operator|=(array<T, N>& value, const T& mask)
01656 {
01657   for (std::size_t i = 0; i != N; ++i) {
01658     value[i] |= mask;
01659   }
01660 
01661   return value;
01662 }
01663 
01668 template<typename T, std::size_t N>
01669 array<T, N>&
01670 operator|=(array<T, N>& value, const typename uncaptured<T>::type& mask)
01671 {
01672   for (std::size_t i = 0; i != N; ++i) {
01673     value[i] |= mask;
01674   }
01675 
01676   return value;
01677 }
01678 
01683 template<typename T, std::size_t N>
01684 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01685 operator<=(const array<T, N>& a, const array<T, N>& b)
01686 {
01687   const detail::proxy_value<array<typename boolean_type<T>::type, N> >& intermediate = b < a;
01688   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(!intermediate.base(), !intermediate.value());
01689 }
01690 
01695 template<typename T, std::size_t N>
01696 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01697 operator<=(const T& a, const array<T, N>& b)
01698 {
01699   const detail::proxy_value<array<typename boolean_type<T>::type, N> >& intermediate = b < a;
01700   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(!intermediate.base(), !intermediate.value());
01701 }
01702 
01707 template<typename T, std::size_t N>
01708 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01709 operator<=(const typename uncaptured<T>::type& a, const array<T, N>& b)
01710 {
01711   const detail::proxy_value<array<typename boolean_type<T>::type, N> >& intermediate = b < a;
01712   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(!intermediate.base(), !intermediate.value());
01713 }
01714 
01719 template<typename T, std::size_t N>
01720 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01721 operator<=(const array<T, N>& a, const T& b)
01722 {
01723   const detail::proxy_value<array<typename boolean_type<T>::type, N> >& intermediate = b < a;
01724   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(!intermediate.base(), !intermediate.value());
01725 }
01726 
01731 template<typename T, std::size_t N>
01732 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01733 operator<=(const array<T, N>& a, const typename uncaptured<T>::type& b)
01734 {
01735   const detail::proxy_value<array<typename boolean_type<T>::type, N> >& intermediate = b < a;
01736   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(!intermediate.base(), !intermediate.value());
01737 }
01738 
01743 template<typename T, std::size_t N>
01744 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01745 operator<(const array<T, N>& a, const array<T, N>& b)
01746 {
01747   typedef typename boolean_type<T>::type boolean_T_type;
01748   array<boolean_T_type, N> result = {};
01749   for (std::size_t i = 0; i != N; ++i) {
01750     result[i] = a[i] < b[i];
01751   }
01752 
01753   struct helper {
01754     static boolean_T_type reduce(const array<T, N>& a,
01755                                                  const array<T, N>& b,
01756                                                  const array<boolean_T_type, N>& c,
01757                                                  std::size_t i) {
01758       boolean_T_type result = false; // tail of the recursion
01759       
01760       // avoid warning: constant control flow
01761       std::size_t n = N;
01762       // avoid warning: pointless comparison
01763       if (i != n && 0 != n) {
01764         // recursive definition of the lexicographical comparison
01765         result = c[i] || (a[i] == b[i] && reduce(a, b, c, i + 1));
01766       }
01767 
01768       return result;
01769     }
01770   };
01771   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(result, helper::reduce(a, b, result, 0));
01772 }
01773 
01778 template<typename T, std::size_t N>
01779 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01780 operator<(const T& a, const array<T, N>& b)
01781 {
01782   typedef typename boolean_type<T>::type boolean_T_type;
01783   array<boolean_T_type, N> result = {};
01784   for (std::size_t i = 0; i != N; ++i) {
01785     result[i] = a < b[i];
01786   }
01787 
01788   struct helper {
01789     static boolean_T_type reduce(const T& a,
01790                                                  const array<T, N>& b,
01791                                                  const array<boolean_T_type, N>& c,
01792                                                  std::size_t i) {
01793       boolean_T_type result = false; // tail of the recursion
01794       
01795       // avoid warning: constant control flow
01796       std::size_t n = N;
01797       // avoid warning: pointless comparison
01798       if (i != n && 0 != n) {
01799         // recursive definition of the lexicographical comparison
01800         result = c[i] || (a == b[i] && reduce(a, b, c, i + 1));
01801       }
01802 
01803       return result;
01804     }
01805   };
01806   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(result, helper::reduce(a, b, result, 0));
01807 }
01808 
01813 template<typename T, std::size_t N>
01814 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01815 operator<(const typename uncaptured<T>::type& a, const array<T, N>& b)
01816 {
01817   typedef typename boolean_type<T>::type boolean_T_type;
01818   array<boolean_T_type, N> result = {};
01819   for (std::size_t i = 0; i != N; ++i) {
01820     result[i] = a < b[i];
01821   }
01822 
01823   struct helper {
01824     static boolean_T_type reduce(const T& a,
01825                                                  const array<T, N>& b,
01826                                                  const array<boolean_T_type, N>& c,
01827                                                  std::size_t i) {
01828       boolean_T_type result = false; // tail of the recursion
01829       
01830       // avoid warning: constant control flow
01831       std::size_t n = N;
01832       // avoid warning: pointless comparison
01833       if (i != n && 0 != n) {
01834         // recursive definition of the lexicographical comparison
01835         result = c[i] || (a == b[i] && reduce(a, b, c, i + 1));
01836       }
01837 
01838       return result;
01839     }
01840   };
01841   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(result, helper::reduce(a, b, result, 0));
01842 }
01843 
01848 template<typename T, std::size_t N>
01849 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01850 operator<(const array<T, N>& a, const T& b)
01851 {
01852   typedef typename boolean_type<T>::type boolean_T_type;
01853   array<boolean_T_type, N> result = {};
01854   for (std::size_t i = 0; i != N; ++i) {
01855     result[i] = a[i] < b;
01856   }
01857 
01858   struct helper {
01859     static boolean_T_type reduce(const array<T, N>& a,
01860                                                  const T& b,
01861                                                  const array<boolean_T_type, N>& c,
01862                                                  std::size_t i) {
01863       boolean_T_type result = false; // tail of the recursion
01864       
01865       // avoid warning: constant control flow
01866       std::size_t n = N;
01867       // avoid warning: pointless comparison
01868       if (i != n && 0 != n) {
01869         // recursive definition of the lexicographical comparison
01870         result = c[i] || (a[i] == b && reduce(a, b, c, i + 1));
01871       }
01872 
01873       return result;
01874     }
01875   };
01876   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(result, helper::reduce(a, b, result, 0));
01877 }
01878 
01883 template<typename T, std::size_t N>
01884 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01885 operator<(const array<T, N>& a, const typename uncaptured<T>::type& b)
01886 {
01887   typedef typename boolean_type<T>::type boolean_T_type;
01888   array<boolean_T_type, N> result = {};
01889   for (std::size_t i = 0; i != N; ++i) {
01890     result[i] = a[i] < b;
01891   }
01892 
01893   struct helper {
01894     static boolean_T_type reduce(const array<T, N>& a,
01895                                                  const T& b,
01896                                                  const array<boolean_T_type, N>& c,
01897                                                  std::size_t i) {
01898       boolean_T_type result = false; // tail of the recursion
01899       
01900       // avoid warning: constant control flow
01901       std::size_t n = N;
01902       // avoid warning: pointless comparison
01903       if (i != n && 0 != n) {
01904         // recursive definition of the lexicographical comparison
01905         result = c[i] || (a[i] == b && reduce(a, b, c, i + 1));
01906       }
01907 
01908       return result;
01909     }
01910   };
01911   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(result, helper::reduce(a, b, result, 0));
01912 }
01913 
01918 template<typename T, std::size_t N>
01919 array<typename boolean_type<T>::type, N>
01920 operator&&(const array<T, N>& a, const array<T, N>& b)
01921 {
01922   array<typename boolean_type<T>::type, N> result = {};
01923   for (std::size_t i = 0; i != N; ++i) {
01924     result[i] = a[i] && b[i];
01925   }
01926 
01927   return result;
01928 }
01929 
01934 template<typename T, std::size_t N>
01935 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01936 operator&&(const detail::proxy_value<array<T, N> >& a, const detail::proxy_value<array<T, N> >& b)
01937 {
01938   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(a.base() && b.base(), a.value() && b.value());
01939 }
01940 
01945 template<typename T, std::size_t N>
01946 array<typename boolean_type<T>::type, N>
01947 operator&&(const T& a, const array<T, N>& b)
01948 {
01949   array<typename boolean_type<T>::type, N> result = {};
01950   for (std::size_t i = 0; i != N; ++i) {
01951     result[i] = a && b[i];
01952   }
01953 
01954   return result;
01955 }
01956 
01961 template<typename T, std::size_t N>
01962 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01963 operator&&(const T& a, const detail::proxy_value<array<T, N> >& b)
01964 {
01965   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(a.base() && b.base(), a.value() && b.value());
01966 }
01967 
01972 template<typename T, std::size_t N>
01973 array<typename boolean_type<T>::type, N>
01974 operator&&(const typename uncaptured<T>::type& a, const array<T, N>& b)
01975 {
01976   array<typename boolean_type<T>::type, N> result = {};
01977   for (std::size_t i = 0; i != N; ++i) {
01978     result[i] = a && b[i];
01979   }
01980 
01981   return result;
01982 }
01983 
01988 template<typename T, std::size_t N>
01989 detail::proxy_value<array<typename boolean_type<T>::type, N> >
01990 operator&&(const typename uncaptured<T>::type& a, const detail::proxy_value<array<T, N> >& b)
01991 {
01992   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(a.base() && b.base(), a.value() && b.value());
01993 }
01994 
01999 template<typename T, std::size_t N>
02000 array<typename boolean_type<T>::type, N>
02001 operator&&(const array<T, N>& a, const T& b)
02002 {
02003   array<typename boolean_type<T>::type, N> result = {};
02004   for (std::size_t i = 0; i != N; ++i) {
02005     result[i] = a[i] && b;
02006   }
02007 
02008   return result;
02009 }
02010 
02015 template<typename T, std::size_t N>
02016 detail::proxy_value<array<typename boolean_type<T>::type, N> >
02017 operator&&(const detail::proxy_value<array<T, N> >& a, const T& b)
02018 {
02019   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(a.base() && b.base(), a.value() && b.value());
02020 }
02021 
02026 template<typename T, std::size_t N>
02027 array<typename boolean_type<T>::type, N>
02028 operator&&(const array<T, N>& a, const typename uncaptured<T>::type& b)
02029 {
02030   array<typename boolean_type<T>::type, N> result = {};
02031   for (std::size_t i = 0; i != N; ++i) {
02032     result[i] = a[i] && b;
02033   }
02034 
02035   return result;
02036 }
02037 
02042 template<typename T, std::size_t N>
02043 detail::proxy_value<array<typename boolean_type<T>::type, N> >
02044 operator&&(const detail::proxy_value<array<T, N> >& a, const typename uncaptured<T>::type& b)
02045 {
02046   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(a.base() && b.base(), a.value() && b.value());
02047 }
02048 
02053 template<typename T, std::size_t N>
02054 array<typename boolean_type<T>::type, N>
02055 operator||(const array<T, N>& a, const array<T, N>& b)
02056 {
02057   array<typename boolean_type<T>::type, N> result = {};
02058   for (std::size_t i = 0; i != N; ++i) {
02059     result[i] = a[i] || b[i];
02060   }
02061 
02062   return result;
02063 }
02064 
02069 template<typename T, std::size_t N>
02070 detail::proxy_value<array<typename boolean_type<T>::type, N> >
02071 operator||(const detail::proxy_value<array<T, N> >& a, const detail::proxy_value<array<T, N> >& b)
02072 {
02073   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(a.base() || b.base(), a.value() || b.value());
02074 }
02075 
02080 template<typename T, std::size_t N>
02081 array<typename boolean_type<T>::type, N>
02082 operator||(const T& a, const array<T, N>& b)
02083 {
02084   array<typename boolean_type<T>::type, N> result = {};
02085   for (std::size_t i = 0; i != N; ++i) {
02086     result[i] = a || b[i];
02087   }
02088 
02089   return result;
02090 }
02091 
02096 template<typename T, std::size_t N>
02097 detail::proxy_value<array<typename boolean_type<T>::type, N> >
02098 operator||(const T& a, const detail::proxy_value<array<T, N> >& b)
02099 {
02100   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(a.base() || b.base(), a.value() || b.value());
02101 }
02102 
02107 template<typename T, std::size_t N>
02108 array<typename boolean_type<T>::type, N>
02109 operator||(const typename uncaptured<T>::type& a, const array<T, N>& b)
02110 {
02111   array<typename boolean_type<T>::type, N> result = {};
02112   for (std::size_t i = 0; i != N; ++i) {
02113     result[i] = a || b[i];
02114   }
02115 
02116   return result;
02117 }
02118 
02123 template<typename T, std::size_t N>
02124 detail::proxy_value<array<typename boolean_type<T>::type, N> >
02125 operator||(const typename uncaptured<T>::type& a, const detail::proxy_value<array<T, N> >& b)
02126 {
02127   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(a.base() || b.base(), a.value() || b.value());
02128 }
02129 
02134 template<typename T, std::size_t N>
02135 array<typename boolean_type<T>::type, N>
02136 operator||(const array<T, N>& a, const T& b)
02137 {
02138   array<typename boolean_type<T>::type, N> result = {};
02139   for (std::size_t i = 0; i != N; ++i) {
02140     result[i] = a[i] || b;
02141   }
02142 
02143   return result;
02144 }
02145 
02150 template<typename T, std::size_t N>
02151 detail::proxy_value<array<typename boolean_type<T>::type, N> >
02152 operator||(const detail::proxy_value<array<T, N> >& a, const T& b)
02153 {
02154   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(a.base() || b.base(), a.value() || b.value());
02155 }
02156 
02161 template<typename T, std::size_t N>
02162 array<typename boolean_type<T>::type, N>
02163 operator||(const array<T, N>& a, const typename uncaptured<T>::type& b)
02164 {
02165   array<typename boolean_type<T>::type, N> result = {};
02166   for (std::size_t i = 0; i != N; ++i) {
02167     result[i] = a[i] || b;
02168   }
02169 
02170   return result;
02171 }
02172 
02177 template<typename T, std::size_t N>
02178 detail::proxy_value<array<typename boolean_type<T>::type, N> >
02179 operator||(const detail::proxy_value<array<T, N> >& a, const typename uncaptured<T>::type& b)
02180 {
02181   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(a.base() || b.base(), a.value() || b.value());
02182 }
02183 
02188 template<typename T, std::size_t N>
02189 array<T, N>
02190 operator<<(const array<T, N>& value, const array<T, N>& shift_amount)
02191 {
02192   array<T, N> result = {};
02193   for (std::size_t i = 0; i != N; ++i) {
02194     result[i] = value[i] << shift_amount[i];
02195   }
02196 
02197   return result;
02198 }
02199 
02204 template<typename T, std::size_t N>
02205 array<T, N>
02206 operator<<(const T& value, const array<T, N>& shift_amount)
02207 {
02208   array<T, N> result = {};
02209   for (std::size_t i = 0; i != N; ++i) {
02210     result[i] = value << shift_amount[i];
02211   }
02212 
02213   return result;
02214 }
02215 
02220 template<typename T, std::size_t N>
02221 array<T, N>
02222 operator<<(const typename uncaptured<T>::type& value, const array<T, N>& shift_amount)
02223 {
02224   array<T, N> result = {};
02225   for (std::size_t i = 0; i != N; ++i) {
02226     result[i] = value << shift_amount[i];
02227   }
02228 
02229   return result;
02230 }
02231 
02236 template<typename T, std::size_t N>
02237 array<T, N>
02238 operator<<(const array<T, N>& value, const T& shift_amount)
02239 {
02240   array<T, N> result = {};
02241   for (std::size_t i = 0; i != N; ++i) {
02242     result[i] = value[i] << shift_amount;
02243   }
02244 
02245   return result;
02246 }
02247 
02252 template<typename T, std::size_t N>
02253 array<T, N>
02254 operator<<(const array<T, N>& value, const typename uncaptured<T>::type& shift_amount)
02255 {
02256   array<T, N> result = {};
02257   for (std::size_t i = 0; i != N; ++i) {
02258     result[i] = value[i] << shift_amount;
02259   }
02260 
02261   return result;
02262 }
02263 
02268 template<typename T, std::size_t N>
02269 array<T, N>&
02270 operator<<=(array<T, N>& value, const array<T, N>& shift_amount)
02271 {
02272   for (std::size_t i = 0; i != N; ++i) {
02273     value[i] <<= shift_amount[i];
02274   }
02275 
02276   return value;
02277 }
02278 
02283 template<typename T, std::size_t N>
02284 array<T, N>&
02285 operator<<=(array<T, N>& value, const T& shift_amount)
02286 {
02287   for (std::size_t i = 0; i != N; ++i) {
02288     value[i] <<= shift_amount;
02289   }
02290 
02291   return value;
02292 }
02293 
02298 template<typename T, std::size_t N>
02299 array<T, N>&
02300 operator<<=(array<T, N>& value, const typename uncaptured<T>::type& shift_amount)
02301 {
02302   for (std::size_t i = 0; i != N; ++i) {
02303     value[i] <<= shift_amount;
02304   }
02305 
02306   return value;
02307 }
02308 
02313 template<typename T, std::size_t N>
02314 array<T, N>
02315 max(const array<T, N>& a, const array<T, N>& b)
02316 {
02317   using std::max;
02318   array<T, N> result = {};
02319   for (std::size_t i = 0; i != N; ++i) {
02320     result[i] = max(a[i], b[i]);
02321   }
02322 
02323   return result;
02324 }
02325 
02330 template<typename T, std::size_t N>
02331 array<T, N>
02332 max(const T& a, const array<T, N>& b)
02333 {
02334   using std::max;
02335   array<T, N> result = {};
02336   for (std::size_t i = 0; i != N; ++i) {
02337     result[i] = max(a, b[i]);
02338   }
02339 
02340   return result;
02341 }
02342 
02347 template<typename T, std::size_t N>
02348 array<T, N>
02349 max(const typename uncaptured<T>::type& a, const array<T, N>& b)
02350 {
02351   using std::max;
02352   array<T, N> result = {};
02353   for (std::size_t i = 0; i != N; ++i) {
02354     result[i] = max(a, b[i]);
02355   }
02356 
02357   return result;
02358 }
02359 
02364 template<typename T, std::size_t N>
02365 array<T, N>
02366 max(const array<T, N>& a, const T& b)
02367 {
02368   using std::max;
02369   array<T, N> result = {};
02370   for (std::size_t i = 0; i != N; ++i) {
02371     result[i] = max(a[i], b);
02372   }
02373 
02374   return result;
02375 }
02376 
02381 template<typename T, std::size_t N>
02382 array<T, N>
02383 max(const array<T, N>& a, const typename uncaptured<T>::type& b)
02384 {
02385   using std::max;
02386   array<T, N> result = {};
02387   for (std::size_t i = 0; i != N; ++i) {
02388     result[i] = max(a[i], b);
02389   }
02390 
02391   return result;
02392 }
02393 
02398 template<typename T, std::size_t N>
02399 array<T, N>
02400 min(const array<T, N>& a, const array<T, N>& b)
02401 {
02402   using std::min;
02403   array<T, N> result = {};
02404   for (std::size_t i = 0; i != N; ++i) {
02405     result[i] = min(a[i], b[i]);
02406   }
02407 
02408   return result;
02409 }
02410 
02415 template<typename T, std::size_t N>
02416 array<T, N>
02417 min(const T& a, const array<T, N>& b)
02418 {
02419   using std::min;
02420   array<T, N> result = {};
02421   for (std::size_t i = 0; i != N; ++i) {
02422     result[i] = min(a, b[i]);
02423   }
02424 
02425   return result;
02426 }
02427 
02432 template<typename T, std::size_t N>
02433 array<T, N>
02434 min(const typename uncaptured<T>::type& a, const array<T, N>& b)
02435 {
02436   using std::min;
02437   array<T, N> result = {};
02438   for (std::size_t i = 0; i != N; ++i) {
02439     result[i] = min(a, b[i]);
02440   }
02441 
02442   return result;
02443 }
02444 
02449 template<typename T, std::size_t N>
02450 array<T, N>
02451 min(const array<T, N>& a, const T& b)
02452 {
02453   using std::min;
02454   array<T, N> result = {};
02455   for (std::size_t i = 0; i != N; ++i) {
02456     result[i] = min(a[i], b);
02457   }
02458 
02459   return result;
02460 }
02461 
02466 template<typename T, std::size_t N>
02467 array<T, N>
02468 min(const array<T, N>& a, const typename uncaptured<T>::type& b)
02469 {
02470   using std::min;
02471   array<T, N> result = {};
02472   for (std::size_t i = 0; i != N; ++i) {
02473     result[i] = min(a[i], b);
02474   }
02475 
02476   return result;
02477 }
02478 
02483 template<typename T, std::size_t N>
02484 array<T, N>
02485 operator%(const array<T, N>& dividend, const array<T, N>& divisor)
02486 {
02487   array<T, N> result = {};
02488   for (std::size_t i = 0; i != N; ++i) {
02489     result[i] = dividend[i] % divisor[i];
02490   }
02491 
02492   return result;
02493 }
02494 
02499 template<typename T, std::size_t N>
02500 array<T, N>
02501 operator%(const T& dividend, const array<T, N>& divisor)
02502 {
02503   array<T, N> result = {};
02504   for (std::size_t i = 0; i != N; ++i) {
02505     result[i] = dividend % divisor[i];
02506   }
02507 
02508   return result;
02509 }
02510 
02515 template<typename T, std::size_t N>
02516 array<T, N>
02517 operator%(const typename uncaptured<T>::type& dividend, const array<T, N>& divisor)
02518 {
02519   array<T, N> result = {};
02520   for (std::size_t i = 0; i != N; ++i) {
02521     result[i] = dividend % divisor[i];
02522   }
02523 
02524   return result;
02525 }
02526 
02531 template<typename T, std::size_t N>
02532 array<T, N>
02533 operator%(const array<T, N>& dividend, const T& divisor)
02534 {
02535   array<T, N> result = {};
02536   for (std::size_t i = 0; i != N; ++i) {
02537     result[i] = dividend[i] % divisor;
02538   }
02539 
02540   return result;
02541 }
02542 
02547 template<typename T, std::size_t N>
02548 array<T, N>
02549 operator%(const array<T, N>& dividend, const typename uncaptured<T>::type& divisor)
02550 {
02551   array<T, N> result = {};
02552   for (std::size_t i = 0; i != N; ++i) {
02553     result[i] = dividend[i] % divisor;
02554   }
02555 
02556   return result;
02557 }
02558 
02563 template<typename T, std::size_t N>
02564 array<T, N>&
02565 operator%=(array<T, N>& value, const array<T, N>& divisor)
02566 {
02567   for (std::size_t i = 0; i != N; ++i) {
02568     value[i] %= divisor[i];
02569   }
02570 
02571   return value;
02572 }
02573 
02578 template<typename T, std::size_t N>
02579 array<T, N>&
02580 operator%=(array<T, N>& value, const T& divisor)
02581 {
02582   for (std::size_t i = 0; i != N; ++i) {
02583     value[i] %= divisor;
02584   }
02585 
02586   return value;
02587 }
02588 
02593 template<typename T, std::size_t N>
02594 array<T, N>&
02595 operator%=(array<T, N>& value, const typename uncaptured<T>::type& divisor)
02596 {
02597   for (std::size_t i = 0; i != N; ++i) {
02598     value[i] %= divisor;
02599   }
02600 
02601   return value;
02602 }
02603 
02608 template<typename T, std::size_t N>
02609 array<T, N>
02610 operator*(const array<T, N>& a, const array<T, N>& b)
02611 {
02612   array<T, N> result = {};
02613   for (std::size_t i = 0; i != N; ++i) {
02614     result[i] = a[i] * b[i];
02615   }
02616 
02617   return result;
02618 }
02619 
02624 template<typename T, std::size_t N>
02625 array<T, N>
02626 operator*(const T& a, const array<T, N>& b)
02627 {
02628   array<T, N> result = {};
02629   for (std::size_t i = 0; i != N; ++i) {
02630     result[i] = a * b[i];
02631   }
02632 
02633   return result;
02634 }
02635 
02640 template<typename T, std::size_t N>
02641 array<T, N>
02642 operator*(const typename uncaptured<T>::type& a, const array<T, N>& b)
02643 {
02644   array<T, N> result = {};
02645   for (std::size_t i = 0; i != N; ++i) {
02646     result[i] = a * b[i];
02647   }
02648 
02649   return result;
02650 }
02651 
02656 template<typename T, std::size_t N>
02657 array<T, N>
02658 operator*(const array<T, N>& a, const T& b)
02659 {
02660   array<T, N> result = {};
02661   for (std::size_t i = 0; i != N; ++i) {
02662     result[i] = a[i] * b;
02663   }
02664 
02665   return result;
02666 }
02667 
02672 template<typename T, std::size_t N>
02673 array<T, N>
02674 operator*(const array<T, N>& a, const typename uncaptured<T>::type& b)
02675 {
02676   array<T, N> result = {};
02677   for (std::size_t i = 0; i != N; ++i) {
02678     result[i] = a[i] * b;
02679   }
02680 
02681   return result;
02682 }
02683 
02688 template<typename T, std::size_t N>
02689 array<T, N>&
02690 operator*=(array<T, N>& value, const array<T, N>& multiplicand)
02691 {
02692   for (std::size_t i = 0; i != N; ++i) {
02693     value[i] *= multiplicand[i];
02694   }
02695 
02696   return value;
02697 }
02698 
02703 template<typename T, std::size_t N>
02704 array<T, N>&
02705 operator*=(array<T, N>& value, const T& multiplicand)
02706 {
02707   for (std::size_t i = 0; i != N; ++i) {
02708     value[i] *= multiplicand;
02709   }
02710 
02711   return value;
02712 }
02713 
02718 template<typename T, std::size_t N>
02719 array<T, N>&
02720 operator*=(array<T, N>& value, const typename uncaptured<T>::type& multiplicand)
02721 {
02722   for (std::size_t i = 0; i != N; ++i) {
02723     value[i] *= multiplicand;
02724   }
02725 
02726   return value;
02727 }
02728 
02733 template<typename T, std::size_t N>
02734 detail::proxy_value<array<typename boolean_type<T>::type, N> >
02735 operator!=(const array<T, N>& a, const array<T, N>& b)
02736 {
02737   const detail::proxy_value<array<typename boolean_type<T>::type, N> >& intermediate = a == b;
02738   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(!intermediate.base(), !intermediate.value());
02739 }
02740 
02745 template<typename T, std::size_t N>
02746 detail::proxy_value<array<typename boolean_type<T>::type, N> >
02747 operator!=(const T& a, const array<T, N>& b)
02748 {
02749   const detail::proxy_value<array<typename boolean_type<T>::type, N> >& intermediate = a == b;
02750   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(!intermediate.base(), !intermediate.value());
02751 }
02752 
02757 template<typename T, std::size_t N>
02758 detail::proxy_value<array<typename boolean_type<T>::type, N> >
02759 operator!=(const typename uncaptured<T>::type& a, const array<T, N>& b)
02760 {
02761   const detail::proxy_value<array<typename boolean_type<T>::type, N> >& intermediate = a == b;
02762   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(!intermediate.base(), !intermediate.value());
02763 }
02764 
02769 template<typename T, std::size_t N>
02770 detail::proxy_value<array<typename boolean_type<T>::type, N> >
02771 operator!=(const array<T, N>& a, const T& b)
02772 {
02773   const detail::proxy_value<array<typename boolean_type<T>::type, N> >& intermediate = a == b;
02774   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(!intermediate.base(), !intermediate.value());
02775 }
02776 
02781 template<typename T, std::size_t N>
02782 detail::proxy_value<array<typename boolean_type<T>::type, N> >
02783 operator!=(const array<T, N>& a, const typename uncaptured<T>::type& b)
02784 {
02785   const detail::proxy_value<array<typename boolean_type<T>::type, N> >& intermediate = a == b;
02786   return detail::proxy_value<array<typename boolean_type<T>::type, N> >(!intermediate.base(), !intermediate.value());
02787 }
02788 
02793 template<typename T, std::size_t N>
02794 array<T, N>
02795 pow(const array<T, N>& base, const array<T, N>& exponent)
02796 {
02797   using std::pow;
02798   array<T, N> result = {};
02799   for (std::size_t i = 0; i != N; ++i) {
02800     result[i] = pow(base[i], exponent[i]);
02801   }
02802 
02803   return result;
02804 }
02805 
02810 template<typename T, std::size_t N>
02811 array<T, N>
02812 pow(const T& base, const array<T, N>& exponent)
02813 {
02814   using std::pow;
02815   array<T, N> result = {};
02816   for (std::size_t i = 0; i != N; ++i) {
02817     result[i] = pow(base, exponent[i]);
02818   }
02819 
02820   return result;
02821 }
02822 
02827 template<typename T, std::size_t N>
02828 array<T, N>
02829 pow(const typename uncaptured<T>::type& base, const array<T, N>& exponent)
02830 {
02831   using std::pow;
02832   array<T, N> result = {};
02833   for (std::size_t i = 0; i != N; ++i) {
02834     result[i] = pow(base, exponent[i]);
02835   }
02836 
02837   return result;
02838 }
02839 
02844 template<typename T, std::size_t N>
02845 array<T, N>
02846 pow(const array<T, N>& base, const T& exponent)
02847 {
02848   using std::pow;
02849   array<T, N> result = {};
02850   for (std::size_t i = 0; i != N; ++i) {
02851     result[i] = pow(base[i], exponent);
02852   }
02853 
02854   return result;
02855 }
02856 
02861 template<typename T, std::size_t N>
02862 array<T, N>
02863 pow(const array<T, N>& base, const typename uncaptured<T>::type& exponent)
02864 {
02865   using std::pow;
02866   array<T, N> result = {};
02867   for (std::size_t i = 0; i != N; ++i) {
02868     result[i] = pow(base[i], exponent);
02869   }
02870 
02871   return result;
02872 }
02873 
02878 template<typename T, std::size_t N>
02879 array<T, N>
02880 operator>>(const array<T, N>& value, const array<T, N>& shift_amount)
02881 {
02882   array<T, N> result = {};
02883   for (std::size_t i = 0; i != N; ++i) {
02884     result[i] = value[i] >> shift_amount[i];
02885   }
02886 
02887   return result;
02888 }
02889 
02894 template<typename T, std::size_t N>
02895 array<T, N>
02896 operator>>(const T& value, const array<T, N>& shift_amount)
02897 {
02898   array<T, N> result = {};
02899   for (std::size_t i = 0; i != N; ++i) {
02900     result[i] = value >> shift_amount[i];
02901   }
02902 
02903   return result;
02904 }
02905 
02910 template<typename T, std::size_t N>
02911 array<T, N>
02912 operator>>(const typename uncaptured<T>::type& value, const array<T, N>& shift_amount)
02913 {
02914   array<T, N> result = {};
02915   for (std::size_t i = 0; i != N; ++i) {
02916     result[i] = value >> shift_amount[i];
02917   }
02918 
02919   return result;
02920 }
02921 
02926 template<typename T, std::size_t N>
02927 array<T, N>
02928 operator>>(const array<T, N>& value, const T& shift_amount)
02929 {
02930   array<T, N> result = {};
02931   for (std::size_t i = 0; i != N; ++i) {
02932     result[i] = value[i] >> shift_amount;
02933   }
02934 
02935   return result;
02936 }
02937 
02942 template<typename T, std::size_t N>
02943 array<T, N>
02944 operator>>(const array<T, N>& value, const typename uncaptured<T>::type& shift_amount)
02945 {
02946   array<T, N> result = {};
02947   for (std::size_t i = 0; i != N; ++i) {
02948     result[i] = value[i] >> shift_amount;
02949   }
02950 
02951   return result;
02952 }
02953 
02958 template<typename T, std::size_t N>
02959 array<T, N>&
02960 operator>>=(array<T, N>& value, const array<T, N>& shift_amount)
02961 {
02962   for (std::size_t i = 0; i != N; ++i) {
02963     value[i] >>= shift_amount[i];
02964   }
02965 
02966   return value;
02967 }
02968 
02973 template<typename T, std::size_t N>
02974 array<T, N>&
02975 operator>>=(array<T, N>& value, const T& shift_amount)
02976 {
02977   for (std::size_t i = 0; i != N; ++i) {
02978     value[i] >>= shift_amount;
02979   }
02980 
02981   return value;
02982 }
02983 
02988 template<typename T, std::size_t N>
02989 array<T, N>&
02990 operator>>=(array<T, N>& value, const typename uncaptured<T>::type& shift_amount)
02991 {
02992   for (std::size_t i = 0; i != N; ++i) {
02993     value[i] >>= shift_amount;
02994   }
02995 
02996   return value;
02997 }
02998 
03003 template<typename T, std::size_t N>
03004 array<T, N>
03005 operator-(const array<T, N>& value, const array<T, N>& amount)
03006 {
03007   array<T, N> result = {};
03008   for (std::size_t i = 0; i != N; ++i) {
03009     result[i] = value[i] - amount[i];
03010   }
03011 
03012   return result;
03013 }
03014 
03019 template<typename T, std::size_t N>
03020 array<T, N>
03021 operator-(const T& value, const array<T, N>& amount)
03022 {
03023   array<T, N> result = {};
03024   for (std::size_t i = 0; i != N; ++i) {
03025     result[i] = value - amount[i];
03026   }
03027 
03028   return result;
03029 }
03030 
03035 template<typename T, std::size_t N>
03036 array<T, N>
03037 operator-(const typename uncaptured<T>::type& value, const array<T, N>& amount)
03038 {
03039   array<T, N> result = {};
03040   for (std::size_t i = 0; i != N; ++i) {
03041     result[i] = value - amount[i];
03042   }
03043 
03044   return result;
03045 }
03046 
03051 template<typename T, std::size_t N>
03052 array<T, N>
03053 operator-(const array<T, N>& value, const T& amount)
03054 {
03055   array<T, N> result = {};
03056   for (std::size_t i = 0; i != N; ++i) {
03057     result[i] = value[i] - amount;
03058   }
03059 
03060   return result;
03061 }
03062 
03067 template<typename T, std::size_t N>
03068 array<T, N>
03069 operator-(const array<T, N>& value, const typename uncaptured<T>::type& amount)
03070 {
03071   array<T, N> result = {};
03072   for (std::size_t i = 0; i != N; ++i) {
03073     result[i] = value[i] - amount;
03074   }
03075 
03076   return result;
03077 }
03078 
03083 template<typename T, std::size_t N>
03084 array<T, N>&
03085 operator-=(array<T, N>& value, const array<T, N>& amount)
03086 {
03087   for (std::size_t i = 0; i != N; ++i) {
03088     value[i] -= amount[i];
03089   }
03090 
03091   return value;
03092 }
03093 
03098 template<typename T, std::size_t N>
03099 array<T, N>&
03100 operator-=(array<T, N>& value, const T& amount)
03101 {
03102   for (std::size_t i = 0; i != N; ++i) {
03103     value[i] -= amount;
03104   }
03105 
03106   return value;
03107 }
03108 
03113 template<typename T, std::size_t N>
03114 array<T, N>&
03115 operator-=(array<T, N>& value, const typename uncaptured<T>::type& amount)
03116 {
03117   for (std::size_t i = 0; i != N; ++i) {
03118     value[i] -= amount;
03119   }
03120 
03121   return value;
03122 }
03123 
03128 template<typename T, std::size_t N>
03129 array<T, N>
03130 operator^(const array<T, N>& value, const array<T, N>& mask)
03131 {
03132   array<T, N> result = {};
03133   for (std::size_t i = 0; i != N; ++i) {
03134     result[i] = value[i] ^ mask[i];
03135   }
03136 
03137   return result;
03138 }
03139 
03144 template<typename T, std::size_t N>
03145 array<T, N>
03146 operator^(const T& value, const array<T, N>& mask)
03147 {
03148   array<T, N> result = {};
03149   for (std::size_t i = 0; i != N; ++i) {
03150     result[i] = value ^ mask[i];
03151   }
03152 
03153   return result;
03154 }
03155 
03160 template<typename T, std::size_t N>
03161 array<T, N>
03162 operator^(const typename uncaptured<T>::type& value, const array<T, N>& mask)
03163 {
03164   array<T, N> result = {};
03165   for (std::size_t i = 0; i != N; ++i) {
03166     result[i] = value ^ mask[i];
03167   }
03168 
03169   return result;
03170 }
03171 
03176 template<typename T, std::size_t N>
03177 array<T, N>
03178 operator^(const array<T, N>& value, const T& mask)
03179 {
03180   array<T, N> result = {};
03181   for (std::size_t i = 0; i != N; ++i) {
03182     result[i] = value[i] ^ mask;
03183   }
03184 
03185   return result;
03186 }
03187 
03192 template<typename T, std::size_t N>
03193 array<T, N>
03194 operator^(const array<T, N>& value, const typename uncaptured<T>::type& mask)
03195 {
03196   array<T, N> result = {};
03197   for (std::size_t i = 0; i != N; ++i) {
03198     result[i] = value[i] ^ mask;
03199   }
03200 
03201   return result;
03202 }
03203 
03208 template<typename T, std::size_t N>
03209 array<T, N>&
03210 operator^=(array<T, N>& value, const array<T, N>& mask)
03211 {
03212   for (std::size_t i = 0; i != N; ++i) {
03213     value[i] ^= mask[i];
03214   }
03215 
03216   return value;
03217 }
03218 
03223 template<typename T, std::size_t N>
03224 array<T, N>&
03225 operator^=(array<T, N>& value, const T& mask)
03226 {
03227   for (std::size_t i = 0; i != N; ++i) {
03228     value[i] ^= mask;
03229   }
03230 
03231   return value;
03232 }
03233 
03238 template<typename T, std::size_t N>
03239 array<T, N>&
03240 operator^=(array<T, N>& value, const typename uncaptured<T>::type& mask)
03241 {
03242   for (std::size_t i = 0; i != N; ++i) {
03243     value[i] ^= mask;
03244   }
03245 
03246   return value;
03247 }
03248 
03254 template<typename T, std::size_t N>
03255 array<T, N>
03256 select(const array<typename boolean_type<T>::type, N>& condition, const array<T, N>& true_case, const array<T, N>& false_case)
03257 {
03258   using detail::select;
03259   array<T, N> result = {};
03260   for (std::size_t i = 0; i != N; ++i) {
03261     result[i] = select(condition[i], true_case[i], false_case[i]);
03262   }
03263 
03264   return result;
03265 }
03266 
03272 template<typename T, std::size_t N>
03273 array<T, N>
03274 select(const typename boolean_type<T>::type& condition, const array<T, N>& true_case, const array<T, N>& false_case)
03275 {
03276   using detail::select;
03277   array<T, N> result = {};
03278   for (std::size_t i = 0; i != N; ++i) {
03279     result[i] = select(condition, true_case[i], false_case[i]);
03280   }
03281 
03282   return result;
03283 }
03284 
03290 template<typename T, std::size_t N>
03291 array<T, N>
03292 select(const typename uncaptured<typename boolean_type<T>::type>::type& condition, const array<T, N>& true_case, const array<T, N>& false_case)
03293 {
03294   using detail::select;
03295   array<T, N> result = {};
03296   for (std::size_t i = 0; i != N; ++i) {
03297     result[i] = select(condition, true_case[i], false_case[i]);
03298   }
03299 
03300   return result;
03301 }
03302 
03308 template<typename T, std::size_t N>
03309 array<T, N>
03310 select(const array<typename boolean_type<T>::type, N>& condition, const T& true_case, const array<T, N>& false_case)
03311 {
03312   using detail::select;
03313   array<T, N> result = {};
03314   for (std::size_t i = 0; i != N; ++i) {
03315     result[i] = select(condition[i], true_case, false_case[i]);
03316   }
03317 
03318   return result;
03319 }
03320 
03326 template<typename T, std::size_t N>
03327 array<T, N>
03328 select(const array<typename boolean_type<T>::type, N>& condition, const typename uncaptured<T>::type& true_case, const array<T, N>& false_case)
03329 {
03330   using detail::select;
03331   array<T, N> result = {};
03332   for (std::size_t i = 0; i != N; ++i) {
03333     result[i] = select(condition[i], true_case, false_case[i]);
03334   }
03335 
03336   return result;
03337 }
03338 
03344 template<typename T, std::size_t N>
03345 array<T, N>
03346 select(const typename boolean_type<T>::type& condition, const T& true_case, const array<T, N>& false_case)
03347 {
03348   using detail::select;
03349   array<T, N> result = {};
03350   for (std::size_t i = 0; i != N; ++i) {
03351     result[i] = select(condition, true_case, false_case[i]);
03352   }
03353 
03354   return result;
03355 }
03356 
03362 template<typename T, std::size_t N>
03363 array<T, N>
03364 select(const typename uncaptured<typename boolean_type<T>::type>::type& condition, const typename uncaptured<T>::type& true_case, const array<T, N>& false_case)
03365 {
03366   using detail::select;
03367   array<T, N> result = {};
03368   for (std::size_t i = 0; i != N; ++i) {
03369     result[i] = select(condition, true_case, false_case[i]);
03370   }
03371 
03372   return result;
03373 }
03374 
03380 template<typename T, std::size_t N>
03381 array<T, N>
03382 select(const array<typename boolean_type<T>::type, N>& condition, const array<T, N>& true_case, const T& false_case)
03383 {
03384   using detail::select;
03385   array<T, N> result = {};
03386   for (std::size_t i = 0; i != N; ++i) {
03387     result[i] = select(condition[i], true_case[i], false_case);
03388   }
03389 
03390   return result;
03391 }
03392 
03398 template<typename T, std::size_t N>
03399 array<T, N>
03400 select(const array<typename boolean_type<T>::type, N>& condition, const array<T, N>& true_case, const typename uncaptured<T>::type& false_case)
03401 {
03402   using detail::select;
03403   array<T, N> result = {};
03404   for (std::size_t i = 0; i != N; ++i) {
03405     result[i] = select(condition[i], true_case[i], false_case);
03406   }
03407 
03408   return result;
03409 }
03410 
03416 template<typename T, std::size_t N>
03417 array<T, N>
03418 select(const typename boolean_type<T>::type& condition, const array<T, N>& true_case, const T& false_case)
03419 {
03420   using detail::select;
03421   array<T, N> result = {};
03422   for (std::size_t i = 0; i != N; ++i) {
03423     result[i] = select(condition, true_case[i], false_case);
03424   }
03425 
03426   return result;
03427 }
03428 
03434 template<typename T, std::size_t N>
03435 array<T, N>
03436 select(const typename uncaptured<typename boolean_type<T>::type>::type& condition, const array<T, N>& true_case, const typename uncaptured<T>::type& false_case)
03437 {
03438   using detail::select;
03439   array<T, N> result = {};
03440   for (std::size_t i = 0; i != N; ++i) {
03441     result[i] = select(condition, true_case[i], false_case);
03442   }
03443 
03444   return result;
03445 }
03446 
03452 template<typename T, std::size_t N>
03453 array<T, N>
03454 select(const array<typename boolean_type<T>::type, N>& condition, const T& true_case, const T& false_case)
03455 {
03456   using detail::select;
03457   array<T, N> result = {};
03458   for (std::size_t i = 0; i != N; ++i) {
03459     result[i] = select(condition[i], true_case, false_case);
03460   }
03461 
03462   return result;
03463 }
03464 
03468 template<typename T, std::size_t N>
03469 array<T, N>&
03470 operator++(array<T, N>& value)
03471 {
03472   for (std::size_t i = 0; i != N; ++i) {
03473     ++value[i];
03474   }
03475 
03476   return value;
03477 }
03478 
03482 template<typename T, std::size_t N>
03483 array<T, N>
03484 operator++(array<T, N>& value, int)
03485 {
03486   array<T, N> original_value = value;
03487   for (std::size_t i = 0; i != N; ++i) {
03488     value[i]++;
03489   }
03490 
03491   return original_value;
03492 }
03493 
03497 template<typename T, std::size_t N>
03498 array<T, N>&
03499 operator--(array<T, N>& value)
03500 {
03501   for (std::size_t i = 0; i != N; ++i) {
03502     --value[i];
03503   }
03504 
03505   return value;
03506 }
03507 
03511 template<typename T, std::size_t N>
03512 array<T, N>
03513 operator--(array<T, N>& value, int)
03514 {
03515   array<T, N> original_value = value;
03516   for (std::size_t i = 0; i != N; ++i) {
03517     value[i]--;
03518   }
03519 
03520   return original_value;
03521 }
03522 
03524 
03527 
03531 template<typename T, std::size_t N>
03532 T
03533 add_reduce(const array<T, N>& source)
03534 {
03535   T result = source.at(0);
03536   // avoid warnings: pointless comparison, constant control flow
03537   for (std::size_t i = 1, n = N; i != n && 0 != n; ++i) {
03538     result = result + source[i];
03539   }
03540 
03541   return result;
03542 }
03543 
03547 template<typename T, std::size_t N>
03548 T
03549 mul_reduce(const array<T, N>& source)
03550 {
03551   T result = source.at(0);
03552   // avoid warnings: pointless comparison, constant control flow
03553   for (std::size_t i = 1, n = N; i != n && 0 != n; ++i) {
03554     result = result * source[i];
03555   }
03556 
03557   return result;
03558 }
03559 
03563 template<typename T, std::size_t N>
03564 T
03565 min_reduce(const array<T, N>& source)
03566 {
03567   using std::min;
03568   
03569   T result = source.at(0);
03570   // avoid warnings: pointless comparison, constant control flow
03571   for (std::size_t i = 1, n = N; i != n && 0 != n; ++i) {
03572     result = min(result, source[i]);
03573   }
03574 
03575   return result;
03576 }
03577 
03581 template<typename T, std::size_t N>
03582 T
03583 max_reduce(const array<T, N>& source)
03584 {
03585   using std::max;
03586   
03587   T result = source.at(0);
03588   // avoid warnings: pointless comparison, constant control flow
03589   for (std::size_t i = 1, n = N; i != n && 0 != n; ++i) {
03590     result = max(result, source[i]);
03591   }
03592 
03593   return result;
03594 }
03595 
03599 template<typename T, std::size_t N>
03600 T
03601 and_reduce(const array<T, N>& source)
03602 {
03603   T result = true;
03604   // avoid warnings: pointless comparison, constant control flow
03605   for (std::size_t i = 0, n = N; i != n && 0 != n; ++i) {
03606     result = result && source[i];
03607   }
03608 
03609   return result;
03610 }
03611 
03615 template<typename T, std::size_t N>
03616 T
03617 ior_reduce(const array<T, N>& source)
03618 {
03619   T result = false;
03620   // avoid warnings: pointless comparison, constant control flow
03621   for (std::size_t i = 0, n = N; i != n && 0 != n; ++i) {
03622     result = result || source[i];
03623   }
03624 
03625   return result;
03626 }
03627 
03631 template<typename T, std::size_t N>
03632 T
03633 xor_reduce(const array<T, N>& source)
03634 {
03635   T result = source.at(0);
03636   // avoid warnings: pointless comparison, constant control flow
03637   for (std::size_t i = 1, n = N; i != n && 0 != n; ++i) {
03638     result = result != source[i];
03639   }
03640 
03641   return result;
03642 }
03643 
03645 
03648 
03652 template <std::size_t M, typename T, std::size_t N>
03653 array<T, M>
03654 resize(const array<T, N>& a, const T& value)
03655 {
03656   array<T, M> result = {};
03657   const std::size_t min_size = std::min(M, N);
03658 
03659   std::copy(a.begin(), a.begin() + min_size, result.begin());
03660   std::fill(result.begin() + min_size, result.end(), value);
03661 
03662   return result;
03663 }
03664 
03668 template <std::size_t M, typename T, std::size_t N>
03669 array<T, M>
03670 resize(const array<T, N>& a)
03671 {
03672   const T zero = static_cast<T>(0);
03673   return resize<M>(a, zero);
03674 }
03675 
03678 template <typename T, std::size_t M, std::size_t N>
03679 array<T, M + N>
03680 cat(const array<T, M>& a, const array<T, N>& b)
03681 {
03682   array<T, M + N> result = {};
03683 
03684   std::copy(a.begin(), a.end(), result.begin());
03685   std::copy(b.begin(), b.end(), result.begin() + M);
03686 
03687   return result;
03688 }
03689 
03691 
03694 
03698 template <typename Dest, typename Source, std::size_t N>
03699 array<Dest, N> bitwise_cast(const array<Source, N>& value)
03700 {
03701   using detail::bitwise_cast;
03702   using ARBB_CPP_NS::bitwise_cast;
03703 
03704   array<Dest, N> result = {};
03705   for (std::size_t i = 0; i != N; ++i) {
03706     result[i] = bitwise_cast<Dest>(value[i]);
03707   }
03708 
03709   return result;
03710 }
03711 
03717 template<typename U, std::size_t N>
03718 typename detail::disable_if<!detail::is_uncaptured_scalar<U>::value, array<typename captured<U>::type, N> >::type
03719 select(const array<typename boolean_type<typename captured<U>::type>::type, N>& condition, const U& true_case, const U& false_case)
03720 {
03721   using detail::select;
03722   array<typename captured<U>::type, N> result = {};
03723   for (std::size_t i = 0; i != N; ++i) {
03724     result[i] = select(condition[i], true_case, false_case);
03725   }
03726 
03727   return result;
03728 }
03729 
03731 
03734 
03736 template <typename T, std::size_t N>
03737 ARBB_CPP_NS::boolean
03738 any(const array<T, N>& source)
03739 {
03740   return ior_reduce(source);
03741 }
03742 
03744 template <typename T, std::size_t N>
03745 ARBB_CPP_NS::boolean
03746 all(const array<T, N>& source)
03747 {
03748   return and_reduce(source);
03749 }
03750 
03752 template <typename T, std::size_t N>
03753 T
03754 sum(const array<T, N>& source)
03755 {
03756   return add_reduce(source);
03757 }
03758 
03760 template <typename T, std::size_t N>
03761 T
03762 product(const array<T, N>& source)
03763 {
03764   return mul_reduce(source);
03765 }
03766 
03768  
03769 
03770 
03771 } // namespace ARBB_CPP_NS
03772 
03773 
03774 
03775 #endif // ARBB_CPP_ARRAY_FUNCS_HPP
03776 
03777 

Submit feedback on this help topic

Copyright © 2010, Intel Corporation. All rights reserved.