Skip to content

Commit 375962f

Browse files
committed
Add cow_vector
In majority of cases, a copy-on-write type should be a vector, cow_vector reduces reference indirection from cow_ptr Add basic_iterator For common type-safe contigious iterator functionality Replace `cow_ptr<std::vector>` in basic_signal with `cow_vector`
1 parent 94d0812 commit 375962f

File tree

6 files changed

+1452
-23
lines changed

6 files changed

+1452
-23
lines changed
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
#pragma once
2+
3+
#include <concepts>
4+
5+
#include "openvic-simulation/utility/Utility.hpp"
6+
7+
namespace OpenVic {
8+
template<typename Pointer, typename ContainerTag>
9+
struct basic_iterator {
10+
using iterator_type = Pointer;
11+
using value_type = typename std::iterator_traits<iterator_type>::value_type;
12+
using difference_type = typename std::iterator_traits<iterator_type>::difference_type;
13+
using pointer = typename std::iterator_traits<iterator_type>::pointer;
14+
using reference = typename std::iterator_traits<iterator_type>::reference;
15+
using iterator_category = typename std::iterator_traits<iterator_type>::iterator_category;
16+
using iterator_concept = std::contiguous_iterator_tag;
17+
18+
OV_ALWAYS_INLINE constexpr basic_iterator() = default;
19+
OV_ALWAYS_INLINE constexpr basic_iterator(Pointer const& ptr) : _current { ptr } {}
20+
21+
template<std::convertible_to<Pointer> It>
22+
OV_ALWAYS_INLINE constexpr basic_iterator(basic_iterator<It, ContainerTag> const& i) : _current(i.base()) {}
23+
24+
[[nodiscard]] OV_ALWAYS_INLINE constexpr reference operator*() const {
25+
return *_current;
26+
}
27+
28+
[[nodiscard]] OV_ALWAYS_INLINE constexpr pointer operator->() const {
29+
return _current;
30+
}
31+
32+
OV_ALWAYS_INLINE constexpr basic_iterator& operator++() {
33+
++_current;
34+
return *this;
35+
}
36+
37+
OV_ALWAYS_INLINE constexpr basic_iterator operator++(int) {
38+
return basic_iterator(_current++);
39+
}
40+
41+
OV_ALWAYS_INLINE constexpr basic_iterator& operator--() {
42+
--_current;
43+
return *this;
44+
}
45+
46+
OV_ALWAYS_INLINE constexpr basic_iterator operator--(int) {
47+
return basic_iterator(_current--);
48+
}
49+
50+
[[nodiscard]] OV_ALWAYS_INLINE constexpr reference operator[](difference_type index) const {
51+
return _current[index];
52+
}
53+
54+
OV_ALWAYS_INLINE constexpr basic_iterator& operator+=(difference_type index) {
55+
_current += index;
56+
return *this;
57+
}
58+
59+
[[nodiscard]] OV_ALWAYS_INLINE constexpr basic_iterator operator+(difference_type index) const {
60+
return basic_iterator(_current + index);
61+
}
62+
63+
OV_ALWAYS_INLINE constexpr basic_iterator& operator-=(difference_type index) {
64+
_current -= index;
65+
return *this;
66+
}
67+
68+
[[nodiscard]] OV_ALWAYS_INLINE constexpr basic_iterator operator-(difference_type index) const {
69+
return basic_iterator(_current - index);
70+
}
71+
72+
[[nodiscard]] OV_ALWAYS_INLINE constexpr iterator_type const& base() const {
73+
return _current;
74+
}
75+
76+
protected:
77+
iterator_type _current {};
78+
};
79+
80+
template<typename PtrL, typename PtrR, typename ContainerTag>
81+
[[nodiscard]] OV_ALWAYS_INLINE constexpr bool operator==( //
82+
basic_iterator<PtrL, ContainerTag> const& lhs, basic_iterator<PtrR, ContainerTag> const& rhs
83+
)
84+
requires requires {
85+
{ lhs.base() == rhs.base() } -> std::convertible_to<bool>;
86+
}
87+
{
88+
return lhs.base() == rhs.base();
89+
}
90+
91+
template<typename PtrL, typename PtrR, typename ContainerTag>
92+
[[nodiscard]] OV_ALWAYS_INLINE constexpr auto operator<=>( //
93+
basic_iterator<PtrL, ContainerTag> const& lhs, basic_iterator<PtrR, ContainerTag> const& rhs
94+
) {
95+
return three_way(lhs.base(), rhs.base());
96+
}
97+
98+
template<typename Ptr, typename ContainerTag>
99+
[[nodiscard]] OV_ALWAYS_INLINE constexpr bool operator==( //
100+
basic_iterator<Ptr, ContainerTag> const& lhs, basic_iterator<Ptr, ContainerTag> const& rhs
101+
)
102+
requires requires {
103+
{ lhs.base() == rhs.base() } -> std::convertible_to<bool>;
104+
}
105+
{
106+
return lhs.base() == rhs.base();
107+
}
108+
109+
template<typename Ptr, typename ContainerTag>
110+
[[nodiscard]] OV_ALWAYS_INLINE constexpr auto operator<=>( //
111+
basic_iterator<Ptr, ContainerTag> const& lhs, basic_iterator<Ptr, ContainerTag> const& rhs
112+
) {
113+
return three_way(lhs.base(), rhs.base());
114+
}
115+
116+
template<typename ItL, typename ItR, typename ContainerTag>
117+
[[nodiscard]] OV_ALWAYS_INLINE constexpr auto operator-( //
118+
basic_iterator<ItL, ContainerTag> const& lhs, basic_iterator<ItR, ContainerTag> const& rhs
119+
) -> decltype(lhs.base() - rhs.base()) {
120+
return lhs.base() - rhs.base();
121+
}
122+
123+
template<typename It, typename ContainerTag>
124+
[[nodiscard]] OV_ALWAYS_INLINE constexpr typename basic_iterator<It, ContainerTag>::difference_type operator-( //
125+
basic_iterator<It, ContainerTag> const& lhs, basic_iterator<It, ContainerTag> const& rhs
126+
) {
127+
return lhs.base() - rhs.base();
128+
}
129+
130+
template<typename It, typename ContainerTag>
131+
[[nodiscard]] OV_ALWAYS_INLINE constexpr basic_iterator<It, ContainerTag> operator+( //
132+
typename basic_iterator<It, ContainerTag>::difference_type n, basic_iterator<It, ContainerTag> const& i
133+
) {
134+
return basic_iterator<It, ContainerTag>(i.base() + n);
135+
}
136+
137+
template<typename It, typename ContainerTag>
138+
[[nodiscard]] OV_ALWAYS_INLINE constexpr It iterator_base(basic_iterator<It, ContainerTag> it) {
139+
return it.base();
140+
}
141+
142+
template<typename It>
143+
[[nodiscard]] OV_ALWAYS_INLINE constexpr It iterator_base(It it) {
144+
return it;
145+
}
146+
147+
template<typename It>
148+
constexpr inline auto iterator_base(std::reverse_iterator<It> it)
149+
-> decltype(std::make_reverse_iterator(iterator_base(it.base()))) {
150+
return std::make_reverse_iterator(iterator_base(it.base()));
151+
}
152+
153+
template<typename It>
154+
constexpr inline auto iterator_base(std::move_iterator<It> it)
155+
-> decltype(std::make_move_iterator(iterator_base(it.base()))) {
156+
return std::make_move_iterator(iterator_base(it.base()));
157+
}
158+
159+
template<typename From, typename To>
160+
[[nodiscard]] constexpr inline From unwrap_iterator(From from, To res) {
161+
return from + (iterator_base(res) - iterator_base(from));
162+
}
163+
164+
template<typename It>
165+
[[nodiscard]] OV_ALWAYS_INLINE constexpr It unwrap_iterator(It const&, It res) {
166+
return res;
167+
}
168+
};

src/openvic-simulation/types/CowPtr.hpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -174,21 +174,11 @@ namespace OpenVic {
174174
}
175175

176176
namespace cow {
177-
template<typename T>
178-
T const& read(T const& v) {
179-
return v;
180-
}
181-
182177
template<utility::specialization_of<cow_ptr> T>
183178
typename T::element_type const& read(T& v) {
184179
return v.read();
185180
}
186181

187-
template<typename T>
188-
T& write(T& v) {
189-
return v;
190-
}
191-
192182
template<utility::specialization_of<cow_ptr> T>
193183
typename T::element_type& write(T& v) {
194184
return v.write();

0 commit comments

Comments
 (0)