Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1542 lines
39 KiB

  1. // valarray standard header
  2. #pragma once
  3. #ifndef _VALARRAY_
  4. #define _VALARRAY_
  5. #include <cmath>
  6. #include <xstddef>
  7. #pragma pack(push,8)
  8. #pragma warning(push,3)
  9. #pragma warning(disable: 4244 4700)
  10. _STD_BEGIN
  11. // FORWARD REFERENCES
  12. class gslice;
  13. class slice;
  14. template<class _Ty>
  15. class gslice_array;
  16. template<class _Ty>
  17. class indirect_array;
  18. template<class _Ty>
  19. class mask_array;
  20. template<class _Ty>
  21. class slice_array;
  22. template<class _Ty>
  23. class valarray;
  24. typedef valarray<_Bool> _Boolarray;
  25. typedef valarray<size_t> _Sizarray;
  26. // MACROS FOR valarray
  27. #define _VALOP(TYPE, LENGTH, RHS) /* assign RHS(_Idx) to new valarray */ \
  28. valarray<TYPE> _Ans(LENGTH); \
  29. for (size_t _Idx = 0; _Idx < _Ans.size(); ++_Idx) \
  30. _Ans[_Idx] = RHS; \
  31. return _Ans
  32. #define _VALGOP(RHS) /* apply RHS(_Idx) to valarray */ \
  33. for (size_t _Idx = 0; _Idx < size(); ++_Idx) \
  34. _Myptr[_Idx] RHS; \
  35. return *this
  36. // TEMPLATE CLASS valarray
  37. template<class _Ty>
  38. class valarray
  39. { // store array with various indexing options
  40. public:
  41. typedef _Ty value_type;
  42. explicit valarray(size_t _Count = 0)
  43. { // construct with _Count * _Ty()
  44. _Tidy();
  45. _Myres = _Count;
  46. _Grow(_Count);
  47. }
  48. valarray(const _Ty& _Val, size_t _Count)
  49. { // construct with _Count * _Val
  50. _Tidy();
  51. _Grow(_Count, &_Val);
  52. }
  53. valarray(const _Ty *_Ptr, size_t _Count)
  54. { // construct with [_Ptr, _Ptr + _Count)
  55. _Tidy();
  56. _Grow(_Count, _Ptr, 1);
  57. }
  58. valarray(const valarray<_Ty>& _Right)
  59. { // construct from valarray
  60. _Tidy();
  61. _Grow(_Right.size(), _Right._Myptr, 1);
  62. }
  63. valarray(const slice_array<_Ty>& _Slicearr)
  64. { // construct from slice_array
  65. _Tidy();
  66. *this = _Slicearr;
  67. }
  68. valarray(const gslice_array<_Ty>& _Gslicearr)
  69. { // construct from gslice_array
  70. _Tidy();
  71. *this = _Gslicearr;
  72. }
  73. valarray(const mask_array<_Ty>& _Maskarr)
  74. { // construct from mask_array
  75. _Tidy();
  76. *this = _Maskarr;
  77. }
  78. valarray(const indirect_array<_Ty>& _Indarr)
  79. { // construct from indirect_array
  80. _Tidy();
  81. *this = _Indarr;
  82. }
  83. ~valarray()
  84. { // destroy the object
  85. _Tidy(true);
  86. }
  87. valarray<_Ty>& operator=(const valarray<_Ty>& _Right)
  88. { // assign valarray _Right
  89. if (this != &_Right)
  90. { // worth doing
  91. _Tidy(true);
  92. _Grow(_Right.size(), _Right._Myptr, 1);
  93. }
  94. return (*this);
  95. }
  96. valarray<_Ty>& operator=(const _Ty& _Val)
  97. { // assign _Val to each element
  98. _VALGOP(= _Val);
  99. }
  100. void resize(size_t _Newsize)
  101. { // determine new length, padding with _Ty() elements as needed
  102. resize(_Newsize, _Ty());
  103. }
  104. void resize(size_t _Newsize, const _Ty _Val)
  105. { // determine new length, padding with _Val elements as needed
  106. _Grow(_Newsize, &_Val, 0, true);
  107. }
  108. valarray<_Ty>& operator=(
  109. const slice_array<_Ty>& _Slicearr); // defined below
  110. valarray<_Ty>& operator=(
  111. const gslice_array<_Ty>& _Gslicearr); // defined below
  112. valarray<_Ty>& operator=(
  113. const mask_array<_Ty>& _Maskarr); // defined below
  114. valarray<_Ty>& operator=(
  115. const indirect_array<_Ty>& _Indarr); // defined below
  116. valarray<_Ty> operator+() const
  117. { // return +valarray
  118. _VALOP(_Ty, size(), +_Myptr[_Idx]);
  119. }
  120. valarray<_Ty> operator-() const
  121. { // return -valarray
  122. _VALOP(_Ty, size(), -_Myptr[_Idx]);
  123. }
  124. valarray<_Ty> operator~() const
  125. { // return ~valarray
  126. _VALOP(_Ty, size(), ~_Myptr[_Idx]);
  127. }
  128. _Boolarray operator!() const
  129. { // return !valarray
  130. _VALOP(_Bool, size(), !_Myptr[_Idx]);
  131. }
  132. valarray<_Ty>& operator*=(const _Ty& _Right)
  133. { // multiply valarray elements by _Right
  134. _VALGOP(*= _Right);
  135. }
  136. valarray<_Ty>& operator/=(const _Ty& _Right)
  137. { // divide valarray elements by _Right
  138. _VALGOP(/= _Right);
  139. }
  140. valarray<_Ty>& operator%=(const _Ty& _Right)
  141. { // remainder valarray elements by _Right
  142. _VALGOP(%= _Right);
  143. }
  144. valarray<_Ty>& operator+=(const _Ty& _Right)
  145. { // add _Right to valarray elements
  146. _VALGOP(+= _Right);
  147. }
  148. valarray<_Ty>& operator-=(const _Ty& _Right)
  149. { // subtract _Right from valarray elements
  150. _VALGOP(-= _Right);
  151. }
  152. valarray<_Ty>& operator^=(const _Ty& _Right)
  153. { // XOR _Right into valarray elements
  154. _VALGOP(^= _Right);
  155. }
  156. valarray<_Ty>& operator&=(const _Ty& _Right)
  157. { // AND _Right into valarray elements
  158. _VALGOP(&= _Right);
  159. }
  160. valarray<_Ty>& operator|=(const _Ty& _Right)
  161. { // OR _Right into valarray elements
  162. _VALGOP(|= _Right);
  163. }
  164. valarray<_Ty>& operator<<=(const _Ty& _Right)
  165. { // left shift valarray elements by _Right
  166. _VALGOP(<<= _Right);
  167. }
  168. valarray<_Ty>& operator>>=(const _Ty& _Right)
  169. { // right shift valarray elements by _Right
  170. _VALGOP(>>= _Right);
  171. }
  172. valarray<_Ty>& operator*=(const valarray<_Ty>& _Right)
  173. { // multiply valarray elements by valarray _Right elements
  174. _VALGOP(*= _Right[_Idx]);
  175. }
  176. valarray<_Ty>& operator/=(const valarray<_Ty>& _Right)
  177. { // divide valarray elements by valarray _Right elements
  178. _VALGOP(/= _Right[_Idx]);
  179. }
  180. valarray<_Ty>& operator%=(const valarray<_Ty>& _Right)
  181. { // remainder valarray elements by valarray _Right elements
  182. _VALGOP(%= _Right[_Idx]);
  183. }
  184. valarray<_Ty>& operator+=(const valarray<_Ty>& _Right)
  185. { // add valarray _Right elements to valarray elements
  186. _VALGOP(+= _Right[_Idx]);
  187. }
  188. valarray<_Ty>& operator-=(const valarray<_Ty>& _Right)
  189. { // subtract valarray _Right elements from valarray elements
  190. _VALGOP(-= _Right[_Idx]);
  191. }
  192. valarray<_Ty>& operator^=(const valarray<_Ty>& _Right)
  193. { // XOR valarray _Right elements into valarray elements
  194. _VALGOP(^= _Right[_Idx]);
  195. }
  196. valarray<_Ty>& operator|=(const valarray<_Ty>& _Right)
  197. { // OR valarray _Right elements into valarray elements
  198. _VALGOP(|= _Right[_Idx]);
  199. }
  200. valarray<_Ty>& operator&=(const valarray<_Ty>& _Right)
  201. { // AND valarray _Right elements into valarray elements
  202. _VALGOP(&= _Right[_Idx]);
  203. }
  204. valarray<_Ty>& operator<<=(const valarray<_Ty>& _Right)
  205. { // left shift valarray elements by valarray _Right elements
  206. _VALGOP(<<= _Right[_Idx]);
  207. }
  208. valarray<_Ty>& operator>>=(const valarray<_Ty>& _Right)
  209. { // right shift valarray elements by valarray _Right elements
  210. _VALGOP(>>= _Right[_Idx]);
  211. }
  212. size_t size() const
  213. { // return length of sequence
  214. return (_Mysize);
  215. }
  216. _Ty operator[](size_t _Off) const
  217. { // subscript nonmutable sequence
  218. return (_Myptr[_Off]);
  219. }
  220. _Ty& operator[](size_t _Off)
  221. { // subscript mutable sequence
  222. return (_Myptr[_Off]);
  223. }
  224. valarray<_Ty> operator[](
  225. slice _Slicearr) const; // defined below
  226. slice_array<_Ty> operator[](
  227. slice _Slicearr); // defined below
  228. valarray<_Ty> operator[](
  229. const gslice& _Gslicearr) const; // defined below
  230. gslice_array<_Ty> operator[](
  231. const gslice& _Gslicearr); // defined below
  232. valarray<_Ty> operator[](
  233. const _Boolarray& _Boolarr) const; // defined below
  234. mask_array<_Ty> operator[](
  235. const _Boolarray& _Boolarr); // defined below
  236. valarray<_Ty> operator[](
  237. const _Sizarray& _Indarr) const; // defined below
  238. indirect_array<_Ty> operator[](
  239. const _Sizarray& _Indarr); // defined below
  240. _Ty sum() const
  241. { // return sum all elements
  242. _Ty _Sum = _Myptr[0];
  243. for (size_t _Idx = 0; ++_Idx < size(); )
  244. _Sum += _Myptr[_Idx];
  245. return (_Sum);
  246. }
  247. _Ty min() const
  248. { // return smallest of all elements
  249. _Ty _Min = _Myptr[0];
  250. for (size_t _Idx = 0; ++_Idx < size(); )
  251. if (_Myptr[_Idx] < _Min)
  252. _Min = _Myptr[_Idx];
  253. return (_Min);
  254. }
  255. _Ty max() const
  256. { // return largest of all elements
  257. _Ty _Max = _Myptr[0];
  258. for (size_t _Idx = 0; ++_Idx < size(); )
  259. if (_Max < _Myptr[_Idx])
  260. _Max = _Myptr[_Idx];
  261. return (_Max);
  262. }
  263. valarray<_Ty> shift(int _Count) const
  264. { // return valarray left shifted
  265. static _Ty _Dflt;
  266. _VALOP(_Ty, size(),
  267. 0 < _Count && size() - _Idx <= (size_t)_Count
  268. || _Count < 0 && _Idx < (size_t)-_Count
  269. ? _Dflt : _Myptr[_Idx + _Count]);
  270. }
  271. valarray<_Ty> cshift(int _Count) const
  272. { // return valarray left rotated
  273. if (size() == 0)
  274. ; // no shift
  275. else if (_Count < 0)
  276. { // right shift
  277. if ((_Count += size()) < 0)
  278. _Count = size() - (-_Count) % size();
  279. }
  280. else if (size() <= (size_t)_Count)
  281. _Count %= size();
  282. _VALOP(_Ty, size(), size() - _Idx <= (size_t)_Count
  283. ? _Myptr[_Idx - size() + _Count] : _Myptr[_Idx + _Count]);
  284. }
  285. valarray<_Ty> apply(_Ty _Func(_Ty)) const
  286. { // return valarray transformed by _Func, value argument
  287. _VALOP(_Ty, size(), _Func(_Myptr[_Idx]));
  288. }
  289. valarray<_Ty> apply(_Ty _Func(const _Ty&)) const
  290. { // return valarray transformed by _Func, nonmutable argument
  291. _VALOP(_Ty, size(), _Func(_Myptr[_Idx]));
  292. }
  293. void free() // retained
  294. { // erase all elements
  295. _Tidy(true);
  296. }
  297. private:
  298. void _Grow(size_t _Count, const _Ty *_Ptr = 0, size_t _Inc = 0,
  299. bool _Trim = false)
  300. { // grow to _Count elements and pad, trim if _Trim is true
  301. size_t _Oldsize = _Myptr == 0 ? 0 : _Myres;
  302. if (_Count == 0)
  303. { // new sequence empty
  304. if (_Trim)
  305. _Tidy(true);
  306. }
  307. else if (_Count == _Oldsize || _Count < _Oldsize && !_Trim)
  308. ; // big enough, no need to pad or trim
  309. else
  310. { // allocate new array, copy and pad
  311. size_t _Idx;
  312. size_t _Newsize = _Myptr == 0 && _Count < _Myres
  313. ? _Myres : _Count;
  314. _Ty *_Newptr = 0;
  315. size_t _Nm = _Count < _Mysize ? _Count : _Mysize;
  316. _TRY_BEGIN
  317. _Newptr = new _Ty[_Newsize];
  318. _CATCH_ALL
  319. _Tidy(true); // allocation failed, discard storage and reraise
  320. _RERAISE;
  321. _CATCH_END
  322. for (_Idx = 0; _Idx < _Nm; ++_Idx)
  323. _Newptr[_Idx] = _Myptr[_Idx];
  324. if (_Ptr != 0)
  325. for (; _Idx < _Newsize; ++_Idx, _Ptr += _Inc)
  326. _Newptr[_Idx] = *_Ptr;
  327. _Tidy(true);
  328. _Myptr = _Newptr;
  329. _Myres = _Newsize;
  330. }
  331. _Mysize = _Count;
  332. }
  333. void _Tidy(bool _Constructed = false)
  334. { // initialize the object, freeing any allocated storage
  335. if (_Constructed && _Myptr != 0)
  336. delete[] _Myptr;
  337. _Mysize = 0;
  338. _Myptr = 0;
  339. _Myres = 0;
  340. }
  341. _Ty *_Myptr; // current storage reserved for array
  342. size_t _Mysize; // current length of sequence
  343. size_t _Myres; // length of array
  344. };
  345. // valarray TEMPLATE FUNCTIONS
  346. template<class _Ty> inline
  347. valarray<_Ty> operator*(const valarray<_Ty>& _Left,
  348. const _Ty& _Right)
  349. { // return valarray * scalar
  350. _VALOP(_Ty, _Left.size(), _Left[_Idx] * _Right);
  351. }
  352. template<class _Ty> inline
  353. valarray<_Ty> operator*(const _Ty& _Left,
  354. const valarray<_Ty>& _Right)
  355. { // return scalar * valarray
  356. _VALOP(_Ty, _Right.size(), _Left * _Right[_Idx]);
  357. }
  358. template<class _Ty> inline
  359. valarray<_Ty> operator/(const valarray<_Ty>& _Left,
  360. const _Ty& _Right)
  361. { // return valarray / scalar
  362. _VALOP(_Ty, _Left.size(), _Left[_Idx] / _Right);
  363. }
  364. template<class _Ty> inline
  365. valarray<_Ty> operator/(const _Ty& _Left,
  366. const valarray<_Ty>& _Right)
  367. { // return scalar / valarray
  368. _VALOP(_Ty, _Right.size(), _Left / _Right[_Idx]);
  369. }
  370. template<class _Ty> inline
  371. valarray<_Ty> operator%(const valarray<_Ty>& _Left,
  372. const _Ty& _Right)
  373. { // return valarray % scalar
  374. _VALOP(_Ty, _Left.size(), _Left[_Idx] % _Right);
  375. }
  376. template<class _Ty> inline
  377. valarray<_Ty> operator%(const _Ty& _Left,
  378. const valarray<_Ty>& _Right)
  379. { // return scalar % valarray
  380. _VALOP(_Ty, _Right.size(), _Left % _Right[_Idx]);
  381. }
  382. template<class _Ty> inline
  383. valarray<_Ty> operator+(const valarray<_Ty>& _Left,
  384. const _Ty& _Right)
  385. { // return valarray + scalar
  386. _VALOP(_Ty, _Left.size(), _Left[_Idx] + _Right);
  387. }
  388. template<class _Ty> inline
  389. valarray<_Ty> operator+(const _Ty& _Left,
  390. const valarray<_Ty>& _Right)
  391. { // return scalar + valarray
  392. _VALOP(_Ty, _Right.size(), _Left + _Right[_Idx]);
  393. }
  394. template<class _Ty> inline
  395. valarray<_Ty> operator-(const valarray<_Ty>& _Left,
  396. const _Ty& _Right)
  397. { // return valarray - scalar
  398. _VALOP(_Ty, _Left.size(), _Left[_Idx] - _Right);
  399. }
  400. template<class _Ty> inline
  401. valarray<_Ty> operator-(const _Ty& _Left,
  402. const valarray<_Ty>& _Right)
  403. { // return scalar - valarray
  404. _VALOP(_Ty, _Right.size(), _Left - _Right[_Idx]);
  405. }
  406. template<class _Ty> inline
  407. valarray<_Ty> operator^(const valarray<_Ty>& _Left,
  408. const _Ty& _Right)
  409. { // return valarray ^ scalar
  410. _VALOP(_Ty, _Left.size(), _Left[_Idx] ^ _Right);
  411. }
  412. template<class _Ty> inline
  413. valarray<_Ty> operator^(const _Ty& _Left,
  414. const valarray<_Ty>& _Right)
  415. { // return scalar ^ valarray
  416. _VALOP(_Ty, _Right.size(), _Left ^ _Right[_Idx]);
  417. }
  418. template<class _Ty> inline
  419. valarray<_Ty> operator&(const valarray<_Ty>& _Left,
  420. const _Ty& _Right)
  421. { // return valarray & scalar
  422. _VALOP(_Ty, _Left.size(), _Left[_Idx] & _Right);
  423. }
  424. template<class _Ty> inline
  425. valarray<_Ty> operator&(const _Ty& _Left,
  426. const valarray<_Ty>& _Right)
  427. { // return scalar & valarray
  428. _VALOP(_Ty, _Right.size(), _Left & _Right[_Idx]);
  429. }
  430. template<class _Ty> inline
  431. valarray<_Ty> operator|(const valarray<_Ty>& _Left,
  432. const _Ty& _Right)
  433. { // return valarray | scalar
  434. _VALOP(_Ty, _Left.size(), _Left[_Idx] | _Right);
  435. }
  436. template<class _Ty> inline
  437. valarray<_Ty> operator|(const _Ty& _Left,
  438. const valarray<_Ty>& _Right)
  439. { // return scalar | valarray
  440. _VALOP(_Ty, _Right.size(), _Left | _Right[_Idx]);
  441. }
  442. template<class _Ty> inline
  443. valarray<_Ty> operator<<(const valarray<_Ty>& _Left,
  444. const _Ty& _Right)
  445. { // return valarray << scalar
  446. _VALOP(_Ty, _Left.size(), _Left[_Idx] << _Right);
  447. }
  448. template<class _Ty> inline
  449. valarray<_Ty> operator<<(const _Ty& _Left,
  450. const valarray<_Ty>& _Right)
  451. { // return scalar << valarray
  452. _VALOP(_Ty, _Right.size(), _Left << _Right[_Idx]);
  453. }
  454. template<class _Ty> inline
  455. valarray<_Ty> operator>>(const valarray<_Ty>& _Left,
  456. const _Ty& _Right)
  457. { // return valarray >> scalar
  458. _VALOP(_Ty, _Left.size(), _Left[_Idx] >> _Right);
  459. }
  460. template<class _Ty> inline
  461. valarray<_Ty> operator>>(const _Ty& _Left,
  462. const valarray<_Ty>& _Right)
  463. { // return scalar >> valarray
  464. _VALOP(_Ty, _Right.size(), _Left >> _Right[_Idx]);
  465. }
  466. template<class _Ty> inline
  467. _Boolarray operator&&(const valarray<_Ty>& _Left,
  468. const _Ty& _Right)
  469. { // return valarray && scalar
  470. _VALOP(_Bool, _Left.size(), _Left[_Idx] && _Right);
  471. }
  472. template<class _Ty> inline
  473. _Boolarray operator&&(const _Ty& _Left,
  474. const valarray<_Ty>& _Right)
  475. { // return scalar && valarray
  476. _VALOP(_Bool, _Right.size(), _Left && _Right[_Idx]);
  477. }
  478. template<class _Ty> inline
  479. _Boolarray operator||(const valarray<_Ty>& _Left,
  480. const _Ty& _Right)
  481. { // return valarray || scalar
  482. _VALOP(_Bool, _Left.size(), _Left[_Idx] || _Right);
  483. }
  484. template<class _Ty> inline
  485. _Boolarray operator||(const _Ty& _Left,
  486. const valarray<_Ty>& _Right)
  487. { // return scalar || valarray
  488. _VALOP(_Bool, _Right.size(), _Left || _Right[_Idx]);
  489. }
  490. template<class _Ty> inline
  491. valarray<_Ty> operator*(const valarray<_Ty>& _Left,
  492. const valarray<_Ty>& _Right)
  493. { // return valarray * valarray
  494. _VALOP(_Ty, _Left.size(), _Left[_Idx] * _Right[_Idx]);
  495. }
  496. template<class _Ty> inline
  497. valarray<_Ty> operator/(const valarray<_Ty>& _Left,
  498. const valarray<_Ty>& _Right)
  499. { // return valarray ? valarray
  500. _VALOP(_Ty, _Left.size(), _Left[_Idx] / _Right[_Idx]);
  501. }
  502. template<class _Ty> inline
  503. valarray<_Ty> operator%(const valarray<_Ty>& _Left,
  504. const valarray<_Ty>& _Right)
  505. { // return valarray % valarray
  506. _VALOP(_Ty, _Left.size(), _Left[_Idx] % _Right[_Idx]);
  507. }
  508. template<class _Ty> inline
  509. valarray<_Ty> operator+(const valarray<_Ty>& _Left,
  510. const valarray<_Ty>& _Right)
  511. { // return valarray + valarray
  512. _VALOP(_Ty, _Left.size(), _Left[_Idx] + _Right[_Idx]);
  513. }
  514. template<class _Ty> inline
  515. valarray<_Ty> operator-(const valarray<_Ty>& _Left,
  516. const valarray<_Ty>& _Right)
  517. { // return valarray - valarray
  518. _VALOP(_Ty, _Left.size(), _Left[_Idx] - _Right[_Idx]);
  519. }
  520. template<class _Ty> inline
  521. valarray<_Ty> operator^(const valarray<_Ty>& _Left,
  522. const valarray<_Ty>& _Right)
  523. { // return valarray ^ valarray
  524. _VALOP(_Ty, _Left.size(), _Left[_Idx] ^ _Right[_Idx]);
  525. }
  526. template<class _Ty> inline
  527. valarray<_Ty> operator&(const valarray<_Ty>& _Left,
  528. const valarray<_Ty>& _Right)
  529. { // return valarray & valarray
  530. _VALOP(_Ty, _Left.size(), _Left[_Idx] & _Right[_Idx]);
  531. }
  532. template<class _Ty> inline
  533. valarray<_Ty> operator|(const valarray<_Ty>& _Left,
  534. const valarray<_Ty>& _Right)
  535. { // return valarray | valarray
  536. _VALOP(_Ty, _Left.size(), _Left[_Idx] | _Right[_Idx]);
  537. }
  538. template<class _Ty> inline
  539. valarray<_Ty> operator<<(const valarray<_Ty>& _Left,
  540. const valarray<_Ty>& _Right)
  541. { // return valarray << valarray
  542. _VALOP(_Ty, _Left.size(), _Left[_Idx] << _Right[_Idx]);
  543. }
  544. template<class _Ty> inline
  545. valarray<_Ty> operator>>(const valarray<_Ty>& _Left,
  546. const valarray<_Ty>& _Right)
  547. { // return valarray >> valarray
  548. _VALOP(_Ty, _Left.size(), _Left[_Idx] >> _Right[_Idx]);
  549. }
  550. template<class _Ty> inline
  551. _Boolarray operator&&(const valarray<_Ty>& _Left,
  552. const valarray<_Ty>& _Right)
  553. { // return valarray && valarray
  554. _VALOP(_Bool, _Left.size(), _Left[_Idx] && _Right[_Idx]);
  555. }
  556. template<class _Ty> inline
  557. _Boolarray operator||(const valarray<_Ty>& _Left,
  558. const valarray<_Ty>& _Right)
  559. { // return valarray || valarray
  560. _VALOP(_Bool, _Left.size(), _Left[_Idx] || _Right[_Idx]);
  561. }
  562. template<class _Ty> inline
  563. _Boolarray operator==(const valarray<_Ty>& _Left,
  564. const _Ty& _Right)
  565. { // return valarray == scalar
  566. _VALOP(_Bool, _Left.size(), _Left[_Idx] == _Right);
  567. }
  568. template<class _Ty> inline
  569. _Boolarray operator==(const _Ty& _Left,
  570. const valarray<_Ty>& _Right)
  571. { // return scalar == valarray
  572. _VALOP(_Bool, _Right.size(), _Left == _Right[_Idx]);
  573. }
  574. template<class _Ty> inline
  575. _Boolarray operator==(const valarray<_Ty>& _Left,
  576. const valarray<_Ty>& _Right)
  577. { // return valarray == valarray
  578. _VALOP(_Bool, _Left.size(), _Left[_Idx] == _Right[_Idx]);
  579. }
  580. template<class _Ty> inline
  581. _Boolarray operator!=(const valarray<_Ty>& _Left,
  582. const _Ty& _Right)
  583. { // return valarray != scalar
  584. _VALOP(_Bool, _Left.size(), _Left[_Idx] != _Right);
  585. }
  586. template<class _Ty> inline
  587. _Boolarray operator!=(const _Ty& _Left,
  588. const valarray<_Ty>& _Right)
  589. { // return scalar != valarray
  590. _VALOP(_Bool, _Right.size(), _Left != _Right[_Idx]);
  591. }
  592. template<class _Ty> inline
  593. _Boolarray operator!=(const valarray<_Ty>& _Left,
  594. const valarray<_Ty>& _Right)
  595. { // return valarray != valarray
  596. _VALOP(_Bool, _Left.size(), _Left[_Idx] != _Right[_Idx]);
  597. }
  598. template<class _Ty> inline
  599. _Boolarray operator<(const valarray<_Ty>& _Left,
  600. const _Ty& _Right)
  601. { // return valarray < scalar
  602. _VALOP(_Bool, _Left.size(), _Left[_Idx] < _Right);
  603. }
  604. template<class _Ty> inline
  605. _Boolarray operator<(const _Ty& _Left,
  606. const valarray<_Ty>& _Right)
  607. { // return scalar < valarray
  608. _VALOP(_Bool, _Right.size(), _Left < _Right[_Idx]);
  609. }
  610. template<class _Ty> inline
  611. _Boolarray operator<(const valarray<_Ty>& _Left,
  612. const valarray<_Ty>& _Right)
  613. { // return valarray < valarray
  614. _VALOP(_Bool, _Left.size(), _Left[_Idx] < _Right[_Idx]);
  615. }
  616. template<class _Ty> inline
  617. _Boolarray operator>(const valarray<_Ty>& _Left,
  618. const _Ty& _Right)
  619. { // return valarray > scalar
  620. _VALOP(_Bool, _Left.size(), _Left[_Idx] > _Right);
  621. }
  622. template<class _Ty> inline
  623. _Boolarray operator>(const _Ty& _Left,
  624. const valarray<_Ty>& _Right)
  625. { // return scalar > valarray
  626. _VALOP(_Bool, _Right.size(), _Left > _Right[_Idx]);
  627. }
  628. template<class _Ty> inline
  629. _Boolarray operator>(const valarray<_Ty>& _Left,
  630. const valarray<_Ty>& _Right)
  631. { // return valarray > valarray
  632. _VALOP(_Bool, _Left.size(), _Left[_Idx] > _Right[_Idx]);
  633. }
  634. template<class _Ty> inline
  635. _Boolarray operator<=(const valarray<_Ty>& _Left,
  636. const _Ty& _Right)
  637. { // return valarray <= scalar
  638. _VALOP(_Bool, _Left.size(), _Left[_Idx] <= _Right);
  639. }
  640. template<class _Ty> inline
  641. _Boolarray operator<=(const _Ty& _Left,
  642. const valarray<_Ty>& _Right)
  643. { // return scalar <= valarray
  644. _VALOP(_Bool, _Right.size(), _Left <= _Right[_Idx]);
  645. }
  646. template<class _Ty> inline
  647. _Boolarray operator<=(const valarray<_Ty>& _Left,
  648. const valarray<_Ty>& _Right)
  649. { // return valarray <= valarray
  650. _VALOP(_Bool, _Left.size(), _Left[_Idx] <= _Right[_Idx]);
  651. }
  652. template<class _Ty> inline
  653. _Boolarray operator>=(const valarray<_Ty>& _Left,
  654. const _Ty& _Right)
  655. { // return valarray >= scalar
  656. _VALOP(_Bool, _Left.size(), _Left[_Idx] >= _Right);
  657. }
  658. template<class _Ty> inline
  659. _Boolarray operator>=(const _Ty& _Left,
  660. const valarray<_Ty>& _Right)
  661. { // return scalar >= valarray
  662. _VALOP(_Bool, _Right.size(), _Left >= _Right[_Idx]);
  663. }
  664. template<class _Ty> inline
  665. _Boolarray operator>=(const valarray<_Ty>& _Left,
  666. const valarray<_Ty>& _Right)
  667. { // return valarray >= valarray
  668. _VALOP(_Bool, _Left.size(), _Left[_Idx] >= _Right[_Idx]);
  669. }
  670. template<class _Ty> inline
  671. valarray<_Ty> abs(const valarray<_Ty>& _Left)
  672. { // apply abs to each element of valarray
  673. _VALOP(_Ty, _Left.size(), _Left[_Idx] < 0 ? -_Left[_Idx] : _Left[_Idx]);
  674. }
  675. template<class _Ty> inline
  676. valarray<_Ty> acos(const valarray<_Ty>& _Left)
  677. { // apply acos to each element of valarray
  678. _VALOP(_Ty, _Left.size(), ::acos(_Left[_Idx]));
  679. }
  680. template<class _Ty> inline
  681. valarray<_Ty> asin(const valarray<_Ty>& _Left)
  682. { // apply asin to each element of valarray
  683. _VALOP(_Ty, _Left.size(), ::asin(_Left[_Idx]));
  684. }
  685. template<class _Ty> inline
  686. valarray<_Ty> atan(const valarray<_Ty>& _Left)
  687. { // apply atan to each element of valarray
  688. _VALOP(_Ty, _Left.size(), ::atan(_Left[_Idx]));
  689. }
  690. template<class _Ty> inline
  691. valarray<_Ty> atan2(const valarray<_Ty>& _Left,
  692. const valarray<_Ty>& _Right)
  693. { // apply atan2 to pairs of valarray elements
  694. _VALOP(_Ty, _Left.size(), ::atan2(_Left[_Idx], _Right[_Idx]));
  695. }
  696. template<class _Ty> inline
  697. valarray<_Ty> atan2(const valarray<_Ty>& _Left, const _Ty& _Right)
  698. { // apply atan2 to each valarray element and scalar
  699. _VALOP(_Ty, _Left.size(), ::atan2(_Left[_Idx], _Right));
  700. }
  701. template<class _Ty> inline
  702. valarray<_Ty> atan2(const _Ty& _Left, const valarray<_Ty>& _Right)
  703. { // apply atan2 to scalar and each valarray element
  704. _VALOP(_Ty, _Right.size(), ::atan2(_Left, _Right[_Idx]));
  705. }
  706. template<class _Ty> inline
  707. valarray<_Ty> cos(const valarray<_Ty>& _Left)
  708. { // apply cos to each element of valarray
  709. _VALOP(_Ty, _Left.size(), ::cos(_Left[_Idx]));
  710. }
  711. template<class _Ty> inline
  712. valarray<_Ty> cosh(const valarray<_Ty>& _Left)
  713. { // apply cosh to each element of valarray
  714. _VALOP(_Ty, _Left.size(), ::cosh(_Left[_Idx]));
  715. }
  716. template<class _Ty> inline
  717. valarray<_Ty> exp(const valarray<_Ty>& _Left)
  718. { // apply exp to each element of valarray
  719. _VALOP(_Ty, _Left.size(), ::exp(_Left[_Idx]));
  720. }
  721. template<class _Ty> inline
  722. valarray<_Ty> log(const valarray<_Ty>& _Left)
  723. { // apply log to each element of valarray
  724. _VALOP(_Ty, _Left.size(), ::log(_Left[_Idx]));
  725. }
  726. template<class _Ty> inline
  727. valarray<_Ty> log10(const valarray<_Ty>& _Left)
  728. { // apply log10 to each element of valarray
  729. _VALOP(_Ty, _Left.size(), ::log10(_Left[_Idx]));
  730. }
  731. template<class _Ty> inline
  732. valarray<_Ty> pow(const valarray<_Ty>& _Left,
  733. const valarray<_Ty>& _Right)
  734. { // apply pow to pairs of valarray elements
  735. _VALOP(_Ty, _Left.size(), ::pow(_Left[_Idx], _Right[_Idx]));
  736. }
  737. template<class _Ty> inline
  738. valarray<_Ty> pow(const valarray<_Ty>& _Left, const _Ty& _Right)
  739. { // apply pow to each valarray element and scalar
  740. _VALOP(_Ty, _Left.size(), ::pow(_Left[_Idx], _Right));
  741. }
  742. template<class _Ty> inline
  743. valarray<_Ty> pow(const _Ty& _Left, const valarray<_Ty>& _Right)
  744. { // apply pow to scalar and each valarray element
  745. _VALOP(_Ty, _Right.size(), ::pow(_Left, _Right[_Idx]));
  746. }
  747. template<class _Ty> inline
  748. valarray<_Ty> sin(const valarray<_Ty>& _Left)
  749. { // apply sin to each element of valarray
  750. _VALOP(_Ty, _Left.size(), ::sin(_Left[_Idx]));
  751. }
  752. template<class _Ty> inline
  753. valarray<_Ty> sinh(const valarray<_Ty>& _Left)
  754. { // apply sinh to each element of valarray
  755. _VALOP(_Ty, _Left.size(), ::sinh(_Left[_Idx]));
  756. }
  757. template<class _Ty> inline
  758. valarray<_Ty> sqrt(const valarray<_Ty>& _Left)
  759. { // apply sqrt to each element of valarray
  760. _VALOP(_Ty, _Left.size(), ::sqrt(_Left[_Idx]));
  761. }
  762. template<class _Ty> inline
  763. valarray<_Ty> tan(const valarray<_Ty>& _Left)
  764. { // apply tan to each element of valarray
  765. _VALOP(_Ty, _Left.size(), ::tan(_Left[_Idx]));
  766. }
  767. template<class _Ty> inline
  768. valarray<_Ty> tanh(const valarray<_Ty>& _Left)
  769. { // apply tanh to each element of valarray
  770. _VALOP(_Ty, _Left.size(), ::tanh(_Left[_Idx]));
  771. }
  772. // CLASS slice
  773. class slice
  774. { // define a slice of a valarray
  775. public:
  776. slice()
  777. : _Start(0), _Len(0), _Stride(0)
  778. { // construct with all zeros
  779. }
  780. slice(size_t _Off, size_t _Count, size_t _Inc)
  781. : _Start(_Off), _Len(_Count), _Stride(_Inc)
  782. { // construct slice from starting offset, length, and stride
  783. }
  784. size_t start() const
  785. { // return starting offset of slice
  786. return (_Start);
  787. }
  788. size_t size() const
  789. { // return number of elements specified by slice
  790. return (_Len);
  791. }
  792. size_t stride() const
  793. { // return distance between elements specified by slice
  794. return (_Stride);
  795. }
  796. protected:
  797. size_t _Start; // the starting offset
  798. size_t _Len; // the number of elements
  799. size_t _Stride; // the distance between elements
  800. };
  801. // MACROS FOR slice_array
  802. #define _SLOP(RHS) /* apply RHS(_Idx) to slice_array */ \
  803. size_t _Off = _Start; \
  804. for (size_t _Idx = 0; _Idx < _Len; ++_Idx, _Off += _Stride) \
  805. _Myptr[_Off] RHS;
  806. // TEMPLATE CLASS slice_array
  807. template<class _Ty>
  808. class slice_array
  809. : public slice
  810. { // define a slice of a valarray
  811. public:
  812. typedef _Ty value_type;
  813. void operator=(const valarray<_Ty>& _Right) const
  814. { // assign a valarray to a slice
  815. _SLOP(= _Right[_Idx]);
  816. }
  817. void operator=(const _Ty& _Right) const
  818. { // assign a scalar to elements of a slice
  819. _SLOP(= _Right);
  820. }
  821. void operator*=(const valarray<_Ty>& _Right) const
  822. { // multiply slice by valarray
  823. _SLOP(*= _Right[_Idx]);
  824. }
  825. void operator/=(const valarray<_Ty>& _Right) const
  826. { // divide slice by valarray
  827. _SLOP(/= _Right[_Idx]);
  828. }
  829. void operator%=(const valarray<_Ty>& _Right) const
  830. { // remainder slice by valarray
  831. _SLOP(%= _Right[_Idx]);
  832. }
  833. void operator+=(const valarray<_Ty>& _Right) const
  834. { // add slice to valarray
  835. _SLOP(+= _Right[_Idx]);
  836. }
  837. void operator-=(const valarray<_Ty>& _Right) const
  838. { // subtract valarray from slice
  839. _SLOP(-= _Right[_Idx]);
  840. }
  841. void operator^=(const valarray<_Ty>& _Right) const
  842. { // XOR valarray into slice
  843. _SLOP(^= _Right[_Idx]);
  844. }
  845. void operator&=(const valarray<_Ty>& _Right) const
  846. { // AND valarray into slice
  847. _SLOP(&= _Right[_Idx]);
  848. }
  849. void operator|=(const valarray<_Ty>& _Right) const
  850. { // OR valarray into slice
  851. _SLOP(|= _Right[_Idx]);
  852. }
  853. void operator<<=(const valarray<_Ty>& _Right) const
  854. { // left shift slice by valarray
  855. _SLOP(<<= _Right[_Idx]);
  856. }
  857. void operator>>=(const valarray<_Ty>& _Right) const
  858. { // right shift slice by valarray
  859. _SLOP(>>= _Right[_Idx]);
  860. }
  861. _Ty& _Data(size_t _Idx) const
  862. { // return reference to underlying array element
  863. return (_Myptr[_Idx]);
  864. }
  865. private:
  866. friend class valarray<_Ty>;
  867. slice_array(const slice& _Slice, _Ty *_Pdata)
  868. : slice(_Slice), _Myptr(_Pdata)
  869. { // construct from slice and pointer to valarray contents
  870. }
  871. // slice_array(); // not defined
  872. // slice_array(const slice_array&); // not defined
  873. // slice_array& operator=(const slice_array&); // not defined
  874. _Ty *_Myptr; // pointer to valarray contents
  875. };
  876. // CLASS gslice
  877. class gslice
  878. { // define a generalized (multidimensional) slice of a valarray
  879. public:
  880. gslice()
  881. : _Start(0)
  882. { // construct with all zeros
  883. }
  884. gslice(size_t _Off, const _Sizarray& _Lenarr,
  885. const _Sizarray& _Incarr)
  886. : _Start(_Off), _Len(_Lenarr), _Stride(_Incarr)
  887. { // construct from starting offset, arrays of lengths and strides
  888. }
  889. size_t start() const
  890. { // return starting offset of generalized slice
  891. return (_Start);
  892. }
  893. _Sizarray size() const
  894. { // return array of lengths of slices
  895. return (_Len);
  896. }
  897. _Sizarray stride() const
  898. { // return array of strides of slices
  899. return (_Stride);
  900. }
  901. size_t _Nslice() const
  902. { // return number of slices
  903. return (_Len.size());
  904. }
  905. size_t _Off(_Sizarray& _Indexarr) const
  906. { // return offset for an array of indexes, then increment
  907. size_t _Idx, _Ans = _Start;
  908. for (_Idx = 0; _Idx < _Indexarr.size(); ++_Idx)
  909. _Ans += _Indexarr[_Idx] * _Stride[_Idx]; // compute offset
  910. while (0 < _Idx--)
  911. if (++_Indexarr[_Idx] < _Len[_Idx])
  912. break; // increment done, quit
  913. else
  914. _Indexarr[_Idx] = 0; // carry to more-significant index
  915. return (_Ans);
  916. }
  917. size_t _Totlen() const
  918. { // return total length of generalized slice
  919. if (_Len.size() == 0)
  920. return (0);
  921. size_t _Count = _Len[0];
  922. for (size_t _Idx = 0; ++_Idx < _Len.size(); )
  923. _Count *= _Len[_Idx];
  924. return (_Count);
  925. }
  926. private:
  927. size_t _Start; // the starting offset
  928. _Sizarray _Len; // array of numbers of elements
  929. _Sizarray _Stride; // array of distances between elements
  930. };
  931. // MACROS FOR gslice_array
  932. #define _GSLOP(RHS) /* apply RHS(_Idx) to gslice_array */ \
  933. _Sizarray _Indexarray((size_t)0, _Nslice()); \
  934. size_t _Size = _Totlen(); \
  935. for (size_t _Idx = 0; _Idx < _Size; ++_Idx) \
  936. _Myptr[_Off(_Indexarray)] RHS;
  937. // TEMPLATE CLASS gslice_array
  938. template<class _Ty>
  939. class gslice_array
  940. : public gslice
  941. { // define a generalized slice of a valarray
  942. public:
  943. typedef _Ty value_type;
  944. void operator=(const valarray<_Ty>& _Right) const
  945. { // assign a valarray to a generalized slice
  946. _GSLOP(= _Right[_Idx]);
  947. }
  948. void operator=(const _Ty& _Right) const
  949. { // assign a scalar to elements of a generalized slice
  950. _GSLOP(= _Right);
  951. }
  952. void operator*=(const valarray<_Ty>& _Right) const
  953. { // multiply generalized slice by valarray
  954. _GSLOP(*= _Right[_Idx]);
  955. }
  956. void operator/=(const valarray<_Ty>& _Right) const
  957. { // divide generalized slice by valarray
  958. _GSLOP(/= _Right[_Idx]);
  959. }
  960. void operator%=(const valarray<_Ty>& _Right) const
  961. { // remainder generalized slice by valarray
  962. _GSLOP(%= _Right[_Idx]);
  963. }
  964. void operator+=(const valarray<_Ty>& _Right) const
  965. { // add valarray to generalized slice
  966. _GSLOP(+= _Right[_Idx]);
  967. }
  968. void operator-=(const valarray<_Ty>& _Right) const
  969. { // subtract valarray from generalized slice
  970. _GSLOP(-= _Right[_Idx]);
  971. }
  972. void operator^=(const valarray<_Ty>& _Right) const
  973. { // XOR valarray into generalized slice
  974. _GSLOP(^= _Right[_Idx]);
  975. }
  976. void operator&=(const valarray<_Ty>& _Right) const
  977. { // AND valarray into generalized slice
  978. _GSLOP(&= _Right[_Idx]);
  979. }
  980. void operator|=(const valarray<_Ty>& _Right) const
  981. { // OR valarray into generalized slice
  982. _GSLOP(|= _Right[_Idx]);
  983. }
  984. void operator<<=(const valarray<_Ty>& _Right) const
  985. { // left shift generalized slice by valarray
  986. _GSLOP(<<= _Right[_Idx]);
  987. }
  988. void operator>>=(const valarray<_Ty>& _Right) const
  989. { // right shift generalized slice by valarray
  990. _GSLOP(>>= _Right[_Idx]);
  991. }
  992. _Ty& _Data(size_t _Idx) const
  993. { // return reference to underlying array element
  994. return (_Myptr[_Idx]);
  995. }
  996. private:
  997. friend class valarray<_Ty>;
  998. gslice_array(const gslice& _Gslice, _Ty *_Ptr)
  999. : gslice(_Gslice), _Myptr(_Ptr)
  1000. { // construct from gslice and pointer to valarray contents
  1001. }
  1002. // gslice_array(); // not defined
  1003. // gslice_array(const gslice_array&); // not defined
  1004. // gslice_array& operator=( const gslice_array&); // not defined
  1005. _Ty *_Myptr; // pointer to valarray contents
  1006. };
  1007. // MACROS FOR mask_array
  1008. #define _MOP(RHS) /* apply RHS(_Idx) to mask_array */ \
  1009. size_t _Off = 0; \
  1010. size_t _Size = _Totlen(); \
  1011. for (size_t _Idx = 0; _Idx < _Size; ++_Off) \
  1012. if (_Mask(_Off)) \
  1013. _Myptr[_Off] RHS, ++_Idx;
  1014. // TEMPLATE CLASS mask_array
  1015. template<class _Ty>
  1016. class mask_array
  1017. { // define a subset of a valarray with an array of mask bits
  1018. public:
  1019. typedef _Ty value_type;
  1020. void operator=(const valarray<_Ty>& _Right) const
  1021. { // assign a valarray to a masked array
  1022. _MOP(= _Right[_Idx]);
  1023. }
  1024. void operator=(const _Ty& _Right) const
  1025. { // assign a scalar to elements of a masked array
  1026. _MOP(= _Right);
  1027. }
  1028. void operator*=(const valarray<_Ty>& _Right) const
  1029. { // multiply masked array by valarray
  1030. _MOP(*= _Right[_Idx]);
  1031. }
  1032. void operator/=(const valarray<_Ty>& _Right) const
  1033. { // divide masked array by valarray
  1034. _MOP(/= _Right[_Idx]);
  1035. }
  1036. void operator%=(const valarray<_Ty>& _Right) const
  1037. { // remainder masked array by valarray
  1038. _MOP(%= _Right[_Idx]);
  1039. }
  1040. void operator+=(const valarray<_Ty>& _Right) const
  1041. { // add valarray to masked array
  1042. _MOP(+= _Right[_Idx]);
  1043. }
  1044. void operator-=(const valarray<_Ty>& _Right) const
  1045. { // subtract valarray from masked array
  1046. _MOP(-= _Right[_Idx]);
  1047. }
  1048. void operator^=(const valarray<_Ty>& _Right) const
  1049. { // XOR valarray into masked array
  1050. _MOP(^= _Right[_Idx]);
  1051. }
  1052. void operator&=(const valarray<_Ty>& _Right) const
  1053. { // OR valarray into masked array
  1054. _MOP(&= _Right[_Idx]);
  1055. }
  1056. void operator|=(const valarray<_Ty>& _Right) const
  1057. { // OR valarray into masked array
  1058. _MOP(|= _Right[_Idx]);
  1059. }
  1060. void operator<<=(const valarray<_Ty>& _Right) const
  1061. { // left shift masked array by valarray
  1062. _MOP(<<= _Right[_Idx]);
  1063. }
  1064. void operator>>=(const valarray<_Ty>& _Right) const
  1065. { // right shift masked array by valarray
  1066. _MOP(>>= _Right[_Idx]);
  1067. }
  1068. _Ty& _Data(size_t _Idx) const
  1069. { // return reference to underlying array element
  1070. return (_Myptr[_Idx]);
  1071. }
  1072. bool _Mask(size_t _Idx) const
  1073. { // return mask element for a given index
  1074. return (_Mybool[_Idx]);
  1075. }
  1076. size_t _Totlen() const
  1077. { // return total length of masked array
  1078. size_t _Count = 0;
  1079. for (size_t _Idx = 0; _Idx < _Mybool.size(); ++_Idx)
  1080. if (_Mybool[_Idx])
  1081. ++_Count;
  1082. return (_Count);
  1083. }
  1084. private:
  1085. friend class valarray<_Ty>;
  1086. mask_array(const _Boolarray& _Maskarr, _Ty *_Pdata)
  1087. : _Mybool(_Maskarr), _Myptr(_Pdata)
  1088. { // construct from mask array and pointer to valarray contents
  1089. }
  1090. // mask_array(); // not defined
  1091. // mask_array(const mask_array&); // not defined
  1092. // mask_array& operator=(const mask_array&); // not defined
  1093. _Boolarray _Mybool; // array of mask bits
  1094. _Ty *_Myptr; // pointer to valarray contents
  1095. };
  1096. // MACROS FOR indirect_array
  1097. #define _IOP(RHS) /* apply RHS(_Idx) to indirect_array */ \
  1098. size_t _Size = _Totlen(); \
  1099. for (size_t _Idx = 0; _Idx < _Size; ++_Idx) \
  1100. _Myptr[_Indir(_Idx)] RHS;
  1101. // TEMPLATE CLASS indirect_array
  1102. template<class _Ty>
  1103. class indirect_array
  1104. { // define a subset of a valarray with an array of indexes
  1105. public:
  1106. typedef _Ty value_type;
  1107. void operator=(const valarray<_Ty>& _Right) const
  1108. { // assign a valarray to an indirect array
  1109. _IOP(= _Right[_Idx]);
  1110. }
  1111. void operator=(const _Ty& _Right) const
  1112. { // assign a scalar to elements of an indirect array
  1113. _IOP(= _Right);
  1114. }
  1115. void operator*=(const valarray<_Ty>& _Right) const
  1116. { // multiply indirect array by valarray
  1117. _IOP(*= _Right[_Idx]);
  1118. }
  1119. void operator/=(const valarray<_Ty>& _Right) const
  1120. { // divide indirect array by valarray
  1121. _IOP(/= _Right[_Idx]);
  1122. }
  1123. void operator%=(const valarray<_Ty>& _Right) const
  1124. { // remainder indirect array by valarray
  1125. _IOP(%= _Right[_Idx]);
  1126. }
  1127. void operator+=(const valarray<_Ty>& _Right) const
  1128. { // add valarray to indirect array
  1129. _IOP(+= _Right[_Idx]);
  1130. }
  1131. void operator-=(const valarray<_Ty>& _Right) const
  1132. { // subtract valarray from indirect array
  1133. _IOP(-= _Right[_Idx]);
  1134. }
  1135. void operator^=(const valarray<_Ty>& _Right) const
  1136. { // XOR valarray into indirect array
  1137. _IOP(^= _Right[_Idx]);
  1138. }
  1139. void operator&=(const valarray<_Ty>& _Right) const
  1140. { // AND valarray into indirect array
  1141. _IOP(&= _Right[_Idx]);
  1142. }
  1143. void operator|=(const valarray<_Ty>& _Right) const
  1144. { // OR valarray into indirect array
  1145. _IOP(|= _Right[_Idx]);
  1146. }
  1147. void operator<<=(const valarray<_Ty>& _Right) const
  1148. { // left shift indirect array by valarray
  1149. _IOP(<<= _Right[_Idx]);
  1150. }
  1151. void operator>>=(const valarray<_Ty>& _Right) const
  1152. { // right shift indirect array by valarray
  1153. _IOP(>>= _Right[_Idx]);
  1154. }
  1155. _Ty& _Data(size_t _Idx) const
  1156. { // return reference to underlying array element
  1157. return (_Myptr[_Idx]);
  1158. }
  1159. size_t _Indir(size_t _Idx) const
  1160. { // return mapped index for a given index
  1161. return (_Myindarr[_Idx]);
  1162. }
  1163. size_t _Totlen() const
  1164. { // return total length of indirect array
  1165. return (_Myindarr.size());
  1166. }
  1167. private:
  1168. friend class valarray<_Ty>;
  1169. indirect_array(const _Sizarray& _Indarr, _Ty *_Ptr)
  1170. : _Myindarr(_Indarr), _Myptr(_Ptr)
  1171. { // construct from indirect array and pointer to valarray contents
  1172. }
  1173. // indirect_array(); // not defined
  1174. // indirect_array(const indirect_array&); // not defined
  1175. // indirect_array& operator=(const indirect_array&); // not defined
  1176. _Sizarray _Myindarr; // array of indirect indexes
  1177. _Ty *_Myptr; // pointer to valarray contents
  1178. };
  1179. // slice_array TEMPLATE FUNCTIONS
  1180. template<class _Ty> inline
  1181. valarray<_Ty>& valarray<_Ty>::operator=(
  1182. const slice_array<_Ty>& _Slicearr)
  1183. { // assign slice array to valarray
  1184. _Tidy(true);
  1185. _Grow(_Slicearr.size(), &_Slicearr._Data(_Slicearr.start()),
  1186. _Slicearr.stride());
  1187. return (*this);
  1188. }
  1189. template<class _Ty> inline
  1190. valarray<_Ty> valarray<_Ty>::operator[](slice _Slice) const
  1191. { // subscript nonmutable valarray by slice
  1192. return (valarray<_Ty>(slice_array<_Ty>(_Slice, _Myptr)));
  1193. }
  1194. template<class _Ty> inline
  1195. slice_array<_Ty> valarray<_Ty>::operator[](slice _Slice)
  1196. { // subscript mutable valarray by slice
  1197. return (slice_array<_Ty>(_Slice, _Myptr));
  1198. }
  1199. // gslice_array TEMPLATE FUNCTIONS
  1200. template<class _Ty> inline
  1201. valarray<_Ty>& valarray<_Ty>::operator=(
  1202. const gslice_array<_Ty>& _Gslicearr)
  1203. { // assign generalized slice array to valarray
  1204. _Tidy(true);
  1205. _Grow(_Gslicearr._Totlen());
  1206. _Sizarray _Indexarray((size_t)0, _Gslicearr._Nslice());
  1207. _VALGOP(= _Gslicearr._Data(_Gslicearr._Off(_Indexarray)));
  1208. }
  1209. template<class _Ty> inline
  1210. valarray<_Ty> valarray<_Ty>::operator[](const gslice& _Gslice) const
  1211. { // subscript nonmutable valarray by generalized slice
  1212. return (valarray<_Ty>(gslice_array<_Ty>(_Gslice, _Myptr)));
  1213. }
  1214. template<class _Ty> inline
  1215. gslice_array<_Ty> valarray<_Ty>::operator[](const gslice& _Gslicearr)
  1216. { // subscript mutable valarray by generalized slice
  1217. return (gslice_array<_Ty>(_Gslicearr, _Myptr));
  1218. }
  1219. // mask_array TEMPLATE FUNCTIONS
  1220. template<class _Ty> inline
  1221. valarray<_Ty>& valarray<_Ty>::operator=(const mask_array<_Ty>& _Maskarr)
  1222. { // assign masked array to valarray
  1223. _Tidy(true);
  1224. _Grow(_Maskarr._Totlen());
  1225. size_t _Count = 0;
  1226. for (size_t _Idx = 0; _Idx < size(); ++_Count)
  1227. if (_Maskarr._Mask(_Count))
  1228. _Myptr[_Idx++] = _Maskarr._Data(_Count);
  1229. return (*this);
  1230. }
  1231. template<class _Ty> inline
  1232. valarray<_Ty> valarray<_Ty>::operator[](const _Boolarray& _Boolarr) const
  1233. { // subscript nonmutable valarray by boolean (mask) array
  1234. return (valarray<_Ty>(mask_array<_Ty>(_Boolarr, _Myptr)));
  1235. }
  1236. template<class _Ty> inline
  1237. mask_array<_Ty> valarray<_Ty>::operator[](const _Boolarray& _Boolarr)
  1238. { // subscript nonmutable valarray by boolean (mask) array
  1239. return (mask_array<_Ty>(_Boolarr, _Myptr));
  1240. }
  1241. // indirect_array TEMPLATE FUNCTIONS
  1242. template<class _Ty> inline
  1243. valarray<_Ty>& valarray<_Ty>::operator=(
  1244. const indirect_array<_Ty>& _Indarr)
  1245. { // assign indirect array to valarray
  1246. _Tidy(true);
  1247. _Grow(_Indarr._Totlen());
  1248. _VALGOP(= _Indarr._Data(_Indarr._Indir(_Idx)));
  1249. }
  1250. template<class _Ty> inline
  1251. valarray<_Ty> valarray<_Ty>::operator[](const _Sizarray& _Indarr) const
  1252. { // subscript nonmutable valarray by indirect (mapping) array
  1253. return (valarray<_Ty>(indirect_array<_Ty>(_Indarr, _Myptr)));
  1254. }
  1255. template<class _Ty> inline
  1256. indirect_array<_Ty> valarray<_Ty>::operator[](const _Sizarray& _Indarr)
  1257. { // subscript mutable valarray by indirect (mapping) array
  1258. return (indirect_array<_Ty>(_Indarr, _Myptr));
  1259. }
  1260. _STD_END
  1261. #pragma warning(default: 4244)
  1262. #pragma warning(default: 4700)
  1263. #pragma warning(pop)
  1264. #pragma pack(pop)
  1265. #endif /* _VALARRAY_ */
  1266. /*
  1267. * Copyright (c) 1992-2001 by P.J. Plauger. ALL RIGHTS RESERVED.
  1268. * Consult your license regarding permissions and restrictions.
  1269. V3.10:0009 */