Skip to content

Commit 02bdb12

Browse files
committed
Make Range conditionally implement Iterator
Add a Step concept for internal library use which is implemented for integer types and use it to implement the Range iterator when Range is holding an integer type
1 parent 5b0e54d commit 02bdb12

17 files changed

+586
-108
lines changed

subspace/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ target_sources(subspace PUBLIC
5353
"fn/fn_impl.h"
5454
"iter/__private/iterator_end.h"
5555
"iter/__private/iterator_loop.h"
56+
"iter/__private/step.h"
5657
"iter/boxed_iterator.h"
5758
"iter/filter.h"
5859
"iter/from_iterator.h"
@@ -61,8 +62,8 @@ target_sources(subspace PUBLIC
6162
"iter/iterator_defn.h"
6263
"iter/map.h"
6364
"iter/once.h"
64-
"iter/sized_iterator.h"
6565
"iter/reverse.h"
66+
"iter/sized_iterator.h"
6667
"macros/__private/compiler_bugs.h"
6768
"macros/always_inline.h"
6869
"macros/builtin.h"

subspace/iter/__private/step.h

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// Copyright 2023 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#pragma once
16+
17+
#include "subspace/marker/unsafe.h"
18+
#include "subspace/num/integer_concepts.h"
19+
#include "subspace/num/types.h"
20+
21+
namespace sus::option {
22+
template <class T>
23+
class Option;
24+
}
25+
26+
namespace sus::num {
27+
struct usize;
28+
}
29+
30+
namespace sus::iter::__private {
31+
32+
template <::sus::num::Integer T>
33+
constexpr T step_forward(T l) noexcept {
34+
// SAFETY: All `Integer` can hold `1`.
35+
return l + T::from_unchecked(::sus::marker::unsafe_fn, 1);
36+
}
37+
template <::sus::num::Integer T>
38+
constexpr T step_backward(T l) noexcept {
39+
// SAFETY: All `Integer` can hold `1`.
40+
return l - T::from_unchecked(::sus::marker::unsafe_fn, 1);
41+
}
42+
template <::sus::num::Integer T>
43+
constexpr Option<T> step_forward_checked(T l) noexcept {
44+
// SAFETY: All `Integer` can hold `1`.
45+
return l.checked_add(T::from_unchecked(::sus::marker::unsafe_fn, 1));
46+
}
47+
template <::sus::num::Integer T>
48+
constexpr Option<T> step_backward_checked(T l) noexcept {
49+
// SAFETY: All `Integer` can hold `1`.
50+
return l.checked_sub(T::from_unchecked(::sus::marker::unsafe_fn, 1));
51+
}
52+
template <::sus::num::Integer T>
53+
constexpr T step_forward_by(T l, ::sus::num::usize steps) noexcept {
54+
return l + T::from(steps);
55+
}
56+
template <::sus::num::Integer T>
57+
constexpr T step_backward_by(T l, ::sus::num::usize steps) noexcept {
58+
return l - T::from(steps);
59+
}
60+
template <::sus::num::Integer T>
61+
constexpr Option<T> step_forward_by_checked(T l,
62+
::sus::num::usize steps) noexcept {
63+
return T::try_from(steps).ok().and_then(
64+
[&l](T steps) { return l.checked_add(::sus::marker::unsafe_fn, steps); });
65+
}
66+
template <::sus::num::Integer T>
67+
constexpr Option<T> step_backward_by_checked(T l,
68+
::sus::num::usize steps) noexcept {
69+
return T::try_from(steps).ok().and_then(
70+
[&l](T steps) { return l.checked_sub(::sus::marker::unsafe_fn, steps); });
71+
}
72+
template <::sus::num::Integer T>
73+
constexpr Option<::sus::num::usize> steps_between(const T& l,
74+
const T& r) noexcept {
75+
return r.checked_sub(l).and_then(
76+
[](T steps) { return ::sus::num::usize::try_from(steps).ok(); });
77+
}
78+
79+
/// Objects that have a notion of successor and predecessor operations.
80+
///
81+
/// The successor operations move towards values that compare greater. The
82+
/// predecessor operations moves toward values that compare lesser.
83+
template <class T>
84+
concept Step = requires(const T& t, ::sus::num::usize n) {
85+
// Required methods.
86+
{ ::sus::iter::__private::step_forward(t) } -> std::same_as<T>;
87+
{ ::sus::iter::__private::step_backward(t) } -> std::same_as<T>;
88+
{
89+
::sus::iter::__private::step_forward_checked(t)
90+
} -> std::same_as<::sus::option::Option<T>>;
91+
{
92+
::sus::iter::__private::step_backward_checked(t)
93+
} -> std::same_as<::sus::option::Option<T>>;
94+
{ ::sus::iter::__private::step_forward_by(t, n) } -> std::same_as<T>;
95+
{ ::sus::iter::__private::step_backward_by(t, n) } -> std::same_as<T>;
96+
{
97+
::sus::iter::__private::step_forward_by_checked(t, n)
98+
} -> std::same_as<::sus::option::Option<T>>;
99+
{
100+
::sus::iter::__private::step_backward_by_checked(t, n)
101+
} -> std::same_as<::sus::option::Option<T>>;
102+
{
103+
::sus::iter::__private::steps_between(t, t)
104+
} -> std::same_as<::sus::option::Option<::sus::num::usize>>;
105+
};
106+
107+
} // namespace sus::iter::__private

subspace/num/__private/float_macros.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -192,27 +192,27 @@ class Array;
192192
constexpr inline T operator-() const { return T(-primitive_value); }
193193

194194
#define _sus__float_binary_ops(T) \
195-
/** sus::concepts::Add<##T##> trait. \
195+
/** sus::num::Add<##T##> trait. \
196196
* #[doc.overloads=float##T##.+] */ \
197197
friend constexpr inline T operator+(const T& l, const T& r) noexcept { \
198198
return l.primitive_value + r.primitive_value; \
199199
} \
200-
/** sus::concepts::Sub<##T##> trait. \
200+
/** sus::num::Sub<##T##> trait. \
201201
* #[doc.overloads=float##T##.-] */ \
202202
friend constexpr inline T operator-(const T& l, const T& r) noexcept { \
203203
return l.primitive_value - r.primitive_value; \
204204
} \
205-
/** sus::concepts::Mul<##T##> trait. \
205+
/** sus::num::Mul<##T##> trait. \
206206
* #[doc.overloads=float##T##.*] */ \
207207
friend constexpr inline T operator*(const T& l, const T& r) noexcept { \
208208
return l.primitive_value * r.primitive_value; \
209209
} \
210-
/** sus::concepts::Div<##T##> trait. \
210+
/** sus::num::Div<##T##> trait. \
211211
* #[doc.overloads=float##T##./] */ \
212212
friend constexpr inline T operator/(const T& l, const T& r) noexcept { \
213213
return l.primitive_value / r.primitive_value; \
214214
} \
215-
/** sus::concepts::Rem<##T##> trait. \
215+
/** sus::num::Rem<##T##> trait. \
216216
* \
217217
* The remainder from the division of two floats. \
218218
* \
@@ -228,23 +228,23 @@ class Array;
228228
static_assert(true)
229229

230230
#define _sus__float_mutable_ops(T) \
231-
/** sus::concepts::AddAssign<##T##> trait. */ \
231+
/** sus::num::AddAssign<##T##> trait. */ \
232232
constexpr inline void operator+=(T r)& noexcept { \
233233
primitive_value += r.primitive_value; \
234234
} \
235-
/** sus::concepts::SubAssign<##T##> trait. */ \
235+
/** sus::num::SubAssign<##T##> trait. */ \
236236
constexpr inline void operator-=(T r)& noexcept { \
237237
primitive_value -= r.primitive_value; \
238238
} \
239-
/** sus::concepts::MulAssign<##T##> trait. */ \
239+
/** sus::num::MulAssign<##T##> trait. */ \
240240
constexpr inline void operator*=(T r)& noexcept { \
241241
primitive_value *= r.primitive_value; \
242242
} \
243-
/** sus::concepts::DivAssign<##T##> trait. */ \
243+
/** sus::num::DivAssign<##T##> trait. */ \
244244
constexpr inline void operator/=(T r)& noexcept { \
245245
primitive_value /= r.primitive_value; \
246246
} \
247-
/** sus::concepts::RemAssign<##T##> trait. \
247+
/** sus::num::RemAssign<##T##> trait. \
248248
* \
249249
* Assigns the remainder from the division of two floats. \
250250
* \

0 commit comments

Comments
 (0)