| [1166] | 1 | // The template and inlines for the -*- C++ -*- slice_array class. | 
|---|
|  | 2 |  | 
|---|
|  | 3 | // Copyright (C) 1997-2021 Free Software Foundation, Inc. | 
|---|
|  | 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 3, 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 | // Under Section 7 of GPL version 3, you are granted additional | 
|---|
|  | 17 | // permissions described in the GCC Runtime Library Exception, version | 
|---|
|  | 18 | // 3.1, as published by the Free Software Foundation. | 
|---|
|  | 19 |  | 
|---|
|  | 20 | // You should have received a copy of the GNU General Public License and | 
|---|
|  | 21 | // a copy of the GCC Runtime Library Exception along with this program; | 
|---|
|  | 22 | // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see | 
|---|
|  | 23 | // <http://www.gnu.org/licenses/>. | 
|---|
|  | 24 |  | 
|---|
|  | 25 | /** @file bits/slice_array.h | 
|---|
|  | 26 | *  This is an internal header file, included by other library headers. | 
|---|
|  | 27 | *  Do not attempt to use it directly. @headername{valarray} | 
|---|
|  | 28 | */ | 
|---|
|  | 29 |  | 
|---|
|  | 30 | // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> | 
|---|
|  | 31 |  | 
|---|
|  | 32 | #ifndef _SLICE_ARRAY_H | 
|---|
|  | 33 | #define _SLICE_ARRAY_H 1 | 
|---|
|  | 34 |  | 
|---|
|  | 35 | #pragma GCC system_header | 
|---|
|  | 36 |  | 
|---|
|  | 37 | namespace std _GLIBCXX_VISIBILITY(default) | 
|---|
|  | 38 | { | 
|---|
|  | 39 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | 
|---|
|  | 40 |  | 
|---|
|  | 41 | /** | 
|---|
|  | 42 | * @addtogroup numeric_arrays | 
|---|
|  | 43 | * @{ | 
|---|
|  | 44 | */ | 
|---|
|  | 45 |  | 
|---|
|  | 46 | /** | 
|---|
|  | 47 | *  @brief  Class defining one-dimensional subset of an array. | 
|---|
|  | 48 | * | 
|---|
|  | 49 | *  The slice class represents a one-dimensional subset of an array, | 
|---|
|  | 50 | *  specified by three parameters: start offset, size, and stride.  The | 
|---|
|  | 51 | *  start offset is the index of the first element of the array that is part | 
|---|
|  | 52 | *  of the subset.  The size is the total number of elements in the subset. | 
|---|
|  | 53 | *  Stride is the distance between each successive array element to include | 
|---|
|  | 54 | *  in the subset. | 
|---|
|  | 55 | * | 
|---|
|  | 56 | *  For example, with an array of size 10, and a slice with offset 1, size 3 | 
|---|
|  | 57 | *  and stride 2, the subset consists of array elements 1, 3, and 5. | 
|---|
|  | 58 | */ | 
|---|
|  | 59 | class slice | 
|---|
|  | 60 | { | 
|---|
|  | 61 | public: | 
|---|
|  | 62 | ///  Construct an empty slice. | 
|---|
|  | 63 | slice(); | 
|---|
|  | 64 |  | 
|---|
|  | 65 | /** | 
|---|
|  | 66 | *  @brief  Construct a slice. | 
|---|
|  | 67 | * | 
|---|
|  | 68 | *  @param  __o  Offset in array of first element. | 
|---|
|  | 69 | *  @param  __d  Number of elements in slice. | 
|---|
|  | 70 | *  @param  __s  Stride between array elements. | 
|---|
|  | 71 | */ | 
|---|
|  | 72 | slice(size_t __o, size_t __d, size_t __s); | 
|---|
|  | 73 |  | 
|---|
|  | 74 | ///  Return array offset of first slice element. | 
|---|
|  | 75 | size_t start() const; | 
|---|
|  | 76 | ///  Return size of slice. | 
|---|
|  | 77 | size_t size() const; | 
|---|
|  | 78 | ///  Return array stride of slice. | 
|---|
|  | 79 | size_t stride() const; | 
|---|
|  | 80 |  | 
|---|
|  | 81 | #if __cpp_impl_three_way_comparison >= 201907L | 
|---|
|  | 82 | /// Equality comparison | 
|---|
|  | 83 | friend bool operator==(const slice&, const slice&) = default; | 
|---|
|  | 84 | #endif | 
|---|
|  | 85 |  | 
|---|
|  | 86 | private: | 
|---|
|  | 87 | size_t _M_off;                      // offset | 
|---|
|  | 88 | size_t _M_sz;                       // size | 
|---|
|  | 89 | size_t _M_st;                       // stride unit | 
|---|
|  | 90 | }; | 
|---|
|  | 91 |  | 
|---|
|  | 92 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | 
|---|
|  | 93 | // 543. valarray slice default constructor | 
|---|
|  | 94 | inline | 
|---|
|  | 95 | slice::slice() | 
|---|
|  | 96 | : _M_off(0), _M_sz(0), _M_st(0) {} | 
|---|
|  | 97 |  | 
|---|
|  | 98 | inline | 
|---|
|  | 99 | slice::slice(size_t __o, size_t __d, size_t __s) | 
|---|
|  | 100 | : _M_off(__o), _M_sz(__d), _M_st(__s) {} | 
|---|
|  | 101 |  | 
|---|
|  | 102 | inline size_t | 
|---|
|  | 103 | slice::start() const | 
|---|
|  | 104 | { return _M_off; } | 
|---|
|  | 105 |  | 
|---|
|  | 106 | inline size_t | 
|---|
|  | 107 | slice::size() const | 
|---|
|  | 108 | { return _M_sz; } | 
|---|
|  | 109 |  | 
|---|
|  | 110 | inline size_t | 
|---|
|  | 111 | slice::stride() const | 
|---|
|  | 112 | { return _M_st; } | 
|---|
|  | 113 |  | 
|---|
|  | 114 | /** | 
|---|
|  | 115 | *  @brief  Reference to one-dimensional subset of an array. | 
|---|
|  | 116 | * | 
|---|
|  | 117 | *  A slice_array is a reference to the actual elements of an array | 
|---|
|  | 118 | *  specified by a slice.  The way to get a slice_array is to call | 
|---|
|  | 119 | *  operator[](slice) on a valarray.  The returned slice_array then permits | 
|---|
|  | 120 | *  carrying operations out on the referenced subset of elements in the | 
|---|
|  | 121 | *  original valarray.  For example, operator+=(valarray) will add values | 
|---|
|  | 122 | *  to the subset of elements in the underlying valarray this slice_array | 
|---|
|  | 123 | *  refers to. | 
|---|
|  | 124 | * | 
|---|
|  | 125 | *  @param  Tp  Element type. | 
|---|
|  | 126 | */ | 
|---|
|  | 127 | template<typename _Tp> | 
|---|
|  | 128 | class slice_array | 
|---|
|  | 129 | { | 
|---|
|  | 130 | public: | 
|---|
|  | 131 | typedef _Tp value_type; | 
|---|
|  | 132 |  | 
|---|
|  | 133 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | 
|---|
|  | 134 | // 253. valarray helper functions are almost entirely useless | 
|---|
|  | 135 |  | 
|---|
|  | 136 | ///  Copy constructor.  Both slices refer to the same underlying array. | 
|---|
|  | 137 | slice_array(const slice_array&); | 
|---|
|  | 138 |  | 
|---|
|  | 139 | ///  Assignment operator.  Assigns slice elements to corresponding | 
|---|
|  | 140 | ///  elements of @a a. | 
|---|
|  | 141 | slice_array& operator=(const slice_array&); | 
|---|
|  | 142 |  | 
|---|
|  | 143 | ///  Assign slice elements to corresponding elements of @a v. | 
|---|
|  | 144 | void operator=(const valarray<_Tp>&) const; | 
|---|
|  | 145 | ///  Multiply slice elements by corresponding elements of @a v. | 
|---|
|  | 146 | void operator*=(const valarray<_Tp>&) const; | 
|---|
|  | 147 | ///  Divide slice elements by corresponding elements of @a v. | 
|---|
|  | 148 | void operator/=(const valarray<_Tp>&) const; | 
|---|
|  | 149 | ///  Modulo slice elements by corresponding elements of @a v. | 
|---|
|  | 150 | void operator%=(const valarray<_Tp>&) const; | 
|---|
|  | 151 | ///  Add corresponding elements of @a v to slice elements. | 
|---|
|  | 152 | void operator+=(const valarray<_Tp>&) const; | 
|---|
|  | 153 | ///  Subtract corresponding elements of @a v from slice elements. | 
|---|
|  | 154 | void operator-=(const valarray<_Tp>&) const; | 
|---|
|  | 155 | ///  Logical xor slice elements with corresponding elements of @a v. | 
|---|
|  | 156 | void operator^=(const valarray<_Tp>&) const; | 
|---|
|  | 157 | ///  Logical and slice elements with corresponding elements of @a v. | 
|---|
|  | 158 | void operator&=(const valarray<_Tp>&) const; | 
|---|
|  | 159 | ///  Logical or slice elements with corresponding elements of @a v. | 
|---|
|  | 160 | void operator|=(const valarray<_Tp>&) const; | 
|---|
|  | 161 | ///  Left shift slice elements by corresponding elements of @a v. | 
|---|
|  | 162 | void operator<<=(const valarray<_Tp>&) const; | 
|---|
|  | 163 | ///  Right shift slice elements by corresponding elements of @a v. | 
|---|
|  | 164 | void operator>>=(const valarray<_Tp>&) const; | 
|---|
|  | 165 | ///  Assign all slice elements to @a t. | 
|---|
|  | 166 | void operator=(const _Tp &) const; | 
|---|
|  | 167 | //        ~slice_array (); | 
|---|
|  | 168 |  | 
|---|
|  | 169 | template<class _Dom> | 
|---|
|  | 170 | void operator=(const _Expr<_Dom, _Tp>&) const; | 
|---|
|  | 171 | template<class _Dom> | 
|---|
|  | 172 | void operator*=(const _Expr<_Dom, _Tp>&) const; | 
|---|
|  | 173 | template<class _Dom> | 
|---|
|  | 174 | void operator/=(const _Expr<_Dom, _Tp>&) const; | 
|---|
|  | 175 | template<class _Dom> | 
|---|
|  | 176 | void operator%=(const _Expr<_Dom, _Tp>&) const; | 
|---|
|  | 177 | template<class _Dom> | 
|---|
|  | 178 | void operator+=(const _Expr<_Dom, _Tp>&) const; | 
|---|
|  | 179 | template<class _Dom> | 
|---|
|  | 180 | void operator-=(const _Expr<_Dom, _Tp>&) const; | 
|---|
|  | 181 | template<class _Dom> | 
|---|
|  | 182 | void operator^=(const _Expr<_Dom, _Tp>&) const; | 
|---|
|  | 183 | template<class _Dom> | 
|---|
|  | 184 | void operator&=(const _Expr<_Dom, _Tp>&) const; | 
|---|
|  | 185 | template<class _Dom> | 
|---|
|  | 186 | void operator|=(const _Expr<_Dom, _Tp>&) const; | 
|---|
|  | 187 | template<class _Dom> | 
|---|
|  | 188 | void operator<<=(const _Expr<_Dom, _Tp>&) const; | 
|---|
|  | 189 | template<class _Dom> | 
|---|
|  | 190 | void operator>>=(const _Expr<_Dom, _Tp>&) const; | 
|---|
|  | 191 |  | 
|---|
|  | 192 | private: | 
|---|
|  | 193 | friend class valarray<_Tp>; | 
|---|
|  | 194 | slice_array(_Array<_Tp>, const slice&); | 
|---|
|  | 195 |  | 
|---|
|  | 196 | const size_t      _M_sz; | 
|---|
|  | 197 | const size_t      _M_stride; | 
|---|
|  | 198 | const _Array<_Tp> _M_array; | 
|---|
|  | 199 |  | 
|---|
|  | 200 | #if __cplusplus < 201103L | 
|---|
|  | 201 | // not implemented | 
|---|
|  | 202 | slice_array(); | 
|---|
|  | 203 | #else | 
|---|
|  | 204 | public: | 
|---|
|  | 205 | slice_array() = delete; | 
|---|
|  | 206 | #endif | 
|---|
|  | 207 | }; | 
|---|
|  | 208 |  | 
|---|
|  | 209 | template<typename _Tp> | 
|---|
|  | 210 | inline | 
|---|
|  | 211 | slice_array<_Tp>::slice_array(_Array<_Tp> __a, const slice& __s) | 
|---|
|  | 212 | : _M_sz(__s.size()), _M_stride(__s.stride()), | 
|---|
|  | 213 | _M_array(__a.begin() + __s.start()) {} | 
|---|
|  | 214 |  | 
|---|
|  | 215 | template<typename _Tp> | 
|---|
|  | 216 | inline | 
|---|
|  | 217 | slice_array<_Tp>::slice_array(const slice_array<_Tp>& __a) | 
|---|
|  | 218 | : _M_sz(__a._M_sz), _M_stride(__a._M_stride), _M_array(__a._M_array) {} | 
|---|
|  | 219 |  | 
|---|
|  | 220 | //    template<typename _Tp> | 
|---|
|  | 221 | //    inline slice_array<_Tp>::~slice_array () {} | 
|---|
|  | 222 |  | 
|---|
|  | 223 | template<typename _Tp> | 
|---|
|  | 224 | inline slice_array<_Tp>& | 
|---|
|  | 225 | slice_array<_Tp>::operator=(const slice_array<_Tp>& __a) | 
|---|
|  | 226 | { | 
|---|
|  | 227 | std::__valarray_copy(__a._M_array, __a._M_sz, __a._M_stride, | 
|---|
|  | 228 | _M_array, _M_stride); | 
|---|
|  | 229 | return *this; | 
|---|
|  | 230 | } | 
|---|
|  | 231 |  | 
|---|
|  | 232 | template<typename _Tp> | 
|---|
|  | 233 | inline void | 
|---|
|  | 234 | slice_array<_Tp>::operator=(const _Tp& __t) const | 
|---|
|  | 235 | { std::__valarray_fill(_M_array, _M_sz, _M_stride, __t); } | 
|---|
|  | 236 |  | 
|---|
|  | 237 | template<typename _Tp> | 
|---|
|  | 238 | inline void | 
|---|
|  | 239 | slice_array<_Tp>::operator=(const valarray<_Tp>& __v) const | 
|---|
|  | 240 | { std::__valarray_copy(_Array<_Tp>(__v), _M_array, _M_sz, _M_stride); } | 
|---|
|  | 241 |  | 
|---|
|  | 242 | template<typename _Tp> | 
|---|
|  | 243 | template<class _Dom> | 
|---|
|  | 244 | inline void | 
|---|
|  | 245 | slice_array<_Tp>::operator=(const _Expr<_Dom,_Tp>& __e) const | 
|---|
|  | 246 | { std::__valarray_copy(__e, _M_sz, _M_array, _M_stride); } | 
|---|
|  | 247 |  | 
|---|
|  | 248 | #undef _DEFINE_VALARRAY_OPERATOR | 
|---|
|  | 249 | #define _DEFINE_VALARRAY_OPERATOR(_Op,_Name)                            \ | 
|---|
|  | 250 | template<typename _Tp>                                                \ | 
|---|
|  | 251 | inline void                                                         \ | 
|---|
|  | 252 | slice_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const   \ | 
|---|
|  | 253 | {                                                                   \ | 
|---|
|  | 254 | _Array_augmented_##_Name(_M_array, _M_sz, _M_stride, _Array<_Tp>(__v));\ | 
|---|
|  | 255 | }                                                                   \ | 
|---|
|  | 256 | \ | 
|---|
|  | 257 | template<typename _Tp>                                                \ | 
|---|
|  | 258 | template<class _Dom>                                                \ | 
|---|
|  | 259 | inline void                                                       \ | 
|---|
|  | 260 | slice_array<_Tp>::operator _Op##=(const _Expr<_Dom,_Tp>& __e) const\ | 
|---|
|  | 261 | {                                                                 \ | 
|---|
|  | 262 | _Array_augmented_##_Name(_M_array, _M_stride, __e, _M_sz);    \ | 
|---|
|  | 263 | } | 
|---|
|  | 264 |  | 
|---|
|  | 265 |  | 
|---|
|  | 266 | _DEFINE_VALARRAY_OPERATOR(*, __multiplies) | 
|---|
|  | 267 | _DEFINE_VALARRAY_OPERATOR(/, __divides) | 
|---|
|  | 268 | _DEFINE_VALARRAY_OPERATOR(%, __modulus) | 
|---|
|  | 269 | _DEFINE_VALARRAY_OPERATOR(+, __plus) | 
|---|
|  | 270 | _DEFINE_VALARRAY_OPERATOR(-, __minus) | 
|---|
|  | 271 | _DEFINE_VALARRAY_OPERATOR(^, __bitwise_xor) | 
|---|
|  | 272 | _DEFINE_VALARRAY_OPERATOR(&, __bitwise_and) | 
|---|
|  | 273 | _DEFINE_VALARRAY_OPERATOR(|, __bitwise_or) | 
|---|
|  | 274 | _DEFINE_VALARRAY_OPERATOR(<<, __shift_left) | 
|---|
|  | 275 | _DEFINE_VALARRAY_OPERATOR(>>, __shift_right) | 
|---|
|  | 276 |  | 
|---|
|  | 277 | #undef _DEFINE_VALARRAY_OPERATOR | 
|---|
|  | 278 |  | 
|---|
|  | 279 | /// @} group numeric_arrays | 
|---|
|  | 280 |  | 
|---|
|  | 281 | _GLIBCXX_END_NAMESPACE_VERSION | 
|---|
|  | 282 | } // namespace | 
|---|
|  | 283 |  | 
|---|
|  | 284 | #endif /* _SLICE_ARRAY_H */ | 
|---|