home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 November / PCWorld_2000-11_cd.bin / Software / Topware / devc40 / _SETUP.6 / Group12 / std_valarray.h < prev    next >
C/C++ Source or Header  |  2000-01-21  |  24KB  |  729 lines

  1. // The template and inlines for the -*- C++ -*- valarray class.
  2.  
  3. // Copyright (C) 1997-1999 Cygnus Solutions
  4. //
  5. // This file is part of the GNU ISO C++ Library.  This library is free
  6. // software; you can redistribute it and/or modify it under the
  7. // terms of the GNU General Public License as published by the
  8. // Free Software Foundation; either version 2, or (at your option)
  9. // any later version.
  10.  
  11. // This library is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. // GNU General Public License for more details.
  15.  
  16. // You should have received a copy of the GNU General Public License along
  17. // with this library; see the file COPYING.  If not, write to the Free
  18. // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  19. // USA.
  20.  
  21. // As a special exception, you may use this file as part of a free software
  22. // library without restriction.  Specifically, if other files instantiate
  23. // templates or use macros or inline functions from this file, or you compile
  24. // this file and link it with other files to produce an executable, this
  25. // file does not by itself cause the resulting executable to be covered by
  26. // the GNU General Public License.  This exception does not however
  27. // invalidate any other reasons why the executable file might be covered by
  28. // the GNU General Public License.
  29.  
  30. // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
  31.  
  32. #ifndef __STD_VALARRAY__
  33. #define __STD_VALARRAY__
  34. #define _G_NO_VALARRAY_TEMPLATE_EXPORT 1
  35.  
  36. #include <cstddef>
  37. #include <cmath>
  38. #include <cstdlib>
  39. #include <numeric>
  40. #include <functional>
  41. #include <algorithm>
  42.  
  43. #ifndef alloca
  44. #ifdef __GNUC__
  45. #define alloca __builtin_alloca
  46. #else /* not GNU C.  */
  47. #if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
  48. #include <alloca.h>
  49. #else /* not sparc */
  50. #if defined (MSDOS) && !defined (__TURBOC__)
  51. #include <malloc.h>
  52. #else /* not MSDOS, or __TURBOC__ */
  53. #if defined(_AIX)
  54. #include <malloc.h>
  55.  #pragma alloca
  56. #else /* not MSDOS, __TURBOC__, or _AIX */
  57. #ifdef __hpux
  58. #endif /* __hpux */
  59. #endif /* not _AIX */
  60. #endif /* not MSDOS, or __TURBOC__ */
  61. #endif /* not sparc.  */
  62. #endif /* not GNU C.  */
  63. #endif /* alloca not defined.  */
  64.  
  65. extern "C" {
  66.     void* alloca(size_t);
  67. }
  68.  
  69.  
  70. extern "C++" {
  71.  
  72. template<class _Clos, typename _Tp> class _Expr;
  73.  
  74. template<typename _Tp1, typename _Tp2> class _ValArray;    
  75.  
  76. template<template<class> class _Oper,
  77.     template<class, class> class _Meta, class _Dom> struct _UnClos;
  78.  
  79. template<template<class> class _Oper,
  80.     template<class, class> class _Meta1,
  81.     template<class, class> class _Meta2,
  82.     class _Dom1, class _Dom2> class _BinClos;
  83.  
  84. template<template<class, class> class _Meta, class _Dom> class _SClos;
  85.  
  86. template<template<class, class> class _Meta, class _Dom> class _GClos;
  87.     
  88. template<template<class, class> class _Meta, class _Dom> class _IClos;
  89.     
  90. template<template<class, class> class _Meta, class _Dom> class _ValFunClos;
  91.  
  92. template<template<class, class> class _Meta, class _Dom> class _RefFunClos;
  93.  
  94. template<class _Tp> struct _Unary_plus;
  95. template<class _Tp> struct _Bitwise_and;
  96. template<class _Tp> struct _Bitwise_or;
  97. template<class _Tp> struct _Bitwise_xor;  
  98. template<class _Tp> struct _Bitwise_not;
  99. template<class _Tp> struct _Shift_left;
  100. template<class _Tp> struct _Shift_right;
  101.  
  102. template<class _Tp> class valarray;   // An array of type _Tp
  103. class slice;                          // BLAS-like slice out of an array
  104. template<class _Tp> class slice_array;
  105. class gslice;                         // generalized slice out of an array
  106. template<class _Tp> class gslice_array;
  107. template<class _Tp> class mask_array;     // masked array
  108. template<class _Tp> class indirect_array; // indirected array
  109.  
  110. } // extern "C++"
  111.  
  112. #include <std/valarray_array.h>
  113. #include <std/valarray_meta.h>
  114.  
  115. extern "C++" {
  116.  
  117. template<class _Tp> class valarray
  118. {
  119. public:
  120.     typedef _Tp value_type;
  121.     
  122.     // _lib.valarray.cons_ construct/destroy:
  123.     valarray();
  124.     explicit valarray(size_t);
  125.     valarray(const _Tp&, size_t);
  126.     valarray(const _Tp* __restrict__, size_t);
  127.     valarray(const valarray&);
  128.     valarray(const slice_array<_Tp>&);
  129.     valarray(const gslice_array<_Tp>&);
  130.     valarray(const mask_array<_Tp>&);
  131.     valarray(const indirect_array<_Tp>&);
  132.     template<class _Dom>
  133.     valarray(const _Expr<_Dom,_Tp>& __e);
  134.     ~valarray();
  135.     
  136.     // _lib.valarray.assign_ assignment:
  137.     valarray<_Tp>& operator=(const valarray<_Tp>&);
  138.     valarray<_Tp>& operator=(const _Tp&);
  139.     valarray<_Tp>& operator=(const slice_array<_Tp>&);
  140.     valarray<_Tp>& operator=(const gslice_array<_Tp>&);
  141.     valarray<_Tp>& operator=(const mask_array<_Tp>&);
  142.     valarray<_Tp>& operator=(const indirect_array<_Tp>&);
  143.     
  144.     template<class _Dom> valarray<_Tp>&
  145.     operator= (const _Expr<_Dom,_Tp>&);
  146.     
  147.     // _lib.valarray.access_ element access:
  148.     _Tp                 operator[](size_t) const;
  149.     _Tp&                operator[](size_t);        
  150.     // _lib.valarray.sub_ subset operations:
  151.     _Expr<_SClos<_ValArray,_Tp>, _Tp> operator[](slice) const;
  152.     slice_array<_Tp>    operator[](slice);
  153.     _Expr<_GClos<_ValArray,_Tp>, _Tp> operator[](const gslice&) const;
  154.     gslice_array<_Tp>   operator[](const gslice&);
  155.     valarray<_Tp>          operator[](const valarray<bool>&) const;
  156.     mask_array<_Tp>     operator[](const valarray<bool>&);
  157.     _Expr<_IClos<_ValArray, _Tp>, _Tp>
  158.     operator[](const valarray<size_t>&) const;
  159.     indirect_array<_Tp> operator[](const valarray<size_t>&);
  160.     
  161.     // _lib.valarray.unary_ unary operators:
  162.     _Expr<_UnClos<_Unary_plus,_ValArray,_Tp>,_Tp>  operator+ () const;
  163.     _Expr<_UnClos<negate,_ValArray,_Tp>,_Tp> operator- () const;
  164.     _Expr<_UnClos<_Bitwise_not,_ValArray,_Tp>,_Tp> operator~ () const;
  165.     _Expr<_UnClos<logical_not,_ValArray,_Tp>,bool> operator! () const;
  166.     
  167.     // _lib.valarray.cassign_ computed assignment:
  168.     valarray<_Tp>& operator*= (const _Tp&);
  169.     valarray<_Tp>& operator/= (const _Tp&);
  170.     valarray<_Tp>& operator%= (const _Tp&);
  171.     valarray<_Tp>& operator+= (const _Tp&);
  172.     valarray<_Tp>& operator-= (const _Tp&);
  173.     valarray<_Tp>& operator^= (const _Tp&);
  174.     valarray<_Tp>& operator&= (const _Tp&);
  175.     valarray<_Tp>& operator|= (const _Tp&);
  176.     valarray<_Tp>& operator<<=(const _Tp&);
  177.     valarray<_Tp>& operator>>=(const _Tp&);
  178.     valarray<_Tp>& operator*= (const valarray<_Tp>&);
  179.     valarray<_Tp>& operator/= (const valarray<_Tp>&);
  180.     valarray<_Tp>& operator%= (const valarray<_Tp>&);
  181.     valarray<_Tp>& operator+= (const valarray<_Tp>&);
  182.     valarray<_Tp>& operator-= (const valarray<_Tp>&);
  183.     valarray<_Tp>& operator^= (const valarray<_Tp>&);
  184.     valarray<_Tp>& operator|= (const valarray<_Tp>&);
  185.     valarray<_Tp>& operator&= (const valarray<_Tp>&);
  186.     valarray<_Tp>& operator<<=(const valarray<_Tp>&);
  187.     valarray<_Tp>& operator>>=(const valarray<_Tp>&);
  188.  
  189.     template<class _Dom>
  190.     valarray<_Tp>& operator*= (const _Expr<_Dom,_Tp>&);
  191.     template<class _Dom>
  192.        valarray<_Tp>& operator/= (const _Expr<_Dom,_Tp>&);
  193.     template<class _Dom>
  194.        valarray<_Tp>& operator%= (const _Expr<_Dom,_Tp>&);
  195.     template<class _Dom>
  196.        valarray<_Tp>& operator+= (const _Expr<_Dom,_Tp>&);
  197.     template<class _Dom>
  198.        valarray<_Tp>& operator-= (const _Expr<_Dom,_Tp>&);
  199.     template<class _Dom>
  200.        valarray<_Tp>& operator^= (const _Expr<_Dom,_Tp>&);
  201.     template<class _Dom>
  202.        valarray<_Tp>& operator|= (const _Expr<_Dom,_Tp>&);
  203.     template<class _Dom>
  204.        valarray<_Tp>& operator&= (const _Expr<_Dom,_Tp>&);
  205.     template<class _Dom>
  206.        valarray<_Tp>& operator<<=(const _Expr<_Dom,_Tp>&);
  207.     template<class _Dom>
  208.        valarray<_Tp>& operator>>=(const _Expr<_Dom,_Tp>&);
  209.  
  210.       
  211.     // _lib.valarray.members_ member functions:
  212.     size_t size() const;
  213.     _Tp    sum() const;    
  214.     _Tp    min() const;    
  215.     _Tp    max() const;    
  216.     
  217.     // FIXME: Extension
  218.     _Tp    product () const;
  219.  
  220.     valarray<_Tp> shift (int) const;
  221.     valarray<_Tp> cshift(int) const;
  222.     _Expr<_ValFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(_Tp)) const;
  223.     _Expr<_RefFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(const _Tp&)) const;
  224.     void resize(size_t __size, _Tp __c = _Tp());
  225.     
  226. private:
  227.     size_t _M_size;
  228.     _Tp* __restrict__ _M_data;
  229.  
  230.     friend class _Array<_Tp>;
  231. };
  232.  
  233.  
  234. template<typename _Tp> struct _Unary_plus : unary_function<_Tp,_Tp> {
  235.     _Tp operator() (const _Tp& __t) const { return __t; }
  236. };
  237.  
  238. template<typename _Tp> struct _Bitwise_and : binary_function<_Tp,_Tp,_Tp> {
  239.     _Tp operator() (_Tp __x, _Tp __y) const { return __x & __y; }
  240. };
  241.  
  242. template<typename _Tp> struct _Bitwise_or : binary_function<_Tp,_Tp,_Tp> {
  243.     _Tp operator() (_Tp __x, _Tp __y) const { return __x | __y; }
  244. };
  245.  
  246. template<typename _Tp> struct _Bitwise_xor : binary_function<_Tp,_Tp,_Tp> {
  247.     _Tp operator() (_Tp __x, _Tp __y) const { return __x ^ __y; }
  248. };
  249.  
  250. template<typename _Tp> struct _Bitwise_not : unary_function<_Tp,_Tp> {
  251.     _Tp operator() (_Tp __t) const { return ~__t; }
  252. };
  253.  
  254. template<typename _Tp> struct _Shift_left : unary_function<_Tp,_Tp> {
  255.     _Tp operator() (_Tp __x, _Tp __y) const { return __x << __y; }
  256. };
  257.  
  258. template<typename _Tp> struct _Shift_right : unary_function<_Tp,_Tp> {
  259.     _Tp operator() (_Tp __x, _Tp __y) const { return __x >> __y; }
  260. };
  261.  
  262.   
  263. template<typename _Tp>
  264. inline _Tp
  265. valarray<_Tp>::operator[] (size_t __i) const
  266. { return _M_data[__i]; }
  267.  
  268. template<typename _Tp>
  269. inline _Tp&
  270. valarray<_Tp>::operator[] (size_t __i)
  271. { return _M_data[__i]; }
  272.  
  273. } // extern "C++"
  274.  
  275. #include <std/slice.h>
  276. #include <std/slice_array.h>
  277. #include <std/gslice.h>
  278. #include <std/gslice_array.h>
  279. #include <std/mask_array.h>
  280. #include <std/indirect_array.h>
  281.  
  282. extern "C++" {
  283.  
  284. template<typename _Tp>
  285. inline valarray<_Tp>::valarray () : _M_size (0), _M_data (0) {}
  286.  
  287. template<typename _Tp>
  288. inline valarray<_Tp>::valarray (size_t __n) 
  289.         : _M_size (__n), _M_data (new _Tp[__n]) {}
  290.  
  291. template<typename _Tp>
  292. inline valarray<_Tp>::valarray (const _Tp& __t, size_t __n)
  293.         : _M_size (__n), _M_data (new _Tp[__n])
  294. { __valarray_fill (_M_data, _M_size, __t); }
  295.  
  296. template<typename _Tp>
  297. inline valarray<_Tp>::valarray (const _Tp* __restrict__ __pT, size_t __n)
  298.         : _M_size (__n), _M_data (new _Tp[__n])
  299. { __valarray_copy (__pT, __n, _M_data); }
  300.  
  301. template<typename _Tp>
  302. inline valarray<_Tp>::valarray (const valarray<_Tp>& __v)
  303.         : _M_size (__v._M_size), _M_data (new _Tp[__v._M_size])
  304. { __valarray_copy (__v._M_data, _M_size, _M_data); }
  305.  
  306. template<typename _Tp>
  307. inline valarray<_Tp>::valarray (const slice_array<_Tp>& __sa)
  308.         : _M_size (__sa._M_sz), _M_data (new _Tp[__sa._M_sz])
  309. { __valarray_copy (__sa._M_array, __sa._M_sz, __sa._M_stride,
  310.                    _Array<_Tp>(_M_data)); }
  311.  
  312. template<typename _Tp>
  313. inline valarray<_Tp>::valarray (const gslice_array<_Tp>& __ga)
  314.         : _M_size (__ga._M_index.size()), _M_data (new _Tp[_M_size])
  315. { __valarray_copy (__ga._M_array, _Array<size_t>(__ga._M_index), 
  316.                    _Array<_Tp>(_M_data), _M_size); }
  317.  
  318. template<typename _Tp>
  319. inline valarray<_Tp>::valarray (const mask_array<_Tp>& __ma)
  320.         : _M_size (__ma._M_sz), _M_data (new _Tp[__ma._M_sz])
  321. { __valarray_copy (__ma._M_array, __ma._M_mask,
  322.                    _Array<_Tp>(_M_data), _M_size); }
  323.  
  324. template<typename _Tp>
  325. inline valarray<_Tp>::valarray (const indirect_array<_Tp>& __ia)
  326.         : _M_size (__ia._M_sz), _M_data (new _Tp[__ia._M_sz])
  327. { __valarray_copy (__ia._M_array, __ia._M_index, 
  328.                    _Array<_Tp>(_M_data), _M_size); }
  329.  
  330. template<typename _Tp> template<class _Dom>
  331. inline valarray<_Tp>::valarray (const _Expr<_Dom, _Tp>& __e)
  332.         : _M_size (__e.size ()), _M_data (new _Tp[_M_size])
  333. { __valarray_copy (__e, _M_size, _Array<_Tp>(_M_data)); }
  334.  
  335. template<typename _Tp>
  336. inline valarray<_Tp>::~valarray () { delete[] _M_data; }
  337.  
  338. template<typename _Tp>
  339. inline valarray<_Tp>&
  340. valarray<_Tp>::operator= (const valarray<_Tp>& __v)
  341. {
  342.     __valarray_copy(__v._M_data, _M_size, _M_data);
  343.     return *this;
  344. }
  345.  
  346. template<typename _Tp>
  347. inline valarray<_Tp>&
  348. valarray<_Tp>::operator= (const _Tp& __t)
  349. {
  350.     __valarray_fill (_M_data, _M_size, __t);
  351.     return *this;
  352. }
  353.  
  354. template<typename _Tp>
  355. inline valarray<_Tp>&
  356. valarray<_Tp>::operator= (const slice_array<_Tp>& __sa)
  357. {
  358.     __valarray_copy (__sa._M_array, __sa._M_sz,
  359.                      __sa._M_stride, _Array<_Tp>(_M_data));
  360.     return *this;
  361. }
  362.  
  363. template<typename _Tp>
  364. inline valarray<_Tp>&
  365. valarray<_Tp>::operator= (const gslice_array<_Tp>& __ga)
  366. {
  367.     __valarray_copy (__ga._M_array, _Array<size_t>(__ga._M_index),
  368.                      _Array<_Tp>(_M_data), _M_size);
  369.     return *this;
  370. }
  371.  
  372. template<typename _Tp>
  373. inline valarray<_Tp>&
  374. valarray<_Tp>::operator= (const mask_array<_Tp>& __ma)
  375. {
  376.     __valarray_copy (__ma._M_array, __ma._M_mask,
  377.                      _Array<_Tp>(_M_data), _M_size);
  378.     return *this;
  379. }
  380.  
  381. template<typename _Tp>
  382. inline valarray<_Tp>&
  383. valarray<_Tp>::operator= (const indirect_array<_Tp>& __ia)
  384. {
  385.     __valarray_copy (__ia._M_array, __ia._M_index,
  386.                      _Array<_Tp>(_M_data), _M_size);
  387.     return *this;
  388. }
  389.  
  390. template<typename _Tp> template<class _Dom>
  391. inline valarray<_Tp>&
  392. valarray<_Tp>::operator= (const _Expr<_Dom, _Tp>& __e)
  393. {
  394.     __valarray_copy (__e, _M_size, _Array<_Tp>(_M_data));
  395.     return *this;
  396. }
  397.  
  398. template<typename _Tp>
  399. inline _Expr<_SClos<_ValArray,_Tp>, _Tp>
  400. valarray<_Tp>::operator[] (slice __s) const
  401. {
  402.     typedef _SClos<_ValArray,_Tp> _Closure;
  403.     return _Expr<_Closure, _Tp> (_Closure (_Array<_Tp>(_M_data), __s));
  404. }
  405.  
  406. template<typename _Tp>
  407. inline slice_array<_Tp>
  408. valarray<_Tp>::operator[] (slice __s)
  409. {
  410.     return slice_array<_Tp> (_Array<_Tp>(_M_data), __s);
  411. }
  412.  
  413. template<typename _Tp>
  414. inline _Expr<_GClos<_ValArray,_Tp>, _Tp>
  415. valarray<_Tp>::operator[] (const gslice& __gs) const
  416. {
  417.     typedef _GClos<_ValArray,_Tp> _Closure;
  418.     return _Expr<_Closure, _Tp>
  419.         (_Closure (_Array<_Tp>(_M_data), __gs._M_index->_M_index));
  420. }
  421.  
  422. template<typename _Tp>
  423. inline gslice_array<_Tp>
  424. valarray<_Tp>::operator[] (const gslice& __gs)
  425. {
  426.     return gslice_array<_Tp>
  427.         (_Array<_Tp>(_M_data), __gs._M_index->_M_index);
  428. }
  429.  
  430. template<typename _Tp>
  431. inline valarray<_Tp>
  432. valarray<_Tp>::operator[] (const valarray<bool>& __m) const
  433. {
  434.     size_t __s (0);
  435.     size_t __e (__m.size ());
  436.     for (size_t __i=0; __i<__e; ++__i)
  437.         if (__m[__i]) ++__s;
  438.     return valarray<_Tp> (mask_array<_Tp> (_Array<_Tp>(_M_data), __s,
  439.                                            _Array<bool> (__m)));
  440. }
  441.  
  442. template<typename _Tp>
  443. inline mask_array<_Tp>
  444. valarray<_Tp>::operator[] (const valarray<bool>& __m)
  445. {
  446.     size_t __s (0);
  447.     size_t __e (__m.size ());
  448.     for (size_t __i=0; __i<__e; ++__i)
  449.         if (__m[__i]) ++__s;
  450.     return mask_array<_Tp> (_Array<_Tp>(_M_data), __s, _Array<bool> (__m));
  451. }
  452.  
  453. template<typename _Tp>
  454. inline _Expr<_IClos<_ValArray,_Tp>, _Tp>
  455. valarray<_Tp>::operator[] (const valarray<size_t>& __i) const
  456. {
  457.     typedef _IClos<_ValArray,_Tp> _Closure;
  458.     return _Expr<_Closure, _Tp> (_Closure (*this, __i));
  459. }
  460.  
  461. template<typename _Tp>
  462. inline indirect_array<_Tp>
  463. valarray<_Tp>::operator[] (const valarray<size_t>& __i)
  464. {
  465.     return indirect_array<_Tp> (_Array<_Tp>(_M_data), __i.size(),
  466.                                 _Array<size_t> (__i));
  467. }
  468.  
  469. template<class _Tp>
  470. inline size_t valarray<_Tp>::size () const { return _M_size; }
  471.  
  472. template<class _Tp>
  473. inline _Tp
  474. valarray<_Tp>::sum () const
  475. {
  476.     return accumulate (_M_data, _M_data + _M_size, _Tp ());
  477. }
  478.  
  479. template<typename _Tp>
  480. inline _Tp
  481. valarray<_Tp>::product () const
  482. {
  483.     return accumulate (_M_data, _M_data+_M_size, _Tp(1), multiplies<_Tp> ());
  484. }
  485.  
  486. template <class _Tp>
  487. inline valarray<_Tp>
  488. valarray<_Tp>::shift (int __n) const
  489. {
  490.     _Tp* const __a = static_cast<_Tp*> (alloca (sizeof(_Tp) * _M_size));
  491.     if (! __n)                          // __n == 0: no shift
  492.         __valarray_copy (_M_data, _M_size, __a);
  493.     else if (__n > 0) {                  // __n > 0: shift left
  494.         if (__n > _M_size)
  495.             __valarray_fill(__a, __n, _Tp());
  496.         else {
  497.             __valarray_copy (_M_data+__n, _M_size-__n, __a);
  498.             __valarray_fill (__a+_M_size-__n, __n, _Tp());
  499.         }
  500.     }
  501.     else {                             // __n < 0: shift right
  502.         __valarray_copy (_M_data, _M_size+__n, __a-__n);
  503.         __valarray_fill(__a, -__n, _Tp());
  504.     }
  505.     return valarray<_Tp> (__a, _M_size);
  506. }
  507.  
  508. template <class _Tp>
  509. inline valarray<_Tp>
  510. valarray<_Tp>::cshift (int __n) const
  511. {
  512.     _Tp* const __a = static_cast<_Tp*> (alloca (sizeof(_Tp) * _M_size));
  513.     if (! __n)                          // __n == 0: no cshift
  514.         __valarray_copy(_M_data, _M_size, __a);
  515.     else if (__n > 0) {                 // __n > 0: cshift left
  516.         __valarray_copy (_M_data, __n, __a + _M_size-__n);
  517.         __valarray_copy (_M_data + __n, _M_size-__n, __a);
  518.     }
  519.     else {                            // __n < 0: cshift right
  520.         __valarray_copy (_M_data + _M_size + __n, -__n, __a);
  521.         __valarray_copy (_M_data, _M_size + __n, __a - __n);
  522.     }
  523.     return valarray<_Tp> (__a, _M_size);
  524. }
  525.  
  526. template <class _Tp>
  527. inline void
  528. valarray<_Tp>::resize (size_t __n, _Tp __c)
  529. {
  530.     if (_M_size != __n) {
  531.         delete[] _M_data;
  532.         _M_size = __n;
  533.         _M_data = new _Tp[_M_size];
  534.     }
  535.     __valarray_fill (_M_data, _M_size, __c);
  536. }
  537.  
  538. template<typename _Tp>
  539. inline _Tp
  540. valarray<_Tp>::min() const
  541. {
  542.     return *min_element (_M_data, _M_data+_M_size);
  543. }
  544.  
  545. template<typename _Tp>
  546. inline _Tp
  547. valarray<_Tp>::max() const
  548. {
  549.     return *max_element (_M_data, _M_data+_M_size);
  550. }
  551.  
  552. template<class _Tp>
  553. inline _Expr<_ValFunClos<_ValArray,_Tp>,_Tp>
  554. valarray<_Tp>::apply (_Tp func (_Tp)) const
  555. {
  556.     typedef _ValFunClos<_ValArray,_Tp> _Closure;
  557.     return _Expr<_Closure,_Tp> (_Closure (*this, func));
  558. }
  559.  
  560. template<class _Tp>
  561. inline _Expr<_RefFunClos<_ValArray,_Tp>,_Tp>
  562. valarray<_Tp>::apply (_Tp func (const _Tp &)) const
  563. {
  564.     typedef _RefFunClos<_ValArray,_Tp> _Closure;
  565.     return _Expr<_Closure,_Tp> (_Closure (*this, func));
  566. }
  567.  
  568. #define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name)                     \
  569.   template<typename _Tp>                        \
  570.   inline _Expr<_UnClos<_Name,_ValArray,_Tp>, _Tp>                   \
  571.   valarray<_Tp>::operator##_Op() const                    \
  572.   {                                    \
  573.       typedef _UnClos<_Name,_ValArray,_Tp> _Closure;                    \
  574.       return _Expr<_Closure, _Tp> (_Closure (*this));            \
  575.   }
  576.  
  577.     _DEFINE_VALARRAY_UNARY_OPERATOR(+, _Unary_plus)
  578.     _DEFINE_VALARRAY_UNARY_OPERATOR(-, negate)
  579.     _DEFINE_VALARRAY_UNARY_OPERATOR(~, _Bitwise_not)
  580.  
  581. #undef _DEFINE_VALARRAY_UNARY_OPERATOR
  582.   
  583.   template<typename _Tp>
  584.   inline _Expr<_UnClos<logical_not,_ValArray,_Tp>, bool>
  585.   valarray<_Tp>::operator!() const
  586.   {
  587.       typedef _UnClos<logical_not,_ValArray,_Tp> _Closure;
  588.       return _Expr<_Closure, bool> (_Closure (*this));
  589.   }
  590.  
  591. #define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name)               \
  592.   template<class _Tp>                            \
  593.   inline valarray<_Tp> &                        \
  594.   valarray<_Tp>::operator##_Op##= (const _Tp &__t)            \
  595.   {                                    \
  596.       _Array_augmented_##_Name (_Array<_Tp>(_M_data), _M_size, __t);    \
  597.       return *this;                            \
  598.   }                                    \
  599.                                     \
  600.   template<class _Tp>                            \
  601.   inline valarray<_Tp> &                        \
  602.   valarray<_Tp>::operator##_Op##= (const valarray<_Tp> &__v)        \
  603.   {                                    \
  604.       _Array_augmented_##_Name (_Array<_Tp>(_M_data), _M_size,         \
  605.                                _Array<_Tp>(__v._M_data));        \
  606.       return *this;                            \
  607.   }
  608.  
  609. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, plus)
  610. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, minus)
  611. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, multiplies)
  612. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, divides)
  613. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, modulus)
  614. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, xor)
  615. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, and)
  616. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, or)
  617. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, shift_left)
  618. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, shift_right)
  619.  
  620. #undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT
  621.  
  622.  
  623. #define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name)          \
  624.   template<class _Tp> template<class _Dom>                \
  625.   inline valarray<_Tp> &                        \
  626.   valarray<_Tp>::operator##_Op##= (const _Expr<_Dom,_Tp> &__e)        \
  627.   {                                    \
  628.       _Array_augmented_##_Name (_Array<_Tp>(_M_data), __e, _M_size);    \
  629.       return *this;                            \
  630.   }
  631.  
  632. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, plus)
  633. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, minus)
  634. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, multiplies)
  635. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, divides)
  636. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, modulus)
  637. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, xor)
  638. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, and)
  639. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, or)
  640. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, shift_left)
  641. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, shift_right)
  642.  
  643. #undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT
  644.     
  645.  
  646. #define _DEFINE_BINARY_OPERATOR(_Op, _Name)                \
  647.   template<typename _Tp>                        \
  648.   inline _Expr<_BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp>, _Tp>        \
  649.   operator##_Op (const valarray<_Tp> &__v, const valarray<_Tp> &__w)    \
  650.   {                                    \
  651.       typedef _BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp> _Closure;     \
  652.       return _Expr<_Closure, _Tp> (_Closure (__v, __w));        \
  653.   }                                    \
  654.                                     \
  655.   template<typename _Tp>                        \
  656.   inline _Expr<_BinClos<_Name,_ValArray,_Constant,_Tp,_Tp>,_Tp>         \
  657.   operator##_Op (const valarray<_Tp> &__v, const _Tp &__t)        \
  658.   {                                    \
  659.       typedef _BinClos<_Name,_ValArray,_Constant,_Tp,_Tp> _Closure;    \
  660.       return _Expr<_Closure, _Tp> (_Closure (__v, __t));            \
  661.   }                                    \
  662.                                     \
  663.   template<typename _Tp>                        \
  664.   inline _Expr<_BinClos<_Name,_Constant,_ValArray,_Tp,_Tp>,_Tp>         \
  665.   operator##_Op (const _Tp &__t, const valarray<_Tp> &__v)        \
  666.   {                                    \
  667.       typedef _BinClos<_Name,_Constant,_ValArray,_Tp,_Tp> _Closure;     \
  668.       return _Expr<_Closure, _Tp> (_Closure (__t, __v));            \
  669.   }
  670.  
  671. _DEFINE_BINARY_OPERATOR(+, plus)
  672. _DEFINE_BINARY_OPERATOR(-, minus)
  673. _DEFINE_BINARY_OPERATOR(*, multiplies)
  674. _DEFINE_BINARY_OPERATOR(/, divides)
  675. _DEFINE_BINARY_OPERATOR(%, modulus)
  676. _DEFINE_BINARY_OPERATOR(^, _Bitwise_xor)
  677. _DEFINE_BINARY_OPERATOR(&, _Bitwise_and)
  678. _DEFINE_BINARY_OPERATOR(|, _Bitwise_or)
  679. _DEFINE_BINARY_OPERATOR(<<, _Shift_left)
  680. _DEFINE_BINARY_OPERATOR(>>, _Shift_right)
  681.  
  682. #undef _DEFINE_BINARY_OPERATOR
  683.  
  684. #define _DEFINE_LOGICAL_OPERATOR(_Op, _Name)                \
  685.   template<typename _Tp>                        \
  686.   inline _Expr<_BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp>,bool>        \
  687.   operator##_Op (const valarray<_Tp> &__v, const valarray<_Tp> &__w)    \
  688.   {                                    \
  689.       typedef _BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp> _Closure;     \
  690.       return _Expr<_Closure, bool> (_Closure (__v, __w));               \
  691.   }                                    \
  692.                                     \
  693.   template<class _Tp>                            \
  694.   inline _Expr<_BinClos<_Name,_ValArray,_Constant,_Tp,_Tp>,bool>        \
  695.   operator##_Op (const valarray<_Tp> &__v, const _Tp &__t)        \
  696.   {                                    \
  697.       typedef _BinClos<_Name,_ValArray,_Constant,_Tp,_Tp> _Closure;     \
  698.       return _Expr<_Closure, bool> (_Closure (__v, __t));           \
  699.   }                                    \
  700.                                     \
  701.   template<class _Tp>                            \
  702.   inline _Expr<_BinClos<_Name,_Constant,_ValArray,_Tp,_Tp>,bool>        \
  703.   operator##_Op (const _Tp &__t, const valarray<_Tp> &__v)        \
  704.   {                                    \
  705.       typedef _BinClos<_Name,_Constant,_ValArray,_Tp,_Tp> _Closure;     \
  706.       return _Expr<_Closure, bool> (_Closure (__t, __v));            \
  707.   }
  708.  
  709. _DEFINE_LOGICAL_OPERATOR(&&, logical_and)
  710. _DEFINE_LOGICAL_OPERATOR(||, logical_or)
  711. _DEFINE_LOGICAL_OPERATOR(==, equal_to)
  712. _DEFINE_LOGICAL_OPERATOR(!=, not_equal_to)
  713. _DEFINE_LOGICAL_OPERATOR(<, less)
  714. _DEFINE_LOGICAL_OPERATOR(>, greater)
  715. _DEFINE_LOGICAL_OPERATOR(<=, less_equal)
  716. _DEFINE_LOGICAL_OPERATOR(>=, greater_equal)
  717.  
  718. #undef _DEFINE_VALARRAY_OPERATOR
  719.  
  720. #undef _G_NO_VALARRAY_TEMPLATE_EXPORT
  721.  
  722. } // extern "C++"
  723.  
  724. #endif // __STD_VALARRAY__
  725.  
  726. // Local Variables:
  727. // mode:c++
  728. // End:
  729.