1*404b540aSrobert // The template and inlines for the -*- C++ -*- internal _Meta class. 2*404b540aSrobert 3*404b540aSrobert // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 4*404b540aSrobert // Free Software Foundation, Inc. 5*404b540aSrobert // 6*404b540aSrobert // This file is part of the GNU ISO C++ Library. This library is free 7*404b540aSrobert // software; you can redistribute it and/or modify it under the 8*404b540aSrobert // terms of the GNU General Public License as published by the 9*404b540aSrobert // Free Software Foundation; either version 2, or (at your option) 10*404b540aSrobert // any later version. 11*404b540aSrobert 12*404b540aSrobert // This library is distributed in the hope that it will be useful, 13*404b540aSrobert // but WITHOUT ANY WARRANTY; without even the implied warranty of 14*404b540aSrobert // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*404b540aSrobert // GNU General Public License for more details. 16*404b540aSrobert 17*404b540aSrobert // You should have received a copy of the GNU General Public License along 18*404b540aSrobert // with this library; see the file COPYING. If not, write to the Free 19*404b540aSrobert // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20*404b540aSrobert // USA. 21*404b540aSrobert 22*404b540aSrobert // As a special exception, you may use this file as part of a free software 23*404b540aSrobert // library without restriction. Specifically, if other files instantiate 24*404b540aSrobert // templates or use macros or inline functions from this file, or you compile 25*404b540aSrobert // this file and link it with other files to produce an executable, this 26*404b540aSrobert // file does not by itself cause the resulting executable to be covered by 27*404b540aSrobert // the GNU General Public License. This exception does not however 28*404b540aSrobert // invalidate any other reasons why the executable file might be covered by 29*404b540aSrobert // the GNU General Public License. 30*404b540aSrobert 31*404b540aSrobert /** @file valarray_before.h 32*404b540aSrobert * This is an internal header file, included by other library headers. 33*404b540aSrobert * You should not attempt to use it directly. 34*404b540aSrobert */ 35*404b540aSrobert 36*404b540aSrobert // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr> 37*404b540aSrobert 38*404b540aSrobert #ifndef _VALARRAY_BEFORE_H 39*404b540aSrobert #define _VALARRAY_BEFORE_H 1 40*404b540aSrobert 41*404b540aSrobert #pragma GCC system_header 42*404b540aSrobert 43*404b540aSrobert #include <bits/slice_array.h> 44*404b540aSrobert 45*404b540aSrobert _GLIBCXX_BEGIN_NAMESPACE(std) 46*404b540aSrobert 47*404b540aSrobert // 48*404b540aSrobert // Implementing a loosened valarray return value is tricky. 49*404b540aSrobert // First we need to meet 26.3.1/3: we should not add more than 50*404b540aSrobert // two levels of template nesting. Therefore we resort to template 51*404b540aSrobert // template to "flatten" loosened return value types. 52*404b540aSrobert // At some point we use partial specialization to remove one level 53*404b540aSrobert // template nesting due to _Expr<> 54*404b540aSrobert // 55*404b540aSrobert 56*404b540aSrobert // This class is NOT defined. It doesn't need to. 57*404b540aSrobert template<typename _Tp1, typename _Tp2> class _Constant; 58*404b540aSrobert 59*404b540aSrobert // Implementations of unary functions applied to valarray<>s. 60*404b540aSrobert // I use hard-coded object functions here instead of a generic 61*404b540aSrobert // approach like pointers to function: 62*404b540aSrobert // 1) correctness: some functions take references, others values. 63*404b540aSrobert // we can't deduce the correct type afterwards. 64*404b540aSrobert // 2) efficiency -- object functions can be easily inlined 65*404b540aSrobert // 3) be Koenig-lookup-friendly 66*404b540aSrobert 67*404b540aSrobert struct __abs 68*404b540aSrobert { 69*404b540aSrobert template<typename _Tp> operator__abs70*404b540aSrobert _Tp operator()(const _Tp& __t) const 71*404b540aSrobert { return abs(__t); } 72*404b540aSrobert }; 73*404b540aSrobert 74*404b540aSrobert struct __cos 75*404b540aSrobert { 76*404b540aSrobert template<typename _Tp> operator__cos77*404b540aSrobert _Tp operator()(const _Tp& __t) const 78*404b540aSrobert { return cos(__t); } 79*404b540aSrobert }; 80*404b540aSrobert 81*404b540aSrobert struct __acos 82*404b540aSrobert { 83*404b540aSrobert template<typename _Tp> operator__acos84*404b540aSrobert _Tp operator()(const _Tp& __t) const 85*404b540aSrobert { return acos(__t); } 86*404b540aSrobert }; 87*404b540aSrobert 88*404b540aSrobert struct __cosh 89*404b540aSrobert { 90*404b540aSrobert template<typename _Tp> operator__cosh91*404b540aSrobert _Tp operator()(const _Tp& __t) const 92*404b540aSrobert { return cosh(__t); } 93*404b540aSrobert }; 94*404b540aSrobert 95*404b540aSrobert struct __sin 96*404b540aSrobert { 97*404b540aSrobert template<typename _Tp> operator__sin98*404b540aSrobert _Tp operator()(const _Tp& __t) const 99*404b540aSrobert { return sin(__t); } 100*404b540aSrobert }; 101*404b540aSrobert 102*404b540aSrobert struct __asin 103*404b540aSrobert { 104*404b540aSrobert template<typename _Tp> operator__asin105*404b540aSrobert _Tp operator()(const _Tp& __t) const 106*404b540aSrobert { return asin(__t); } 107*404b540aSrobert }; 108*404b540aSrobert 109*404b540aSrobert struct __sinh 110*404b540aSrobert { 111*404b540aSrobert template<typename _Tp> operator__sinh112*404b540aSrobert _Tp operator()(const _Tp& __t) const 113*404b540aSrobert { return sinh(__t); } 114*404b540aSrobert }; 115*404b540aSrobert 116*404b540aSrobert struct __tan 117*404b540aSrobert { 118*404b540aSrobert template<typename _Tp> operator__tan119*404b540aSrobert _Tp operator()(const _Tp& __t) const 120*404b540aSrobert { return tan(__t); } 121*404b540aSrobert }; 122*404b540aSrobert 123*404b540aSrobert struct __atan 124*404b540aSrobert { 125*404b540aSrobert template<typename _Tp> operator__atan126*404b540aSrobert _Tp operator()(const _Tp& __t) const 127*404b540aSrobert { return atan(__t); } 128*404b540aSrobert }; 129*404b540aSrobert 130*404b540aSrobert struct __tanh 131*404b540aSrobert { 132*404b540aSrobert template<typename _Tp> operator__tanh133*404b540aSrobert _Tp operator()(const _Tp& __t) const 134*404b540aSrobert { return tanh(__t); } 135*404b540aSrobert }; 136*404b540aSrobert 137*404b540aSrobert struct __exp 138*404b540aSrobert { 139*404b540aSrobert template<typename _Tp> operator__exp140*404b540aSrobert _Tp operator()(const _Tp& __t) const 141*404b540aSrobert { return exp(__t); } 142*404b540aSrobert }; 143*404b540aSrobert 144*404b540aSrobert struct __log 145*404b540aSrobert { 146*404b540aSrobert template<typename _Tp> operator__log147*404b540aSrobert _Tp operator()(const _Tp& __t) const 148*404b540aSrobert { return log(__t); } 149*404b540aSrobert }; 150*404b540aSrobert 151*404b540aSrobert struct __log10 152*404b540aSrobert { 153*404b540aSrobert template<typename _Tp> operator__log10154*404b540aSrobert _Tp operator()(const _Tp& __t) const 155*404b540aSrobert { return log10(__t); } 156*404b540aSrobert }; 157*404b540aSrobert 158*404b540aSrobert struct __sqrt 159*404b540aSrobert { 160*404b540aSrobert template<typename _Tp> operator__sqrt161*404b540aSrobert _Tp operator()(const _Tp& __t) const 162*404b540aSrobert { return sqrt(__t); } 163*404b540aSrobert }; 164*404b540aSrobert 165*404b540aSrobert // In the past, we used to tailor operator applications semantics 166*404b540aSrobert // to the specialization of standard function objects (i.e. plus<>, etc.) 167*404b540aSrobert // That is incorrect. Therefore we provide our own surrogates. 168*404b540aSrobert 169*404b540aSrobert struct __unary_plus 170*404b540aSrobert { 171*404b540aSrobert template<typename _Tp> operator__unary_plus172*404b540aSrobert _Tp operator()(const _Tp& __t) const 173*404b540aSrobert { return +__t; } 174*404b540aSrobert }; 175*404b540aSrobert 176*404b540aSrobert struct __negate 177*404b540aSrobert { 178*404b540aSrobert template<typename _Tp> operator__negate179*404b540aSrobert _Tp operator()(const _Tp& __t) const 180*404b540aSrobert { return -__t; } 181*404b540aSrobert }; 182*404b540aSrobert 183*404b540aSrobert struct __bitwise_not 184*404b540aSrobert { 185*404b540aSrobert template<typename _Tp> operator__bitwise_not186*404b540aSrobert _Tp operator()(const _Tp& __t) const 187*404b540aSrobert { return ~__t; } 188*404b540aSrobert }; 189*404b540aSrobert 190*404b540aSrobert struct __plus 191*404b540aSrobert { 192*404b540aSrobert template<typename _Tp> operator__plus193*404b540aSrobert _Tp operator()(const _Tp& __x, const _Tp& __y) const 194*404b540aSrobert { return __x + __y; } 195*404b540aSrobert }; 196*404b540aSrobert 197*404b540aSrobert struct __minus 198*404b540aSrobert { 199*404b540aSrobert template<typename _Tp> operator__minus200*404b540aSrobert _Tp operator()(const _Tp& __x, const _Tp& __y) const 201*404b540aSrobert { return __x - __y; } 202*404b540aSrobert }; 203*404b540aSrobert 204*404b540aSrobert struct __multiplies 205*404b540aSrobert { 206*404b540aSrobert template<typename _Tp> operator__multiplies207*404b540aSrobert _Tp operator()(const _Tp& __x, const _Tp& __y) const 208*404b540aSrobert { return __x * __y; } 209*404b540aSrobert }; 210*404b540aSrobert 211*404b540aSrobert struct __divides 212*404b540aSrobert { 213*404b540aSrobert template<typename _Tp> operator__divides214*404b540aSrobert _Tp operator()(const _Tp& __x, const _Tp& __y) const 215*404b540aSrobert { return __x / __y; } 216*404b540aSrobert }; 217*404b540aSrobert 218*404b540aSrobert struct __modulus 219*404b540aSrobert { 220*404b540aSrobert template<typename _Tp> operator__modulus221*404b540aSrobert _Tp operator()(const _Tp& __x, const _Tp& __y) const 222*404b540aSrobert { return __x % __y; } 223*404b540aSrobert }; 224*404b540aSrobert 225*404b540aSrobert struct __bitwise_xor 226*404b540aSrobert { 227*404b540aSrobert template<typename _Tp> operator__bitwise_xor228*404b540aSrobert _Tp operator()(const _Tp& __x, const _Tp& __y) const 229*404b540aSrobert { return __x ^ __y; } 230*404b540aSrobert }; 231*404b540aSrobert 232*404b540aSrobert struct __bitwise_and 233*404b540aSrobert { 234*404b540aSrobert template<typename _Tp> operator__bitwise_and235*404b540aSrobert _Tp operator()(const _Tp& __x, const _Tp& __y) const 236*404b540aSrobert { return __x & __y; } 237*404b540aSrobert }; 238*404b540aSrobert 239*404b540aSrobert struct __bitwise_or 240*404b540aSrobert { 241*404b540aSrobert template<typename _Tp> operator__bitwise_or242*404b540aSrobert _Tp operator()(const _Tp& __x, const _Tp& __y) const 243*404b540aSrobert { return __x | __y; } 244*404b540aSrobert }; 245*404b540aSrobert 246*404b540aSrobert struct __shift_left 247*404b540aSrobert { 248*404b540aSrobert template<typename _Tp> operator__shift_left249*404b540aSrobert _Tp operator()(const _Tp& __x, const _Tp& __y) const 250*404b540aSrobert { return __x << __y; } 251*404b540aSrobert }; 252*404b540aSrobert 253*404b540aSrobert struct __shift_right 254*404b540aSrobert { 255*404b540aSrobert template<typename _Tp> operator__shift_right256*404b540aSrobert _Tp operator()(const _Tp& __x, const _Tp& __y) const 257*404b540aSrobert { return __x >> __y; } 258*404b540aSrobert }; 259*404b540aSrobert 260*404b540aSrobert struct __logical_and 261*404b540aSrobert { 262*404b540aSrobert template<typename _Tp> operator__logical_and263*404b540aSrobert bool operator()(const _Tp& __x, const _Tp& __y) const 264*404b540aSrobert { return __x && __y; } 265*404b540aSrobert }; 266*404b540aSrobert 267*404b540aSrobert struct __logical_or 268*404b540aSrobert { 269*404b540aSrobert template<typename _Tp> operator__logical_or270*404b540aSrobert bool operator()(const _Tp& __x, const _Tp& __y) const 271*404b540aSrobert { return __x || __y; } 272*404b540aSrobert }; 273*404b540aSrobert 274*404b540aSrobert struct __logical_not 275*404b540aSrobert { 276*404b540aSrobert template<typename _Tp> operator__logical_not277*404b540aSrobert bool operator()(const _Tp& __x) const { return !__x; } 278*404b540aSrobert }; 279*404b540aSrobert 280*404b540aSrobert struct __equal_to 281*404b540aSrobert { 282*404b540aSrobert template<typename _Tp> operator__equal_to283*404b540aSrobert bool operator()(const _Tp& __x, const _Tp& __y) const 284*404b540aSrobert { return __x == __y; } 285*404b540aSrobert }; 286*404b540aSrobert 287*404b540aSrobert struct __not_equal_to 288*404b540aSrobert { 289*404b540aSrobert template<typename _Tp> operator__not_equal_to290*404b540aSrobert bool operator()(const _Tp& __x, const _Tp& __y) const 291*404b540aSrobert { return __x != __y; } 292*404b540aSrobert }; 293*404b540aSrobert 294*404b540aSrobert struct __less 295*404b540aSrobert { 296*404b540aSrobert template<typename _Tp> operator__less297*404b540aSrobert bool operator()(const _Tp& __x, const _Tp& __y) const 298*404b540aSrobert { return __x < __y; } 299*404b540aSrobert }; 300*404b540aSrobert 301*404b540aSrobert struct __greater 302*404b540aSrobert { 303*404b540aSrobert template<typename _Tp> operator__greater304*404b540aSrobert bool operator()(const _Tp& __x, const _Tp& __y) const 305*404b540aSrobert { return __x > __y; } 306*404b540aSrobert }; 307*404b540aSrobert 308*404b540aSrobert struct __less_equal 309*404b540aSrobert { 310*404b540aSrobert template<typename _Tp> operator__less_equal311*404b540aSrobert bool operator()(const _Tp& __x, const _Tp& __y) const 312*404b540aSrobert { return __x <= __y; } 313*404b540aSrobert }; 314*404b540aSrobert 315*404b540aSrobert struct __greater_equal 316*404b540aSrobert { 317*404b540aSrobert template<typename _Tp> operator__greater_equal318*404b540aSrobert bool operator()(const _Tp& __x, const _Tp& __y) const 319*404b540aSrobert { return __x >= __y; } 320*404b540aSrobert }; 321*404b540aSrobert 322*404b540aSrobert // The few binary functions we miss. 323*404b540aSrobert struct __atan2 324*404b540aSrobert { 325*404b540aSrobert template<typename _Tp> operator__atan2326*404b540aSrobert _Tp operator()(const _Tp& __x, const _Tp& __y) const 327*404b540aSrobert { return atan2(__x, __y); } 328*404b540aSrobert }; 329*404b540aSrobert 330*404b540aSrobert struct __pow 331*404b540aSrobert { 332*404b540aSrobert template<typename _Tp> operator__pow333*404b540aSrobert _Tp operator()(const _Tp& __x, const _Tp& __y) const 334*404b540aSrobert { return pow(__x, __y); } 335*404b540aSrobert }; 336*404b540aSrobert 337*404b540aSrobert 338*404b540aSrobert // We need these bits in order to recover the return type of 339*404b540aSrobert // some functions/operators now that we're no longer using 340*404b540aSrobert // function templates. 341*404b540aSrobert template<typename, typename _Tp> 342*404b540aSrobert struct __fun 343*404b540aSrobert { 344*404b540aSrobert typedef _Tp result_type; 345*404b540aSrobert }; 346*404b540aSrobert 347*404b540aSrobert // several specializations for relational operators. 348*404b540aSrobert template<typename _Tp> 349*404b540aSrobert struct __fun<__logical_not, _Tp> 350*404b540aSrobert { 351*404b540aSrobert typedef bool result_type; 352*404b540aSrobert }; 353*404b540aSrobert 354*404b540aSrobert template<typename _Tp> 355*404b540aSrobert struct __fun<__logical_and, _Tp> 356*404b540aSrobert { 357*404b540aSrobert typedef bool result_type; 358*404b540aSrobert }; 359*404b540aSrobert 360*404b540aSrobert template<typename _Tp> 361*404b540aSrobert struct __fun<__logical_or, _Tp> 362*404b540aSrobert { 363*404b540aSrobert typedef bool result_type; 364*404b540aSrobert }; 365*404b540aSrobert 366*404b540aSrobert template<typename _Tp> 367*404b540aSrobert struct __fun<__less, _Tp> 368*404b540aSrobert { 369*404b540aSrobert typedef bool result_type; 370*404b540aSrobert }; 371*404b540aSrobert 372*404b540aSrobert template<typename _Tp> 373*404b540aSrobert struct __fun<__greater, _Tp> 374*404b540aSrobert { 375*404b540aSrobert typedef bool result_type; 376*404b540aSrobert }; 377*404b540aSrobert 378*404b540aSrobert template<typename _Tp> 379*404b540aSrobert struct __fun<__less_equal, _Tp> 380*404b540aSrobert { 381*404b540aSrobert typedef bool result_type; 382*404b540aSrobert }; 383*404b540aSrobert 384*404b540aSrobert template<typename _Tp> 385*404b540aSrobert struct __fun<__greater_equal, _Tp> 386*404b540aSrobert { 387*404b540aSrobert typedef bool result_type; 388*404b540aSrobert }; 389*404b540aSrobert 390*404b540aSrobert template<typename _Tp> 391*404b540aSrobert struct __fun<__equal_to, _Tp> 392*404b540aSrobert { 393*404b540aSrobert typedef bool result_type; 394*404b540aSrobert }; 395*404b540aSrobert 396*404b540aSrobert template<typename _Tp> 397*404b540aSrobert struct __fun<__not_equal_to, _Tp> 398*404b540aSrobert { 399*404b540aSrobert typedef bool result_type; 400*404b540aSrobert }; 401*404b540aSrobert 402*404b540aSrobert // 403*404b540aSrobert // Apply function taking a value/const reference closure 404*404b540aSrobert // 405*404b540aSrobert 406*404b540aSrobert template<typename _Dom, typename _Arg> 407*404b540aSrobert class _FunBase 408*404b540aSrobert { 409*404b540aSrobert public: 410*404b540aSrobert typedef typename _Dom::value_type value_type; 411*404b540aSrobert 412*404b540aSrobert _FunBase(const _Dom& __e, value_type __f(_Arg)) 413*404b540aSrobert : _M_expr(__e), _M_func(__f) {} 414*404b540aSrobert 415*404b540aSrobert value_type operator[](size_t __i) const 416*404b540aSrobert { return _M_func (_M_expr[__i]); } 417*404b540aSrobert 418*404b540aSrobert size_t size() const { return _M_expr.size ();} 419*404b540aSrobert 420*404b540aSrobert private: 421*404b540aSrobert const _Dom& _M_expr; 422*404b540aSrobert value_type (*_M_func)(_Arg); 423*404b540aSrobert }; 424*404b540aSrobert 425*404b540aSrobert template<class _Dom> 426*404b540aSrobert struct _ValFunClos<_Expr,_Dom> : _FunBase<_Dom, typename _Dom::value_type> 427*404b540aSrobert { 428*404b540aSrobert typedef _FunBase<_Dom, typename _Dom::value_type> _Base; 429*404b540aSrobert typedef typename _Base::value_type value_type; 430*404b540aSrobert typedef value_type _Tp; 431*404b540aSrobert 432*404b540aSrobert _ValFunClos(const _Dom& __e, _Tp __f(_Tp)) : _Base(__e, __f) {} 433*404b540aSrobert }; 434*404b540aSrobert 435*404b540aSrobert template<typename _Tp> 436*404b540aSrobert struct _ValFunClos<_ValArray,_Tp> : _FunBase<valarray<_Tp>, _Tp> 437*404b540aSrobert { 438*404b540aSrobert typedef _FunBase<valarray<_Tp>, _Tp> _Base; 439*404b540aSrobert typedef _Tp value_type; 440*404b540aSrobert 441*404b540aSrobert _ValFunClos(const valarray<_Tp>& __v, _Tp __f(_Tp)) : _Base(__v, __f) {} 442*404b540aSrobert }; 443*404b540aSrobert 444*404b540aSrobert template<class _Dom> 445*404b540aSrobert struct _RefFunClos<_Expr, _Dom> 446*404b540aSrobert : _FunBase<_Dom, const typename _Dom::value_type&> 447*404b540aSrobert { 448*404b540aSrobert typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base; 449*404b540aSrobert typedef typename _Base::value_type value_type; 450*404b540aSrobert typedef value_type _Tp; 451*404b540aSrobert 452*404b540aSrobert _RefFunClos(const _Dom& __e, _Tp __f(const _Tp&)) 453*404b540aSrobert : _Base(__e, __f) {} 454*404b540aSrobert }; 455*404b540aSrobert 456*404b540aSrobert template<typename _Tp> 457*404b540aSrobert struct _RefFunClos<_ValArray, _Tp> 458*404b540aSrobert : _FunBase<valarray<_Tp>, const _Tp&> 459*404b540aSrobert { 460*404b540aSrobert typedef _FunBase<valarray<_Tp>, const _Tp&> _Base; 461*404b540aSrobert typedef _Tp value_type; 462*404b540aSrobert 463*404b540aSrobert _RefFunClos(const valarray<_Tp>& __v, _Tp __f(const _Tp&)) 464*404b540aSrobert : _Base(__v, __f) {} 465*404b540aSrobert }; 466*404b540aSrobert 467*404b540aSrobert // 468*404b540aSrobert // Unary expression closure. 469*404b540aSrobert // 470*404b540aSrobert 471*404b540aSrobert template<class _Oper, class _Arg> 472*404b540aSrobert class _UnBase 473*404b540aSrobert { 474*404b540aSrobert public: 475*404b540aSrobert typedef typename _Arg::value_type _Vt; 476*404b540aSrobert typedef typename __fun<_Oper, _Vt>::result_type value_type; 477*404b540aSrobert 478*404b540aSrobert _UnBase(const _Arg& __e) : _M_expr(__e) {} 479*404b540aSrobert 480*404b540aSrobert value_type operator[](size_t __i) const 481*404b540aSrobert { return _Oper()(_M_expr[__i]); } 482*404b540aSrobert 483*404b540aSrobert size_t size() const { return _M_expr.size(); } 484*404b540aSrobert 485*404b540aSrobert private: 486*404b540aSrobert const _Arg& _M_expr; 487*404b540aSrobert }; 488*404b540aSrobert 489*404b540aSrobert template<class _Oper, class _Dom> 490*404b540aSrobert struct _UnClos<_Oper, _Expr, _Dom> 491*404b540aSrobert : _UnBase<_Oper, _Dom> 492*404b540aSrobert { 493*404b540aSrobert typedef _Dom _Arg; 494*404b540aSrobert typedef _UnBase<_Oper, _Dom> _Base; 495*404b540aSrobert typedef typename _Base::value_type value_type; 496*404b540aSrobert 497*404b540aSrobert _UnClos(const _Arg& __e) : _Base(__e) {} 498*404b540aSrobert }; 499*404b540aSrobert 500*404b540aSrobert template<class _Oper, typename _Tp> 501*404b540aSrobert struct _UnClos<_Oper, _ValArray, _Tp> 502*404b540aSrobert : _UnBase<_Oper, valarray<_Tp> > 503*404b540aSrobert { 504*404b540aSrobert typedef valarray<_Tp> _Arg; 505*404b540aSrobert typedef _UnBase<_Oper, valarray<_Tp> > _Base; 506*404b540aSrobert typedef typename _Base::value_type value_type; 507*404b540aSrobert 508*404b540aSrobert _UnClos(const _Arg& __e) : _Base(__e) {} 509*404b540aSrobert }; 510*404b540aSrobert 511*404b540aSrobert 512*404b540aSrobert // 513*404b540aSrobert // Binary expression closure. 514*404b540aSrobert // 515*404b540aSrobert 516*404b540aSrobert template<class _Oper, class _FirstArg, class _SecondArg> 517*404b540aSrobert class _BinBase 518*404b540aSrobert { 519*404b540aSrobert public: 520*404b540aSrobert typedef typename _FirstArg::value_type _Vt; 521*404b540aSrobert typedef typename __fun<_Oper, _Vt>::result_type value_type; 522*404b540aSrobert 523*404b540aSrobert _BinBase(const _FirstArg& __e1, const _SecondArg& __e2) 524*404b540aSrobert : _M_expr1(__e1), _M_expr2(__e2) {} 525*404b540aSrobert 526*404b540aSrobert value_type operator[](size_t __i) const 527*404b540aSrobert { return _Oper()(_M_expr1[__i], _M_expr2[__i]); } 528*404b540aSrobert 529*404b540aSrobert size_t size() const { return _M_expr1.size(); } 530*404b540aSrobert 531*404b540aSrobert private: 532*404b540aSrobert const _FirstArg& _M_expr1; 533*404b540aSrobert const _SecondArg& _M_expr2; 534*404b540aSrobert }; 535*404b540aSrobert 536*404b540aSrobert 537*404b540aSrobert template<class _Oper, class _Clos> 538*404b540aSrobert class _BinBase2 539*404b540aSrobert { 540*404b540aSrobert public: 541*404b540aSrobert typedef typename _Clos::value_type _Vt; 542*404b540aSrobert typedef typename __fun<_Oper, _Vt>::result_type value_type; 543*404b540aSrobert 544*404b540aSrobert _BinBase2(const _Clos& __e, const _Vt& __t) 545*404b540aSrobert : _M_expr1(__e), _M_expr2(__t) {} 546*404b540aSrobert 547*404b540aSrobert value_type operator[](size_t __i) const 548*404b540aSrobert { return _Oper()(_M_expr1[__i], _M_expr2); } 549*404b540aSrobert 550*404b540aSrobert size_t size() const { return _M_expr1.size(); } 551*404b540aSrobert 552*404b540aSrobert private: 553*404b540aSrobert const _Clos& _M_expr1; 554*404b540aSrobert const _Vt& _M_expr2; 555*404b540aSrobert }; 556*404b540aSrobert 557*404b540aSrobert template<class _Oper, class _Clos> 558*404b540aSrobert class _BinBase1 559*404b540aSrobert { 560*404b540aSrobert public: 561*404b540aSrobert typedef typename _Clos::value_type _Vt; 562*404b540aSrobert typedef typename __fun<_Oper, _Vt>::result_type value_type; 563*404b540aSrobert 564*404b540aSrobert _BinBase1(const _Vt& __t, const _Clos& __e) 565*404b540aSrobert : _M_expr1(__t), _M_expr2(__e) {} 566*404b540aSrobert 567*404b540aSrobert value_type operator[](size_t __i) const 568*404b540aSrobert { return _Oper()(_M_expr1, _M_expr2[__i]); } 569*404b540aSrobert 570*404b540aSrobert size_t size() const { return _M_expr2.size(); } 571*404b540aSrobert 572*404b540aSrobert private: 573*404b540aSrobert const _Vt& _M_expr1; 574*404b540aSrobert const _Clos& _M_expr2; 575*404b540aSrobert }; 576*404b540aSrobert 577*404b540aSrobert template<class _Oper, class _Dom1, class _Dom2> 578*404b540aSrobert struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2> 579*404b540aSrobert : _BinBase<_Oper, _Dom1, _Dom2> 580*404b540aSrobert { 581*404b540aSrobert typedef _BinBase<_Oper, _Dom1, _Dom2> _Base; 582*404b540aSrobert typedef typename _Base::value_type value_type; 583*404b540aSrobert 584*404b540aSrobert _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {} 585*404b540aSrobert }; 586*404b540aSrobert 587*404b540aSrobert template<class _Oper, typename _Tp> 588*404b540aSrobert struct _BinClos<_Oper,_ValArray, _ValArray, _Tp, _Tp> 589*404b540aSrobert : _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> > 590*404b540aSrobert { 591*404b540aSrobert typedef _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> > _Base; 592*404b540aSrobert typedef typename _Base::value_type value_type; 593*404b540aSrobert 594*404b540aSrobert _BinClos(const valarray<_Tp>& __v, const valarray<_Tp>& __w) 595*404b540aSrobert : _Base(__v, __w) {} 596*404b540aSrobert }; 597*404b540aSrobert 598*404b540aSrobert template<class _Oper, class _Dom> 599*404b540aSrobert struct _BinClos<_Oper, _Expr, _ValArray, _Dom, typename _Dom::value_type> 600*404b540aSrobert : _BinBase<_Oper, _Dom, valarray<typename _Dom::value_type> > 601*404b540aSrobert { 602*404b540aSrobert typedef typename _Dom::value_type _Tp; 603*404b540aSrobert typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base; 604*404b540aSrobert typedef typename _Base::value_type value_type; 605*404b540aSrobert 606*404b540aSrobert _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2) 607*404b540aSrobert : _Base(__e1, __e2) {} 608*404b540aSrobert }; 609*404b540aSrobert 610*404b540aSrobert template<class _Oper, class _Dom> 611*404b540aSrobert struct _BinClos<_Oper, _ValArray, _Expr, typename _Dom::value_type, _Dom> 612*404b540aSrobert : _BinBase<_Oper, valarray<typename _Dom::value_type>,_Dom> 613*404b540aSrobert { 614*404b540aSrobert typedef typename _Dom::value_type _Tp; 615*404b540aSrobert typedef _BinBase<_Oper, valarray<_Tp>, _Dom> _Base; 616*404b540aSrobert typedef typename _Base::value_type value_type; 617*404b540aSrobert 618*404b540aSrobert _BinClos(const valarray<_Tp>& __e1, const _Dom& __e2) 619*404b540aSrobert : _Base(__e1, __e2) {} 620*404b540aSrobert }; 621*404b540aSrobert 622*404b540aSrobert template<class _Oper, class _Dom> 623*404b540aSrobert struct _BinClos<_Oper, _Expr, _Constant, _Dom, typename _Dom::value_type> 624*404b540aSrobert : _BinBase2<_Oper, _Dom> 625*404b540aSrobert { 626*404b540aSrobert typedef typename _Dom::value_type _Tp; 627*404b540aSrobert typedef _BinBase2<_Oper,_Dom> _Base; 628*404b540aSrobert typedef typename _Base::value_type value_type; 629*404b540aSrobert 630*404b540aSrobert _BinClos(const _Dom& __e1, const _Tp& __e2) : _Base(__e1, __e2) {} 631*404b540aSrobert }; 632*404b540aSrobert 633*404b540aSrobert template<class _Oper, class _Dom> 634*404b540aSrobert struct _BinClos<_Oper, _Constant, _Expr, typename _Dom::value_type, _Dom> 635*404b540aSrobert : _BinBase1<_Oper, _Dom> 636*404b540aSrobert { 637*404b540aSrobert typedef typename _Dom::value_type _Tp; 638*404b540aSrobert typedef _BinBase1<_Oper, _Dom> _Base; 639*404b540aSrobert typedef typename _Base::value_type value_type; 640*404b540aSrobert 641*404b540aSrobert _BinClos(const _Tp& __e1, const _Dom& __e2) : _Base(__e1, __e2) {} 642*404b540aSrobert }; 643*404b540aSrobert 644*404b540aSrobert template<class _Oper, typename _Tp> 645*404b540aSrobert struct _BinClos<_Oper, _ValArray, _Constant, _Tp, _Tp> 646*404b540aSrobert : _BinBase2<_Oper, valarray<_Tp> > 647*404b540aSrobert { 648*404b540aSrobert typedef _BinBase2<_Oper,valarray<_Tp> > _Base; 649*404b540aSrobert typedef typename _Base::value_type value_type; 650*404b540aSrobert 651*404b540aSrobert _BinClos(const valarray<_Tp>& __v, const _Tp& __t) : _Base(__v, __t) {} 652*404b540aSrobert }; 653*404b540aSrobert 654*404b540aSrobert template<class _Oper, typename _Tp> 655*404b540aSrobert struct _BinClos<_Oper, _Constant, _ValArray, _Tp, _Tp> 656*404b540aSrobert : _BinBase1<_Oper, valarray<_Tp> > 657*404b540aSrobert { 658*404b540aSrobert typedef _BinBase1<_Oper, valarray<_Tp> > _Base; 659*404b540aSrobert typedef typename _Base::value_type value_type; 660*404b540aSrobert 661*404b540aSrobert _BinClos(const _Tp& __t, const valarray<_Tp>& __v) : _Base(__t, __v) {} 662*404b540aSrobert }; 663*404b540aSrobert 664*404b540aSrobert // 665*404b540aSrobert // slice_array closure. 666*404b540aSrobert // 667*404b540aSrobert template<typename _Dom> 668*404b540aSrobert class _SBase 669*404b540aSrobert { 670*404b540aSrobert public: 671*404b540aSrobert typedef typename _Dom::value_type value_type; 672*404b540aSrobert 673*404b540aSrobert _SBase (const _Dom& __e, const slice& __s) 674*404b540aSrobert : _M_expr (__e), _M_slice (__s) {} 675*404b540aSrobert 676*404b540aSrobert value_type 677*404b540aSrobert operator[] (size_t __i) const 678*404b540aSrobert { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; } 679*404b540aSrobert 680*404b540aSrobert size_t 681*404b540aSrobert size() const 682*404b540aSrobert { return _M_slice.size (); } 683*404b540aSrobert 684*404b540aSrobert private: 685*404b540aSrobert const _Dom& _M_expr; 686*404b540aSrobert const slice& _M_slice; 687*404b540aSrobert }; 688*404b540aSrobert 689*404b540aSrobert template<typename _Tp> 690*404b540aSrobert class _SBase<_Array<_Tp> > 691*404b540aSrobert { 692*404b540aSrobert public: 693*404b540aSrobert typedef _Tp value_type; 694*404b540aSrobert 695*404b540aSrobert _SBase (_Array<_Tp> __a, const slice& __s) 696*404b540aSrobert : _M_array (__a._M_data+__s.start()), _M_size (__s.size()), 697*404b540aSrobert _M_stride (__s.stride()) {} 698*404b540aSrobert 699*404b540aSrobert value_type 700*404b540aSrobert operator[] (size_t __i) const 701*404b540aSrobert { return _M_array._M_data[__i * _M_stride]; } 702*404b540aSrobert 703*404b540aSrobert size_t 704*404b540aSrobert size() const 705*404b540aSrobert { return _M_size; } 706*404b540aSrobert 707*404b540aSrobert private: 708*404b540aSrobert const _Array<_Tp> _M_array; 709*404b540aSrobert const size_t _M_size; 710*404b540aSrobert const size_t _M_stride; 711*404b540aSrobert }; 712*404b540aSrobert 713*404b540aSrobert template<class _Dom> 714*404b540aSrobert struct _SClos<_Expr, _Dom> 715*404b540aSrobert : _SBase<_Dom> 716*404b540aSrobert { 717*404b540aSrobert typedef _SBase<_Dom> _Base; 718*404b540aSrobert typedef typename _Base::value_type value_type; 719*404b540aSrobert 720*404b540aSrobert _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {} 721*404b540aSrobert }; 722*404b540aSrobert 723*404b540aSrobert template<typename _Tp> 724*404b540aSrobert struct _SClos<_ValArray, _Tp> 725*404b540aSrobert : _SBase<_Array<_Tp> > 726*404b540aSrobert { 727*404b540aSrobert typedef _SBase<_Array<_Tp> > _Base; 728*404b540aSrobert typedef _Tp value_type; 729*404b540aSrobert 730*404b540aSrobert _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {} 731*404b540aSrobert }; 732*404b540aSrobert 733*404b540aSrobert _GLIBCXX_END_NAMESPACE 734*404b540aSrobert 735*404b540aSrobert #endif /* _CPP_VALARRAY_BEFORE_H */ 736