valarray_before.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  1. // The template and inlines for the -*- C++ -*- internal _Meta class.
  2. // Copyright (C) 1997-2021 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 bits/valarray_before.h
  21. * This is an internal header file, included by other library headers.
  22. * Do not attempt to use it directly. @headername{valarray}
  23. */
  24. // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr>
  25. #ifndef _VALARRAY_BEFORE_H
  26. #define _VALARRAY_BEFORE_H 1
  27. #pragma GCC system_header
  28. #include <bits/slice_array.h>
  29. namespace std _GLIBCXX_VISIBILITY(default)
  30. {
  31. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  32. //
  33. // Implementing a loosened valarray return value is tricky.
  34. // First we need to meet 26.3.1/3: we should not add more than
  35. // two levels of template nesting. Therefore we resort to template
  36. // template to "flatten" loosened return value types.
  37. // At some point we use partial specialization to remove one level
  38. // template nesting due to _Expr<>
  39. //
  40. // This class is NOT defined. It doesn't need to.
  41. template<typename _Tp1, typename _Tp2> class _Constant;
  42. // Implementations of unary functions applied to valarray<>s.
  43. // I use hard-coded object functions here instead of a generic
  44. // approach like pointers to function:
  45. // 1) correctness: some functions take references, others values.
  46. // we can't deduce the correct type afterwards.
  47. // 2) efficiency -- object functions can be easily inlined
  48. // 3) be Koenig-lookup-friendly
  49. struct _Abs
  50. {
  51. template<typename _Tp>
  52. _Tp operator()(const _Tp& __t) const
  53. { return abs(__t); }
  54. };
  55. struct _Cos
  56. {
  57. template<typename _Tp>
  58. _Tp operator()(const _Tp& __t) const
  59. { return cos(__t); }
  60. };
  61. struct _Acos
  62. {
  63. template<typename _Tp>
  64. _Tp operator()(const _Tp& __t) const
  65. { return acos(__t); }
  66. };
  67. struct _Cosh
  68. {
  69. template<typename _Tp>
  70. _Tp operator()(const _Tp& __t) const
  71. { return cosh(__t); }
  72. };
  73. struct _Sin
  74. {
  75. template<typename _Tp>
  76. _Tp operator()(const _Tp& __t) const
  77. { return sin(__t); }
  78. };
  79. struct _Asin
  80. {
  81. template<typename _Tp>
  82. _Tp operator()(const _Tp& __t) const
  83. { return asin(__t); }
  84. };
  85. struct _Sinh
  86. {
  87. template<typename _Tp>
  88. _Tp operator()(const _Tp& __t) const
  89. { return sinh(__t); }
  90. };
  91. struct _Tan
  92. {
  93. template<typename _Tp>
  94. _Tp operator()(const _Tp& __t) const
  95. { return tan(__t); }
  96. };
  97. struct _Atan
  98. {
  99. template<typename _Tp>
  100. _Tp operator()(const _Tp& __t) const
  101. { return atan(__t); }
  102. };
  103. struct _Tanh
  104. {
  105. template<typename _Tp>
  106. _Tp operator()(const _Tp& __t) const
  107. { return tanh(__t); }
  108. };
  109. struct _Exp
  110. {
  111. template<typename _Tp>
  112. _Tp operator()(const _Tp& __t) const
  113. { return exp(__t); }
  114. };
  115. struct _Log
  116. {
  117. template<typename _Tp>
  118. _Tp operator()(const _Tp& __t) const
  119. { return log(__t); }
  120. };
  121. struct _Log10
  122. {
  123. template<typename _Tp>
  124. _Tp operator()(const _Tp& __t) const
  125. { return log10(__t); }
  126. };
  127. struct _Sqrt
  128. {
  129. template<typename _Tp>
  130. _Tp operator()(const _Tp& __t) const
  131. { return sqrt(__t); }
  132. };
  133. // In the past, we used to tailor operator applications semantics
  134. // to the specialization of standard function objects (i.e. plus<>, etc.)
  135. // That is incorrect. Therefore we provide our own surrogates.
  136. struct __unary_plus
  137. {
  138. template<typename _Tp>
  139. _Tp operator()(const _Tp& __t) const
  140. { return +__t; }
  141. };
  142. struct __negate
  143. {
  144. template<typename _Tp>
  145. _Tp operator()(const _Tp& __t) const
  146. { return -__t; }
  147. };
  148. struct __bitwise_not
  149. {
  150. template<typename _Tp>
  151. _Tp operator()(const _Tp& __t) const
  152. { return ~__t; }
  153. };
  154. struct __plus
  155. {
  156. template<typename _Tp>
  157. _Tp operator()(const _Tp& __x, const _Tp& __y) const
  158. { return __x + __y; }
  159. };
  160. struct __minus
  161. {
  162. template<typename _Tp>
  163. _Tp operator()(const _Tp& __x, const _Tp& __y) const
  164. { return __x - __y; }
  165. };
  166. struct __multiplies
  167. {
  168. template<typename _Tp>
  169. _Tp operator()(const _Tp& __x, const _Tp& __y) const
  170. { return __x * __y; }
  171. };
  172. struct __divides
  173. {
  174. template<typename _Tp>
  175. _Tp operator()(const _Tp& __x, const _Tp& __y) const
  176. { return __x / __y; }
  177. };
  178. struct __modulus
  179. {
  180. template<typename _Tp>
  181. _Tp operator()(const _Tp& __x, const _Tp& __y) const
  182. { return __x % __y; }
  183. };
  184. struct __bitwise_xor
  185. {
  186. template<typename _Tp>
  187. _Tp operator()(const _Tp& __x, const _Tp& __y) const
  188. { return __x ^ __y; }
  189. };
  190. struct __bitwise_and
  191. {
  192. template<typename _Tp>
  193. _Tp operator()(const _Tp& __x, const _Tp& __y) const
  194. { return __x & __y; }
  195. };
  196. struct __bitwise_or
  197. {
  198. template<typename _Tp>
  199. _Tp operator()(const _Tp& __x, const _Tp& __y) const
  200. { return __x | __y; }
  201. };
  202. struct __shift_left
  203. {
  204. template<typename _Tp>
  205. _Tp operator()(const _Tp& __x, const _Tp& __y) const
  206. { return __x << __y; }
  207. };
  208. struct __shift_right
  209. {
  210. template<typename _Tp>
  211. _Tp operator()(const _Tp& __x, const _Tp& __y) const
  212. { return __x >> __y; }
  213. };
  214. struct __logical_and
  215. {
  216. template<typename _Tp>
  217. bool operator()(const _Tp& __x, const _Tp& __y) const
  218. { return __x && __y; }
  219. };
  220. struct __logical_or
  221. {
  222. template<typename _Tp>
  223. bool operator()(const _Tp& __x, const _Tp& __y) const
  224. { return __x || __y; }
  225. };
  226. struct __logical_not
  227. {
  228. template<typename _Tp>
  229. bool operator()(const _Tp& __x) const
  230. { return !__x; }
  231. };
  232. struct __equal_to
  233. {
  234. template<typename _Tp>
  235. bool operator()(const _Tp& __x, const _Tp& __y) const
  236. { return __x == __y; }
  237. };
  238. struct __not_equal_to
  239. {
  240. template<typename _Tp>
  241. bool operator()(const _Tp& __x, const _Tp& __y) const
  242. { return __x != __y; }
  243. };
  244. struct __less
  245. {
  246. template<typename _Tp>
  247. bool operator()(const _Tp& __x, const _Tp& __y) const
  248. { return __x < __y; }
  249. };
  250. struct __greater
  251. {
  252. template<typename _Tp>
  253. bool operator()(const _Tp& __x, const _Tp& __y) const
  254. { return __x > __y; }
  255. };
  256. struct __less_equal
  257. {
  258. template<typename _Tp>
  259. bool operator()(const _Tp& __x, const _Tp& __y) const
  260. { return __x <= __y; }
  261. };
  262. struct __greater_equal
  263. {
  264. template<typename _Tp>
  265. bool operator()(const _Tp& __x, const _Tp& __y) const
  266. { return __x >= __y; }
  267. };
  268. // The few binary functions we miss.
  269. struct _Atan2
  270. {
  271. template<typename _Tp>
  272. _Tp operator()(const _Tp& __x, const _Tp& __y) const
  273. { return atan2(__x, __y); }
  274. };
  275. struct _Pow
  276. {
  277. template<typename _Tp>
  278. _Tp operator()(const _Tp& __x, const _Tp& __y) const
  279. { return pow(__x, __y); }
  280. };
  281. template<typename _Tp, bool _IsValidValarrayValue = !__is_abstract(_Tp)>
  282. struct __fun_with_valarray
  283. {
  284. typedef _Tp result_type;
  285. };
  286. template<typename _Tp>
  287. struct __fun_with_valarray<_Tp, false>
  288. {
  289. // No result type defined for invalid value types.
  290. };
  291. // We need these bits in order to recover the return type of
  292. // some functions/operators now that we're no longer using
  293. // function templates.
  294. template<typename, typename _Tp>
  295. struct __fun : __fun_with_valarray<_Tp>
  296. {
  297. };
  298. // several specializations for relational operators.
  299. template<typename _Tp>
  300. struct __fun<__logical_not, _Tp>
  301. {
  302. typedef bool result_type;
  303. };
  304. template<typename _Tp>
  305. struct __fun<__logical_and, _Tp>
  306. {
  307. typedef bool result_type;
  308. };
  309. template<typename _Tp>
  310. struct __fun<__logical_or, _Tp>
  311. {
  312. typedef bool result_type;
  313. };
  314. template<typename _Tp>
  315. struct __fun<__less, _Tp>
  316. {
  317. typedef bool result_type;
  318. };
  319. template<typename _Tp>
  320. struct __fun<__greater, _Tp>
  321. {
  322. typedef bool result_type;
  323. };
  324. template<typename _Tp>
  325. struct __fun<__less_equal, _Tp>
  326. {
  327. typedef bool result_type;
  328. };
  329. template<typename _Tp>
  330. struct __fun<__greater_equal, _Tp>
  331. {
  332. typedef bool result_type;
  333. };
  334. template<typename _Tp>
  335. struct __fun<__equal_to, _Tp>
  336. {
  337. typedef bool result_type;
  338. };
  339. template<typename _Tp>
  340. struct __fun<__not_equal_to, _Tp>
  341. {
  342. typedef bool result_type;
  343. };
  344. namespace __detail
  345. {
  346. // Closure types already have reference semantics and are often short-lived,
  347. // so store them by value to avoid (some cases of) dangling references to
  348. // out-of-scope temporaries.
  349. template<typename _Tp>
  350. struct _ValArrayRef
  351. { typedef const _Tp __type; };
  352. // Use real references for std::valarray objects.
  353. template<typename _Tp>
  354. struct _ValArrayRef< valarray<_Tp> >
  355. { typedef const valarray<_Tp>& __type; };
  356. //
  357. // Apply function taking a value/const reference closure
  358. //
  359. template<typename _Dom, typename _Arg>
  360. class _FunBase
  361. {
  362. public:
  363. typedef typename _Dom::value_type value_type;
  364. _FunBase(const _Dom& __e, value_type __f(_Arg))
  365. : _M_expr(__e), _M_func(__f) {}
  366. value_type operator[](size_t __i) const
  367. { return _M_func (_M_expr[__i]); }
  368. size_t size() const { return _M_expr.size ();}
  369. private:
  370. typename _ValArrayRef<_Dom>::__type _M_expr;
  371. value_type (*_M_func)(_Arg);
  372. };
  373. template<class _Dom>
  374. struct _ValFunClos<_Expr,_Dom> : _FunBase<_Dom, typename _Dom::value_type>
  375. {
  376. typedef _FunBase<_Dom, typename _Dom::value_type> _Base;
  377. typedef typename _Base::value_type value_type;
  378. typedef value_type _Tp;
  379. _ValFunClos(const _Dom& __e, _Tp __f(_Tp)) : _Base(__e, __f) {}
  380. };
  381. template<typename _Tp>
  382. struct _ValFunClos<_ValArray,_Tp> : _FunBase<valarray<_Tp>, _Tp>
  383. {
  384. typedef _FunBase<valarray<_Tp>, _Tp> _Base;
  385. typedef _Tp value_type;
  386. _ValFunClos(const valarray<_Tp>& __v, _Tp __f(_Tp)) : _Base(__v, __f) {}
  387. };
  388. template<class _Dom>
  389. struct _RefFunClos<_Expr, _Dom>
  390. : _FunBase<_Dom, const typename _Dom::value_type&>
  391. {
  392. typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base;
  393. typedef typename _Base::value_type value_type;
  394. typedef value_type _Tp;
  395. _RefFunClos(const _Dom& __e, _Tp __f(const _Tp&))
  396. : _Base(__e, __f) {}
  397. };
  398. template<typename _Tp>
  399. struct _RefFunClos<_ValArray, _Tp>
  400. : _FunBase<valarray<_Tp>, const _Tp&>
  401. {
  402. typedef _FunBase<valarray<_Tp>, const _Tp&> _Base;
  403. typedef _Tp value_type;
  404. _RefFunClos(const valarray<_Tp>& __v, _Tp __f(const _Tp&))
  405. : _Base(__v, __f) {}
  406. };
  407. //
  408. // Unary expression closure.
  409. //
  410. template<class _Oper, class _Arg>
  411. class _UnBase
  412. {
  413. public:
  414. typedef typename _Arg::value_type _Vt;
  415. typedef typename __fun<_Oper, _Vt>::result_type value_type;
  416. _UnBase(const _Arg& __e) : _M_expr(__e) {}
  417. value_type operator[](size_t __i) const
  418. { return _Oper()(_M_expr[__i]); }
  419. size_t size() const { return _M_expr.size(); }
  420. private:
  421. typename _ValArrayRef<_Arg>::__type _M_expr;
  422. };
  423. template<class _Oper, class _Dom>
  424. struct _UnClos<_Oper, _Expr, _Dom>
  425. : _UnBase<_Oper, _Dom>
  426. {
  427. typedef _Dom _Arg;
  428. typedef _UnBase<_Oper, _Dom> _Base;
  429. typedef typename _Base::value_type value_type;
  430. _UnClos(const _Arg& __e) : _Base(__e) {}
  431. };
  432. template<class _Oper, typename _Tp>
  433. struct _UnClos<_Oper, _ValArray, _Tp>
  434. : _UnBase<_Oper, valarray<_Tp> >
  435. {
  436. typedef valarray<_Tp> _Arg;
  437. typedef _UnBase<_Oper, valarray<_Tp> > _Base;
  438. typedef typename _Base::value_type value_type;
  439. _UnClos(const _Arg& __e) : _Base(__e) {}
  440. };
  441. //
  442. // Binary expression closure.
  443. //
  444. template<class _Oper, class _FirstArg, class _SecondArg>
  445. class _BinBase
  446. {
  447. public:
  448. typedef typename _FirstArg::value_type _Vt;
  449. typedef typename __fun<_Oper, _Vt>::result_type value_type;
  450. _BinBase(const _FirstArg& __e1, const _SecondArg& __e2)
  451. : _M_expr1(__e1), _M_expr2(__e2) {}
  452. value_type operator[](size_t __i) const
  453. { return _Oper()(_M_expr1[__i], _M_expr2[__i]); }
  454. size_t size() const { return _M_expr1.size(); }
  455. private:
  456. typename _ValArrayRef<_FirstArg>::__type _M_expr1;
  457. typename _ValArrayRef<_SecondArg>::__type _M_expr2;
  458. };
  459. template<class _Oper, class _Clos>
  460. class _BinBase2
  461. {
  462. public:
  463. typedef typename _Clos::value_type _Vt;
  464. typedef typename __fun<_Oper, _Vt>::result_type value_type;
  465. _BinBase2(const _Clos& __e, const _Vt& __t)
  466. : _M_expr1(__e), _M_expr2(__t) {}
  467. value_type operator[](size_t __i) const
  468. { return _Oper()(_M_expr1[__i], _M_expr2); }
  469. size_t size() const { return _M_expr1.size(); }
  470. private:
  471. typename _ValArrayRef<_Clos>::__type _M_expr1;
  472. _Vt _M_expr2;
  473. };
  474. template<class _Oper, class _Clos>
  475. class _BinBase1
  476. {
  477. public:
  478. typedef typename _Clos::value_type _Vt;
  479. typedef typename __fun<_Oper, _Vt>::result_type value_type;
  480. _BinBase1(const _Vt& __t, const _Clos& __e)
  481. : _M_expr1(__t), _M_expr2(__e) {}
  482. value_type operator[](size_t __i) const
  483. { return _Oper()(_M_expr1, _M_expr2[__i]); }
  484. size_t size() const { return _M_expr2.size(); }
  485. private:
  486. _Vt _M_expr1;
  487. typename _ValArrayRef<_Clos>::__type _M_expr2;
  488. };
  489. template<class _Oper, class _Dom1, class _Dom2>
  490. struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2>
  491. : _BinBase<_Oper, _Dom1, _Dom2>
  492. {
  493. typedef _BinBase<_Oper, _Dom1, _Dom2> _Base;
  494. typedef typename _Base::value_type value_type;
  495. _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {}
  496. };
  497. template<class _Oper, typename _Tp>
  498. struct _BinClos<_Oper, _ValArray, _ValArray, _Tp, _Tp>
  499. : _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> >
  500. {
  501. typedef _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> > _Base;
  502. typedef typename _Base::value_type value_type;
  503. _BinClos(const valarray<_Tp>& __v, const valarray<_Tp>& __w)
  504. : _Base(__v, __w) {}
  505. };
  506. template<class _Oper, class _Dom>
  507. struct _BinClos<_Oper, _Expr, _ValArray, _Dom, typename _Dom::value_type>
  508. : _BinBase<_Oper, _Dom, valarray<typename _Dom::value_type> >
  509. {
  510. typedef typename _Dom::value_type _Tp;
  511. typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base;
  512. typedef typename _Base::value_type value_type;
  513. _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2)
  514. : _Base(__e1, __e2) {}
  515. };
  516. template<class _Oper, class _Dom>
  517. struct _BinClos<_Oper, _ValArray, _Expr, typename _Dom::value_type, _Dom>
  518. : _BinBase<_Oper, valarray<typename _Dom::value_type>,_Dom>
  519. {
  520. typedef typename _Dom::value_type _Tp;
  521. typedef _BinBase<_Oper, valarray<_Tp>, _Dom> _Base;
  522. typedef typename _Base::value_type value_type;
  523. _BinClos(const valarray<_Tp>& __e1, const _Dom& __e2)
  524. : _Base(__e1, __e2) {}
  525. };
  526. template<class _Oper, class _Dom>
  527. struct _BinClos<_Oper, _Expr, _Constant, _Dom, typename _Dom::value_type>
  528. : _BinBase2<_Oper, _Dom>
  529. {
  530. typedef typename _Dom::value_type _Tp;
  531. typedef _BinBase2<_Oper,_Dom> _Base;
  532. typedef typename _Base::value_type value_type;
  533. _BinClos(const _Dom& __e1, const _Tp& __e2) : _Base(__e1, __e2) {}
  534. };
  535. template<class _Oper, class _Dom>
  536. struct _BinClos<_Oper, _Constant, _Expr, typename _Dom::value_type, _Dom>
  537. : _BinBase1<_Oper, _Dom>
  538. {
  539. typedef typename _Dom::value_type _Tp;
  540. typedef _BinBase1<_Oper, _Dom> _Base;
  541. typedef typename _Base::value_type value_type;
  542. _BinClos(const _Tp& __e1, const _Dom& __e2) : _Base(__e1, __e2) {}
  543. };
  544. template<class _Oper, typename _Tp>
  545. struct _BinClos<_Oper, _ValArray, _Constant, _Tp, _Tp>
  546. : _BinBase2<_Oper, valarray<_Tp> >
  547. {
  548. typedef _BinBase2<_Oper,valarray<_Tp> > _Base;
  549. typedef typename _Base::value_type value_type;
  550. _BinClos(const valarray<_Tp>& __v, const _Tp& __t) : _Base(__v, __t) {}
  551. };
  552. template<class _Oper, typename _Tp>
  553. struct _BinClos<_Oper, _Constant, _ValArray, _Tp, _Tp>
  554. : _BinBase1<_Oper, valarray<_Tp> >
  555. {
  556. typedef _BinBase1<_Oper, valarray<_Tp> > _Base;
  557. typedef typename _Base::value_type value_type;
  558. _BinClos(const _Tp& __t, const valarray<_Tp>& __v) : _Base(__t, __v) {}
  559. };
  560. //
  561. // slice_array closure.
  562. //
  563. template<typename _Dom>
  564. class _SBase
  565. {
  566. public:
  567. typedef typename _Dom::value_type value_type;
  568. _SBase (const _Dom& __e, const slice& __s)
  569. : _M_expr (__e), _M_slice (__s) {}
  570. value_type
  571. operator[] (size_t __i) const
  572. { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; }
  573. size_t
  574. size() const
  575. { return _M_slice.size (); }
  576. private:
  577. typename _ValArrayRef<_Dom>::__type _M_expr;
  578. const slice& _M_slice;
  579. };
  580. template<typename _Tp>
  581. class _SBase<_Array<_Tp> >
  582. {
  583. public:
  584. typedef _Tp value_type;
  585. _SBase (_Array<_Tp> __a, const slice& __s)
  586. : _M_array (__a._M_data+__s.start()), _M_size (__s.size()),
  587. _M_stride (__s.stride()) {}
  588. value_type
  589. operator[] (size_t __i) const
  590. { return _M_array._M_data[__i * _M_stride]; }
  591. size_t
  592. size() const
  593. { return _M_size; }
  594. private:
  595. const _Array<_Tp> _M_array;
  596. const size_t _M_size;
  597. const size_t _M_stride;
  598. };
  599. template<class _Dom>
  600. struct _SClos<_Expr, _Dom>
  601. : _SBase<_Dom>
  602. {
  603. typedef _SBase<_Dom> _Base;
  604. typedef typename _Base::value_type value_type;
  605. _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {}
  606. };
  607. template<typename _Tp>
  608. struct _SClos<_ValArray, _Tp>
  609. : _SBase<_Array<_Tp> >
  610. {
  611. typedef _SBase<_Array<_Tp> > _Base;
  612. typedef _Tp value_type;
  613. _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {}
  614. };
  615. } // namespace __detail
  616. _GLIBCXX_END_NAMESPACE_VERSION
  617. } // namespace
  618. #endif /* _CPP_VALARRAY_BEFORE_H */