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 // 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, const valarray<size_t>&, const valarray<size_t>&); 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