(root)/
gcc-13.2.0/
libstdc++-v3/
include/
bits/
gslice.h
       1  // The template and inlines for the -*- C++ -*- gslice class.
       2  
       3  // Copyright (C) 1997-2023 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@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 */