Line data Source code
1 : /**
2 : Copyright (c) 2020-2022 Roman Katuntsev <sbkarr@stappler.org>
3 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
4 :
5 : Permission is hereby granted, free of charge, to any person obtaining a copy
6 : of this software and associated documentation files (the "Software"), to deal
7 : in the Software without restriction, including without limitation the rights
8 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 : copies of the Software, and to permit persons to whom the Software is
10 : furnished to do so, subject to the following conditions:
11 :
12 : The above copyright notice and this permission notice shall be included in
13 : all copies or substantial portions of the Software.
14 :
15 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 : THE SOFTWARE.
22 : **/
23 :
24 : #ifndef STAPPLER_CORE_STRING_SPSPANVIEW_H_
25 : #define STAPPLER_CORE_STRING_SPSPANVIEW_H_
26 :
27 : #include "SPCommon.h"
28 :
29 : namespace STAPPLER_VERSIONIZED stappler {
30 :
31 : template <typename _Type>
32 : class SpanView {
33 : public:
34 : using Type = _Type;
35 : using Self = SpanView<Type>;
36 : using iterator = memory::pointer_iterator<const Type, const Type *, const Type &>;
37 : using reverse_iterator = std::reverse_iterator<iterator>;
38 :
39 196885 : constexpr SpanView() : ptr(nullptr), len(0) { }
40 2727187 : constexpr SpanView(const Type *p, size_t l) : ptr(p), len(l) { }
41 : constexpr SpanView(const Type *begin, const Type *end) : ptr(begin), len(end - begin) { }
42 :
43 : static Self alloc(memory::pool_t *pool, size_t count) {
44 : auto mem = (Type *)memory::pool::palloc(pool, count * sizeof(Type));
45 : return Self(mem, count);
46 : }
47 :
48 : template< class InputIt >
49 : SpanView( InputIt first, InputIt last) : ptr(&(*first)), len(std::distance(first, last)) { }
50 :
51 : SpanView(InitializerList<Type> il) : ptr(il.begin()), len(il.size()) { }
52 :
53 2789847 : SpanView(const std::vector<Type> &vec) : ptr(vec.data()), len(vec.size()) { }
54 : SpanView(const std::vector<Type> &vec, size_t count) : ptr(vec.data()), len(std::min(vec.size(), count)) { }
55 6607 : SpanView(const std::vector<Type> &vec, size_t off, size_t count) : ptr(vec.data() + off), len(std::min(vec.size() - off, count)) { }
56 :
57 142348 : SpanView(const memory::vector<Type> &vec) : ptr(vec.data()), len(vec.size()) { }
58 : SpanView(const memory::vector<Type> &vec, size_t count) : ptr(vec.data()), len(std::min(vec.size(), count)) { }
59 : SpanView(const memory::vector<Type> &vec, size_t off, size_t count) : ptr(vec.data() + off), len(std::min(vec.size() - off, count)) { }
60 :
61 : template<size_t Size>
62 7346 : SpanView(const Type (&array)[Size]) : ptr(&array[0]), len(Size) { }
63 :
64 : template <size_t Size>
65 126 : SpanView(const std::array<Type, Size> &arr) : ptr(arr.data()), len(arr.size()) { }
66 :
67 621653 : SpanView(const Self &v) : ptr(v.data()), len(v.size()) { }
68 : SpanView(const Self &v, size_t len) : ptr(v.data()), len(std::min(len, v.size())) { }
69 7396 : SpanView(const Self &v, size_t pos, size_t len) : ptr(v.data() + pos), len(std::min(len, v.size() - pos)) { }
70 :
71 : Self &operator=(const memory::vector<Type> &vec) { ptr = vec.data(); len = vec.size(); return *this; }
72 84 : Self &operator=(const std::vector<Type> &vec) { ptr = vec.data(); len = vec.size(); return *this; }
73 :
74 : template <size_t Size>
75 : Self &operator=(const std::array<Type, Size> &arr) { ptr = arr.data(); len = arr.size(); return *this; }
76 196691 : Self &operator=(const Self &v) { ptr = v.data(); len = v.size(); return *this; }
77 :
78 : Self & set(const Type *p, size_t l) { ptr = p; len = l; return *this; }
79 :
80 : void offset(size_t l) { if (l > len) { len = 0; } else { ptr += l; len -= l; } }
81 :
82 2474457 : const Type *data() const { return ptr; }
83 10970885 : size_t size() const { return len; }
84 :
85 1932886 : iterator begin() const noexcept { return iterator(ptr); }
86 1934834 : iterator end() const noexcept { return iterator(ptr + len); }
87 :
88 : reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); }
89 : reverse_iterator rend() const noexcept { return reverse_iterator(begin()); }
90 :
91 : bool operator > (const size_t &val) const { return len > val; }
92 : bool operator >= (const size_t &val) const { return len >= val; }
93 : bool operator < (const size_t &val) const { return len < val; }
94 : bool operator <= (const size_t &val) const { return len <= val; }
95 :
96 : Self & operator ++ () { if (len > 0) { ptr ++; len --; } return *this; }
97 : Self operator ++ (int) { auto tmp = *this; if (len > 0) { ptr ++; len --; } return tmp; }
98 : Self & operator += (size_t l) { if (len > 0) { offset(l); } return *this; }
99 :
100 : bool operator == (const Self &other) const { return len == other.size() && std::equal(begin(), end(), other.begin()); }
101 : bool operator != (const Self &other) const { return len != other.size() || !std::equal(begin(), end(), other.begin()); }
102 :
103 269024 : const Type & front() const { return *ptr; }
104 381509 : const Type & back() const { return ptr[len - 1]; }
105 :
106 5495119 : const Type & at(const size_t &s) const { return ptr[s]; }
107 2423502 : const Type & operator[] (const size_t &s) const { return ptr[s]; }
108 : const Type & operator * () const { return *ptr; }
109 :
110 : void clear() { len = 0; }
111 286712 : bool empty() const { return len == 0 || !ptr; }
112 :
113 : Self first(size_t count) const { return Self(ptr, std::min(count, len)); }
114 148986 : Self last(size_t count) const { return (count < len) ? Self(ptr + len - count, count) : Self(ptr, len); }
115 :
116 : Self pop_front(size_t count = 1) { auto ret = first(count); offset(count); return ret; }
117 148986 : Self pop_back(size_t count = 1) { auto ret = last(count); len -= ret.size(); return ret; }
118 :
119 : template <typename Interface>
120 64853 : auto vec() const -> typename Interface::template VectorType<Type> {
121 64853 : return typename Interface::template VectorType<Type>(ptr, ptr + len);
122 : }
123 :
124 : BytesView bytes() const {
125 : return BytesView((uint8_t *)ptr, len * sizeof(Type));
126 : }
127 :
128 139086 : Self pdup(memory::pool_t *p = nullptr) const {
129 139086 : if (!p) {
130 0 : p = memory::pool::acquire();
131 : }
132 139086 : auto buf = (Type *)memory::pool::palloc(p, this->size() * sizeof(Type));
133 139086 : memcpy(buf, this->data(), this->size() * sizeof(Type));
134 139086 : return Self(buf, this->size());
135 : }
136 :
137 : size_t hash() const {
138 : if constexpr (sizeof(size_t) == 4) {
139 : return hash::hash32((const char *)data(), size() * sizeof(_Type));
140 : } else {
141 : return hash::hash64((const char *)data(), size() * sizeof(_Type));
142 : }
143 : }
144 :
145 7396 : Self sub(size_t pos = 0, size_t len = maxOf<size_t>()) const { return Self(*this, pos, len); }
146 :
147 : protected:
148 : const Type *ptr = nullptr;
149 : size_t len = 0;
150 : };
151 :
152 : template<typename _Tp> inline bool
153 : operator<(const SpanView<_Tp>& __x, const SpanView<_Tp>& __y) {
154 : return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
155 : }
156 :
157 : /// Based on operator<
158 : template<typename _Tp> inline bool
159 : operator>(const SpanView<_Tp>& __x, const SpanView<_Tp>& __y) {
160 : return __y < __x;
161 : }
162 :
163 : /// Based on operator<
164 : template<typename _Tp> inline bool
165 : operator<=(const SpanView<_Tp>& __x, const SpanView<_Tp>& __y) {
166 : return !(__y < __x);
167 : }
168 :
169 : /// Based on operator<
170 : template<typename _Tp> inline bool
171 : operator>=(const SpanView<_Tp>& __x, const SpanView<_Tp>& __y) {
172 : return !(__x < __y);
173 : }
174 :
175 : template <typename Type>
176 : auto makeSpanView(const std::vector<Type> &vec) -> SpanView<Type> {
177 : return SpanView<Type>(vec);
178 : }
179 :
180 : template <typename Type>
181 3175 : auto makeSpanView(const memory::vector<Type> &vec) -> SpanView<Type> {
182 3175 : return SpanView<Type>(vec);
183 : }
184 :
185 : template <typename Type, size_t Size>
186 : auto makeSpanView(const std::array<Type, Size> &vec) -> SpanView<Type> {
187 : return SpanView<Type>(vec);
188 : }
189 :
190 : template <typename Type>
191 1391717 : auto makeSpanView(const Type *ptr, size_t size) -> SpanView<Type> {
192 1391717 : return SpanView<Type>(ptr, size);
193 : }
194 :
195 : }
196 :
197 : namespace std {
198 :
199 : template<typename Value>
200 : struct hash<STAPPLER_VERSIONIZED_NAMESPACE::SpanView<Value>> {
201 : size_t operator() (const STAPPLER_VERSIONIZED_NAMESPACE::SpanView<Value> &value) {
202 : return value.hash();
203 : }
204 : };
205 :
206 : }
207 :
208 : #endif /* STAPPLER_CORE_STRING_SPSPANVIEW_H_ */
|