1 // The template and inlines for the -*- C++ -*- gslice class. 2 3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2004, 2005, 2006, 2009, 2010, 4 // 2011 Free Software Foundation, Inc. 5 // 6 // This file is part of the GNU ISO C++ Library. This library is free 7 // software; you can redistribute it and/or modify it under the 8 // terms of the GNU General Public License as published by the 9 // Free Software Foundation; either version 3, or (at your option) 10 // any later version. 11 12 // This library is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 // GNU General Public License for more details. 16 17 // Under Section 7 of GPL version 3, you are granted additional 18 // permissions described in the GCC Runtime Library Exception, version 19 // 3.1, as published by the Free Software Foundation. 20 21 // You should have received a copy of the GNU General Public License and 22 // a copy of the GCC Runtime Library Exception along with this program; 23 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24 // <http://www.gnu.org/licenses/>. 25 26 /** @file bits/gslice.h 27 * This is an internal header file, included by other library headers. 28 * Do not attempt to use it directly. @headername{valarray} 29 */ 30 31 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis (at) DPTMaths.ENS-Cachan.Fr> 32 33 #ifndef _GSLICE_H 34 #define _GSLICE_H 1 35 36 #pragma GCC system_header 37 38 namespace std _GLIBCXX_VISIBILITY(default) 39 { 40 _GLIBCXX_BEGIN_NAMESPACE_VERSION 41 42 /** 43 * @addtogroup numeric_arrays 44 * @{ 45 */ 46 47 /** 48 * @brief Class defining multi-dimensional subset of an array. 49 * 50 * The slice class represents a multi-dimensional subset of an array, 51 * specified by three parameter sets: start offset, size array, and stride 52 * array. The start offset is the index of the first element of the array 53 * that is part of the subset. The size and stride array describe each 54 * dimension of the slice. Size is the number of elements in that 55 * dimension, and stride is the distance in the array between successive 56 * elements in that dimension. Each dimension's size and stride is taken 57 * to begin at an array element described by the previous dimension. The 58 * size array and stride array must be the same size. 59 * 60 * For example, if you have offset==3, stride[0]==11, size[1]==3, 61 * stride[1]==3, then slice[0,0]==array[3], slice[0,1]==array[6], 62 * slice[0,2]==array[9], slice[1,0]==array[14], slice[1,1]==array[17], 63 * slice[1,2]==array[20]. 64 */ 65 class gslice 66 { 67 public: 68 /// Construct an empty slice. 69 gslice(); 70 71 /** 72 * @brief Construct a slice. 73 * 74 * Constructs a slice with as many dimensions as the length of the @a l 75 * and @a s arrays. 76 * 77 * @param __o Offset in array of first element. 78 * @param __l Array of dimension lengths. 79 * @param __s Array of dimension strides between array elements. 80 */ 81 gslice(size_t __o, const valarray<size_t>& __l, 82 const valarray<size_t>& __s); 83 84 // XXX: the IS says the copy-ctor and copy-assignment operators are 85 // synthesized by the compiler but they are just unsuitable 86 // for a ref-counted semantic 87 /// Copy constructor. 88 gslice(const gslice&); 89 90 /// Destructor. 91 ~gslice(); 92 93 // XXX: See the note above. 94 /// Assignment operator. 95 gslice& operator=(const gslice&); 96 97 /// Return array offset of first slice element. 98 size_t start() const; 99 100 /// Return array of sizes of slice dimensions. 101 valarray<size_t> size() const; 102 103 /// Return array of array strides for each dimension. 104 valarray<size_t> stride() const; 105 106 private: 107 struct _Indexer 108 { 109 size_t _M_count; 110 size_t _M_start; 111 valarray<size_t> _M_size; 112 valarray<size_t> _M_stride; 113 valarray<size_t> _M_index; // Linear array of referenced indices 114 115 _Indexer() 116 : _M_count(1), _M_start(0), _M_size(), _M_stride(), _M_index() {} 117 118 _Indexer(size_t, const valarray<size_t>&, 119 const valarray<size_t>&); 120 121 void 122 _M_increment_use() 123 { ++_M_count; } 124 125 size_t 126 _M_decrement_use() 127 { return --_M_count; } 128 }; 129 130 _Indexer* _M_index; 131 132 template<typename _Tp> friend class valarray; 133 }; 134 135 inline size_t 136 gslice::start() const 137 { return _M_index ? _M_index->_M_start : 0; } 138 139 inline valarray<size_t> 140 gslice::size() const 141 { return _M_index ? _M_index->_M_size : valarray<size_t>(); } 142 143 inline valarray<size_t> 144 gslice::stride() const 145 { return _M_index ? _M_index->_M_stride : valarray<size_t>(); } 146 147 // _GLIBCXX_RESOLVE_LIB_DEFECTS 148 // 543. valarray slice default constructor 149 inline 150 gslice::gslice() 151 : _M_index(new gslice::_Indexer()) {} 152 153 inline 154 gslice::gslice(size_t __o, const valarray<size_t>& __l, 155 const valarray<size_t>& __s) 156 : _M_index(new gslice::_Indexer(__o, __l, __s)) {} 157 158 inline 159 gslice::gslice(const gslice& __g) 160 : _M_index(__g._M_index) 161 { if (_M_index) _M_index->_M_increment_use(); } 162 163 inline 164 gslice::~gslice() 165 { 166 if (_M_index && _M_index->_M_decrement_use() == 0) 167 delete _M_index; 168 } 169 170 inline gslice& 171 gslice::operator=(const gslice& __g) 172 { 173 if (__g._M_index) 174 __g._M_index->_M_increment_use(); 175 if (_M_index && _M_index->_M_decrement_use() == 0) 176 delete _M_index; 177 _M_index = __g._M_index; 178 return *this; 179 } 180 181 // @} group numeric_arrays 182 183 _GLIBCXX_END_NAMESPACE_VERSION 184 } // namespace 185 186 #endif /* _GSLICE_H */ 187