1#[macro_use]
2use crate::stdlib::*;
3
4pub mod scalar;
9#[cfg(feature = "matrix")]
10pub mod scalar_to_mat;
11#[cfg(feature = "matrix")]
12pub mod mat_to_mat;
13
14pub use self::scalar::*;
15#[cfg(feature = "matrix")]
16pub use self::scalar_to_mat::*;
17#[cfg(feature = "matrix")]
18pub use self::mat_to_mat::*;
19
20macro_rules! lossless_into {
21 ($from_type:ty) => {
22 impl LosslessInto<String> for $from_type {
23 fn lossless_into(self) -> String {
24 self.to_string()
25 }
26 }
27 };
28 ($from_type:ty, $to_type:ty) => {
29 impl LosslessInto<$to_type> for $from_type {
30 fn lossless_into(self) -> $to_type {
31 self as $to_type
32 }
33 }
34 };
35}
36
37#[cfg(feature = "i8")]
38lossless_into!(i8);
39#[cfg(feature = "i16")]
40lossless_into!(i16);
41#[cfg(feature = "i32")]
42lossless_into!(i32);
43#[cfg(feature = "i64")]
44lossless_into!(i64);
45#[cfg(feature = "i128")]
46lossless_into!(i128);
47#[cfg(feature = "u8")]
48lossless_into!(u8);
49#[cfg(feature = "u16")]
50lossless_into!(u16);
51#[cfg(feature = "u32")]
52lossless_into!(u32);
53#[cfg(feature = "u64")]
54lossless_into!(u64);
55#[cfg(feature = "u128")]
56lossless_into!(u128);
57#[cfg(feature = "f32")]
58lossless_into!(f32);
59#[cfg(feature = "f64")]
60lossless_into!(f64);
61#[cfg(feature = "bool")]
62lossless_into!(bool);
63#[cfg(feature = "string")]
64lossless_into!(String);
65
66#[cfg(all(feature = "u8", feature = "u8"))]
67lossless_into!(u8,u8);
68#[cfg(all(feature = "u8", feature = "u16"))]
69lossless_into!(u8,u16);
70#[cfg(all(feature = "u8", feature = "u32"))]
71lossless_into!(u8,u32);
72#[cfg(all(feature = "u8", feature = "u64"))]
73lossless_into!(u8,u64);
74#[cfg(all(feature = "u8", feature = "u128"))]
75lossless_into!(u8,u128);
76#[cfg(all(feature = "u8", feature = "i8"))]
77lossless_into!(u8,i8);
78#[cfg(all(feature = "u8", feature = "i16"))]
79lossless_into!(u8,i16);
80#[cfg(all(feature = "u8", feature = "i32"))]
81lossless_into!(u8,i32);
82#[cfg(all(feature = "u8", feature = "i64"))]
83lossless_into!(u8,i64);
84#[cfg(all(feature = "u8", feature = "i128"))]
85lossless_into!(u8,i128);
86
87#[cfg(all(feature = "u16", feature = "u8"))]
88lossless_into!(u16,u8);
89#[cfg(all(feature = "u16", feature = "u16"))]
90lossless_into!(u16,u16);
91#[cfg(all(feature = "u16", feature = "u32"))]
92lossless_into!(u16,u32);
93#[cfg(all(feature = "u16", feature = "u64"))]
94lossless_into!(u16,u64);
95#[cfg(all(feature = "u16", feature = "u128"))]
96lossless_into!(u16,u128);
97#[cfg(all(feature = "u16", feature = "i8"))]
98lossless_into!(u16,i8);
99#[cfg(all(feature = "u16", feature = "i16"))]
100lossless_into!(u16,i16);
101#[cfg(all(feature = "u16", feature = "i32"))]
102lossless_into!(u16,i32);
103#[cfg(all(feature = "u16", feature = "i64"))]
104lossless_into!(u16,i64);
105#[cfg(all(feature = "u16", feature = "i128"))]
106lossless_into!(u16,i128);
107
108#[cfg(all(feature = "u32", feature = "u8"))]
109lossless_into!(u32,u8);
110#[cfg(all(feature = "u32", feature = "u16"))]
111lossless_into!(u32,u16);
112#[cfg(all(feature = "u32", feature = "u32"))]
113lossless_into!(u32,u32);
114#[cfg(all(feature = "u32", feature = "u64"))]
115lossless_into!(u32,u64);
116#[cfg(all(feature = "u32", feature = "u128"))]
117lossless_into!(u32,u128);
118#[cfg(all(feature = "u32", feature = "i8"))]
119lossless_into!(u32,i8);
120#[cfg(all(feature = "u32", feature = "i16"))]
121lossless_into!(u32,i16);
122#[cfg(all(feature = "u32", feature = "i32"))]
123lossless_into!(u32,i32);
124#[cfg(all(feature = "u32", feature = "i64"))]
125lossless_into!(u32,i64);
126#[cfg(all(feature = "u32", feature = "i128"))]
127lossless_into!(u32,i128);
128
129#[cfg(all(feature = "u64", feature = "u8"))]
130lossless_into!(u64,u8);
131#[cfg(all(feature = "u64", feature = "u16"))]
132lossless_into!(u64,u16);
133#[cfg(all(feature = "u64", feature = "u32"))]
134lossless_into!(u64,u32);
135#[cfg(all(feature = "u64", feature = "u64"))]
136lossless_into!(u64,u64);
137#[cfg(all(feature = "u64", feature = "u128"))]
138lossless_into!(u64,u128);
139#[cfg(all(feature = "u64", feature = "i8"))]
140lossless_into!(u64,i8);
141#[cfg(all(feature = "u64", feature = "i16"))]
142lossless_into!(u64,i16);
143#[cfg(all(feature = "u64", feature = "i32"))]
144lossless_into!(u64,i32);
145#[cfg(all(feature = "u64", feature = "i64"))]
146lossless_into!(u64,i64);
147#[cfg(all(feature = "u64", feature = "i128"))]
148lossless_into!(u64,i128);
149
150#[cfg(all(feature = "u128", feature = "u8"))]
151lossless_into!(u128,u8);
152#[cfg(all(feature = "u128", feature = "u16"))]
153lossless_into!(u128,u16);
154#[cfg(all(feature = "u128", feature = "u32"))]
155lossless_into!(u128,u32);
156#[cfg(all(feature = "u128", feature = "u64"))]
157lossless_into!(u128,u64);
158#[cfg(all(feature = "u128", feature = "u128"))]
159lossless_into!(u128,u128);
160#[cfg(all(feature = "u128", feature = "i8"))]
161lossless_into!(u128,i8);
162#[cfg(all(feature = "u128", feature = "i16"))]
163lossless_into!(u128,i16);
164#[cfg(all(feature = "u128", feature = "i32"))]
165lossless_into!(u128,i32);
166#[cfg(all(feature = "u128", feature = "i64"))]
167lossless_into!(u128,i64);
168#[cfg(all(feature = "u128", feature = "i128"))]
169lossless_into!(u128,i128);
170
171#[cfg(all(feature = "i8", feature = "i8"))]
172lossless_into!(i8,i8);
173#[cfg(all(feature = "i8", feature = "i16"))]
174lossless_into!(i8,i16);
175#[cfg(all(feature = "i8", feature = "i32"))]
176lossless_into!(i8,i32);
177#[cfg(all(feature = "i8", feature = "i64"))]
178lossless_into!(i8,i64);
179#[cfg(all(feature = "i8", feature = "i128"))]
180lossless_into!(i8,i128);
181#[cfg(all(feature = "i8", feature = "u8"))]
182lossless_into!(i8,u8);
183#[cfg(all(feature = "i8", feature = "u16"))]
184lossless_into!(i8,u16);
185#[cfg(all(feature = "i8", feature = "u32"))]
186lossless_into!(i8,u32);
187#[cfg(all(feature = "i8", feature = "u64"))]
188lossless_into!(i8,u64);
189#[cfg(all(feature = "i8", feature = "u128"))]
190lossless_into!(i8,u128);
191
192#[cfg(all(feature = "i16", feature = "i8"))]
193lossless_into!(i16,i8);
194#[cfg(all(feature = "i16", feature = "i16"))]
195lossless_into!(i16,i16);
196#[cfg(all(feature = "i16", feature = "i32"))]
197lossless_into!(i16,i32);
198#[cfg(all(feature = "i16", feature = "i64"))]
199lossless_into!(i16,i64);
200#[cfg(all(feature = "i16", feature = "i128"))]
201lossless_into!(i16,i128);
202#[cfg(all(feature = "i16", feature = "u8"))]
203lossless_into!(i16,u8);
204#[cfg(all(feature = "i16", feature = "u16"))]
205lossless_into!(i16,u16);
206#[cfg(all(feature = "i16", feature = "u32"))]
207lossless_into!(i16,u32);
208#[cfg(all(feature = "i16", feature = "u64"))]
209lossless_into!(i16,u64);
210#[cfg(all(feature = "i16", feature = "u128"))]
211lossless_into!(i16,u128);
212
213#[cfg(all(feature = "i32", feature = "i8"))]
214lossless_into!(i32,i8);
215#[cfg(all(feature = "i32", feature = "i16"))]
216lossless_into!(i32,i16);
217#[cfg(all(feature = "i32", feature = "i32"))]
218lossless_into!(i32,i32);
219#[cfg(all(feature = "i32", feature = "i64"))]
220lossless_into!(i32,i64);
221#[cfg(all(feature = "i32", feature = "i128"))]
222lossless_into!(i32,i128);
223#[cfg(all(feature = "i32", feature = "u8"))]
224lossless_into!(i32,u8);
225#[cfg(all(feature = "i32", feature = "u16"))]
226lossless_into!(i32,u16);
227#[cfg(all(feature = "i32", feature = "u32"))]
228lossless_into!(i32,u32);
229#[cfg(all(feature = "i32", feature = "u64"))]
230lossless_into!(i32,u64);
231#[cfg(all(feature = "i32", feature = "u128"))]
232lossless_into!(i32,u128);
233
234#[cfg(all(feature = "i64", feature = "i8"))]
235lossless_into!(i64,i8);
236#[cfg(all(feature = "i64", feature = "i16"))]
237lossless_into!(i64,i16);
238#[cfg(all(feature = "i64", feature = "i32"))]
239lossless_into!(i64,i32);
240#[cfg(all(feature = "i64", feature = "i64"))]
241lossless_into!(i64,i64);
242#[cfg(all(feature = "i64", feature = "i128"))]
243lossless_into!(i64,i128);
244#[cfg(all(feature = "i64", feature = "u8"))]
245lossless_into!(i64,u8);
246#[cfg(all(feature = "i64", feature = "u16"))]
247lossless_into!(i64,u16);
248#[cfg(all(feature = "i64", feature = "u32"))]
249lossless_into!(i64,u32);
250#[cfg(all(feature = "i64", feature = "u64"))]
251lossless_into!(i64,u64);
252#[cfg(all(feature = "i64", feature = "u128"))]
253lossless_into!(i64,u128);
254
255#[cfg(all(feature = "i128", feature = "i8"))]
256lossless_into!(i128,i8);
257#[cfg(all(feature = "i128", feature = "i16"))]
258lossless_into!(i128,i16);
259#[cfg(all(feature = "i128", feature = "i32"))]
260lossless_into!(i128,i32);
261#[cfg(all(feature = "i128", feature = "i64"))]
262lossless_into!(i128,i64);
263#[cfg(all(feature = "i128", feature = "i128"))]
264lossless_into!(i128,i128);
265#[cfg(all(feature = "i128", feature = "u8"))]
266lossless_into!(i128,u8);
267#[cfg(all(feature = "i128", feature = "u16"))]
268lossless_into!(i128,u16);
269#[cfg(all(feature = "i128", feature = "u32"))]
270lossless_into!(i128,u32);
271#[cfg(all(feature = "i128", feature = "u64"))]
272lossless_into!(i128,u64);
273#[cfg(all(feature = "i128", feature = "u128"))]
274lossless_into!(i128,u128);
275
276macro_rules! lossless_into_float_to_int {
278 ($float_type:ty, $int_type:ty) => {
279 impl LosslessInto<$int_type> for $float_type {
280 fn lossless_into(self) -> $int_type {
281 self as $int_type
282 }
283 }
284 };
285}
286
287#[cfg(all(feature = "f64", feature = "u8"))]
288lossless_into_float_to_int!(f64, u8);
289#[cfg(all(feature = "f64", feature = "u16"))]
290lossless_into_float_to_int!(f64, u16);
291#[cfg(all(feature = "f64", feature = "u32"))]
292lossless_into_float_to_int!(f64, u32);
293#[cfg(all(feature = "f64", feature = "u64"))]
294lossless_into_float_to_int!(f64, u64);
295#[cfg(all(feature = "f64", feature = "u128"))]
296lossless_into_float_to_int!(f64, u128);
297#[cfg(all(feature = "f64", feature = "i8"))]
298lossless_into_float_to_int!(f64, i8);
299#[cfg(all(feature = "f64", feature = "i16"))]
300lossless_into_float_to_int!(f64, i16);
301#[cfg(all(feature = "f64", feature = "i32"))]
302lossless_into_float_to_int!(f64, i32);
303#[cfg(all(feature = "f64", feature = "i64"))]
304lossless_into_float_to_int!(f64, i64);
305#[cfg(all(feature = "f64", feature = "i128"))]
306lossless_into_float_to_int!(f64, i128);
307
308#[cfg(all(feature = "f32", feature = "u8"))]
309lossless_into_float_to_int!(f32, u8);
310#[cfg(all(feature = "f32", feature = "u16"))]
311lossless_into_float_to_int!(f32, u16);
312#[cfg(all(feature = "f32", feature = "u32"))]
313lossless_into_float_to_int!(f32, u32);
314#[cfg(all(feature = "f32", feature = "u64"))]
315lossless_into_float_to_int!(f32, u64);
316#[cfg(all(feature = "f32", feature = "u128"))]
317lossless_into_float_to_int!(f32, u128);
318#[cfg(all(feature = "f32", feature = "i8"))]
319lossless_into_float_to_int!(f32, i8);
320#[cfg(all(feature = "f32", feature = "i16"))]
321lossless_into_float_to_int!(f32, i16);
322#[cfg(all(feature = "f32", feature = "i32"))]
323lossless_into_float_to_int!(f32, i32);
324#[cfg(all(feature = "f32", feature = "i64"))]
325lossless_into_float_to_int!(f32, i64);
326#[cfg(all(feature = "f32", feature = "i128"))]
327lossless_into_float_to_int!(f32, i128);
328
329macro_rules! lossless_into_int_to_float {
330 ($int_type:ty) => {
331 paste!{
332 #[cfg(feature = "f32")]
333 impl LosslessInto<f32> for $int_type {
334 fn lossless_into(self) -> f32 {
335 self as f32
336 }
337 }
338 #[cfg(feature = "f64")]
339 impl LosslessInto<f64> for $int_type {
340 fn lossless_into(self) -> f64 {
341 self as f64
342 }
343 }
344 }
345 };
346}
347
348#[cfg(feature = "u8")]
349lossless_into_int_to_float!(u8);
350#[cfg(feature = "u16")]
351lossless_into_int_to_float!(u16);
352#[cfg(feature = "u32")]
353lossless_into_int_to_float!(u32);
354#[cfg(feature = "u64")]
355lossless_into_int_to_float!(u64);
356#[cfg(feature = "u128")]
357lossless_into_int_to_float!(u128);
358#[cfg(feature = "i8")]
359lossless_into_int_to_float!(i8);
360#[cfg(feature = "i16")]
361lossless_into_int_to_float!(i16);
362#[cfg(feature = "i32")]
363lossless_into_int_to_float!(i32);
364#[cfg(feature = "i64")]
365lossless_into_int_to_float!(i64);
366#[cfg(feature = "i128")]
367lossless_into_int_to_float!(i128);
368
369#[cfg(feature = "bool")]
370impl LosslessInto<bool> for bool {
371 fn lossless_into(self) -> bool {
372 self
373 }
374}
375
376#[cfg(all(feature = "bool", feature = "f64"))]
377impl LosslessInto<f64> for bool {
378 fn lossless_into(self) -> f64 {
379 if self { 1.0 } else { 0.0 }
380 }
381}
382
383#[cfg(all(feature = "bool", feature = "f32"))]
384impl LosslessInto<f32> for bool {
385 fn lossless_into(self) -> f32 {
386 if self { 1.0 } else { 0.0 }
387 }
388}
389
390macro_rules! lossless_into_bool {
391 ($to_type:ty) => {
392 paste! {
393 impl LosslessInto<$to_type> for bool {
394 fn lossless_into(self) -> $to_type {
395 if self { 1 } else { 0 }
396 }
397 }
398 }
399 };
400}
401
402#[cfg(all(feature = "bool", feature = "u8"))]
403lossless_into_bool!(u8);
404#[cfg(all(feature = "bool", feature = "u16"))]
405lossless_into_bool!(u16);
406#[cfg(all(feature = "bool", feature = "u32"))]
407lossless_into_bool!(u32);
408#[cfg(all(feature = "bool", feature = "u64"))]
409lossless_into_bool!(u64);
410#[cfg(all(feature = "bool", feature = "u128"))]
411lossless_into_bool!(u128);
412#[cfg(all(feature = "bool", feature = "i8"))]
413lossless_into_bool!(i8);
414#[cfg(all(feature = "bool", feature = "i16"))]
415lossless_into_bool!(i16);
416#[cfg(all(feature = "bool", feature = "i32"))]
417lossless_into_bool!(i32);
418#[cfg(all(feature = "bool", feature = "i64"))]
419lossless_into_bool!(i64);
420#[cfg(all(feature = "bool", feature = "i128"))]
421lossless_into_bool!(i128);
422
423#[cfg(all(feature = "f64", feature = "f32"))]
424impl LosslessInto<f32> for f64 {
425 fn lossless_into(self) -> f32 {
426 self as f32
427 }
428}
429
430#[cfg(all(feature = "f32", feature = "f64"))]
431impl LosslessInto<f64> for f32 {
432 fn lossless_into(self) -> f64 {
433 self as f64
434 }
435}
436
437#[cfg(feature = "f64")]
438impl LosslessInto<f64> for f64 {
439 fn lossless_into(self) -> f64 {
440 self
441 }
442}
443
444#[cfg(feature = "f32")]
445impl LosslessInto<f32> for f32 {
446 fn lossless_into(self) -> f32 {
447 self
448 }
449}
450
451#[cfg(all(feature = "rational", feature = "string"))]
452impl LosslessInto<String> for R64 {
453 fn lossless_into(self) -> String {
454 self.pretty_print()
455 }
456}
457
458#[cfg(all(feature = "rational", feature = "f64"))]
459impl LosslessInto<f64> for R64 {
460 fn lossless_into(self) -> f64 {
461 match self.to_f64() {
462 Some(val) => val,
463 None => panic!("Cannot convert R64 to F64: value is not representable"),
464 }
465 }
466}
467
468#[cfg(feature = "rational")]
469impl LosslessInto<R64> for R64 {
470 fn lossless_into(self) -> R64 {
471 self
472 }
473}
474#[cfg(all(feature = "rational", feature = "f64"))]
475impl LosslessInto<R64> for f64 {
476 fn lossless_into(self) -> R64 {
477 R64::from_f64(self).unwrap_or_else(|| panic!("Cannot convert F64 to R64: value is not representable"))
478 }
479}
480
481#[cfg(all(feature = "rational", feature = "f32"))]
482impl LosslessInto<R64> for f32 {
483 fn lossless_into(self) -> R64 {
484 R64::from_f64(self as f64).unwrap_or_else(|| panic!("Cannot convert F32 to R64: value is not representable"))
485 }
486}
487
488#[cfg(all(feature = "complex", feature = "string"))]
489impl LosslessInto<String> for C64 {
490 fn lossless_into(self) -> String {
491 self.pretty_print()
492 }
493}
494
495#[cfg(feature = "complex")]
496impl LosslessInto<C64> for C64 {
497 fn lossless_into(self) -> C64 {
498 self
499 }
500}
501
502macro_rules! impl_lossy_from {
503 ($($from:ty => $($to:ty),*);* $(;)?) => {
504 $(
505 $(
506 impl LossyFrom<$from> for $to {
507 fn lossy_from(value: $from) -> Self {
508 value as $to
509 }
510 }
511 )*
512 )*
513 };
514}
515
516impl_lossy_from!(u8 => u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64);
517impl_lossy_from!(u16 => u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64);
518impl_lossy_from!(u32 => u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64);
519impl_lossy_from!(u64 => u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64);
520impl_lossy_from!(i8 => u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64);
521impl_lossy_from!(i16 => u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64);
522impl_lossy_from!(i32 => u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64);
523impl_lossy_from!(i64 => u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64);
524impl_lossy_from!(i128 => u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64);
525impl_lossy_from!(u128 => u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64);
526impl_lossy_from!(f32 => u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64);
527impl_lossy_from!(f64 => u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64);
528
529#[cfg(all(feature = "rational", feature = "f64"))]
554impl LossyFrom<f64> for R64 {
555 fn lossy_from(value: f64) -> Self {
556 R64::from(value)
557 }
558}
559
560#[cfg(all(feature = "rational", feature = "string"))]
561impl LossyFrom<R64> for String {
562 fn lossy_from(value: R64) -> Self {
563 value.pretty_print()
564 }
565}
566
567#[cfg(all(feature = "rational", feature = "f64"))]
568impl LossyFrom<R64> for f64 {
569 fn lossy_from(value: R64) -> Self {
570 value.to_f64().unwrap_or_else(|| panic!("Cannot convert R64 to F64: value is not representable"))
571 }
572}
573
574#[cfg(all(feature = "f64", feature = "string"))]
575impl LossyFrom<f64> for String {
576 fn lossy_from(value: f64) -> Self {
577 value.to_string()
578 }
579}
580
581#[cfg(all(feature = "f32", feature = "string"))]
582impl LossyFrom<f32> for String {
583 fn lossy_from(value: f32) -> Self {
584 value.to_string()
585 }
586}
587
588#[cfg(feature = "string")]
589impl LossyFrom<String> for String {
590 fn lossy_from(value: String) -> Self {
591 value
592 }
593}
594
595#[cfg(feature = "bool")]
596impl LossyFrom<bool> for bool {
597 fn lossy_from(value: bool) -> Self {
598 value
599 }
600}
601
602#[cfg(all(feature = "bool", feature = "string"))]
603impl LossyFrom<bool> for String {
604 fn lossy_from(value: bool) -> Self {
605 format!("{}",value)
606 }
607}
608
609macro_rules! impl_lossy_from_numeric_to_string {
610 ($($t:ty),*) => {
611 $(
612 impl LossyFrom<$t> for String {
613 fn lossy_from(value: $t) -> Self {
614 value.to_string()
615 }
616 }
617 )*
618 };
619}
620
621impl_lossy_from_numeric_to_string!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128);
622
623#[derive(Debug, Clone)]
624pub struct UnsupportedConversionError{from: ValueKind, to: ValueKind}
625impl MechErrorKind for UnsupportedConversionError {
626 fn name(&self) -> &str { "UnsupportedConversion" }
627 fn message(&self) -> String {
628 format!("Unsupported conversion from {:?} to {:?}", self.from, self.to)
629 }
630}