1132720Skan// The template and inlines for the -*- C++ -*- internal _Meta class. 2132720Skan 3169691Skan// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 4169691Skan// Free Software Foundation, Inc. 5132720Skan// 6132720Skan// This file is part of the GNU ISO C++ Library. This library is free 7132720Skan// software; you can redistribute it and/or modify it under the 8132720Skan// terms of the GNU General Public License as published by the 9132720Skan// Free Software Foundation; either version 2, or (at your option) 10132720Skan// any later version. 11132720Skan 12132720Skan// This library is distributed in the hope that it will be useful, 13132720Skan// but WITHOUT ANY WARRANTY; without even the implied warranty of 14132720Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15132720Skan// GNU General Public License for more details. 16132720Skan 17132720Skan// You should have received a copy of the GNU General Public License along 18132720Skan// with this library; see the file COPYING. If not, write to the Free 19169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20132720Skan// USA. 21132720Skan 22132720Skan// As a special exception, you may use this file as part of a free software 23132720Skan// library without restriction. Specifically, if other files instantiate 24132720Skan// templates or use macros or inline functions from this file, or you compile 25132720Skan// this file and link it with other files to produce an executable, this 26132720Skan// file does not by itself cause the resulting executable to be covered by 27132720Skan// the GNU General Public License. This exception does not however 28132720Skan// invalidate any other reasons why the executable file might be covered by 29132720Skan// the GNU General Public License. 30132720Skan 31169691Skan/** @file valarray_before.h 32132720Skan * This is an internal header file, included by other library headers. 33132720Skan * You should not attempt to use it directly. 34132720Skan */ 35132720Skan 36169691Skan// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr> 37169691Skan 38132720Skan#ifndef _VALARRAY_BEFORE_H 39132720Skan#define _VALARRAY_BEFORE_H 1 40132720Skan 41132720Skan#pragma GCC system_header 42132720Skan 43132720Skan#include <bits/slice_array.h> 44132720Skan 45169691Skan_GLIBCXX_BEGIN_NAMESPACE(std) 46169691Skan 47132720Skan // 48132720Skan // Implementing a loosened valarray return value is tricky. 49132720Skan // First we need to meet 26.3.1/3: we should not add more than 50132720Skan // two levels of template nesting. Therefore we resort to template 51132720Skan // template to "flatten" loosened return value types. 52132720Skan // At some point we use partial specialization to remove one level 53132720Skan // template nesting due to _Expr<> 54132720Skan // 55132720Skan 56132720Skan // This class is NOT defined. It doesn't need to. 57132720Skan template<typename _Tp1, typename _Tp2> class _Constant; 58132720Skan 59132720Skan // Implementations of unary functions applied to valarray<>s. 60132720Skan // I use hard-coded object functions here instead of a generic 61132720Skan // approach like pointers to function: 62132720Skan // 1) correctness: some functions take references, others values. 63132720Skan // we can't deduce the correct type afterwards. 64132720Skan // 2) efficiency -- object functions can be easily inlined 65132720Skan // 3) be Koenig-lookup-friendly 66132720Skan 67132720Skan struct __abs 68132720Skan { 69132720Skan template<typename _Tp> 70169691Skan _Tp operator()(const _Tp& __t) const 71169691Skan { return abs(__t); } 72132720Skan }; 73132720Skan 74132720Skan struct __cos 75132720Skan { 76132720Skan template<typename _Tp> 77169691Skan _Tp operator()(const _Tp& __t) const 78169691Skan { return cos(__t); } 79132720Skan }; 80132720Skan 81132720Skan struct __acos 82132720Skan { 83132720Skan template<typename _Tp> 84169691Skan _Tp operator()(const _Tp& __t) const 85169691Skan { return acos(__t); } 86132720Skan }; 87132720Skan 88132720Skan struct __cosh 89132720Skan { 90132720Skan template<typename _Tp> 91169691Skan _Tp operator()(const _Tp& __t) const 92169691Skan { return cosh(__t); } 93132720Skan }; 94132720Skan 95132720Skan struct __sin 96132720Skan { 97132720Skan template<typename _Tp> 98169691Skan _Tp operator()(const _Tp& __t) const 99169691Skan { return sin(__t); } 100132720Skan }; 101132720Skan 102132720Skan struct __asin 103132720Skan { 104132720Skan template<typename _Tp> 105169691Skan _Tp operator()(const _Tp& __t) const 106169691Skan { return asin(__t); } 107132720Skan }; 108132720Skan 109132720Skan struct __sinh 110132720Skan { 111132720Skan template<typename _Tp> 112169691Skan _Tp operator()(const _Tp& __t) const 113169691Skan { return sinh(__t); } 114132720Skan }; 115132720Skan 116132720Skan struct __tan 117132720Skan { 118132720Skan template<typename _Tp> 119169691Skan _Tp operator()(const _Tp& __t) const 120169691Skan { return tan(__t); } 121132720Skan }; 122132720Skan 123132720Skan struct __atan 124132720Skan { 125132720Skan template<typename _Tp> 126169691Skan _Tp operator()(const _Tp& __t) const 127169691Skan { return atan(__t); } 128132720Skan }; 129132720Skan 130132720Skan struct __tanh 131132720Skan { 132132720Skan template<typename _Tp> 133169691Skan _Tp operator()(const _Tp& __t) const 134169691Skan { return tanh(__t); } 135132720Skan }; 136132720Skan 137132720Skan struct __exp 138132720Skan { 139132720Skan template<typename _Tp> 140169691Skan _Tp operator()(const _Tp& __t) const 141169691Skan { return exp(__t); } 142132720Skan }; 143132720Skan 144132720Skan struct __log 145132720Skan { 146132720Skan template<typename _Tp> 147169691Skan _Tp operator()(const _Tp& __t) const 148169691Skan { return log(__t); } 149132720Skan }; 150132720Skan 151132720Skan struct __log10 152132720Skan { 153132720Skan template<typename _Tp> 154169691Skan _Tp operator()(const _Tp& __t) const 155169691Skan { return log10(__t); } 156132720Skan }; 157132720Skan 158132720Skan struct __sqrt 159132720Skan { 160132720Skan template<typename _Tp> 161169691Skan _Tp operator()(const _Tp& __t) const 162169691Skan { return sqrt(__t); } 163132720Skan }; 164132720Skan 165132720Skan // In the past, we used to tailor operator applications semantics 166132720Skan // to the specialization of standard function objects (i.e. plus<>, etc.) 167132720Skan // That is incorrect. Therefore we provide our own surrogates. 168132720Skan 169132720Skan struct __unary_plus 170132720Skan { 171132720Skan template<typename _Tp> 172169691Skan _Tp operator()(const _Tp& __t) const 173169691Skan { return +__t; } 174132720Skan }; 175132720Skan 176132720Skan struct __negate 177132720Skan { 178132720Skan template<typename _Tp> 179169691Skan _Tp operator()(const _Tp& __t) const 180169691Skan { return -__t; } 181132720Skan }; 182132720Skan 183132720Skan struct __bitwise_not 184132720Skan { 185132720Skan template<typename _Tp> 186169691Skan _Tp operator()(const _Tp& __t) const 187169691Skan { return ~__t; } 188132720Skan }; 189132720Skan 190132720Skan struct __plus 191132720Skan { 192132720Skan template<typename _Tp> 193132720Skan _Tp operator()(const _Tp& __x, const _Tp& __y) const 194132720Skan { return __x + __y; } 195132720Skan }; 196132720Skan 197132720Skan struct __minus 198132720Skan { 199132720Skan template<typename _Tp> 200132720Skan _Tp operator()(const _Tp& __x, const _Tp& __y) const 201132720Skan { return __x - __y; } 202132720Skan }; 203132720Skan 204132720Skan struct __multiplies 205132720Skan { 206132720Skan template<typename _Tp> 207132720Skan _Tp operator()(const _Tp& __x, const _Tp& __y) const 208132720Skan { return __x * __y; } 209132720Skan }; 210132720Skan 211132720Skan struct __divides 212132720Skan { 213132720Skan template<typename _Tp> 214132720Skan _Tp operator()(const _Tp& __x, const _Tp& __y) const 215132720Skan { return __x / __y; } 216132720Skan }; 217132720Skan 218132720Skan struct __modulus 219132720Skan { 220132720Skan template<typename _Tp> 221132720Skan _Tp operator()(const _Tp& __x, const _Tp& __y) const 222132720Skan { return __x % __y; } 223132720Skan }; 224132720Skan 225132720Skan struct __bitwise_xor 226132720Skan { 227132720Skan template<typename _Tp> 228132720Skan _Tp operator()(const _Tp& __x, const _Tp& __y) const 229132720Skan { return __x ^ __y; } 230132720Skan }; 231132720Skan 232132720Skan struct __bitwise_and 233132720Skan { 234132720Skan template<typename _Tp> 235132720Skan _Tp operator()(const _Tp& __x, const _Tp& __y) const 236132720Skan { return __x & __y; } 237132720Skan }; 238132720Skan 239132720Skan struct __bitwise_or 240132720Skan { 241132720Skan template<typename _Tp> 242132720Skan _Tp operator()(const _Tp& __x, const _Tp& __y) const 243132720Skan { return __x | __y; } 244132720Skan }; 245132720Skan 246132720Skan struct __shift_left 247132720Skan { 248132720Skan template<typename _Tp> 249132720Skan _Tp operator()(const _Tp& __x, const _Tp& __y) const 250132720Skan { return __x << __y; } 251132720Skan }; 252132720Skan 253132720Skan struct __shift_right 254132720Skan { 255132720Skan template<typename _Tp> 256132720Skan _Tp operator()(const _Tp& __x, const _Tp& __y) const 257132720Skan { return __x >> __y; } 258132720Skan }; 259132720Skan 260132720Skan struct __logical_and 261132720Skan { 262132720Skan template<typename _Tp> 263132720Skan bool operator()(const _Tp& __x, const _Tp& __y) const 264132720Skan { return __x && __y; } 265132720Skan }; 266132720Skan 267132720Skan struct __logical_or 268132720Skan { 269132720Skan template<typename _Tp> 270132720Skan bool operator()(const _Tp& __x, const _Tp& __y) const 271132720Skan { return __x || __y; } 272132720Skan }; 273132720Skan 274132720Skan struct __logical_not 275132720Skan { 276132720Skan template<typename _Tp> 277132720Skan bool operator()(const _Tp& __x) const { return !__x; } 278132720Skan }; 279132720Skan 280132720Skan struct __equal_to 281132720Skan { 282132720Skan template<typename _Tp> 283132720Skan bool operator()(const _Tp& __x, const _Tp& __y) const 284132720Skan { return __x == __y; } 285132720Skan }; 286132720Skan 287132720Skan struct __not_equal_to 288132720Skan { 289132720Skan template<typename _Tp> 290132720Skan bool operator()(const _Tp& __x, const _Tp& __y) const 291132720Skan { return __x != __y; } 292132720Skan }; 293132720Skan 294132720Skan struct __less 295132720Skan { 296132720Skan template<typename _Tp> 297132720Skan bool operator()(const _Tp& __x, const _Tp& __y) const 298132720Skan { return __x < __y; } 299132720Skan }; 300132720Skan 301132720Skan struct __greater 302132720Skan { 303132720Skan template<typename _Tp> 304132720Skan bool operator()(const _Tp& __x, const _Tp& __y) const 305132720Skan { return __x > __y; } 306132720Skan }; 307132720Skan 308132720Skan struct __less_equal 309132720Skan { 310132720Skan template<typename _Tp> 311132720Skan bool operator()(const _Tp& __x, const _Tp& __y) const 312132720Skan { return __x <= __y; } 313132720Skan }; 314132720Skan 315132720Skan struct __greater_equal 316132720Skan { 317132720Skan template<typename _Tp> 318132720Skan bool operator()(const _Tp& __x, const _Tp& __y) const 319132720Skan { return __x >= __y; } 320132720Skan }; 321132720Skan 322132720Skan // The few binary functions we miss. 323132720Skan struct __atan2 324132720Skan { 325132720Skan template<typename _Tp> 326132720Skan _Tp operator()(const _Tp& __x, const _Tp& __y) const 327132720Skan { return atan2(__x, __y); } 328132720Skan }; 329132720Skan 330132720Skan struct __pow 331132720Skan { 332132720Skan template<typename _Tp> 333132720Skan _Tp operator()(const _Tp& __x, const _Tp& __y) const 334132720Skan { return pow(__x, __y); } 335132720Skan }; 336132720Skan 337132720Skan 338132720Skan // We need these bits in order to recover the return type of 339132720Skan // some functions/operators now that we're no longer using 340132720Skan // function templates. 341132720Skan template<typename, typename _Tp> 342132720Skan struct __fun 343132720Skan { 344132720Skan typedef _Tp result_type; 345132720Skan }; 346132720Skan 347132720Skan // several specializations for relational operators. 348132720Skan template<typename _Tp> 349132720Skan struct __fun<__logical_not, _Tp> 350132720Skan { 351132720Skan typedef bool result_type; 352132720Skan }; 353132720Skan 354132720Skan template<typename _Tp> 355132720Skan struct __fun<__logical_and, _Tp> 356132720Skan { 357132720Skan typedef bool result_type; 358132720Skan }; 359132720Skan 360132720Skan template<typename _Tp> 361132720Skan struct __fun<__logical_or, _Tp> 362132720Skan { 363132720Skan typedef bool result_type; 364132720Skan }; 365132720Skan 366132720Skan template<typename _Tp> 367132720Skan struct __fun<__less, _Tp> 368132720Skan { 369132720Skan typedef bool result_type; 370132720Skan }; 371132720Skan 372132720Skan template<typename _Tp> 373132720Skan struct __fun<__greater, _Tp> 374132720Skan { 375132720Skan typedef bool result_type; 376132720Skan }; 377132720Skan 378132720Skan template<typename _Tp> 379132720Skan struct __fun<__less_equal, _Tp> 380132720Skan { 381132720Skan typedef bool result_type; 382132720Skan }; 383132720Skan 384132720Skan template<typename _Tp> 385132720Skan struct __fun<__greater_equal, _Tp> 386132720Skan { 387132720Skan typedef bool result_type; 388132720Skan }; 389132720Skan 390132720Skan template<typename _Tp> 391132720Skan struct __fun<__equal_to, _Tp> 392132720Skan { 393132720Skan typedef bool result_type; 394132720Skan }; 395132720Skan 396132720Skan template<typename _Tp> 397132720Skan struct __fun<__not_equal_to, _Tp> 398132720Skan { 399132720Skan typedef bool result_type; 400132720Skan }; 401132720Skan 402169691Skan // 403169691Skan // Apply function taking a value/const reference closure 404169691Skan // 405132720Skan 406132720Skan template<typename _Dom, typename _Arg> 407132720Skan class _FunBase 408132720Skan { 409132720Skan public: 410132720Skan typedef typename _Dom::value_type value_type; 411132720Skan 412132720Skan _FunBase(const _Dom& __e, value_type __f(_Arg)) 413169691Skan : _M_expr(__e), _M_func(__f) {} 414132720Skan 415132720Skan value_type operator[](size_t __i) const 416132720Skan { return _M_func (_M_expr[__i]); } 417132720Skan 418132720Skan size_t size() const { return _M_expr.size ();} 419132720Skan 420132720Skan private: 421169691Skan const _Dom& _M_expr; 422169691Skan value_type (*_M_func)(_Arg); 423132720Skan }; 424132720Skan 425132720Skan template<class _Dom> 426132720Skan struct _ValFunClos<_Expr,_Dom> : _FunBase<_Dom, typename _Dom::value_type> 427132720Skan { 428132720Skan typedef _FunBase<_Dom, typename _Dom::value_type> _Base; 429132720Skan typedef typename _Base::value_type value_type; 430132720Skan typedef value_type _Tp; 431132720Skan 432132720Skan _ValFunClos(const _Dom& __e, _Tp __f(_Tp)) : _Base(__e, __f) {} 433132720Skan }; 434132720Skan 435132720Skan template<typename _Tp> 436132720Skan struct _ValFunClos<_ValArray,_Tp> : _FunBase<valarray<_Tp>, _Tp> 437132720Skan { 438132720Skan typedef _FunBase<valarray<_Tp>, _Tp> _Base; 439132720Skan typedef _Tp value_type; 440132720Skan 441132720Skan _ValFunClos(const valarray<_Tp>& __v, _Tp __f(_Tp)) : _Base(__v, __f) {} 442132720Skan }; 443132720Skan 444132720Skan template<class _Dom> 445169691Skan struct _RefFunClos<_Expr, _Dom> 446169691Skan : _FunBase<_Dom, const typename _Dom::value_type&> 447132720Skan { 448132720Skan typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base; 449132720Skan typedef typename _Base::value_type value_type; 450132720Skan typedef value_type _Tp; 451132720Skan 452132720Skan _RefFunClos(const _Dom& __e, _Tp __f(const _Tp&)) 453169691Skan : _Base(__e, __f) {} 454132720Skan }; 455132720Skan 456132720Skan template<typename _Tp> 457169691Skan struct _RefFunClos<_ValArray, _Tp> 458169691Skan : _FunBase<valarray<_Tp>, const _Tp&> 459132720Skan { 460132720Skan typedef _FunBase<valarray<_Tp>, const _Tp&> _Base; 461132720Skan typedef _Tp value_type; 462132720Skan 463132720Skan _RefFunClos(const valarray<_Tp>& __v, _Tp __f(const _Tp&)) 464169691Skan : _Base(__v, __f) {} 465132720Skan }; 466132720Skan 467132720Skan // 468132720Skan // Unary expression closure. 469132720Skan // 470132720Skan 471132720Skan template<class _Oper, class _Arg> 472132720Skan class _UnBase 473132720Skan { 474132720Skan public: 475132720Skan typedef typename _Arg::value_type _Vt; 476132720Skan typedef typename __fun<_Oper, _Vt>::result_type value_type; 477132720Skan 478132720Skan _UnBase(const _Arg& __e) : _M_expr(__e) {} 479132720Skan 480132720Skan value_type operator[](size_t __i) const 481132720Skan { return _Oper()(_M_expr[__i]); } 482132720Skan 483132720Skan size_t size() const { return _M_expr.size(); } 484169691Skan 485132720Skan private: 486132720Skan const _Arg& _M_expr; 487132720Skan }; 488132720Skan 489132720Skan template<class _Oper, class _Dom> 490169691Skan struct _UnClos<_Oper, _Expr, _Dom> 491169691Skan : _UnBase<_Oper, _Dom> 492132720Skan { 493132720Skan typedef _Dom _Arg; 494132720Skan typedef _UnBase<_Oper, _Dom> _Base; 495132720Skan typedef typename _Base::value_type value_type; 496132720Skan 497132720Skan _UnClos(const _Arg& __e) : _Base(__e) {} 498132720Skan }; 499132720Skan 500132720Skan template<class _Oper, typename _Tp> 501169691Skan struct _UnClos<_Oper, _ValArray, _Tp> 502169691Skan : _UnBase<_Oper, valarray<_Tp> > 503132720Skan { 504132720Skan typedef valarray<_Tp> _Arg; 505132720Skan typedef _UnBase<_Oper, valarray<_Tp> > _Base; 506132720Skan typedef typename _Base::value_type value_type; 507132720Skan 508132720Skan _UnClos(const _Arg& __e) : _Base(__e) {} 509132720Skan }; 510132720Skan 511132720Skan 512132720Skan // 513132720Skan // Binary expression closure. 514132720Skan // 515132720Skan 516132720Skan template<class _Oper, class _FirstArg, class _SecondArg> 517132720Skan class _BinBase 518132720Skan { 519132720Skan public: 520169691Skan typedef typename _FirstArg::value_type _Vt; 521169691Skan typedef typename __fun<_Oper, _Vt>::result_type value_type; 522132720Skan 523132720Skan _BinBase(const _FirstArg& __e1, const _SecondArg& __e2) 524169691Skan : _M_expr1(__e1), _M_expr2(__e2) {} 525132720Skan 526132720Skan value_type operator[](size_t __i) const 527132720Skan { return _Oper()(_M_expr1[__i], _M_expr2[__i]); } 528132720Skan 529132720Skan size_t size() const { return _M_expr1.size(); } 530132720Skan 531132720Skan private: 532132720Skan const _FirstArg& _M_expr1; 533132720Skan const _SecondArg& _M_expr2; 534132720Skan }; 535132720Skan 536132720Skan 537132720Skan template<class _Oper, class _Clos> 538132720Skan class _BinBase2 539132720Skan { 540132720Skan public: 541132720Skan typedef typename _Clos::value_type _Vt; 542132720Skan typedef typename __fun<_Oper, _Vt>::result_type value_type; 543132720Skan 544132720Skan _BinBase2(const _Clos& __e, const _Vt& __t) 545169691Skan : _M_expr1(__e), _M_expr2(__t) {} 546132720Skan 547132720Skan value_type operator[](size_t __i) const 548132720Skan { return _Oper()(_M_expr1[__i], _M_expr2); } 549132720Skan 550132720Skan size_t size() const { return _M_expr1.size(); } 551132720Skan 552132720Skan private: 553132720Skan const _Clos& _M_expr1; 554132720Skan const _Vt& _M_expr2; 555132720Skan }; 556132720Skan 557132720Skan template<class _Oper, class _Clos> 558132720Skan class _BinBase1 559132720Skan { 560132720Skan public: 561132720Skan typedef typename _Clos::value_type _Vt; 562132720Skan typedef typename __fun<_Oper, _Vt>::result_type value_type; 563132720Skan 564132720Skan _BinBase1(const _Vt& __t, const _Clos& __e) 565169691Skan : _M_expr1(__t), _M_expr2(__e) {} 566132720Skan 567132720Skan value_type operator[](size_t __i) const 568132720Skan { return _Oper()(_M_expr1, _M_expr2[__i]); } 569132720Skan 570132720Skan size_t size() const { return _M_expr2.size(); } 571132720Skan 572132720Skan private: 573132720Skan const _Vt& _M_expr1; 574132720Skan const _Clos& _M_expr2; 575132720Skan }; 576132720Skan 577132720Skan template<class _Oper, class _Dom1, class _Dom2> 578132720Skan struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2> 579169691Skan : _BinBase<_Oper, _Dom1, _Dom2> 580132720Skan { 581169691Skan typedef _BinBase<_Oper, _Dom1, _Dom2> _Base; 582132720Skan typedef typename _Base::value_type value_type; 583132720Skan 584132720Skan _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {} 585132720Skan }; 586132720Skan 587132720Skan template<class _Oper, typename _Tp> 588169691Skan struct _BinClos<_Oper,_ValArray, _ValArray, _Tp, _Tp> 589169691Skan : _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> > 590132720Skan { 591169691Skan typedef _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> > _Base; 592169691Skan typedef typename _Base::value_type value_type; 593132720Skan 594132720Skan _BinClos(const valarray<_Tp>& __v, const valarray<_Tp>& __w) 595169691Skan : _Base(__v, __w) {} 596132720Skan }; 597132720Skan 598132720Skan template<class _Oper, class _Dom> 599169691Skan struct _BinClos<_Oper, _Expr, _ValArray, _Dom, typename _Dom::value_type> 600169691Skan : _BinBase<_Oper, _Dom, valarray<typename _Dom::value_type> > 601132720Skan { 602132720Skan typedef typename _Dom::value_type _Tp; 603132720Skan typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base; 604132720Skan typedef typename _Base::value_type value_type; 605132720Skan 606132720Skan _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2) 607169691Skan : _Base(__e1, __e2) {} 608132720Skan }; 609132720Skan 610132720Skan template<class _Oper, class _Dom> 611169691Skan struct _BinClos<_Oper, _ValArray, _Expr, typename _Dom::value_type, _Dom> 612169691Skan : _BinBase<_Oper, valarray<typename _Dom::value_type>,_Dom> 613132720Skan { 614132720Skan typedef typename _Dom::value_type _Tp; 615169691Skan typedef _BinBase<_Oper, valarray<_Tp>, _Dom> _Base; 616132720Skan typedef typename _Base::value_type value_type; 617132720Skan 618132720Skan _BinClos(const valarray<_Tp>& __e1, const _Dom& __e2) 619169691Skan : _Base(__e1, __e2) {} 620132720Skan }; 621132720Skan 622132720Skan template<class _Oper, class _Dom> 623169691Skan struct _BinClos<_Oper, _Expr, _Constant, _Dom, typename _Dom::value_type> 624169691Skan : _BinBase2<_Oper, _Dom> 625132720Skan { 626132720Skan typedef typename _Dom::value_type _Tp; 627132720Skan typedef _BinBase2<_Oper,_Dom> _Base; 628132720Skan typedef typename _Base::value_type value_type; 629132720Skan 630132720Skan _BinClos(const _Dom& __e1, const _Tp& __e2) : _Base(__e1, __e2) {} 631132720Skan }; 632132720Skan 633132720Skan template<class _Oper, class _Dom> 634169691Skan struct _BinClos<_Oper, _Constant, _Expr, typename _Dom::value_type, _Dom> 635169691Skan : _BinBase1<_Oper, _Dom> 636132720Skan { 637132720Skan typedef typename _Dom::value_type _Tp; 638169691Skan typedef _BinBase1<_Oper, _Dom> _Base; 639132720Skan typedef typename _Base::value_type value_type; 640132720Skan 641132720Skan _BinClos(const _Tp& __e1, const _Dom& __e2) : _Base(__e1, __e2) {} 642132720Skan }; 643132720Skan 644132720Skan template<class _Oper, typename _Tp> 645169691Skan struct _BinClos<_Oper, _ValArray, _Constant, _Tp, _Tp> 646169691Skan : _BinBase2<_Oper, valarray<_Tp> > 647132720Skan { 648132720Skan typedef _BinBase2<_Oper,valarray<_Tp> > _Base; 649132720Skan typedef typename _Base::value_type value_type; 650132720Skan 651132720Skan _BinClos(const valarray<_Tp>& __v, const _Tp& __t) : _Base(__v, __t) {} 652132720Skan }; 653132720Skan 654132720Skan template<class _Oper, typename _Tp> 655169691Skan struct _BinClos<_Oper, _Constant, _ValArray, _Tp, _Tp> 656169691Skan : _BinBase1<_Oper, valarray<_Tp> > 657132720Skan { 658169691Skan typedef _BinBase1<_Oper, valarray<_Tp> > _Base; 659132720Skan typedef typename _Base::value_type value_type; 660132720Skan 661132720Skan _BinClos(const _Tp& __t, const valarray<_Tp>& __v) : _Base(__t, __v) {} 662132720Skan }; 663132720Skan 664132720Skan // 665132720Skan // slice_array closure. 666132720Skan // 667169691Skan template<typename _Dom> 668169691Skan class _SBase 669169691Skan { 670132720Skan public: 671169691Skan typedef typename _Dom::value_type value_type; 672169691Skan 673169691Skan _SBase (const _Dom& __e, const slice& __s) 674169691Skan : _M_expr (__e), _M_slice (__s) {} 675169691Skan 676169691Skan value_type 677169691Skan operator[] (size_t __i) const 678169691Skan { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; } 679169691Skan 680169691Skan size_t 681169691Skan size() const 682169691Skan { return _M_slice.size (); } 683132720Skan 684132720Skan private: 685169691Skan const _Dom& _M_expr; 686169691Skan const slice& _M_slice; 687132720Skan }; 688132720Skan 689169691Skan template<typename _Tp> 690169691Skan class _SBase<_Array<_Tp> > 691169691Skan { 692132720Skan public: 693169691Skan typedef _Tp value_type; 694169691Skan 695169691Skan _SBase (_Array<_Tp> __a, const slice& __s) 696169691Skan : _M_array (__a._M_data+__s.start()), _M_size (__s.size()), 697169691Skan _M_stride (__s.stride()) {} 698169691Skan 699169691Skan value_type 700169691Skan operator[] (size_t __i) const 701169691Skan { return _M_array._M_data[__i * _M_stride]; } 702169691Skan 703169691Skan size_t 704169691Skan size() const 705169691Skan { return _M_size; } 706132720Skan 707132720Skan private: 708169691Skan const _Array<_Tp> _M_array; 709169691Skan const size_t _M_size; 710169691Skan const size_t _M_stride; 711132720Skan }; 712132720Skan 713169691Skan template<class _Dom> 714169691Skan struct _SClos<_Expr, _Dom> 715169691Skan : _SBase<_Dom> 716169691Skan { 717169691Skan typedef _SBase<_Dom> _Base; 718169691Skan typedef typename _Base::value_type value_type; 719169691Skan 720169691Skan _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {} 721132720Skan }; 722132720Skan 723169691Skan template<typename _Tp> 724169691Skan struct _SClos<_ValArray, _Tp> 725169691Skan : _SBase<_Array<_Tp> > 726169691Skan { 727169691Skan typedef _SBase<_Array<_Tp> > _Base; 728169691Skan typedef _Tp value_type; 729169691Skan 730169691Skan _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {} 731132720Skan }; 732132720Skan 733169691Skan_GLIBCXX_END_NAMESPACE 734132720Skan 735132720Skan#endif /* _CPP_VALARRAY_BEFORE_H */ 736