You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

186 lines
5.4KB

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