proxsuite 0.6.7
The Advanced Proximal Optimization Toolbox
Loading...
Searching...
No Matches
fix_index.hpp
Go to the documentation of this file.
1#ifndef VEG_META_INT_FIX_HPP_7S9Y48TFS
2#define VEG_META_INT_FIX_HPP_7S9Y48TFS
3
8
9namespace proxsuite {
10namespace linalg {
11namespace veg {
12struct Dyn;
13template<isize N>
14struct Fix;
15
16namespace _detail {
17template<typename L, typename R>
19{
20 using Add = void;
21 using Sub = void;
22 using Mul = void;
23 using Div = void;
24 using Mod = void;
25
26 using CmpEq = void;
27 using CmpNEq = void;
28 using CmpLT = void;
29 using CmpLE = void;
30 using CmpGT = void;
31 using CmpGE = void;
32};
33
34namespace idx {
35namespace adl {
36template<typename T>
37struct IdxBase
38{};
39} // namespace adl
40} // namespace idx
41namespace _meta {
42template<typename T>
44{};
45template<isize N>
46struct is_fix<Fix<N>> : true_type
47{};
48} // namespace _meta
49} // namespace _detail
50
51namespace concepts {
52VEG_DEF_CONCEPT(typename T,
53 index,
55} // namespace concepts
56
57enum struct Ternary : unsigned char
58{
59 no,
60 maybe,
61 yes,
62};
63
64constexpr auto no = Ternary::no;
65constexpr auto maybe = Ternary::maybe;
66constexpr auto yes = Ternary::yes;
70
71template<Ternary T>
72struct Boolean;
73
74template<Ternary T>
75struct Boolean
76{
78 using type = meta::constant<Ternary, T>;
79
81 Unsafe /*tag*/) VEG_NOEXCEPT;
82 VEG_INLINE constexpr Boolean // NOLINT(hicpp-explicit-conversions)
84
86 VEG_NOEXCEPT->Boolean<T == yes ? no : yes>
87 {
88 return {};
89 }
90 VEG_NODISCARD VEG_INLINE explicit constexpr operator bool() const VEG_NOEXCEPT
91 {
92 return T == yes;
93 }
94};
95
96template<isize N>
98{
99 constexpr Fix() VEG_NOEXCEPT = default;
100 VEG_INLINE constexpr Fix(Dyn /*arg*/, Unsafe /*tag*/) VEG_NOEXCEPT;
101 VEG_INLINE constexpr Fix // NOLINT(hicpp-explicit-conversions)
102 (Dyn arg) VEG_NOEXCEPT;
104 requires((M != N)),
106 (/*arg*/, Fix<M>)) = delete;
107
114 {
115 return {};
116 }
118 VEG_NOEXCEPT->Fix<-N>
119 {
120 return {};
121 }
122
123#define VEG_OP(Op, Name, TypeName) \
124 VEG_TEMPLATE((typename R), \
125 requires(VEG_CONCEPT(index<R>)), \
126 VEG_NODISCARD VEG_INLINE constexpr auto \
127 operator Op, \
128 (b, R)) \
129 const VEG_NOEXCEPT->typename _detail::binary_traits<Fix, R>::TypeName \
130 { \
131 return _detail::binary_traits<Fix, R>::Name##_fn(*this, b); \
132 } \
133 VEG_NOM_SEMICOLON
134
135 VEG_OP(+, add, Add);
136 VEG_OP(-, sub, Sub);
137 VEG_OP(*, mul, Mul);
138
139#undef VEG_OP
140
142 (typename R),
143 requires(VEG_CONCEPT(index<R>) &&
145 VEG_NODISCARD VEG_INLINE constexpr auto
146 operator/,
147 (b, R))
149 {
151 }
152
154 (typename R),
155 requires(VEG_CONCEPT(index<R>) &&
157 VEG_NODISCARD VEG_INLINE constexpr auto
158 operator%,
159 (b, R))
161 {
163 }
164
165#define VEG_CMP(Name, TypeName, Op) \
166 VEG_TEMPLATE((typename R), \
167 requires(VEG_CONCEPT(index<R>)), \
168 VEG_NODISCARD VEG_INLINE constexpr auto \
169 operator Op, /* NOLINT */ \
170 (b, R)) \
171 const VEG_NOEXCEPT->typename _detail::binary_traits<Fix, R>::TypeName \
172 { \
173 return _detail::binary_traits<Fix, R>::cmp_##Name##_fn(*this, b); \
174 } \
175 VEG_NOM_SEMICOLON
176
177 VEG_CMP(eq, CmpEq, ==);
178 VEG_CMP(neq, CmpNEq, !=);
179 VEG_CMP(lt, CmpLT, <);
180 VEG_CMP(le, CmpLE, <=);
181 VEG_CMP(gt, CmpGT, >);
182 VEG_CMP(ge, CmpGE, >=);
183
184#undef VEG_CMP
185
186#undef VEG_CMP
187};
188
189namespace _detail {
190struct Error
191{
192 constexpr auto operator()(u64 const* fail = nullptr) const VEG_NOEXCEPT->u64
193 {
194 return *fail;
195 }
196};
197
198using parser = auto (*)(char, Error) -> u64;
199constexpr auto
201{
202 return (c == '0') ? 0 : (c == '1' ? 1 : e());
203}
204constexpr auto
206{
207 return (c >= '0' && c <= '7') ? u64(c - '0') : e();
208}
209constexpr auto
211{
212 return (c >= '0' && c <= '9') ? u64(c - '0') : e();
213}
214constexpr auto
216{
217 return (c >= '0' && c <= '9') //
218 ? u64(c - '0')
219 : (c >= 'a' && c <= 'f') //
220 ? u64(c - 'a')
221 : (c >= 'A' && c <= 'F') //
222 ? u64(c - 'A')
223 : e();
224}
225
226constexpr auto
228{
229 return radix == 2
231 : (radix == 8
233 : (radix == 10 ? parse_digit_10
234 : (radix == 16 ? parse_digit_16 : nullptr)));
235}
236
237constexpr auto
239{
240 return (len == 0) ? 0
241 : radix * parse_num(str, len - 1, radix, e) +
242 (parse_digit(radix)(str[len - 1], e));
243}
244
245constexpr auto
246parse_int(char const* str, u64 len, Error e) VEG_NOEXCEPT -> u64
247{
248 return (len == 0) //
249 ? e()
250 : ((str[0] == '0') //
251 ? ((len == 1) //
252 ? 0
253 : (str[1] == 'b' || str[1] == 'B') //
254 ? parse_num(str + 2, len - 2, 2, e)
255 : (str[1] == 'x' || str[1] == 'X') //
256 ? parse_num(str + 2, len - 2, 16, e)
257 : parse_num(str + 1, len - 1, 8, e))
258 : parse_num(str, len, 10, e));
259}
260
261template<char... Chars>
263{
264 static constexpr char value[] = { Chars... };
265};
266
267template<isize N, isize M>
268struct binary_traits<Fix<N>, Fix<M>>
269{
270
271#define VEG_OP(Name, TypeName, Op) \
272 using TypeName /* NOLINT(bugprone-macro-parentheses) */ = \
273 Fix<isize(usize(isize{ N }) Op usize(isize{ M }))>; \
274 VEG_NODISCARD VEG_INLINE static constexpr auto Name##_fn(Fix<N>, Fix<M>) \
275 VEG_NOEXCEPT->TypeName \
276 { \
277 return {}; \
278 } \
279 static_assert(true, "")
280
281#define VEG_CMP(Name, TypeName, Op) \
282 using TypeName /* NOLINT(bugprone-macro-parentheses) */ = \
283 Boolean<(N Op M) ? yes : no>; \
284 VEG_NODISCARD VEG_INLINE static constexpr auto Name##_fn(Fix<N>, Fix<M>) \
285 VEG_NOEXCEPT->TypeName \
286 { \
287 return {}; \
288 } \
289 static_assert(true, "")
290
293 VEG_OP(mul, Mul, *);
300
301 using Div = meta::if_t<M == 0, void, Fix<N / (M != 0 ? M : 1)>>;
302 using Mod = meta::if_t<M == 0, void, Fix<N % (M != 0 ? M : 1)>>;
303
304 VEG_NODISCARD VEG_INLINE static constexpr auto div_fn(Fix<N> /*a*/,
305 Fix<M> /*b*/)
307 {
308 return Div();
309 }
310 VEG_NODISCARD VEG_INLINE static constexpr auto mod_fn(Fix<N> /*a*/,
311 Fix<M> /*b*/)
313 {
314 return Mod();
315 }
316
317#undef VEG_OP
318#undef VEG_CMP
319};
320namespace idx {
321namespace adl {
322} // namespace adl
323} // namespace idx
324} // namespace _detail
325
326inline namespace literals {
327template<char... Chars>
328VEG_INLINE constexpr auto
329operator"" _c() VEG_NOEXCEPT
330{
331 return Fix<_detail::parse_int(
333}
334} // namespace literals
335} // namespace veg
336} // namespace linalg
337} // namespace proxsuite
338
340#endif /* end of include guard VEG_META_INT_FIX_HPP_7S9Y48TFS */
#define VEG_OP(Op, Name, TypeName)
Definition dyn_index.hpp:75
#define VEG_CONCEPT(...)
Definition macros.hpp:1243
#define VEG_TEMPLATE(TParams, Constraint, Attr_Name,...)
Definition macros.hpp:385
#define VEG_INLINE
Definition macros.hpp:118
#define VEG_DEF_CONCEPT(Tpl, Name,...)
Definition macros.hpp:321
constexpr auto parse_digit_10(char c, Error e) VEG_NOEXCEPT -> u64
constexpr auto parse_digit_16(char c, Error e) VEG_NOEXCEPT -> u64
constexpr auto parse_int(char const *str, u64 len, Error e) VEG_NOEXCEPT -> u64
constexpr auto parse_digit_2(char c, Error e) VEG_NOEXCEPT -> u64
constexpr auto parse_num(char const *str, u64 len, u64 radix, Error e) VEG_NOEXCEPT -> u64
constexpr auto parse_digit(u64 radix) VEG_NOEXCEPT -> parser
constexpr auto parse_digit_8(char c, Error e) VEG_NOEXCEPT -> u64
typename _detail::_meta::conditional_< B >::template type< T, F > if_t
Definition core.hpp:83
constexpr auto maybe
Definition fix_index.hpp:65
constexpr auto no
Definition fix_index.hpp:64
constexpr auto yes
Definition fix_index.hpp:66
std::uint64_t u64
Definition typedefs.hpp:46
_detail::_meta::make_signed< usize >::Type isize
Definition typedefs.hpp:43
#define VEG_NODISCARD
Definition prologue.hpp:97
#define VEG_NOEXCEPT
Definition prologue.hpp:30
constexpr Boolean() VEG_NOEXCEPT=default
VEG_NODISCARD VEG_INLINE constexpr auto operator+() const VEG_NOEXCEPT -> Fix
VEG_TEMPLATE((typename R), requires(VEG_CONCEPT(index< R >) &&VEG_CONCEPT(index< typename _detail::binary_traits< Fix, R >::Div >)), VEG_NODISCARD VEG_INLINE constexpr auto operator/,(b, R)) const VEG_NOEXCEPT -> typename _detail::binary_traits< Fix, R >::Div
VEG_NODISCARD VEG_INLINE constexpr auto operator-() const VEG_NOEXCEPT -> Fix<-N >
VEG_TEMPLATE((typename R), requires(VEG_CONCEPT(index< R >) &&VEG_CONCEPT(index< typename _detail::binary_traits< Fix, R >::Mod >)), VEG_NODISCARD VEG_INLINE constexpr auto operator%,(b, R)) const VEG_NOEXCEPT -> typename _detail::binary_traits< Fix, R >::Mod
constexpr Fix() VEG_NOEXCEPT=default
VEG_CMP(neq, CmpNEq, !=)
constexpr auto operator()(u64 const *fail=nullptr) const VEG_NOEXCEPT -> u64
VEG_NODISCARD static VEG_INLINE constexpr auto mod_fn(Fix< N >, Fix< M >) VEG_NOEXCEPT -> Mod
meta::if_t< M==0, void, Fix< N %(M !=0 ? M :1)> > Mod
meta::if_t< M==0, void, Fix< N/(M !=0 ? M :1)> > Div
VEG_NODISCARD static VEG_INLINE constexpr auto div_fn(Fix< N >, Fix< M >) VEG_NOEXCEPT -> Div