di 0.1.0
Loading...
Searching...
No Matches
encoding.h
Go to the documentation of this file.
1#pragma once
2
7#include "di/meta/core.h"
8#include "di/meta/language.h"
10#include "di/types/prelude.h"
13
14namespace di::meta {
15template<typename T>
17
18template<typename T>
20
21template<typename T>
23}
24
26namespace detail {
27 struct UniversalFunction {
28 template<typename T>
29 constexpr auto operator()(InPlaceType<T>) const -> bool {
32 } else {
33 return false;
34 }
35 }
36 };
37
38 struct ContiguousFunction {
39 template<typename T>
40 constexpr auto operator()(InPlaceType<T>) const -> bool {
43 } else {
44 return false;
45 }
46 }
47 };
48
49 struct NullTerminatedFunction {
50 template<typename T>
51 constexpr auto operator()(InPlaceType<T>) const -> bool {
54 } else {
55 return false;
56 }
57 }
58 };
59}
60
61constexpr inline auto universal = detail::UniversalFunction {};
62constexpr inline auto contiguous = detail::ContiguousFunction {};
63constexpr inline auto null_terminated = detail::NullTerminatedFunction {};
64
65template<typename T>
67
68template<typename T>
70
71template<typename T>
73
74namespace detail {
75 struct ValidateFunction {
76 template<typename T>
77 requires(Universal<T> ||
79 constexpr auto operator()(T const& encoding, Span<meta::EncodingCodeUnit<T> const> code_units) const -> bool {
80 if constexpr (universal(in_place_type<T>)) {
81 return true;
82 } else {
83 return function::tag_invoke(*this, encoding, code_units);
84 }
85 }
86 };
87
88 struct ValidByteOffsetFunction {
89 template<typename T, typename U = meta::EncodingCodeUnit<T>>
90 requires(Contiguous<T> ||
92 constexpr auto operator()(T const& encoding, Span<U const> code_units, size_t offset) const -> bool {
93 if constexpr (Contiguous<T>) {
94 return offset <= code_units.size();
95 } else {
96 return function::tag_invoke(*this, encoding, code_units, offset);
97 }
98 }
99 };
100
101 struct MakeIteratorFunction {
102 template<typename T, typename U = meta::EncodingCodeUnit<T>, typename Iter = meta::EncodingIterator<T>>
103 requires(concepts::TagInvocableTo<MakeIteratorFunction, Iter, T const&, Span<U const>, size_t> ||
104 concepts::ConstructibleFrom<Iter, U const*>)
105 constexpr auto operator()(T const& encoding, Span<U const> code_units, size_t offset) const -> Iter {
106 if constexpr (concepts::TagInvocableTo<MakeIteratorFunction, Iter, T const&, Span<U const>, size_t>) {
107 return function::tag_invoke(*this, encoding, code_units, offset);
108 } else {
109 return Iter(code_units.data() + offset);
110 }
111 }
112 };
113
114 struct IteratorDataFunction {
115 template<typename T, typename U = meta::EncodingCodeUnit<T>, typename Iter = meta::EncodingIterator<T>>
116 requires(concepts::ExplicitlyConvertibleTo<Iter, U const*>)
117 constexpr auto operator()(T const&, Span<U>, Iter iterator) const -> U* {
118 // NOTE: this is safe since we have a "mutable" storage to the underlying code units.
119 return const_cast<U*>(static_cast<U const*>(iterator));
120 }
121 };
122
123 struct ConvertToCodeUnitsFunction {
124 template<typename T, typename U = meta::EncodingCodeUnit<T>, typename P = meta::EncodingCodePoint<T>>
125 requires(concepts::TagInvocable<ConvertToCodeUnitsFunction, T const&, P> || concepts::SameAs<U, P>)
126 constexpr auto operator()(T const& encoding, P code_point) const -> concepts::ContainerOf<U> auto {
127 if constexpr (concepts::TagInvocable<ConvertToCodeUnitsFunction, T const&, P>) {
128 return function::tag_invoke(*this, encoding, code_point);
129 } else {
130 return view::single(code_point);
131 }
132 }
133 };
134}
135constexpr inline auto validate = detail::ValidateFunction {};
136constexpr inline auto valid_byte_offset = detail::ValidByteOffsetFunction {};
137constexpr inline auto make_iterator = detail::MakeIteratorFunction {};
138constexpr inline auto iterator_data = detail::IteratorDataFunction {};
139constexpr inline auto convert_to_code_units = detail::ConvertToCodeUnitsFunction {};
140
141namespace detail {
142 template<typename V, typename P>
145
146 struct CodePointViewFunction {
147 template<typename T, typename U = meta::EncodingCodeUnit<T>, typename P = meta::EncodingCodePoint<T>>
148 constexpr auto operator()(T const& encoding, Span<U const> code_units) const -> CodePointView<P> auto {
150 return function::tag_invoke(*this, encoding, code_units);
151 } else {
152 return container::View(make_iterator(encoding, code_units, 0),
153 make_iterator(encoding, code_units, code_units.size()));
154 }
155 }
156 };
157}
158
159constexpr inline auto code_point_view = detail::CodePointViewFunction {};
160
161namespace detail {
162 template<typename V>
164
165 struct UnicodeCodePointViewFunction {
166 template<typename T, typename U = meta::EncodingCodePoint<T>, typename P = meta::EncodingCodePoint<T>>
169 constexpr auto operator()(T const& encoding, Span<U const> code_units) const -> UnicodeCodePointView auto {
171 return function::tag_invoke(*this, encoding, code_units);
172 } else if constexpr (concepts::SameAs<P, c32>) {
173 return code_point_view(encoding, code_units);
174 } else {
175 return code_point_view(encoding, code_units) | view::transform([](auto code_point) {
176 return c32(code_point);
177 });
178 }
179 }
180 };
181
182 struct UnicodeCodePointUnwrapFunction {
183 template<typename T, typename Input, typename U = meta::EncodingCodePoint<T>,
184 typename P = meta::EncodingCodePoint<T>>
185 requires(concepts::TagInvocable<UnicodeCodePointUnwrapFunction, T const&, Input> || concepts::SameAs<P, c32> ||
186 concepts::ConstructibleFrom<c32, P>)
187 constexpr auto operator()(T const& encoding, Input it) const -> meta::EncodingIterator<T> {
188 if constexpr (concepts::TagInvocable<UnicodeCodePointViewFunction, T const&, Input>) {
189 return function::tag_invoke(*this, encoding, util::move(it));
190 } else if constexpr (concepts::SameAs<P, c32>) {
191 return it;
192 } else {
193 return it.base();
194 }
195 }
196 };
197}
198
199constexpr inline auto unicode_code_point_view = detail::UnicodeCodePointViewFunction {};
200constexpr inline auto unicode_code_point_unwrap = detail::UnicodeCodePointUnwrapFunction {};
201}
202
203namespace di::concepts {
204template<typename T>
206 requires {
210 } &&
211 requires(T const& encoding, size_t offset, vocab::Span<meta::EncodingCodeUnit<T> const> code_units,
212 vocab::Span<meta::EncodingCodeUnit<T>> mutable_code_units,
214 container::string::encoding::validate(encoding, code_units);
215 container::string::encoding::valid_byte_offset(encoding, code_units, offset);
216 container::string::encoding::make_iterator(encoding, code_units, offset);
217 container::string::encoding::iterator_data(encoding, mutable_code_units, iterator);
222 };
223
224template<typename T>
225concept HasEncoding = requires { typename meta::RemoveCVRef<T>::Encoding; };
226}
227
228namespace di::meta {
229template<concepts::HasEncoding T>
231}
232
234struct AssumeValid {};
235
236constexpr inline auto assume_valid = AssumeValid {};
237}
238
239namespace di {
240namespace encoding = container::string::encoding;
241}
Definition span_forward_declaration.h:10
Definition bidirectional_container.h:8
Definition operations.h:11
Definition container_of.h:9
Definition encoding.h:205
Definition forward_container.h:8
Definition encoding.h:225
Definition core.h:114
Definition operations.h:117
Definition tag_invoke.h:45
Definition tag_invoke.h:33
Definition tuple_like.h:38
Definition view.h:10
Definition any_storable.h:9
constexpr auto iterator(Ring &, RingIterator< Value const > iterator)
Definition ring_operations.h:78
Definition encoding.h:25
constexpr auto validate
Definition encoding.h:135
constexpr auto convert_to_code_units
Definition encoding.h:139
constexpr auto make_iterator
Definition encoding.h:137
constexpr auto universal
Definition encoding.h:61
constexpr auto valid_byte_offset
Definition encoding.h:136
constexpr auto unicode_code_point_unwrap
Definition encoding.h:200
constexpr auto unicode_code_point_view
Definition encoding.h:199
constexpr auto iterator_data
Definition encoding.h:138
constexpr auto code_point_view
Definition encoding.h:159
constexpr auto contiguous
Definition encoding.h:62
constexpr auto null_terminated
Definition encoding.h:63
constexpr auto assume_valid
Definition encoding.h:236
constexpr auto transform
Definition transform.h:28
constexpr auto single
Definition single.h:23
View(Iter, Sent) -> View< Iter, Sent >
constexpr tag_invoke_detail::TagInvokeFn tag_invoke
Definition tag_invoke.h:22
Definition merge_interfaces.h:6
constexpr auto TupleSize
Definition tuple_size.h:23
RemoveCVRef< T >::CodeUnit EncodingCodeUnit
Definition encoding.h:16
RemoveCVRef< T >::CodePoint EncodingCodePoint
Definition encoding.h:19
RemoveCV< RemoveReference< T > > RemoveCVRef
Definition core.h:74
meta::RemoveCVRef< T >::Encoding Encoding
Definition encoding.h:230
RemoveCVRef< T >::Iterator EncodingIterator
Definition encoding.h:22
constexpr auto code_point
Definition code_point_parser.h:35
char32_t c32
Definition char.h:6
Definition any_storable.h:9
constexpr auto in_place_type
Definition in_place_type.h:12
Definition in_place_type.h:5