11module ;
22
33#include < compare>
4+ #include < concepts>
45#include < expected>
56#include < type_traits>
67#include < utility>
@@ -67,6 +68,21 @@ using primitive_dispatch_result_t = std::expected<meta::make_primitive_t<
6768 typename meta::traits<Lhs>::policies>,
6869 ErrorPayload>;
6970
71+ template <typename T>
72+ concept underlying_operand = underlying_type<std::remove_cvref_t <T>>;
73+
74+ template <primitive_instance Primitive, underlying_operand Underlying>
75+ using mixed_bridge_primitive_t = meta::make_primitive_t <
76+ std::remove_cvref_t <Underlying>, typename meta::traits<Primitive>::policies>;
77+
78+ template <operation OpTag, primitive_instance Primitive,
79+ underlying_operand Underlying,
80+ typename ErrorPayload = policy::error::kind>
81+ using mixed_primitive_dispatch_result_t =
82+ primitive_dispatch_result_t <OpTag, Primitive,
83+ mixed_bridge_primitive_t <Primitive, Underlying>,
84+ ErrorPayload>;
85+
7086template <primitive_instance Lhs, primitive_instance Rhs,
7187 typename ErrorPayload = policy::error::kind>
7288using three_way_dispatch_result_t = std::expected<
@@ -75,6 +91,25 @@ using three_way_dispatch_result_t = std::expected<
7591 ErrorPayload>::common_rep>,
7692 ErrorPayload>;
7793
94+ template <primitive_instance Primitive, underlying_operand Underlying,
95+ typename ErrorPayload = policy::error::kind>
96+ using mixed_three_way_dispatch_result_t =
97+ three_way_dispatch_result_t <Primitive,
98+ mixed_bridge_primitive_t <Primitive, Underlying>,
99+ ErrorPayload>;
100+
101+ template <operation OpTag, underlying_operand Underlying,
102+ primitive_instance Primitive,
103+ typename ErrorPayload = policy::error::kind>
104+ using flipped_mixed_primitive_dispatch_result_t = primitive_dispatch_result_t <
105+ OpTag, mixed_bridge_primitive_t <Primitive, Underlying>, Primitive,
106+ ErrorPayload>;
107+
108+ template <underlying_operand Underlying, primitive_instance Primitive,
109+ typename ErrorPayload = policy::error::kind>
110+ using flipped_mixed_three_way_dispatch_result_t = three_way_dispatch_result_t <
111+ mixed_bridge_primitive_t <Primitive, Underlying>, Primitive, ErrorPayload>;
112+
78113template <operation OpTag, primitive_instance Lhs, primitive_instance Rhs,
79114 typename ErrorPayload = policy::error::kind>
80115constexpr auto apply (Lhs const &lhs, Rhs const &rhs)
@@ -91,48 +126,158 @@ constexpr auto apply(Lhs const &lhs, Rhs const &rhs)
91126 return result_primitive{*raw};
92127}
93128
129+ template <operation OpTag, primitive_instance Lhs, underlying_operand Rhs,
130+ typename ErrorPayload = policy::error::kind>
131+ constexpr auto apply (Lhs const &lhs, Rhs const &rhs)
132+ -> mixed_primitive_dispatch_result_t<OpTag, Lhs, Rhs, ErrorPayload> {
133+ using bridge_rhs_t = mixed_bridge_primitive_t <Lhs, Rhs>;
134+ auto const bridge_rhs = bridge_rhs_t {rhs};
135+ return apply<OpTag, Lhs, bridge_rhs_t , ErrorPayload>(lhs, bridge_rhs);
136+ }
137+
138+ template <operation OpTag, underlying_operand Lhs, primitive_instance Rhs,
139+ typename ErrorPayload = policy::error::kind>
140+ constexpr auto apply (Lhs const &lhs, Rhs const &rhs)
141+ -> flipped_mixed_primitive_dispatch_result_t<OpTag, Lhs, Rhs,
142+ ErrorPayload> {
143+ using bridge_lhs_t = mixed_bridge_primitive_t <Rhs, Lhs>;
144+ auto const bridge_lhs = bridge_lhs_t {lhs};
145+ return apply<OpTag, bridge_lhs_t , Rhs, ErrorPayload>(bridge_lhs, rhs);
146+ }
147+
94148template <primitive_instance Lhs, primitive_instance Rhs,
95149 typename ErrorPayload = policy::error::kind>
96150constexpr auto add (Lhs const &lhs, Rhs const &rhs)
97151 -> primitive_dispatch_result_t<Addition, Lhs, Rhs, ErrorPayload> {
98152 return apply<Addition, Lhs, Rhs, ErrorPayload>(lhs, rhs);
99153}
100154
155+ template <primitive_instance Lhs, underlying_operand Rhs,
156+ typename ErrorPayload = policy::error::kind>
157+ constexpr auto add (Lhs const &lhs, Rhs const &rhs)
158+ -> mixed_primitive_dispatch_result_t<Addition, Lhs, Rhs, ErrorPayload> {
159+ return apply<Addition, Lhs, Rhs, ErrorPayload>(lhs, rhs);
160+ }
161+
162+ template <underlying_operand Lhs, primitive_instance Rhs,
163+ typename ErrorPayload = policy::error::kind>
164+ constexpr auto add (Lhs const &lhs, Rhs const &rhs)
165+ -> flipped_mixed_primitive_dispatch_result_t<Addition, Lhs, Rhs,
166+ ErrorPayload> {
167+ return apply<Addition, Lhs, Rhs, ErrorPayload>(lhs, rhs);
168+ }
169+
101170template <primitive_instance Lhs, primitive_instance Rhs,
102171 typename ErrorPayload = policy::error::kind>
103172constexpr auto sub (Lhs const &lhs, Rhs const &rhs)
104173 -> primitive_dispatch_result_t<Subtraction, Lhs, Rhs, ErrorPayload> {
105174 return apply<Subtraction, Lhs, Rhs, ErrorPayload>(lhs, rhs);
106175}
107176
177+ template <primitive_instance Lhs, underlying_operand Rhs,
178+ typename ErrorPayload = policy::error::kind>
179+ constexpr auto sub (Lhs const &lhs, Rhs const &rhs)
180+ -> mixed_primitive_dispatch_result_t<Subtraction, Lhs, Rhs, ErrorPayload> {
181+ return apply<Subtraction, Lhs, Rhs, ErrorPayload>(lhs, rhs);
182+ }
183+
184+ template <underlying_operand Lhs, primitive_instance Rhs,
185+ typename ErrorPayload = policy::error::kind>
186+ constexpr auto sub (Lhs const &lhs, Rhs const &rhs)
187+ -> flipped_mixed_primitive_dispatch_result_t<Subtraction, Lhs, Rhs,
188+ ErrorPayload> {
189+ return apply<Subtraction, Lhs, Rhs, ErrorPayload>(lhs, rhs);
190+ }
191+
108192template <primitive_instance Lhs, primitive_instance Rhs,
109193 typename ErrorPayload = policy::error::kind>
110194constexpr auto mul (Lhs const &lhs, Rhs const &rhs)
111195 -> primitive_dispatch_result_t<Multiplication, Lhs, Rhs, ErrorPayload> {
112196 return apply<Multiplication, Lhs, Rhs, ErrorPayload>(lhs, rhs);
113197}
114198
199+ template <primitive_instance Lhs, underlying_operand Rhs,
200+ typename ErrorPayload = policy::error::kind>
201+ constexpr auto mul (Lhs const &lhs, Rhs const &rhs)
202+ -> mixed_primitive_dispatch_result_t<Multiplication, Lhs, Rhs,
203+ ErrorPayload> {
204+ return apply<Multiplication, Lhs, Rhs, ErrorPayload>(lhs, rhs);
205+ }
206+
207+ template <underlying_operand Lhs, primitive_instance Rhs,
208+ typename ErrorPayload = policy::error::kind>
209+ constexpr auto mul (Lhs const &lhs, Rhs const &rhs)
210+ -> flipped_mixed_primitive_dispatch_result_t<Multiplication, Lhs, Rhs,
211+ ErrorPayload> {
212+ return apply<Multiplication, Lhs, Rhs, ErrorPayload>(lhs, rhs);
213+ }
214+
115215template <primitive_instance Lhs, primitive_instance Rhs,
116216 typename ErrorPayload = policy::error::kind>
117217constexpr auto div (Lhs const &lhs, Rhs const &rhs)
118218 -> primitive_dispatch_result_t<Division, Lhs, Rhs, ErrorPayload> {
119219 return apply<Division, Lhs, Rhs, ErrorPayload>(lhs, rhs);
120220}
121221
222+ template <primitive_instance Lhs, underlying_operand Rhs,
223+ typename ErrorPayload = policy::error::kind>
224+ constexpr auto div (Lhs const &lhs, Rhs const &rhs)
225+ -> mixed_primitive_dispatch_result_t<Division, Lhs, Rhs, ErrorPayload> {
226+ return apply<Division, Lhs, Rhs, ErrorPayload>(lhs, rhs);
227+ }
228+
229+ template <underlying_operand Lhs, primitive_instance Rhs,
230+ typename ErrorPayload = policy::error::kind>
231+ constexpr auto div (Lhs const &lhs, Rhs const &rhs)
232+ -> flipped_mixed_primitive_dispatch_result_t<Division, Lhs, Rhs,
233+ ErrorPayload> {
234+ return apply<Division, Lhs, Rhs, ErrorPayload>(lhs, rhs);
235+ }
236+
122237template <primitive_instance Lhs, primitive_instance Rhs,
123238 typename ErrorPayload = policy::error::kind>
124239constexpr auto equal (Lhs const &lhs, Rhs const &rhs)
125240 -> primitive_dispatch_result_t<Equal, Lhs, Rhs, ErrorPayload> {
126241 return apply<Equal, Lhs, Rhs, ErrorPayload>(lhs, rhs);
127242}
128243
244+ template <primitive_instance Lhs, underlying_operand Rhs,
245+ typename ErrorPayload = policy::error::kind>
246+ constexpr auto equal (Lhs const &lhs, Rhs const &rhs)
247+ -> mixed_primitive_dispatch_result_t<Equal, Lhs, Rhs, ErrorPayload> {
248+ return apply<Equal, Lhs, Rhs, ErrorPayload>(lhs, rhs);
249+ }
250+
251+ template <underlying_operand Lhs, primitive_instance Rhs,
252+ typename ErrorPayload = policy::error::kind>
253+ constexpr auto equal (Lhs const &lhs, Rhs const &rhs)
254+ -> flipped_mixed_primitive_dispatch_result_t<Equal, Lhs, Rhs,
255+ ErrorPayload> {
256+ return apply<Equal, Lhs, Rhs, ErrorPayload>(lhs, rhs);
257+ }
258+
129259template <primitive_instance Lhs, primitive_instance Rhs,
130260 typename ErrorPayload = policy::error::kind>
131261constexpr auto not_equal (Lhs const &lhs, Rhs const &rhs)
132262 -> primitive_dispatch_result_t<NotEqual, Lhs, Rhs, ErrorPayload> {
133263 return apply<NotEqual, Lhs, Rhs, ErrorPayload>(lhs, rhs);
134264}
135265
266+ template <primitive_instance Lhs, underlying_operand Rhs,
267+ typename ErrorPayload = policy::error::kind>
268+ constexpr auto not_equal (Lhs const &lhs, Rhs const &rhs)
269+ -> mixed_primitive_dispatch_result_t<NotEqual, Lhs, Rhs, ErrorPayload> {
270+ return apply<NotEqual, Lhs, Rhs, ErrorPayload>(lhs, rhs);
271+ }
272+
273+ template <underlying_operand Lhs, primitive_instance Rhs,
274+ typename ErrorPayload = policy::error::kind>
275+ constexpr auto not_equal (Lhs const &lhs, Rhs const &rhs)
276+ -> flipped_mixed_primitive_dispatch_result_t<NotEqual, Lhs, Rhs,
277+ ErrorPayload> {
278+ return apply<NotEqual, Lhs, Rhs, ErrorPayload>(lhs, rhs);
279+ }
280+
136281template <primitive_instance Lhs, primitive_instance Rhs,
137282 typename ErrorPayload = policy::error::kind>
138283constexpr auto three_way_compare (Lhs const &lhs, Rhs const &rhs)
@@ -151,6 +296,24 @@ constexpr auto three_way_compare(Lhs const &lhs, Rhs const &rhs)
151296 return details::decode_three_way_code<ordering, common_rep>(*raw);
152297}
153298
299+ template <primitive_instance Lhs, underlying_operand Rhs,
300+ typename ErrorPayload = policy::error::kind>
301+ constexpr auto three_way_compare (Lhs const &lhs, Rhs const &rhs)
302+ -> mixed_three_way_dispatch_result_t<Lhs, Rhs, ErrorPayload> {
303+ using bridge_rhs_t = mixed_bridge_primitive_t <Lhs, Rhs>;
304+ auto const bridge_rhs = bridge_rhs_t {rhs};
305+ return three_way_compare<Lhs, bridge_rhs_t , ErrorPayload>(lhs, bridge_rhs);
306+ }
307+
308+ template <underlying_operand Lhs, primitive_instance Rhs,
309+ typename ErrorPayload = policy::error::kind>
310+ constexpr auto three_way_compare (Lhs const &lhs, Rhs const &rhs)
311+ -> flipped_mixed_three_way_dispatch_result_t<Lhs, Rhs, ErrorPayload> {
312+ using bridge_lhs_t = mixed_bridge_primitive_t <Rhs, Lhs>;
313+ auto const bridge_lhs = bridge_lhs_t {lhs};
314+ return three_way_compare<bridge_lhs_t , Rhs, ErrorPayload>(bridge_lhs, rhs);
315+ }
316+
154317template <operation OpTag, primitive_instance Lhs, primitive_instance Rhs,
155318 typename ErrorPayload = policy::error::kind>
156319constexpr auto apply_assign (Lhs &lhs, Rhs const &rhs)
@@ -223,6 +386,22 @@ constexpr auto operator+(Lhs const &lhs, Rhs const &rhs)
223386 return operations::add (lhs, rhs);
224387}
225388
389+ template <operations::primitive_instance Lhs,
390+ operations::underlying_operand Rhs>
391+ constexpr auto operator +(Lhs const &lhs, Rhs const &rhs)
392+ -> operations::mixed_primitive_dispatch_result_t <operations::Addition, Lhs,
393+ Rhs> {
394+ return operations::add (lhs, rhs);
395+ }
396+
397+ template <operations::underlying_operand Lhs,
398+ operations::primitive_instance Rhs>
399+ constexpr auto operator +(Lhs const &lhs, Rhs const &rhs)
400+ -> operations::flipped_mixed_primitive_dispatch_result_t <
401+ operations::Addition, Lhs, Rhs> {
402+ return operations::add (lhs, rhs);
403+ }
404+
226405template <operations::primitive_instance Lhs,
227406 operations::primitive_instance Rhs>
228407constexpr auto operator -(Lhs const &lhs, Rhs const &rhs)
@@ -231,6 +410,22 @@ constexpr auto operator-(Lhs const &lhs, Rhs const &rhs)
231410 return operations::sub (lhs, rhs);
232411}
233412
413+ template <operations::primitive_instance Lhs,
414+ operations::underlying_operand Rhs>
415+ constexpr auto operator -(Lhs const &lhs, Rhs const &rhs)
416+ -> operations::mixed_primitive_dispatch_result_t <operations::Subtraction,
417+ Lhs, Rhs> {
418+ return operations::sub (lhs, rhs);
419+ }
420+
421+ template <operations::underlying_operand Lhs,
422+ operations::primitive_instance Rhs>
423+ constexpr auto operator -(Lhs const &lhs, Rhs const &rhs)
424+ -> operations::flipped_mixed_primitive_dispatch_result_t <
425+ operations::Subtraction, Lhs, Rhs> {
426+ return operations::sub (lhs, rhs);
427+ }
428+
234429template <operations::primitive_instance Lhs,
235430 operations::primitive_instance Rhs>
236431constexpr auto operator *(Lhs const &lhs, Rhs const &rhs)
@@ -239,34 +434,112 @@ constexpr auto operator*(Lhs const &lhs, Rhs const &rhs)
239434 return operations::mul (lhs, rhs);
240435}
241436
437+ template <operations::primitive_instance Lhs,
438+ operations::underlying_operand Rhs>
439+ constexpr auto operator *(Lhs const &lhs, Rhs const &rhs)
440+ -> operations::mixed_primitive_dispatch_result_t <operations::Multiplication,
441+ Lhs, Rhs> {
442+ return operations::mul (lhs, rhs);
443+ }
444+
445+ template <operations::underlying_operand Lhs,
446+ operations::primitive_instance Rhs>
447+ constexpr auto operator *(Lhs const &lhs, Rhs const &rhs)
448+ -> operations::flipped_mixed_primitive_dispatch_result_t <
449+ operations::Multiplication, Lhs, Rhs> {
450+ return operations::mul (lhs, rhs);
451+ }
452+
242453template <operations::primitive_instance Lhs,
243454 operations::primitive_instance Rhs>
244455constexpr auto operator /(Lhs const &lhs, Rhs const &rhs)
245456 -> operations::primitive_dispatch_result_t <operations::Division, Lhs, Rhs> {
246457 return operations::div (lhs, rhs);
247458}
248459
460+ template <operations::primitive_instance Lhs,
461+ operations::underlying_operand Rhs>
462+ constexpr auto operator /(Lhs const &lhs, Rhs const &rhs)
463+ -> operations::mixed_primitive_dispatch_result_t <operations::Division, Lhs,
464+ Rhs> {
465+ return operations::div (lhs, rhs);
466+ }
467+
468+ template <operations::underlying_operand Lhs,
469+ operations::primitive_instance Rhs>
470+ constexpr auto operator /(Lhs const &lhs, Rhs const &rhs)
471+ -> operations::flipped_mixed_primitive_dispatch_result_t <
472+ operations::Division, Lhs, Rhs> {
473+ return operations::div (lhs, rhs);
474+ }
475+
249476template <operations::primitive_instance Lhs,
250477 operations::primitive_instance Rhs>
251478constexpr auto operator ==(Lhs const &lhs, Rhs const &rhs)
252479 -> operations::primitive_dispatch_result_t <operations::Equal, Lhs, Rhs> {
253480 return operations::equal (lhs, rhs);
254481}
255482
483+ template <operations::primitive_instance Lhs,
484+ operations::underlying_operand Rhs>
485+ constexpr auto operator ==(Lhs const &lhs, Rhs const &rhs)
486+ -> operations::mixed_primitive_dispatch_result_t <operations::Equal, Lhs,
487+ Rhs> {
488+ return operations::equal (lhs, rhs);
489+ }
490+
491+ template <operations::underlying_operand Lhs,
492+ operations::primitive_instance Rhs>
493+ constexpr auto operator ==(Lhs const &lhs, Rhs const &rhs)
494+ -> operations::flipped_mixed_primitive_dispatch_result_t <operations::Equal,
495+ Lhs, Rhs> {
496+ return operations::equal (lhs, rhs);
497+ }
498+
256499template <operations::primitive_instance Lhs,
257500 operations::primitive_instance Rhs>
258501constexpr auto operator !=(Lhs const &lhs, Rhs const &rhs)
259502 -> operations::primitive_dispatch_result_t <operations::NotEqual, Lhs, Rhs> {
260503 return operations::not_equal (lhs, rhs);
261504}
262505
506+ template <operations::primitive_instance Lhs,
507+ operations::underlying_operand Rhs>
508+ constexpr auto operator !=(Lhs const &lhs, Rhs const &rhs)
509+ -> operations::mixed_primitive_dispatch_result_t <operations::NotEqual, Lhs,
510+ Rhs> {
511+ return operations::not_equal (lhs, rhs);
512+ }
513+
514+ template <operations::underlying_operand Lhs,
515+ operations::primitive_instance Rhs>
516+ constexpr auto operator !=(Lhs const &lhs, Rhs const &rhs)
517+ -> operations::flipped_mixed_primitive_dispatch_result_t <
518+ operations::NotEqual, Lhs, Rhs> {
519+ return operations::not_equal (lhs, rhs);
520+ }
521+
263522template <operations::primitive_instance Lhs,
264523 operations::primitive_instance Rhs>
265524constexpr auto operator <=>(Lhs const &lhs, Rhs const &rhs)
266525 -> operations::three_way_dispatch_result_t <Lhs, Rhs> {
267526 return operations::three_way_compare (lhs, rhs);
268527}
269528
529+ template <operations::primitive_instance Lhs,
530+ operations::underlying_operand Rhs>
531+ constexpr auto operator <=>(Lhs const &lhs, Rhs const &rhs)
532+ -> operations::mixed_three_way_dispatch_result_t <Lhs, Rhs> {
533+ return operations::three_way_compare (lhs, rhs);
534+ }
535+
536+ template <operations::underlying_operand Lhs,
537+ operations::primitive_instance Rhs>
538+ constexpr auto operator <=>(Lhs const &lhs, Rhs const &rhs)
539+ -> operations::flipped_mixed_three_way_dispatch_result_t <Lhs, Rhs> {
540+ return operations::three_way_compare (lhs, rhs);
541+ }
542+
270543template <operations::primitive_instance Lhs,
271544 operations::primitive_instance Rhs>
272545constexpr auto operator +=(Lhs &lhs, Rhs const &rhs)
0 commit comments