mech_core/
value.rs

1use crate::*;
2use crate::nodes::Matrix as Mat;
3#[cfg(feature = "matrix")]
4use crate::matrix::Matrix;
5#[cfg(feature = "complex")]
6use crate::types::complex_numbers::ComplexNumber;
7#[cfg(feature = "rational")]
8use num_rational::Rational64;
9
10#[cfg(feature = "no_std")]
11use core::mem;
12#[cfg(not(feature = "no_std"))]
13use std::mem;
14
15#[cfg(feature = "matrix")]
16use nalgebra::DVector;
17
18macro_rules! impl_as_type {
19  ($target_type:ty) => {
20    paste!{
21      pub fn [<as_ $target_type>](&self) -> Option<Ref<$target_type>> {
22        match self {
23          #[cfg(feature = "u8")]
24          Value::U8(v) => Some(Ref::new(*v.borrow() as $target_type)),
25          #[cfg(feature = "u16")]
26          Value::U16(v) => Some(Ref::new(*v.borrow() as $target_type)),
27          #[cfg(feature = "u32")]
28          Value::U32(v) => Some(Ref::new(*v.borrow() as $target_type)),
29          #[cfg(feature = "u64")]
30          Value::U64(v) => Some(Ref::new(*v.borrow() as $target_type)),
31          #[cfg(feature = "u128")]
32          Value::U128(v) => Some(Ref::new(*v.borrow() as $target_type)),
33          #[cfg(feature = "i8")]
34          Value::I8(v) => Some(Ref::new(*v.borrow() as $target_type)),
35          #[cfg(feature = "i16")]
36          Value::I16(v) => Some(Ref::new(*v.borrow() as $target_type)),
37          #[cfg(feature = "i32")]
38          Value::I32(v) => Some(Ref::new(*v.borrow() as $target_type)),
39          #[cfg(feature = "i64")]
40          Value::I64(v) => Some(Ref::new(*v.borrow() as $target_type)),
41          #[cfg(feature = "i128")]
42          Value::I128(v) => Some(Ref::new(*v.borrow() as $target_type)),
43          #[cfg(feature = "f32")]
44          Value::F32(v) => Some(Ref::new((*v.borrow()).0 as $target_type)),
45          #[cfg(feature = "f64")]
46          Value::F64(v) => Some(Ref::new((*v.borrow()).0 as $target_type)),
47          Value::Id(v) => Some(Ref::new(*v as $target_type)),
48          Value::MutableReference(val) => val.borrow().[<as_ $target_type>](),
49          _ => None,
50        }
51      }
52    }
53  };
54}
55
56// Value Kind
57// ----------------------------------------------------------------------------
58
59#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
60#[derive(Clone, Debug, Eq, PartialEq, Hash)]
61pub enum ValueKind {
62  U8, U16, U32, U64, U128, I8, I16, I32, I64, I128, F32, F64, ComplexNumber, RationalNumber,
63  String, Bool, Id, Index, Empty, Any, 
64  Matrix(Box<ValueKind>,Vec<usize>),  Enum(u64),                  Record(Vec<(String,ValueKind)>),
65  Map(Box<ValueKind>,Box<ValueKind>), Atom(u64),                  Table(Vec<(String,ValueKind)>, usize), 
66  Tuple(Vec<ValueKind>),              Reference(Box<ValueKind>),  Set(Box<ValueKind>, Option<usize>), 
67  Option(Box<ValueKind>),
68}
69
70impl Display for ValueKind {
71  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
72    match self {
73      ValueKind::RationalNumber => write!(f, "r64"),
74      ValueKind::ComplexNumber => write!(f, "c64"),
75      ValueKind::U8 => write!(f, "u8"),
76      ValueKind::U16 => write!(f, "u16"),
77      ValueKind::U32 => write!(f, "u32"),
78      ValueKind::U64 => write!(f, "u64"),
79      ValueKind::U128 => write!(f, "u128"),
80      ValueKind::I8 => write!(f, "i8"),
81      ValueKind::I16 => write!(f, "i16"),
82      ValueKind::I32 => write!(f, "i32"),
83      ValueKind::I64 => write!(f, "i64"),
84      ValueKind::I128 => write!(f, "i128"),
85      ValueKind::F32 => write!(f, "f32"),
86      ValueKind::F64 => write!(f, "f64"),
87      ValueKind::String => write!(f, "string"),
88      ValueKind::Bool => write!(f, "bool"),
89      ValueKind::Matrix(x,s) => write!(f, "[{}]:{}", x, s.iter().map(|s| s.to_string()).collect::<Vec<String>>().join(",")),
90      ValueKind::Enum(x) => write!(f, "{}",x),
91      ValueKind::Set(x,el) => write!(f, "{{{}}}{}", x, el.map_or("".to_string(), |e| format!(":{}", e))),
92      ValueKind::Map(x,y) => write!(f, "{{{}:{}}}",x,y),
93      ValueKind::Record(x) => write!(f, "{{{}}}",x.iter().map(|(i,k)| format!("{}<{}>",i.to_string(),k)).collect::<Vec<String>>().join(" ")),
94      ValueKind::Table(x,y) => {
95        let size_str = if y > &0 { format!(":{}", y) } else { "".to_string() };
96        write!(f, "|{}|{}",x.iter().map(|(i,k)| format!("{}<{}>",i.to_string(),k)).collect::<Vec<String>>().join(" "),size_str)
97      }
98      ValueKind::Tuple(x) => write!(f, "({})",x.iter().map(|x| format!("{}",x)).collect::<Vec<String>>().join(",")),
99      ValueKind::Id => write!(f, "id"),
100      ValueKind::Index => write!(f, "ix"),
101      ValueKind::Reference(x) => write!(f, "{}",x),
102      ValueKind::Atom(x) => write!(f, "`{}",x),
103      ValueKind::Empty => write!(f, "_"),
104      ValueKind::Any => write!(f, "*"),
105      ValueKind::Option(x) => write!(f, "{}?", x),
106    }
107  }
108}
109
110impl ValueKind {
111
112  #[cfg(feature = "compiler")]
113  pub fn to_feature_kind(&self) -> FeatureKind {
114    match self {
115      ValueKind::I8 => FeatureKind::I8,
116      ValueKind::I16 => FeatureKind::I16,
117      ValueKind::I32 => FeatureKind::I32,
118      ValueKind::I64 => FeatureKind::I64,
119      ValueKind::I128 => FeatureKind::I128,
120      ValueKind::U8 => FeatureKind::U8,
121      ValueKind::U16 => FeatureKind::U16,
122      ValueKind::U32 => FeatureKind::U32,
123      ValueKind::U64 => FeatureKind::U64,
124      ValueKind::U128 => FeatureKind::U128,
125      ValueKind::F32 => FeatureKind::F32,
126      ValueKind::F64 => FeatureKind::F64,
127      ValueKind::String => FeatureKind::String,
128      ValueKind::Bool => FeatureKind::Bool,
129      #[cfg(feature = "complex")]
130      ValueKind::ComplexNumber => FeatureKind::C64,
131      #[cfg(feature = "rational")]
132      ValueKind::RationalNumber => FeatureKind::R64,
133      _ => panic!("Unsupported feature kind for value kind: {}", self),
134    }
135  }
136
137  pub fn collection_kind(&self) -> Option<ValueKind> {
138    match self {
139      ValueKind::Matrix(x,_) => Some(*x.clone()),
140      ValueKind::Set(x,_) => Some(*x.clone()),
141      _ => None,
142    }
143  }
144
145  pub fn deref_kind(&self) -> ValueKind {
146    match self {
147      ValueKind::Reference(x) => *x.clone(),
148      _ => self.clone(),
149    }
150  }
151
152  pub fn is_convertible_to(&self, other: &ValueKind) -> bool {
153    use ValueKind::*;
154    match (self, other) {
155      // Unsigned widening
156      (U8, U16) | (U8, U32) | (U8, U64) | (U8, U128) |
157      (U16, U32) | (U16, U64) | (U16, U128) |
158      (U32, U64) | (U32, U128) |
159      (U64, U128) => true,
160
161      // Signed widening
162      (I8, I16) | (I8, I32) | (I8, I64) | (I8, I128) |
163      (I16, I32) | (I16, I64) | (I16, I128) |
164      (I32, I64) | (I32, I128) |
165      (I64, I128) => true,
166
167      // Unsigned -> signed widening
168      (U8, I16) | (U8, I32) | (U8, I64) | (U8, I128) |
169      (U16, I32) | (U16, I64) | (U16, I128) |
170      (U32, I64) | (U32, I128) |
171      (U64, I128) => true,
172
173      // Signed -> unsigned widening (runtime safety not enforced here)
174      (I8, U16) | (I8, U32) | (I8, U64) | (I8, U128) |
175      (I16, U32) | (I16, U64) | (I16, U128) |
176      (I32, U64) | (I32, U128) |
177      (I64, U128) => true,
178
179      // Integer -> float
180      (U8, F32) | (U8, F64) |
181      (U16, F32) | (U16, F64) |
182      (U32, F32) | (U32, F64) |
183      (U64, F32) | (U64, F64) |
184      (U128, F32) | (U128, F64) |
185      (I8, F32) | (I8, F64) |
186      (I16, F32) | (I16, F64) |
187      (I32, F32) | (I32, F64) |
188      (I64, F32) | (I64, F64) |
189      (I128, F32) | (I128, F64) => true,
190
191      // Float widening + narrowing
192      (F32, F64) | (F64, F32) => true,
193
194      // Float -> integer (allowed, but lossy)
195      (F32, I8) | (F32, I16) | (F32, I32) | (F32, I64) | (F32, I128) |
196      (F32, U8) | (F32, U16) | (F32, U32) | (F32, U64) | (F32, U128) |
197      (F64, I8) | (F64, I16) | (F64, I32) | (F64, I64) | (F64, I128) |
198      (F64, U8) | (F64, U16) | (F64, U32) | (F64, U64) | (F64, U128) => true,
199
200      // Index conversions (both ways)
201      (Index, U8) | (Index, U16) | (Index, U32) | (Index, U64) | (Index, U128) |
202      (Index, I8) | (Index, I16) | (Index, I32) | (Index, I64) | (Index, I128) |
203      (Index, F32) | (Index, F64) |
204      (U8, Index) | (U16, Index) | (U32, Index) | (U64, Index) | (U128, Index) |
205      (I8, Index) | (I16, Index) | (I32, Index) | (I64, Index) | (I128, Index) => true,
206
207      // Matrix: element type convertible and shape matches
208      (Matrix(box a, ashape), Matrix(box b, bshape)) if ashape.into_iter().product::<usize>() == bshape.into_iter().product::<usize>() && a.is_convertible_to(b) => true,
209
210      // Option conversions
211      (Option(box a), Option(box b)) if a.is_convertible_to(b) => true,
212
213      // Reference conversions
214      (Reference(box a), Reference(box b)) if a.is_convertible_to(b) => true,
215
216      // Tuple conversions (element-wise)
217      (Tuple(a), Tuple(b)) if a.len() == b.len() && a.iter().zip(b.iter()).all(|(x, y)| x.is_convertible_to(y)) => true,
218
219      // Set conversions
220      (Set(box a, _), Set(box b, _)) if a.is_convertible_to(b) => true,
221
222      // Map conversions
223      (Map(box ak, box av), Map(box bk, box bv)) if ak.is_convertible_to(bk) && av.is_convertible_to(bv) => true,
224
225      // Table conversions: allow source to have extra columns
226      (Table(acols, _), Table(bcols, _)) if bcols.iter().all(|(bk, bv)| 
227        acols.iter().any(|(ak, av)| ak == bk && av.is_convertible_to(bv))
228      ) => true,
229
230      // Record conversions: allow source to have extra fields
231      (Record(afields), Record(bfields)) if bfields.iter().all(|(bk, bv)| 
232        afields.iter().any(|(ak, av)| ak == bk && av.is_convertible_to(bv))
233      ) => true,
234
235      // Direct match
236      _ => self == other,
237    }
238  }
239
240  pub fn is_compatible(k1: ValueKind, k2: ValueKind) -> bool {
241    match k1 {
242      ValueKind::Reference(x) => {
243        ValueKind::is_compatible(*x,k2)
244      }
245      ValueKind::Matrix(x,_) => {
246        *x == k2
247      }
248      x => x == k2,
249    }
250  }
251
252  pub fn align(&self) -> usize {
253    // pointer alignment (platform word size) for pointer-like kinds
254    let ptr_align = mem::align_of::<usize>();
255
256    match self {
257      // unsigned integers
258      ValueKind::U8   => 1,
259      ValueKind::U16  => 2,
260      ValueKind::U32  => 4,
261      ValueKind::U64  => 8,
262      ValueKind::U128 => 16,
263
264      // signed integers
265      ValueKind::I8   => 1,
266      ValueKind::I16  => 2,
267      ValueKind::I32  => 4,
268      ValueKind::I64  => 8,
269      ValueKind::I128 => 16,
270
271      // floats
272      ValueKind::F32  => 4,
273      ValueKind::F64  => 8,
274
275      // complex / rational (assume composed of f64 parts)
276      ValueKind::ComplexNumber => 8,
277      ValueKind::RationalNumber => 8,
278
279      // small simple payloads
280      ValueKind::Bool => 1,
281      ValueKind::String => 1, // strings are length+bytes; bytes are packed
282      ValueKind::Id | ValueKind::Index => 8, // id/index -> likely machine word (u64)
283      ValueKind::Empty => 1,
284      ValueKind::Any => ptr_align,
285
286      // compound types
287      ValueKind::Matrix(elem_ty, _dims) => {
288        // matrix alignment = alignment of element type
289        elem_ty.align()
290      }
291
292      ValueKind::Enum(_space) => 8, // enum tag stored in u64
293      ValueKind::Atom(_id) => 8,
294
295      ValueKind::Record(fields) => {
296        // record alignment = max alignment of fields (or 1 if empty)
297        fields.iter()
298            .map(|(_, ty)| ty.align())
299            .max()
300            .unwrap_or(1)
301      }
302
303      ValueKind::Map(_, _) => ptr_align,   // typically pointer-based representation
304      ValueKind::Table(cols, _pk) => {
305        // table: use max column alignment or pointer-align if empty
306        cols.iter()
307            .map(|(_, ty)| ty.align())
308            .max()
309            .unwrap_or(ptr_align)
310      }
311
312      ValueKind::Tuple(elems) => {
313        elems.iter().map(|ty| ty.align()).max().unwrap_or(1)
314      }
315
316      ValueKind::Reference(inner) => ptr_align, // references are pointers at runtime
317
318      ValueKind::Set(elem, _) => {
319        // set alignment equals element alignment (or ptr_align fallback)
320        match elem.as_ref() {
321          v => v.align()
322        }
323      }
324      ValueKind::Option(inner) => inner.align(),
325    }
326  }
327}
328
329// Value
330// ----------------------------------------------------------------------------
331
332#[derive(Clone, Debug, PartialEq, Eq)]
333pub enum Value {
334  #[cfg(feature = "u8")]
335  U8(Ref<u8>),
336  #[cfg(feature = "u16")]
337  U16(Ref<u16>),
338  #[cfg(feature = "u32")]
339  U32(Ref<u32>),
340  #[cfg(feature = "u64")]
341  U64(Ref<u64>),
342  #[cfg(feature = "u128")]
343  U128(Ref<u128>),
344  #[cfg(feature = "i8")]
345  I8(Ref<i8>),
346  #[cfg(feature = "i16")]
347  I16(Ref<i16>),
348  #[cfg(feature = "i32")]
349  I32(Ref<i32>),
350  #[cfg(feature = "i64")]
351  I64(Ref<i64>),
352  #[cfg(feature = "i128")]
353  I128(Ref<i128>),
354  #[cfg(feature = "f32")]
355  F32(Ref<F32>),
356  #[cfg(feature = "f64")]
357  F64(Ref<F64>),
358  #[cfg(feature = "string")]
359  String(Ref<String>),
360  #[cfg(feature = "bool")]
361  Bool(Ref<bool>),
362  #[cfg(feature = "atom")]
363  Atom(u64),
364  #[cfg(feature = "matrix")]
365  MatrixIndex(Matrix<usize>),
366  #[cfg(all(feature = "matrix", feature = "bool"))]
367  MatrixBool(Matrix<bool>),
368  #[cfg(all(feature = "matrix", feature = "u8"))]
369  MatrixU8(Matrix<u8>),
370  #[cfg(all(feature = "matrix", feature = "u16"))]
371  MatrixU16(Matrix<u16>),
372  #[cfg(all(feature = "matrix", feature = "u32"))]
373  MatrixU32(Matrix<u32>),
374  #[cfg(all(feature = "matrix", feature = "u64"))]
375  MatrixU64(Matrix<u64>),
376  #[cfg(all(feature = "matrix", feature = "u128"))]
377  MatrixU128(Matrix<u128>),
378  #[cfg(all(feature = "matrix", feature = "i8"))]
379  MatrixI8(Matrix<i8>),
380  #[cfg(all(feature = "matrix", feature = "i16"))]
381  MatrixI16(Matrix<i16>),
382  #[cfg(all(feature = "matrix", feature = "i32"))]
383  MatrixI32(Matrix<i32>),
384  #[cfg(all(feature = "matrix", feature = "i64"))]
385  MatrixI64(Matrix<i64>),
386  #[cfg(all(feature = "matrix", feature = "i128"))]
387  MatrixI128(Matrix<i128>),
388  #[cfg(all(feature = "matrix", feature = "f32"))]
389  MatrixF32(Matrix<F32>),
390  #[cfg(all(feature = "matrix", feature = "f64"))]
391  MatrixF64(Matrix<F64>),
392  #[cfg(all(feature = "matrix", feature = "string"))]
393  MatrixString(Matrix<String>),
394  #[cfg(all(feature = "matrix", feature = "rational"))]
395  MatrixRationalNumber(Matrix<RationalNumber>),
396  #[cfg(all(feature = "matrix", feature = "complex"))]
397  MatrixComplexNumber(Matrix<ComplexNumber>),
398  #[cfg(feature = "matrix")]
399  MatrixValue(Matrix<Value>),
400  #[cfg(feature = "complex")]
401  ComplexNumber(Ref<ComplexNumber>),
402  #[cfg(feature = "rational")]
403  RationalNumber(Ref<RationalNumber>),
404  #[cfg(feature = "set")]
405  Set(MechSet),
406  #[cfg(feature = "map")]
407  Map(MechMap),
408  #[cfg(feature = "record")]
409  Record(Ref<MechRecord>),
410  #[cfg(feature = "table")]
411  Table(Ref<MechTable>),
412  #[cfg(feature = "tuple")]
413  Tuple(MechTuple),
414  #[cfg(feature = "enum")]
415  Enum(Box<MechEnum>),
416  Id(u64),
417  Index(Ref<usize>),
418  MutableReference(MutableReference),
419  Kind(ValueKind),
420  IndexAll,
421  Empty
422}
423
424impl fmt::Display for Value {
425  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
426    if cfg!(feature = "pretty_print") {
427      #[cfg(feature = "pretty_print")]
428      return fmt::Display::fmt(&self.pretty_print(), f);
429      fmt::Display::fmt(&"".to_string(), f) // kind of a hack to assuage the compiler
430    } else {
431      write!(f, "{:?}", self)
432    }
433  }
434}
435
436impl Hash for Value {
437  fn hash<H: Hasher>(&self, state: &mut H) {
438    match self {
439      #[cfg(feature = "rational")]
440      Value::RationalNumber(x) => x.borrow().hash(state),
441      #[cfg(feature = "u8")]
442      Value::U8(x)   => x.borrow().hash(state),
443      #[cfg(feature = "u16")]
444      Value::U16(x)  => x.borrow().hash(state),
445      #[cfg(feature = "u32")]
446      Value::U32(x)  => x.borrow().hash(state),
447      #[cfg(feature = "u64")]
448      Value::U64(x)  => x.borrow().hash(state),
449      #[cfg(feature = "u128")]
450      Value::U128(x) => x.borrow().hash(state),
451      #[cfg(feature = "i8")]
452      Value::I8(x)   => x.borrow().hash(state),
453      #[cfg(feature = "i16")]
454      Value::I16(x)  => x.borrow().hash(state),
455      #[cfg(feature = "i32")]
456      Value::I32(x)  => x.borrow().hash(state),
457      #[cfg(feature = "i64")]
458      Value::I64(x)  => x.borrow().hash(state),
459      #[cfg(feature = "i128")]
460      Value::I128(x) => x.borrow().hash(state),
461      #[cfg(feature = "f32")]
462      Value::F32(x)  => x.borrow().hash(state),
463      #[cfg(feature = "f64")]
464      Value::F64(x)  => x.borrow().hash(state),
465      #[cfg(feature = "complex")]
466      Value::ComplexNumber(x) => x.borrow().hash(state),
467      #[cfg(feature = "bool")]
468      Value::Bool(x) => x.borrow().hash(state),
469      #[cfg(feature = "atom")]
470      Value::Atom(x) => x.hash(state),
471      #[cfg(feature = "set")]
472      Value::Set(x)  => x.hash(state),
473      #[cfg(feature = "map")]
474      Value::Map(x)  => x.hash(state),
475      #[cfg(feature = "table")]
476      Value::Table(x) => x.borrow().hash(state),
477      #[cfg(feature = "tuple")]
478      Value::Tuple(x) => x.hash(state),
479      #[cfg(feature = "record")]
480      Value::Record(x) => x.borrow().hash(state),
481      #[cfg(feature = "enum")]
482      Value::Enum(x) => x.hash(state),
483      #[cfg(feature = "string")]
484      Value::String(x) => x.borrow().hash(state),
485      #[cfg(all(feature = "matrix", feature = "bool"))]
486      Value::MatrixBool(x) => x.hash(state),
487      #[cfg(feature = "matrix")]
488      Value::MatrixIndex(x) => x.hash(state),
489      #[cfg(all(feature = "matrix", feature = "u8"))]
490      Value::MatrixU8(x)   => x.hash(state),
491      #[cfg(all(feature = "matrix", feature = "u16"))]
492      Value::MatrixU16(x)  => x.hash(state),
493      #[cfg(all(feature = "matrix", feature = "u32"))]
494      Value::MatrixU32(x)  => x.hash(state),
495      #[cfg(all(feature = "matrix", feature = "u64"))]
496      Value::MatrixU64(x)  => x.hash(state),
497      #[cfg(all(feature = "matrix", feature = "u128"))]
498      Value::MatrixU128(x) => x.hash(state),
499      #[cfg(all(feature = "matrix", feature = "i8"))]
500      Value::MatrixI8(x)   => x.hash(state),
501      #[cfg(all(feature = "matrix", feature = "i16"))]
502      Value::MatrixI16(x)  => x.hash(state),
503      #[cfg(all(feature = "matrix", feature = "i32"))]
504      Value::MatrixI32(x)  => x.hash(state),
505      #[cfg(all(feature = "matrix", feature = "i64"))]
506      Value::MatrixI64(x)  => x.hash(state),
507      #[cfg(all(feature = "matrix", feature = "i128"))]
508      Value::MatrixI128(x) => x.hash(state),
509      #[cfg(all(feature = "matrix", feature = "f32"))]
510      Value::MatrixF32(x)  => x.hash(state),
511      #[cfg(all(feature = "matrix", feature = "f64"))]
512      Value::MatrixF64(x)  => x.hash(state),
513      #[cfg(all(feature = "matrix", feature = "string"))]
514      Value::MatrixString(x) => x.hash(state),
515      #[cfg(feature = "matrix")]
516      Value::MatrixValue(x)  => x.hash(state),
517      #[cfg(all(feature = "matrix", feature = "rational"))]
518      Value::MatrixRationalNumber(x) => x.hash(state),
519      #[cfg(all(feature = "matrix", feature = "complex"))]
520      Value::MatrixComplexNumber(x) => x.hash(state),
521      Value::Id(x)   => x.hash(state),
522      Value::Kind(x) => x.hash(state),
523      Value::Index(x)=> x.borrow().hash(state),
524      Value::MutableReference(x) => x.borrow().hash(state),
525      Value::Empty => Value::Empty.hash(state),
526      Value::IndexAll => Value::IndexAll.hash(state),
527    }
528  }
529}
530
531impl Value {
532
533  pub fn convert_to(&self, other: &ValueKind) -> Option<Value> {
534
535    if self.kind() == *other {
536        return Some(self.clone());
537    }
538
539    if !self.kind().is_convertible_to(other) {
540        return None;
541    }
542
543    match (self, other) {
544    // ==== Unsigned widening and narrowing ====
545    #[cfg(all(feature = "u8", feature = "u16"))]
546    (Value::U8(v), ValueKind::U16) => Some(Value::U16(Ref::new((*v.borrow()) as u16))),
547    #[cfg(all(feature = "u8", feature = "u32"))]
548    (Value::U8(v), ValueKind::U32) => Some(Value::U32(Ref::new((*v.borrow()) as u32))),
549    #[cfg(all(feature = "u8", feature = "u64"))]
550    (Value::U8(v), ValueKind::U64) => Some(Value::U64(Ref::new((*v.borrow()) as u64))),
551    #[cfg(all(feature = "u8", feature = "u128"))]
552    (Value::U8(v), ValueKind::U128) => Some(Value::U128(Ref::new((*v.borrow()) as u128))),
553    #[cfg(all(feature = "u8", feature = "i16"))]
554    (Value::U8(v), ValueKind::I16) => Some(Value::I16(Ref::new((*v.borrow()) as i16))),
555    #[cfg(all(feature = "u8", feature = "i32"))]
556    (Value::U8(v), ValueKind::I32) => Some(Value::I32(Ref::new((*v.borrow()) as i32))),
557    #[cfg(all(feature = "u8", feature = "i64"))]
558    (Value::U8(v), ValueKind::I64) => Some(Value::I64(Ref::new((*v.borrow()) as i64))),
559    #[cfg(all(feature = "u8", feature = "i128"))]
560    (Value::U8(v), ValueKind::I128) => Some(Value::I128(Ref::new((*v.borrow()) as i128))),
561    #[cfg(all(feature = "u8", feature = "f32"))]
562    (Value::U8(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
563    #[cfg(all(feature = "u8", feature = "f64"))]
564    (Value::U8(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
565
566    #[cfg(all(feature = "u16", feature = "u8"))]
567    (Value::U16(v), ValueKind::U8) => Some(Value::U8(Ref::new((*v.borrow()) as u8))),
568    #[cfg(all(feature = "u16", feature = "u32"))]
569    (Value::U16(v), ValueKind::U32) => Some(Value::U32(Ref::new((*v.borrow()) as u32))),
570    #[cfg(all(feature = "u16", feature = "u64"))]
571    (Value::U16(v), ValueKind::U64) => Some(Value::U64(Ref::new((*v.borrow()) as u64))),
572    #[cfg(all(feature = "u16", feature = "u128"))]
573    (Value::U16(v), ValueKind::U128) => Some(Value::U128(Ref::new((*v.borrow()) as u128))),
574    #[cfg(all(feature = "u16", feature = "i8"))]
575    (Value::U16(v), ValueKind::I8) => Some(Value::I8(Ref::new((*v.borrow()) as i8))),
576    #[cfg(all(feature = "u16", feature = "i32"))]
577    (Value::U16(v), ValueKind::I32) => Some(Value::I32(Ref::new((*v.borrow()) as i32))),
578    #[cfg(all(feature = "u16", feature = "i64"))]
579    (Value::U16(v), ValueKind::I64) => Some(Value::I64(Ref::new((*v.borrow()) as i64))),
580    #[cfg(all(feature = "u16", feature = "i128"))]
581    (Value::U16(v), ValueKind::I128) => Some(Value::I128(Ref::new((*v.borrow()) as i128))),
582    #[cfg(all(feature = "u16", feature = "f32"))]
583    (Value::U16(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
584    #[cfg(all(feature = "u16", feature = "f64"))]
585    (Value::U16(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
586
587    #[cfg(all(feature = "u32", feature = "u8"))]
588    (Value::U32(v), ValueKind::U8) => Some(Value::U8(Ref::new((*v.borrow()) as u8))),
589    #[cfg(all(feature = "u32", feature = "u16"))]
590    (Value::U32(v), ValueKind::U16) => Some(Value::U16(Ref::new((*v.borrow()) as u16))),
591    #[cfg(all(feature = "u32", feature = "u64"))]
592    (Value::U32(v), ValueKind::U64) => Some(Value::U64(Ref::new((*v.borrow()) as u64))),
593    #[cfg(all(feature = "u32", feature = "u128"))]
594    (Value::U32(v), ValueKind::U128) => Some(Value::U128(Ref::new((*v.borrow()) as u128))),
595    #[cfg(all(feature = "u32", feature = "i8"))]
596    (Value::U32(v), ValueKind::I8) => Some(Value::I8(Ref::new((*v.borrow()) as i8))),
597    #[cfg(all(feature = "u32", feature = "i16"))]
598    (Value::U32(v), ValueKind::I16) => Some(Value::I16(Ref::new((*v.borrow()) as i16))),
599    #[cfg(all(feature = "u32", feature = "i64"))]
600    (Value::U32(v), ValueKind::I64) => Some(Value::I64(Ref::new((*v.borrow()) as i64))),
601    #[cfg(all(feature = "u32", feature = "i128"))]
602    (Value::U32(v), ValueKind::I128) => Some(Value::I128(Ref::new((*v.borrow()) as i128))),
603    #[cfg(all(feature = "u32", feature = "f32"))]
604    (Value::U32(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
605    #[cfg(all(feature = "u32", feature = "f64"))]
606    (Value::U32(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
607
608    #[cfg(all(feature = "u64", feature = "u8"))]
609    (Value::U64(v), ValueKind::U8) => Some(Value::U8(Ref::new((*v.borrow()) as u8))),
610    #[cfg(all(feature = "u64", feature = "u16"))]
611    (Value::U64(v), ValueKind::U16) => Some(Value::U16(Ref::new((*v.borrow()) as u16))),
612    #[cfg(all(feature = "u64", feature = "u32"))]
613    (Value::U64(v), ValueKind::U32) => Some(Value::U32(Ref::new((*v.borrow()) as u32))),
614    #[cfg(all(feature = "u64", feature = "u128"))]
615    (Value::U64(v), ValueKind::U128) => Some(Value::U128(Ref::new((*v.borrow()) as u128))),
616    #[cfg(all(feature = "u64", feature = "i8"))]
617    (Value::U64(v), ValueKind::I8) => Some(Value::I8(Ref::new((*v.borrow()) as i8))),
618    #[cfg(all(feature = "u64", feature = "i16"))]
619    (Value::U64(v), ValueKind::I16) => Some(Value::I16(Ref::new((*v.borrow()) as i16))),
620    #[cfg(all(feature = "u64", feature = "i32"))]
621    (Value::U64(v), ValueKind::I32) => Some(Value::I32(Ref::new((*v.borrow()) as i32))),
622    #[cfg(all(feature = "u64", feature = "i128"))]
623    (Value::U64(v), ValueKind::I128) => Some(Value::I128(Ref::new((*v.borrow()) as i128))),
624    #[cfg(all(feature = "u64", feature = "f32"))]
625    (Value::U64(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
626    #[cfg(all(feature = "u64", feature = "f64"))]
627    (Value::U64(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
628
629    #[cfg(all(feature = "u128", feature = "u8"))]
630    (Value::U128(v), ValueKind::U8) => Some(Value::U8(Ref::new((*v.borrow()) as u8))),
631    #[cfg(all(feature = "u128", feature = "u16"))]
632    (Value::U128(v), ValueKind::U16) => Some(Value::U16(Ref::new((*v.borrow()) as u16))),
633    #[cfg(all(feature = "u128", feature = "u32"))]
634    (Value::U128(v), ValueKind::U32) => Some(Value::U32(Ref::new((*v.borrow()) as u32))),
635    #[cfg(all(feature = "u128", feature = "u64"))]
636    (Value::U128(v), ValueKind::U64) => Some(Value::U64(Ref::new((*v.borrow()) as u64))),
637    #[cfg(all(feature = "u128", feature = "i8"))]
638    (Value::U128(v), ValueKind::I8) => Some(Value::I8(Ref::new((*v.borrow()) as i8))),
639    #[cfg(all(feature = "u128", feature = "i16"))]
640    (Value::U128(v), ValueKind::I16) => Some(Value::I16(Ref::new((*v.borrow()) as i16))),
641    #[cfg(all(feature = "u128", feature = "i32"))]
642    (Value::U128(v), ValueKind::I32) => Some(Value::I32(Ref::new((*v.borrow()) as i32))),
643    #[cfg(all(feature = "u128", feature = "i64"))]
644    (Value::U128(v), ValueKind::I64) => Some(Value::I64(Ref::new((*v.borrow()) as i64))),
645    #[cfg(all(feature = "u128", feature = "f32"))]
646    (Value::U128(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
647    #[cfg(all(feature = "u128", feature = "f64"))]
648    (Value::U128(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
649
650    // ==== Signed widening and narrowing ====
651    #[cfg(all(feature = "i8", feature = "i16"))]
652    (Value::I8(v), ValueKind::I16) => Some(Value::I16(Ref::new((*v.borrow()) as i16))),
653    #[cfg(all(feature = "i8", feature = "i32"))]
654    (Value::I8(v), ValueKind::I32) => Some(Value::I32(Ref::new((*v.borrow()) as i32))),
655    #[cfg(all(feature = "i8", feature = "i64"))]
656    (Value::I8(v), ValueKind::I64) => Some(Value::I64(Ref::new((*v.borrow()) as i64))),
657    #[cfg(all(feature = "i8", feature = "i128"))]
658    (Value::I8(v), ValueKind::I128) => Some(Value::I128(Ref::new((*v.borrow()) as i128))),
659    #[cfg(all(feature = "i8", feature = "u16"))]
660    (Value::I8(v), ValueKind::U16) => Some(Value::U16(Ref::new((*v.borrow()) as u16))),
661    #[cfg(all(feature = "i8", feature = "u32"))]
662    (Value::I8(v), ValueKind::U32) => Some(Value::U32(Ref::new((*v.borrow()) as u32))),
663    #[cfg(all(feature = "i8", feature = "u64"))]
664    (Value::I8(v), ValueKind::U64) => Some(Value::U64(Ref::new((*v.borrow()) as u64))),
665    #[cfg(all(feature = "i8", feature = "u128"))]
666    (Value::I8(v), ValueKind::U128) => Some(Value::U128(Ref::new((*v.borrow()) as u128))),
667    #[cfg(all(feature = "i8", feature = "f32"))]
668    (Value::I8(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
669    #[cfg(all(feature = "i8", feature = "f64"))]
670    (Value::I8(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
671
672    #[cfg(all(feature = "i16", feature = "i8"))]
673    (Value::I16(v), ValueKind::I8) => Some(Value::I8(Ref::new((*v.borrow()) as i8))),
674    #[cfg(all(feature = "i16", feature = "i32"))]
675    (Value::I16(v), ValueKind::I32) => Some(Value::I32(Ref::new((*v.borrow()) as i32))),
676    #[cfg(all(feature = "i16", feature = "i64"))]
677    (Value::I16(v), ValueKind::I64) => Some(Value::I64(Ref::new((*v.borrow()) as i64))),
678    #[cfg(all(feature = "i16", feature = "i128"))]
679    (Value::I16(v), ValueKind::I128) => Some(Value::I128(Ref::new((*v.borrow()) as i128))),
680    #[cfg(all(feature = "i16", feature = "u8"))]
681    (Value::I16(v), ValueKind::U8) => Some(Value::U8(Ref::new((*v.borrow()) as u8))),
682    #[cfg(all(feature = "i16", feature = "u32"))]
683    (Value::I16(v), ValueKind::U32) => Some(Value::U32(Ref::new((*v.borrow()) as u32))),
684    #[cfg(all(feature = "i16", feature = "u64"))]
685    (Value::I16(v), ValueKind::U64) => Some(Value::U64(Ref::new((*v.borrow()) as u64))),
686    #[cfg(all(feature = "i16", feature = "u128"))]
687    (Value::I16(v), ValueKind::U128) => Some(Value::U128(Ref::new((*v.borrow()) as u128))),
688    #[cfg(all(feature = "i16", feature = "f32"))]
689    (Value::I16(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
690    #[cfg(all(feature = "i16", feature = "f64"))]
691    (Value::I16(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
692
693    #[cfg(all(feature = "i32", feature = "i8"))]
694    (Value::I32(v), ValueKind::I8) => Some(Value::I8(Ref::new((*v.borrow()) as i8))),
695    #[cfg(all(feature = "i32", feature = "i16"))]
696    (Value::I32(v), ValueKind::I16) => Some(Value::I16(Ref::new((*v.borrow()) as i16))),
697    #[cfg(all(feature = "i32", feature = "i64"))]
698    (Value::I32(v), ValueKind::I64) => Some(Value::I64(Ref::new((*v.borrow()) as i64))),
699    #[cfg(all(feature = "i32", feature = "i128"))]
700    (Value::I32(v), ValueKind::I128) => Some(Value::I128(Ref::new((*v.borrow()) as i128))),
701    #[cfg(all(feature = "i32", feature = "u8"))]
702    (Value::I32(v), ValueKind::U8) => Some(Value::U8(Ref::new((*v.borrow()) as u8))),
703    #[cfg(all(feature = "i32", feature = "u16"))]
704    (Value::I32(v), ValueKind::U16) => Some(Value::U16(Ref::new((*v.borrow()) as u16))),
705    #[cfg(all(feature = "i32", feature = "u64"))]
706    (Value::I32(v), ValueKind::U64) => Some(Value::U64(Ref::new((*v.borrow()) as u64))),
707    #[cfg(all(feature = "i32", feature = "u128"))]
708    (Value::I32(v), ValueKind::U128) => Some(Value::U128(Ref::new((*v.borrow()) as u128))),
709    #[cfg(all(feature = "i32", feature = "f32"))]
710    (Value::I32(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
711    #[cfg(all(feature = "i32", feature = "f64"))]
712    (Value::I32(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
713
714    #[cfg(all(feature = "i64", feature = "i8"))]
715    (Value::I64(v), ValueKind::I8) => Some(Value::I8(Ref::new((*v.borrow()) as i8))),
716    #[cfg(all(feature = "i64", feature = "i16"))]
717    (Value::I64(v), ValueKind::I16) => Some(Value::I16(Ref::new((*v.borrow()) as i16))),
718    #[cfg(all(feature = "i64", feature = "i32"))]
719    (Value::I64(v), ValueKind::I32) => Some(Value::I32(Ref::new((*v.borrow()) as i32))),
720    #[cfg(all(feature = "i64", feature = "i128"))]
721    (Value::I64(v), ValueKind::I128) => Some(Value::I128(Ref::new((*v.borrow()) as i128))),
722    #[cfg(all(feature = "i64", feature = "u8"))]
723    (Value::I64(v), ValueKind::U8) => Some(Value::U8(Ref::new((*v.borrow()) as u8))),
724    #[cfg(all(feature = "i64", feature = "u16"))]
725    (Value::I64(v), ValueKind::U16) => Some(Value::U16(Ref::new((*v.borrow()) as u16))),
726    #[cfg(all(feature = "i64", feature = "u32"))]
727    (Value::I64(v), ValueKind::U32) => Some(Value::U32(Ref::new((*v.borrow()) as u32))),
728    #[cfg(all(feature = "i64", feature = "u128"))]
729    (Value::I64(v), ValueKind::U128) => Some(Value::U128(Ref::new((*v.borrow()) as u128))),
730    #[cfg(all(feature = "i64", feature = "f32"))]
731    (Value::I64(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
732    #[cfg(all(feature = "i64", feature = "f64"))]
733    (Value::I64(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
734
735    #[cfg(all(feature = "i128", feature = "i8"))]
736    (Value::I128(v), ValueKind::I8) => Some(Value::I8(Ref::new((*v.borrow()) as i8))),
737    #[cfg(all(feature = "i128", feature = "i16"))]
738    (Value::I128(v), ValueKind::I16) => Some(Value::I16(Ref::new((*v.borrow()) as i16))),
739    #[cfg(all(feature = "i128", feature = "i32"))]
740    (Value::I128(v), ValueKind::I32) => Some(Value::I32(Ref::new((*v.borrow()) as i32))),
741    #[cfg(all(feature = "i128", feature = "i64"))]
742    (Value::I128(v), ValueKind::I64) => Some(Value::I64(Ref::new((*v.borrow()) as i64))),
743    #[cfg(all(feature = "i128", feature = "u8"))]
744    (Value::I128(v), ValueKind::U8) => Some(Value::U8(Ref::new((*v.borrow()) as u8))),
745    #[cfg(all(feature = "i128", feature = "u16"))]
746    (Value::I128(v), ValueKind::U16) => Some(Value::U16(Ref::new((*v.borrow()) as u16))),
747    #[cfg(all(feature = "i128", feature = "u32"))]
748    (Value::I128(v), ValueKind::U32) => Some(Value::U32(Ref::new((*v.borrow()) as u32))),
749    #[cfg(all(feature = "i128", feature = "u64"))]
750    (Value::I128(v), ValueKind::U64) => Some(Value::U64(Ref::new((*v.borrow()) as u64))),
751    #[cfg(all(feature = "i128", feature = "f32"))]
752    (Value::I128(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
753    #[cfg(all(feature = "i128", feature = "f64"))]
754    (Value::I128(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
755
756    // ==== Float widening and narrowing ====
757    #[cfg(all(feature = "f32", feature = "f64"))]
758    (Value::F32(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(v.borrow().0 as f64)))),
759    #[cfg(all(feature = "f32", feature = "f64"))]
760    (Value::F64(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(v.borrow().0 as f32)))),
761
762    // ==== Float to integer conversions (truncate) ====
763    #[cfg(all(feature = "f32", feature = "i8"))]
764    (Value::F32(v), ValueKind::I8) => Some(Value::I8(Ref::new(v.borrow().0 as i8))),
765    #[cfg(all(feature = "f32", feature = "i16"))]
766    (Value::F32(v), ValueKind::I16) => Some(Value::I16(Ref::new(v.borrow().0 as i16))),
767    #[cfg(all(feature = "f32", feature = "i32"))]
768    (Value::F32(v), ValueKind::I32) => Some(Value::I32(Ref::new(v.borrow().0 as i32))),
769    #[cfg(all(feature = "f32", feature = "i64"))]
770    (Value::F32(v), ValueKind::I64) => Some(Value::I64(Ref::new(v.borrow().0 as i64))),
771    #[cfg(all(feature = "f32", feature = "i128"))]
772    (Value::F32(v), ValueKind::I128) => Some(Value::I128(Ref::new(v.borrow().0 as i128))),
773    #[cfg(all(feature = "f32", feature = "u8"))]
774    (Value::F32(v), ValueKind::U8) => Some(Value::U8(Ref::new(v.borrow().0 as u8))),
775    #[cfg(all(feature = "f32", feature = "u16"))]
776    (Value::F32(v), ValueKind::U16) => Some(Value::U16(Ref::new(v.borrow().0 as u16))),
777    #[cfg(all(feature = "f32", feature = "u32"))]
778    (Value::F32(v), ValueKind::U32) => Some(Value::U32(Ref::new(v.borrow().0 as u32))),
779    #[cfg(all(feature = "f32", feature = "u64"))]
780    (Value::F32(v), ValueKind::U64) => Some(Value::U64(Ref::new(v.borrow().0 as u64))),
781    #[cfg(all(feature = "f32", feature = "u128"))]
782    (Value::F32(v), ValueKind::U128) => Some(Value::U128(Ref::new(v.borrow().0 as u128))),
783
784    #[cfg(all(feature = "f64", feature = "i8"))]
785    (Value::F64(v), ValueKind::I8) => Some(Value::I8(Ref::new(v.borrow().0 as i8))),
786    #[cfg(all(feature = "f64", feature = "i16"))]
787    (Value::F64(v), ValueKind::I16) => Some(Value::I16(Ref::new(v.borrow().0 as i16))),
788    #[cfg(all(feature = "f64", feature = "i32"))]
789    (Value::F64(v), ValueKind::I32) => Some(Value::I32(Ref::new(v.borrow().0 as i32))),
790    #[cfg(all(feature = "f64", feature = "i64"))]
791    (Value::F64(v), ValueKind::I64) => Some(Value::I64(Ref::new(v.borrow().0 as i64))),
792    #[cfg(all(feature = "f64", feature = "i128"))]
793    (Value::F64(v), ValueKind::I128) => Some(Value::I128(Ref::new(v.borrow().0 as i128))),
794    #[cfg(all(feature = "f64", feature = "u8"))]
795    (Value::F64(v), ValueKind::U8) => Some(Value::U8(Ref::new(v.borrow().0 as u8))),
796    #[cfg(all(feature = "f64", feature = "u16"))]
797    (Value::F64(v), ValueKind::U16) => Some(Value::U16(Ref::new(v.borrow().0 as u16))),
798    #[cfg(all(feature = "f64", feature = "u32"))]
799    (Value::F64(v), ValueKind::U32) => Some(Value::U32(Ref::new(v.borrow().0 as u32))),
800    #[cfg(all(feature = "f64", feature = "u64"))]
801    (Value::F64(v), ValueKind::U64) => Some(Value::U64(Ref::new(v.borrow().0 as u64))),
802    #[cfg(all(feature = "f64", feature = "u128"))]
803    (Value::F64(v), ValueKind::U128) => Some(Value::U128(Ref::new(v.borrow().0 as u128))),
804
805      /*
806      // ==== INDEX conversions ====
807      (Value::Index(i), U32) => Some(Value::U32(Ref::new((*i.borrow()) as u32))),
808      (Value::U32(v), Index) => Some(Value::Index(Ref::new((*v.borrow()) as usize))),
809
810
811      // ==== MATRIX conversions (element-wise) ====
812      (Value::MatrixU8(m), MatrixU16) => Some(Value::MatrixU16(m.map(|x| *x as u16))),
813      (Value::MatrixI32(m), MatrixF64) => Some(Value::MatrixF64(m.map(|x| (*x) as f64))),
814      // You can expand other matrix conversions similarly...
815
816      // ==== COMPLEX TYPES (stubs) ====
817      (Value::Set(set), Set(_)) => Some(Value::Set(set.clone())), // TODO: element-wise convert
818      (Value::Map(map), Map(_)) => Some(Value::Map(map.clone())), // TODO: key/value convert
819      (Value::Record(r), Record(_)) => Some(Value::Record(r.clone())), // TODO: field convert
820      (Value::Table(t), Table(_)) => Some(Value::Table(t.clone())), // TODO: column convert
821
822      // ==== ENUM, KIND ====
823      (Value::Enum(e), Enum(_)) => Some(Value::Enum(e.clone())),
824      (Value::Kind(k), Kind(_)) => Some(Value::Kind(k.clone())),
825
826      // ==== SPECIAL CASES ====
827      (Value::IndexAll, IndexAll) => Some(Value::IndexAll),
828      (Value::Empty, Empty) => Some(Value::Empty),
829      */
830      // ==== FALLBACK ====
831      _ => None,
832    }
833  }
834
835  pub fn size_of(&self) -> usize {
836    match self {
837      #[cfg(feature = "rational")]
838      Value::RationalNumber(x) => 16,
839      #[cfg(feature = "u8")]
840      Value::U8(x) => 1,
841      #[cfg(feature = "u16")]
842      Value::U16(x) => 2,
843      #[cfg(feature = "u32")]
844      Value::U32(x) => 4,
845      #[cfg(feature = "u64")]
846      Value::U64(x) => 8,
847      #[cfg(feature = "u128")]
848      Value::U128(x) => 16,
849      #[cfg(feature = "i8")]
850      Value::I8(x) => 1,
851      #[cfg(feature = "i16")]
852      Value::I16(x) => 2,
853      #[cfg(feature = "i32")]
854      Value::I32(x) => 4,
855      #[cfg(feature = "i64")]
856      Value::I64(x) => 8,
857      #[cfg(feature = "i128")]
858      Value::I128(x) => 16,
859      #[cfg(feature = "f32")]
860      Value::F32(x) => 4,
861      #[cfg(feature = "f64")]
862      Value::F64(x) => 8,
863      #[cfg(feature = "bool")]
864      Value::Bool(x) => 1,
865      #[cfg(feature = "complex")]
866      Value::ComplexNumber(x) => 16,
867      #[cfg(all(feature = "matrix"))]
868      Value::MatrixIndex(x) => x.size_of(),
869      #[cfg(all(feature = "matrix", feature = "bool"))]
870      Value::MatrixBool(x) => x.size_of(),
871      #[cfg(all(feature = "matrix", feature = "u8"))]
872      Value::MatrixU8(x)   => x.size_of(),
873      #[cfg(all(feature = "matrix", feature = "u16"))]
874      Value::MatrixU16(x)  => x.size_of(),
875      #[cfg(all(feature = "matrix", feature = "u32"))]
876      Value::MatrixU32(x)  => x.size_of(),
877      #[cfg(all(feature = "matrix", feature = "u64"))]
878      Value::MatrixU64(x)  => x.size_of(),
879      #[cfg(all(feature = "matrix", feature = "u128"))]
880      Value::MatrixU128(x) => x.size_of(),
881      #[cfg(all(feature = "matrix", feature = "i8"))]
882      Value::MatrixI8(x)   => x.size_of(),
883      #[cfg(all(feature = "matrix", feature = "i16"))]
884      Value::MatrixI16(x)  => x.size_of(),
885      #[cfg(all(feature = "matrix", feature = "i32"))]
886      Value::MatrixI32(x)  => x.size_of(),
887      #[cfg(all(feature = "matrix", feature = "i64"))]
888      Value::MatrixI64(x)  => x.size_of(),
889      #[cfg(all(feature = "matrix", feature = "i128"))]
890      Value::MatrixI128(x) => x.size_of(),
891      #[cfg(all(feature = "matrix", feature = "f32"))]
892      Value::MatrixF32(x)  => x.size_of(),
893      #[cfg(all(feature = "matrix", feature = "f64"))]
894      Value::MatrixF64(x)  => x.size_of(),
895      #[cfg(feature = "matrix")]
896      Value::MatrixValue(x)  => x.size_of(),
897      #[cfg(all(feature = "matrix", feature = "string"))]
898      Value::MatrixString(x) => x.size_of(),
899      #[cfg(all(feature = "matrix", feature = "rational"))]
900      Value::MatrixRationalNumber(x) => x.size_of(),
901      #[cfg(all(feature = "matrix", feature = "complex"))]
902      Value::MatrixComplexNumber(x) => x.size_of(),
903      #[cfg(feature = "string")]
904      Value::String(x) => x.borrow().len(),
905      #[cfg(feature = "atom")]
906      Value::Atom(x) => 8,
907      #[cfg(feature = "set")]
908      Value::Set(x) => x.size_of(),
909      #[cfg(feature = "map")]
910      Value::Map(x) => x.size_of(),
911      #[cfg(feature = "table")]
912      Value::Table(x) => x.borrow().size_of(),
913      #[cfg(feature = "record")]
914      Value::Record(x) => x.borrow().size_of(),
915      #[cfg(feature = "tuple")]
916      Value::Tuple(x) => x.size_of(),
917      #[cfg(feature = "enum")]
918      Value::Enum(x) => x.size_of(),
919      Value::MutableReference(x) => x.borrow().size_of(),
920      Value::Id(_) => 8,
921      Value::Index(x) => 8,
922      Value::Kind(_) => 0, // Kind is not a value, so it has no size
923      Value::Empty => 0,
924      Value::IndexAll => 0, // IndexAll is a special value, so it has no size
925    }
926  }
927
928  #[cfg(feature = "pretty_print")]
929  pub fn to_html(&self) -> String {
930    match self {
931      #[cfg(feature = "u8")]
932      Value::U8(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
933      #[cfg(feature = "u16")]
934      Value::U16(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
935      #[cfg(feature = "u32")]
936      Value::U32(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
937      #[cfg(feature = "u64")]
938      Value::U64(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
939      #[cfg(feature = "i8")]
940      Value::I8(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
941      #[cfg(feature = "i128")]
942      Value::I128(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
943      #[cfg(feature = "i16")]
944      Value::I16(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
945      #[cfg(feature = "i32")]
946      Value::I32(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
947      #[cfg(feature = "i64")]
948      Value::I64(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
949      #[cfg(feature = "i128")]
950      Value::I128(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
951      #[cfg(feature = "f32")]
952      Value::F32(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
953      #[cfg(feature = "f64")]
954      Value::F64(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
955      #[cfg(feature = "string")]
956      Value::String(s) => format!("<span class='mech-string'>\"{}\"</span>", s.borrow()),
957      #[cfg(feature = "bool")]
958      Value::Bool(b) => format!("<span class='mech-boolean'>{}</span>", b.borrow()),
959      #[cfg(feature = "complex")]
960      Value::ComplexNumber(c) => c.borrow().to_html(),
961      #[cfg(all(feature = "matrix", feature = "u8"))]
962      Value::MatrixU8(m) => m.to_html(),
963      #[cfg(all(feature = "matrix", feature = "u16"))]
964      Value::MatrixU16(m) => m.to_html(),
965      #[cfg(all(feature = "matrix", feature = "u32"))]
966      Value::MatrixU32(m) => m.to_html(),
967      #[cfg(all(feature = "matrix", feature = "u64"))]
968      Value::MatrixU64(m) => m.to_html(),
969      #[cfg(all(feature = "matrix", feature = "u128"))]
970      Value::MatrixU128(m) => m.to_html(),
971      #[cfg(all(feature = "matrix", feature = "i8"))]
972      Value::MatrixI8(m) => m.to_html(),
973      #[cfg(all(feature = "matrix", feature = "i16"))]
974      Value::MatrixI16(m) => m.to_html(),
975      #[cfg(all(feature = "matrix", feature = "i32"))]
976      Value::MatrixI32(m) => m.to_html(),
977      #[cfg(all(feature = "matrix", feature = "i64"))]
978      Value::MatrixI64(m) => m.to_html(),
979      #[cfg(all(feature = "matrix", feature = "i128"))]
980      Value::MatrixI128(m) => m.to_html(),
981      #[cfg(all(feature = "matrix", feature = "f64"))]
982      Value::MatrixF64(m) => m.to_html(),
983      #[cfg(all(feature = "matrix", feature = "f32"))]
984      Value::MatrixF32(m) => m.to_html(),
985      #[cfg(feature = "matrix")]
986      Value::MatrixIndex(m) => m.to_html(),
987      #[cfg(all(feature = "matrix", feature = "bool"))]
988      Value::MatrixBool(m) => m.to_html(),
989      #[cfg(all(feature = "matrix", feature = "string"))]
990      Value::MatrixString(m) => m.to_html(),
991      #[cfg(feature = "matrix")]
992      Value::MatrixValue(m) => m.to_html(),
993      #[cfg(all(feature = "matrix", feature = "rational"))]
994      Value::MatrixRationalNumber(m) => m.to_html(),
995      #[cfg(all(feature = "matrix", feature = "complex"))]
996      Value::MatrixComplexNumber(m) => m.to_html(),
997      #[cfg(feature = "atom")]
998      Value::Atom(a) => format!("<span class=\"mech-atom\"><span class=\"mech-atom-grave\">`</span><span class=\"mech-atom-name\">{}</span></span>",a),
999      #[cfg(feature = "set")]
1000      Value::Set(s) => s.to_html(),
1001      #[cfg(feature = "map")]
1002      Value::Map(m) => m.to_html(),
1003      #[cfg(feature = "table")]
1004      Value::Table(t) => t.borrow().to_html(),
1005      #[cfg(feature = "record")]
1006      Value::Record(r) => r.borrow().to_html(),
1007      #[cfg(feature = "tuple")]
1008      Value::Tuple(t) => t.to_html(),
1009      #[cfg(feature = "enum")]
1010      Value::Enum(e) => e.to_html(),
1011      Value::MutableReference(m) => {
1012        let inner = m.borrow();
1013        format!("<span class='mech-reference'>{}</span>", inner.to_html())
1014      },
1015      _ => "???".to_string(),
1016    }
1017  }
1018
1019  pub fn shape(&self) -> Vec<usize> {
1020    match self {
1021      #[cfg(feature = "rational")]
1022      Value::RationalNumber(x) => vec![1,1],
1023      #[cfg(feature = "complex")]
1024      Value::ComplexNumber(x) => vec![1,1],
1025      #[cfg(feature = "u8")]
1026      Value::U8(x) => vec![1,1],
1027      #[cfg(feature = "u16")]
1028      Value::U16(x) => vec![1,1],
1029      #[cfg(feature = "u32")]
1030      Value::U32(x) => vec![1,1],
1031      #[cfg(feature = "u64")]
1032      Value::U64(x) => vec![1,1],
1033      #[cfg(feature = "u128")]
1034      Value::U128(x) => vec![1,1],
1035      #[cfg(feature = "i8")]
1036      Value::I8(x) => vec![1,1],
1037      #[cfg(feature = "i16")]
1038      Value::I16(x) => vec![1,1],
1039      #[cfg(feature = "i32")]
1040      Value::I32(x) => vec![1,1],
1041      #[cfg(feature = "i64")]
1042      Value::I64(x) => vec![1,1],
1043      #[cfg(feature = "i128")]
1044      Value::I128(x) => vec![1,1],
1045      #[cfg(feature = "f32")]
1046      Value::F32(x) => vec![1,1],
1047      #[cfg(feature = "f64")]
1048      Value::F64(x) => vec![1,1],
1049      #[cfg(feature = "string")]
1050      Value::String(x) => vec![1,1],
1051      #[cfg(feature = "bool")]
1052      Value::Bool(x) => vec![1,1],
1053      #[cfg(feature = "atom")]
1054      Value::Atom(x) => vec![1,1],
1055      #[cfg(feature = "matrix")]
1056      Value::MatrixIndex(x) => x.shape(),
1057      #[cfg(all(feature = "matrix", feature = "bool"))]
1058      Value::MatrixBool(x) => x.shape(),
1059      #[cfg(all(feature = "matrix", feature = "u8"))]
1060      Value::MatrixU8(x) => x.shape(),
1061      #[cfg(all(feature = "matrix", feature = "u16"))]
1062      Value::MatrixU16(x) => x.shape(),
1063      #[cfg(all(feature = "matrix", feature = "u32"))]
1064      Value::MatrixU32(x) => x.shape(),
1065      #[cfg(all(feature = "matrix", feature = "u64"))]
1066      Value::MatrixU64(x) => x.shape(),
1067      #[cfg(all(feature = "matrix", feature = "u128"))]
1068      Value::MatrixU128(x) => x.shape(),
1069      #[cfg(all(feature = "matrix", feature = "i8"))]
1070      Value::MatrixI8(x) => x.shape(),
1071      #[cfg(all(feature = "matrix", feature = "i16"))]
1072      Value::MatrixI16(x) => x.shape(),
1073      #[cfg(all(feature = "matrix", feature = "i32"))]
1074      Value::MatrixI32(x) => x.shape(),
1075      #[cfg(all(feature = "matrix", feature = "i64"))]
1076      Value::MatrixI64(x) => x.shape(),
1077      #[cfg(all(feature = "matrix", feature = "i128"))]
1078      Value::MatrixI128(x) => x.shape(),
1079      #[cfg(all(feature = "matrix", feature = "f32"))]
1080      Value::MatrixF32(x) => x.shape(),
1081      #[cfg(all(feature = "matrix", feature = "f64"))]
1082      Value::MatrixF64(x) => x.shape(),
1083      #[cfg(all(feature = "matrix", feature = "string"))]
1084      Value::MatrixString(x) => x.shape(),
1085      #[cfg(feature = "matrix")]
1086      Value::MatrixValue(x) => x.shape(),
1087      #[cfg(all(feature = "matrix", feature = "rational"))]
1088      Value::MatrixRationalNumber(x) => x.shape(),
1089      #[cfg(all(feature = "matrix", feature = "complex"))]
1090      Value::MatrixComplexNumber(x) => x.shape(),
1091      #[cfg(feature = "enum")]
1092      Value::Enum(x) => vec![1,1],
1093      #[cfg(feature = "table")]
1094      Value::Table(x) => x.borrow().shape(),
1095      #[cfg(feature = "set")]
1096      Value::Set(x) => vec![1,x.set.len()],
1097      #[cfg(feature = "map")]
1098      Value::Map(x) => vec![1,x.map.len()],
1099      #[cfg(feature = "record")]
1100      Value::Record(x) => x.borrow().shape(),
1101      #[cfg(feature = "tuple")]
1102      Value::Tuple(x) => vec![1,x.size()],
1103      Value::Index(x) => vec![1,1],
1104      Value::MutableReference(x) => x.borrow().shape(),
1105      Value::Empty => vec![0,0],
1106      Value::IndexAll => vec![0,0],
1107      Value::Kind(_) => vec![0,0],
1108      Value::Id(x) => vec![0,0],
1109    }
1110  }
1111
1112  pub fn deref_kind(&self) -> ValueKind {
1113    match self {
1114      Value::MutableReference(x) => x.borrow().kind(),
1115      x => x.kind(),
1116    }
1117  }
1118
1119  pub fn kind(&self) -> ValueKind {
1120    match self {
1121      #[cfg(feature = "complex")]
1122      Value::ComplexNumber(_) => ValueKind::ComplexNumber,
1123      #[cfg(feature = "rational")]
1124      Value::RationalNumber(_) => ValueKind::RationalNumber,
1125      #[cfg(feature = "u8")]
1126      Value::U8(_) => ValueKind::U8,
1127      #[cfg(feature = "u16")]
1128      Value::U16(_) => ValueKind::U16,
1129      #[cfg(feature = "u32")]
1130      Value::U32(_) => ValueKind::U32,
1131      #[cfg(feature = "u64")]
1132      Value::U64(_) => ValueKind::U64,
1133      #[cfg(feature = "u128")]
1134      Value::U128(_) => ValueKind::U128,
1135      #[cfg(feature = "i8")]
1136      Value::I8(_) => ValueKind::I8,
1137      #[cfg(feature = "i16")]
1138      Value::I16(_) => ValueKind::I16,
1139      #[cfg(feature = "i32")]
1140      Value::I32(_) => ValueKind::I32,
1141      #[cfg(feature = "i64")]
1142      Value::I64(_) => ValueKind::I64,
1143      #[cfg(feature = "i128")]
1144      Value::I128(_) => ValueKind::I128,
1145      #[cfg(feature = "f32")]
1146      Value::F32(_) => ValueKind::F32,
1147      #[cfg(feature = "f64")]
1148      Value::F64(_) => ValueKind::F64,
1149      #[cfg(feature = "string")]
1150      Value::String(_) => ValueKind::String,
1151      #[cfg(feature = "bool")]
1152      Value::Bool(_) => ValueKind::Bool,
1153      #[cfg(feature = "atom")]
1154      Value::Atom(x) => ValueKind::Atom(*x),
1155      #[cfg(feature = "matrix")]
1156      Value::MatrixValue(x) => ValueKind::Matrix(Box::new(ValueKind::Any),x.shape()),
1157      #[cfg(feature = "matrix")]
1158      Value::MatrixIndex(x) => ValueKind::Matrix(Box::new(ValueKind::Index),x.shape()),
1159      #[cfg(all(feature = "matrix", feature = "bool"))]
1160      Value::MatrixBool(x) => ValueKind::Matrix(Box::new(ValueKind::Bool), x.shape()),
1161      #[cfg(all(feature = "matrix", feature = "u8"))]
1162      Value::MatrixU8(x) => ValueKind::Matrix(Box::new(ValueKind::U8), x.shape()),
1163      #[cfg(all(feature = "matrix", feature = "u16"))]
1164      Value::MatrixU16(x) => ValueKind::Matrix(Box::new(ValueKind::U16), x.shape()),
1165      #[cfg(all(feature = "matrix", feature = "u32"))]
1166      Value::MatrixU32(x) => ValueKind::Matrix(Box::new(ValueKind::U32), x.shape()),
1167      #[cfg(all(feature = "matrix", feature = "u64"))]
1168      Value::MatrixU64(x) => ValueKind::Matrix(Box::new(ValueKind::U64), x.shape()),
1169      #[cfg(all(feature = "matrix", feature = "u128"))]
1170      Value::MatrixU128(x) => ValueKind::Matrix(Box::new(ValueKind::U128), x.shape()),
1171      #[cfg(all(feature = "matrix", feature = "i8"))]
1172      Value::MatrixI8(x) => ValueKind::Matrix(Box::new(ValueKind::I8), x.shape()),
1173      #[cfg(all(feature = "matrix", feature = "i16"))]
1174      Value::MatrixI16(x) => ValueKind::Matrix(Box::new(ValueKind::I16), x.shape()),
1175      #[cfg(all(feature = "matrix", feature = "i32"))]
1176      Value::MatrixI32(x) => ValueKind::Matrix(Box::new(ValueKind::I32), x.shape()),
1177      #[cfg(all(feature = "matrix", feature = "i64"))]
1178      Value::MatrixI64(x) => ValueKind::Matrix(Box::new(ValueKind::I64), x.shape()),
1179      #[cfg(all(feature = "matrix", feature = "i128"))]
1180      Value::MatrixI128(x) => ValueKind::Matrix(Box::new(ValueKind::I128), x.shape()),
1181      #[cfg(all(feature = "matrix", feature = "f32"))]
1182      Value::MatrixF32(x) => ValueKind::Matrix(Box::new(ValueKind::F32), x.shape()),
1183      #[cfg(all(feature = "matrix", feature = "f64"))]
1184      Value::MatrixF64(x) => ValueKind::Matrix(Box::new(ValueKind::F64), x.shape()),
1185      #[cfg(all(feature = "matrix", feature = "string"))]
1186      Value::MatrixString(x) => ValueKind::Matrix(Box::new(ValueKind::String), x.shape()),
1187      #[cfg(all(feature = "matrix", feature = "rational"))]
1188      Value::MatrixRationalNumber(x) => ValueKind::Matrix(Box::new(ValueKind::RationalNumber), x.shape()),
1189      #[cfg(all(feature = "matrix", feature = "complex"))]
1190      Value::MatrixComplexNumber(x) => ValueKind::Matrix(Box::new(ValueKind::ComplexNumber), x.shape()),
1191      #[cfg(feature = "table")]
1192      Value::Table(x) => x.borrow().kind(),
1193      #[cfg(feature = "set")]
1194      Value::Set(x) => x.kind(),
1195      #[cfg(feature = "map")]
1196      Value::Map(x) => x.kind(),
1197      #[cfg(feature = "record")]
1198      Value::Record(x) => x.borrow().kind(),
1199      #[cfg(feature = "tuple")]
1200      Value::Tuple(x) => x.kind(),
1201      #[cfg(feature = "enum")]
1202      Value::Enum(x) => x.kind(),
1203      Value::MutableReference(x) => ValueKind::Reference(Box::new(x.borrow().kind())),
1204      Value::Empty => ValueKind::Empty,
1205      Value::IndexAll => ValueKind::Empty,
1206      Value::Id(x) => ValueKind::Id,
1207      Value::Index(x) => ValueKind::Index,
1208      Value::Kind(x) => x.clone(),
1209    }
1210  }
1211
1212  #[cfg(feature = "matrix")]
1213  pub fn is_matrix(&self) -> bool {
1214    match self {
1215      #[cfg(feature = "matrix")]
1216      Value::MatrixIndex(_) => true,
1217      #[cfg(all(feature = "matrix", feature = "bool"))]
1218      Value::MatrixBool(_) => true,
1219      #[cfg(all(feature = "matrix", feature = "u8"))]
1220      Value::MatrixU8(_) => true,
1221      #[cfg(all(feature = "matrix", feature = "u16"))]
1222      Value::MatrixU16(_) => true,
1223      #[cfg(all(feature = "matrix", feature = "u32"))]
1224      Value::MatrixU32(_) => true,
1225      #[cfg(all(feature = "matrix", feature = "u64"))]
1226      Value::MatrixU64(_) => true,
1227      #[cfg(all(feature = "matrix", feature = "u128"))]
1228      Value::MatrixU128(_) => true,
1229      #[cfg(all(feature = "matrix", feature = "i8"))]
1230      Value::MatrixI8(_) => true,
1231      #[cfg(all(feature = "matrix", feature = "i16"))]
1232      Value::MatrixI16(_) => true,
1233      #[cfg(all(feature = "matrix", feature = "i32"))]
1234      Value::MatrixI32(_) => true,
1235      #[cfg(all(feature = "matrix", feature = "i64"))]
1236      Value::MatrixI64(_) => true,
1237      #[cfg(all(feature = "matrix", feature = "i128"))]
1238      Value::MatrixI128(_) => true,
1239      #[cfg(all(feature = "matrix", feature = "f32"))]
1240      Value::MatrixF32(_) => true,
1241      #[cfg(all(feature = "matrix", feature = "f64"))]
1242      Value::MatrixF64(_) => true,
1243      #[cfg(all(feature = "matrix", feature = "string"))]
1244      Value::MatrixString(_) => true,
1245      #[cfg(all(feature = "matrix", feature = "rational"))]
1246      Value::MatrixRationalNumber(_) => true,
1247      #[cfg(all(feature = "matrix", feature = "complex"))]
1248      Value::MatrixComplexNumber(_) => true,
1249      #[cfg(feature = "matrix")]
1250      Value::MatrixValue(_) => true,
1251      _ => false,
1252    }
1253  }
1254
1255  pub fn is_scalar(&self) -> bool {
1256    match self {
1257      #[cfg(feature = "u8")]
1258      Value::U8(_) => true,
1259      #[cfg(feature = "u16")]
1260      Value::U16(_) => true,
1261      #[cfg(feature = "u32")]
1262      Value::U32(_) => true,
1263      #[cfg(feature = "u64")]
1264      Value::U64(_) => true,
1265      #[cfg(feature = "u128")]
1266      Value::U128(_) => true,
1267      #[cfg(feature = "i8")]
1268      Value::I8(_) => true,
1269      #[cfg(feature = "i16")]
1270      Value::I16(_) => true,
1271      #[cfg(feature = "i32")]
1272      Value::I32(_) => true,
1273      #[cfg(feature = "i64")]
1274      Value::I64(_) => true,
1275      #[cfg(feature = "i128")]
1276      Value::I128(_) => true,
1277      #[cfg(feature = "f32")]
1278      Value::F32(_) => true,
1279      #[cfg(feature = "f64")]
1280      Value::F64(_) => true,
1281      #[cfg(feature = "bool")]
1282      Value::Bool(_) => true,
1283      #[cfg(feature = "string")]
1284      Value::String(_) => true,
1285      #[cfg(feature = "atom")]
1286      Value::Atom(_) => true,
1287      Value::Index(_) => true,
1288      _ => false,
1289    }
1290  }
1291
1292  #[cfg(feature = "bool")]
1293  pub fn as_bool(&self) -> Option<Ref<bool>> {if let Value::Bool(v) = self { Some(v.clone()) } else if let Value::MutableReference(val) = self { val.borrow().as_bool() } else { None }}
1294  
1295  impl_as_type!(i8);
1296  impl_as_type!(i16);
1297  impl_as_type!(i32);
1298  impl_as_type!(i64);
1299  impl_as_type!(i128);
1300  impl_as_type!(u8);
1301  impl_as_type!(u16);
1302  impl_as_type!(u32);
1303  impl_as_type!(u64);
1304  impl_as_type!(u128);
1305
1306  #[cfg(feature = "string")]
1307  pub fn as_string(&self) -> Option<Ref<String>> {
1308    match self {
1309      #[cfg(feature = "string")]
1310      Value::String(v) => Some(v.clone()),
1311      #[cfg(feature = "u8")]
1312      Value::U8(v) => Some(Ref::new(v.borrow().to_string())),
1313      #[cfg(feature = "u16")]
1314      Value::U16(v) => Some(Ref::new(v.borrow().to_string())),
1315      #[cfg(feature = "u32")]
1316      Value::U32(v) => Some(Ref::new(v.borrow().to_string())),
1317      #[cfg(feature = "u64")]
1318      Value::U64(v) => Some(Ref::new(v.borrow().to_string())),
1319      #[cfg(feature = "u128")]
1320      Value::U128(v) => Some(Ref::new(v.borrow().to_string())),
1321      #[cfg(feature = "i8")]
1322      Value::I8(v) => Some(Ref::new(v.borrow().to_string())),
1323      #[cfg(feature = "i16")]
1324      Value::I16(v) => Some(Ref::new(v.borrow().to_string())),
1325      #[cfg(feature = "i32")]
1326      Value::I32(v) => Some(Ref::new(v.borrow().to_string())),
1327      #[cfg(feature = "i64")]
1328      Value::I64(v) => Some(Ref::new(v.borrow().to_string())),
1329      #[cfg(feature = "i128")]
1330      Value::I128(v) => Some(Ref::new(v.borrow().to_string())),
1331      #[cfg(feature = "f32")]
1332      Value::F32(v) => Some(Ref::new(format!("{}", v.borrow().0))),
1333      #[cfg(feature = "f64")]
1334      Value::F64(v) => Some(Ref::new(format!("{}", v.borrow().0))),
1335      #[cfg(feature = "bool")]
1336      Value::Bool(v) => Some(Ref::new(format!("{}", v.borrow()))),
1337      #[cfg(feature = "rational")]
1338      Value::RationalNumber(v) => Some(Ref::new(v.borrow().to_string())),
1339      #[cfg(feature = "complex")]
1340      Value::ComplexNumber(v) => Some(Ref::new(v.borrow().to_string())),
1341      Value::MutableReference(val) => val.borrow().as_string(),
1342      _ => None,
1343    }
1344  }
1345
1346  #[cfg(feature = "rational")]
1347  pub fn as_rationalnumber(&self) -> Option<Ref<RationalNumber>> {
1348    match self {
1349      Value::RationalNumber(v) => Some(v.clone()),
1350      #[cfg(feature = "f32")]
1351      Value::F32(v) => Some(Ref::new(RationalNumber::new(v.borrow().0 as i64, 1))),
1352      #[cfg(feature = "f64")]
1353      Value::F64(v) => Some(Ref::new(RationalNumber::new(v.borrow().0 as i64, 1))),
1354      #[cfg(feature = "u8")]
1355      Value::U8(v) => Some(Ref::new(RationalNumber::new(*v.borrow() as i64, 1))),
1356      #[cfg(feature = "u16")]
1357      Value::U16(v) => Some(Ref::new(RationalNumber::new(*v.borrow() as i64, 1))),
1358      #[cfg(feature = "u32")]
1359      Value::U32(v) => Some(Ref::new(RationalNumber::new(*v.borrow() as i64, 1))),
1360      #[cfg(feature = "u64")]
1361      Value::U64(v) => Some(Ref::new(RationalNumber::new(*v.borrow() as i64, 1))),
1362      #[cfg(feature = "u128")]
1363      Value::U128(v) => Some(Ref::new(RationalNumber::new(*v.borrow() as i64, 1))),
1364      #[cfg(feature = "i8")]
1365      Value::I8(v) => Some(Ref::new(RationalNumber::new(*v.borrow() as i64, 1))),
1366      #[cfg(feature = "i16")]
1367      Value::I16(v) => Some(Ref::new(RationalNumber::new(*v.borrow() as i64, 1))),
1368      #[cfg(feature = "i32")]
1369      Value::I32(v) => Some(Ref::new(RationalNumber::new(*v.borrow() as i64, 1))),
1370      #[cfg(feature = "i64")]
1371      Value::I64(v) => Some(Ref::new(RationalNumber::new(*v.borrow() as i64, 1))),
1372      #[cfg(feature = "i128")]
1373      Value::I128(v) => Some(Ref::new(RationalNumber::new(*v.borrow() as i64, 1))),
1374      Value::MutableReference(val) => val.borrow().as_rationalnumber(),
1375      _ => None,
1376    }
1377  }
1378
1379  #[cfg(feature = "complex")]
1380  pub fn as_complexnumber(&self) -> Option<Ref<ComplexNumber>> {
1381    match self {
1382      Value::ComplexNumber(v) => Some(v.clone()),
1383      #[cfg(feature = "f32")]
1384      Value::F32(v) =>  Some(Ref::new(ComplexNumber::new(v.borrow().0 as f64, 0.0))),
1385      #[cfg(feature = "f64")]
1386      Value::F64(v) =>  Some(Ref::new(ComplexNumber::new(v.borrow().0, 0.0))),
1387      #[cfg(feature = "u8")]
1388      Value::U8(v) =>   Some(Ref::new(ComplexNumber::new(*v.borrow() as f64, 0.0))),
1389      #[cfg(feature = "u16")]
1390      Value::U16(v) =>  Some(Ref::new(ComplexNumber::new(*v.borrow() as f64, 0.0))),
1391      #[cfg(feature = "u32")]
1392      Value::U32(v) =>  Some(Ref::new(ComplexNumber::new(*v.borrow() as f64, 0.0))),
1393      #[cfg(feature = "u64")]
1394      Value::U64(v) =>  Some(Ref::new(ComplexNumber::new(*v.borrow() as f64, 0.0))),
1395      #[cfg(feature = "u128")]
1396      Value::U128(v) => Some(Ref::new(ComplexNumber::new(*v.borrow() as f64, 0.0))),
1397      #[cfg(feature = "i8")]
1398      Value::I8(v) =>   Some(Ref::new(ComplexNumber::new(*v.borrow() as f64, 0.0))),
1399      #[cfg(feature = "i16")]
1400      Value::I16(v) =>  Some(Ref::new(ComplexNumber::new(*v.borrow() as f64, 0.0))),
1401      #[cfg(feature = "i32")]
1402      Value::I32(v) =>  Some(Ref::new(ComplexNumber::new(*v.borrow() as f64, 0.0))),
1403      #[cfg(feature = "i64")]
1404      Value::I64(v) =>  Some(Ref::new(ComplexNumber::new(*v.borrow() as f64, 0.0))),
1405      #[cfg(feature = "i128")]
1406      Value::I128(v) => Some(Ref::new(ComplexNumber::new(*v.borrow() as f64, 0.0))),
1407      Value::MutableReference(val) => val.borrow().as_complexnumber(),
1408      _ => None,
1409    }
1410  }
1411
1412  #[cfg(feature = "f32")]
1413  pub fn as_f32(&self) -> Option<Ref<F32>> {
1414    match self {
1415      #[cfg(feature = "u8")]
1416      Value::U8(v) => Some(Ref::new(F32::new(*v.borrow() as f32))),
1417      #[cfg(feature = "u16")]
1418      Value::U16(v) => Some(Ref::new(F32::new(*v.borrow() as f32))),
1419      #[cfg(feature = "u32")]
1420      Value::U32(v) => Some(Ref::new(F32::new(*v.borrow() as f32))),
1421      #[cfg(feature = "u64")]
1422      Value::U64(v) => Some(Ref::new(F32::new(*v.borrow() as f32))),
1423      #[cfg(feature = "u128")]
1424      Value::U128(v) => Some(Ref::new(F32::new(*v.borrow() as f32))),
1425      #[cfg(feature = "i8")]
1426      Value::I8(v) => Some(Ref::new(F32::new(*v.borrow() as f32))),
1427      #[cfg(feature = "i16")]
1428      Value::I16(v) => Some(Ref::new(F32::new(*v.borrow() as f32))),
1429      #[cfg(feature = "i32")]
1430      Value::I32(v) => Some(Ref::new(F32::new(*v.borrow() as f32))),
1431      #[cfg(feature = "i64")]
1432      Value::I64(v) => Some(Ref::new(F32::new(*v.borrow() as f32))),
1433      #[cfg(feature = "i128")]
1434      Value::I128(v) => Some(Ref::new(F32::new(*v.borrow() as f32))),
1435      #[cfg(feature = "f32")]
1436      Value::F32(v) => Some(v.clone()),
1437      #[cfg(feature = "f64")]
1438      Value::F64(v) => Some(Ref::new(F32::new((*v.borrow()).0 as f32))),
1439      Value::MutableReference(val) => val.borrow().as_f32(),
1440      _ => None,
1441    }
1442  }
1443
1444  #[cfg(feature = "f64")]
1445  pub fn as_f64(&self) -> Option<Ref<F64>> {
1446    match self {
1447      #[cfg(feature = "u8")]
1448      Value::U8(v) => Some(Ref::new(F64::new(*v.borrow() as f64))),
1449      #[cfg(feature = "u16")]
1450      Value::U16(v) => Some(Ref::new(F64::new(*v.borrow() as f64))),
1451      #[cfg(feature = "u32")]
1452      Value::U32(v) => Some(Ref::new(F64::new(*v.borrow() as f64))),
1453      #[cfg(feature = "u64")]
1454      Value::U64(v) => Some(Ref::new(F64::new(*v.borrow() as f64))),
1455      #[cfg(feature = "u128")]
1456      Value::U128(v) => Some(Ref::new(F64::new(*v.borrow() as f64))),
1457      #[cfg(feature = "i8")]
1458      Value::I8(v) => Some(Ref::new(F64::new(*v.borrow() as f64))),
1459      #[cfg(feature = "i16")]
1460      Value::I16(v) => Some(Ref::new(F64::new(*v.borrow() as f64))),
1461      #[cfg(feature = "i32")]
1462      Value::I32(v) => Some(Ref::new(F64::new(*v.borrow() as f64))),
1463      #[cfg(feature = "i64")]
1464      Value::I64(v) => Some(Ref::new(F64::new(*v.borrow() as f64))),
1465      #[cfg(feature = "i128")]
1466      Value::I128(v) => Some(Ref::new(F64::new(*v.borrow() as f64))),
1467      Value::F64(v) => Some(v.clone()),
1468      Value::MutableReference(val) => val.borrow().as_f64(),
1469      _ => None,
1470    }
1471  }
1472
1473  #[cfg(all(feature = "matrix", feature = "bool"))]
1474  pub fn as_vecbool(&self) -> Option<Vec<bool>> {if let Value::MatrixBool(v)  = self { Some(v.as_vec()) } else if let Value::Bool(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecbool()  } else { None }}
1475  
1476  #[cfg(all(feature = "matrix", feature = "f64"))]
1477  pub fn as_vecf64(&self) -> Option<Vec<F64>> { if let Value::MatrixF64(v) = self { Some(v.as_vec()) } else if let Value::F64(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecf64() } else if let Some(v) = self.as_f64() { Some(vec![v.borrow().clone()]) } else { None } }
1478  #[cfg(all(feature = "matrix", feature = "f32"))]
1479  pub fn as_vecf32(&self) -> Option<Vec<F32>> { if let Value::MatrixF32(v) = self { Some(v.as_vec()) } else if let Value::F32(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecf32() } else if let Some(v) = self.as_f32() { Some(vec![v.borrow().clone()]) } else { None } }
1480
1481  #[cfg(all(feature = "matrix", feature = "u8"))]
1482  pub fn as_vecu8(&self) -> Option<Vec<u8>> { if let Value::MatrixU8(v) = self { Some(v.as_vec()) } else if let Value::U8(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecu8() } else if let Some(v) = self.as_u8() { Some(vec![v.borrow().clone()]) } else { None } }
1483  #[cfg(all(feature = "matrix", feature = "u16"))]
1484  pub fn as_vecu16(&self) -> Option<Vec<u16>> { if let Value::MatrixU16(v) = self { Some(v.as_vec()) } else if let Value::U16(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecu16() } else if let Some(v) = self.as_u16() { Some(vec![v.borrow().clone()]) } else { None } }
1485  #[cfg(all(feature = "matrix", feature = "u32"))]
1486  pub fn as_vecu32(&self) -> Option<Vec<u32>> { if let Value::MatrixU32(v) = self { Some(v.as_vec()) } else if let Value::U32(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecu32() } else if let Some(v) = self.as_u32() { Some(vec![v.borrow().clone()]) } else { None } }
1487  #[cfg(all(feature = "matrix", feature = "u64"))]
1488  pub fn as_vecu64(&self) -> Option<Vec<u64>> { if let Value::MatrixU64(v) = self { Some(v.as_vec()) } else if let Value::U64(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecu64() } else if let Some(v) = self.as_u64() { Some(vec![v.borrow().clone()]) } else { None } }
1489  #[cfg(all(feature = "matrix", feature = "u128"))]
1490  pub fn as_vecu128(&self) -> Option<Vec<u128>> { if let Value::MatrixU128(v) = self { Some(v.as_vec()) } else if let Value::U128(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecu128() } else if let Some(v) = self.as_u128() { Some(vec![v.borrow().clone()]) } else { None } }
1491
1492  #[cfg(all(feature = "matrix", feature = "i8"))]
1493  pub fn as_veci8(&self) -> Option<Vec<i8>> { if let Value::MatrixI8(v) = self { Some(v.as_vec()) } else if let Value::I8(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_veci8() } else if let Some(v) = self.as_i8() { Some(vec![v.borrow().clone()]) } else { None } }
1494  #[cfg(all(feature = "matrix", feature = "i16"))]
1495  pub fn as_veci16(&self) -> Option<Vec<i16>> { if let Value::MatrixI16(v) = self { Some(v.as_vec()) } else if let Value::I16(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_veci16() } else if let Some(v) = self.as_i16() { Some(vec![v.borrow().clone()]) } else { None } }
1496  #[cfg(all(feature = "matrix", feature = "i32"))]
1497  pub fn as_veci32(&self) -> Option<Vec<i32>> { if let Value::MatrixI32(v) = self { Some(v.as_vec()) } else if let Value::I32(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_veci32() } else if let Some(v) = self.as_i32() { Some(vec![v.borrow().clone()]) } else { None } }
1498  #[cfg(all(feature = "matrix", feature = "i64"))]
1499  pub fn as_veci64(&self) -> Option<Vec<i64>> { if let Value::MatrixI64(v) = self { Some(v.as_vec()) } else if let Value::I64(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_veci64() } else if let Some(v) = self.as_i64() { Some(vec![v.borrow().clone()]) } else { None } }
1500  #[cfg(all(feature = "matrix", feature = "i128"))]
1501  pub fn as_veci128(&self) -> Option<Vec<i128>> { if let Value::MatrixI128(v) = self { Some(v.as_vec()) } else if let Value::I128(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_veci128() } else if let Some(v) = self.as_i128() { Some(vec![v.borrow().clone()]) } else { None } }
1502
1503  #[cfg(all(feature = "matrix", feature = "string"))]
1504  pub fn as_vecstring(&self) -> Option<Vec<String>> {if let Value::MatrixString(v)  = self { Some(v.as_vec()) } else if let Value::String(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecstring()  } else { None }}
1505
1506  #[cfg(all(feature = "matrix", feature = "rational"))]
1507  pub fn as_vecrationalnumber(&self) -> Option<Vec<RationalNumber>> {if let Value::MatrixRationalNumber(v)  = self { Some(v.as_vec()) } else if let Value::RationalNumber(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecrationalnumber()  } else { None }}
1508  #[cfg(all(feature = "matrix", feature = "complex"))]
1509  pub fn as_veccomplexnumber(&self) -> Option<Vec<ComplexNumber>> {if let Value::MatrixComplexNumber(v)  = self { Some(v.as_vec()) } else if let Value::ComplexNumber(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_veccomplexnumber()  } else { None }}
1510
1511  pub fn as_vecusize(&self) -> Option<Vec<usize>> {
1512    match self {
1513      #[cfg(feature = "matrix")]
1514      Value::MatrixIndex(v) => Some(v.as_vec()),
1515      #[cfg(all(feature = "matrix", feature = "i64"))]
1516      Value::MatrixI64(v) => Some(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
1517      #[cfg(all(feature = "matrix", feature = "f64"))]
1518      Value::MatrixF64(v) => Some(v.as_vec().iter().map(|x| (*x).0 as usize).collect::<Vec<usize>>()),
1519      #[cfg(all(feature = "matrix", feature = "f32"))]
1520      Value::MatrixF32(v) => Some(v.as_vec().iter().map(|x| (*x).0 as usize).collect::<Vec<usize>>()),
1521      #[cfg(all(feature = "matrix", feature = "bool"))]
1522      Value::MatrixBool(_) => None,
1523      #[cfg(feature = "bool")]
1524      Value::Bool(_) => None,
1525      Value::MutableReference(x) => x.borrow().as_vecusize(),
1526      _ => todo!(),
1527    }
1528  }
1529
1530  pub fn as_index(&self) -> MResult<Value> {
1531    match self.as_usize() {      
1532      Some(ix) => Ok(Value::Index(Ref::new(ix))),
1533      #[cfg(feature = "matrix")]
1534      None => match self.as_vecusize() {
1535        #[cfg(feature = "matrix")]
1536        Some(x) => {
1537          let shape = self.shape();
1538          let out = Value::MatrixIndex(usize::to_matrix(x, shape[0] * shape[1],1 ));
1539          Ok(out)
1540        },
1541        #[cfg(all(feature = "matrix", feature = "bool"))]
1542        None => match self.as_vecbool() {
1543          Some(x) => {
1544            let shape = self.shape();
1545            let out = match (shape[0], shape[1]) {
1546              (1,1) => Value::Bool(Ref::new(x[0])),
1547              #[cfg(all(feature = "vectord", feature = "bool"))]
1548              (1,n) => Value::MatrixBool(Matrix::DVector(Ref::new(DVector::from_vec(x)))),
1549              #[cfg(all(feature = "vectord", feature = "bool"))]
1550              (m,1) => Value::MatrixBool(Matrix::DVector(Ref::new(DVector::from_vec(x)))),
1551              #[cfg(all(feature = "vectord", feature = "bool"))]
1552              (m,n) => Value::MatrixBool(Matrix::DVector(Ref::new(DVector::from_vec(x)))),
1553              _ => todo!(),
1554            };
1555            Ok(out)
1556          }
1557          None => match self.as_bool() {
1558            Some(x) => Ok(Value::Bool(x)),
1559            None => Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledIndexKind}),
1560          }
1561        }
1562        x => Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::None}),
1563      }
1564      _ => todo!(),
1565    }
1566  }
1567
1568  pub fn as_usize(&self) -> Option<usize> {
1569    match self {      
1570      Value::Index(v) => Some(*v.borrow()),
1571      #[cfg(feature = "u8")]
1572      Value::U8(v) => Some(*v.borrow() as usize),
1573      #[cfg(feature = "u16")]
1574      Value::U16(v) => Some(*v.borrow() as usize),
1575      #[cfg(feature = "u32")]
1576      Value::U32(v) => Some(*v.borrow() as usize),
1577      #[cfg(feature = "u64")]
1578      Value::U64(v) => Some(*v.borrow() as usize),
1579      #[cfg(feature = "u128")]
1580      Value::U128(v) => Some(*v.borrow() as usize),
1581      #[cfg(feature = "i8")]
1582      Value::I8(v) => Some(*v.borrow() as usize),
1583      #[cfg(feature = "i16")]
1584      Value::I16(v) => Some(*v.borrow() as usize),
1585      #[cfg(feature = "i32")]
1586      Value::I32(v) => Some(*v.borrow() as usize),
1587      #[cfg(feature = "i64")]
1588      Value::I64(v) => Some(*v.borrow() as usize),
1589      #[cfg(feature = "i128")]
1590      Value::I128(v) => Some(*v.borrow() as usize),
1591      #[cfg(feature = "f32")]
1592      Value::F32(v) => Some((*v.borrow()).0 as usize),
1593      #[cfg(feature = "f64")]
1594      Value::F64(v) => Some((*v.borrow()).0 as usize),
1595      Value::MutableReference(v) => v.borrow().as_usize(),
1596      _ => None,
1597    }
1598  }
1599
1600  #[cfg(feature = "u8")]
1601  pub fn expect_u8(&self) -> MResult<Ref<u8>> {
1602    match self {
1603      Value::U8(v) => Ok(v.clone()),
1604      Value::MutableReference(v) => v.borrow().expect_u8(),
1605      _ => Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::None}),
1606    }
1607  }
1608
1609  #[cfg(feature = "f64")]
1610  pub fn expect_f64(&self) -> MResult<Ref<F64>> {
1611    match self {
1612      Value::F64(v) => Ok(v.clone()),
1613      Value::MutableReference(v) => v.borrow().expect_f64(),
1614      _ => Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::None}),
1615    }
1616  }
1617
1618}
1619
1620#[cfg(feature = "pretty_print")]
1621impl PrettyPrint for Value {
1622  fn pretty_print(&self) -> String {
1623    let mut builder = Builder::default();
1624    match self {
1625      #[cfg(feature = "u8")]
1626      Value::U8(x)   => {builder.push_record(vec![format!("{}",x.borrow())]);},
1627      #[cfg(feature = "u16")]
1628      Value::U16(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
1629      #[cfg(feature = "u32")]
1630      Value::U32(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
1631      #[cfg(feature = "u64")]
1632      Value::U64(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
1633      #[cfg(feature = "u128")]
1634      Value::U128(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
1635      #[cfg(feature = "i8")]
1636      Value::I8(x)   => {builder.push_record(vec![format!("{}",x.borrow())]);},
1637      #[cfg(feature = "i16")]
1638      Value::I16(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
1639      #[cfg(feature = "i32")]
1640      Value::I32(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
1641      #[cfg(feature = "i64")]
1642      Value::I64(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
1643      #[cfg(feature = "i128")]
1644      Value::I128(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
1645      #[cfg(feature = "f32")]
1646      Value::F32(x)  => {builder.push_record(vec![format!("{}",x.borrow().0)]);},
1647      #[cfg(feature = "f64")]
1648      Value::F64(x)  => {builder.push_record(vec![format!("{}",x.borrow().0)]);},
1649      #[cfg(feature = "bool")]
1650      Value::Bool(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
1651      #[cfg(feature = "complex")]
1652      Value::ComplexNumber(x) => {builder.push_record(vec![x.borrow().pretty_print()]);},
1653      #[cfg(feature = "rational")]
1654      Value::RationalNumber(x) => {builder.push_record(vec![format!("{}",x.borrow().pretty_print())]);},
1655      #[cfg(feature = "atom")]
1656      Value::Atom(x) => {builder.push_record(vec![format!("{}",x)]);},
1657      #[cfg(feature = "set")]
1658      Value::Set(x)  => {return x.pretty_print();}
1659      #[cfg(feature = "map")]
1660      Value::Map(x)  => {return x.pretty_print();}
1661      #[cfg(feature = "string")]
1662      Value::String(x) => {return format!("\"{}\"",x.borrow().clone());},
1663      #[cfg(feature = "table")]
1664      Value::Table(x)  => {return x.borrow().pretty_print();},
1665      #[cfg(feature = "tuple")]
1666      Value::Tuple(x)  => {return x.pretty_print();},
1667      #[cfg(feature = "record")]
1668      Value::Record(x) => {return x.borrow().pretty_print();},
1669      #[cfg(feature = "enum")]
1670      Value::Enum(x) => {return x.pretty_print();},
1671      #[cfg(feature = "matrix")]
1672      Value::MatrixIndex(x) => {return x.pretty_print();},
1673      #[cfg(all(feature = "matrix", feature = "bool"))]
1674      Value::MatrixBool(x) => {return x.pretty_print();},
1675      #[cfg(all(feature = "matrix", feature = "u8"))]
1676      Value::MatrixU8(x)   => {return x.pretty_print();},
1677      #[cfg(all(feature = "matrix", feature = "u16"))]
1678      Value::MatrixU16(x)  => {return x.pretty_print();},
1679      #[cfg(all(feature = "matrix", feature = "u32"))]
1680      Value::MatrixU32(x)  => {return x.pretty_print();},
1681      #[cfg(all(feature = "matrix", feature = "u64"))]
1682      Value::MatrixU64(x)  => {return x.pretty_print();},
1683      #[cfg(all(feature = "matrix", feature = "u128"))]
1684      Value::MatrixU128(x) => {return x.pretty_print();},
1685      #[cfg(all(feature = "matrix", feature = "i8"))]
1686      Value::MatrixI8(x)   => {return x.pretty_print();},
1687      #[cfg(all(feature = "matrix", feature = "i16"))]
1688      Value::MatrixI16(x)  => {return x.pretty_print();},
1689      #[cfg(all(feature = "matrix", feature = "i32"))]
1690      Value::MatrixI32(x)  => {return x.pretty_print();},
1691      #[cfg(all(feature = "matrix", feature = "i64"))]
1692      Value::MatrixI64(x)  => {return x.pretty_print();},
1693      #[cfg(all(feature = "matrix", feature = "i128"))]
1694      Value::MatrixI128(x) => {return x.pretty_print();},
1695      #[cfg(all(feature = "matrix", feature = "f32"))]
1696      Value::MatrixF32(x)  => {return x.pretty_print();},
1697      #[cfg(all(feature = "matrix", feature = "f64"))]
1698      Value::MatrixF64(x)  => {return x.pretty_print();},
1699      #[cfg(all(feature = "matrix", feature = "any"))]
1700      Value::MatrixValue(x)  => {return x.pretty_print();},
1701      #[cfg(all(feature = "matrix", feature = "string"))]
1702      Value::MatrixString(x)  => {return x.pretty_print();},
1703      #[cfg(all(feature = "matrix", feature = "rational"))]
1704      Value::MatrixRationalNumber(x) => {return x.pretty_print();},
1705      #[cfg(all(feature = "matrix", feature = "complex"))]
1706      Value::MatrixComplexNumber(x) => {return x.pretty_print();},
1707      Value::Index(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
1708      Value::MutableReference(x) => {return x.borrow().pretty_print();},
1709      Value::Empty => builder.push_record(vec!["_"]),
1710      Value::IndexAll => builder.push_record(vec![":"]),
1711      Value::Id(x) => builder.push_record(vec![format!("{}",humanize(x))]),
1712      Value::Kind(x) => builder.push_record(vec![format!("{}",x)]),
1713      x => {
1714        todo!("{x:#?}");
1715      },
1716    };
1717    let value_style = Style::empty()
1718      .top(' ')
1719      .left(' ')
1720      .right(' ')
1721      .bottom(' ')
1722      .vertical(' ')
1723      .intersection_bottom(' ')
1724      .corner_top_left(' ')
1725      .corner_top_right(' ')
1726      .corner_bottom_left(' ')
1727      .corner_bottom_right(' ');
1728    let mut table = builder.build();
1729    table.with(value_style);
1730    format!("{table}")
1731  }
1732}
1733
1734
1735pub trait ToIndex {
1736  fn to_index(&self) -> Value;
1737}
1738
1739#[cfg(feature = "matrix")]
1740impl ToIndex for Ref<Vec<i64>> { fn to_index(&self) -> Value { (*self.borrow()).iter().map(|x| *x as usize).collect::<Vec<usize>>().to_value() } }
1741
1742pub trait ToValue {
1743  fn to_value(&self) -> Value;
1744}
1745
1746#[cfg(feature = "matrix")]
1747impl ToValue for Vec<usize> {
1748  fn to_value(&self) -> Value {
1749    match self.len() {
1750      1 => Value::Index(Ref::new(self[0].clone())),
1751      //2 => Value::MatrixIndex(Matrix::RowVector2(Ref::new(RowVector2::from_vec(self.clone())))),
1752      //3 => Value::MatrixIndex(Matrix::RowVector3(Ref::new(RowVector3::from_vec(self.clone())))),
1753      //4 => Value::MatrixIndex(Matrix::RowVector4(Ref::new(RowVector4::from_vec(self.clone())))),
1754      n => Value::MatrixIndex(Matrix::DVector(Ref::new(DVector::from_vec(self.clone())))),
1755      _ => todo!(),
1756    }
1757  }
1758}
1759
1760impl ToValue for Ref<usize>  { fn to_value(&self) -> Value { Value::Index(self.clone())  } }
1761#[cfg(feature = "u8")]
1762impl ToValue for Ref<u8>     { fn to_value(&self) -> Value { Value::U8(self.clone())     } }
1763#[cfg(feature = "u16")]
1764impl ToValue for Ref<u16>    { fn to_value(&self) -> Value { Value::U16(self.clone())    } }
1765#[cfg(feature = "u32")]
1766impl ToValue for Ref<u32>    { fn to_value(&self) -> Value { Value::U32(self.clone())    } }
1767#[cfg(feature = "u64")]
1768impl ToValue for Ref<u64>    { fn to_value(&self) -> Value { Value::U64(self.clone())    } }
1769#[cfg(feature = "u128")]
1770impl ToValue for Ref<u128>   { fn to_value(&self) -> Value { Value::U128(self.clone())   } }
1771#[cfg(feature = "i8")]
1772impl ToValue for Ref<i8>     { fn to_value(&self) -> Value { Value::I8(self.clone())     } }
1773#[cfg(feature = "i16")]
1774impl ToValue for Ref<i16>    { fn to_value(&self) -> Value { Value::I16(self.clone())    } }
1775#[cfg(feature = "i32")]
1776impl ToValue for Ref<i32>    { fn to_value(&self) -> Value { Value::I32(self.clone())    } }
1777#[cfg(feature = "i64")]
1778impl ToValue for Ref<i64>    { fn to_value(&self) -> Value { Value::I64(self.clone())    } }
1779#[cfg(feature = "i128")]
1780impl ToValue for Ref<i128>   { fn to_value(&self) -> Value { Value::I128(self.clone())   } }
1781#[cfg(feature = "f32")]
1782impl ToValue for Ref<F32>    { fn to_value(&self) -> Value { Value::F32(self.clone())    } }
1783#[cfg(feature = "f64")]
1784impl ToValue for Ref<F64>    { fn to_value(&self) -> Value { Value::F64(self.clone())    } }
1785#[cfg(feature = "bool")]
1786impl ToValue for Ref<bool>   { fn to_value(&self) -> Value { Value::Bool(self.clone())   } }
1787#[cfg(feature = "string")]
1788impl ToValue for Ref<String> { fn to_value(&self) -> Value { Value::String(self.clone()) } }
1789#[cfg(feature = "rational")]
1790impl ToValue for Ref<RationalNumber> { fn to_value(&self) -> Value { Value::RationalNumber(self.clone()) } }
1791#[cfg(feature = "complex")]
1792impl ToValue for Ref<ComplexNumber> { fn to_value(&self) -> Value { Value::ComplexNumber(self.clone()) } }
1793
1794#[cfg(feature = "u8")]
1795impl From<u8> for Value {
1796  fn from(val: u8) -> Self {
1797    Value::U8(Ref::new(val))
1798  }
1799}
1800
1801#[cfg(feature = "u16")]
1802impl From<u16> for Value {
1803  fn from(val: u16) -> Self {
1804    Value::U16(Ref::new(val))
1805  }
1806}
1807
1808#[cfg(feature = "u32")]
1809impl From<u32> for Value {
1810  fn from(val: u32) -> Self {
1811    Value::U32(Ref::new(val))
1812  }
1813}
1814
1815#[cfg(feature = "u64")]
1816impl From<u64> for Value {
1817  fn from(val: u64) -> Self {
1818    Value::U64(Ref::new(val))
1819  }
1820}
1821
1822#[cfg(feature = "u128")]
1823impl From<u128> for Value {
1824  fn from(val: u128) -> Self {
1825    Value::U128(Ref::new(val))
1826  }
1827}
1828
1829#[cfg(feature = "i8")]
1830impl From<i8> for Value {
1831  fn from(val: i8) -> Self {
1832    Value::I8(Ref::new(val))
1833  }
1834}
1835
1836#[cfg(feature = "i16")]
1837impl From<i16> for Value {
1838  fn from(val: i16) -> Self {
1839    Value::I16(Ref::new(val))
1840  }
1841}
1842
1843#[cfg(feature = "i32")]
1844impl From<i32> for Value {
1845  fn from(val: i32) -> Self {
1846    Value::I32(Ref::new(val))
1847  }
1848}
1849
1850#[cfg(feature = "i64")]
1851impl From<i64> for Value {
1852  fn from(val: i64) -> Self {
1853    Value::I64(Ref::new(val))
1854  }
1855}
1856
1857#[cfg(feature = "i128")]
1858impl From<i128> for Value {
1859  fn from(val: i128) -> Self {
1860    Value::I128(Ref::new(val))
1861  }
1862}
1863
1864#[cfg(feature = "bool")]
1865impl From<bool> for Value {
1866  fn from(val: bool) -> Self {
1867    Value::Bool(Ref::new(val))
1868  }
1869}
1870
1871#[cfg(feature = "string")]
1872impl From<String> for Value {
1873  fn from(val: String) -> Self {
1874    Value::String(Ref::new(val))
1875  }
1876}
1877
1878#[cfg(feature = "rational")]
1879impl From<RationalNumber> for Value {
1880  fn from(val: RationalNumber) -> Self {
1881    Value::RationalNumber(Ref::new(val))
1882  }
1883}
1884
1885
1886pub trait ToUsize {
1887  fn to_usize(&self) -> usize;
1888}
1889
1890macro_rules! impl_to_usize_for {
1891  ($t:ty) => {
1892    impl ToUsize for $t {
1893      fn to_usize(&self) -> usize {
1894        #[allow(unused_comparisons)]
1895        if *self < 0 as $t {
1896          panic!("Cannot convert negative number to usize");
1897        }
1898        *self as usize
1899      }
1900    }
1901  };
1902}
1903
1904#[cfg(feature = "u8")]
1905impl_to_usize_for!(u8);
1906#[cfg(feature = "u16")]
1907impl_to_usize_for!(u16);
1908#[cfg(feature = "u32")]
1909impl_to_usize_for!(u32);
1910#[cfg(feature = "u64")]
1911impl_to_usize_for!(u64);
1912#[cfg(feature = "u128")]
1913impl_to_usize_for!(u128);
1914impl_to_usize_for!(usize);
1915
1916#[cfg(feature = "i8")]
1917impl_to_usize_for!(i8);
1918#[cfg(feature = "i16")]
1919impl_to_usize_for!(i16);
1920#[cfg(feature = "i32")]
1921impl_to_usize_for!(i32);
1922#[cfg(feature = "i64")]
1923impl_to_usize_for!(i64);
1924#[cfg(feature = "i128")]
1925impl_to_usize_for!(i128);
1926