00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 #ifndef _GLIBCXX_VALARRAY
00039 #define _GLIBCXX_VALARRAY 1
00040 
00041 #pragma GCC system_header
00042 
00043 #include <bits/c++config.h>
00044 #include <cstddef>
00045 #include <cmath>
00046 #include <cstdlib>
00047 #include <numeric>
00048 #include <algorithm>
00049 #include <debug/debug.h>
00050 
00051 namespace std
00052 {
00053   template<class _Clos, typename _Tp> 
00054     class _Expr;
00055 
00056   template<typename _Tp1, typename _Tp2> 
00057     class _ValArray;    
00058 
00059   template<class _Oper, template<class, class> class _Meta, class _Dom>
00060     struct _UnClos;
00061 
00062   template<class _Oper,
00063         template<class, class> class _Meta1,
00064         template<class, class> class _Meta2,
00065         class _Dom1, class _Dom2> 
00066     class _BinClos;
00067 
00068   template<template<class, class> class _Meta, class _Dom> 
00069     class _SClos;
00070 
00071   template<template<class, class> class _Meta, class _Dom> 
00072     class _GClos;
00073     
00074   template<template<class, class> class _Meta, class _Dom> 
00075     class _IClos;
00076     
00077   template<template<class, class> class _Meta, class _Dom> 
00078     class _ValFunClos;
00079   
00080   template<template<class, class> class _Meta, class _Dom> 
00081     class _RefFunClos;
00082 
00083   template<class _Tp> class valarray;   
00084   class slice;                          
00085   template<class _Tp> class slice_array;
00086   class gslice;                         
00087   template<class _Tp> class gslice_array;
00088   template<class _Tp> class mask_array;     
00089   template<class _Tp> class indirect_array; 
00090 
00091 } 
00092 
00093 #include <bits/valarray_array.h>
00094 #include <bits/valarray_before.h>
00095   
00096 namespace std
00097 {
00098 
00099 
00100 
00101 
00102 
00103 
00104 
00105 
00106 
00107 
00108 
00109   template<class _Tp> 
00110     class valarray
00111     {
00112       template<class _Op>
00113     struct _UnaryOp 
00114     {
00115       typedef typename __fun<_Op, _Tp>::result_type __rt;
00116       typedef _Expr<_UnClos<_Op, _ValArray, _Tp>, __rt> _Rt;
00117     };
00118     public:
00119       typedef _Tp value_type;
00120       
00121     
00122 
00123       valarray();
00124 
00125 
00126       explicit valarray(size_t);
00127 
00128 
00129       valarray(const _Tp&, size_t);
00130 
00131 
00132       valarray(const _Tp* __restrict__, size_t);
00133 
00134 
00135       valarray(const valarray&);
00136 
00137 
00138       valarray(const slice_array<_Tp>&);
00139 
00140 
00141       valarray(const gslice_array<_Tp>&);
00142 
00143 
00144       valarray(const mask_array<_Tp>&);
00145 
00146 
00147       valarray(const indirect_array<_Tp>&);
00148 
00149       template<class _Dom>
00150     valarray(const _Expr<_Dom,_Tp>& __e);
00151       ~valarray();
00152 
00153       
00154 
00155 
00156 
00157 
00158 
00159 
00160 
00161 
00162       valarray<_Tp>& operator=(const valarray<_Tp>&);
00163 
00164 
00165 
00166 
00167 
00168 
00169 
00170 
00171       valarray<_Tp>& operator=(const _Tp&);
00172 
00173 
00174 
00175 
00176 
00177 
00178 
00179 
00180 
00181       valarray<_Tp>& operator=(const slice_array<_Tp>&);
00182 
00183 
00184 
00185 
00186 
00187 
00188 
00189 
00190 
00191       valarray<_Tp>& operator=(const gslice_array<_Tp>&);
00192 
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 
00201       valarray<_Tp>& operator=(const mask_array<_Tp>&);
00202 
00203 
00204 
00205 
00206 
00207 
00208 
00209 
00210 
00211       valarray<_Tp>& operator=(const indirect_array<_Tp>&);
00212 
00213       template<class _Dom> valarray<_Tp>&
00214     operator= (const _Expr<_Dom,_Tp>&);
00215 
00216       
00217 
00218 
00219 
00220 
00221 
00222 
00223       _Tp&                operator[](size_t);
00224 
00225       
00226       
00227       const _Tp&          operator[](size_t) const;
00228 
00229       
00230 
00231 
00232 
00233 
00234 
00235 
00236 
00237 
00238 
00239 
00240       _Expr<_SClos<_ValArray,_Tp>, _Tp> operator[](slice) const;
00241 
00242 
00243 
00244 
00245 
00246 
00247 
00248 
00249 
00250 
00251 
00252       slice_array<_Tp>    operator[](slice);
00253 
00254 
00255 
00256 
00257 
00258 
00259 
00260 
00261 
00262 
00263       _Expr<_GClos<_ValArray,_Tp>, _Tp> operator[](const gslice&) const;
00264 
00265 
00266 
00267 
00268 
00269 
00270 
00271 
00272 
00273 
00274 
00275       gslice_array<_Tp>   operator[](const gslice&);
00276 
00277 
00278 
00279 
00280 
00281 
00282 
00283 
00284 
00285 
00286 
00287 
00288 
00289       valarray<_Tp>          operator[](const valarray<bool>&) const;
00290 
00291 
00292 
00293 
00294 
00295 
00296 
00297 
00298 
00299 
00300 
00301 
00302 
00303       mask_array<_Tp>     operator[](const valarray<bool>&);
00304 
00305 
00306 
00307 
00308 
00309 
00310 
00311 
00312 
00313 
00314 
00315 
00316       _Expr<_IClos<_ValArray, _Tp>, _Tp>
00317         operator[](const valarray<size_t>&) const;
00318 
00319 
00320 
00321 
00322 
00323 
00324 
00325 
00326 
00327 
00328 
00329 
00330 
00331       indirect_array<_Tp> operator[](const valarray<size_t>&);
00332 
00333       
00334 
00335       typename _UnaryOp<__unary_plus>::_Rt  operator+() const;
00336 
00337 
00338       typename _UnaryOp<__negate>::_Rt      operator-() const;
00339 
00340 
00341       typename _UnaryOp<__bitwise_not>::_Rt operator~() const;
00342 
00343 
00344       typename _UnaryOp<__logical_not>::_Rt operator!() const;
00345 
00346       
00347 
00348       valarray<_Tp>& operator*=(const _Tp&);
00349 
00350 
00351       valarray<_Tp>& operator/=(const _Tp&);
00352 
00353 
00354       valarray<_Tp>& operator%=(const _Tp&);
00355 
00356 
00357       valarray<_Tp>& operator+=(const _Tp&);
00358 
00359 
00360       valarray<_Tp>& operator-=(const _Tp&);
00361 
00362 
00363       valarray<_Tp>& operator^=(const _Tp&);
00364 
00365 
00366       valarray<_Tp>& operator&=(const _Tp&);
00367 
00368 
00369       valarray<_Tp>& operator|=(const _Tp&);
00370 
00371 
00372       valarray<_Tp>& operator<<=(const _Tp&);
00373 
00374 
00375       valarray<_Tp>& operator>>=(const _Tp&);
00376 
00377 
00378       valarray<_Tp>& operator*=(const valarray<_Tp>&);
00379 
00380 
00381       valarray<_Tp>& operator/=(const valarray<_Tp>&);
00382 
00383 
00384       valarray<_Tp>& operator%=(const valarray<_Tp>&);
00385 
00386 
00387       valarray<_Tp>& operator+=(const valarray<_Tp>&);
00388 
00389 
00390       valarray<_Tp>& operator-=(const valarray<_Tp>&);
00391 
00392 
00393       valarray<_Tp>& operator^=(const valarray<_Tp>&);
00394 
00395 
00396       valarray<_Tp>& operator|=(const valarray<_Tp>&);
00397 
00398 
00399       valarray<_Tp>& operator&=(const valarray<_Tp>&);
00400 
00401 
00402       valarray<_Tp>& operator<<=(const valarray<_Tp>&);
00403 
00404 
00405       valarray<_Tp>& operator>>=(const valarray<_Tp>&);
00406 
00407       template<class _Dom>
00408     valarray<_Tp>& operator*=(const _Expr<_Dom,_Tp>&);
00409       template<class _Dom>
00410     valarray<_Tp>& operator/=(const _Expr<_Dom,_Tp>&);
00411       template<class _Dom>
00412     valarray<_Tp>& operator%=(const _Expr<_Dom,_Tp>&);
00413       template<class _Dom>
00414     valarray<_Tp>& operator+=(const _Expr<_Dom,_Tp>&);
00415       template<class _Dom>
00416     valarray<_Tp>& operator-=(const _Expr<_Dom,_Tp>&);
00417       template<class _Dom>
00418     valarray<_Tp>& operator^=(const _Expr<_Dom,_Tp>&);
00419       template<class _Dom>
00420     valarray<_Tp>& operator|=(const _Expr<_Dom,_Tp>&);
00421       template<class _Dom>
00422     valarray<_Tp>& operator&=(const _Expr<_Dom,_Tp>&);
00423       template<class _Dom>
00424       valarray<_Tp>& operator<<=(const _Expr<_Dom,_Tp>&);
00425       template<class _Dom>
00426     valarray<_Tp>& operator>>=(const _Expr<_Dom,_Tp>&);
00427 
00428 
00429       
00430 
00431       size_t size() const;
00432 
00433 
00434 
00435 
00436 
00437 
00438 
00439       _Tp    sum() const;
00440 
00441 
00442       _Tp    min() const;   
00443 
00444 
00445       _Tp    max() const;   
00446 
00447   
00448   
00449 
00450 
00451 
00452 
00453 
00454 
00455 
00456 
00457 
00458 
00459 
00460 
00461 
00462 
00463 
00464 
00465       valarray<_Tp> shift (int) const;
00466 
00467 
00468 
00469 
00470 
00471 
00472 
00473 
00474 
00475 
00476 
00477 
00478 
00479 
00480 
00481 
00482       valarray<_Tp> cshift(int) const;
00483 
00484 
00485 
00486 
00487 
00488 
00489 
00490 
00491 
00492 
00493 
00494       _Expr<_ValFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(_Tp)) const;
00495 
00496 
00497 
00498 
00499 
00500 
00501 
00502 
00503 
00504 
00505 
00506       _Expr<_RefFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(const _Tp&)) const;
00507 
00508 
00509 
00510 
00511 
00512 
00513 
00514 
00515 
00516 
00517       void resize(size_t __size, _Tp __c = _Tp());
00518 
00519     private:
00520       size_t _M_size;
00521       _Tp* __restrict__ _M_data;
00522       
00523       friend class _Array<_Tp>;
00524     };
00525   
00526   template<typename _Tp>
00527     inline const _Tp&
00528     valarray<_Tp>::operator[](size_t __i) const
00529     { 
00530       __glibcxx_requires_subscript(__i);
00531       return _M_data[__i]; 
00532     }
00533 
00534   template<typename _Tp>
00535     inline _Tp&
00536     valarray<_Tp>::operator[](size_t __i)
00537     { 
00538       __glibcxx_requires_subscript(__i);
00539       return _M_data[__i]; 
00540     }
00541 
00542 } 
00543 
00544 #include <bits/valarray_after.h>
00545 
00546 #include <bits/slice_array.h>
00547 #include <bits/gslice.h>
00548 #include <bits/gslice_array.h>
00549 #include <bits/mask_array.h>
00550 #include <bits/indirect_array.h>
00551 
00552 namespace std
00553 {
00554   template<typename _Tp>
00555     inline
00556     valarray<_Tp>::valarray() : _M_size(0), _M_data(0) {}
00557 
00558   template<typename _Tp>
00559     inline 
00560     valarray<_Tp>::valarray(size_t __n) 
00561     : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
00562     { std::__valarray_default_construct(_M_data, _M_data + __n); }
00563 
00564   template<typename _Tp>
00565     inline
00566     valarray<_Tp>::valarray(const _Tp& __t, size_t __n)
00567       : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
00568     { std::__valarray_fill_construct(_M_data, _M_data + __n, __t); }
00569 
00570   template<typename _Tp>
00571     inline
00572     valarray<_Tp>::valarray(const _Tp* __restrict__ __p, size_t __n)
00573       : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
00574     { 
00575       _GLIBCXX_DEBUG_ASSERT(__p != 0 || __n == 0);
00576       std::__valarray_copy_construct(__p, __p + __n, _M_data); 
00577     }
00578 
00579   template<typename _Tp>
00580     inline
00581     valarray<_Tp>::valarray(const valarray<_Tp>& __v)
00582       : _M_size(__v._M_size), _M_data(__valarray_get_storage<_Tp>(__v._M_size))
00583     { std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size, _M_data); }
00584 
00585   template<typename _Tp>
00586     inline
00587     valarray<_Tp>::valarray(const slice_array<_Tp>& __sa)
00588       : _M_size(__sa._M_sz), _M_data(__valarray_get_storage<_Tp>(__sa._M_sz))
00589     {
00590       std::__valarray_copy
00591     (__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data));
00592     }
00593 
00594   template<typename _Tp>
00595     inline
00596     valarray<_Tp>::valarray(const gslice_array<_Tp>& __ga)
00597       : _M_size(__ga._M_index.size()),
00598     _M_data(__valarray_get_storage<_Tp>(_M_size))
00599     {
00600       std::__valarray_copy
00601     (__ga._M_array, _Array<size_t>(__ga._M_index),
00602      _Array<_Tp>(_M_data), _M_size);
00603     }
00604 
00605   template<typename _Tp>
00606     inline
00607     valarray<_Tp>::valarray(const mask_array<_Tp>& __ma)
00608       : _M_size(__ma._M_sz), _M_data(__valarray_get_storage<_Tp>(__ma._M_sz))
00609     {
00610       std::__valarray_copy
00611     (__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size);
00612     }
00613 
00614   template<typename _Tp>
00615     inline
00616     valarray<_Tp>::valarray(const indirect_array<_Tp>& __ia)
00617       : _M_size(__ia._M_sz), _M_data(__valarray_get_storage<_Tp>(__ia._M_sz))
00618     {
00619       std::__valarray_copy
00620     (__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size);
00621     }
00622 
00623   template<typename _Tp> template<class _Dom>
00624     inline
00625     valarray<_Tp>::valarray(const _Expr<_Dom, _Tp>& __e)
00626       : _M_size(__e.size()), _M_data(__valarray_get_storage<_Tp>(_M_size))
00627     { std::__valarray_copy(__e, _M_size, _Array<_Tp>(_M_data)); }
00628 
00629   template<typename _Tp>
00630     inline
00631     valarray<_Tp>::~valarray()
00632     {
00633       std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
00634       std::__valarray_release_memory(_M_data);
00635     }
00636 
00637   template<typename _Tp>
00638     inline valarray<_Tp>&
00639     valarray<_Tp>::operator=(const valarray<_Tp>& __v)
00640     {
00641       _GLIBCXX_DEBUG_ASSERT(_M_size == __v._M_size);
00642       std::__valarray_copy(__v._M_data, _M_size, _M_data);
00643       return *this;
00644     }
00645 
00646   template<typename _Tp>
00647     inline valarray<_Tp>&
00648     valarray<_Tp>::operator=(const _Tp& __t)
00649     {
00650       std::__valarray_fill(_M_data, _M_size, __t);
00651       return *this;
00652     }
00653 
00654   template<typename _Tp>
00655     inline valarray<_Tp>&
00656     valarray<_Tp>::operator=(const slice_array<_Tp>& __sa)
00657     {
00658       _GLIBCXX_DEBUG_ASSERT(_M_size == __sa._M_sz);
00659       std::__valarray_copy(__sa._M_array, __sa._M_sz,
00660                __sa._M_stride, _Array<_Tp>(_M_data));
00661       return *this;
00662     }
00663 
00664   template<typename _Tp>
00665     inline valarray<_Tp>&
00666     valarray<_Tp>::operator=(const gslice_array<_Tp>& __ga)
00667     {
00668       _GLIBCXX_DEBUG_ASSERT(_M_size == __ga._M_index.size());
00669       std::__valarray_copy(__ga._M_array, _Array<size_t>(__ga._M_index),
00670                _Array<_Tp>(_M_data), _M_size);
00671       return *this;
00672     }
00673 
00674   template<typename _Tp>
00675     inline valarray<_Tp>&
00676     valarray<_Tp>::operator=(const mask_array<_Tp>& __ma)
00677     {
00678       _GLIBCXX_DEBUG_ASSERT(_M_size == __ma._M_sz);
00679       std::__valarray_copy(__ma._M_array, __ma._M_mask,
00680                _Array<_Tp>(_M_data), _M_size);
00681       return *this;
00682     }
00683 
00684   template<typename _Tp>
00685     inline valarray<_Tp>&
00686     valarray<_Tp>::operator=(const indirect_array<_Tp>& __ia)
00687     {
00688       _GLIBCXX_DEBUG_ASSERT(_M_size == __ia._M_sz);
00689       std::__valarray_copy(__ia._M_array, __ia._M_index,
00690                _Array<_Tp>(_M_data), _M_size);
00691       return *this;
00692     }
00693 
00694   template<typename _Tp> template<class _Dom>
00695     inline valarray<_Tp>&
00696     valarray<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e)
00697     {
00698       _GLIBCXX_DEBUG_ASSERT(_M_size == __e.size());
00699       std::__valarray_copy(__e, _M_size, _Array<_Tp>(_M_data));
00700       return *this;
00701     }
00702 
00703   template<typename _Tp>
00704     inline _Expr<_SClos<_ValArray,_Tp>, _Tp>
00705     valarray<_Tp>::operator[](slice __s) const
00706     {
00707       typedef _SClos<_ValArray,_Tp> _Closure;
00708       return _Expr<_Closure, _Tp>(_Closure (_Array<_Tp>(_M_data), __s));
00709     }
00710 
00711   template<typename _Tp>
00712     inline slice_array<_Tp>
00713     valarray<_Tp>::operator[](slice __s)
00714     {
00715       return slice_array<_Tp>(_Array<_Tp>(_M_data), __s);
00716     }
00717 
00718   template<typename _Tp>
00719     inline _Expr<_GClos<_ValArray,_Tp>, _Tp>
00720     valarray<_Tp>::operator[](const gslice& __gs) const
00721     {
00722       typedef _GClos<_ValArray,_Tp> _Closure;
00723       return _Expr<_Closure, _Tp>
00724     (_Closure(_Array<_Tp>(_M_data), __gs._M_index->_M_index));
00725     }
00726 
00727   template<typename _Tp>
00728     inline gslice_array<_Tp>
00729     valarray<_Tp>::operator[](const gslice& __gs)
00730     {
00731       return gslice_array<_Tp>
00732     (_Array<_Tp>(_M_data), __gs._M_index->_M_index);
00733     }
00734 
00735   template<typename _Tp>
00736     inline valarray<_Tp>
00737     valarray<_Tp>::operator[](const valarray<bool>& __m) const
00738     {
00739       size_t __s = 0;
00740       size_t __e = __m.size();
00741       for (size_t __i=0; __i<__e; ++__i)
00742     if (__m[__i]) ++__s;
00743       return valarray<_Tp>(mask_array<_Tp>(_Array<_Tp>(_M_data), __s,
00744                        _Array<bool> (__m)));
00745     }
00746 
00747   template<typename _Tp>
00748     inline mask_array<_Tp>
00749     valarray<_Tp>::operator[](const valarray<bool>& __m)
00750     {
00751       size_t __s = 0;
00752       size_t __e = __m.size();
00753       for (size_t __i=0; __i<__e; ++__i)
00754     if (__m[__i]) ++__s;
00755       return mask_array<_Tp>(_Array<_Tp>(_M_data), __s, _Array<bool>(__m));
00756     }
00757 
00758   template<typename _Tp>
00759     inline _Expr<_IClos<_ValArray,_Tp>, _Tp>
00760     valarray<_Tp>::operator[](const valarray<size_t>& __i) const
00761     {
00762       typedef _IClos<_ValArray,_Tp> _Closure;
00763       return _Expr<_Closure, _Tp>(_Closure(*this, __i));
00764     }
00765 
00766   template<typename _Tp>
00767     inline indirect_array<_Tp>
00768     valarray<_Tp>::operator[](const valarray<size_t>& __i)
00769     {
00770       return indirect_array<_Tp>(_Array<_Tp>(_M_data), __i.size(),
00771                  _Array<size_t>(__i));
00772     }
00773 
00774   template<class _Tp>
00775     inline size_t 
00776     valarray<_Tp>::size() const
00777     { return _M_size; }
00778 
00779   template<class _Tp>
00780     inline _Tp
00781     valarray<_Tp>::sum() const
00782     {
00783       _GLIBCXX_DEBUG_ASSERT(_M_size > 0);
00784       return std::__valarray_sum(_M_data, _M_data + _M_size);
00785     }
00786 
00787 
00788 
00789 
00790 
00791 
00792 
00793 
00794   template <class _Tp>
00795      inline valarray<_Tp>
00796      valarray<_Tp>::shift(int __n) const
00797      {
00798        _Tp* const __a = static_cast<_Tp*>
00799          (__builtin_alloca(sizeof(_Tp) * _M_size));
00800        if (__n == 0)                          
00801          std::__valarray_copy_construct(_M_data, _M_data + _M_size, __a);
00802        else if (__n > 0)         
00803          {                 
00804            if (size_t(__n) > _M_size)
00805              std::__valarray_default_construct(__a, __a + __n);
00806            else
00807              {
00808                std::__valarray_copy_construct(_M_data+__n, _M_data + _M_size, __a);
00809                std::__valarray_default_construct(__a+_M_size-__n, __a + _M_size);
00810              }
00811          }
00812        else                        
00813          {                          
00814            std::__valarray_copy_construct (_M_data, _M_data+_M_size+__n, __a-__n);
00815            std::__valarray_default_construct(__a, __a - __n);
00816          }
00817        return valarray<_Tp> (__a, _M_size);
00818      }
00819 
00820   template <class _Tp>
00821      inline valarray<_Tp>
00822      valarray<_Tp>::cshift (int __n) const
00823      {
00824        _Tp* const __a = static_cast<_Tp*>
00825          (__builtin_alloca (sizeof(_Tp) * _M_size));
00826        if (__n == 0)               
00827          std::__valarray_copy_construct(_M_data, _M_data + _M_size, __a);
00828        else if (__n > 0)           
00829          {               
00830            std::__valarray_copy_construct(_M_data, _M_data+__n, __a+_M_size-__n);
00831            std::__valarray_copy_construct(_M_data+__n, _M_data + _M_size, __a);
00832          }
00833        else                        
00834          {                       
00835            std::__valarray_copy_construct
00836              (_M_data + _M_size+__n, _M_data + _M_size, __a);
00837            std::__valarray_copy_construct
00838              (_M_data, _M_data + _M_size+__n, __a - __n);
00839          }
00840        return valarray<_Tp>(__a, _M_size);
00841      }
00842 
00843   template <class _Tp>
00844     inline void
00845     valarray<_Tp>::resize (size_t __n, _Tp __c)
00846     {
00847       
00848       
00849       
00850       std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
00851       if (_M_size != __n)
00852     {
00853       std::__valarray_release_memory(_M_data);
00854       _M_size = __n;
00855       _M_data = __valarray_get_storage<_Tp>(__n);
00856     }
00857       std::__valarray_fill_construct(_M_data, _M_data + __n, __c);
00858     }
00859     
00860   template<typename _Tp>
00861     inline _Tp
00862     valarray<_Tp>::min() const
00863     {
00864       _GLIBCXX_DEBUG_ASSERT(_M_size > 0);
00865       return *std::min_element (_M_data, _M_data+_M_size);
00866     }
00867 
00868   template<typename _Tp>
00869     inline _Tp
00870     valarray<_Tp>::max() const
00871     {
00872       _GLIBCXX_DEBUG_ASSERT(_M_size > 0);
00873       return *std::max_element (_M_data, _M_data+_M_size);
00874     }
00875   
00876   template<class _Tp>
00877     inline _Expr<_ValFunClos<_ValArray,_Tp>,_Tp>
00878     valarray<_Tp>::apply(_Tp func(_Tp)) const
00879     {
00880       typedef _ValFunClos<_ValArray,_Tp> _Closure;
00881       return _Expr<_Closure,_Tp>(_Closure(*this, func));
00882     }
00883 
00884   template<class _Tp>
00885     inline _Expr<_RefFunClos<_ValArray,_Tp>,_Tp>
00886     valarray<_Tp>::apply(_Tp func(const _Tp &)) const
00887     {
00888       typedef _RefFunClos<_ValArray,_Tp> _Closure;
00889       return _Expr<_Closure,_Tp>(_Closure(*this, func));
00890     }
00891 
00892 #define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name)                     \
00893   template<typename _Tp>                        \
00894   inline typename valarray<_Tp>::template _UnaryOp<_Name>::_Rt          \
00895   valarray<_Tp>::operator _Op() const                   \
00896   {                                 \
00897     typedef _UnClos<_Name,_ValArray,_Tp> _Closure;                  \
00898     typedef typename __fun<_Name, _Tp>::result_type _Rt;                \
00899     return _Expr<_Closure, _Rt>(_Closure(*this));           \
00900   }
00901 
00902     _DEFINE_VALARRAY_UNARY_OPERATOR(+, __unary_plus)
00903     _DEFINE_VALARRAY_UNARY_OPERATOR(-, __negate)
00904     _DEFINE_VALARRAY_UNARY_OPERATOR(~, __bitwise_not)
00905     _DEFINE_VALARRAY_UNARY_OPERATOR (!, __logical_not)
00906 
00907 #undef _DEFINE_VALARRAY_UNARY_OPERATOR
00908 
00909 #define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name)               \
00910   template<class _Tp>                           \
00911     inline valarray<_Tp>&                       \
00912     valarray<_Tp>::operator _Op##=(const _Tp &__t)          \
00913     {                                   \
00914       _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, __t); \
00915       return *this;                         \
00916     }                                   \
00917                                     \
00918   template<class _Tp>                           \
00919     inline valarray<_Tp>&                       \
00920     valarray<_Tp>::operator _Op##=(const valarray<_Tp> &__v)        \
00921     {                                   \
00922       _GLIBCXX_DEBUG_ASSERT(_M_size == __v._M_size);                    \
00923       _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size,       \
00924                    _Array<_Tp>(__v._M_data));       \
00925       return *this;                         \
00926     }
00927 
00928 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, __plus)
00929 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, __minus)
00930 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, __multiplies)
00931 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, __divides)
00932 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, __modulus)
00933 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, __bitwise_xor)
00934 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, __bitwise_and)
00935 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, __bitwise_or)
00936 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, __shift_left)
00937 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, __shift_right)
00938 
00939 #undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT
00940 
00941 #define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name)          \
00942   template<class _Tp> template<class _Dom>              \
00943     inline valarray<_Tp>&                       \
00944     valarray<_Tp>::operator _Op##=(const _Expr<_Dom,_Tp>& __e)      \
00945     {                                   \
00946       _Array_augmented_##_Name(_Array<_Tp>(_M_data), __e, _M_size); \
00947       return *this;                         \
00948     }
00949 
00950 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, __plus)
00951 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, __minus)
00952 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, __multiplies)
00953 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, __divides)
00954 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, __modulus)
00955 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, __bitwise_xor)
00956 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, __bitwise_and)
00957 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, __bitwise_or)
00958 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, __shift_left)
00959 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, __shift_right)
00960 
00961 #undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT
00962     
00963 
00964 #define _DEFINE_BINARY_OPERATOR(_Op, _Name)             \
00965   template<typename _Tp>                        \
00966     inline _Expr<_BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp>,           \
00967                  typename __fun<_Name, _Tp>::result_type>               \
00968     operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w)    \
00969     {                                   \
00970       _GLIBCXX_DEBUG_ASSERT(__v.size() == __w.size());                  \
00971       typedef _BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp> _Closure;     \
00972       typedef typename __fun<_Name, _Tp>::result_type _Rt;              \
00973       return _Expr<_Closure, _Rt>(_Closure(__v, __w));                  \
00974     }                                   \
00975                                     \
00976   template<typename _Tp>                        \
00977   inline _Expr<_BinClos<_Name,_ValArray,_Constant,_Tp,_Tp>,             \
00978                typename __fun<_Name, _Tp>::result_type>                 \
00979   operator _Op(const valarray<_Tp>& __v, const _Tp& __t)        \
00980   {                                 \
00981     typedef _BinClos<_Name,_ValArray,_Constant,_Tp,_Tp> _Closure;   \
00982     typedef typename __fun<_Name, _Tp>::result_type _Rt;                \
00983     return _Expr<_Closure, _Rt>(_Closure(__v, __t));                    \
00984   }                                 \
00985                                     \
00986   template<typename _Tp>                        \
00987   inline _Expr<_BinClos<_Name,_Constant,_ValArray,_Tp,_Tp>,             \
00988                typename __fun<_Name, _Tp>::result_type>                 \
00989   operator _Op(const _Tp& __t, const valarray<_Tp>& __v)        \
00990   {                                 \
00991     typedef _BinClos<_Name,_Constant,_ValArray,_Tp,_Tp> _Closure;       \
00992     typedef typename __fun<_Name, _Tp>::result_type _Rt;                \
00993     return _Expr<_Closure, _Tp>(_Closure(__t, __v));                    \
00994   }
00995 
00996 _DEFINE_BINARY_OPERATOR(+, __plus)
00997 _DEFINE_BINARY_OPERATOR(-, __minus)
00998 _DEFINE_BINARY_OPERATOR(*, __multiplies)
00999 _DEFINE_BINARY_OPERATOR(/, __divides)
01000 _DEFINE_BINARY_OPERATOR(%, __modulus)
01001 _DEFINE_BINARY_OPERATOR(^, __bitwise_xor)
01002 _DEFINE_BINARY_OPERATOR(&, __bitwise_and)
01003 _DEFINE_BINARY_OPERATOR(|, __bitwise_or)
01004 _DEFINE_BINARY_OPERATOR(<<, __shift_left)
01005 _DEFINE_BINARY_OPERATOR(>>, __shift_right)
01006 _DEFINE_BINARY_OPERATOR(&&, __logical_and)
01007 _DEFINE_BINARY_OPERATOR(||, __logical_or)
01008 _DEFINE_BINARY_OPERATOR(==, __equal_to)
01009 _DEFINE_BINARY_OPERATOR(!=, __not_equal_to)
01010 _DEFINE_BINARY_OPERATOR(<, __less)
01011 _DEFINE_BINARY_OPERATOR(>, __greater)
01012 _DEFINE_BINARY_OPERATOR(<=, __less_equal)
01013 _DEFINE_BINARY_OPERATOR(>=, __greater_equal)
01014 
01015 } 
01016 
01017 #endif