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.

1254 lines
39KB

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