NumCpp  2.11.0
A Templatized Header Only C++ Implementation of the Python NumPy Library
Slice.hpp
Go to the documentation of this file.
1 
29 #pragma once
30 
31 #include <algorithm>
32 #include <iostream>
33 #include <string>
34 #include <vector>
35 
37 #include "NumCpp/Core/Types.hpp"
38 #include "NumCpp/Utils/num2str.hpp"
39 
40 namespace nc
41 {
42  //================================================================================
44  class Slice
45  {
46  public:
47  //====================================Attributes==============================
48  int32 start{ 0 };
49  int32 stop{ 1 };
50  int32 step{ 1 };
51 
52  //============================================================================
55  constexpr Slice() = default;
56 
57  //============================================================================
62  constexpr explicit Slice(int32 inStop) noexcept :
63  stop(inStop)
64  {
65  }
66 
67  //============================================================================
73  constexpr Slice(int32 inStart, int32 inStop) noexcept :
74  start(inStart),
75  stop(inStop)
76  {
77  }
78 
79  //============================================================================
86  constexpr Slice(int32 inStart, int32 inStop, int32 inStep) noexcept :
87  start(inStart),
88  stop(inStop),
89  step(inStep)
90  {
91  }
92 
93  //============================================================================
100  bool operator==(const Slice& inOtherSlice) const noexcept
101  {
102  return start == inOtherSlice.start && stop == inOtherSlice.stop && step == inOtherSlice.step;
103  }
104 
105  //============================================================================
112  bool operator!=(const Slice& inOtherSlice) const noexcept
113  {
114  return !(*this == inOtherSlice);
115  }
116 
117  //============================================================================
122  [[nodiscard]] std::string str() const
123  {
124  std::string out =
125  "[" + utils::num2str(start) + ":" + utils::num2str(stop) + ":" + utils::num2str(step) + "]\n";
126  return out;
127  }
128 
129  //============================================================================
132  void print() const
133  {
134  std::cout << *this;
135  }
136 
137  //============================================================================
142  void makePositiveAndValidate(uint32 inArraySize)
143  {
145  if (start < 0)
146  {
147  start += static_cast<int32>(inArraySize);
148  }
149  if (start > static_cast<int32>(inArraySize - 1))
150  {
151  THROW_INVALID_ARGUMENT_ERROR("Invalid start value for array of size " + utils::num2str(inArraySize));
152  }
153 
155  if (stop < 0)
156  {
157  stop += static_cast<int32>(inArraySize);
158  }
159  if (stop > static_cast<int32>(inArraySize))
160  {
161  THROW_INVALID_ARGUMENT_ERROR("Invalid stop value for array of size " + utils::num2str(inArraySize));
162  }
163 
165  if (start < stop)
166  {
167  if (step < 0)
168  {
169  THROW_INVALID_ARGUMENT_ERROR("Invalid slice values [" + utils::num2str(start) + ", " +
170  utils::num2str(stop) + ", " + utils::num2str(step) + ']');
171  }
172  }
173 
174  if (stop < start)
175  {
176  if (step > 0)
177  {
178  THROW_INVALID_ARGUMENT_ERROR("Invalid slice values [" + utils::num2str(start) + ", " +
179  utils::num2str(stop) + ", " + utils::num2str(step) + ']');
180  }
181 
183  std::swap(start, stop);
184  step *= -1;
185  }
186  }
187 
188  //============================================================================
195  uint32 numElements(uint32 inArraySize)
196  {
197  makePositiveAndValidate(inArraySize);
198 
199  uint32 num = 0;
200  for (int32 i = start; i < stop; i += step)
201  {
202  ++num;
203  }
204  return num;
205  }
206 
207  //============================================================================
214  std::vector<uint32> toIndices(uint32 inArrayDimSize)
215  {
216  std::vector<uint32> indices;
217  indices.reserve(numElements(inArrayDimSize));
218  for (int32 i = start; i < stop; i += step)
219  {
220  indices.push_back(static_cast<uint32>(i));
221  }
222  return indices;
223  }
224 
225  //============================================================================
233  friend std::ostream& operator<<(std::ostream& inOStream, const Slice& inSlice)
234  {
235  inOStream << inSlice.str();
236  return inOStream;
237  }
238  };
239 } // namespace nc
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:37
A Class for slicing into NdArrays.
Definition: Slice.hpp:45
int32 step
Definition: Slice.hpp:50
void print() const
Definition: Slice.hpp:132
std::vector< uint32 > toIndices(uint32 inArrayDimSize)
Definition: Slice.hpp:214
int32 start
Definition: Slice.hpp:48
void makePositiveAndValidate(uint32 inArraySize)
Definition: Slice.hpp:142
bool operator==(const Slice &inOtherSlice) const noexcept
Definition: Slice.hpp:100
constexpr Slice(int32 inStart, int32 inStop, int32 inStep) noexcept
Definition: Slice.hpp:86
constexpr Slice(int32 inStop) noexcept
Definition: Slice.hpp:62
uint32 numElements(uint32 inArraySize)
Definition: Slice.hpp:195
constexpr Slice(int32 inStart, int32 inStop) noexcept
Definition: Slice.hpp:73
int32 stop
Definition: Slice.hpp:49
friend std::ostream & operator<<(std::ostream &inOStream, const Slice &inSlice)
Definition: Slice.hpp:233
constexpr Slice()=default
std::string str() const
Definition: Slice.hpp:122
bool operator!=(const Slice &inOtherSlice) const noexcept
Definition: Slice.hpp:112
std::string num2str(dtype inNumber)
Definition: num2str.hpp:44
Definition: Cartesian.hpp:40
void swap(NdArray< dtype > &inArray1, NdArray< dtype > &inArray2) noexcept
Definition: swap.hpp:42
std::int32_t int32
Definition: Types.hpp:36
std::uint32_t uint32
Definition: Types.hpp:40