| 1 | // The template and inlines for the -*- C++ -*- gslice class. |
|---|
| 2 | |
|---|
| 3 | // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2004 |
|---|
| 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 2, 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 | // You should have received a copy of the GNU General Public License along |
|---|
| 18 | // with this library; see the file COPYING. If not, write to the Free |
|---|
| 19 | // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|---|
| 20 | // USA. |
|---|
| 21 | |
|---|
| 22 | // As a special exception, you may use this file as part of a free software |
|---|
| 23 | // library without restriction. Specifically, if other files instantiate |
|---|
| 24 | // templates or use macros or inline functions from this file, or you compile |
|---|
| 25 | // this file and link it with other files to produce an executable, this |
|---|
| 26 | // file does not by itself cause the resulting executable to be covered by |
|---|
| 27 | // the GNU General Public License. This exception does not however |
|---|
| 28 | // invalidate any other reasons why the executable file might be covered by |
|---|
| 29 | // the GNU General Public License. |
|---|
| 30 | |
|---|
| 31 | // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> |
|---|
| 32 | |
|---|
| 33 | /** @file gslice.h |
|---|
| 34 | * This is an internal header file, included by other library headers. |
|---|
| 35 | * You should not attempt to use it directly. |
|---|
| 36 | */ |
|---|
| 37 | |
|---|
| 38 | #ifndef _GSLICE_H |
|---|
| 39 | #define _GSLICE_H 1 |
|---|
| 40 | |
|---|
| 41 | #pragma GCC system_header |
|---|
| 42 | |
|---|
| 43 | namespace std { |
|---|
| 44 | |
|---|
| 45 | /** |
|---|
| 46 | * @brief Class defining multi-dimensional subset of an array. |
|---|
| 47 | * |
|---|
| 48 | * The slice class represents a multi-dimensional subset of an array, |
|---|
| 49 | * specified by three parameter sets: start offset, size array, and stride |
|---|
| 50 | * array. The start offset is the index of the first element of the array |
|---|
| 51 | * that is part of the subset. The size and stride array describe each |
|---|
| 52 | * dimension of the slice. Size is the number of elements in that |
|---|
| 53 | * dimension, and stride is the distance in the array between successive |
|---|
| 54 | * elements in that dimension. Each dimension's size and stride is taken |
|---|
| 55 | * to begin at an array element described by the previous dimension. The |
|---|
| 56 | * size array and stride array must be the same size. |
|---|
| 57 | * |
|---|
| 58 | * For example, if you have offset==3, stride[0]==11, size[1]==3, |
|---|
| 59 | * stride[1]==3, then slice[0,0]==array[3], slice[0,1]==array[6], |
|---|
| 60 | * slice[0,2]==array[9], slice[1,0]==array[14], slice[1,1]==array[17], |
|---|
| 61 | * slice[1,2]==array[20]. |
|---|
| 62 | */ |
|---|
| 63 | class gslice |
|---|
| 64 | { |
|---|
| 65 | public: |
|---|
| 66 | /// Construct an empty slice. |
|---|
| 67 | gslice (); |
|---|
| 68 | |
|---|
| 69 | /** |
|---|
| 70 | * @brief Construct a slice. |
|---|
| 71 | * |
|---|
| 72 | * Constructs a slice with as many dimensions as the length of the @a l |
|---|
| 73 | * and @a s arrays. |
|---|
| 74 | * |
|---|
| 75 | * @param o Offset in array of first element. |
|---|
| 76 | * @param l Array of dimension lengths. |
|---|
| 77 | * @param s Array of dimension strides between array elements. |
|---|
| 78 | */ |
|---|
| 79 | gslice(size_t, const valarray<size_t>&, const valarray<size_t>&); |
|---|
| 80 | |
|---|
| 81 | // XXX: the IS says the copy-ctor and copy-assignment operators are |
|---|
| 82 | // synthetized by the compiler but they are just unsuitable |
|---|
| 83 | // for a ref-counted semantic |
|---|
| 84 | /// Copy constructor. |
|---|
| 85 | gslice(const gslice&); |
|---|
| 86 | |
|---|
| 87 | /// Destructor. |
|---|
| 88 | ~gslice(); |
|---|
| 89 | |
|---|
| 90 | // XXX: See the note above. |
|---|
| 91 | /// Assignment operator. |
|---|
| 92 | gslice& operator=(const gslice&); |
|---|
| 93 | |
|---|
| 94 | /// Return array offset of first slice element. |
|---|
| 95 | size_t start() const; |
|---|
| 96 | |
|---|
| 97 | /// Return array of sizes of slice dimensions. |
|---|
| 98 | valarray<size_t> size() const; |
|---|
| 99 | |
|---|
| 100 | /// Return array of array strides for each dimension. |
|---|
| 101 | valarray<size_t> stride() const; |
|---|
| 102 | |
|---|
| 103 | private: |
|---|
| 104 | struct _Indexer { |
|---|
| 105 | size_t _M_count; |
|---|
| 106 | size_t _M_start; |
|---|
| 107 | valarray<size_t> _M_size; |
|---|
| 108 | valarray<size_t> _M_stride; |
|---|
| 109 | valarray<size_t> _M_index; // Linear array of referenced indices |
|---|
| 110 | _Indexer(size_t, const valarray<size_t>&, |
|---|
| 111 | const valarray<size_t>&); |
|---|
| 112 | void _M_increment_use() { ++_M_count; } |
|---|
| 113 | size_t _M_decrement_use() { return --_M_count; } |
|---|
| 114 | }; |
|---|
| 115 | |
|---|
| 116 | _Indexer* _M_index; |
|---|
| 117 | |
|---|
| 118 | template<typename _Tp> friend class valarray; |
|---|
| 119 | }; |
|---|
| 120 | |
|---|
| 121 | inline size_t |
|---|
| 122 | gslice::start () const |
|---|
| 123 | { return _M_index ? _M_index->_M_start : 0; } |
|---|
| 124 | |
|---|
| 125 | inline valarray<size_t> |
|---|
| 126 | gslice::size () const |
|---|
| 127 | { return _M_index ? _M_index->_M_size : valarray<size_t>(); } |
|---|
| 128 | |
|---|
| 129 | inline valarray<size_t> |
|---|
| 130 | gslice::stride () const |
|---|
| 131 | { return _M_index ? _M_index->_M_stride : valarray<size_t>(); } |
|---|
| 132 | |
|---|
| 133 | inline gslice::gslice () : _M_index(0) {} |
|---|
| 134 | |
|---|
| 135 | inline |
|---|
| 136 | gslice::gslice(size_t __o, const valarray<size_t>& __l, |
|---|
| 137 | const valarray<size_t>& __s) |
|---|
| 138 | : _M_index(new gslice::_Indexer(__o, __l, __s)) {} |
|---|
| 139 | |
|---|
| 140 | inline |
|---|
| 141 | gslice::gslice(const gslice& __g) : _M_index(__g._M_index) |
|---|
| 142 | { if (_M_index) _M_index->_M_increment_use(); } |
|---|
| 143 | |
|---|
| 144 | inline |
|---|
| 145 | gslice::~gslice() |
|---|
| 146 | { if (_M_index && _M_index->_M_decrement_use() == 0) delete _M_index; } |
|---|
| 147 | |
|---|
| 148 | inline gslice& |
|---|
| 149 | gslice::operator= (const gslice& __g) |
|---|
| 150 | { |
|---|
| 151 | if (__g._M_index) __g._M_index->_M_increment_use(); |
|---|
| 152 | if (_M_index && _M_index->_M_decrement_use() == 0) delete _M_index; |
|---|
| 153 | _M_index = __g._M_index; |
|---|
| 154 | return *this; |
|---|
| 155 | } |
|---|
| 156 | |
|---|
| 157 | |
|---|
| 158 | } // std:: |
|---|
| 159 | |
|---|
| 160 | |
|---|
| 161 | #endif /* _GSLICE_H */ |
|---|
| 162 | |
|---|
| 163 | // Local Variables: |
|---|
| 164 | // mode:c++ |
|---|
| 165 | // End: |
|---|