WPILibC++ 2025.1.1
Loading...
Searching...
No Matches
Slice.hpp
Go to the documentation of this file.
1// Copyright (c) Sleipnir contributors
2
3#pragma once
4
5#include <concepts>
6#include <limits>
7#include <utility>
8
11
12namespace sleipnir {
13
14namespace slicing {
15
16struct none_t {};
17static inline constexpr none_t _;
18
19} // namespace slicing
20
22 public:
23 /// Start index (inclusive).
24 int start = 0;
25
26 /// Stop index (exclusive).
27 int stop = 0;
28
29 /// Step.
30 int step = 1;
31
32 /**
33 * Constructs a Slice.
34 */
35 constexpr Slice() = default;
36
37 /**
38 * Constructs a slice.
39 *
40 * @param stop Slice stop index (exclusive).
41 */
42 template <typename Stop>
43 requires std::same_as<Stop, slicing::none_t> ||
44 std::convertible_to<Stop, int>
45 constexpr Slice(Stop stop) // NOLINT
46 : Slice(slicing::_, std::move(stop), 1) {}
47
48 /**
49 * Constructs a slice.
50 *
51 * @param start Slice start index (inclusive).
52 * @param stop Slice stop index (exclusive).
53 */
54 template <typename Start, typename Stop>
55 requires(std::same_as<Start, slicing::none_t> ||
56 std::convertible_to<Start, int>) &&
57 (std::same_as<Stop, slicing::none_t> ||
58 std::convertible_to<Stop, int>)
59 constexpr Slice(Start start, Stop stop)
60 : Slice(std::move(start), std::move(stop), 1) {}
61
62 /**
63 * Constructs a slice.
64 *
65 * @param start Slice start index (inclusive).
66 * @param stop Slice stop index (exclusive).
67 * @param step Slice step.
68 */
69 template <typename Start, typename Stop, typename Step>
70 requires(std::same_as<Start, slicing::none_t> ||
71 std::convertible_to<Start, int>) &&
72 (std::same_as<Stop, slicing::none_t> ||
73 std::convertible_to<Stop, int>) &&
74 (std::same_as<Step, slicing::none_t> ||
75 std::convertible_to<Step, int>)
76 constexpr Slice(Start start, Stop stop, Step step) {
77 if constexpr (std::same_as<Step, slicing::none_t>) {
78 this->step = 1;
79 } else {
80 Assert(step != 0);
81
82 this->step = step;
83 }
84
85 // Avoid UB for step = -step if step is INT_MIN
86 if (this->step == std::numeric_limits<int>::min()) {
87 this->step = -std::numeric_limits<int>::max();
88 }
89
90 if constexpr (std::same_as<Start, slicing::none_t>) {
91 if (this->step < 0) {
92 this->start = std::numeric_limits<int>::max();
93 } else {
94 this->start = 0;
95 }
96 } else {
97 this->start = start;
98 }
99
100 if constexpr (std::same_as<Stop, slicing::none_t>) {
101 if (this->step < 0) {
102 this->stop = std::numeric_limits<int>::min();
103 } else {
104 this->stop = std::numeric_limits<int>::max();
105 }
106 } else {
107 this->stop = stop;
108 }
109 }
110
111 /**
112 * Adjusts start and end slice indices assuming a sequence of the specified
113 * length.
114 *
115 * @param length The sequence length.
116 * @return The slice length.
117 */
118 constexpr int Adjust(int length) {
119 Assert(step != 0);
120 Assert(step >= -std::numeric_limits<int>::max());
121
122 if (start < 0) {
123 start += length;
124
125 if (start < 0) {
126 start = (step < 0) ? -1 : 0;
127 }
128 } else if (start >= length) {
129 start = (step < 0) ? length - 1 : length;
130 }
131
132 if (stop < 0) {
133 stop += length;
134
135 if (stop < 0) {
136 stop = (step < 0) ? -1 : 0;
137 }
138 } else if (stop >= length) {
139 stop = (step < 0) ? length - 1 : length;
140 }
141
142 if (step < 0) {
143 if (stop < start) {
144 return (start - stop - 1) / -step + 1;
145 } else {
146 return 0;
147 }
148 } else {
149 if (start < stop) {
150 return (stop - start - 1) / step + 1;
151 } else {
152 return 0;
153 }
154 }
155 }
156};
157
158} // namespace sleipnir
#define SLEIPNIR_DLLEXPORT
Definition SymbolExports.hpp:34
Definition Slice.hpp:21
constexpr Slice()=default
Constructs a Slice.
constexpr int Adjust(int length)
Adjusts start and end slice indices assuming a sequence of the specified length.
Definition Slice.hpp:118
constexpr Slice(Start start, Stop stop)
Constructs a slice.
Definition Slice.hpp:59
constexpr Slice(Stop stop)
Constructs a slice.
Definition Slice.hpp:45
constexpr Slice(Start start, Stop stop, Step step)
Constructs a slice.
Definition Slice.hpp:76
static constexpr none_t _
Definition Slice.hpp:17
Definition Hessian.hpp:18
Implement std::hash so that hash_code can be used in STL containers.
Definition PointerIntPair.h:280
Definition Slice.hpp:16
#define Assert(condition)
Abort in C++.
Definition Assert.hpp:24