valarray 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279
  1. // The template and inlines for the -*- C++ -*- valarray class.
  2. // Copyright (C) 1997-2023 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file include/valarray
  21. * This is a Standard C++ Library header.
  22. */
  23. // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
  24. #ifndef _GLIBCXX_VALARRAY
  25. #define _GLIBCXX_VALARRAY 1
  26. #pragma GCC system_header
  27. #include <bits/requires_hosted.h> // <cmath> dependant
  28. #include <bits/c++config.h>
  29. #include <cmath>
  30. #include <algorithm>
  31. #include <debug/debug.h>
  32. #if __cplusplus >= 201103L
  33. #include <initializer_list>
  34. #endif
  35. namespace std _GLIBCXX_VISIBILITY(default)
  36. {
  37. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  38. template<class _Clos, typename _Tp>
  39. class _Expr;
  40. template<typename _Tp1, typename _Tp2>
  41. class _ValArray;
  42. namespace __detail
  43. {
  44. template<class _Oper, template<class, class> class _Meta, class _Dom>
  45. struct _UnClos;
  46. template<class _Oper,
  47. template<class, class> class _Meta1,
  48. template<class, class> class _Meta2,
  49. class _Dom1, class _Dom2>
  50. struct _BinClos;
  51. template<template<class, class> class _Meta, class _Dom>
  52. struct _SClos;
  53. template<template<class, class> class _Meta, class _Dom>
  54. struct _GClos;
  55. template<template<class, class> class _Meta, class _Dom>
  56. struct _IClos;
  57. template<template<class, class> class _Meta, class _Dom>
  58. struct _ValFunClos;
  59. template<template<class, class> class _Meta, class _Dom>
  60. struct _RefFunClos;
  61. } // namespace __detail
  62. using __detail::_UnClos;
  63. using __detail::_BinClos;
  64. using __detail::_SClos;
  65. using __detail::_GClos;
  66. using __detail::_IClos;
  67. using __detail::_ValFunClos;
  68. using __detail::_RefFunClos;
  69. template<class _Tp> class valarray; // An array of type _Tp
  70. class slice; // BLAS-like slice out of an array
  71. template<class _Tp> class slice_array;
  72. class gslice; // generalized slice out of an array
  73. template<class _Tp> class gslice_array;
  74. template<class _Tp> class mask_array; // masked array
  75. template<class _Tp> class indirect_array; // indirected array
  76. _GLIBCXX_END_NAMESPACE_VERSION
  77. } // namespace
  78. #include <bits/valarray_array.h>
  79. #include <bits/valarray_before.h>
  80. namespace std _GLIBCXX_VISIBILITY(default)
  81. {
  82. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  83. /**
  84. * @defgroup numeric_arrays Numeric Arrays
  85. * @ingroup numerics
  86. *
  87. * Classes and functions for representing and manipulating arrays of elements.
  88. * @{
  89. */
  90. /**
  91. * @brief Smart array designed to support numeric processing.
  92. *
  93. * A valarray is an array that provides constraints intended to allow for
  94. * effective optimization of numeric array processing by reducing the
  95. * aliasing that can result from pointer representations. It represents a
  96. * one-dimensional array from which different multidimensional subsets can
  97. * be accessed and modified.
  98. *
  99. * @tparam _Tp Type of object in the array.
  100. */
  101. template<class _Tp>
  102. class valarray
  103. {
  104. template<class _Op>
  105. struct _UnaryOp
  106. {
  107. typedef typename __fun<_Op, _Tp>::result_type __rt;
  108. typedef _Expr<_UnClos<_Op, _ValArray, _Tp>, __rt> _Rt;
  109. };
  110. public:
  111. typedef _Tp value_type;
  112. // _lib.valarray.cons_ construct/destroy:
  113. /// Construct an empty array.
  114. valarray() _GLIBCXX_NOTHROW;
  115. /// Construct an array with @a n elements.
  116. explicit valarray(size_t);
  117. /// Construct an array with @a n elements initialized to @a t.
  118. valarray(const _Tp&, size_t);
  119. /// Construct an array initialized to the first @a n elements of @a t.
  120. valarray(const _Tp* __restrict__, size_t);
  121. /// Copy constructor.
  122. valarray(const valarray&);
  123. #if __cplusplus >= 201103L
  124. /// Move constructor.
  125. valarray(valarray&&) noexcept;
  126. #endif
  127. /// Construct an array with the same size and values in @a sa.
  128. valarray(const slice_array<_Tp>&);
  129. /// Construct an array with the same size and values in @a ga.
  130. valarray(const gslice_array<_Tp>&);
  131. /// Construct an array with the same size and values in @a ma.
  132. valarray(const mask_array<_Tp>&);
  133. /// Construct an array with the same size and values in @a ia.
  134. valarray(const indirect_array<_Tp>&);
  135. #if __cplusplus >= 201103L
  136. /// Construct an array with an initializer_list of values.
  137. valarray(initializer_list<_Tp>);
  138. #endif
  139. template<class _Dom>
  140. valarray(const _Expr<_Dom, _Tp>& __e);
  141. ~valarray() _GLIBCXX_NOEXCEPT;
  142. // _lib.valarray.assign_ assignment:
  143. /**
  144. * @brief Assign elements to an array.
  145. *
  146. * Assign elements of array to values in @a v.
  147. *
  148. * @param __v Valarray to get values from.
  149. */
  150. valarray<_Tp>& operator=(const valarray<_Tp>& __v);
  151. #if __cplusplus >= 201103L
  152. /**
  153. * @brief Move assign elements to an array.
  154. *
  155. * Move assign elements of array to values in @a v.
  156. *
  157. * @param __v Valarray to get values from.
  158. */
  159. valarray<_Tp>& operator=(valarray<_Tp>&& __v) noexcept;
  160. #endif
  161. /**
  162. * @brief Assign elements to a value.
  163. *
  164. * Assign all elements of array to @a t.
  165. *
  166. * @param __t Value for elements.
  167. */
  168. valarray<_Tp>& operator=(const _Tp& __t);
  169. /**
  170. * @brief Assign elements to an array subset.
  171. *
  172. * Assign elements of array to values in @a sa. Results are undefined
  173. * if @a sa does not have the same size as this array.
  174. *
  175. * @param __sa Array slice to get values from.
  176. */
  177. valarray<_Tp>& operator=(const slice_array<_Tp>& __sa);
  178. /**
  179. * @brief Assign elements to an array subset.
  180. *
  181. * Assign elements of array to values in @a ga. Results are undefined
  182. * if @a ga does not have the same size as this array.
  183. *
  184. * @param __ga Array slice to get values from.
  185. */
  186. valarray<_Tp>& operator=(const gslice_array<_Tp>& __ga);
  187. /**
  188. * @brief Assign elements to an array subset.
  189. *
  190. * Assign elements of array to values in @a ma. Results are undefined
  191. * if @a ma does not have the same size as this array.
  192. *
  193. * @param __ma Array slice to get values from.
  194. */
  195. valarray<_Tp>& operator=(const mask_array<_Tp>& __ma);
  196. /**
  197. * @brief Assign elements to an array subset.
  198. *
  199. * Assign elements of array to values in @a ia. Results are undefined
  200. * if @a ia does not have the same size as this array.
  201. *
  202. * @param __ia Array slice to get values from.
  203. */
  204. valarray<_Tp>& operator=(const indirect_array<_Tp>& __ia);
  205. #if __cplusplus >= 201103L
  206. /**
  207. * @brief Assign elements to an initializer_list.
  208. *
  209. * Assign elements of array to values in @a __l. Results are undefined
  210. * if @a __l does not have the same size as this array.
  211. *
  212. * @param __l initializer_list to get values from.
  213. */
  214. valarray& operator=(initializer_list<_Tp> __l);
  215. #endif
  216. template<class _Dom> valarray<_Tp>&
  217. operator= (const _Expr<_Dom, _Tp>&);
  218. // _lib.valarray.access_ element access:
  219. /**
  220. * Return a reference to the i'th array element.
  221. *
  222. * @param __i Index of element to return.
  223. * @return Reference to the i'th element.
  224. */
  225. _Tp& operator[](size_t __i) _GLIBCXX_NOTHROW;
  226. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  227. // 389. Const overload of valarray::operator[] returns by value.
  228. const _Tp& operator[](size_t) const _GLIBCXX_NOTHROW;
  229. // _lib.valarray.sub_ subset operations:
  230. /**
  231. * @brief Return an array subset.
  232. *
  233. * Returns a new valarray containing the elements of the array
  234. * indicated by the slice argument. The new valarray has the same size
  235. * as the input slice. @see slice.
  236. *
  237. * @param __s The source slice.
  238. * @return New valarray containing elements in @a __s.
  239. */
  240. _Expr<_SClos<_ValArray, _Tp>, _Tp> operator[](slice __s) const;
  241. /**
  242. * @brief Return a reference to an array subset.
  243. *
  244. * Returns a new valarray containing the elements of the array
  245. * indicated by the slice argument. The new valarray has the same size
  246. * as the input slice. @see slice.
  247. *
  248. * @param __s The source slice.
  249. * @return New valarray containing elements in @a __s.
  250. */
  251. slice_array<_Tp> operator[](slice __s);
  252. /**
  253. * @brief Return an array subset.
  254. *
  255. * Returns a slice_array referencing the elements of the array
  256. * indicated by the slice argument. @see gslice.
  257. *
  258. * @param __s The source slice.
  259. * @return Slice_array referencing elements indicated by @a __s.
  260. */
  261. _Expr<_GClos<_ValArray, _Tp>, _Tp> operator[](const gslice& __s) const;
  262. /**
  263. * @brief Return a reference to an array subset.
  264. *
  265. * Returns a new valarray containing the elements of the array
  266. * indicated by the gslice argument. The new valarray has
  267. * the same size as the input gslice. @see gslice.
  268. *
  269. * @param __s The source gslice.
  270. * @return New valarray containing elements in @a __s.
  271. */
  272. gslice_array<_Tp> operator[](const gslice& __s);
  273. /**
  274. * @brief Return an array subset.
  275. *
  276. * Returns a new valarray containing the elements of the array
  277. * indicated by the argument. The input is a valarray of bool which
  278. * represents a bitmask indicating which elements should be copied into
  279. * the new valarray. Each element of the array is added to the return
  280. * valarray if the corresponding element of the argument is true.
  281. *
  282. * @param __m The valarray bitmask.
  283. * @return New valarray containing elements indicated by @a __m.
  284. */
  285. valarray<_Tp> operator[](const valarray<bool>& __m) const;
  286. /**
  287. * @brief Return a reference to an array subset.
  288. *
  289. * Returns a new mask_array referencing the elements of the array
  290. * indicated by the argument. The input is a valarray of bool which
  291. * represents a bitmask indicating which elements are part of the
  292. * subset. Elements of the array are part of the subset if the
  293. * corresponding element of the argument is true.
  294. *
  295. * @param __m The valarray bitmask.
  296. * @return New valarray containing elements indicated by @a __m.
  297. */
  298. mask_array<_Tp> operator[](const valarray<bool>& __m);
  299. /**
  300. * @brief Return an array subset.
  301. *
  302. * Returns a new valarray containing the elements of the array
  303. * indicated by the argument. The elements in the argument are
  304. * interpreted as the indices of elements of this valarray to copy to
  305. * the return valarray.
  306. *
  307. * @param __i The valarray element index list.
  308. * @return New valarray containing elements in @a __s.
  309. */
  310. _Expr<_IClos<_ValArray, _Tp>, _Tp>
  311. operator[](const valarray<size_t>& __i) const;
  312. /**
  313. * @brief Return a reference to an array subset.
  314. *
  315. * Returns an indirect_array referencing the elements of the array
  316. * indicated by the argument. The elements in the argument are
  317. * interpreted as the indices of elements of this valarray to include
  318. * in the subset. The returned indirect_array refers to these
  319. * elements.
  320. *
  321. * @param __i The valarray element index list.
  322. * @return Indirect_array referencing elements in @a __i.
  323. */
  324. indirect_array<_Tp> operator[](const valarray<size_t>& __i);
  325. // _lib.valarray.unary_ unary operators:
  326. /// Return a new valarray by applying unary + to each element.
  327. typename _UnaryOp<__unary_plus>::_Rt operator+() const;
  328. /// Return a new valarray by applying unary - to each element.
  329. typename _UnaryOp<__negate>::_Rt operator-() const;
  330. /// Return a new valarray by applying unary ~ to each element.
  331. typename _UnaryOp<__bitwise_not>::_Rt operator~() const;
  332. /// Return a new valarray by applying unary ! to each element.
  333. typename _UnaryOp<__logical_not>::_Rt operator!() const;
  334. // _lib.valarray.cassign_ computed assignment:
  335. /// Multiply each element of array by @a t.
  336. valarray<_Tp>& operator*=(const _Tp&);
  337. /// Divide each element of array by @a t.
  338. valarray<_Tp>& operator/=(const _Tp&);
  339. /// Set each element e of array to e % @a t.
  340. valarray<_Tp>& operator%=(const _Tp&);
  341. /// Add @a t to each element of array.
  342. valarray<_Tp>& operator+=(const _Tp&);
  343. /// Subtract @a t to each element of array.
  344. valarray<_Tp>& operator-=(const _Tp&);
  345. /// Set each element e of array to e ^ @a t.
  346. valarray<_Tp>& operator^=(const _Tp&);
  347. /// Set each element e of array to e & @a t.
  348. valarray<_Tp>& operator&=(const _Tp&);
  349. /// Set each element e of array to e | @a t.
  350. valarray<_Tp>& operator|=(const _Tp&);
  351. /// Left shift each element e of array by @a t bits.
  352. valarray<_Tp>& operator<<=(const _Tp&);
  353. /// Right shift each element e of array by @a t bits.
  354. valarray<_Tp>& operator>>=(const _Tp&);
  355. /// Multiply elements of array by corresponding elements of @a v.
  356. valarray<_Tp>& operator*=(const valarray<_Tp>&);
  357. /// Divide elements of array by corresponding elements of @a v.
  358. valarray<_Tp>& operator/=(const valarray<_Tp>&);
  359. /// Modulo elements of array by corresponding elements of @a v.
  360. valarray<_Tp>& operator%=(const valarray<_Tp>&);
  361. /// Add corresponding elements of @a v to elements of array.
  362. valarray<_Tp>& operator+=(const valarray<_Tp>&);
  363. /// Subtract corresponding elements of @a v from elements of array.
  364. valarray<_Tp>& operator-=(const valarray<_Tp>&);
  365. /// Logical xor corresponding elements of @a v with elements of array.
  366. valarray<_Tp>& operator^=(const valarray<_Tp>&);
  367. /// Logical or corresponding elements of @a v with elements of array.
  368. valarray<_Tp>& operator|=(const valarray<_Tp>&);
  369. /// Logical and corresponding elements of @a v with elements of array.
  370. valarray<_Tp>& operator&=(const valarray<_Tp>&);
  371. /// Left shift elements of array by corresponding elements of @a v.
  372. valarray<_Tp>& operator<<=(const valarray<_Tp>&);
  373. /// Right shift elements of array by corresponding elements of @a v.
  374. valarray<_Tp>& operator>>=(const valarray<_Tp>&);
  375. template<class _Dom>
  376. valarray<_Tp>& operator*=(const _Expr<_Dom, _Tp>&);
  377. template<class _Dom>
  378. valarray<_Tp>& operator/=(const _Expr<_Dom, _Tp>&);
  379. template<class _Dom>
  380. valarray<_Tp>& operator%=(const _Expr<_Dom, _Tp>&);
  381. template<class _Dom>
  382. valarray<_Tp>& operator+=(const _Expr<_Dom, _Tp>&);
  383. template<class _Dom>
  384. valarray<_Tp>& operator-=(const _Expr<_Dom, _Tp>&);
  385. template<class _Dom>
  386. valarray<_Tp>& operator^=(const _Expr<_Dom, _Tp>&);
  387. template<class _Dom>
  388. valarray<_Tp>& operator|=(const _Expr<_Dom, _Tp>&);
  389. template<class _Dom>
  390. valarray<_Tp>& operator&=(const _Expr<_Dom, _Tp>&);
  391. template<class _Dom>
  392. valarray<_Tp>& operator<<=(const _Expr<_Dom, _Tp>&);
  393. template<class _Dom>
  394. valarray<_Tp>& operator>>=(const _Expr<_Dom, _Tp>&);
  395. // _lib.valarray.members_ member functions:
  396. #if __cplusplus >= 201103L
  397. /// Swap.
  398. void swap(valarray<_Tp>& __v) noexcept;
  399. #endif
  400. /// Return the number of elements in array.
  401. size_t size() const;
  402. /**
  403. * @brief Return the sum of all elements in the array.
  404. *
  405. * Accumulates the sum of all elements into a Tp using +=. The order
  406. * of adding the elements is unspecified.
  407. */
  408. _Tp sum() const;
  409. /// Return the minimum element using operator<().
  410. _Tp min() const;
  411. /// Return the maximum element using operator<().
  412. _Tp max() const;
  413. /**
  414. * @brief Return a shifted array.
  415. *
  416. * A new valarray is constructed as a copy of this array with elements
  417. * in shifted positions. For an element with index i, the new position
  418. * is i - n. The new valarray has the same size as the current one.
  419. * New elements without a value are set to 0. Elements whose new
  420. * position is outside the bounds of the array are discarded.
  421. *
  422. * Positive arguments shift toward index 0, discarding elements [0, n).
  423. * Negative arguments discard elements from the top of the array.
  424. *
  425. * @param __n Number of element positions to shift.
  426. * @return New valarray with elements in shifted positions.
  427. */
  428. valarray<_Tp> shift (int __n) const;
  429. /**
  430. * @brief Return a rotated array.
  431. *
  432. * A new valarray is constructed as a copy of this array with elements
  433. * in shifted positions. For an element with index i, the new position
  434. * is (i - n) % size(). The new valarray has the same size as the
  435. * current one. Elements that are shifted beyond the array bounds are
  436. * shifted into the other end of the array. No elements are lost.
  437. *
  438. * Positive arguments shift toward index 0, wrapping around the top.
  439. * Negative arguments shift towards the top, wrapping around to 0.
  440. *
  441. * @param __n Number of element positions to rotate.
  442. * @return New valarray with elements in shifted positions.
  443. */
  444. valarray<_Tp> cshift(int __n) const;
  445. /**
  446. * @brief Apply a function to the array.
  447. *
  448. * Returns a new valarray with elements assigned to the result of
  449. * applying __func to the corresponding element of this array. The new
  450. * array has the same size as this one.
  451. *
  452. * @param __func Function of Tp returning Tp to apply.
  453. * @return New valarray with transformed elements.
  454. */
  455. _Expr<_ValFunClos<_ValArray, _Tp>, _Tp> apply(_Tp __func(_Tp)) const;
  456. /**
  457. * @brief Apply a function to the array.
  458. *
  459. * Returns a new valarray with elements assigned to the result of
  460. * applying __func to the corresponding element of this array. The new
  461. * array has the same size as this one.
  462. *
  463. * @param __func Function of const Tp& returning Tp to apply.
  464. * @return New valarray with transformed elements.
  465. */
  466. _Expr<_RefFunClos<_ValArray, _Tp>, _Tp> apply(_Tp __func(const _Tp&)) const;
  467. /**
  468. * @brief Resize array.
  469. *
  470. * Resize this array to @a size and set all elements to @a c. All
  471. * references and iterators are invalidated.
  472. *
  473. * @param __size New array size.
  474. * @param __c New value for all elements.
  475. */
  476. void resize(size_t __size, _Tp __c = _Tp());
  477. private:
  478. size_t _M_size;
  479. _Tp* __restrict__ _M_data;
  480. friend struct _Array<_Tp>;
  481. };
  482. #if __cpp_deduction_guides >= 201606
  483. template<typename _Tp, size_t _Nm>
  484. valarray(const _Tp(&)[_Nm], size_t) -> valarray<_Tp>;
  485. #endif
  486. template<typename _Tp>
  487. inline const _Tp&
  488. valarray<_Tp>::operator[](size_t __i) const _GLIBCXX_NOTHROW
  489. {
  490. __glibcxx_requires_subscript(__i);
  491. return _M_data[__i];
  492. }
  493. template<typename _Tp>
  494. inline _Tp&
  495. valarray<_Tp>::operator[](size_t __i) _GLIBCXX_NOTHROW
  496. {
  497. __glibcxx_requires_subscript(__i);
  498. return _M_data[__i];
  499. }
  500. /// @} group numeric_arrays
  501. _GLIBCXX_END_NAMESPACE_VERSION
  502. } // namespace
  503. #include <bits/valarray_after.h>
  504. #include <bits/slice_array.h>
  505. #include <bits/gslice.h>
  506. #include <bits/gslice_array.h>
  507. #include <bits/mask_array.h>
  508. #include <bits/indirect_array.h>
  509. namespace std _GLIBCXX_VISIBILITY(default)
  510. {
  511. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  512. /**
  513. * @addtogroup numeric_arrays
  514. * @{
  515. */
  516. template<typename _Tp>
  517. inline
  518. valarray<_Tp>::valarray() _GLIBCXX_NOTHROW : _M_size(0), _M_data(0) {}
  519. template<typename _Tp>
  520. inline
  521. valarray<_Tp>::valarray(size_t __n)
  522. : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
  523. { std::__valarray_default_construct(_M_data, _M_data + __n); }
  524. template<typename _Tp>
  525. inline
  526. valarray<_Tp>::valarray(const _Tp& __t, size_t __n)
  527. : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
  528. { std::__valarray_fill_construct(_M_data, _M_data + __n, __t); }
  529. template<typename _Tp>
  530. inline
  531. valarray<_Tp>::valarray(const _Tp* __restrict__ __p, size_t __n)
  532. : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
  533. {
  534. __glibcxx_assert(__p != 0 || __n == 0);
  535. std::__valarray_copy_construct(__p, __p + __n, _M_data);
  536. }
  537. template<typename _Tp>
  538. inline
  539. valarray<_Tp>::valarray(const valarray<_Tp>& __v)
  540. : _M_size(__v._M_size), _M_data(__valarray_get_storage<_Tp>(__v._M_size))
  541. { std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size,
  542. _M_data); }
  543. #if __cplusplus >= 201103L
  544. template<typename _Tp>
  545. inline
  546. valarray<_Tp>::valarray(valarray<_Tp>&& __v) noexcept
  547. : _M_size(__v._M_size), _M_data(__v._M_data)
  548. {
  549. __v._M_size = 0;
  550. __v._M_data = 0;
  551. }
  552. #endif
  553. template<typename _Tp>
  554. inline
  555. valarray<_Tp>::valarray(const slice_array<_Tp>& __sa)
  556. : _M_size(__sa._M_sz), _M_data(__valarray_get_storage<_Tp>(__sa._M_sz))
  557. {
  558. std::__valarray_copy_construct
  559. (__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data));
  560. }
  561. template<typename _Tp>
  562. inline
  563. valarray<_Tp>::valarray(const gslice_array<_Tp>& __ga)
  564. : _M_size(__ga._M_index.size()),
  565. _M_data(__valarray_get_storage<_Tp>(_M_size))
  566. {
  567. std::__valarray_copy_construct
  568. (__ga._M_array, _Array<size_t>(__ga._M_index),
  569. _Array<_Tp>(_M_data), _M_size);
  570. }
  571. template<typename _Tp>
  572. inline
  573. valarray<_Tp>::valarray(const mask_array<_Tp>& __ma)
  574. : _M_size(__ma._M_sz), _M_data(__valarray_get_storage<_Tp>(__ma._M_sz))
  575. {
  576. std::__valarray_copy_construct
  577. (__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size);
  578. }
  579. template<typename _Tp>
  580. inline
  581. valarray<_Tp>::valarray(const indirect_array<_Tp>& __ia)
  582. : _M_size(__ia._M_sz), _M_data(__valarray_get_storage<_Tp>(__ia._M_sz))
  583. {
  584. std::__valarray_copy_construct
  585. (__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size);
  586. }
  587. #if __cplusplus >= 201103L
  588. template<typename _Tp>
  589. inline
  590. valarray<_Tp>::valarray(initializer_list<_Tp> __l)
  591. : _M_size(__l.size()), _M_data(__valarray_get_storage<_Tp>(__l.size()))
  592. { std::__valarray_copy_construct(__l.begin(), __l.end(), _M_data); }
  593. #endif
  594. template<typename _Tp> template<class _Dom>
  595. inline
  596. valarray<_Tp>::valarray(const _Expr<_Dom, _Tp>& __e)
  597. : _M_size(__e.size()), _M_data(__valarray_get_storage<_Tp>(_M_size))
  598. { std::__valarray_copy_construct(__e, _M_size, _Array<_Tp>(_M_data)); }
  599. template<typename _Tp>
  600. inline
  601. valarray<_Tp>::~valarray() _GLIBCXX_NOEXCEPT
  602. {
  603. std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
  604. std::__valarray_release_memory(_M_data);
  605. }
  606. template<typename _Tp>
  607. inline valarray<_Tp>&
  608. valarray<_Tp>::operator=(const valarray<_Tp>& __v)
  609. {
  610. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  611. // 630. arrays of valarray.
  612. if (_M_size == __v._M_size)
  613. std::__valarray_copy(__v._M_data, _M_size, _M_data);
  614. else
  615. {
  616. if (_M_data)
  617. {
  618. std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
  619. std::__valarray_release_memory(_M_data);
  620. }
  621. _M_size = __v._M_size;
  622. _M_data = __valarray_get_storage<_Tp>(_M_size);
  623. std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size,
  624. _M_data);
  625. }
  626. return *this;
  627. }
  628. #if __cplusplus >= 201103L
  629. template<typename _Tp>
  630. inline valarray<_Tp>&
  631. valarray<_Tp>::operator=(valarray<_Tp>&& __v) noexcept
  632. {
  633. if (_M_data)
  634. {
  635. std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
  636. std::__valarray_release_memory(_M_data);
  637. }
  638. _M_size = __v._M_size;
  639. _M_data = __v._M_data;
  640. __v._M_size = 0;
  641. __v._M_data = 0;
  642. return *this;
  643. }
  644. template<typename _Tp>
  645. inline valarray<_Tp>&
  646. valarray<_Tp>::operator=(initializer_list<_Tp> __l)
  647. {
  648. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  649. // 630. arrays of valarray.
  650. if (_M_size == __l.size())
  651. std::__valarray_copy(__l.begin(), __l.size(), _M_data);
  652. else
  653. {
  654. if (_M_data)
  655. {
  656. std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
  657. std::__valarray_release_memory(_M_data);
  658. }
  659. _M_size = __l.size();
  660. _M_data = __valarray_get_storage<_Tp>(_M_size);
  661. std::__valarray_copy_construct(__l.begin(), __l.begin() + _M_size,
  662. _M_data);
  663. }
  664. return *this;
  665. }
  666. #endif
  667. template<typename _Tp>
  668. inline valarray<_Tp>&
  669. valarray<_Tp>::operator=(const _Tp& __t)
  670. {
  671. std::__valarray_fill(_M_data, _M_size, __t);
  672. return *this;
  673. }
  674. template<typename _Tp>
  675. inline valarray<_Tp>&
  676. valarray<_Tp>::operator=(const slice_array<_Tp>& __sa)
  677. {
  678. __glibcxx_assert(_M_size == __sa._M_sz);
  679. std::__valarray_copy(__sa._M_array, __sa._M_sz,
  680. __sa._M_stride, _Array<_Tp>(_M_data));
  681. return *this;
  682. }
  683. template<typename _Tp>
  684. inline valarray<_Tp>&
  685. valarray<_Tp>::operator=(const gslice_array<_Tp>& __ga)
  686. {
  687. __glibcxx_assert(_M_size == __ga._M_index.size());
  688. std::__valarray_copy(__ga._M_array, _Array<size_t>(__ga._M_index),
  689. _Array<_Tp>(_M_data), _M_size);
  690. return *this;
  691. }
  692. template<typename _Tp>
  693. inline valarray<_Tp>&
  694. valarray<_Tp>::operator=(const mask_array<_Tp>& __ma)
  695. {
  696. __glibcxx_assert(_M_size == __ma._M_sz);
  697. std::__valarray_copy(__ma._M_array, __ma._M_mask,
  698. _Array<_Tp>(_M_data), _M_size);
  699. return *this;
  700. }
  701. template<typename _Tp>
  702. inline valarray<_Tp>&
  703. valarray<_Tp>::operator=(const indirect_array<_Tp>& __ia)
  704. {
  705. __glibcxx_assert(_M_size == __ia._M_sz);
  706. std::__valarray_copy(__ia._M_array, __ia._M_index,
  707. _Array<_Tp>(_M_data), _M_size);
  708. return *this;
  709. }
  710. template<typename _Tp> template<class _Dom>
  711. inline valarray<_Tp>&
  712. valarray<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e)
  713. {
  714. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  715. // 630. arrays of valarray.
  716. if (_M_size == __e.size())
  717. {
  718. // Copy manually instead of using __valarray_copy, because __e might
  719. // alias _M_data and the _Array param type of __valarray_copy uses
  720. // restrict which doesn't allow aliasing.
  721. for (size_t __i = 0; __i < _M_size; ++__i)
  722. _M_data[__i] = __e[__i];
  723. }
  724. else
  725. {
  726. if (_M_data)
  727. {
  728. std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
  729. std::__valarray_release_memory(_M_data);
  730. }
  731. _M_size = __e.size();
  732. _M_data = __valarray_get_storage<_Tp>(_M_size);
  733. std::__valarray_copy_construct(__e, _M_size, _Array<_Tp>(_M_data));
  734. }
  735. return *this;
  736. }
  737. template<typename _Tp>
  738. inline _Expr<_SClos<_ValArray,_Tp>, _Tp>
  739. valarray<_Tp>::operator[](slice __s) const
  740. {
  741. typedef _SClos<_ValArray,_Tp> _Closure;
  742. return _Expr<_Closure, _Tp>(_Closure (_Array<_Tp>(_M_data), __s));
  743. }
  744. template<typename _Tp>
  745. inline slice_array<_Tp>
  746. valarray<_Tp>::operator[](slice __s)
  747. { return slice_array<_Tp>(_Array<_Tp>(_M_data), __s); }
  748. template<typename _Tp>
  749. inline _Expr<_GClos<_ValArray,_Tp>, _Tp>
  750. valarray<_Tp>::operator[](const gslice& __gs) const
  751. {
  752. typedef _GClos<_ValArray,_Tp> _Closure;
  753. return _Expr<_Closure, _Tp>
  754. (_Closure(_Array<_Tp>(_M_data), __gs._M_index->_M_index));
  755. }
  756. template<typename _Tp>
  757. inline gslice_array<_Tp>
  758. valarray<_Tp>::operator[](const gslice& __gs)
  759. {
  760. return gslice_array<_Tp>
  761. (_Array<_Tp>(_M_data), __gs._M_index->_M_index);
  762. }
  763. template<typename _Tp>
  764. inline valarray<_Tp>
  765. valarray<_Tp>::operator[](const valarray<bool>& __m) const
  766. {
  767. size_t __s = 0;
  768. size_t __e = __m.size();
  769. for (size_t __i=0; __i<__e; ++__i)
  770. if (__m[__i]) ++__s;
  771. __glibcxx_assert(__s <= _M_size);
  772. return valarray<_Tp>(mask_array<_Tp>(_Array<_Tp>(_M_data), __s,
  773. _Array<bool> (__m)));
  774. }
  775. template<typename _Tp>
  776. inline mask_array<_Tp>
  777. valarray<_Tp>::operator[](const valarray<bool>& __m)
  778. {
  779. size_t __s = 0;
  780. size_t __e = __m.size();
  781. for (size_t __i=0; __i<__e; ++__i)
  782. if (__m[__i]) ++__s;
  783. __glibcxx_assert(__s <= _M_size);
  784. return mask_array<_Tp>(_Array<_Tp>(_M_data), __s, _Array<bool>(__m));
  785. }
  786. template<typename _Tp>
  787. inline _Expr<_IClos<_ValArray,_Tp>, _Tp>
  788. valarray<_Tp>::operator[](const valarray<size_t>& __i) const
  789. {
  790. typedef _IClos<_ValArray,_Tp> _Closure;
  791. return _Expr<_Closure, _Tp>(_Closure(*this, __i));
  792. }
  793. template<typename _Tp>
  794. inline indirect_array<_Tp>
  795. valarray<_Tp>::operator[](const valarray<size_t>& __i)
  796. {
  797. return indirect_array<_Tp>(_Array<_Tp>(_M_data), __i.size(),
  798. _Array<size_t>(__i));
  799. }
  800. #if __cplusplus >= 201103L
  801. template<class _Tp>
  802. inline void
  803. valarray<_Tp>::swap(valarray<_Tp>& __v) noexcept
  804. {
  805. std::swap(_M_size, __v._M_size);
  806. std::swap(_M_data, __v._M_data);
  807. }
  808. #endif
  809. template<class _Tp>
  810. inline size_t
  811. valarray<_Tp>::size() const
  812. { return _M_size; }
  813. template<class _Tp>
  814. inline _Tp
  815. valarray<_Tp>::sum() const
  816. {
  817. __glibcxx_assert(_M_size > 0);
  818. return std::__valarray_sum(_M_data, _M_data + _M_size);
  819. }
  820. template<class _Tp>
  821. inline valarray<_Tp>
  822. valarray<_Tp>::shift(int __n) const
  823. {
  824. valarray<_Tp> __ret;
  825. if (_M_size == 0)
  826. return __ret;
  827. _Tp* __restrict__ __tmp_M_data =
  828. std::__valarray_get_storage<_Tp>(_M_size);
  829. if (__n == 0)
  830. std::__valarray_copy_construct(_M_data,
  831. _M_data + _M_size, __tmp_M_data);
  832. else if (__n > 0) // shift left
  833. {
  834. if (size_t(__n) > _M_size)
  835. __n = int(_M_size);
  836. std::__valarray_copy_construct(_M_data + __n,
  837. _M_data + _M_size, __tmp_M_data);
  838. std::__valarray_default_construct(__tmp_M_data + _M_size - __n,
  839. __tmp_M_data + _M_size);
  840. }
  841. else // shift right
  842. {
  843. if (-size_t(__n) > _M_size)
  844. __n = -int(_M_size);
  845. std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n,
  846. __tmp_M_data - __n);
  847. std::__valarray_default_construct(__tmp_M_data,
  848. __tmp_M_data - __n);
  849. }
  850. __ret._M_size = _M_size;
  851. __ret._M_data = __tmp_M_data;
  852. return __ret;
  853. }
  854. template<class _Tp>
  855. inline valarray<_Tp>
  856. valarray<_Tp>::cshift(int __n) const
  857. {
  858. valarray<_Tp> __ret;
  859. if (_M_size == 0)
  860. return __ret;
  861. _Tp* __restrict__ __tmp_M_data =
  862. std::__valarray_get_storage<_Tp>(_M_size);
  863. if (__n == 0)
  864. std::__valarray_copy_construct(_M_data,
  865. _M_data + _M_size, __tmp_M_data);
  866. else if (__n > 0) // cshift left
  867. {
  868. if (size_t(__n) > _M_size)
  869. __n = int(__n % _M_size);
  870. std::__valarray_copy_construct(_M_data, _M_data + __n,
  871. __tmp_M_data + _M_size - __n);
  872. std::__valarray_copy_construct(_M_data + __n, _M_data + _M_size,
  873. __tmp_M_data);
  874. }
  875. else // cshift right
  876. {
  877. if (-size_t(__n) > _M_size)
  878. __n = -int(-size_t(__n) % _M_size);
  879. std::__valarray_copy_construct(_M_data + _M_size + __n,
  880. _M_data + _M_size, __tmp_M_data);
  881. std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n,
  882. __tmp_M_data - __n);
  883. }
  884. __ret._M_size = _M_size;
  885. __ret._M_data = __tmp_M_data;
  886. return __ret;
  887. }
  888. template<class _Tp>
  889. inline void
  890. valarray<_Tp>::resize(size_t __n, _Tp __c)
  891. {
  892. // This complication is so to make valarray<valarray<T> > work
  893. // even though it is not required by the standard. Nobody should
  894. // be saying valarray<valarray<T> > anyway. See the specs.
  895. std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
  896. if (_M_size != __n)
  897. {
  898. std::__valarray_release_memory(_M_data);
  899. _M_size = __n;
  900. _M_data = __valarray_get_storage<_Tp>(__n);
  901. }
  902. std::__valarray_fill_construct(_M_data, _M_data + __n, __c);
  903. }
  904. template<typename _Tp>
  905. inline _Tp
  906. valarray<_Tp>::min() const
  907. {
  908. __glibcxx_assert(_M_size > 0);
  909. return *std::min_element(_M_data, _M_data + _M_size);
  910. }
  911. template<typename _Tp>
  912. inline _Tp
  913. valarray<_Tp>::max() const
  914. {
  915. __glibcxx_assert(_M_size > 0);
  916. return *std::max_element(_M_data, _M_data + _M_size);
  917. }
  918. template<class _Tp>
  919. inline _Expr<_ValFunClos<_ValArray, _Tp>, _Tp>
  920. valarray<_Tp>::apply(_Tp __func(_Tp)) const
  921. {
  922. typedef _ValFunClos<_ValArray, _Tp> _Closure;
  923. return _Expr<_Closure, _Tp>(_Closure(*this, __func));
  924. }
  925. template<class _Tp>
  926. inline _Expr<_RefFunClos<_ValArray, _Tp>, _Tp>
  927. valarray<_Tp>::apply(_Tp __func(const _Tp &)) const
  928. {
  929. typedef _RefFunClos<_ValArray, _Tp> _Closure;
  930. return _Expr<_Closure, _Tp>(_Closure(*this, __func));
  931. }
  932. /// @cond undocumented
  933. #define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name) \
  934. template<typename _Tp> \
  935. inline typename valarray<_Tp>::template _UnaryOp<_Name>::_Rt \
  936. valarray<_Tp>::operator _Op() const \
  937. { \
  938. typedef _UnClos<_Name, _ValArray, _Tp> _Closure; \
  939. typedef typename __fun<_Name, _Tp>::result_type _Rt; \
  940. return _Expr<_Closure, _Rt>(_Closure(*this)); \
  941. }
  942. _DEFINE_VALARRAY_UNARY_OPERATOR(+, __unary_plus)
  943. _DEFINE_VALARRAY_UNARY_OPERATOR(-, __negate)
  944. _DEFINE_VALARRAY_UNARY_OPERATOR(~, __bitwise_not)
  945. _DEFINE_VALARRAY_UNARY_OPERATOR (!, __logical_not)
  946. #undef _DEFINE_VALARRAY_UNARY_OPERATOR
  947. #define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name) \
  948. template<class _Tp> \
  949. inline valarray<_Tp>& \
  950. valarray<_Tp>::operator _Op##=(const _Tp &__t) \
  951. { \
  952. _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, __t); \
  953. return *this; \
  954. } \
  955. \
  956. template<class _Tp> \
  957. inline valarray<_Tp>& \
  958. valarray<_Tp>::operator _Op##=(const valarray<_Tp> &__v) \
  959. { \
  960. __glibcxx_assert(_M_size == __v._M_size); \
  961. _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, \
  962. _Array<_Tp>(__v._M_data)); \
  963. return *this; \
  964. }
  965. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, __plus)
  966. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, __minus)
  967. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, __multiplies)
  968. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, __divides)
  969. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, __modulus)
  970. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, __bitwise_xor)
  971. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, __bitwise_and)
  972. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, __bitwise_or)
  973. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, __shift_left)
  974. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, __shift_right)
  975. #undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT
  976. #define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name) \
  977. template<class _Tp> template<class _Dom> \
  978. inline valarray<_Tp>& \
  979. valarray<_Tp>::operator _Op##=(const _Expr<_Dom, _Tp>& __e) \
  980. { \
  981. _Array_augmented_##_Name(_Array<_Tp>(_M_data), __e, _M_size); \
  982. return *this; \
  983. }
  984. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, __plus)
  985. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, __minus)
  986. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, __multiplies)
  987. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, __divides)
  988. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, __modulus)
  989. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, __bitwise_xor)
  990. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, __bitwise_and)
  991. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, __bitwise_or)
  992. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, __shift_left)
  993. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, __shift_right)
  994. #undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT
  995. #define _DEFINE_BINARY_OPERATOR(_Op, _Name) \
  996. template<typename _Tp> \
  997. inline _Expr<_BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp>, \
  998. typename __fun<_Name, _Tp>::result_type> \
  999. operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \
  1000. { \
  1001. __glibcxx_assert(__v.size() == __w.size()); \
  1002. typedef _BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp> _Closure; \
  1003. typedef typename __fun<_Name, _Tp>::result_type _Rt; \
  1004. return _Expr<_Closure, _Rt>(_Closure(__v, __w)); \
  1005. } \
  1006. \
  1007. template<typename _Tp> \
  1008. inline _Expr<_BinClos<_Name, _ValArray,_Constant, _Tp, _Tp>, \
  1009. typename __fun<_Name, _Tp>::result_type> \
  1010. operator _Op(const valarray<_Tp>& __v, \
  1011. const typename valarray<_Tp>::value_type& __t) \
  1012. { \
  1013. typedef _BinClos<_Name, _ValArray, _Constant, _Tp, _Tp> _Closure; \
  1014. typedef typename __fun<_Name, _Tp>::result_type _Rt; \
  1015. return _Expr<_Closure, _Rt>(_Closure(__v, __t)); \
  1016. } \
  1017. \
  1018. template<typename _Tp> \
  1019. inline _Expr<_BinClos<_Name, _Constant, _ValArray, _Tp, _Tp>, \
  1020. typename __fun<_Name, _Tp>::result_type> \
  1021. operator _Op(const typename valarray<_Tp>::value_type& __t, \
  1022. const valarray<_Tp>& __v) \
  1023. { \
  1024. typedef _BinClos<_Name, _Constant, _ValArray, _Tp, _Tp> _Closure; \
  1025. typedef typename __fun<_Name, _Tp>::result_type _Rt; \
  1026. return _Expr<_Closure, _Rt>(_Closure(__t, __v)); \
  1027. }
  1028. _DEFINE_BINARY_OPERATOR(+, __plus)
  1029. _DEFINE_BINARY_OPERATOR(-, __minus)
  1030. _DEFINE_BINARY_OPERATOR(*, __multiplies)
  1031. _DEFINE_BINARY_OPERATOR(/, __divides)
  1032. _DEFINE_BINARY_OPERATOR(%, __modulus)
  1033. _DEFINE_BINARY_OPERATOR(^, __bitwise_xor)
  1034. _DEFINE_BINARY_OPERATOR(&, __bitwise_and)
  1035. _DEFINE_BINARY_OPERATOR(|, __bitwise_or)
  1036. _DEFINE_BINARY_OPERATOR(<<, __shift_left)
  1037. _DEFINE_BINARY_OPERATOR(>>, __shift_right)
  1038. _DEFINE_BINARY_OPERATOR(&&, __logical_and)
  1039. _DEFINE_BINARY_OPERATOR(||, __logical_or)
  1040. _DEFINE_BINARY_OPERATOR(==, __equal_to)
  1041. _DEFINE_BINARY_OPERATOR(!=, __not_equal_to)
  1042. _DEFINE_BINARY_OPERATOR(<, __less)
  1043. _DEFINE_BINARY_OPERATOR(>, __greater)
  1044. _DEFINE_BINARY_OPERATOR(<=, __less_equal)
  1045. _DEFINE_BINARY_OPERATOR(>=, __greater_equal)
  1046. #undef _DEFINE_BINARY_OPERATOR
  1047. /// @endcond
  1048. #if __cplusplus >= 201103L
  1049. /**
  1050. * @brief Return an iterator pointing to the first element of
  1051. * the valarray.
  1052. * @param __va valarray.
  1053. */
  1054. template<class _Tp>
  1055. [[__nodiscard__]]
  1056. inline _Tp*
  1057. begin(valarray<_Tp>& __va) noexcept
  1058. { return __va.size() ? std::__addressof(__va[0]) : nullptr; }
  1059. /**
  1060. * @brief Return an iterator pointing to the first element of
  1061. * the const valarray.
  1062. * @param __va valarray.
  1063. */
  1064. template<class _Tp>
  1065. [[__nodiscard__]]
  1066. inline const _Tp*
  1067. begin(const valarray<_Tp>& __va) noexcept
  1068. { return __va.size() ? std::__addressof(__va[0]) : nullptr; }
  1069. /**
  1070. * @brief Return an iterator pointing to one past the last element of
  1071. * the valarray.
  1072. * @param __va valarray.
  1073. */
  1074. template<class _Tp>
  1075. [[__nodiscard__]]
  1076. inline _Tp*
  1077. end(valarray<_Tp>& __va) noexcept
  1078. {
  1079. if (auto __n = __va.size())
  1080. return std::__addressof(__va[0]) + __n;
  1081. else
  1082. return nullptr;
  1083. }
  1084. /**
  1085. * @brief Return an iterator pointing to one past the last element of
  1086. * the const valarray.
  1087. * @param __va valarray.
  1088. */
  1089. template<class _Tp>
  1090. [[__nodiscard__]]
  1091. inline const _Tp*
  1092. end(const valarray<_Tp>& __va) noexcept
  1093. {
  1094. if (auto __n = __va.size())
  1095. return std::__addressof(__va[0]) + __n;
  1096. else
  1097. return nullptr;
  1098. }
  1099. #endif // C++11
  1100. /// @} group numeric_arrays
  1101. _GLIBCXX_END_NAMESPACE_VERSION
  1102. } // namespace
  1103. #endif /* _GLIBCXX_VALARRAY */