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.

557 lines
22KB

  1. // The template and inlines for the -*- C++ -*- internal _Meta 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 bits/valarray_after.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_AFTER_H
  26. #define _VALARRAY_AFTER_H 1
  27. #pragma GCC system_header
  28. namespace std _GLIBCXX_VISIBILITY(default)
  29. {
  30. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  31. namespace __detail
  32. {
  33. //
  34. // gslice_array closure.
  35. //
  36. template<class _Dom>
  37. class _GBase
  38. {
  39. public:
  40. typedef typename _Dom::value_type value_type;
  41. _GBase (const _Dom& __e, const valarray<size_t>& __i)
  42. : _M_expr (__e), _M_index(__i) {}
  43. value_type
  44. operator[] (size_t __i) const
  45. { return _M_expr[_M_index[__i]]; }
  46. size_t
  47. size () const
  48. { return _M_index.size(); }
  49. private:
  50. typename _ValArrayRef<_Dom>::__type _M_expr;
  51. const valarray<size_t>& _M_index;
  52. };
  53. template<typename _Tp>
  54. class _GBase<_Array<_Tp> >
  55. {
  56. public:
  57. typedef _Tp value_type;
  58. _GBase (_Array<_Tp> __a, const valarray<size_t>& __i)
  59. : _M_array (__a), _M_index(__i) {}
  60. value_type
  61. operator[] (size_t __i) const
  62. { return _M_array._M_data[_M_index[__i]]; }
  63. size_t
  64. size () const
  65. { return _M_index.size(); }
  66. private:
  67. const _Array<_Tp> _M_array;
  68. const valarray<size_t>& _M_index;
  69. };
  70. template<class _Dom>
  71. struct _GClos<_Expr, _Dom>
  72. : _GBase<_Dom>
  73. {
  74. typedef _GBase<_Dom> _Base;
  75. typedef typename _Base::value_type value_type;
  76. _GClos (const _Dom& __e, const valarray<size_t>& __i)
  77. : _Base (__e, __i) {}
  78. };
  79. template<typename _Tp>
  80. struct _GClos<_ValArray, _Tp>
  81. : _GBase<_Array<_Tp> >
  82. {
  83. typedef _GBase<_Array<_Tp> > _Base;
  84. typedef typename _Base::value_type value_type;
  85. _GClos (_Array<_Tp> __a, const valarray<size_t>& __i)
  86. : _Base (__a, __i) {}
  87. };
  88. //
  89. // indirect_array closure
  90. //
  91. template<class _Dom>
  92. class _IBase
  93. {
  94. public:
  95. typedef typename _Dom::value_type value_type;
  96. _IBase (const _Dom& __e, const valarray<size_t>& __i)
  97. : _M_expr (__e), _M_index (__i) {}
  98. value_type
  99. operator[] (size_t __i) const
  100. { return _M_expr[_M_index[__i]]; }
  101. size_t
  102. size() const
  103. { return _M_index.size(); }
  104. private:
  105. typename _ValArrayRef<_Dom>::__type _M_expr;
  106. const valarray<size_t>& _M_index;
  107. };
  108. template<class _Dom>
  109. struct _IClos<_Expr, _Dom>
  110. : _IBase<_Dom>
  111. {
  112. typedef _IBase<_Dom> _Base;
  113. typedef typename _Base::value_type value_type;
  114. _IClos (const _Dom& __e, const valarray<size_t>& __i)
  115. : _Base (__e, __i) {}
  116. };
  117. template<typename _Tp>
  118. struct _IClos<_ValArray, _Tp>
  119. : _IBase<valarray<_Tp> >
  120. {
  121. typedef _IBase<valarray<_Tp> > _Base;
  122. typedef _Tp value_type;
  123. _IClos (const valarray<_Tp>& __a, const valarray<size_t>& __i)
  124. : _Base (__a, __i) {}
  125. };
  126. } // namespace __detail
  127. //
  128. // class _Expr
  129. //
  130. template<class _Clos, typename _Tp>
  131. class _Expr
  132. {
  133. public:
  134. typedef _Tp value_type;
  135. _Expr(const _Clos&);
  136. const _Clos& operator()() const;
  137. value_type operator[](size_t) const;
  138. valarray<value_type> operator[](slice) const;
  139. valarray<value_type> operator[](const gslice&) const;
  140. valarray<value_type> operator[](const valarray<bool>&) const;
  141. valarray<value_type> operator[](const valarray<size_t>&) const;
  142. _Expr<_UnClos<__unary_plus, std::_Expr, _Clos>, value_type>
  143. operator+() const;
  144. _Expr<_UnClos<__negate, std::_Expr, _Clos>, value_type>
  145. operator-() const;
  146. _Expr<_UnClos<__bitwise_not, std::_Expr, _Clos>, value_type>
  147. operator~() const;
  148. _Expr<_UnClos<__logical_not, std::_Expr, _Clos>, bool>
  149. operator!() const;
  150. size_t size() const;
  151. value_type sum() const;
  152. valarray<value_type> shift(int) const;
  153. valarray<value_type> cshift(int) const;
  154. value_type min() const;
  155. value_type max() const;
  156. valarray<value_type> apply(value_type (*)(const value_type&)) const;
  157. valarray<value_type> apply(value_type (*)(value_type)) const;
  158. private:
  159. const _Clos _M_closure;
  160. };
  161. template<class _Clos, typename _Tp>
  162. inline
  163. _Expr<_Clos, _Tp>::_Expr(const _Clos& __c) : _M_closure(__c) {}
  164. template<class _Clos, typename _Tp>
  165. inline const _Clos&
  166. _Expr<_Clos, _Tp>::operator()() const
  167. { return _M_closure; }
  168. template<class _Clos, typename _Tp>
  169. inline _Tp
  170. _Expr<_Clos, _Tp>::operator[](size_t __i) const
  171. { return _M_closure[__i]; }
  172. template<class _Clos, typename _Tp>
  173. inline valarray<_Tp>
  174. _Expr<_Clos, _Tp>::operator[](slice __s) const
  175. {
  176. valarray<_Tp> __v = valarray<_Tp>(*this)[__s];
  177. return __v;
  178. }
  179. template<class _Clos, typename _Tp>
  180. inline valarray<_Tp>
  181. _Expr<_Clos, _Tp>::operator[](const gslice& __gs) const
  182. {
  183. valarray<_Tp> __v = valarray<_Tp>(*this)[__gs];
  184. return __v;
  185. }
  186. template<class _Clos, typename _Tp>
  187. inline valarray<_Tp>
  188. _Expr<_Clos, _Tp>::operator[](const valarray<bool>& __m) const
  189. {
  190. valarray<_Tp> __v = valarray<_Tp>(*this)[__m];
  191. return __v;
  192. }
  193. template<class _Clos, typename _Tp>
  194. inline valarray<_Tp>
  195. _Expr<_Clos, _Tp>::operator[](const valarray<size_t>& __i) const
  196. {
  197. valarray<_Tp> __v = valarray<_Tp>(*this)[__i];
  198. return __v;
  199. }
  200. template<class _Clos, typename _Tp>
  201. inline size_t
  202. _Expr<_Clos, _Tp>::size() const
  203. { return _M_closure.size(); }
  204. template<class _Clos, typename _Tp>
  205. inline valarray<_Tp>
  206. _Expr<_Clos, _Tp>::shift(int __n) const
  207. {
  208. valarray<_Tp> __v = valarray<_Tp>(*this).shift(__n);
  209. return __v;
  210. }
  211. template<class _Clos, typename _Tp>
  212. inline valarray<_Tp>
  213. _Expr<_Clos, _Tp>::cshift(int __n) const
  214. {
  215. valarray<_Tp> __v = valarray<_Tp>(*this).cshift(__n);
  216. return __v;
  217. }
  218. template<class _Clos, typename _Tp>
  219. inline valarray<_Tp>
  220. _Expr<_Clos, _Tp>::apply(_Tp __f(const _Tp&)) const
  221. {
  222. valarray<_Tp> __v = valarray<_Tp>(*this).apply(__f);
  223. return __v;
  224. }
  225. template<class _Clos, typename _Tp>
  226. inline valarray<_Tp>
  227. _Expr<_Clos, _Tp>::apply(_Tp __f(_Tp)) const
  228. {
  229. valarray<_Tp> __v = valarray<_Tp>(*this).apply(__f);
  230. return __v;
  231. }
  232. // XXX: replace this with a more robust summation algorithm.
  233. template<class _Clos, typename _Tp>
  234. inline _Tp
  235. _Expr<_Clos, _Tp>::sum() const
  236. {
  237. size_t __n = _M_closure.size();
  238. if (__n == 0)
  239. return _Tp();
  240. else
  241. {
  242. _Tp __s = _M_closure[--__n];
  243. while (__n != 0)
  244. __s += _M_closure[--__n];
  245. return __s;
  246. }
  247. }
  248. template<class _Clos, typename _Tp>
  249. inline _Tp
  250. _Expr<_Clos, _Tp>::min() const
  251. { return __valarray_min(_M_closure); }
  252. template<class _Clos, typename _Tp>
  253. inline _Tp
  254. _Expr<_Clos, _Tp>::max() const
  255. { return __valarray_max(_M_closure); }
  256. template<class _Dom, typename _Tp>
  257. inline _Expr<_UnClos<__logical_not, _Expr, _Dom>, bool>
  258. _Expr<_Dom, _Tp>::operator!() const
  259. {
  260. typedef _UnClos<__logical_not, std::_Expr, _Dom> _Closure;
  261. return _Expr<_Closure, bool>(_Closure(this->_M_closure));
  262. }
  263. #define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name) \
  264. template<class _Dom, typename _Tp> \
  265. inline _Expr<_UnClos<_Name, std::_Expr, _Dom>, _Tp> \
  266. _Expr<_Dom, _Tp>::operator _Op() const \
  267. { \
  268. typedef _UnClos<_Name, std::_Expr, _Dom> _Closure; \
  269. return _Expr<_Closure, _Tp>(_Closure(this->_M_closure)); \
  270. }
  271. _DEFINE_EXPR_UNARY_OPERATOR(+, __unary_plus)
  272. _DEFINE_EXPR_UNARY_OPERATOR(-, __negate)
  273. _DEFINE_EXPR_UNARY_OPERATOR(~, __bitwise_not)
  274. #undef _DEFINE_EXPR_UNARY_OPERATOR
  275. #define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name) \
  276. template<class _Dom1, class _Dom2> \
  277. inline _Expr<_BinClos<_Name, _Expr, _Expr, _Dom1, _Dom2>, \
  278. typename __fun<_Name, typename _Dom1::value_type>::result_type> \
  279. operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v, \
  280. const _Expr<_Dom2, typename _Dom2::value_type>& __w) \
  281. { \
  282. typedef typename _Dom1::value_type _Arg; \
  283. typedef typename __fun<_Name, _Arg>::result_type _Value; \
  284. typedef _BinClos<_Name, _Expr, _Expr, _Dom1, _Dom2> _Closure; \
  285. return _Expr<_Closure, _Value>(_Closure(__v(), __w())); \
  286. } \
  287. \
  288. template<class _Dom> \
  289. inline _Expr<_BinClos<_Name, _Expr, _Constant, _Dom, \
  290. typename _Dom::value_type>, \
  291. typename __fun<_Name, typename _Dom::value_type>::result_type> \
  292. operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v, \
  293. const typename _Dom::value_type& __t) \
  294. { \
  295. typedef typename _Dom::value_type _Arg; \
  296. typedef typename __fun<_Name, _Arg>::result_type _Value; \
  297. typedef _BinClos<_Name, _Expr, _Constant, _Dom, _Arg> _Closure; \
  298. return _Expr<_Closure, _Value>(_Closure(__v(), __t)); \
  299. } \
  300. \
  301. template<class _Dom> \
  302. inline _Expr<_BinClos<_Name, _Constant, _Expr, \
  303. typename _Dom::value_type, _Dom>, \
  304. typename __fun<_Name, typename _Dom::value_type>::result_type> \
  305. operator _Op(const typename _Dom::value_type& __t, \
  306. const _Expr<_Dom, typename _Dom::value_type>& __v) \
  307. { \
  308. typedef typename _Dom::value_type _Arg; \
  309. typedef typename __fun<_Name, _Arg>::result_type _Value; \
  310. typedef _BinClos<_Name, _Constant, _Expr, _Arg, _Dom> _Closure; \
  311. return _Expr<_Closure, _Value>(_Closure(__t, __v())); \
  312. } \
  313. \
  314. template<class _Dom> \
  315. inline _Expr<_BinClos<_Name, _Expr, _ValArray, \
  316. _Dom, typename _Dom::value_type>, \
  317. typename __fun<_Name, typename _Dom::value_type>::result_type> \
  318. operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \
  319. const valarray<typename _Dom::value_type>& __v) \
  320. { \
  321. typedef typename _Dom::value_type _Arg; \
  322. typedef typename __fun<_Name, _Arg>::result_type _Value; \
  323. typedef _BinClos<_Name, _Expr, _ValArray, _Dom, _Arg> _Closure; \
  324. return _Expr<_Closure, _Value>(_Closure(__e(), __v)); \
  325. } \
  326. \
  327. template<class _Dom> \
  328. inline _Expr<_BinClos<_Name, _ValArray, _Expr, \
  329. typename _Dom::value_type, _Dom>, \
  330. typename __fun<_Name, typename _Dom::value_type>::result_type> \
  331. operator _Op(const valarray<typename _Dom::value_type>& __v, \
  332. const _Expr<_Dom, typename _Dom::value_type>& __e) \
  333. { \
  334. typedef typename _Dom::value_type _Tp; \
  335. typedef typename __fun<_Name, _Tp>::result_type _Value; \
  336. typedef _BinClos<_Name, _ValArray, _Expr, _Tp, _Dom> _Closure; \
  337. return _Expr<_Closure, _Value>(_Closure(__v, __e ())); \
  338. }
  339. _DEFINE_EXPR_BINARY_OPERATOR(+, __plus)
  340. _DEFINE_EXPR_BINARY_OPERATOR(-, __minus)
  341. _DEFINE_EXPR_BINARY_OPERATOR(*, __multiplies)
  342. _DEFINE_EXPR_BINARY_OPERATOR(/, __divides)
  343. _DEFINE_EXPR_BINARY_OPERATOR(%, __modulus)
  344. _DEFINE_EXPR_BINARY_OPERATOR(^, __bitwise_xor)
  345. _DEFINE_EXPR_BINARY_OPERATOR(&, __bitwise_and)
  346. _DEFINE_EXPR_BINARY_OPERATOR(|, __bitwise_or)
  347. _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)
  348. _DEFINE_EXPR_BINARY_OPERATOR(>>, __shift_right)
  349. _DEFINE_EXPR_BINARY_OPERATOR(&&, __logical_and)
  350. _DEFINE_EXPR_BINARY_OPERATOR(||, __logical_or)
  351. _DEFINE_EXPR_BINARY_OPERATOR(==, __equal_to)
  352. _DEFINE_EXPR_BINARY_OPERATOR(!=, __not_equal_to)
  353. _DEFINE_EXPR_BINARY_OPERATOR(<, __less)
  354. _DEFINE_EXPR_BINARY_OPERATOR(>, __greater)
  355. _DEFINE_EXPR_BINARY_OPERATOR(<=, __less_equal)
  356. _DEFINE_EXPR_BINARY_OPERATOR(>=, __greater_equal)
  357. #undef _DEFINE_EXPR_BINARY_OPERATOR
  358. #define _DEFINE_EXPR_UNARY_FUNCTION(_Name, _UName) \
  359. template<class _Dom> \
  360. inline _Expr<_UnClos<_UName, _Expr, _Dom>, \
  361. typename _Dom::value_type> \
  362. _Name(const _Expr<_Dom, typename _Dom::value_type>& __e) \
  363. { \
  364. typedef typename _Dom::value_type _Tp; \
  365. typedef _UnClos<_UName, _Expr, _Dom> _Closure; \
  366. return _Expr<_Closure, _Tp>(_Closure(__e())); \
  367. } \
  368. \
  369. template<typename _Tp> \
  370. inline _Expr<_UnClos<_UName, _ValArray, _Tp>, _Tp> \
  371. _Name(const valarray<_Tp>& __v) \
  372. { \
  373. typedef _UnClos<_UName, _ValArray, _Tp> _Closure; \
  374. return _Expr<_Closure, _Tp>(_Closure(__v)); \
  375. }
  376. _DEFINE_EXPR_UNARY_FUNCTION(abs, _Abs)
  377. _DEFINE_EXPR_UNARY_FUNCTION(cos, _Cos)
  378. _DEFINE_EXPR_UNARY_FUNCTION(acos, _Acos)
  379. _DEFINE_EXPR_UNARY_FUNCTION(cosh, _Cosh)
  380. _DEFINE_EXPR_UNARY_FUNCTION(sin, _Sin)
  381. _DEFINE_EXPR_UNARY_FUNCTION(asin, _Asin)
  382. _DEFINE_EXPR_UNARY_FUNCTION(sinh, _Sinh)
  383. _DEFINE_EXPR_UNARY_FUNCTION(tan, _Tan)
  384. _DEFINE_EXPR_UNARY_FUNCTION(tanh, _Tanh)
  385. _DEFINE_EXPR_UNARY_FUNCTION(atan, _Atan)
  386. _DEFINE_EXPR_UNARY_FUNCTION(exp, _Exp)
  387. _DEFINE_EXPR_UNARY_FUNCTION(log, _Log)
  388. _DEFINE_EXPR_UNARY_FUNCTION(log10, _Log10)
  389. _DEFINE_EXPR_UNARY_FUNCTION(sqrt, _Sqrt)
  390. #undef _DEFINE_EXPR_UNARY_FUNCTION
  391. #define _DEFINE_EXPR_BINARY_FUNCTION(_Fun, _UFun) \
  392. template<class _Dom1, class _Dom2> \
  393. inline _Expr<_BinClos<_UFun, _Expr, _Expr, _Dom1, _Dom2>, \
  394. typename _Dom1::value_type> \
  395. _Fun(const _Expr<_Dom1, typename _Dom1::value_type>& __e1, \
  396. const _Expr<_Dom2, typename _Dom2::value_type>& __e2) \
  397. { \
  398. typedef typename _Dom1::value_type _Tp; \
  399. typedef _BinClos<_UFun, _Expr, _Expr, _Dom1, _Dom2> _Closure; \
  400. return _Expr<_Closure, _Tp>(_Closure(__e1(), __e2())); \
  401. } \
  402. \
  403. template<class _Dom> \
  404. inline _Expr<_BinClos<_UFun, _Expr, _ValArray, _Dom, \
  405. typename _Dom::value_type>, \
  406. typename _Dom::value_type> \
  407. _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e, \
  408. const valarray<typename _Dom::value_type>& __v) \
  409. { \
  410. typedef typename _Dom::value_type _Tp; \
  411. typedef _BinClos<_UFun, _Expr, _ValArray, _Dom, _Tp> _Closure; \
  412. return _Expr<_Closure, _Tp>(_Closure(__e(), __v)); \
  413. } \
  414. \
  415. template<class _Dom> \
  416. inline _Expr<_BinClos<_UFun, _ValArray, _Expr, \
  417. typename _Dom::value_type, _Dom>, \
  418. typename _Dom::value_type> \
  419. _Fun(const valarray<typename _Dom::valarray>& __v, \
  420. const _Expr<_Dom, typename _Dom::value_type>& __e) \
  421. { \
  422. typedef typename _Dom::value_type _Tp; \
  423. typedef _BinClos<_UFun, _ValArray, _Expr, _Tp, _Dom> _Closure; \
  424. return _Expr<_Closure, _Tp>(_Closure(__v, __e())); \
  425. } \
  426. \
  427. template<class _Dom> \
  428. inline _Expr<_BinClos<_UFun, _Expr, _Constant, _Dom, \
  429. typename _Dom::value_type>, \
  430. typename _Dom::value_type> \
  431. _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e, \
  432. const typename _Dom::value_type& __t) \
  433. { \
  434. typedef typename _Dom::value_type _Tp; \
  435. typedef _BinClos<_UFun, _Expr, _Constant, _Dom, _Tp> _Closure; \
  436. return _Expr<_Closure, _Tp>(_Closure(__e(), __t)); \
  437. } \
  438. \
  439. template<class _Dom> \
  440. inline _Expr<_BinClos<_UFun, _Constant, _Expr, \
  441. typename _Dom::value_type, _Dom>, \
  442. typename _Dom::value_type> \
  443. _Fun(const typename _Dom::value_type& __t, \
  444. const _Expr<_Dom, typename _Dom::value_type>& __e) \
  445. { \
  446. typedef typename _Dom::value_type _Tp; \
  447. typedef _BinClos<_UFun, _Constant, _Expr, _Tp, _Dom> _Closure; \
  448. return _Expr<_Closure, _Tp>(_Closure(__t, __e())); \
  449. } \
  450. \
  451. template<typename _Tp> \
  452. inline _Expr<_BinClos<_UFun, _ValArray, _ValArray, _Tp, _Tp>, _Tp> \
  453. _Fun(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \
  454. { \
  455. typedef _BinClos<_UFun, _ValArray, _ValArray, _Tp, _Tp> _Closure;\
  456. return _Expr<_Closure, _Tp>(_Closure(__v, __w)); \
  457. } \
  458. \
  459. template<typename _Tp> \
  460. inline _Expr<_BinClos<_UFun, _ValArray, _Constant, _Tp, _Tp>, _Tp> \
  461. _Fun(const valarray<_Tp>& __v, \
  462. const typename valarray<_Tp>::value_type& __t) \
  463. { \
  464. typedef _BinClos<_UFun, _ValArray, _Constant, _Tp, _Tp> _Closure;\
  465. return _Expr<_Closure, _Tp>(_Closure(__v, __t)); \
  466. } \
  467. \
  468. template<typename _Tp> \
  469. inline _Expr<_BinClos<_UFun, _Constant, _ValArray, _Tp, _Tp>, _Tp> \
  470. _Fun(const typename valarray<_Tp>::value_type& __t, \
  471. const valarray<_Tp>& __v) \
  472. { \
  473. typedef _BinClos<_UFun, _Constant, _ValArray, _Tp, _Tp> _Closure;\
  474. return _Expr<_Closure, _Tp>(_Closure(__t, __v)); \
  475. }
  476. _DEFINE_EXPR_BINARY_FUNCTION(atan2, _Atan2)
  477. _DEFINE_EXPR_BINARY_FUNCTION(pow, _Pow)
  478. #undef _DEFINE_EXPR_BINARY_FUNCTION
  479. _GLIBCXX_END_NAMESPACE_VERSION
  480. } // namespace
  481. #endif /* _CPP_VALARRAY_AFTER_H */