1 // The template and inlines for the -*- C++ -*- gslice class. 2 3 // Copyright (C) 1997-2014 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/gslice.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 (at) DPTMaths.ENS-Cachan.Fr> 31 32 #ifndef _GSLICE_H 33 #define _GSLICE_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 multi-dimensional subset of an array. 48 * 49 * The slice class represents a multi-dimensional subset of an array, 50 * specified by three parameter sets: start offset, size array, and stride 51 * array. The start offset is the index of the first element of the array 52 * that is part of the subset. The size and stride array describe each 53 * dimension of the slice. Size is the number of elements in that 54 * dimension, and stride is the distance in the array between successive 55 * elements in that dimension. Each dimension's size and stride is taken 56 * to begin at an array element described by the previous dimension. The 57 * size array and stride array must be the same size. 58 * 59 * For example, if you have offset==3, stride[0]==11, size[1]==3, 60 * stride[1]==3, then slice[0,0]==array[3], slice[0,1]==array[6], 61 * slice[0,2]==array[9], slice[1,0]==array[14], slice[1,1]==array[17], 62 * slice[1,2]==array[20]. 63 */ 64 class gslice 65 { 66 public: 67 /// Construct an empty slice. 68 gslice(); 69 70 /** 71 * @brief Construct a slice. 72 * 73 * Constructs a slice with as many dimensions as the length of the @a l 74 * and @a s arrays. 75 * 76 * @param __o Offset in array of first element. 77 * @param __l Array of dimension lengths. 78 * @param __s Array of dimension strides between array elements. 79 */ 80 gslice(size_t __o, const valarray<size_t>& __l, 81 const valarray<size_t>& __s); 82 83 // XXX: the IS says the copy-ctor and copy-assignment operators are 84 // synthesized by the compiler but they are just unsuitable 85 // for a ref-counted semantic 86 /// Copy constructor. 87 gslice(const gslice&); 88 89 /// Destructor. 90 ~gslice(); 91 92 // XXX: See the note above. 93 /// Assignment operator. 94 gslice& operator=(const gslice&); 95 96 /// Return array offset of first slice element. 97 size_t start() const; 98 99 /// Return array of sizes of slice dimensions. 100 valarray<size_t> size() const; 101 102 /// Return array of array strides for each dimension. 103 valarray<size_t> stride() const; 104 105 private: 106 struct _Indexer 107 { 108 size_t _M_count; 109 size_t _M_start; 110 valarray<size_t> _M_size; 111 valarray<size_t> _M_stride; 112 valarray<size_t> _M_index; // Linear array of referenced indices 113 114 _Indexer() 115 : _M_count(1), _M_start(0), _M_size(), _M_stride(), _M_index() {} 116 117 _Indexer(size_t, const valarray<size_t>&, 118 const valarray<size_t>&); 119 120 void 121 _M_increment_use() 122 { ++_M_count; } 123 124 size_t 125 _M_decrement_use() 126 { return --_M_count; } 127 }; 128 129 _Indexer* _M_index; 130 131 template<typename _Tp> friend class valarray; 132 }; 133 134 inline size_t 135 gslice::start() const 136 { return _M_index ? _M_index->_M_start : 0; } 137 138 inline valarray<size_t> 139 gslice::size() const 140 { return _M_index ? _M_index->_M_size : valarray<size_t>(); } 141 142 inline valarray<size_t> 143 gslice::stride() const 144 { return _M_index ? _M_index->_M_stride : valarray<size_t>(); } 145 146 // _GLIBCXX_RESOLVE_LIB_DEFECTS 147 // 543. valarray slice default constructor 148 inline 149 gslice::gslice() 150 : _M_index(new gslice::_Indexer()) {} 151 152 inline 153 gslice::gslice(size_t __o, const valarray<size_t>& __l, 154 const valarray<size_t>& __s) 155 : _M_index(new gslice::_Indexer(__o, __l, __s)) {} 156 157 inline 158 gslice::gslice(const gslice& __g) 159 : _M_index(__g._M_index) 160 { if (_M_index) _M_index->_M_increment_use(); } 161 162 inline 163 gslice::~gslice() 164 { 165 if (_M_index && _M_index->_M_decrement_use() == 0) 166 delete _M_index; 167 } 168 169 inline gslice& 170 gslice::operator=(const gslice& __g) 171 { 172 if (__g._M_index) 173 __g._M_index->_M_increment_use(); 174 if (_M_index && _M_index->_M_decrement_use() == 0) 175 delete _M_index; 176 _M_index = __g._M_index; 177 return *this; 178 } 179 180 // @} group numeric_arrays 181 182 _GLIBCXX_END_NAMESPACE_VERSION 183 } // namespace 184 185 #endif /* _GSLICE_H */ 186