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::C64;
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, C64, R64,
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::R64 => write!(f, "r64"),
74      ValueKind::C64 => 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      #[cfg(feature = "i8")]
116      ValueKind::I8 => FeatureKind::I8,
117      #[cfg(feature = "i16")]
118      ValueKind::I16 => FeatureKind::I16,
119      #[cfg(feature = "i32")]
120      ValueKind::I32 => FeatureKind::I32,
121      #[cfg(feature = "i64")]
122      ValueKind::I64 => FeatureKind::I64,
123      #[cfg(feature = "i128")]
124      ValueKind::I128 => FeatureKind::I128,
125      #[cfg(feature = "u8")] 
126      ValueKind::U8 => FeatureKind::U8,
127      #[cfg(feature = "u16")]
128      ValueKind::U16 => FeatureKind::U16,
129      #[cfg(feature = "u32")]
130      ValueKind::U32 => FeatureKind::U32,
131      #[cfg(feature = "u64")]
132      ValueKind::U64 => FeatureKind::U64,
133      #[cfg(feature = "u128")]
134      ValueKind::U128 => FeatureKind::U128,
135      #[cfg(feature = "f32")]
136      ValueKind::F32 => FeatureKind::F32, 
137      #[cfg(feature = "f64")]
138      ValueKind::F64 => FeatureKind::F64,
139      #[cfg(feature = "string")]
140      ValueKind::String => FeatureKind::String,
141      #[cfg(feature = "bool")]
142      ValueKind::Bool => FeatureKind::Bool,
143      #[cfg(feature = "table")]
144      ValueKind::Table(_,_) => FeatureKind::Table,
145      #[cfg(feature = "set")]
146      ValueKind::Set(_,_) => FeatureKind::Set,
147      #[cfg(feature = "map")]
148      ValueKind::Map(_,_) => FeatureKind::Map,
149      #[cfg(feature = "record")]
150      ValueKind::Record(_) => FeatureKind::Record,
151      #[cfg(feature = "tuple")] 
152      ValueKind::Tuple(_) => FeatureKind::Tuple,
153      #[cfg(feature = "enum")]
154      ValueKind::Enum(_) => FeatureKind::Enum,
155      #[cfg(feature = "matrix")]
156      ValueKind::Matrix(_,shape) => {
157        match shape[..] {
158          #[cfg(feature = "matrix1")]
159          [1,1] => FeatureKind::Matrix1,
160          #[cfg(feature = "matrix2")]
161          [2,2] => FeatureKind::Matrix2,
162          #[cfg(feature = "matrix3")]
163          [3,3] => FeatureKind::Matrix3,
164          #[cfg(feature = "matrix4")]
165          [4,4] => FeatureKind::Matrix4,
166          #[cfg(feature = "matrix2x3")]
167          [2,3] => FeatureKind::Matrix2x3,
168          #[cfg(feature = "matrix3x2")]
169          [3,2] => FeatureKind::Matrix3x2,
170          #[cfg(feature = "row_vector2")]
171          [1,2] => FeatureKind::RowVector2,
172          #[cfg(feature = "row_vector3")]
173          [1,3] => FeatureKind::RowVector3,
174          #[cfg(feature = "row_vector4")]
175          [1,4] => FeatureKind::RowVector4,
176          #[cfg(feature = "vector2")]
177          [2,1] => FeatureKind::Vector2,
178          #[cfg(feature = "vector3")]
179          [3,1] => FeatureKind::Vector3,
180          #[cfg(feature = "vector4")]
181          [4,1] => FeatureKind::Vector4,
182          #[cfg(feature = "row_vectord")]
183          [1,n] => FeatureKind::RowVectorD,
184          #[cfg(feature = "vectord")]
185          [n,1] => FeatureKind::VectorD,
186          #[cfg(feature = "matrixd")]
187          [n,m] => FeatureKind::MatrixD,
188          _ => panic!("Unsupported matrix shape for feature kind: {}", self),
189        }
190      }
191      #[cfg(feature = "complex")]
192      ValueKind::C64 => FeatureKind::C64,
193      #[cfg(feature = "rational")]
194      ValueKind::R64 => FeatureKind::R64,
195      ValueKind::Atom(_) => FeatureKind::Atom,
196      ValueKind::Index => FeatureKind::Index,
197      _ => panic!("Unsupported feature kind for value kind: {}", self),
198    }
199  }
200
201  pub fn collection_kind(&self) -> Option<ValueKind> {
202    match self {
203      ValueKind::Matrix(x,_) => Some(*x.clone()),
204      ValueKind::Set(x,_) => Some(*x.clone()),
205      _ => None,
206    }
207  }
208
209  pub fn deref_kind(&self) -> ValueKind {
210    match self {
211      ValueKind::Reference(x) => *x.clone(),
212      _ => self.clone(),
213    }
214  }
215
216  pub fn is_convertible_to(&self, other: &ValueKind) -> bool {
217    use ValueKind::*;
218    match (self, other) {
219      // Unsigned widening
220      (U8, U16) | (U8, U32) | (U8, U64) | (U8, U128) |
221      (U16, U32) | (U16, U64) | (U16, U128) |
222      (U32, U64) | (U32, U128) |
223      (U64, U128) => true,
224
225      // Signed widening
226      (I8, I16) | (I8, I32) | (I8, I64) | (I8, I128) |
227      (I16, I32) | (I16, I64) | (I16, I128) |
228      (I32, I64) | (I32, I128) |
229      (I64, I128) => true,
230
231      // Unsigned -> signed widening
232      (U8, I16) | (U8, I32) | (U8, I64) | (U8, I128) |
233      (U16, I32) | (U16, I64) | (U16, I128) |
234      (U32, I64) | (U32, I128) |
235      (U64, I128) => true,
236
237      // Signed -> unsigned widening (runtime safety not enforced here)
238      (I8, U16) | (I8, U32) | (I8, U64) | (I8, U128) |
239      (I16, U32) | (I16, U64) | (I16, U128) |
240      (I32, U64) | (I32, U128) |
241      (I64, U128) => true,
242
243      // Integer -> float
244      (U8, F32) | (U8, F64) |
245      (U16, F32) | (U16, F64) |
246      (U32, F32) | (U32, F64) |
247      (U64, F32) | (U64, F64) |
248      (U128, F32) | (U128, F64) |
249      (I8, F32) | (I8, F64) |
250      (I16, F32) | (I16, F64) |
251      (I32, F32) | (I32, F64) |
252      (I64, F32) | (I64, F64) |
253      (I128, F32) | (I128, F64) => true,
254
255      // Float widening + narrowing
256      (F32, F64) | (F64, F32) => true,
257
258      // Float -> integer (allowed, but lossy)
259      (F32, I8) | (F32, I16) | (F32, I32) | (F32, I64) | (F32, I128) |
260      (F32, U8) | (F32, U16) | (F32, U32) | (F32, U64) | (F32, U128) |
261      (F64, I8) | (F64, I16) | (F64, I32) | (F64, I64) | (F64, I128) |
262      (F64, U8) | (F64, U16) | (F64, U32) | (F64, U64) | (F64, U128) => true,
263
264      // Index conversions (both ways)
265      (Index, U8) | (Index, U16) | (Index, U32) | (Index, U64) | (Index, U128) |
266      (Index, I8) | (Index, I16) | (Index, I32) | (Index, I64) | (Index, I128) |
267      (Index, F32) | (Index, F64) |
268      (U8, Index) | (U16, Index) | (U32, Index) | (U64, Index) | (U128, Index) |
269      (I8, Index) | (I16, Index) | (I32, Index) | (I64, Index) | (I128, Index) => true,
270
271      // Matrix: element type convertible and shape matches
272      (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,
273
274      // Option conversions
275      (Option(box a), Option(box b)) if a.is_convertible_to(b) => true,
276
277      // Reference conversions
278      (Reference(box a), Reference(box b)) if a.is_convertible_to(b) => true,
279
280      // Tuple conversions (element-wise)
281      (Tuple(a), Tuple(b)) if a.len() == b.len() && a.iter().zip(b.iter()).all(|(x, y)| x.is_convertible_to(y)) => true,
282
283      // Set conversions
284      (Set(box a, _), Set(box b, _)) if a.is_convertible_to(b) => true,
285
286      // Map conversions
287      (Map(box ak, box av), Map(box bk, box bv)) if ak.is_convertible_to(bk) && av.is_convertible_to(bv) => true,
288
289      // Table conversions: allow source to have extra columns
290      (Table(acols, _), Table(bcols, _)) if bcols.iter().all(|(bk, bv)| 
291        acols.iter().any(|(ak, av)| ak == bk && av.is_convertible_to(bv))
292      ) => true,
293
294      // Record conversions: allow source to have extra fields
295      (Record(afields), Record(bfields)) if bfields.iter().all(|(bk, bv)| 
296        afields.iter().any(|(ak, av)| ak == bk && av.is_convertible_to(bv))
297      ) => true,
298
299      // Direct match
300      _ => self == other,
301    }
302  }
303
304  pub fn is_compatible(k1: ValueKind, k2: ValueKind) -> bool {
305    match k1 {
306      ValueKind::Reference(x) => {
307        ValueKind::is_compatible(*x,k2)
308      }
309      ValueKind::Matrix(x,_) => {
310        *x == k2
311      }
312      x => x == k2,
313    }
314  }
315
316  pub fn align(&self) -> usize {
317    // pointer alignment (platform word size) for pointer-like kinds
318    let ptr_align = mem::align_of::<usize>();
319
320    match self {
321      // unsigned integers
322      ValueKind::U8   => 1,
323      ValueKind::U16  => 2,
324      ValueKind::U32  => 4,
325      ValueKind::U64  => 8,
326      ValueKind::U128 => 16,
327
328      // signed integers
329      ValueKind::I8   => 1,
330      ValueKind::I16  => 2,
331      ValueKind::I32  => 4,
332      ValueKind::I64  => 8,
333      ValueKind::I128 => 16,
334
335      // floats
336      ValueKind::F32  => 4,
337      ValueKind::F64  => 8,
338
339      // complex / rational (assume composed of f64 parts)
340      ValueKind::C64 => 8,
341      ValueKind::R64 => 8,
342
343      // small simple payloads
344      ValueKind::Bool => 1,
345      ValueKind::String => 1, // strings are length+bytes; bytes are packed
346      ValueKind::Id | ValueKind::Index => 8, // id/index -> likely machine word (u64)
347      ValueKind::Empty => 1,
348      ValueKind::Any => ptr_align,
349
350      // compound types
351      ValueKind::Matrix(elem_ty, _dims) => {
352        // matrix alignment = alignment of element type
353        elem_ty.align()
354      }
355
356      ValueKind::Enum(_space) => 8, // enum tag stored in u64
357      ValueKind::Atom(_id) => 8,
358
359      ValueKind::Record(fields) => {
360        // record alignment = max alignment of fields (or 1 if empty)
361        fields.iter()
362            .map(|(_, ty)| ty.align())
363            .max()
364            .unwrap_or(1)
365      }
366
367      ValueKind::Map(_, _) => ptr_align,   // typically pointer-based representation
368      ValueKind::Table(cols, _pk) => {
369        // table: use max column alignment or pointer-align if empty
370        cols.iter()
371            .map(|(_, ty)| ty.align())
372            .max()
373            .unwrap_or(ptr_align)
374      }
375
376      ValueKind::Tuple(elems) => {
377        elems.iter().map(|ty| ty.align()).max().unwrap_or(1)
378      }
379
380      ValueKind::Reference(inner) => ptr_align, // references are pointers at runtime
381
382      ValueKind::Set(elem, _) => {
383        // set alignment equals element alignment (or ptr_align fallback)
384        match elem.as_ref() {
385          v => v.align()
386        }
387      }
388      ValueKind::Option(inner) => inner.align(),
389    }
390  }
391}
392
393pub trait AsNaKind {
394  fn as_na_kind() -> String;
395}
396
397macro_rules! impl_as_na_kind {
398  ($type:ty, $kind:expr) => {
399    impl<T> AsNaKind for $type {
400      fn as_na_kind() -> String { $kind.to_string() }
401    }
402  };
403}
404
405#[cfg(feature = "row_vector2")]
406impl_as_na_kind!(RowVector2<T>, "RowVector2");
407#[cfg(feature = "row_vector3")]
408impl_as_na_kind!(RowVector3<T>, "RowVector3");
409#[cfg(feature = "row_vector4")]
410impl_as_na_kind!(RowVector4<T>, "RowVector4");
411#[cfg(feature = "row_vectord")]
412impl_as_na_kind!(RowDVector<T>, "RowDVector");
413#[cfg(feature = "vector2")]
414impl_as_na_kind!(Vector2<T>, "Vector2");
415#[cfg(feature = "vector3")]
416impl_as_na_kind!(Vector3<T>, "Vector3");
417#[cfg(feature = "vector4")]
418impl_as_na_kind!(Vector4<T>, "Vector4");
419#[cfg(feature = "vectord")]
420impl_as_na_kind!(DVector<T>, "DVector");
421#[cfg(feature = "matrix1")]
422impl_as_na_kind!(Matrix1<T>, "Matrix1");
423#[cfg(feature = "matrix2")]
424impl_as_na_kind!(Matrix2<T>, "Matrix2");
425#[cfg(feature = "matrix3")]
426impl_as_na_kind!(Matrix3<T>, "Matrix3");
427#[cfg(feature = "matrix4")]
428impl_as_na_kind!(Matrix4<T>, "Matrix4");
429#[cfg(feature = "matrix2x3")]
430impl_as_na_kind!(Matrix2x3<T>, "Matrix2x3");
431#[cfg(feature = "matrix3x2")]
432impl_as_na_kind!(Matrix3x2<T>, "Matrix3x2");
433#[cfg(feature = "matrixd")]
434impl_as_na_kind!(DMatrix<T>, "DMatrix");
435
436pub trait AsValueKind {
437  fn as_value_kind() -> ValueKind;
438}
439
440macro_rules! impl_as_value_kind {
441  ($type:ty, $value_kind:expr) => {
442    impl AsValueKind for $type {
443      fn as_value_kind() -> ValueKind { $value_kind }
444    }
445  };
446}
447
448impl_as_value_kind!(usize, ValueKind::Index);
449
450#[cfg(feature = "i8")]
451impl_as_value_kind!(i8, ValueKind::I8);
452#[cfg(feature = "i16")]
453impl_as_value_kind!(i16, ValueKind::I16);
454#[cfg(feature = "i32")]
455impl_as_value_kind!(i32, ValueKind::I32);
456#[cfg(feature = "i64")]
457impl_as_value_kind!(i64, ValueKind::I64);
458#[cfg(feature = "i128")]
459impl_as_value_kind!(i128, ValueKind::I128);
460#[cfg(feature = "u8")]
461impl_as_value_kind!(u8, ValueKind::U8);
462#[cfg(feature = "u16")]
463impl_as_value_kind!(u16, ValueKind::U16);
464#[cfg(feature = "u32")]
465impl_as_value_kind!(u32, ValueKind::U32);
466#[cfg(feature = "u64")]
467impl_as_value_kind!(u64, ValueKind::U64);
468#[cfg(feature = "u128")]
469impl_as_value_kind!(u128, ValueKind::U128);
470#[cfg(feature = "f32")]
471impl_as_value_kind!(F32, ValueKind::F32);
472#[cfg(feature = "f64")]
473impl_as_value_kind!(F64, ValueKind::F64);
474#[cfg(feature = "bool")]
475impl_as_value_kind!(bool, ValueKind::Bool);
476#[cfg(feature = "string")]
477impl_as_value_kind!(String, ValueKind::String);
478#[cfg(feature = "rational")]
479impl_as_value_kind!(R64, ValueKind::R64);
480#[cfg(feature = "complex")]
481impl_as_value_kind!(C64, ValueKind::C64);
482
483
484macro_rules! impl_as_value_kind_for_matrix {
485  ($type:ty, $dims:expr) => {
486    impl<T: AsValueKind> AsValueKind for $type {
487      fn as_value_kind() -> ValueKind {
488        ValueKind::Matrix(Box::new(T::as_value_kind()), $dims)
489      }
490    }
491  };
492}
493
494#[cfg(feature = "row_vectord")]
495impl_as_value_kind_for_matrix!(RowDVector<T>, vec![1, 0]);
496#[cfg(feature = "row_vector2")]
497impl_as_value_kind_for_matrix!(RowVector2<T>, vec![1, 2]);
498#[cfg(feature = "row_vector3")]
499impl_as_value_kind_for_matrix!(RowVector3<T>, vec![1, 3]);
500#[cfg(feature = "row_vector4")]
501impl_as_value_kind_for_matrix!(RowVector4<T>, vec![1, 4]);
502#[cfg(feature = "vectord")]
503impl_as_value_kind_for_matrix!(DVector<T>, vec![0, 1]);
504#[cfg(feature = "vector2")]
505impl_as_value_kind_for_matrix!(Vector2<T>, vec![2, 1]);
506#[cfg(feature = "vector3")]
507impl_as_value_kind_for_matrix!(Vector3<T>, vec![3, 1]);
508#[cfg(feature = "vector4")]
509impl_as_value_kind_for_matrix!(Vector4<T>, vec![4, 1]);
510#[cfg(feature = "matrix1")]
511impl_as_value_kind_for_matrix!(Matrix1<T>, vec![1, 1]);
512#[cfg(feature = "matrix2")]
513impl_as_value_kind_for_matrix!(Matrix2<T>, vec![2, 2]);
514#[cfg(feature = "matrix3")]
515impl_as_value_kind_for_matrix!(Matrix3<T>, vec![3, 3]);
516#[cfg(feature = "matrix4")]
517impl_as_value_kind_for_matrix!(Matrix4<T>, vec![4, 4]);
518#[cfg(feature = "matrix2x3")]
519impl_as_value_kind_for_matrix!(Matrix2x3<T>, vec![2, 3]);
520#[cfg(feature = "matrix3x2")]
521impl_as_value_kind_for_matrix!(Matrix3x2<T>, vec![3, 2]);
522#[cfg(feature = "matrixd")]
523impl_as_value_kind_for_matrix!(DMatrix<T>, vec![0, 0]);
524
525impl AsValueKind for Value {
526  fn as_value_kind() -> ValueKind {
527    ValueKind::Any
528  }
529}
530
531
532// Value
533// ----------------------------------------------------------------------------
534
535#[derive(Clone, Debug, PartialEq, Eq)]
536pub enum Value {
537  #[cfg(feature = "u8")]
538  U8(Ref<u8>),
539  #[cfg(feature = "u16")]
540  U16(Ref<u16>),
541  #[cfg(feature = "u32")]
542  U32(Ref<u32>),
543  #[cfg(feature = "u64")]
544  U64(Ref<u64>),
545  #[cfg(feature = "u128")]
546  U128(Ref<u128>),
547  #[cfg(feature = "i8")]
548  I8(Ref<i8>),
549  #[cfg(feature = "i16")]
550  I16(Ref<i16>),
551  #[cfg(feature = "i32")]
552  I32(Ref<i32>),
553  #[cfg(feature = "i64")]
554  I64(Ref<i64>),
555  #[cfg(feature = "i128")]
556  I128(Ref<i128>),
557  #[cfg(feature = "f32")]
558  F32(Ref<F32>),
559  #[cfg(feature = "f64")]
560  F64(Ref<F64>),
561  #[cfg(feature = "string")]
562  String(Ref<String>),
563  #[cfg(feature = "bool")]
564  Bool(Ref<bool>),
565  #[cfg(feature = "atom")]
566  Atom(Ref<MechAtom>),
567  #[cfg(feature = "matrix")]
568  MatrixIndex(Matrix<usize>),
569  #[cfg(all(feature = "matrix", feature = "bool"))]
570  MatrixBool(Matrix<bool>),
571  #[cfg(all(feature = "matrix", feature = "u8"))]
572  MatrixU8(Matrix<u8>),
573  #[cfg(all(feature = "matrix", feature = "u16"))]
574  MatrixU16(Matrix<u16>),
575  #[cfg(all(feature = "matrix", feature = "u32"))]
576  MatrixU32(Matrix<u32>),
577  #[cfg(all(feature = "matrix", feature = "u64"))]
578  MatrixU64(Matrix<u64>),
579  #[cfg(all(feature = "matrix", feature = "u128"))]
580  MatrixU128(Matrix<u128>),
581  #[cfg(all(feature = "matrix", feature = "i8"))]
582  MatrixI8(Matrix<i8>),
583  #[cfg(all(feature = "matrix", feature = "i16"))]
584  MatrixI16(Matrix<i16>),
585  #[cfg(all(feature = "matrix", feature = "i32"))]
586  MatrixI32(Matrix<i32>),
587  #[cfg(all(feature = "matrix", feature = "i64"))]
588  MatrixI64(Matrix<i64>),
589  #[cfg(all(feature = "matrix", feature = "i128"))]
590  MatrixI128(Matrix<i128>),
591  #[cfg(all(feature = "matrix", feature = "f32"))]
592  MatrixF32(Matrix<F32>),
593  #[cfg(all(feature = "matrix", feature = "f64"))]
594  MatrixF64(Matrix<F64>),
595  #[cfg(all(feature = "matrix", feature = "string"))]
596  MatrixString(Matrix<String>),
597  #[cfg(all(feature = "matrix", feature = "rational"))]
598  MatrixR64(Matrix<R64>),
599  #[cfg(all(feature = "matrix", feature = "complex"))]
600  MatrixC64(Matrix<C64>),
601  #[cfg(feature = "matrix")]
602  MatrixValue(Matrix<Value>),
603  #[cfg(feature = "complex")]
604  C64(Ref<C64>),
605  #[cfg(feature = "rational")]
606  R64(Ref<R64>),
607  #[cfg(feature = "set")]
608  Set(Ref<MechSet>),
609  #[cfg(feature = "map")]
610  Map(Ref<MechMap>),
611  #[cfg(feature = "record")]
612  Record(Ref<MechRecord>),
613  #[cfg(feature = "table")]
614  Table(Ref<MechTable>),
615  #[cfg(feature = "tuple")]
616  Tuple(Ref<MechTuple>),
617  #[cfg(feature = "enum")]
618  Enum(Ref<MechEnum>),
619  Id(u64),
620  Index(Ref<usize>),
621  MutableReference(MutableReference),
622  Kind(ValueKind),
623  IndexAll,
624  Empty
625}
626
627impl fmt::Display for Value {
628  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
629    if cfg!(feature = "pretty_print") {
630      #[cfg(feature = "pretty_print")]
631      return fmt::Display::fmt(&self.pretty_print(), f);
632      fmt::Display::fmt(&"".to_string(), f) // kind of a hack to assuage the compiler
633    } else {
634      write!(f, "{:?}", self)
635    }
636  }
637}
638
639impl Hash for Value {
640  fn hash<H: Hasher>(&self, state: &mut H) {
641    match self {
642      #[cfg(feature = "rational")]
643      Value::R64(x) => x.borrow().hash(state),
644      #[cfg(feature = "u8")]
645      Value::U8(x)   => x.borrow().hash(state),
646      #[cfg(feature = "u16")]
647      Value::U16(x)  => x.borrow().hash(state),
648      #[cfg(feature = "u32")]
649      Value::U32(x)  => x.borrow().hash(state),
650      #[cfg(feature = "u64")]
651      Value::U64(x)  => x.borrow().hash(state),
652      #[cfg(feature = "u128")]
653      Value::U128(x) => x.borrow().hash(state),
654      #[cfg(feature = "i8")]
655      Value::I8(x)   => x.borrow().hash(state),
656      #[cfg(feature = "i16")]
657      Value::I16(x)  => x.borrow().hash(state),
658      #[cfg(feature = "i32")]
659      Value::I32(x)  => x.borrow().hash(state),
660      #[cfg(feature = "i64")]
661      Value::I64(x)  => x.borrow().hash(state),
662      #[cfg(feature = "i128")]
663      Value::I128(x) => x.borrow().hash(state),
664      #[cfg(feature = "f32")]
665      Value::F32(x)  => x.borrow().hash(state),
666      #[cfg(feature = "f64")]
667      Value::F64(x)  => x.borrow().hash(state),
668      #[cfg(feature = "complex")]
669      Value::C64(x) => x.borrow().hash(state),
670      #[cfg(feature = "bool")]
671      Value::Bool(x) => x.borrow().hash(state),
672      #[cfg(feature = "atom")]
673      Value::Atom(x) => x.borrow().hash(state),
674      #[cfg(feature = "set")]
675      Value::Set(x)  => x.borrow().hash(state),
676      #[cfg(feature = "map")]
677      Value::Map(x)  => x.borrow().hash(state),
678      #[cfg(feature = "table")]
679      Value::Table(x) => x.borrow().hash(state),
680      #[cfg(feature = "tuple")]
681      Value::Tuple(x) => x.borrow().hash(state),
682      #[cfg(feature = "record")]
683      Value::Record(x) => x.borrow().hash(state),
684      #[cfg(feature = "enum")]
685      Value::Enum(x) => x.borrow().hash(state),
686      #[cfg(feature = "string")]
687      Value::String(x) => x.borrow().hash(state),
688      #[cfg(all(feature = "matrix", feature = "bool"))]
689      Value::MatrixBool(x) => x.hash(state),
690      #[cfg(feature = "matrix")]
691      Value::MatrixIndex(x) => x.hash(state),
692      #[cfg(all(feature = "matrix", feature = "u8"))]
693      Value::MatrixU8(x)   => x.hash(state),
694      #[cfg(all(feature = "matrix", feature = "u16"))]
695      Value::MatrixU16(x)  => x.hash(state),
696      #[cfg(all(feature = "matrix", feature = "u32"))]
697      Value::MatrixU32(x)  => x.hash(state),
698      #[cfg(all(feature = "matrix", feature = "u64"))]
699      Value::MatrixU64(x)  => x.hash(state),
700      #[cfg(all(feature = "matrix", feature = "u128"))]
701      Value::MatrixU128(x) => x.hash(state),
702      #[cfg(all(feature = "matrix", feature = "i8"))]
703      Value::MatrixI8(x)   => x.hash(state),
704      #[cfg(all(feature = "matrix", feature = "i16"))]
705      Value::MatrixI16(x)  => x.hash(state),
706      #[cfg(all(feature = "matrix", feature = "i32"))]
707      Value::MatrixI32(x)  => x.hash(state),
708      #[cfg(all(feature = "matrix", feature = "i64"))]
709      Value::MatrixI64(x)  => x.hash(state),
710      #[cfg(all(feature = "matrix", feature = "i128"))]
711      Value::MatrixI128(x) => x.hash(state),
712      #[cfg(all(feature = "matrix", feature = "f32"))]
713      Value::MatrixF32(x)  => x.hash(state),
714      #[cfg(all(feature = "matrix", feature = "f64"))]
715      Value::MatrixF64(x)  => x.hash(state),
716      #[cfg(all(feature = "matrix", feature = "string"))]
717      Value::MatrixString(x) => x.hash(state),
718      #[cfg(feature = "matrix")]
719      Value::MatrixValue(x)  => x.hash(state),
720      #[cfg(all(feature = "matrix", feature = "rational"))]
721      Value::MatrixR64(x) => x.hash(state),
722      #[cfg(all(feature = "matrix", feature = "complex"))]
723      Value::MatrixC64(x) => x.hash(state),
724      Value::Id(x)   => x.hash(state),
725      Value::Kind(x) => x.hash(state),
726      Value::Index(x)=> x.borrow().hash(state),
727      Value::MutableReference(x) => x.borrow().hash(state),
728      Value::Empty => Value::Empty.hash(state),
729      Value::IndexAll => Value::IndexAll.hash(state),
730    }
731  }
732}
733impl Value {
734
735  #[cfg(feature = "matrix")]
736  pub unsafe fn get_copyable_matrix_unchecked<T>(&self) -> Box<dyn CopyMat<T>> 
737  where T: AsValueKind + 'static
738  {
739    match (T::as_value_kind(), self) {
740      #[cfg(all(feature = "matrix", feature = "bool"))]
741      (ValueKind::Bool, Value::MatrixBool(m)) => {
742        let b: Box<dyn CopyMat<bool>> = m.get_copyable_matrix();
743        std::mem::transmute::<Box<dyn CopyMat<bool>>, Box<dyn CopyMat<T>>>(b)
744      }
745      #[cfg(all(feature = "matrix", feature = "u8"))]
746      (ValueKind::U8, Value::MatrixU8(m)) => {
747        let b: Box<dyn CopyMat<u8>> = m.get_copyable_matrix();
748        std::mem::transmute::<Box<dyn CopyMat<u8>>, Box<dyn CopyMat<T>>>(b)
749      }
750      #[cfg(all(feature = "matrix", feature = "u16"))]
751      (ValueKind::U16, Value::MatrixU16(m)) => {
752        let b: Box<dyn CopyMat<u16>> = m.get_copyable_matrix();
753        std::mem::transmute::<Box<dyn CopyMat<u16>>, Box<dyn CopyMat<T>>>(b)
754      }
755      #[cfg(all(feature = "matrix", feature = "u32"))]
756      (ValueKind::U32, Value::MatrixU32(m)) => {
757        let b: Box<dyn CopyMat<u32>> = m.get_copyable_matrix();
758        std::mem::transmute::<Box<dyn CopyMat<u32>>, Box<dyn CopyMat<T>>>(b)
759      }
760      #[cfg(all(feature = "matrix", feature = "u64"))]
761      (ValueKind::U64, Value::MatrixU64(m)) => {
762        let b: Box<dyn CopyMat<u64>> = m.get_copyable_matrix();
763        std::mem::transmute::<Box<dyn CopyMat<u64>>, Box<dyn CopyMat<T>>>(b)
764      }
765      #[cfg(all(feature = "matrix", feature = "u128"))]
766      (ValueKind::U128, Value::MatrixU128(m)) => {
767        let b: Box<dyn CopyMat<u128>> = m.get_copyable_matrix();
768        std::mem::transmute::<Box<dyn CopyMat<u128>>, Box<dyn CopyMat<T>>>(b)
769      }
770      #[cfg(all(feature = "matrix", feature = "i8"))]
771      (ValueKind::I8, Value::MatrixI8(m)) => {
772        let b: Box<dyn CopyMat<i8>> = m.get_copyable_matrix();
773        std::mem::transmute::<Box<dyn CopyMat<i8>>, Box<dyn CopyMat<T>>>(b)
774      }
775      #[cfg(all(feature = "matrix", feature = "i16"))]
776      (ValueKind::I16, Value::MatrixI16(m)) => {
777        let b: Box<dyn CopyMat<i16>> = m.get_copyable_matrix();
778        std::mem::transmute::<Box<dyn CopyMat<i16>>, Box<dyn CopyMat<T>>>(b)
779      }
780      #[cfg(all(feature = "matrix", feature = "i32"))]
781      (ValueKind::I32, Value::MatrixI32(m)) => {
782        let b: Box<dyn CopyMat<i32>> = m.get_copyable_matrix();
783        std::mem::transmute::<Box<dyn CopyMat<i32>>, Box<dyn CopyMat<T>>>(b)
784      }
785      #[cfg(all(feature = "matrix", feature = "i64"))]
786      (ValueKind::I64, Value::MatrixI64(m)) => {
787        let b: Box<dyn CopyMat<i64>> = m.get_copyable_matrix();
788        std::mem::transmute::<Box<dyn CopyMat<i64>>, Box<dyn CopyMat<T>>>(b)
789      }
790      #[cfg(all(feature = "matrix", feature = "i128"))]
791      (ValueKind::I128, Value::MatrixI128(m)) => {
792        let b: Box<dyn CopyMat<i128>> = m.get_copyable_matrix();
793        std::mem::transmute::<Box<dyn CopyMat<i128>>, Box<dyn CopyMat<T>>>(b)
794      }
795      #[cfg(all(feature = "matrix", feature = "f32"))]
796      (ValueKind::F32, Value::MatrixF32(m)) => {
797        let b: Box<dyn CopyMat<F32>> = m.get_copyable_matrix();
798        std::mem::transmute::<Box<dyn CopyMat<F32>>, Box<dyn CopyMat<T>>>(b)
799      }
800      #[cfg(all(feature = "matrix", feature = "f64"))]
801      (ValueKind::F64, Value::MatrixF64(m)) => {
802        let b: Box<dyn CopyMat<F64>> = m.get_copyable_matrix();
803        std::mem::transmute::<Box<dyn CopyMat<F64>>, Box<dyn CopyMat<T>>>(b)
804      }
805      #[cfg(all(feature = "matrix", feature = "string"))]
806      (ValueKind::String, Value::MatrixString(m)) => {
807        let b: Box<dyn CopyMat<String>> = m.get_copyable_matrix();
808        std::mem::transmute::<Box<dyn CopyMat<String>>, Box<dyn CopyMat<T>>>(b)
809      }
810      _ => panic!("Unsupported type for get_copyable_matrix_unchecked"),
811    }
812  }
813
814  pub unsafe fn as_unchecked<T>(&self) -> &Ref<T> {
815    match self {
816      #[cfg(feature = "u8")]
817      Value::U8(r) => &*(r as *const Ref<u8> as *const Ref<T>),
818      #[cfg(feature = "u16")]
819      Value::U16(r) => &*(r as *const Ref<u16> as *const Ref<T>),
820      #[cfg(feature = "u32")]
821      Value::U32(r) => &*(r as *const Ref<u32> as *const Ref<T>),
822      #[cfg(feature = "u64")]
823      Value::U64(r) => &*(r as *const Ref<u64> as *const Ref<T>),
824      #[cfg(feature = "u128")]
825      Value::U128(r) => &*(r as *const Ref<u128> as *const Ref<T>),
826      #[cfg(feature = "i8")]
827      Value::I8(r) => &*(r as *const Ref<i8> as *const Ref<T>),
828      #[cfg(feature = "i16")]
829      Value::I16(r) => &*(r as *const Ref<i16> as *const Ref<T>),
830      #[cfg(feature = "i32")]
831      Value::I32(r) => &*(r as *const Ref<i32> as *const Ref<T>),
832      #[cfg(feature = "i64")]
833      Value::I64(r) => &*(r as *const Ref<i64> as *const Ref<T>),
834      #[cfg(feature = "i128")]
835      Value::I128(r) => &*(r as *const Ref<i128> as *const Ref<T>),
836      #[cfg(feature = "f32")]
837      Value::F32(r) => &*(r as *const Ref<F32> as *const Ref<T>),
838      #[cfg(feature = "f64")]
839      Value::F64(r) => &*(r as *const Ref<F64> as *const Ref<T>),
840      #[cfg(feature = "string")]
841      Value::String(r) => &*(r as *const Ref<String> as *const Ref<T>),
842      #[cfg(feature = "bool")]
843      Value::Bool(r) => &*(r as *const Ref<bool> as *const Ref<T>),
844      #[cfg(feature = "rational")]
845      Value::R64(r) => &*(r as *const Ref<R64> as *const Ref<T>),
846      #[cfg(feature = "complex")]
847      Value::C64(r) => &*(r as *const Ref<C64> as *const Ref<T>),
848      #[cfg(all(feature = "f64", feature = "matrix"))]
849      Value::MatrixF64(r) => r.as_unchecked(),
850      #[cfg(all(feature = "f32", feature = "matrix"))]
851      Value::MatrixF32(r) => r.as_unchecked(),
852      #[cfg(all(feature = "i8", feature = "matrix"))]
853      Value::MatrixI8(r) => r.as_unchecked(),
854      #[cfg(all(feature = "i16", feature = "matrix"))]
855      Value::MatrixI16(r) => r.as_unchecked(),
856      #[cfg(all(feature = "i32", feature = "matrix"))]
857      Value::MatrixI32(r) => r.as_unchecked(),
858      #[cfg(all(feature = "i64", feature = "matrix"))]
859      Value::MatrixI64(r) => r.as_unchecked(),
860      #[cfg(all(feature = "i128", feature = "matrix"))]
861      Value::MatrixI128(r) => r.as_unchecked(),
862      #[cfg(all(feature = "u8", feature = "matrix"))]
863      Value::MatrixU8(r) => r.as_unchecked(),
864      #[cfg(all(feature = "u16", feature = "matrix"))]
865      Value::MatrixU16(r) => r.as_unchecked(),
866      #[cfg(all(feature = "u32", feature = "matrix"))]
867      Value::MatrixU32(r) => r.as_unchecked(),
868      #[cfg(all(feature = "u64", feature = "matrix"))]
869      Value::MatrixU64(r) => r.as_unchecked(),
870      #[cfg(all(feature = "u128", feature = "matrix"))]
871      Value::MatrixU128(r) => r.as_unchecked(),
872      #[cfg(all(feature = "bool", feature = "matrix"))]
873      Value::MatrixBool(r) => r.as_unchecked(),
874      #[cfg(all(feature = "string", feature = "matrix"))]
875      Value::MatrixString(r) => r.as_unchecked(),
876      #[cfg(all(feature = "rational", feature = "matrix"))]
877      Value::MatrixR64(r) => r.as_unchecked(),
878      #[cfg(all(feature = "complex", feature = "matrix"))]
879      Value::MatrixC64(r) => r.as_unchecked(),
880      #[cfg(feature = "matrix")]
881      Value::MatrixIndex(r) => r.as_unchecked(),
882      Value::Index(r) => &*(r as *const Ref<usize> as *const Ref<T>),
883      #[cfg(feature = "enum")]
884      Value::Enum(r) => &*(r as *const Ref<MechEnum> as *const Ref<T>),
885      #[cfg(feature = "set")]
886      Value::Set(r) => &*(r as *const Ref<MechSet> as *const Ref<T>),
887      #[cfg(feature = "table")]
888      Value::Table(r) => &*(r as *const Ref<MechTable> as *const Ref<T>),
889      _ => panic!("Unsupported type for as_unchecked"),
890    }
891  }
892
893  pub fn addr(&self) -> usize {
894    match self {
895      #[cfg(feature = "u8")]
896      Value::U8(v) => v.addr(),
897      #[cfg(feature = "u16")]
898      Value::U16(v) => v.addr(),
899      #[cfg(feature = "u32")]
900      Value::U32(v) => v.addr(),
901      #[cfg(feature = "u64")]
902      Value::U64(v) => v.addr(),
903      #[cfg(feature = "u128")]
904      Value::U128(v) => v.addr(),
905      #[cfg(feature = "i8")]
906      Value::I8(v) => v.addr(),
907      #[cfg(feature = "i16")]
908      Value::I16(v) => v.addr(),
909      #[cfg(feature = "i32")]
910      Value::I32(v) => v.addr(),
911      #[cfg(feature = "i64")]
912      Value::I64(v) => v.addr(),
913      #[cfg(feature = "i128")]
914      Value::I128(v) => v.addr(),
915      #[cfg(feature = "f32")]
916      Value::F32(v) => v.addr(),
917      #[cfg(feature = "f64")]
918      Value::F64(v) => v.addr(),
919      #[cfg(feature = "string")]
920      Value::String(v) => v.addr(),
921      #[cfg(feature = "bool")]
922      Value::Bool(v) => v.addr(),
923      #[cfg(feature = "complex")]
924      Value::C64(v) => v.addr(),
925      #[cfg(feature = "rational")]
926      Value::R64(v) => v.addr(),
927      #[cfg(feature = "record")]
928      Value::Record(v) => v.addr(),
929      #[cfg(feature = "table")]
930      Value::Table(v) => v.addr(),
931      #[cfg(feature = "map")]
932      Value::Map(v) => v.addr(),
933      #[cfg(feature = "tuple")]
934      Value::Tuple(v) => v.addr(),
935      #[cfg(feature = "set")]
936      Value::Set(v) => v.addr(),
937      #[cfg(feature = "enum")]
938      Value::Enum(v) => v.addr(),
939      #[cfg(feature = "atom")]
940      Value::Atom(v) => v.addr(),
941      #[cfg(feature = "matrix")]
942      Value::MatrixIndex(v) => v.addr(),
943      Value::Index(v) => v.addr(),
944      Value::MutableReference(v) => v.addr(),
945      _ => todo!(),
946    }
947  }
948
949  pub fn convert_to(&self, other: &ValueKind) -> Option<Value> {
950
951    if self.kind() == *other {
952        return Some(self.clone());
953    }
954
955    if !self.kind().is_convertible_to(other) {
956        return None;
957    }
958
959    match (self, other) {
960    // ==== Unsigned widening and narrowing ====
961    #[cfg(all(feature = "u8", feature = "u16"))]
962    (Value::U8(v), ValueKind::U16) => Some(Value::U16(Ref::new((*v.borrow()) as u16))),
963    #[cfg(all(feature = "u8", feature = "u32"))]
964    (Value::U8(v), ValueKind::U32) => Some(Value::U32(Ref::new((*v.borrow()) as u32))),
965    #[cfg(all(feature = "u8", feature = "u64"))]
966    (Value::U8(v), ValueKind::U64) => Some(Value::U64(Ref::new((*v.borrow()) as u64))),
967    #[cfg(all(feature = "u8", feature = "u128"))]
968    (Value::U8(v), ValueKind::U128) => Some(Value::U128(Ref::new((*v.borrow()) as u128))),
969    #[cfg(all(feature = "u8", feature = "i16"))]
970    (Value::U8(v), ValueKind::I16) => Some(Value::I16(Ref::new((*v.borrow()) as i16))),
971    #[cfg(all(feature = "u8", feature = "i32"))]
972    (Value::U8(v), ValueKind::I32) => Some(Value::I32(Ref::new((*v.borrow()) as i32))),
973    #[cfg(all(feature = "u8", feature = "i64"))]
974    (Value::U8(v), ValueKind::I64) => Some(Value::I64(Ref::new((*v.borrow()) as i64))),
975    #[cfg(all(feature = "u8", feature = "i128"))]
976    (Value::U8(v), ValueKind::I128) => Some(Value::I128(Ref::new((*v.borrow()) as i128))),
977    #[cfg(all(feature = "u8", feature = "f32"))]
978    (Value::U8(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
979    #[cfg(all(feature = "u8", feature = "f64"))]
980    (Value::U8(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
981
982    #[cfg(all(feature = "u16", feature = "u8"))]
983    (Value::U16(v), ValueKind::U8) => Some(Value::U8(Ref::new((*v.borrow()) as u8))),
984    #[cfg(all(feature = "u16", feature = "u32"))]
985    (Value::U16(v), ValueKind::U32) => Some(Value::U32(Ref::new((*v.borrow()) as u32))),
986    #[cfg(all(feature = "u16", feature = "u64"))]
987    (Value::U16(v), ValueKind::U64) => Some(Value::U64(Ref::new((*v.borrow()) as u64))),
988    #[cfg(all(feature = "u16", feature = "u128"))]
989    (Value::U16(v), ValueKind::U128) => Some(Value::U128(Ref::new((*v.borrow()) as u128))),
990    #[cfg(all(feature = "u16", feature = "i8"))]
991    (Value::U16(v), ValueKind::I8) => Some(Value::I8(Ref::new((*v.borrow()) as i8))),
992    #[cfg(all(feature = "u16", feature = "i32"))]
993    (Value::U16(v), ValueKind::I32) => Some(Value::I32(Ref::new((*v.borrow()) as i32))),
994    #[cfg(all(feature = "u16", feature = "i64"))]
995    (Value::U16(v), ValueKind::I64) => Some(Value::I64(Ref::new((*v.borrow()) as i64))),
996    #[cfg(all(feature = "u16", feature = "i128"))]
997    (Value::U16(v), ValueKind::I128) => Some(Value::I128(Ref::new((*v.borrow()) as i128))),
998    #[cfg(all(feature = "u16", feature = "f32"))]
999    (Value::U16(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
1000    #[cfg(all(feature = "u16", feature = "f64"))]
1001    (Value::U16(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
1002
1003    #[cfg(all(feature = "u32", feature = "u8"))]
1004    (Value::U32(v), ValueKind::U8) => Some(Value::U8(Ref::new((*v.borrow()) as u8))),
1005    #[cfg(all(feature = "u32", feature = "u16"))]
1006    (Value::U32(v), ValueKind::U16) => Some(Value::U16(Ref::new((*v.borrow()) as u16))),
1007    #[cfg(all(feature = "u32", feature = "u64"))]
1008    (Value::U32(v), ValueKind::U64) => Some(Value::U64(Ref::new((*v.borrow()) as u64))),
1009    #[cfg(all(feature = "u32", feature = "u128"))]
1010    (Value::U32(v), ValueKind::U128) => Some(Value::U128(Ref::new((*v.borrow()) as u128))),
1011    #[cfg(all(feature = "u32", feature = "i8"))]
1012    (Value::U32(v), ValueKind::I8) => Some(Value::I8(Ref::new((*v.borrow()) as i8))),
1013    #[cfg(all(feature = "u32", feature = "i16"))]
1014    (Value::U32(v), ValueKind::I16) => Some(Value::I16(Ref::new((*v.borrow()) as i16))),
1015    #[cfg(all(feature = "u32", feature = "i64"))]
1016    (Value::U32(v), ValueKind::I64) => Some(Value::I64(Ref::new((*v.borrow()) as i64))),
1017    #[cfg(all(feature = "u32", feature = "i128"))]
1018    (Value::U32(v), ValueKind::I128) => Some(Value::I128(Ref::new((*v.borrow()) as i128))),
1019    #[cfg(all(feature = "u32", feature = "f32"))]
1020    (Value::U32(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
1021    #[cfg(all(feature = "u32", feature = "f64"))]
1022    (Value::U32(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
1023
1024    #[cfg(all(feature = "u64", feature = "u8"))]
1025    (Value::U64(v), ValueKind::U8) => Some(Value::U8(Ref::new((*v.borrow()) as u8))),
1026    #[cfg(all(feature = "u64", feature = "u16"))]
1027    (Value::U64(v), ValueKind::U16) => Some(Value::U16(Ref::new((*v.borrow()) as u16))),
1028    #[cfg(all(feature = "u64", feature = "u32"))]
1029    (Value::U64(v), ValueKind::U32) => Some(Value::U32(Ref::new((*v.borrow()) as u32))),
1030    #[cfg(all(feature = "u64", feature = "u128"))]
1031    (Value::U64(v), ValueKind::U128) => Some(Value::U128(Ref::new((*v.borrow()) as u128))),
1032    #[cfg(all(feature = "u64", feature = "i8"))]
1033    (Value::U64(v), ValueKind::I8) => Some(Value::I8(Ref::new((*v.borrow()) as i8))),
1034    #[cfg(all(feature = "u64", feature = "i16"))]
1035    (Value::U64(v), ValueKind::I16) => Some(Value::I16(Ref::new((*v.borrow()) as i16))),
1036    #[cfg(all(feature = "u64", feature = "i32"))]
1037    (Value::U64(v), ValueKind::I32) => Some(Value::I32(Ref::new((*v.borrow()) as i32))),
1038    #[cfg(all(feature = "u64", feature = "i128"))]
1039    (Value::U64(v), ValueKind::I128) => Some(Value::I128(Ref::new((*v.borrow()) as i128))),
1040    #[cfg(all(feature = "u64", feature = "f32"))]
1041    (Value::U64(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
1042    #[cfg(all(feature = "u64", feature = "f64"))]
1043    (Value::U64(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
1044
1045    #[cfg(all(feature = "u128", feature = "u8"))]
1046    (Value::U128(v), ValueKind::U8) => Some(Value::U8(Ref::new((*v.borrow()) as u8))),
1047    #[cfg(all(feature = "u128", feature = "u16"))]
1048    (Value::U128(v), ValueKind::U16) => Some(Value::U16(Ref::new((*v.borrow()) as u16))),
1049    #[cfg(all(feature = "u128", feature = "u32"))]
1050    (Value::U128(v), ValueKind::U32) => Some(Value::U32(Ref::new((*v.borrow()) as u32))),
1051    #[cfg(all(feature = "u128", feature = "u64"))]
1052    (Value::U128(v), ValueKind::U64) => Some(Value::U64(Ref::new((*v.borrow()) as u64))),
1053    #[cfg(all(feature = "u128", feature = "i8"))]
1054    (Value::U128(v), ValueKind::I8) => Some(Value::I8(Ref::new((*v.borrow()) as i8))),
1055    #[cfg(all(feature = "u128", feature = "i16"))]
1056    (Value::U128(v), ValueKind::I16) => Some(Value::I16(Ref::new((*v.borrow()) as i16))),
1057    #[cfg(all(feature = "u128", feature = "i32"))]
1058    (Value::U128(v), ValueKind::I32) => Some(Value::I32(Ref::new((*v.borrow()) as i32))),
1059    #[cfg(all(feature = "u128", feature = "i64"))]
1060    (Value::U128(v), ValueKind::I64) => Some(Value::I64(Ref::new((*v.borrow()) as i64))),
1061    #[cfg(all(feature = "u128", feature = "f32"))]
1062    (Value::U128(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
1063    #[cfg(all(feature = "u128", feature = "f64"))]
1064    (Value::U128(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
1065
1066    // ==== Signed widening and narrowing ====
1067    #[cfg(all(feature = "i8", feature = "i16"))]
1068    (Value::I8(v), ValueKind::I16) => Some(Value::I16(Ref::new((*v.borrow()) as i16))),
1069    #[cfg(all(feature = "i8", feature = "i32"))]
1070    (Value::I8(v), ValueKind::I32) => Some(Value::I32(Ref::new((*v.borrow()) as i32))),
1071    #[cfg(all(feature = "i8", feature = "i64"))]
1072    (Value::I8(v), ValueKind::I64) => Some(Value::I64(Ref::new((*v.borrow()) as i64))),
1073    #[cfg(all(feature = "i8", feature = "i128"))]
1074    (Value::I8(v), ValueKind::I128) => Some(Value::I128(Ref::new((*v.borrow()) as i128))),
1075    #[cfg(all(feature = "i8", feature = "u16"))]
1076    (Value::I8(v), ValueKind::U16) => Some(Value::U16(Ref::new((*v.borrow()) as u16))),
1077    #[cfg(all(feature = "i8", feature = "u32"))]
1078    (Value::I8(v), ValueKind::U32) => Some(Value::U32(Ref::new((*v.borrow()) as u32))),
1079    #[cfg(all(feature = "i8", feature = "u64"))]
1080    (Value::I8(v), ValueKind::U64) => Some(Value::U64(Ref::new((*v.borrow()) as u64))),
1081    #[cfg(all(feature = "i8", feature = "u128"))]
1082    (Value::I8(v), ValueKind::U128) => Some(Value::U128(Ref::new((*v.borrow()) as u128))),
1083    #[cfg(all(feature = "i8", feature = "f32"))]
1084    (Value::I8(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
1085    #[cfg(all(feature = "i8", feature = "f64"))]
1086    (Value::I8(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
1087
1088    #[cfg(all(feature = "i16", feature = "i8"))]
1089    (Value::I16(v), ValueKind::I8) => Some(Value::I8(Ref::new((*v.borrow()) as i8))),
1090    #[cfg(all(feature = "i16", feature = "i32"))]
1091    (Value::I16(v), ValueKind::I32) => Some(Value::I32(Ref::new((*v.borrow()) as i32))),
1092    #[cfg(all(feature = "i16", feature = "i64"))]
1093    (Value::I16(v), ValueKind::I64) => Some(Value::I64(Ref::new((*v.borrow()) as i64))),
1094    #[cfg(all(feature = "i16", feature = "i128"))]
1095    (Value::I16(v), ValueKind::I128) => Some(Value::I128(Ref::new((*v.borrow()) as i128))),
1096    #[cfg(all(feature = "i16", feature = "u8"))]
1097    (Value::I16(v), ValueKind::U8) => Some(Value::U8(Ref::new((*v.borrow()) as u8))),
1098    #[cfg(all(feature = "i16", feature = "u32"))]
1099    (Value::I16(v), ValueKind::U32) => Some(Value::U32(Ref::new((*v.borrow()) as u32))),
1100    #[cfg(all(feature = "i16", feature = "u64"))]
1101    (Value::I16(v), ValueKind::U64) => Some(Value::U64(Ref::new((*v.borrow()) as u64))),
1102    #[cfg(all(feature = "i16", feature = "u128"))]
1103    (Value::I16(v), ValueKind::U128) => Some(Value::U128(Ref::new((*v.borrow()) as u128))),
1104    #[cfg(all(feature = "i16", feature = "f32"))]
1105    (Value::I16(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
1106    #[cfg(all(feature = "i16", feature = "f64"))]
1107    (Value::I16(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
1108
1109    #[cfg(all(feature = "i32", feature = "i8"))]
1110    (Value::I32(v), ValueKind::I8) => Some(Value::I8(Ref::new((*v.borrow()) as i8))),
1111    #[cfg(all(feature = "i32", feature = "i16"))]
1112    (Value::I32(v), ValueKind::I16) => Some(Value::I16(Ref::new((*v.borrow()) as i16))),
1113    #[cfg(all(feature = "i32", feature = "i64"))]
1114    (Value::I32(v), ValueKind::I64) => Some(Value::I64(Ref::new((*v.borrow()) as i64))),
1115    #[cfg(all(feature = "i32", feature = "i128"))]
1116    (Value::I32(v), ValueKind::I128) => Some(Value::I128(Ref::new((*v.borrow()) as i128))),
1117    #[cfg(all(feature = "i32", feature = "u8"))]
1118    (Value::I32(v), ValueKind::U8) => Some(Value::U8(Ref::new((*v.borrow()) as u8))),
1119    #[cfg(all(feature = "i32", feature = "u16"))]
1120    (Value::I32(v), ValueKind::U16) => Some(Value::U16(Ref::new((*v.borrow()) as u16))),
1121    #[cfg(all(feature = "i32", feature = "u64"))]
1122    (Value::I32(v), ValueKind::U64) => Some(Value::U64(Ref::new((*v.borrow()) as u64))),
1123    #[cfg(all(feature = "i32", feature = "u128"))]
1124    (Value::I32(v), ValueKind::U128) => Some(Value::U128(Ref::new((*v.borrow()) as u128))),
1125    #[cfg(all(feature = "i32", feature = "f32"))]
1126    (Value::I32(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
1127    #[cfg(all(feature = "i32", feature = "f64"))]
1128    (Value::I32(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
1129
1130    #[cfg(all(feature = "i64", feature = "i8"))]
1131    (Value::I64(v), ValueKind::I8) => Some(Value::I8(Ref::new((*v.borrow()) as i8))),
1132    #[cfg(all(feature = "i64", feature = "i16"))]
1133    (Value::I64(v), ValueKind::I16) => Some(Value::I16(Ref::new((*v.borrow()) as i16))),
1134    #[cfg(all(feature = "i64", feature = "i32"))]
1135    (Value::I64(v), ValueKind::I32) => Some(Value::I32(Ref::new((*v.borrow()) as i32))),
1136    #[cfg(all(feature = "i64", feature = "i128"))]
1137    (Value::I64(v), ValueKind::I128) => Some(Value::I128(Ref::new((*v.borrow()) as i128))),
1138    #[cfg(all(feature = "i64", feature = "u8"))]
1139    (Value::I64(v), ValueKind::U8) => Some(Value::U8(Ref::new((*v.borrow()) as u8))),
1140    #[cfg(all(feature = "i64", feature = "u16"))]
1141    (Value::I64(v), ValueKind::U16) => Some(Value::U16(Ref::new((*v.borrow()) as u16))),
1142    #[cfg(all(feature = "i64", feature = "u32"))]
1143    (Value::I64(v), ValueKind::U32) => Some(Value::U32(Ref::new((*v.borrow()) as u32))),
1144    #[cfg(all(feature = "i64", feature = "u128"))]
1145    (Value::I64(v), ValueKind::U128) => Some(Value::U128(Ref::new((*v.borrow()) as u128))),
1146    #[cfg(all(feature = "i64", feature = "f32"))]
1147    (Value::I64(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
1148    #[cfg(all(feature = "i64", feature = "f64"))]
1149    (Value::I64(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
1150
1151    #[cfg(all(feature = "i128", feature = "i8"))]
1152    (Value::I128(v), ValueKind::I8) => Some(Value::I8(Ref::new((*v.borrow()) as i8))),
1153    #[cfg(all(feature = "i128", feature = "i16"))]
1154    (Value::I128(v), ValueKind::I16) => Some(Value::I16(Ref::new((*v.borrow()) as i16))),
1155    #[cfg(all(feature = "i128", feature = "i32"))]
1156    (Value::I128(v), ValueKind::I32) => Some(Value::I32(Ref::new((*v.borrow()) as i32))),
1157    #[cfg(all(feature = "i128", feature = "i64"))]
1158    (Value::I128(v), ValueKind::I64) => Some(Value::I64(Ref::new((*v.borrow()) as i64))),
1159    #[cfg(all(feature = "i128", feature = "u8"))]
1160    (Value::I128(v), ValueKind::U8) => Some(Value::U8(Ref::new((*v.borrow()) as u8))),
1161    #[cfg(all(feature = "i128", feature = "u16"))]
1162    (Value::I128(v), ValueKind::U16) => Some(Value::U16(Ref::new((*v.borrow()) as u16))),
1163    #[cfg(all(feature = "i128", feature = "u32"))]
1164    (Value::I128(v), ValueKind::U32) => Some(Value::U32(Ref::new((*v.borrow()) as u32))),
1165    #[cfg(all(feature = "i128", feature = "u64"))]
1166    (Value::I128(v), ValueKind::U64) => Some(Value::U64(Ref::new((*v.borrow()) as u64))),
1167    #[cfg(all(feature = "i128", feature = "f32"))]
1168    (Value::I128(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(*v.borrow() as f32)))),
1169    #[cfg(all(feature = "i128", feature = "f64"))]
1170    (Value::I128(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(*v.borrow() as f64)))),
1171
1172    // ==== Float widening and narrowing ====
1173    #[cfg(all(feature = "f32", feature = "f64"))]
1174    (Value::F32(v), ValueKind::F64) => Some(Value::F64(Ref::new(F64::new(v.borrow().0 as f64)))),
1175    #[cfg(all(feature = "f32", feature = "f64"))]
1176    (Value::F64(v), ValueKind::F32) => Some(Value::F32(Ref::new(F32::new(v.borrow().0 as f32)))),
1177
1178    // ==== Float to integer conversions (truncate) ====
1179    #[cfg(all(feature = "f32", feature = "i8"))]
1180    (Value::F32(v), ValueKind::I8) => Some(Value::I8(Ref::new(v.borrow().0 as i8))),
1181    #[cfg(all(feature = "f32", feature = "i16"))]
1182    (Value::F32(v), ValueKind::I16) => Some(Value::I16(Ref::new(v.borrow().0 as i16))),
1183    #[cfg(all(feature = "f32", feature = "i32"))]
1184    (Value::F32(v), ValueKind::I32) => Some(Value::I32(Ref::new(v.borrow().0 as i32))),
1185    #[cfg(all(feature = "f32", feature = "i64"))]
1186    (Value::F32(v), ValueKind::I64) => Some(Value::I64(Ref::new(v.borrow().0 as i64))),
1187    #[cfg(all(feature = "f32", feature = "i128"))]
1188    (Value::F32(v), ValueKind::I128) => Some(Value::I128(Ref::new(v.borrow().0 as i128))),
1189    #[cfg(all(feature = "f32", feature = "u8"))]
1190    (Value::F32(v), ValueKind::U8) => Some(Value::U8(Ref::new(v.borrow().0 as u8))),
1191    #[cfg(all(feature = "f32", feature = "u16"))]
1192    (Value::F32(v), ValueKind::U16) => Some(Value::U16(Ref::new(v.borrow().0 as u16))),
1193    #[cfg(all(feature = "f32", feature = "u32"))]
1194    (Value::F32(v), ValueKind::U32) => Some(Value::U32(Ref::new(v.borrow().0 as u32))),
1195    #[cfg(all(feature = "f32", feature = "u64"))]
1196    (Value::F32(v), ValueKind::U64) => Some(Value::U64(Ref::new(v.borrow().0 as u64))),
1197    #[cfg(all(feature = "f32", feature = "u128"))]
1198    (Value::F32(v), ValueKind::U128) => Some(Value::U128(Ref::new(v.borrow().0 as u128))),
1199
1200    #[cfg(all(feature = "f64", feature = "i8"))]
1201    (Value::F64(v), ValueKind::I8) => Some(Value::I8(Ref::new(v.borrow().0 as i8))),
1202    #[cfg(all(feature = "f64", feature = "i16"))]
1203    (Value::F64(v), ValueKind::I16) => Some(Value::I16(Ref::new(v.borrow().0 as i16))),
1204    #[cfg(all(feature = "f64", feature = "i32"))]
1205    (Value::F64(v), ValueKind::I32) => Some(Value::I32(Ref::new(v.borrow().0 as i32))),
1206    #[cfg(all(feature = "f64", feature = "i64"))]
1207    (Value::F64(v), ValueKind::I64) => Some(Value::I64(Ref::new(v.borrow().0 as i64))),
1208    #[cfg(all(feature = "f64", feature = "i128"))]
1209    (Value::F64(v), ValueKind::I128) => Some(Value::I128(Ref::new(v.borrow().0 as i128))),
1210    #[cfg(all(feature = "f64", feature = "u8"))]
1211    (Value::F64(v), ValueKind::U8) => Some(Value::U8(Ref::new(v.borrow().0 as u8))),
1212    #[cfg(all(feature = "f64", feature = "u16"))]
1213    (Value::F64(v), ValueKind::U16) => Some(Value::U16(Ref::new(v.borrow().0 as u16))),
1214    #[cfg(all(feature = "f64", feature = "u32"))]
1215    (Value::F64(v), ValueKind::U32) => Some(Value::U32(Ref::new(v.borrow().0 as u32))),
1216    #[cfg(all(feature = "f64", feature = "u64"))]
1217    (Value::F64(v), ValueKind::U64) => Some(Value::U64(Ref::new(v.borrow().0 as u64))),
1218    #[cfg(all(feature = "f64", feature = "u128"))]
1219    (Value::F64(v), ValueKind::U128) => Some(Value::U128(Ref::new(v.borrow().0 as u128))),
1220
1221      /*
1222      // ==== INDEX conversions ====
1223      (Value::Index(i), U32) => Some(Value::U32(Ref::new((*i.borrow()) as u32))),
1224      (Value::U32(v), Index) => Some(Value::Index(Ref::new((*v.borrow()) as usize))),
1225
1226
1227      // ==== MATRIX conversions (element-wise) ====
1228      (Value::MatrixU8(m), MatrixU16) => Some(Value::MatrixU16(m.map(|x| *x as u16))),
1229      (Value::MatrixI32(m), MatrixF64) => Some(Value::MatrixF64(m.map(|x| (*x) as f64))),
1230      // You can expand other matrix conversions similarly...
1231
1232      // ==== COMPLEX TYPES (stubs) ====
1233      (Value::Set(set), Set(_)) => Some(Value::Set(set.clone())), // TODO: element-wise convert
1234      (Value::Map(map), Map(_)) => Some(Value::Map(map.clone())), // TODO: key/value convert
1235      (Value::Record(r), Record(_)) => Some(Value::Record(r.clone())), // TODO: field convert
1236      (Value::Table(t), Table(_)) => Some(Value::Table(t.clone())), // TODO: column convert
1237
1238      // ==== ENUM, KIND ====
1239      (Value::Enum(e), Enum(_)) => Some(Value::Enum(e.clone())),
1240      (Value::Kind(k), Kind(_)) => Some(Value::Kind(k.clone())),
1241
1242      // ==== SPECIAL CASES ====
1243      (Value::IndexAll, IndexAll) => Some(Value::IndexAll),
1244      (Value::Empty, Empty) => Some(Value::Empty),
1245      */
1246      // ==== FALLBACK ====
1247      _ => None,
1248    }
1249  }
1250
1251  pub fn size_of(&self) -> usize {
1252    match self {
1253      #[cfg(feature = "rational")]
1254      Value::R64(x) => 16,
1255      #[cfg(feature = "u8")]
1256      Value::U8(x) => 1,
1257      #[cfg(feature = "u16")]
1258      Value::U16(x) => 2,
1259      #[cfg(feature = "u32")]
1260      Value::U32(x) => 4,
1261      #[cfg(feature = "u64")]
1262      Value::U64(x) => 8,
1263      #[cfg(feature = "u128")]
1264      Value::U128(x) => 16,
1265      #[cfg(feature = "i8")]
1266      Value::I8(x) => 1,
1267      #[cfg(feature = "i16")]
1268      Value::I16(x) => 2,
1269      #[cfg(feature = "i32")]
1270      Value::I32(x) => 4,
1271      #[cfg(feature = "i64")]
1272      Value::I64(x) => 8,
1273      #[cfg(feature = "i128")]
1274      Value::I128(x) => 16,
1275      #[cfg(feature = "f32")]
1276      Value::F32(x) => 4,
1277      #[cfg(feature = "f64")]
1278      Value::F64(x) => 8,
1279      #[cfg(feature = "bool")]
1280      Value::Bool(x) => 1,
1281      #[cfg(feature = "complex")]
1282      Value::C64(x) => 16,
1283      #[cfg(all(feature = "matrix"))]
1284      Value::MatrixIndex(x) => x.size_of(),
1285      #[cfg(all(feature = "matrix", feature = "bool"))]
1286      Value::MatrixBool(x) => x.size_of(),
1287      #[cfg(all(feature = "matrix", feature = "u8"))]
1288      Value::MatrixU8(x)   => x.size_of(),
1289      #[cfg(all(feature = "matrix", feature = "u16"))]
1290      Value::MatrixU16(x)  => x.size_of(),
1291      #[cfg(all(feature = "matrix", feature = "u32"))]
1292      Value::MatrixU32(x)  => x.size_of(),
1293      #[cfg(all(feature = "matrix", feature = "u64"))]
1294      Value::MatrixU64(x)  => x.size_of(),
1295      #[cfg(all(feature = "matrix", feature = "u128"))]
1296      Value::MatrixU128(x) => x.size_of(),
1297      #[cfg(all(feature = "matrix", feature = "i8"))]
1298      Value::MatrixI8(x)   => x.size_of(),
1299      #[cfg(all(feature = "matrix", feature = "i16"))]
1300      Value::MatrixI16(x)  => x.size_of(),
1301      #[cfg(all(feature = "matrix", feature = "i32"))]
1302      Value::MatrixI32(x)  => x.size_of(),
1303      #[cfg(all(feature = "matrix", feature = "i64"))]
1304      Value::MatrixI64(x)  => x.size_of(),
1305      #[cfg(all(feature = "matrix", feature = "i128"))]
1306      Value::MatrixI128(x) => x.size_of(),
1307      #[cfg(all(feature = "matrix", feature = "f32"))]
1308      Value::MatrixF32(x)  => x.size_of(),
1309      #[cfg(all(feature = "matrix", feature = "f64"))]
1310      Value::MatrixF64(x)  => x.size_of(),
1311      #[cfg(feature = "matrix")]
1312      Value::MatrixValue(x)  => x.size_of(),
1313      #[cfg(all(feature = "matrix", feature = "string"))]
1314      Value::MatrixString(x) => x.size_of(),
1315      #[cfg(all(feature = "matrix", feature = "rational"))]
1316      Value::MatrixR64(x) => x.size_of(),
1317      #[cfg(all(feature = "matrix", feature = "complex"))]
1318      Value::MatrixC64(x) => x.size_of(),
1319      #[cfg(feature = "string")]
1320      Value::String(x) => x.borrow().len(),
1321      #[cfg(feature = "atom")]
1322      Value::Atom(x) => 8,
1323      #[cfg(feature = "set")]
1324      Value::Set(x) => x.borrow().size_of(),
1325      #[cfg(feature = "map")]
1326      Value::Map(x) => x.borrow().size_of(),
1327      #[cfg(feature = "table")]
1328      Value::Table(x) => x.borrow().size_of(),
1329      #[cfg(feature = "record")]
1330      Value::Record(x) => x.borrow().size_of(),
1331      #[cfg(feature = "tuple")]
1332      Value::Tuple(x) => x.borrow().size_of(),
1333      #[cfg(feature = "enum")]
1334      Value::Enum(x) => x.borrow().size_of(),
1335      Value::MutableReference(x) => x.borrow().size_of(),
1336      Value::Id(_) => 8,
1337      Value::Index(x) => 8,
1338      Value::Kind(_) => 0, // Kind is not a value, so it has no size
1339      Value::Empty => 0,
1340      Value::IndexAll => 0, // IndexAll is a special value, so it has no size
1341    }
1342  }
1343
1344  #[cfg(feature = "pretty_print")]
1345  pub fn to_html(&self) -> String {
1346    match self {
1347      #[cfg(feature = "u8")]
1348      Value::U8(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1349      #[cfg(feature = "u16")]
1350      Value::U16(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1351      #[cfg(feature = "u32")]
1352      Value::U32(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1353      #[cfg(feature = "u64")]
1354      Value::U64(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1355      #[cfg(feature = "i8")]
1356      Value::I8(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1357      #[cfg(feature = "i128")]
1358      Value::I128(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1359      #[cfg(feature = "i16")]
1360      Value::I16(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1361      #[cfg(feature = "i32")]
1362      Value::I32(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1363      #[cfg(feature = "i64")]
1364      Value::I64(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1365      #[cfg(feature = "i128")]
1366      Value::I128(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1367      #[cfg(feature = "f32")]
1368      Value::F32(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1369      #[cfg(feature = "f64")]
1370      Value::F64(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
1371      #[cfg(feature = "string")]
1372      Value::String(s) => format!("<span class='mech-string'>\"{}\"</span>", s.borrow()),
1373      #[cfg(feature = "bool")]
1374      Value::Bool(b) => format!("<span class='mech-boolean'>{}</span>", b.borrow()),
1375      #[cfg(feature = "complex")]
1376      Value::C64(c) => c.borrow().to_html(),
1377      #[cfg(all(feature = "matrix", feature = "u8"))]
1378      Value::MatrixU8(m) => m.to_html(),
1379      #[cfg(all(feature = "matrix", feature = "u16"))]
1380      Value::MatrixU16(m) => m.to_html(),
1381      #[cfg(all(feature = "matrix", feature = "u32"))]
1382      Value::MatrixU32(m) => m.to_html(),
1383      #[cfg(all(feature = "matrix", feature = "u64"))]
1384      Value::MatrixU64(m) => m.to_html(),
1385      #[cfg(all(feature = "matrix", feature = "u128"))]
1386      Value::MatrixU128(m) => m.to_html(),
1387      #[cfg(all(feature = "matrix", feature = "i8"))]
1388      Value::MatrixI8(m) => m.to_html(),
1389      #[cfg(all(feature = "matrix", feature = "i16"))]
1390      Value::MatrixI16(m) => m.to_html(),
1391      #[cfg(all(feature = "matrix", feature = "i32"))]
1392      Value::MatrixI32(m) => m.to_html(),
1393      #[cfg(all(feature = "matrix", feature = "i64"))]
1394      Value::MatrixI64(m) => m.to_html(),
1395      #[cfg(all(feature = "matrix", feature = "i128"))]
1396      Value::MatrixI128(m) => m.to_html(),
1397      #[cfg(all(feature = "matrix", feature = "f64"))]
1398      Value::MatrixF64(m) => m.to_html(),
1399      #[cfg(all(feature = "matrix", feature = "f32"))]
1400      Value::MatrixF32(m) => m.to_html(),
1401      #[cfg(feature = "matrix")]
1402      Value::MatrixIndex(m) => m.to_html(),
1403      #[cfg(all(feature = "matrix", feature = "bool"))]
1404      Value::MatrixBool(m) => m.to_html(),
1405      #[cfg(all(feature = "matrix", feature = "string"))]
1406      Value::MatrixString(m) => m.to_html(),
1407      #[cfg(feature = "matrix")]
1408      Value::MatrixValue(m) => m.to_html(),
1409      #[cfg(all(feature = "matrix", feature = "rational"))]
1410      Value::MatrixR64(m) => m.to_html(),
1411      #[cfg(all(feature = "matrix", feature = "complex"))]
1412      Value::MatrixC64(m) => m.to_html(),
1413      #[cfg(feature = "atom")]
1414      Value::Atom(a) => format!("<span class=\"mech-atom\"><span class=\"mech-atom-grave\">`</span><span class=\"mech-atom-name\">{}</span></span>",a.borrow()),
1415      #[cfg(feature = "set")]
1416      Value::Set(s) => s.borrow().to_html(),
1417      #[cfg(feature = "map")]
1418      Value::Map(m) => m.borrow().to_html(),
1419      #[cfg(feature = "table")]
1420      Value::Table(t) => t.borrow().to_html(),
1421      #[cfg(feature = "record")]
1422      Value::Record(r) => r.borrow().to_html(),
1423      #[cfg(feature = "tuple")]
1424      Value::Tuple(t) => t.borrow().to_html(),
1425      #[cfg(feature = "enum")]
1426      Value::Enum(e) => e.borrow().to_html(),
1427      Value::MutableReference(m) => {
1428        let inner = m.borrow();
1429        format!("<span class='mech-reference'>{}</span>", inner.to_html())
1430      },
1431      _ => "???".to_string(),
1432    }
1433  }
1434
1435  pub fn shape(&self) -> Vec<usize> {
1436    match self {
1437      #[cfg(feature = "rational")]
1438      Value::R64(x) => vec![1,1],
1439      #[cfg(feature = "complex")]
1440      Value::C64(x) => vec![1,1],
1441      #[cfg(feature = "u8")]
1442      Value::U8(x) => vec![1,1],
1443      #[cfg(feature = "u16")]
1444      Value::U16(x) => vec![1,1],
1445      #[cfg(feature = "u32")]
1446      Value::U32(x) => vec![1,1],
1447      #[cfg(feature = "u64")]
1448      Value::U64(x) => vec![1,1],
1449      #[cfg(feature = "u128")]
1450      Value::U128(x) => vec![1,1],
1451      #[cfg(feature = "i8")]
1452      Value::I8(x) => vec![1,1],
1453      #[cfg(feature = "i16")]
1454      Value::I16(x) => vec![1,1],
1455      #[cfg(feature = "i32")]
1456      Value::I32(x) => vec![1,1],
1457      #[cfg(feature = "i64")]
1458      Value::I64(x) => vec![1,1],
1459      #[cfg(feature = "i128")]
1460      Value::I128(x) => vec![1,1],
1461      #[cfg(feature = "f32")]
1462      Value::F32(x) => vec![1,1],
1463      #[cfg(feature = "f64")]
1464      Value::F64(x) => vec![1,1],
1465      #[cfg(feature = "string")]
1466      Value::String(x) => vec![1,1],
1467      #[cfg(feature = "bool")]
1468      Value::Bool(x) => vec![1,1],
1469      #[cfg(feature = "atom")]
1470      Value::Atom(x) => vec![1,1],
1471      #[cfg(feature = "matrix")]
1472      Value::MatrixIndex(x) => x.shape(),
1473      #[cfg(all(feature = "matrix", feature = "bool"))]
1474      Value::MatrixBool(x) => x.shape(),
1475      #[cfg(all(feature = "matrix", feature = "u8"))]
1476      Value::MatrixU8(x) => x.shape(),
1477      #[cfg(all(feature = "matrix", feature = "u16"))]
1478      Value::MatrixU16(x) => x.shape(),
1479      #[cfg(all(feature = "matrix", feature = "u32"))]
1480      Value::MatrixU32(x) => x.shape(),
1481      #[cfg(all(feature = "matrix", feature = "u64"))]
1482      Value::MatrixU64(x) => x.shape(),
1483      #[cfg(all(feature = "matrix", feature = "u128"))]
1484      Value::MatrixU128(x) => x.shape(),
1485      #[cfg(all(feature = "matrix", feature = "i8"))]
1486      Value::MatrixI8(x) => x.shape(),
1487      #[cfg(all(feature = "matrix", feature = "i16"))]
1488      Value::MatrixI16(x) => x.shape(),
1489      #[cfg(all(feature = "matrix", feature = "i32"))]
1490      Value::MatrixI32(x) => x.shape(),
1491      #[cfg(all(feature = "matrix", feature = "i64"))]
1492      Value::MatrixI64(x) => x.shape(),
1493      #[cfg(all(feature = "matrix", feature = "i128"))]
1494      Value::MatrixI128(x) => x.shape(),
1495      #[cfg(all(feature = "matrix", feature = "f32"))]
1496      Value::MatrixF32(x) => x.shape(),
1497      #[cfg(all(feature = "matrix", feature = "f64"))]
1498      Value::MatrixF64(x) => x.shape(),
1499      #[cfg(all(feature = "matrix", feature = "string"))]
1500      Value::MatrixString(x) => x.shape(),
1501      #[cfg(feature = "matrix")]
1502      Value::MatrixValue(x) => x.shape(),
1503      #[cfg(all(feature = "matrix", feature = "rational"))]
1504      Value::MatrixR64(x) => x.shape(),
1505      #[cfg(all(feature = "matrix", feature = "complex"))]
1506      Value::MatrixC64(x) => x.shape(),
1507      #[cfg(feature = "enum")]
1508      Value::Enum(x) => vec![1,1],
1509      #[cfg(feature = "table")]
1510      Value::Table(x) => x.borrow().shape(),
1511      #[cfg(feature = "set")]
1512      Value::Set(x) => vec![1,x.borrow().set.len()],
1513      #[cfg(feature = "map")]
1514      Value::Map(x) => vec![1,x.borrow().map.len()],
1515      #[cfg(feature = "record")]
1516      Value::Record(x) => x.borrow().shape(),
1517      #[cfg(feature = "tuple")]
1518      Value::Tuple(x) => vec![1,x.borrow().size()],
1519      Value::Index(x) => vec![1,1],
1520      Value::MutableReference(x) => x.borrow().shape(),
1521      Value::Empty => vec![0,0],
1522      Value::IndexAll => vec![0,0],
1523      Value::Kind(_) => vec![0,0],
1524      Value::Id(x) => vec![0,0],
1525    }
1526  }
1527
1528  pub fn deref_kind(&self) -> ValueKind {
1529    match self {
1530      Value::MutableReference(x) => x.borrow().kind(),
1531      x => x.kind(),
1532    }
1533  }
1534
1535  pub fn kind(&self) -> ValueKind {
1536    match self {
1537      #[cfg(feature = "complex")]
1538      Value::C64(_) => ValueKind::C64,
1539      #[cfg(feature = "rational")]
1540      Value::R64(_) => ValueKind::R64,
1541      #[cfg(feature = "u8")]
1542      Value::U8(_) => ValueKind::U8,
1543      #[cfg(feature = "u16")]
1544      Value::U16(_) => ValueKind::U16,
1545      #[cfg(feature = "u32")]
1546      Value::U32(_) => ValueKind::U32,
1547      #[cfg(feature = "u64")]
1548      Value::U64(_) => ValueKind::U64,
1549      #[cfg(feature = "u128")]
1550      Value::U128(_) => ValueKind::U128,
1551      #[cfg(feature = "i8")]
1552      Value::I8(_) => ValueKind::I8,
1553      #[cfg(feature = "i16")]
1554      Value::I16(_) => ValueKind::I16,
1555      #[cfg(feature = "i32")]
1556      Value::I32(_) => ValueKind::I32,
1557      #[cfg(feature = "i64")]
1558      Value::I64(_) => ValueKind::I64,
1559      #[cfg(feature = "i128")]
1560      Value::I128(_) => ValueKind::I128,
1561      #[cfg(feature = "f32")]
1562      Value::F32(_) => ValueKind::F32,
1563      #[cfg(feature = "f64")]
1564      Value::F64(_) => ValueKind::F64,
1565      #[cfg(feature = "string")]
1566      Value::String(_) => ValueKind::String,
1567      #[cfg(feature = "bool")]
1568      Value::Bool(_) => ValueKind::Bool,
1569      #[cfg(feature = "atom")]
1570      Value::Atom(x) => ValueKind::Atom((x.borrow().0)),
1571      #[cfg(feature = "matrix")]
1572      Value::MatrixValue(x) => ValueKind::Matrix(Box::new(ValueKind::Any),x.shape()),
1573      #[cfg(feature = "matrix")]
1574      Value::MatrixIndex(x) => ValueKind::Matrix(Box::new(ValueKind::Index),x.shape()),
1575      #[cfg(all(feature = "matrix", feature = "bool"))]
1576      Value::MatrixBool(x) => ValueKind::Matrix(Box::new(ValueKind::Bool), x.shape()),
1577      #[cfg(all(feature = "matrix", feature = "u8"))]
1578      Value::MatrixU8(x) => ValueKind::Matrix(Box::new(ValueKind::U8), x.shape()),
1579      #[cfg(all(feature = "matrix", feature = "u16"))]
1580      Value::MatrixU16(x) => ValueKind::Matrix(Box::new(ValueKind::U16), x.shape()),
1581      #[cfg(all(feature = "matrix", feature = "u32"))]
1582      Value::MatrixU32(x) => ValueKind::Matrix(Box::new(ValueKind::U32), x.shape()),
1583      #[cfg(all(feature = "matrix", feature = "u64"))]
1584      Value::MatrixU64(x) => ValueKind::Matrix(Box::new(ValueKind::U64), x.shape()),
1585      #[cfg(all(feature = "matrix", feature = "u128"))]
1586      Value::MatrixU128(x) => ValueKind::Matrix(Box::new(ValueKind::U128), x.shape()),
1587      #[cfg(all(feature = "matrix", feature = "i8"))]
1588      Value::MatrixI8(x) => ValueKind::Matrix(Box::new(ValueKind::I8), x.shape()),
1589      #[cfg(all(feature = "matrix", feature = "i16"))]
1590      Value::MatrixI16(x) => ValueKind::Matrix(Box::new(ValueKind::I16), x.shape()),
1591      #[cfg(all(feature = "matrix", feature = "i32"))]
1592      Value::MatrixI32(x) => ValueKind::Matrix(Box::new(ValueKind::I32), x.shape()),
1593      #[cfg(all(feature = "matrix", feature = "i64"))]
1594      Value::MatrixI64(x) => ValueKind::Matrix(Box::new(ValueKind::I64), x.shape()),
1595      #[cfg(all(feature = "matrix", feature = "i128"))]
1596      Value::MatrixI128(x) => ValueKind::Matrix(Box::new(ValueKind::I128), x.shape()),
1597      #[cfg(all(feature = "matrix", feature = "f32"))]
1598      Value::MatrixF32(x) => ValueKind::Matrix(Box::new(ValueKind::F32), x.shape()),
1599      #[cfg(all(feature = "matrix", feature = "f64"))]
1600      Value::MatrixF64(x) => ValueKind::Matrix(Box::new(ValueKind::F64), x.shape()),
1601      #[cfg(all(feature = "matrix", feature = "string"))]
1602      Value::MatrixString(x) => ValueKind::Matrix(Box::new(ValueKind::String), x.shape()),
1603      #[cfg(all(feature = "matrix", feature = "rational"))]
1604      Value::MatrixR64(x) => ValueKind::Matrix(Box::new(ValueKind::R64), x.shape()),
1605      #[cfg(all(feature = "matrix", feature = "complex"))]
1606      Value::MatrixC64(x) => ValueKind::Matrix(Box::new(ValueKind::C64), x.shape()),
1607      #[cfg(feature = "table")]
1608      Value::Table(x) => x.borrow().kind(),
1609      #[cfg(feature = "set")]
1610      Value::Set(x) => x.borrow().kind(),
1611      #[cfg(feature = "map")]
1612      Value::Map(x) => x.borrow().kind(),
1613      #[cfg(feature = "record")]
1614      Value::Record(x) => x.borrow().kind(),
1615      #[cfg(feature = "tuple")]
1616      Value::Tuple(x) => x.borrow().kind(),
1617      #[cfg(feature = "enum")]
1618      Value::Enum(x) => x.borrow().kind(),
1619      Value::MutableReference(x) => ValueKind::Reference(Box::new(x.borrow().kind())),
1620      Value::Empty => ValueKind::Empty,
1621      Value::IndexAll => ValueKind::Empty,
1622      Value::Id(x) => ValueKind::Id,
1623      Value::Index(x) => ValueKind::Index,
1624      Value::Kind(x) => x.clone(),
1625    }
1626  }
1627
1628  #[cfg(feature = "matrix")]
1629  pub fn is_matrix(&self) -> bool {
1630    match self {
1631      #[cfg(feature = "matrix")]
1632      Value::MatrixIndex(_) => true,
1633      #[cfg(all(feature = "matrix", feature = "bool"))]
1634      Value::MatrixBool(_) => true,
1635      #[cfg(all(feature = "matrix", feature = "u8"))]
1636      Value::MatrixU8(_) => true,
1637      #[cfg(all(feature = "matrix", feature = "u16"))]
1638      Value::MatrixU16(_) => true,
1639      #[cfg(all(feature = "matrix", feature = "u32"))]
1640      Value::MatrixU32(_) => true,
1641      #[cfg(all(feature = "matrix", feature = "u64"))]
1642      Value::MatrixU64(_) => true,
1643      #[cfg(all(feature = "matrix", feature = "u128"))]
1644      Value::MatrixU128(_) => true,
1645      #[cfg(all(feature = "matrix", feature = "i8"))]
1646      Value::MatrixI8(_) => true,
1647      #[cfg(all(feature = "matrix", feature = "i16"))]
1648      Value::MatrixI16(_) => true,
1649      #[cfg(all(feature = "matrix", feature = "i32"))]
1650      Value::MatrixI32(_) => true,
1651      #[cfg(all(feature = "matrix", feature = "i64"))]
1652      Value::MatrixI64(_) => true,
1653      #[cfg(all(feature = "matrix", feature = "i128"))]
1654      Value::MatrixI128(_) => true,
1655      #[cfg(all(feature = "matrix", feature = "f32"))]
1656      Value::MatrixF32(_) => true,
1657      #[cfg(all(feature = "matrix", feature = "f64"))]
1658      Value::MatrixF64(_) => true,
1659      #[cfg(all(feature = "matrix", feature = "string"))]
1660      Value::MatrixString(_) => true,
1661      #[cfg(all(feature = "matrix", feature = "rational"))]
1662      Value::MatrixR64(_) => true,
1663      #[cfg(all(feature = "matrix", feature = "complex"))]
1664      Value::MatrixC64(_) => true,
1665      #[cfg(feature = "matrix")]
1666      Value::MatrixValue(_) => true,
1667      _ => false,
1668    }
1669  }
1670
1671  pub fn is_scalar(&self) -> bool {
1672    match self {
1673      #[cfg(feature = "u8")]
1674      Value::U8(_) => true,
1675      #[cfg(feature = "u16")]
1676      Value::U16(_) => true,
1677      #[cfg(feature = "u32")]
1678      Value::U32(_) => true,
1679      #[cfg(feature = "u64")]
1680      Value::U64(_) => true,
1681      #[cfg(feature = "u128")]
1682      Value::U128(_) => true,
1683      #[cfg(feature = "i8")]
1684      Value::I8(_) => true,
1685      #[cfg(feature = "i16")]
1686      Value::I16(_) => true,
1687      #[cfg(feature = "i32")]
1688      Value::I32(_) => true,
1689      #[cfg(feature = "i64")]
1690      Value::I64(_) => true,
1691      #[cfg(feature = "i128")]
1692      Value::I128(_) => true,
1693      #[cfg(feature = "f32")]
1694      Value::F32(_) => true,
1695      #[cfg(feature = "f64")]
1696      Value::F64(_) => true,
1697      #[cfg(feature = "bool")]
1698      Value::Bool(_) => true,
1699      #[cfg(feature = "string")]
1700      Value::String(_) => true,
1701      #[cfg(feature = "atom")]
1702      Value::Atom(_) => true,
1703      Value::Index(_) => true,
1704      _ => false,
1705    }
1706  }
1707
1708  #[cfg(feature = "bool")]
1709  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 }}
1710  
1711  impl_as_type!(i8);
1712  impl_as_type!(i16);
1713  impl_as_type!(i32);
1714  impl_as_type!(i64);
1715  impl_as_type!(i128);
1716  impl_as_type!(u8);
1717  impl_as_type!(u16);
1718  impl_as_type!(u32);
1719  impl_as_type!(u64);
1720  impl_as_type!(u128);
1721
1722  #[cfg(feature = "string")]
1723  pub fn as_string(&self) -> Option<Ref<String>> {
1724    match self {
1725      #[cfg(feature = "string")]
1726      Value::String(v) => Some(v.clone()),
1727      #[cfg(feature = "u8")]
1728      Value::U8(v) => Some(Ref::new(v.borrow().to_string())),
1729      #[cfg(feature = "u16")]
1730      Value::U16(v) => Some(Ref::new(v.borrow().to_string())),
1731      #[cfg(feature = "u32")]
1732      Value::U32(v) => Some(Ref::new(v.borrow().to_string())),
1733      #[cfg(feature = "u64")]
1734      Value::U64(v) => Some(Ref::new(v.borrow().to_string())),
1735      #[cfg(feature = "u128")]
1736      Value::U128(v) => Some(Ref::new(v.borrow().to_string())),
1737      #[cfg(feature = "i8")]
1738      Value::I8(v) => Some(Ref::new(v.borrow().to_string())),
1739      #[cfg(feature = "i16")]
1740      Value::I16(v) => Some(Ref::new(v.borrow().to_string())),
1741      #[cfg(feature = "i32")]
1742      Value::I32(v) => Some(Ref::new(v.borrow().to_string())),
1743      #[cfg(feature = "i64")]
1744      Value::I64(v) => Some(Ref::new(v.borrow().to_string())),
1745      #[cfg(feature = "i128")]
1746      Value::I128(v) => Some(Ref::new(v.borrow().to_string())),
1747      #[cfg(feature = "f32")]
1748      Value::F32(v) => Some(Ref::new(format!("{}", v.borrow().0))),
1749      #[cfg(feature = "f64")]
1750      Value::F64(v) => Some(Ref::new(format!("{}", v.borrow().0))),
1751      #[cfg(feature = "bool")]
1752      Value::Bool(v) => Some(Ref::new(format!("{}", v.borrow()))),
1753      #[cfg(feature = "rational")]
1754      Value::R64(v) => Some(Ref::new(v.borrow().to_string())),
1755      #[cfg(feature = "complex")]
1756      Value::C64(v) => Some(Ref::new(v.borrow().to_string())),
1757      Value::MutableReference(val) => val.borrow().as_string(),
1758      _ => None,
1759    }
1760  }
1761
1762  #[cfg(feature = "rational")]
1763  pub fn as_r64(&self) -> Option<Ref<R64>> {
1764    match self {
1765      Value::R64(v) => Some(v.clone()),
1766      #[cfg(feature = "f32")]
1767      Value::F32(v) => Some(Ref::new(R64::new(v.borrow().0 as i64, 1))),
1768      #[cfg(feature = "f64")]
1769      Value::F64(v) => Some(Ref::new(R64::new(v.borrow().0 as i64, 1))),
1770      #[cfg(feature = "u8")]
1771      Value::U8(v) => Some(Ref::new(R64::new(*v.borrow() as i64, 1))),
1772      #[cfg(feature = "u16")]
1773      Value::U16(v) => Some(Ref::new(R64::new(*v.borrow() as i64, 1))),
1774      #[cfg(feature = "u32")]
1775      Value::U32(v) => Some(Ref::new(R64::new(*v.borrow() as i64, 1))),
1776      #[cfg(feature = "u64")]
1777      Value::U64(v) => Some(Ref::new(R64::new(*v.borrow() as i64, 1))),
1778      #[cfg(feature = "u128")]
1779      Value::U128(v) => Some(Ref::new(R64::new(*v.borrow() as i64, 1))),
1780      #[cfg(feature = "i8")]
1781      Value::I8(v) => Some(Ref::new(R64::new(*v.borrow() as i64, 1))),
1782      #[cfg(feature = "i16")]
1783      Value::I16(v) => Some(Ref::new(R64::new(*v.borrow() as i64, 1))),
1784      #[cfg(feature = "i32")]
1785      Value::I32(v) => Some(Ref::new(R64::new(*v.borrow() as i64, 1))),
1786      #[cfg(feature = "i64")]
1787      Value::I64(v) => Some(Ref::new(R64::new(*v.borrow() as i64, 1))),
1788      #[cfg(feature = "i128")]
1789      Value::I128(v) => Some(Ref::new(R64::new(*v.borrow() as i64, 1))),
1790      Value::MutableReference(val) => val.borrow().as_r64(),
1791      _ => None,
1792    }
1793  }
1794
1795  #[cfg(feature = "complex")]
1796  pub fn as_c64(&self) -> Option<Ref<C64>> {
1797    match self {
1798      Value::C64(v) => Some(v.clone()),
1799      #[cfg(feature = "f32")]
1800      Value::F32(v) =>  Some(Ref::new(C64::new(v.borrow().0 as f64, 0.0))),
1801      #[cfg(feature = "f64")]
1802      Value::F64(v) =>  Some(Ref::new(C64::new(v.borrow().0, 0.0))),
1803      #[cfg(feature = "u8")]
1804      Value::U8(v) =>   Some(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1805      #[cfg(feature = "u16")]
1806      Value::U16(v) =>  Some(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1807      #[cfg(feature = "u32")]
1808      Value::U32(v) =>  Some(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1809      #[cfg(feature = "u64")]
1810      Value::U64(v) =>  Some(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1811      #[cfg(feature = "u128")]
1812      Value::U128(v) => Some(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1813      #[cfg(feature = "i8")]
1814      Value::I8(v) =>   Some(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1815      #[cfg(feature = "i16")]
1816      Value::I16(v) =>  Some(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1817      #[cfg(feature = "i32")]
1818      Value::I32(v) =>  Some(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1819      #[cfg(feature = "i64")]
1820      Value::I64(v) =>  Some(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1821      #[cfg(feature = "i128")]
1822      Value::I128(v) => Some(Ref::new(C64::new(*v.borrow() as f64, 0.0))),
1823      Value::MutableReference(val) => val.borrow().as_c64(),
1824      _ => None,
1825    }
1826  }
1827
1828  #[cfg(feature = "f32")]
1829  pub fn as_f32(&self) -> Option<Ref<F32>> {
1830    match self {
1831      #[cfg(feature = "u8")]
1832      Value::U8(v) => Some(Ref::new(F32::new(*v.borrow() as f32))),
1833      #[cfg(feature = "u16")]
1834      Value::U16(v) => Some(Ref::new(F32::new(*v.borrow() as f32))),
1835      #[cfg(feature = "u32")]
1836      Value::U32(v) => Some(Ref::new(F32::new(*v.borrow() as f32))),
1837      #[cfg(feature = "u64")]
1838      Value::U64(v) => Some(Ref::new(F32::new(*v.borrow() as f32))),
1839      #[cfg(feature = "u128")]
1840      Value::U128(v) => Some(Ref::new(F32::new(*v.borrow() as f32))),
1841      #[cfg(feature = "i8")]
1842      Value::I8(v) => Some(Ref::new(F32::new(*v.borrow() as f32))),
1843      #[cfg(feature = "i16")]
1844      Value::I16(v) => Some(Ref::new(F32::new(*v.borrow() as f32))),
1845      #[cfg(feature = "i32")]
1846      Value::I32(v) => Some(Ref::new(F32::new(*v.borrow() as f32))),
1847      #[cfg(feature = "i64")]
1848      Value::I64(v) => Some(Ref::new(F32::new(*v.borrow() as f32))),
1849      #[cfg(feature = "i128")]
1850      Value::I128(v) => Some(Ref::new(F32::new(*v.borrow() as f32))),
1851      #[cfg(feature = "f32")]
1852      Value::F32(v) => Some(v.clone()),
1853      #[cfg(feature = "f64")]
1854      Value::F64(v) => Some(Ref::new(F32::new((*v.borrow()).0 as f32))),
1855      Value::MutableReference(val) => val.borrow().as_f32(),
1856      _ => None,
1857    }
1858  }
1859
1860  #[cfg(feature = "f64")]
1861  pub fn as_f64(&self) -> Option<Ref<F64>> {
1862    match self {
1863      #[cfg(feature = "u8")]
1864      Value::U8(v) => Some(Ref::new(F64::new(*v.borrow() as f64))),
1865      #[cfg(feature = "u16")]
1866      Value::U16(v) => Some(Ref::new(F64::new(*v.borrow() as f64))),
1867      #[cfg(feature = "u32")]
1868      Value::U32(v) => Some(Ref::new(F64::new(*v.borrow() as f64))),
1869      #[cfg(feature = "u64")]
1870      Value::U64(v) => Some(Ref::new(F64::new(*v.borrow() as f64))),
1871      #[cfg(feature = "u128")]
1872      Value::U128(v) => Some(Ref::new(F64::new(*v.borrow() as f64))),
1873      #[cfg(feature = "i8")]
1874      Value::I8(v) => Some(Ref::new(F64::new(*v.borrow() as f64))),
1875      #[cfg(feature = "i16")]
1876      Value::I16(v) => Some(Ref::new(F64::new(*v.borrow() as f64))),
1877      #[cfg(feature = "i32")]
1878      Value::I32(v) => Some(Ref::new(F64::new(*v.borrow() as f64))),
1879      #[cfg(feature = "i64")]
1880      Value::I64(v) => Some(Ref::new(F64::new(*v.borrow() as f64))),
1881      #[cfg(feature = "i128")]
1882      Value::I128(v) => Some(Ref::new(F64::new(*v.borrow() as f64))),
1883      Value::F64(v) => Some(v.clone()),
1884      Value::MutableReference(val) => val.borrow().as_f64(),
1885      _ => None,
1886    }
1887  }
1888
1889  #[cfg(all(feature = "matrix", feature = "bool"))]
1890  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 }}
1891  
1892  #[cfg(all(feature = "matrix", feature = "f64"))]
1893  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 } }
1894  #[cfg(all(feature = "matrix", feature = "f32"))]
1895  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 } }
1896
1897  #[cfg(all(feature = "matrix", feature = "u8"))]
1898  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 } }
1899  #[cfg(all(feature = "matrix", feature = "u16"))]
1900  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 } }
1901  #[cfg(all(feature = "matrix", feature = "u32"))]
1902  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 } }
1903  #[cfg(all(feature = "matrix", feature = "u64"))]
1904  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 } }
1905  #[cfg(all(feature = "matrix", feature = "u128"))]
1906  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 } }
1907
1908  #[cfg(all(feature = "matrix", feature = "i8"))]
1909  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 } }
1910  #[cfg(all(feature = "matrix", feature = "i16"))]
1911  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 } }
1912  #[cfg(all(feature = "matrix", feature = "i32"))]
1913  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 } }
1914  #[cfg(all(feature = "matrix", feature = "i64"))]
1915  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 } }
1916  #[cfg(all(feature = "matrix", feature = "i128"))]
1917  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 } }
1918
1919  #[cfg(all(feature = "matrix", feature = "string"))]
1920  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 }}
1921
1922  #[cfg(all(feature = "matrix", feature = "rational"))]
1923  pub fn as_vecr64(&self) -> Option<Vec<R64>> {if let Value::MatrixR64(v)  = self { Some(v.as_vec()) } else if let Value::R64(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecr64()  } else { None }}
1924  #[cfg(all(feature = "matrix", feature = "complex"))]
1925  pub fn as_vecc64(&self) -> Option<Vec<C64>> {if let Value::MatrixC64(v)  = self { Some(v.as_vec()) } else if let Value::C64(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecc64()  } else { None }}
1926
1927  pub fn as_vecusize(&self) -> Option<Vec<usize>> {
1928    match self {
1929      #[cfg(feature = "u8")]
1930      Value::U8(v) => Some(vec![*v.borrow() as usize]),
1931      #[cfg(feature = "u16")]
1932      Value::U16(v) => Some(vec![*v.borrow() as usize]),
1933      #[cfg(feature = "u32")]
1934      Value::U32(v) => Some(vec![*v.borrow() as usize]),
1935      #[cfg(feature = "u64")]
1936      Value::U64(v) => Some(vec![*v.borrow() as usize]),
1937      #[cfg(feature = "u128")]
1938      Value::U128(v) => Some(vec![*v.borrow() as usize]),
1939      #[cfg(feature = "i8")]
1940      Value::I8(v) => Some(vec![*v.borrow() as usize]),
1941      #[cfg(feature = "i16")]
1942      Value::I16(v) => Some(vec![*v.borrow() as usize]),
1943      #[cfg(feature = "i32")]
1944      Value::I32(v) => Some(vec![*v.borrow() as usize]),
1945      #[cfg(feature = "i64")]
1946      Value::I64(v) => Some(vec![*v.borrow() as usize]),
1947      #[cfg(feature = "i128")]
1948      Value::I128(v) => Some(vec![*v.borrow() as usize]),
1949      #[cfg(feature = "f32")]
1950      Value::F32(v) => Some(vec![(*v.borrow()).0 as usize]),
1951      #[cfg(feature = "f64")]
1952      Value::F64(v) => Some(vec![(*v.borrow()).0 as usize]),
1953      #[cfg(feature = "matrix")]
1954      Value::MatrixIndex(v) => Some(v.as_vec()),
1955      #[cfg(all(feature = "matrix", feature = "f64"))]
1956      Value::MatrixF64(v) => Some(v.as_vec().iter().map(|x| (*x).0 as usize).collect::<Vec<usize>>()),
1957      #[cfg(all(feature = "matrix", feature = "f32"))]
1958      Value::MatrixF32(v) => Some(v.as_vec().iter().map(|x| (*x).0 as usize).collect::<Vec<usize>>()),
1959      #[cfg(all(feature = "matrix", feature = "u8"))]
1960      Value::MatrixU8(v) => Some(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
1961      #[cfg(all(feature = "matrix", feature = "u16"))]  
1962      Value::MatrixU16(v) => Some(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
1963      #[cfg(all(feature = "matrix", feature = "u32"))]
1964      Value::MatrixU32(v) => Some(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
1965      #[cfg(all(feature = "matrix", feature = "u64"))]
1966      Value::MatrixU64(v) => Some(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
1967      #[cfg(all(feature = "matrix", feature = "u128"))]
1968      Value::MatrixU128(v) => Some(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
1969      #[cfg(all(feature = "matrix", feature = "i8"))]
1970      Value::MatrixI8(v) => Some(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
1971      #[cfg(all(feature = "matrix", feature = "i16"))]
1972      Value::MatrixI16(v) => Some(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
1973      #[cfg(all(feature = "matrix", feature = "i32"))]
1974      Value::MatrixI32(v) => Some(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
1975      #[cfg(all(feature = "matrix", feature = "i128"))]
1976      Value::MatrixI128(v) => Some(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
1977      #[cfg(all(feature = "matrix", feature = "i64"))]
1978      Value::MatrixI64(v) => Some(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
1979      #[cfg(all(feature = "matrix", feature = "bool"))]
1980      Value::MatrixBool(_) => None,
1981      #[cfg(feature = "bool")]
1982      Value::Bool(_) => None,
1983      Value::MutableReference(x) => x.borrow().as_vecusize(),
1984      _ => todo!(),
1985    }
1986  }
1987
1988  pub fn as_index(&self) -> MResult<Value> {
1989    match self.as_usize() {      
1990      Some(ix) => Ok(Value::Index(Ref::new(ix))),
1991      #[cfg(feature = "matrix")]
1992      None => match self.as_vecusize() {
1993        #[cfg(feature = "matrix")]
1994        Some(x) => {
1995          let shape = self.shape();
1996          let out = Value::MatrixIndex(usize::to_matrix(x, shape[0] * shape[1],1 ));
1997          Ok(out)
1998        },
1999        #[cfg(all(feature = "matrix", feature = "bool"))]
2000        None => match self.as_vecbool() {
2001          Some(x) => {
2002            let shape = self.shape();
2003            let out = match (shape[0], shape[1]) {
2004              (1,1) => Value::Bool(Ref::new(x[0])),
2005              #[cfg(all(feature = "vectord", feature = "bool"))]
2006              (1,n) => Value::MatrixBool(Matrix::DVector(Ref::new(DVector::from_vec(x)))),
2007              #[cfg(all(feature = "vectord", feature = "bool"))]
2008              (m,1) => Value::MatrixBool(Matrix::DVector(Ref::new(DVector::from_vec(x)))),
2009              #[cfg(all(feature = "vectord", feature = "bool"))]
2010              (m,n) => Value::MatrixBool(Matrix::DVector(Ref::new(DVector::from_vec(x)))),
2011              _ => todo!(),
2012            };
2013            Ok(out)
2014          }
2015          None => match self.as_bool() {
2016            Some(x) => Ok(Value::Bool(x)),
2017            None => Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledIndexKind}),
2018          }
2019        }
2020        x => Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::None}),
2021      }
2022      _ => todo!(),
2023    }
2024  }
2025
2026  pub fn as_usize(&self) -> Option<usize> {
2027    match self {      
2028      Value::Index(v) => Some(*v.borrow()),
2029      #[cfg(feature = "u8")]
2030      Value::U8(v) => Some(*v.borrow() as usize),
2031      #[cfg(feature = "u16")]
2032      Value::U16(v) => Some(*v.borrow() as usize),
2033      #[cfg(feature = "u32")]
2034      Value::U32(v) => Some(*v.borrow() as usize),
2035      #[cfg(feature = "u64")]
2036      Value::U64(v) => Some(*v.borrow() as usize),
2037      #[cfg(feature = "u128")]
2038      Value::U128(v) => Some(*v.borrow() as usize),
2039      #[cfg(feature = "i8")]
2040      Value::I8(v) => Some(*v.borrow() as usize),
2041      #[cfg(feature = "i16")]
2042      Value::I16(v) => Some(*v.borrow() as usize),
2043      #[cfg(feature = "i32")]
2044      Value::I32(v) => Some(*v.borrow() as usize),
2045      #[cfg(feature = "i64")]
2046      Value::I64(v) => Some(*v.borrow() as usize),
2047      #[cfg(feature = "i128")]
2048      Value::I128(v) => Some(*v.borrow() as usize),
2049      #[cfg(feature = "f32")]
2050      Value::F32(v) => Some((*v.borrow()).0 as usize),
2051      #[cfg(feature = "f64")]
2052      Value::F64(v) => Some((*v.borrow()).0 as usize),
2053      Value::MutableReference(v) => v.borrow().as_usize(),
2054      _ => None,
2055    }
2056  }
2057
2058  #[cfg(feature = "u8")]
2059  pub fn expect_u8(&self) -> MResult<Ref<u8>> {
2060    match self {
2061      Value::U8(v) => Ok(v.clone()),
2062      Value::MutableReference(v) => v.borrow().expect_u8(),
2063      _ => Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::None}),
2064    }
2065  }
2066
2067  #[cfg(feature = "f64")]
2068  pub fn expect_f64(&self) -> MResult<Ref<F64>> {
2069    match self {
2070      Value::F64(v) => Ok(v.clone()),
2071      Value::MutableReference(v) => v.borrow().expect_f64(),
2072      _ => Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::None}),
2073    }
2074  }
2075
2076}
2077
2078#[cfg(feature = "pretty_print")]
2079impl PrettyPrint for Value {
2080  fn pretty_print(&self) -> String {
2081    let mut builder = Builder::default();
2082    match self {
2083      #[cfg(feature = "u8")]
2084      Value::U8(x)   => {builder.push_record(vec![format!("{}",x.borrow())]);},
2085      #[cfg(feature = "u16")]
2086      Value::U16(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
2087      #[cfg(feature = "u32")]
2088      Value::U32(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
2089      #[cfg(feature = "u64")]
2090      Value::U64(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
2091      #[cfg(feature = "u128")]
2092      Value::U128(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
2093      #[cfg(feature = "i8")]
2094      Value::I8(x)   => {builder.push_record(vec![format!("{}",x.borrow())]);},
2095      #[cfg(feature = "i16")]
2096      Value::I16(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
2097      #[cfg(feature = "i32")]
2098      Value::I32(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
2099      #[cfg(feature = "i64")]
2100      Value::I64(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
2101      #[cfg(feature = "i128")]
2102      Value::I128(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
2103      #[cfg(feature = "f32")]
2104      Value::F32(x)  => {builder.push_record(vec![format!("{}",x.borrow().0)]);},
2105      #[cfg(feature = "f64")]
2106      Value::F64(x)  => {builder.push_record(vec![format!("{}",x.borrow().0)]);},
2107      #[cfg(feature = "bool")]
2108      Value::Bool(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
2109      #[cfg(feature = "complex")]
2110      Value::C64(x) => {builder.push_record(vec![x.borrow().pretty_print()]);},
2111      #[cfg(feature = "rational")]
2112      Value::R64(x) => {builder.push_record(vec![format!("{}",x.borrow().pretty_print())]);},
2113      #[cfg(feature = "atom")]
2114      Value::Atom(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
2115      #[cfg(feature = "set")]
2116      Value::Set(x)  => {return x.borrow().pretty_print();}
2117      #[cfg(feature = "map")]
2118      Value::Map(x)  => {return x.borrow().pretty_print();}
2119      #[cfg(feature = "string")]
2120      Value::String(x) => {return format!("\"{}\"",x.borrow().clone());},
2121      #[cfg(feature = "table")]
2122      Value::Table(x)  => {return x.borrow().pretty_print();},
2123      #[cfg(feature = "tuple")]
2124      Value::Tuple(x)  => {return x.borrow().pretty_print();},
2125      #[cfg(feature = "record")]
2126      Value::Record(x) => {return x.borrow().pretty_print();},
2127      #[cfg(feature = "enum")]
2128      Value::Enum(x) => {return x.borrow().pretty_print();},
2129      #[cfg(feature = "matrix")]
2130      Value::MatrixIndex(x) => {return x.pretty_print();},
2131      #[cfg(all(feature = "matrix", feature = "bool"))]
2132      Value::MatrixBool(x) => {return x.pretty_print();},
2133      #[cfg(all(feature = "matrix", feature = "u8"))]
2134      Value::MatrixU8(x)   => {return x.pretty_print();},
2135      #[cfg(all(feature = "matrix", feature = "u16"))]
2136      Value::MatrixU16(x)  => {return x.pretty_print();},
2137      #[cfg(all(feature = "matrix", feature = "u32"))]
2138      Value::MatrixU32(x)  => {return x.pretty_print();},
2139      #[cfg(all(feature = "matrix", feature = "u64"))]
2140      Value::MatrixU64(x)  => {return x.pretty_print();},
2141      #[cfg(all(feature = "matrix", feature = "u128"))]
2142      Value::MatrixU128(x) => {return x.pretty_print();},
2143      #[cfg(all(feature = "matrix", feature = "i8"))]
2144      Value::MatrixI8(x)   => {return x.pretty_print();},
2145      #[cfg(all(feature = "matrix", feature = "i16"))]
2146      Value::MatrixI16(x)  => {return x.pretty_print();},
2147      #[cfg(all(feature = "matrix", feature = "i32"))]
2148      Value::MatrixI32(x)  => {return x.pretty_print();},
2149      #[cfg(all(feature = "matrix", feature = "i64"))]
2150      Value::MatrixI64(x)  => {return x.pretty_print();},
2151      #[cfg(all(feature = "matrix", feature = "i128"))]
2152      Value::MatrixI128(x) => {return x.pretty_print();},
2153      #[cfg(all(feature = "matrix", feature = "f32"))]
2154      Value::MatrixF32(x)  => {return x.pretty_print();},
2155      #[cfg(all(feature = "matrix", feature = "f64"))]
2156      Value::MatrixF64(x)  => {return x.pretty_print();},
2157      #[cfg(all(feature = "matrix", feature = "any"))]
2158      Value::MatrixValue(x)  => {return x.pretty_print();},
2159      #[cfg(all(feature = "matrix", feature = "string"))]
2160      Value::MatrixString(x)  => {return x.pretty_print();},
2161      #[cfg(all(feature = "matrix", feature = "rational"))]
2162      Value::MatrixR64(x) => {return x.pretty_print();},
2163      #[cfg(all(feature = "matrix", feature = "complex"))]
2164      Value::MatrixC64(x) => {return x.pretty_print();},
2165      Value::Index(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
2166      Value::MutableReference(x) => {return x.borrow().pretty_print();},
2167      Value::Empty => builder.push_record(vec!["_"]),
2168      Value::IndexAll => builder.push_record(vec![":"]),
2169      Value::Id(x) => builder.push_record(vec![format!("{}",humanize(x))]),
2170      Value::Kind(x) => builder.push_record(vec![format!("{}",x)]),
2171      x => {
2172        todo!("{x:#?}");
2173      },
2174    };
2175    let value_style = Style::empty()
2176      .top(' ')
2177      .left(' ')
2178      .right(' ')
2179      .bottom(' ')
2180      .vertical(' ')
2181      .intersection_bottom(' ')
2182      .corner_top_left(' ')
2183      .corner_top_right(' ')
2184      .corner_bottom_left(' ')
2185      .corner_bottom_right(' ');
2186    let mut table = builder.build();
2187    table.with(value_style);
2188    format!("{table}")
2189  }
2190}
2191
2192
2193pub trait ToIndex {
2194  fn to_index(&self) -> Value;
2195}
2196
2197#[cfg(feature = "matrix")]
2198impl ToIndex for Ref<Vec<i64>> { fn to_index(&self) -> Value { (*self.borrow()).iter().map(|x| *x as usize).collect::<Vec<usize>>().to_value() } }
2199
2200pub trait ToValue {
2201  fn to_value(&self) -> Value;
2202}
2203
2204#[cfg(feature = "matrix")]
2205impl ToValue for Vec<usize> {
2206  fn to_value(&self) -> Value {
2207    match self.len() {
2208      1 => Value::Index(Ref::new(self[0].clone())),
2209      #[cfg(feature = "vector2")]
2210      2 => Value::MatrixIndex(Matrix::Vector2(Ref::new(Vector2::from_vec(self.clone())))),
2211      #[cfg(feature = "vector3")]
2212      3 => Value::MatrixIndex(Matrix::Vector3(Ref::new(Vector3::from_vec(self.clone())))),
2213      #[cfg(feature = "vector4")]
2214      4 => Value::MatrixIndex(Matrix::Vector4(Ref::new(Vector4::from_vec(self.clone())))),
2215      #[cfg(feature = "vectord")]
2216      n => Value::MatrixIndex(Matrix::DVector(Ref::new(DVector::from_vec(self.clone())))),
2217      _ => todo!(),
2218    }
2219  }
2220}
2221
2222impl ToValue for Ref<usize>  { fn to_value(&self) -> Value { Value::Index(self.clone())  } }
2223#[cfg(feature = "u8")]
2224impl ToValue for Ref<u8>     { fn to_value(&self) -> Value { Value::U8(self.clone())     } }
2225#[cfg(feature = "u16")]
2226impl ToValue for Ref<u16>    { fn to_value(&self) -> Value { Value::U16(self.clone())    } }
2227#[cfg(feature = "u32")]
2228impl ToValue for Ref<u32>    { fn to_value(&self) -> Value { Value::U32(self.clone())    } }
2229#[cfg(feature = "u64")]
2230impl ToValue for Ref<u64>    { fn to_value(&self) -> Value { Value::U64(self.clone())    } }
2231#[cfg(feature = "u128")]
2232impl ToValue for Ref<u128>   { fn to_value(&self) -> Value { Value::U128(self.clone())   } }
2233#[cfg(feature = "i8")]
2234impl ToValue for Ref<i8>     { fn to_value(&self) -> Value { Value::I8(self.clone())     } }
2235#[cfg(feature = "i16")]
2236impl ToValue for Ref<i16>    { fn to_value(&self) -> Value { Value::I16(self.clone())    } }
2237#[cfg(feature = "i32")]
2238impl ToValue for Ref<i32>    { fn to_value(&self) -> Value { Value::I32(self.clone())    } }
2239#[cfg(feature = "i64")]
2240impl ToValue for Ref<i64>    { fn to_value(&self) -> Value { Value::I64(self.clone())    } }
2241#[cfg(feature = "i128")]
2242impl ToValue for Ref<i128>   { fn to_value(&self) -> Value { Value::I128(self.clone())   } }
2243#[cfg(feature = "f32")]
2244impl ToValue for Ref<F32>    { fn to_value(&self) -> Value { Value::F32(self.clone())    } }
2245#[cfg(feature = "f64")]
2246impl ToValue for Ref<F64>    { fn to_value(&self) -> Value { Value::F64(self.clone())    } }
2247#[cfg(feature = "bool")]
2248impl ToValue for Ref<bool>   { fn to_value(&self) -> Value { Value::Bool(self.clone())   } }
2249#[cfg(feature = "string")]
2250impl ToValue for Ref<String> { fn to_value(&self) -> Value { Value::String(self.clone()) } }
2251#[cfg(feature = "rational")]
2252impl ToValue for Ref<R64> { fn to_value(&self) -> Value { Value::R64(self.clone()) } }
2253#[cfg(feature = "complex")]
2254impl ToValue for Ref<C64> { fn to_value(&self) -> Value { Value::C64(self.clone()) } }
2255
2256#[cfg(feature = "u8")]
2257impl From<u8> for Value {
2258  fn from(val: u8) -> Self {
2259    Value::U8(Ref::new(val))
2260  }
2261}
2262
2263#[cfg(feature = "u16")]
2264impl From<u16> for Value {
2265  fn from(val: u16) -> Self {
2266    Value::U16(Ref::new(val))
2267  }
2268}
2269
2270#[cfg(feature = "u32")]
2271impl From<u32> for Value {
2272  fn from(val: u32) -> Self {
2273    Value::U32(Ref::new(val))
2274  }
2275}
2276
2277#[cfg(feature = "u64")]
2278impl From<u64> for Value {
2279  fn from(val: u64) -> Self {
2280    Value::U64(Ref::new(val))
2281  }
2282}
2283
2284#[cfg(feature = "u128")]
2285impl From<u128> for Value {
2286  fn from(val: u128) -> Self {
2287    Value::U128(Ref::new(val))
2288  }
2289}
2290
2291#[cfg(feature = "i8")]
2292impl From<i8> for Value {
2293  fn from(val: i8) -> Self {
2294    Value::I8(Ref::new(val))
2295  }
2296}
2297
2298#[cfg(feature = "i16")]
2299impl From<i16> for Value {
2300  fn from(val: i16) -> Self {
2301    Value::I16(Ref::new(val))
2302  }
2303}
2304
2305#[cfg(feature = "i32")]
2306impl From<i32> for Value {
2307  fn from(val: i32) -> Self {
2308    Value::I32(Ref::new(val))
2309  }
2310}
2311
2312#[cfg(feature = "i64")]
2313impl From<i64> for Value {
2314  fn from(val: i64) -> Self {
2315    Value::I64(Ref::new(val))
2316  }
2317}
2318
2319#[cfg(feature = "i128")]
2320impl From<i128> for Value {
2321  fn from(val: i128) -> Self {
2322    Value::I128(Ref::new(val))
2323  }
2324}
2325
2326#[cfg(feature = "bool")]
2327impl From<bool> for Value {
2328  fn from(val: bool) -> Self {
2329    Value::Bool(Ref::new(val))
2330  }
2331}
2332
2333#[cfg(feature = "string")]
2334impl From<String> for Value {
2335  fn from(val: String) -> Self {
2336    Value::String(Ref::new(val))
2337  }
2338}
2339
2340#[cfg(feature = "rational")]
2341impl From<R64> for Value {
2342  fn from(val: R64) -> Self {
2343    Value::R64(Ref::new(val))
2344  }
2345}
2346
2347
2348pub trait ToUsize {
2349  fn to_usize(&self) -> usize;
2350}
2351
2352macro_rules! impl_to_usize_for {
2353  ($t:ty) => {
2354    impl ToUsize for $t {
2355      fn to_usize(&self) -> usize {
2356        #[allow(unused_comparisons)]
2357        if *self < 0 as $t {
2358          panic!("Cannot convert negative number to usize");
2359        }
2360        *self as usize
2361      }
2362    }
2363  };
2364}
2365
2366#[cfg(feature = "u8")]
2367impl_to_usize_for!(u8);
2368#[cfg(feature = "u16")]
2369impl_to_usize_for!(u16);
2370#[cfg(feature = "u32")]
2371impl_to_usize_for!(u32);
2372#[cfg(feature = "u64")]
2373impl_to_usize_for!(u64);
2374#[cfg(feature = "u128")]
2375impl_to_usize_for!(u128);
2376impl_to_usize_for!(usize);
2377
2378#[cfg(feature = "i8")]
2379impl_to_usize_for!(i8);
2380#[cfg(feature = "i16")]
2381impl_to_usize_for!(i16);
2382#[cfg(feature = "i32")]
2383impl_to_usize_for!(i32);
2384#[cfg(feature = "i64")]
2385impl_to_usize_for!(i64);
2386#[cfg(feature = "i128")]
2387impl_to_usize_for!(i128);
2388