Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // The template and inlines for the -*- C++ -*- gslice class.
  2.  
  3. // Copyright (C) 1997-2015 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 */
  186.