1 // The template and inlines for the -*- C++ -*- internal _Array helper class. 2 3 // Copyright (C) 1997-1999 Cygnus Solutions 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 2, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // You should have received a copy of the GNU General Public License along 17 // with this library; see the file COPYING. If not, write to the Free 18 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 19 // USA. 20 21 // As a special exception, you may use this file as part of a free software 22 // library without restriction. Specifically, if other files instantiate 23 // templates or use macros or inline functions from this file, or you compile 24 // this file and link it with other files to produce an executable, this 25 // file does not by itself cause the resulting executable to be covered by 26 // the GNU General Public License. This exception does not however 27 // invalidate any other reasons why the executable file might be covered by 28 // the GNU General Public License. 29 30 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> 31 32 #ifndef __VALARRAY_ARRAY__ 33 #define __VALARRAY_ARRAY__ 34 35 #include <cstdlib> 36 #include <cstring> 37 38 extern "C++" { 39 40 // 41 // Helper functions on raw pointers 42 // 43 44 // fill plain array __a[<__n>] with __t 45 template<typename _Tp> 46 inline void 47 __valarray_fill (_Tp* __restrict__ __a, size_t __n, const _Tp& __t) 48 { while (__n--) *__a++ = __t; } 49 50 // fill strided array __a[<__n-1 : __s>] with __t 51 template<typename _Tp> 52 inline void 53 __valarray_fill (_Tp* __restrict__ __a, size_t __n, 54 size_t __s, const _Tp& __t) 55 { for (size_t __i=0; __i<__n; ++__i, __a+=__s) *__a = __t; } 56 57 // fill indirect array __a[__i[<__n>]] with __i 58 template<typename _Tp> 59 inline void 60 __valarray_fill(_Tp* __restrict__ __a, const size_t* __restrict__ __i, 61 size_t __n, const _Tp& __t) 62 { for (size_t __j=0; __j<__n; ++__j, ++__i) __a[*__i] = __t; } 63 64 // copy plain array __a[<__n>] in __b[<__n>] 65 template<typename _Tp> 66 inline void 67 __valarray_copy (const _Tp* __restrict__ __a, size_t __n, 68 _Tp* __restrict__ __b) 69 { memcpy (__b, __a, __n * sizeof(_Tp)); } 70 71 // copy strided array __a[<__n : __s>] in plain __b[<__n>] 72 template<typename _Tp> 73 inline void 74 __valarray_copy (const _Tp* __restrict__ __a, size_t __n, size_t __s, 75 _Tp* __restrict__ __b) 76 { for (size_t __i=0; __i<__n; ++__i, ++__b, __a += __s) *__b = *__a; } 77 78 // copy plain __a[<__n>] in strided __b[<__n : __s>] 79 template<typename _Tp> 80 inline void 81 __valarray_copy (const _Tp* __restrict__ __a, _Tp* __restrict__ __b, 82 size_t __n, size_t __s) 83 { for (size_t __i=0; __i<__n; ++__i, ++__a, __b+=__s) *__b = *__a; } 84 85 // copy indexed __a[__i[<__n>]] in plain __b[<__n>] 86 template<typename _Tp> 87 inline void 88 __valarray_copy (const _Tp* __restrict__ __a, 89 const size_t* __restrict__ __i, 90 _Tp* __restrict__ __b, size_t __n) 91 { for (size_t __j=0; __j<__n; ++__j, ++__b, ++__i) *__b = __a[*__i]; } 92 93 // copy plain __a[<__n>] in indexed __b[__i[<__n>]] 94 template<typename _Tp> 95 inline void 96 __valarray_copy (const _Tp* __restrict__ __a, size_t __n, 97 _Tp* __restrict__ __b, const size_t* __restrict__ __i) 98 { for (size_t __j=0; __j<__n; ++__j, ++__a, ++__i) __b[*__i] = *__a; } 99 100 // 101 // Helper class _Array, first layer of valarray abstraction. 102 // All operations on valarray should be forwarded to this class 103 // whenever possible. -- gdr 104 // 105 106 template<typename _Tp> struct _Array { 107 108 explicit _Array (size_t); 109 explicit _Array (_Tp* const __restrict__); 110 explicit _Array (const valarray<_Tp>&); 111 _Array (const _Tp* __restrict__, size_t); 112 113 void free_data() const; 114 _Tp* begin () const; 115 116 _Tp* const __restrict__ _M_data; 117 }; 118 119 template<typename _Tp> 120 inline void 121 __valarray_fill (_Array<_Tp> __a, size_t __n, const _Tp& __t) 122 { __valarray_fill (__a._M_data, __n, __t); } 123 124 template<typename _Tp> 125 inline void 126 __valarray_fill (_Array<_Tp> __a, size_t __n, size_t __s, const _Tp& __t) 127 { __valarray_fill (__a._M_data, __n, __s, __t); } 128 129 template<typename _Tp> 130 inline void 131 __valarray_fill (_Array<_Tp> __a, _Array<size_t> __i, 132 size_t __n, const _Tp& __t) 133 { __valarray_fill (__a._M_data, __i._M_data, __n, __t); } 134 135 template<typename _Tp> 136 inline void 137 __valarray_copy (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) 138 { __valarray_copy (__a._M_data, __n, __b._M_data); } 139 140 template<typename _Tp> 141 inline void 142 __valarray_copy (_Array<_Tp> __a, size_t __n, size_t __s, _Array<_Tp> __b) 143 { __valarray_copy(__a._M_data, __n, __s, __b._M_data); } 144 145 template<typename _Tp> 146 inline void 147 __valarray_copy (_Array<_Tp> __a, _Array<_Tp> __b, size_t __n, size_t __s) 148 { __valarray_copy (__a._M_data, __b._M_data, __n, __s); } 149 150 template<typename _Tp> 151 inline void 152 __valarray_copy (_Array<_Tp> __a, _Array<size_t> __i, 153 _Array<_Tp> __b, size_t __n) 154 { __valarray_copy (__a._M_data, __i._M_data, __b._M_data, __n); } 155 156 template<typename _Tp> 157 inline void 158 __valarray_copy (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b, 159 _Array<size_t> __i) 160 { __valarray_copy (__a._M_data, __n, __b._M_data, __i._M_data); } 161 162 template<typename _Tp> 163 inline 164 _Array<_Tp>::_Array (size_t __n) : _M_data (new _Tp[__n]) {} 165 166 template<typename _Tp> 167 inline 168 _Array<_Tp>::_Array (_Tp* const __restrict__ __p) : _M_data (__p) {} 169 170 template<typename _Tp> 171 inline _Array<_Tp>::_Array (const valarray<_Tp>& __v) 172 : _M_data (__v._M_data) {} 173 174 template<typename _Tp> 175 inline 176 _Array<_Tp>::_Array (const _Tp* __restrict__ __b, size_t __s) 177 : _M_data (new _Tp[__s]) { __valarray_copy (__b, __s, _M_data); } 178 179 template<typename _Tp> 180 inline void 181 _Array<_Tp>::free_data() const { delete[] _M_data; } 182 183 template<typename _Tp> 184 inline _Tp* 185 _Array<_Tp>::begin () const 186 { return _M_data; } 187 188 #define _DEFINE_ARRAY_FUNCTION(_Op, _Name) \ 189 template<typename _Tp> \ 190 inline void \ 191 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, const _Tp& __t) \ 192 { \ 193 for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p) \ 194 *__p _Op##= __t; \ 195 } \ 196 \ 197 template<typename _Tp> \ 198 inline void \ 199 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \ 200 { \ 201 _Tp* __p (__a._M_data); \ 202 for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__p, ++__q) \ 203 *__p _Op##= *__q; \ 204 } \ 205 \ 206 template<typename _Tp, class _Dom> \ 207 void \ 208 _Array_augmented_##_Name (_Array<_Tp> __a, \ 209 const _Expr<_Dom,_Tp>& __e, size_t __n) \ 210 { \ 211 _Tp* __p (__a._M_data); \ 212 for (size_t __i=0; __i<__n; ++__i, ++__p) *__p _Op##= __e[__i]; \ 213 } \ 214 \ 215 template<typename _Tp> \ 216 inline void \ 217 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, size_t __s, \ 218 _Array<_Tp> __b) \ 219 { \ 220 _Tp* __q (__b._M_data); \ 221 for (_Tp* __p=__a._M_data; __p<__a._M_data+__s*__n; __p+=__s, ++__q) \ 222 *__p _Op##= *__q; \ 223 } \ 224 \ 225 template<typename _Tp> \ 226 inline void \ 227 _Array_augmented_##_Name (_Array<_Tp> __a, _Array<_Tp> __b, \ 228 size_t __n, size_t __s) \ 229 { \ 230 _Tp* __q (__b._M_data); \ 231 for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, __q+=__s) \ 232 *__p _Op##= *__q; \ 233 } \ 234 \ 235 template<typename _Tp, class _Dom> \ 236 void \ 237 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __s, \ 238 const _Expr<_Dom,_Tp>& __e, size_t __n) \ 239 { \ 240 _Tp* __p (__a._M_data); \ 241 for (size_t __i=0; __i<__n; ++__i, __p+=__s) *__p _Op##= __e[__i]; \ 242 } \ 243 \ 244 template<typename _Tp> \ 245 inline void \ 246 _Array_augmented_##_Name (_Array<_Tp> __a, _Array<size_t> __i, \ 247 _Array<_Tp> __b, size_t __n) \ 248 { \ 249 _Tp* __q (__b._M_data); \ 250 for (size_t* __j=__i._M_data; __j<__i._M_data+__n; ++__j, ++__q) \ 251 __a._M_data[*__j] _Op##= *__q; \ 252 } \ 253 \ 254 template<typename _Tp> \ 255 inline void \ 256 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, \ 257 _Array<_Tp> __b, _Array<size_t> __i) \ 258 { \ 259 _Tp* __p (__a._M_data); \ 260 for (size_t* __j=__i._M_data; __j<__i._M_data+__n; ++__j, ++__p) \ 261 *__p _Op##= __b._M_data[*__j]; \ 262 } \ 263 \ 264 template<typename _Tp, class _Dom> \ 265 void \ 266 _Array_augmented_##_Name (_Array<_Tp> __a, _Array<size_t> __i, \ 267 const _Expr<_Dom, _Tp>& __e, size_t __n) \ 268 { \ 269 size_t* __j (__i._M_data); \ 270 for (size_t __k=0; __k<__n; ++__k, ++__j) \ 271 __a._M_data[*__j] _Op##= __e[__k]; \ 272 } \ 273 \ 274 template<typename _Tp> \ 275 void \ 276 _Array_augmented_##_Name (_Array<_Tp> __a, _Array<bool> __m, \ 277 _Array<_Tp> __b, size_t __n) \ 278 { \ 279 bool* ok (__m._M_data); \ 280 _Tp* __p (__a._M_data); \ 281 for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__q, ++ok, ++__p) { \ 282 while (! *ok) { \ 283 ++ok; \ 284 ++__p; \ 285 } \ 286 *__p _Op##= *__q; \ 287 } \ 288 } \ 289 \ 290 template<typename _Tp> \ 291 void \ 292 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, \ 293 _Array<_Tp> __b, _Array<bool> __m) \ 294 { \ 295 bool* ok (__m._M_data); \ 296 _Tp* __q (__b._M_data); \ 297 for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, ++ok, ++__q) { \ 298 while (! *ok) { \ 299 ++ok; \ 300 ++__q; \ 301 } \ 302 *__p _Op##= *__q; \ 303 } \ 304 } \ 305 \ 306 template<typename _Tp, class _Dom> \ 307 void \ 308 _Array_augmented_##_Name (_Array<_Tp> __a, _Array<bool> __m, \ 309 const _Expr<_Dom, _Tp>& __e, size_t __n) \ 310 { \ 311 bool* ok(__m._M_data); \ 312 _Tp* __p (__a._M_data); \ 313 for (size_t __i=0; __i<__n; ++__i, ++ok, ++__p) { \ 314 while (! *ok) { \ 315 ++ok; \ 316 ++__p; \ 317 } \ 318 *__p _Op##= __e[__i]; \ 319 } \ 320 } 321 322 _DEFINE_ARRAY_FUNCTION(+, plus) 323 _DEFINE_ARRAY_FUNCTION(-, minus) 324 _DEFINE_ARRAY_FUNCTION(*, multiplies) 325 _DEFINE_ARRAY_FUNCTION(/, divides) 326 _DEFINE_ARRAY_FUNCTION(%, modulus) 327 _DEFINE_ARRAY_FUNCTION(^, xor) 328 _DEFINE_ARRAY_FUNCTION(|, or) 329 _DEFINE_ARRAY_FUNCTION(&, and) 330 _DEFINE_ARRAY_FUNCTION(<<, shift_left) 331 _DEFINE_ARRAY_FUNCTION(>>, shift_right) 332 333 #undef _DEFINE_ARRAY_FUNCTION 334 335 } // extern "C++" 336 337 #ifdef _G_NO_VALARRAY_TEMPLATE_EXPORT 338 # define export 339 # include <std/valarray_array.tcc> 340 #endif 341 342 #endif // __VALARRAY_ARRAY__ 343 344 // Local Variables: 345 // mode:c++ 346 // End: 347