1use crate::dag::{Dag, DagLike};
9use crate::types::{CompleteBound, Final};
10use crate::{BitCollector, EarlyEndOfStreamError};
11use crate::{BitIter, Tmr};
12
13use hashes::sha256;
14
15use core::{cmp, fmt, iter};
16use std::collections::VecDeque;
17use std::hash::Hash;
18use std::sync::Arc;
19
20#[derive(Clone)]
22pub struct Value {
23 inner: Arc<[u8]>,
34 bit_offset: usize,
38 ty: Arc<Final>,
40}
41
42#[derive(Debug, Clone, Copy)]
44pub struct ValueRef<'v> {
45 inner: &'v Arc<[u8]>,
46 bit_offset: usize,
47 ty: &'v Arc<Final>,
48}
49
50impl PartialEq for Value {
56 fn eq(&self, other: &Self) -> bool {
57 self.ty == other.ty && self.raw_byte_iter().eq(other.raw_byte_iter())
58 }
59}
60impl Eq for Value {}
61
62impl PartialOrd for Value {
63 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
64 Some(self.cmp(other))
65 }
66}
67impl Ord for Value {
68 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
69 self.ty
70 .cmp(&other.ty)
71 .then_with(|| self.raw_byte_iter().cmp(other.raw_byte_iter()))
72 }
73}
74
75impl core::hash::Hash for Value {
76 fn hash<H: core::hash::Hasher>(&self, h: &mut H) {
77 b"Simplicity\x1fValue".hash(h);
78 self.ty.hash(h);
79 for val in self.raw_byte_iter() {
80 val.hash(h);
81 }
82 }
83}
84
85impl DagLike for ValueRef<'_> {
86 type Node = Self;
87
88 fn data(&self) -> &Self {
89 self
90 }
91
92 fn as_dag_node(&self) -> Dag<Self> {
93 if let Some((left, right)) = self.as_product() {
94 Dag::Binary(left, right)
95 } else if let Some(left) = self.as_left() {
96 Dag::Unary(left)
97 } else if let Some(right) = self.as_right() {
98 Dag::Unary(right)
99 } else {
100 assert!(self.ty.is_unit());
101 Dag::Nullary
102 }
103 }
104}
105
106impl<'v> ValueRef<'v> {
107 pub fn is_unit(&self) -> bool {
109 self.ty.is_unit()
110 }
111
112 fn first_bit(&self) -> Option<bool> {
117 let mask = if self.bit_offset % 8 == 0 {
118 0x80
119 } else {
120 1 << (7 - self.bit_offset % 8)
121 };
122 let res = self
123 .inner
124 .get(self.bit_offset / 8)
125 .map(|x| x & mask == mask);
126 res
127 }
128
129 pub fn as_left(&self) -> Option<Self> {
131 if self.first_bit() == Some(false) {
132 if let Some((lty, rty)) = self.ty.as_sum() {
133 let sum_width = 1 + cmp::max(lty.bit_width(), rty.bit_width());
134 Some(Self {
135 inner: self.inner,
136 bit_offset: self.bit_offset + sum_width - lty.bit_width(),
137 ty: lty,
138 })
139 } else {
140 None
141 }
142 } else {
143 None
144 }
145 }
146
147 pub fn as_right(&self) -> Option<Self> {
149 if self.first_bit() == Some(true) {
150 if let Some((lty, rty)) = self.ty.as_sum() {
151 let sum_width = 1 + cmp::max(lty.bit_width(), rty.bit_width());
152 Some(Self {
153 inner: self.inner,
154 bit_offset: self.bit_offset + sum_width - rty.bit_width(),
155 ty: rty,
156 })
157 } else {
158 None
159 }
160 } else {
161 None
162 }
163 }
164
165 pub fn as_product(&self) -> Option<(Self, Self)> {
167 if let Some((lty, rty)) = self.ty.as_product() {
168 Some((
169 Self {
170 inner: self.inner,
171 bit_offset: self.bit_offset,
172 ty: lty,
173 },
174 Self {
175 inner: self.inner,
176 bit_offset: self.bit_offset + lty.bit_width(),
177 ty: rty,
178 },
179 ))
180 } else {
181 None
182 }
183 }
184
185 pub fn to_value(&self) -> Value {
187 Value {
188 inner: Arc::clone(self.inner),
189 bit_offset: self.bit_offset,
190 ty: Arc::clone(self.ty),
191 }
192 }
193
194 pub fn to_word(&self) -> Option<Word> {
196 self.ty.as_word().map(|n| Word {
197 value: self.to_value(),
198 n,
199 })
200 }
201
202 pub fn raw_byte_iter(&self) -> RawByteIter<'v> {
208 RawByteIter {
209 value: *self,
210 yielded_bytes: 0,
211 }
212 }
213
214 pub fn iter_compact(&self) -> CompactBitsIter<'v> {
218 CompactBitsIter::new(*self)
219 }
220
221 pub fn iter_padded(&self) -> PreOrderIter<'v> {
225 PreOrderIter {
226 inner: BitIter::new(self.raw_byte_iter()).take(self.ty.bit_width()),
227 }
228 }
229}
230
231pub struct RawByteIter<'v> {
232 value: ValueRef<'v>,
233 yielded_bytes: usize,
234}
235
236impl Iterator for RawByteIter<'_> {
237 type Item = u8;
238 fn next(&mut self) -> Option<Self::Item> {
239 if 8 * self.yielded_bytes >= self.value.ty.bit_width() {
240 None
241 } else if self.value.bit_offset % 8 == 0 {
242 self.yielded_bytes += 1;
243
244 Some(self.value.inner[self.value.bit_offset / 8 + self.yielded_bytes - 1])
245 } else {
246 self.yielded_bytes += 1;
247
248 let ret1 = self.value.inner[self.value.bit_offset / 8 + self.yielded_bytes - 1];
249 let ret2 = self
250 .value
251 .inner
252 .get(self.value.bit_offset / 8 + self.yielded_bytes)
253 .copied()
254 .unwrap_or(0);
255 let bit_offset = self.value.bit_offset % 8;
256 Some((ret1 << bit_offset) | (ret2 >> (8 - bit_offset)))
257 }
258 }
259}
260
261pub struct PreOrderIter<'v> {
262 inner: iter::Take<BitIter<RawByteIter<'v>>>,
263}
264
265impl Iterator for PreOrderIter<'_> {
266 type Item = bool;
267 fn next(&mut self) -> Option<Self::Item> {
268 self.inner.next()
269 }
270}
271
272fn right_shift_1(inner: &Arc<[u8]>, bit_offset: usize, new_bit: bool) -> (Arc<[u8]>, usize) {
278 if bit_offset > 0 {
281 let new_bit_offset = bit_offset - 1;
282 let mask = 1u8 << (7 - new_bit_offset % 8);
283 let current_bit = inner[new_bit_offset / 8] & mask != 0;
284 if current_bit == new_bit {
285 (Arc::clone(inner), new_bit_offset)
286 } else if new_bit {
287 let mut bx: Box<[u8]> = inner.as_ref().into();
288 bx[new_bit_offset / 8] |= mask;
289 (bx.into(), new_bit_offset)
290 } else {
291 let mut bx: Box<[u8]> = inner.as_ref().into();
292 bx[new_bit_offset / 8] &= !mask;
293 (bx.into(), new_bit_offset)
294 }
295 } else {
296 let mut new = Vec::with_capacity(inner.len() + 1);
300 new.push(u8::from(new_bit));
301 new.extend(inner.iter().copied());
302 (new.into(), 7)
303 }
304}
305
306fn copy_bits(src: &[u8], src_offset: usize, dst: &mut [u8], dst_offset: usize, nbits: usize) {
311 for i in 0..nbits {
314 let bit = (src[(src_offset + i) / 8] >> (7 - (src_offset + i) % 8)) & 1;
315 dst[(dst_offset + i) / 8] |= bit << (7 - (dst_offset + i) % 8);
316 }
317}
318
319fn product(
326 left: Option<(&Arc<[u8]>, usize)>,
327 left_bit_length: usize,
328 right: Option<(&Arc<[u8]>, usize)>,
329 right_bit_length: usize,
330) -> (Arc<[u8]>, usize) {
331 if left_bit_length == 0 {
332 if let Some((right, right_bit_offset)) = right {
333 (Arc::clone(right), right_bit_offset)
334 } else if right_bit_length == 0 {
335 (Arc::new([]), 0)
336 } else {
337 (Arc::from(vec![0; right_bit_length.div_ceil(8)]), 0)
338 }
339 } else if right_bit_length == 0 {
340 if let Some((lt, left_bit_offset)) = left {
341 (Arc::clone(lt), left_bit_offset)
342 } else {
343 (Arc::from(vec![0; left_bit_length.div_ceil(8)]), 0)
344 }
345 } else {
346 let mut bx = Box::<[u8]>::from(vec![0; (left_bit_length + right_bit_length).div_ceil(8)]);
350 if let Some((left, left_bit_offset)) = left {
351 copy_bits(left, left_bit_offset, &mut bx, 0, left_bit_length);
352 }
353 if let Some((right, right_bit_offset)) = right {
354 copy_bits(
355 right,
356 right_bit_offset,
357 &mut bx,
358 left_bit_length,
359 right_bit_length,
360 );
361 }
362
363 (bx.into(), 0)
364 }
365}
366
367impl Value {
368 pub fn shallow_clone(&self) -> Self {
370 Self {
371 inner: Arc::clone(&self.inner),
372 bit_offset: self.bit_offset,
373 ty: Arc::clone(&self.ty),
374 }
375 }
376
377 pub fn ty(&self) -> &Final {
379 &self.ty
380 }
381
382 pub fn unit() -> Self {
384 Self {
385 inner: Arc::new([]),
386 bit_offset: 0,
387 ty: Final::unit(),
388 }
389 }
390
391 pub fn left(inner: Self, right: Arc<Final>) -> Self {
393 let total_width = cmp::max(inner.ty.bit_width(), right.bit_width());
394
395 let (concat, concat_offset) = product(
396 None,
397 total_width - inner.ty.bit_width(),
398 Some((&inner.inner, inner.bit_offset)),
399 inner.ty.bit_width(),
400 );
401 let (new_inner, new_bit_offset) = right_shift_1(&concat, concat_offset, false);
402 Self {
403 inner: new_inner,
404 bit_offset: new_bit_offset,
405 ty: Final::sum(Arc::clone(&inner.ty), right),
406 }
407 }
408
409 pub fn right(left: Arc<Final>, inner: Self) -> Self {
411 let total_width = cmp::max(left.bit_width(), inner.ty.bit_width());
412 let (concat, concat_offset) = product(
413 None,
414 total_width - inner.ty.bit_width(),
415 Some((&inner.inner, inner.bit_offset)),
416 inner.ty.bit_width(),
417 );
418 let (new_inner, new_bit_offset) = right_shift_1(&concat, concat_offset, true);
419 Self {
420 inner: new_inner,
421 bit_offset: new_bit_offset,
422 ty: Final::sum(left, Arc::clone(&inner.ty)),
423 }
424 }
425
426 pub fn product(left: Self, right: Self) -> Self {
428 let (new_inner, new_bit_offset) = product(
429 Some((&left.inner, left.bit_offset)),
430 left.ty.bit_width(),
431 Some((&right.inner, right.bit_offset)),
432 right.ty.bit_width(),
433 );
434 Self {
435 inner: new_inner,
436 bit_offset: new_bit_offset,
437 ty: Final::product(Arc::clone(&left.ty), Arc::clone(&right.ty)),
438 }
439 }
440
441 pub fn none(right: Arc<Final>) -> Self {
443 Self::left(Value::unit(), right)
444 }
445
446 pub fn some(inner: Self) -> Self {
448 Self::right(Final::unit(), inner)
449 }
450
451 pub fn buffer8_two_n_plus_one(mut n: usize, mut data: &[u8]) -> Result<Self, Buffer8Error> {
457 let ty = Final::buffer8_two_n_plus_one(n).map_err(Buffer8Error::NTooLarge)?;
462
463 debug_assert!(
464 ty.bit_width() > (2 << n) - 1,
465 "sanity check to prove that the below line won't overflow",
466 );
467 if data.len() > (2 << n) - 1 {
468 return Err(Buffer8Error::SliceTooLarge {
469 length: data.len(),
470 n,
471 });
472 }
473
474 let mut dest = vec![0; ty.bit_width().div_ceil(8)];
475 let mut dest_offset = 0;
476 loop {
477 let n_bytes = 1 << n;
478
479 if data.len() & n_bytes != 0 {
480 let (first, rest) = data.split_at(n_bytes);
482 copy_bits(&[0x80], 0, &mut dest, dest_offset, 1);
483 copy_bits(first, 0, &mut dest, dest_offset + 1, 8 * n_bytes);
484 data = rest;
485 };
486 dest_offset += 1 + 8 * n_bytes;
487
488 n = match n.checked_sub(1) {
489 Some(n) => n,
490 None => break,
491 };
492 }
493 debug_assert_eq!(dest_offset, ty.bit_width());
494
495 Ok(Self {
496 inner: Arc::from(dest),
497 bit_offset: 0,
498 ty,
499 })
500 }
501
502 pub fn ctx8(
514 midstate: [u8; 32],
515 bytes_hashed: u64,
516 buffer: &[u8],
517 ) -> Result<Self, Buffer8Error> {
518 Ok(Self::product(
519 Self::buffer8_two_n_plus_one(5, buffer)?,
520 Self::product(Self::u64(bytes_hashed), Self::u256(midstate)),
521 ))
522 }
523
524 pub fn ctx8_from_midstate(midstate: sha256::Midstate) -> Self {
526 let (hash, n) = midstate.to_parts();
527 Self::ctx8(hash, n, &[]).expect("0 < 64")
528 }
529
530 pub fn ctx8_from_hash_engine(engine: &sha256::HashEngine) -> Self {
532 match engine.midstate() {
533 Ok(midstate) => {
534 let (hash, n) = midstate.to_parts();
535 Self::ctx8(hash, n, &[]).expect("0 < 64")
536 }
537 Err(midstate_err) => {
538 let (hash, n) = midstate_err.midstate().to_parts();
539 Self::ctx8(hash, n, midstate_err.unprocessed_bytes()).expect("< 64")
540 }
541 }
542 }
543
544 pub fn compact_len(&self) -> usize {
546 self.iter_compact().count()
547 }
548
549 pub fn padded_len(&self) -> usize {
551 self.ty.bit_width()
552 }
553
554 pub fn is_empty(&self) -> bool {
557 self.ty.bit_width() == 0
558 }
559
560 pub fn is_unit(&self) -> bool {
562 self.ty.is_unit()
563 }
564
565 pub fn as_ref(&self) -> ValueRef<'_> {
567 ValueRef {
568 inner: &self.inner,
569 bit_offset: self.bit_offset,
570 ty: &self.ty,
571 }
572 }
573
574 pub fn as_left(&self) -> Option<ValueRef<'_>> {
576 self.as_ref().as_left()
577 }
578
579 pub fn as_right(&self) -> Option<ValueRef<'_>> {
581 self.as_ref().as_right()
582 }
583
584 pub fn as_product(&self) -> Option<(ValueRef<'_>, ValueRef<'_>)> {
586 self.as_ref().as_product()
587 }
588
589 pub fn u1(value: u8) -> Self {
595 assert!(value <= 1, "{} out of range for Value::u1", value);
596 Self {
597 inner: Arc::new([value]),
598 bit_offset: 7,
599 ty: Final::two_two_n_fixed::<0>(),
600 }
601 }
602
603 pub fn u2(value: u8) -> Self {
609 assert!(value <= 3, "{} out of range for Value::u2", value);
610 Self {
611 inner: Arc::new([value]),
612 bit_offset: 6,
613 ty: Final::two_two_n_fixed::<1>(),
614 }
615 }
616
617 pub fn u4(value: u8) -> Self {
623 assert!(value <= 15, "{} out of range for Value::u2", value);
624 Self {
625 inner: Arc::new([value]),
626 bit_offset: 4,
627 ty: Final::two_two_n_fixed::<2>(),
628 }
629 }
630
631 pub fn u8(value: u8) -> Self {
633 Self {
634 inner: Arc::new([value]),
635 bit_offset: 0,
636 ty: Final::two_two_n_fixed::<3>(),
637 }
638 }
639
640 pub fn u16(bytes: u16) -> Self {
642 Self {
643 inner: Arc::new(bytes.to_be_bytes()),
644 bit_offset: 0,
645 ty: Final::two_two_n_fixed::<4>(),
646 }
647 }
648
649 pub fn u32(bytes: u32) -> Self {
651 Self {
652 inner: Arc::new(bytes.to_be_bytes()),
653 bit_offset: 0,
654 ty: Final::two_two_n_fixed::<5>(),
655 }
656 }
657
658 pub fn u64(bytes: u64) -> Self {
660 Self {
661 inner: Arc::new(bytes.to_be_bytes()),
662 bit_offset: 0,
663 ty: Final::two_two_n_fixed::<6>(),
664 }
665 }
666
667 pub fn u128(bytes: u128) -> Self {
669 Self {
670 inner: Arc::new(bytes.to_be_bytes()),
671 bit_offset: 0,
672 ty: Final::two_two_n_fixed::<7>(),
673 }
674 }
675
676 pub fn u256(bytes: [u8; 32]) -> Self {
678 Self {
679 inner: Arc::new(bytes),
680 bit_offset: 0,
681 ty: Final::two_two_n_fixed::<8>(),
682 }
683 }
684
685 pub fn u512(bytes: [u8; 64]) -> Self {
687 Self {
688 inner: Arc::new(bytes),
689 bit_offset: 0,
690 ty: Final::two_two_n_fixed::<9>(),
691 }
692 }
693
694 pub fn from_byte_array<const N: usize>(bytes: [u8; N]) -> Self {
700 assert!(N.is_power_of_two(), "Array length must be a power of two");
701 let mut values: VecDeque<_> = bytes.into_iter().map(Value::u8).collect();
702
703 while values.len() > 1 {
704 let mut alt_values = VecDeque::with_capacity(values.len() / 2);
705
706 while let (Some(left), Some(right)) = (values.pop_front(), values.pop_front()) {
707 alt_values.push_back(Value::product(left, right));
708 }
709
710 values = alt_values;
711 }
712
713 values.into_iter().next().unwrap()
714 }
715
716 pub fn raw_byte_iter(&self) -> RawByteIter<'_> {
722 self.as_ref().raw_byte_iter()
723 }
724
725 pub fn iter_compact(&self) -> CompactBitsIter<'_> {
729 self.as_ref().iter_compact()
730 }
731
732 pub fn iter_padded(&self) -> PreOrderIter<'_> {
736 self.as_ref().iter_padded()
737 }
738
739 pub fn is_of_type(&self, ty: &Final) -> bool {
741 self.ty.as_ref() == ty
742 }
743
744 pub fn zero(ty: &Final) -> Self {
754 Self {
755 inner: Arc::from(vec![0; ty.bit_width().div_ceil(8)]),
756 bit_offset: 0,
757 ty: Arc::new(ty.clone()),
758 }
759 }
760
761 pub fn to_word(&self) -> Option<Word> {
765 self.ty.as_word().map(|n| Word {
766 value: self.shallow_clone(),
767 n,
768 })
769 }
770
771 pub fn prune(&self, pruned_ty: &Final) -> Option<Self> {
790 enum Task<'v, 'ty> {
791 Prune(ValueRef<'v>, &'ty Final),
792 MakeLeft(Arc<Final>),
793 MakeRight(Arc<Final>),
794 MakeProduct,
795 }
796
797 let mut stack = vec![Task::Prune(self.as_ref(), pruned_ty)];
798 let mut output = vec![];
799
800 while let Some(task) = stack.pop() {
801 match task {
802 Task::Prune(value, pruned_ty) if value.ty.as_ref() == pruned_ty => {
803 output.push(value.to_value())
804 }
805 Task::Prune(value, pruned_ty) => match pruned_ty.bound() {
806 CompleteBound::Unit => output.push(Value::unit()),
807 CompleteBound::Sum(l_ty, r_ty) => {
808 if let Some(l_value) = value.as_left() {
809 stack.push(Task::MakeLeft(Arc::clone(r_ty)));
810 stack.push(Task::Prune(l_value, l_ty));
811 } else {
812 let r_value = value.as_right()?;
813 stack.push(Task::MakeRight(Arc::clone(l_ty)));
814 stack.push(Task::Prune(r_value, r_ty));
815 }
816 }
817 CompleteBound::Product(l_ty, r_ty) => {
818 let (l_value, r_value) = value.as_product()?;
819 stack.push(Task::MakeProduct);
820 stack.push(Task::Prune(r_value, r_ty));
821 stack.push(Task::Prune(l_value, l_ty));
822 }
823 },
824 Task::MakeLeft(r_ty) => {
825 let l_value = output.pop().unwrap();
826 output.push(Value::left(l_value, r_ty));
827 }
828 Task::MakeRight(l_ty) => {
829 let r_value = output.pop().unwrap();
830 output.push(Value::right(l_ty, r_value));
831 }
832 Task::MakeProduct => {
833 let r_value = output.pop().unwrap();
834 let l_value = output.pop().unwrap();
835 output.push(Value::product(l_value, r_value));
836 }
837 }
838 }
839
840 debug_assert_eq!(output.len(), 1);
841 output.pop()
842 }
843}
844
845impl fmt::Debug for Value {
846 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
847 f.debug_struct("Value")
848 .field("value", &format_args!("{}", self))
849 .field("ty", &self.ty)
850 .field("raw_value", &self.inner)
851 .field("raw_bit_offset", &self.bit_offset)
852 .finish()
853 }
854}
855
856impl fmt::Display for Value {
857 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
858 enum S<'v> {
861 Disp(ValueRef<'v>),
862 DispCh(char),
863 }
864
865 let mut stack = Vec::with_capacity(1024);
866 stack.push(S::Disp(self.as_ref()));
868
869 'main_loop: while let Some(next) = stack.pop() {
870 let value = match next {
871 S::Disp(ref value) => value,
872 S::DispCh(ch) => {
873 write!(f, "{}", ch)?;
874 continue;
875 }
876 };
877
878 if value.is_unit() {
879 f.write_str("ε")?;
880 } else {
881 for tmr in &Tmr::TWO_TWO_N {
883 if value.ty.tmr() == *tmr {
884 if value.ty.bit_width() < 4 {
885 f.write_str("0b")?;
886 for bit in value.iter_padded() {
887 f.write_str(if bit { "1" } else { "0" })?;
888 }
889 } else {
890 f.write_str("0x")?;
891 let mut iter = value.iter_padded();
894 while let (Some(a), Some(b), Some(c), Some(d)) =
895 (iter.next(), iter.next(), iter.next(), iter.next())
896 {
897 let n = (u8::from(a) << 3)
898 + (u8::from(b) << 2)
899 + (u8::from(c) << 1)
900 + u8::from(d);
901 write!(f, "{:x}", n)?;
902 }
903 }
904 continue 'main_loop;
905 }
906 }
907
908 if let Some(l_value) = value.as_left() {
910 f.write_str("L(")?;
911 stack.push(S::DispCh(')'));
912 stack.push(S::Disp(l_value));
913 } else if let Some(r_value) = value.as_right() {
914 f.write_str("R(")?;
915 stack.push(S::DispCh(')'));
916 stack.push(S::Disp(r_value));
917 } else if let Some((l_value, r_value)) = value.as_product() {
918 stack.push(S::DispCh(')'));
919 stack.push(S::Disp(r_value));
920 stack.push(S::DispCh(','));
921 stack.push(S::Disp(l_value));
922 stack.push(S::DispCh('('));
923 } else {
924 unreachable!()
925 }
926 }
927 }
928 Ok(())
929 }
930}
931
932#[derive(Debug, Clone)]
934pub struct CompactBitsIter<'v> {
935 stack: Vec<ValueRef<'v>>,
936}
937
938impl<'v> CompactBitsIter<'v> {
939 fn new(value: ValueRef<'v>) -> Self {
941 Self { stack: vec![value] }
942 }
943}
944
945impl Iterator for CompactBitsIter<'_> {
946 type Item = bool;
947
948 fn next(&mut self) -> Option<Self::Item> {
949 while let Some(value) = self.stack.pop() {
950 if value.ty.bit_width() == 0 {
951 } else if let Some(l_value) = value.as_left() {
953 self.stack.push(l_value);
954 return Some(false);
955 } else if let Some(r_value) = value.as_right() {
956 self.stack.push(r_value);
957 return Some(true);
958 } else if let Some((l_value, r_value)) = value.as_product() {
959 self.stack.push(r_value);
960 self.stack.push(l_value);
961 }
962 }
963
964 None
965 }
966}
967
968impl Value {
969 pub fn from_compact_bits<I: Iterator<Item = u8>>(
971 bits: &mut BitIter<I>,
972 ty: &Final,
973 ) -> Result<Self, EarlyEndOfStreamError> {
974 enum State<'a> {
975 ProcessType(&'a Final),
976 DoSumL(Arc<Final>),
977 DoSumR(Arc<Final>),
978 DoProduct,
979 }
980
981 let mut stack = vec![State::ProcessType(ty)];
982 let mut result_stack = vec![];
983 while let Some(state) = stack.pop() {
984 match state {
985 State::ProcessType(ty) if ty.has_padding() => match ty.bound() {
986 CompleteBound::Unit => result_stack.push(Value::unit()),
987 CompleteBound::Sum(ref l, ref r) => {
988 if !bits.next().ok_or(EarlyEndOfStreamError)? {
989 stack.push(State::DoSumL(Arc::clone(r)));
990 stack.push(State::ProcessType(l));
991 } else {
992 stack.push(State::DoSumR(Arc::clone(l)));
993 stack.push(State::ProcessType(r));
994 }
995 }
996 CompleteBound::Product(ref l, ref r) => {
997 stack.push(State::DoProduct);
998 stack.push(State::ProcessType(r));
999 stack.push(State::ProcessType(l));
1000 }
1001 },
1002 State::ProcessType(ty) => {
1003 result_stack.push(Value::from_padded_bits(bits, ty)?);
1005 }
1006 State::DoSumL(r) => {
1007 let val = result_stack.pop().unwrap();
1008 result_stack.push(Value::left(val, r));
1009 }
1010 State::DoSumR(l) => {
1011 let val = result_stack.pop().unwrap();
1012 result_stack.push(Value::right(l, val));
1013 }
1014 State::DoProduct => {
1015 let val_r = result_stack.pop().unwrap();
1016 let val_l = result_stack.pop().unwrap();
1017 result_stack.push(Value::product(val_l, val_r));
1018 }
1019 }
1020 }
1021 debug_assert_eq!(result_stack.len(), 1);
1022 Ok(result_stack.pop().unwrap())
1023 }
1024
1025 pub fn from_padded_bits<I: Iterator<Item = u8>>(
1027 bits: &mut BitIter<I>,
1028 ty: &Final,
1029 ) -> Result<Self, EarlyEndOfStreamError> {
1030 const MAX_INITIAL_ALLOC: usize = 32 * 1024 * 1024; let cap = cmp::min(MAX_INITIAL_ALLOC, ty.bit_width().div_ceil(8));
1033 let mut blob = Vec::with_capacity(cap);
1034 for _ in 0..ty.bit_width() / 8 {
1035 blob.push(bits.read_u8()?);
1036 }
1037 let mut last = 0u8;
1038 for i in 0..ty.bit_width() % 8 {
1039 if bits.read_bit()? {
1040 last |= 1 << (7 - i);
1041 }
1042 }
1043 blob.push(last);
1044
1045 Ok(Value {
1046 inner: blob.into(),
1047 bit_offset: 0,
1048 ty: Arc::new(ty.clone()),
1049 })
1050 }
1051}
1052
1053#[derive(Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
1055pub struct Word {
1056 value: Value,
1058 n: u8,
1060}
1061
1062macro_rules! construct_word_fallible {
1063 ($name: ident, $n: expr, $text: expr) => {
1064 #[doc = "Create"]
1065 #[doc = $text]
1066 #[doc = "word.\n\n"]
1067 #[doc = "## Panics\n"]
1068 #[doc = "The value is ouf of range."]
1069 pub fn $name(bit: u8) -> Self {
1070 Self {
1071 value: Value::$name(bit),
1072 n: $n,
1073 }
1074 }
1075 };
1076}
1077
1078macro_rules! construct_word {
1079 ($name: ident, $ty: ty, $n: expr, $text: expr) => {
1080 #[doc = "Create"]
1081 #[doc = $text]
1082 #[doc = "word."]
1083 pub fn $name(bit: $ty) -> Self {
1084 Self {
1085 value: Value::$name(bit),
1086 n: $n,
1087 }
1088 }
1089 };
1090}
1091
1092impl Word {
1093 pub fn product(self, right: Self) -> Option<Self> {
1103 if self.n == right.n && self.n < 30 {
1104 Some(Self {
1105 value: Value::product(self.value, right.value),
1106 n: self.n + 1,
1107 })
1108 } else {
1109 None
1110 }
1111 }
1112
1113 construct_word_fallible!(u1, 0, "a 1-bit");
1114 construct_word_fallible!(u2, 1, "a 2-bit");
1115 construct_word_fallible!(u4, 2, "a 4-bit");
1116 construct_word!(u8, u8, 3, "an 8-bit");
1117 construct_word!(u16, u16, 4, "a 16-bit");
1118 construct_word!(u32, u32, 5, "a 32-bit");
1119 construct_word!(u64, u64, 6, "a 64-bit");
1120 construct_word!(u128, u128, 7, "a 128-bit");
1121 construct_word!(u256, [u8; 32], 8, "a 256-bit");
1122 construct_word!(u512, [u8; 64], 9, "a 512-bit");
1123
1124 pub fn shallow_clone(&self) -> Self {
1126 Self {
1127 value: self.value.shallow_clone(),
1128 n: self.n,
1129 }
1130 }
1131
1132 pub fn as_value(&self) -> &Value {
1134 &self.value
1135 }
1136
1137 pub fn n(&self) -> usize {
1139 usize::from(self.n)
1140 }
1141
1142 #[allow(clippy::len_without_is_empty)]
1146 pub fn len(&self) -> usize {
1147 2usize.pow(u32::from(self.n))
1148 }
1149
1150 pub fn iter(&self) -> impl Iterator<Item = bool> + '_ {
1155 self.value.iter_compact()
1156 }
1157
1158 pub fn from_bits<I: Iterator<Item = u8>>(
1164 bits: &mut BitIter<I>,
1165 n: u32,
1166 ) -> Result<Self, EarlyEndOfStreamError> {
1167 let n8 = u8::try_from(n).unwrap_or(u8::MAX); let Ok(ty) = Final::two_two_n(usize::from(n8)) else {
1169 panic!("TWO^(2^{n}) is not supported as a word type");
1170 };
1171 let value = Value::from_compact_bits(bits, &ty)?;
1172 Ok(Self { value, n: n8 })
1173 }
1174}
1175
1176impl fmt::Debug for Word {
1177 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1178 fmt::Display::fmt(self, f)
1179 }
1180}
1181
1182impl fmt::Display for Word {
1183 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1184 use hex::DisplayHex;
1185
1186 if let Ok(hex) = self.iter().try_collect_bytes() {
1187 write!(f, "0x{}", hex.as_hex())
1188 } else {
1189 f.write_str("0b")?;
1190 for bit in self.iter() {
1191 match bit {
1192 false => f.write_str("0")?,
1193 true => f.write_str("1")?,
1194 }
1195 }
1196 Ok(())
1197 }
1198 }
1199}
1200
1201#[derive(Clone, PartialEq, Eq, Debug)]
1203pub enum Buffer8Error {
1204 NTooLarge(crate::types::TypeTooLargeError),
1205 SliceTooLarge { length: usize, n: usize },
1206}
1207
1208impl fmt::Display for Buffer8Error {
1209 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1210 match *self {
1211 Self::NTooLarge(_) => f.write_str("failed to construct (sub)type of buffer"),
1212 Self::SliceTooLarge { length, n } => write!(
1213 f,
1214 "slice of length {} too long for type (TWO^8)^<2^({}+1) (maximum {})",
1215 length,
1216 n,
1217 (1 << (n + 1)) - 1,
1218 ),
1219 }
1220 }
1221}
1222
1223impl std::error::Error for Buffer8Error {
1224 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1225 match *self {
1226 Self::NTooLarge(ref e) => Some(e),
1227 Self::SliceTooLarge { .. } => None,
1228 }
1229 }
1230}
1231
1232#[cfg(test)]
1233mod tests {
1234 use super::*;
1235 use crate::bit_encoding::{BitCollector as _, BitIter};
1236 use crate::jet::type_name::TypeName;
1237
1238 #[test]
1239 fn value_len() {
1240 let v = Value::u4(6);
1241 let s_v = Value::some(v.shallow_clone());
1242 let n_v = Value::none(Final::two_two_n_fixed::<2>());
1243
1244 assert_eq!(v.compact_len(), 4);
1245 assert_eq!(v.padded_len(), 4);
1246 assert_eq!(s_v.compact_len(), 5);
1247 assert_eq!(s_v.padded_len(), 5);
1248 assert_eq!(n_v.compact_len(), 1);
1249 assert_eq!(n_v.padded_len(), 5);
1250 }
1251
1252 #[test]
1253 fn value_display() {
1254 assert_eq!(Value::u1(0).to_string(), "0b0",);
1257 assert_eq!(Value::u1(1).to_string(), "0b1",);
1258 assert_eq!(Value::u4(6).to_string(), "0x6",);
1259 }
1260
1261 #[test]
1262 fn is_of_type() {
1263 let value_typename = [
1264 (Value::unit(), TypeName(b"1")),
1265 (Value::left(Value::unit(), Final::unit()), TypeName(b"+11")),
1266 (Value::right(Final::unit(), Value::unit()), TypeName(b"+11")),
1267 (
1268 Value::left(Value::unit(), Final::two_two_n_fixed::<8>()),
1269 TypeName(b"+1h"),
1270 ),
1271 (
1272 Value::right(Final::two_two_n_fixed::<8>(), Value::unit()),
1273 TypeName(b"+h1"),
1274 ),
1275 (
1276 Value::product(Value::unit(), Value::unit()),
1277 TypeName(b"*11"),
1278 ),
1279 (Value::u8(u8::MAX), TypeName(b"c")),
1280 (Value::u64(u64::MAX), TypeName(b"l")),
1281 ];
1282
1283 for (value, typename) in value_typename {
1284 let ty = typename.to_final();
1285 assert!(value.is_of_type(ty.as_ref()));
1286 }
1287 }
1288
1289 #[test]
1290 fn prune_regression_1() {
1291 let nontrivial_sum = Value::product(
1293 Value::right(Final::two_two_n_fixed::<4>(), Value::u16(0)),
1294 Value::u8(0),
1295 );
1296 let _ = format!("{nontrivial_sum}");
1298 assert_eq!(
1300 nontrivial_sum.prune(nontrivial_sum.ty()),
1301 Some(nontrivial_sum)
1302 );
1303 }
1304
1305 #[test]
1306 fn prune() {
1307 let test_vectors = [
1308 (Value::unit(), Value::unit()),
1309 (Value::u64(42), Value::unit()),
1310 (
1311 Value::left(Value::u64(42), Final::u64()),
1312 Value::left(Value::u64(42), Final::unit()),
1313 ),
1314 (
1315 Value::right(Final::u64(), Value::u64(1337)),
1316 Value::right(Final::unit(), Value::u64(1337)),
1317 ),
1318 (
1319 Value::product(Value::u64(42), Value::u64(1337)),
1320 Value::product(Value::u64(42), Value::unit()),
1321 ),
1322 (
1323 Value::product(Value::u64(42), Value::u64(1337)),
1324 Value::product(Value::unit(), Value::u64(1337)),
1325 ),
1326 ];
1327
1328 for (value, expected_pruned_value) in test_vectors {
1329 assert_eq!(
1330 value.prune(expected_pruned_value.ty()),
1331 Some(expected_pruned_value)
1332 );
1333 }
1334
1335 let bad_test_vectors = [
1336 (Value::unit(), Final::u1()),
1337 (
1338 Value::product(Value::unit(), Value::unit()),
1339 Final::sum(Final::unit(), Final::unit()),
1340 ),
1341 (
1342 Value::left(Value::unit(), Final::unit()),
1343 Final::product(Final::unit(), Final::unit()),
1344 ),
1345 (
1346 Value::right(Final::unit(), Value::unit()),
1347 Final::product(Final::unit(), Final::unit()),
1348 ),
1349 ];
1350
1351 for (value, pruned_ty) in bad_test_vectors {
1352 assert_eq!(value.prune(&pruned_ty), None);
1353 }
1354 }
1355
1356 #[test]
1357 fn zero_value() {
1358 let test_vectors = [
1359 (Final::unit(), Value::unit()),
1360 (Final::u8(), Value::u8(0)),
1361 (Final::u64(), Value::u64(0)),
1362 (
1363 Final::product(Final::u16(), Final::u32()),
1364 Value::product(Value::u16(0), Value::u32(0)),
1365 ),
1366 (
1367 Final::sum(Final::unit(), Final::u64()),
1368 Value::left(Value::unit(), Final::u64()),
1369 ),
1370 (
1371 Final::product(Final::unit(), Final::unit()),
1372 Value::product(Value::unit(), Value::unit()),
1373 ),
1374 ];
1375
1376 for (ty, expected_default_value) in test_vectors {
1377 assert_eq!(Value::zero(&ty), expected_default_value);
1378 }
1379 }
1380
1381 #[test]
1382 fn compact_round_trip() {
1383 let v = Value::u64(0xff00_00ff_ff00_00ff);
1384 let (bits, _) = v.iter_compact().collect_bits();
1385 let mut iter = BitIter::new(bits.into_iter());
1386 let new_v = Value::from_compact_bits(&mut iter, &v.ty).unwrap();
1387 assert_eq!(v, new_v);
1388 }
1389
1390 #[test]
1391 fn padded_round_trip() {
1392 let v = Value::u64(0xff00_00ff_ff00_00ff);
1393 let (bits, _) = v.iter_padded().collect_bits();
1394 let mut iter = BitIter::new(bits.into_iter());
1395 let new_v = Value::from_padded_bits(&mut iter, &v.ty).unwrap();
1396 assert_eq!(v, new_v);
1397 }
1398
1399 #[test]
1424 fn left_tag_not_corrupted_by_dirty_buffer() {
1425 let product_val = Value::product(
1426 Value::right(Final::u1(), Value::u1(1)), Value::right(Final::u1(), Value::u1(0)), );
1429
1430 let (_, right_sub) = product_val.as_product().unwrap();
1431 let right_sub_owned = right_sub.to_value();
1433
1434 let left_val = Value::left(right_sub_owned, Final::unit());
1435
1436 assert!(
1437 left_val.as_left().is_some(),
1438 "BUG: Left tag corrupted — right_shift_1(false) did not clear dirty bit; \
1439 value reads as Right instead of Left"
1440 );
1441 assert!(
1442 left_val.as_right().is_none(),
1443 "BUG: Left tag corrupted — as_right() should return None for a Left value"
1444 );
1445 }
1446
1447 #[test]
1450 fn left_tag_first_padded_bit_is_zero() {
1451 let product_val = Value::product(
1452 Value::right(Final::u1(), Value::u1(1)),
1453 Value::right(Final::u1(), Value::u1(0)),
1454 );
1455
1456 let (_, right_sub) = product_val.as_product().unwrap();
1457 let left_val = Value::left(right_sub.to_value(), Final::unit());
1458
1459 let first_bit = left_val.iter_padded().next();
1460 assert_eq!(
1461 first_bit,
1462 Some(false),
1463 "BUG: first padded bit of Left value is {:?}, expected Some(false)",
1464 first_bit
1465 );
1466 }
1467
1468 #[test]
1482 fn prune_does_not_corrupt_left_tag_via_shared_buffer() {
1483 let original = Value::left(
1484 Value::product(
1485 Value::right(Final::u1(), Value::u1(1)),
1486 Value::right(Final::u1(), Value::u1(0)),
1487 ),
1488 Final::unit(),
1489 );
1490
1491 let pruned_ty = Final::sum(
1495 Final::product(Final::unit(), Final::sum(Final::u1(), Final::u1())),
1496 Final::unit(),
1497 );
1498
1499 let pruned = original
1500 .prune(&pruned_ty)
1501 .expect("prune returned None; the target type is compatible");
1502
1503 assert!(
1504 pruned.as_left().is_some(),
1505 "BUG: prune corrupted the Left tag — right_shift_1(false) did not clear \
1506 a dirty bit from the shared product buffer; value reads as Right"
1507 );
1508 }
1509
1510 #[test]
1511 fn buffer8_two_n_plus_one() {
1512 assert_eq!(
1514 Value::buffer8_two_n_plus_one(0, &[]).unwrap(),
1515 Value::none(Final::two_two_n_fixed::<3>()),
1516 );
1517 assert_eq!(
1518 Value::buffer8_two_n_plus_one(0, &[3]).unwrap(),
1519 Value::some(Value::u8(3)),
1520 );
1521 assert_eq!(
1523 Value::buffer8_two_n_plus_one(1, &[]).unwrap(),
1524 Value::product(
1525 Value::none(Final::two_two_n_fixed::<4>()),
1526 Value::none(Final::two_two_n_fixed::<3>()),
1527 ),
1528 );
1529 assert_eq!(
1530 Value::buffer8_two_n_plus_one(1, &[0x99]).unwrap(),
1531 Value::product(
1532 Value::none(Final::two_two_n_fixed::<4>()),
1533 Value::some(Value::u8(0x99)),
1534 ),
1535 );
1536 assert_eq!(
1537 Value::buffer8_two_n_plus_one(1, &[0x12, 0x34]).unwrap(),
1538 Value::product(
1539 Value::some(Value::u16(0x1234)),
1540 Value::none(Final::two_two_n_fixed::<3>()),
1541 ),
1542 );
1543 assert_eq!(
1544 Value::buffer8_two_n_plus_one(1, &[0x12, 0x34, 0xff]).unwrap(),
1545 Value::product(
1546 Value::some(Value::u16(0x1234)),
1547 Value::some(Value::u8(0xff)),
1548 ),
1549 );
1550
1551 let sample: [u8; 49] = *b"there are strange things done in the midnight sun";
1553 Value::buffer8_two_n_plus_one(0, &sample).unwrap_err();
1554 Value::buffer8_two_n_plus_one(4, &sample).unwrap_err();
1555 assert_eq!(
1556 Value::buffer8_two_n_plus_one(5, &sample).unwrap(),
1557 Value::product(
1558 Value::some(Value::from_byte_array(*b"there are strange things done in")),
1559 Value::product(
1560 Value::some(Value::from_byte_array(*b" the midnight su")),
1561 Value::product(
1562 Value::none(Final::two_two_n_fixed::<6>()),
1563 Value::product(
1564 Value::none(Final::two_two_n_fixed::<5>()),
1565 Value::product(
1566 Value::none(Final::two_two_n_fixed::<4>()),
1567 Value::some(Value::u8(b'n')),
1568 ),
1569 ),
1570 ),
1571 ),
1572 ),
1573 );
1574 }
1575}
1576
1577#[cfg(bench)]
1578mod benches {
1579 use super::*;
1580
1581 use crate::bit_encoding::{BitCollector as _, BitIter};
1582
1583 use test::{black_box, Bencher};
1584
1585 #[bench]
1587 fn bench_value_create_u64(bh: &mut Bencher) {
1588 bh.iter(|| black_box(Value::u64(0xff00_00ff_ff00_00ff)))
1589 }
1590
1591 #[bench]
1592 fn bench_value_create_u2048(bh: &mut Bencher) {
1593 bh.iter(|| black_box(Value::from_byte_array([0xcd; 2048])));
1594 }
1595
1596 #[bench]
1597 fn bench_value_create_deep_some(bh: &mut Bencher) {
1598 bh.iter(|| {
1599 let mut kilo = Value::from_byte_array([0xab; 1024]);
1600 for _ in 0..1000 {
1601 kilo = Value::some(kilo.shallow_clone());
1602 }
1603 black_box(kilo)
1604 });
1605 }
1606
1607 #[bench]
1608 fn bench_value_create_64k(bh: &mut Bencher) {
1609 bh.iter(|| {
1610 let mut kilo = Value::from_byte_array([0xab; 1024]);
1611 for _ in 0..5 {
1612 kilo = Value::product(kilo.shallow_clone(), kilo.shallow_clone());
1613 }
1614 black_box(kilo)
1615 });
1616 }
1617
1618 #[bench]
1619 fn bench_value_create_512_256(bh: &mut Bencher) {
1620 bh.iter(|| {
1621 let mut s512_256 = Value::product(
1630 Value::from_byte_array([0x12; 64]),
1631 Value::from_byte_array([0x23; 32]),
1632 );
1633 for _ in 0..5 {
1634 s512_256 = Value::product(s512_256.shallow_clone(), s512_256.shallow_clone());
1635 }
1636 black_box(s512_256);
1637 });
1638 }
1639
1640 fn padded_bits(v: &Value) -> (Vec<u8>, &Final) {
1642 let (bits, _) = v.iter_padded().collect_bits();
1643 (bits, v.ty.as_ref())
1644 }
1645
1646 #[bench]
1647 fn bench_value_create_u64_padded(bh: &mut Bencher) {
1648 let v = Value::u64(0xff00_00ff_ff00_00ff);
1649 let (bits, ty) = padded_bits(&v);
1650 bh.iter(|| {
1651 black_box(Value::from_padded_bits(
1652 &mut BitIter::new(bits.iter().copied()),
1653 ty,
1654 ))
1655 })
1656 }
1657
1658 #[bench]
1659 fn bench_value_create_u2048_padded(bh: &mut Bencher) {
1660 let v = Value::from_byte_array([0xcd; 2048]);
1661 let (bits, ty) = padded_bits(&v);
1662 bh.iter(|| {
1663 black_box(Value::from_padded_bits(
1664 &mut BitIter::new(bits.iter().copied()),
1665 ty,
1666 ))
1667 })
1668 }
1669
1670 #[bench]
1671 fn bench_value_create_deep_some_padded(bh: &mut Bencher) {
1672 let mut kilo = Value::from_byte_array([0xab; 1024]);
1673 for _ in 0..1000 {
1674 kilo = Value::some(kilo.shallow_clone());
1675 }
1676 let (bits, ty) = padded_bits(&kilo);
1677 bh.iter(|| {
1678 black_box(Value::from_padded_bits(
1679 &mut BitIter::new(bits.iter().copied()),
1680 ty,
1681 ))
1682 })
1683 }
1684
1685 #[bench]
1686 fn bench_value_create_64k_padded(bh: &mut Bencher) {
1687 let mut kilo = Value::from_byte_array([0xab; 1024]);
1688 for _ in 0..5 {
1689 kilo = Value::product(kilo.shallow_clone(), kilo.shallow_clone());
1690 }
1691 let (bits, ty) = padded_bits(&kilo);
1692 bh.iter(|| {
1693 black_box(Value::from_padded_bits(
1694 &mut BitIter::new(bits.iter().copied()),
1695 ty,
1696 ))
1697 })
1698 }
1699
1700 #[bench]
1701 fn bench_value_create_512_256_padded(bh: &mut Bencher) {
1702 let mut s512_256 = Value::product(
1704 Value::from_byte_array([0x12; 64]),
1705 Value::from_byte_array([0x23; 32]),
1706 );
1707 for _ in 0..5 {
1708 s512_256 = Value::product(s512_256.shallow_clone(), s512_256.shallow_clone());
1709 }
1710 let (bits, ty) = padded_bits(&s512_256);
1711 bh.iter(|| {
1712 black_box(Value::from_padded_bits(
1713 &mut BitIter::new(bits.iter().copied()),
1714 ty,
1715 ))
1716 })
1717 }
1718
1719 fn compact_bits(v: &Value) -> (Vec<u8>, &Final) {
1721 let (bits, _) = v.iter_compact().collect_bits();
1722 (bits, v.ty.as_ref())
1723 }
1724
1725 #[bench]
1726 fn bench_value_create_u64_compact(bh: &mut Bencher) {
1727 let v = Value::u64(0xff00_00ff_ff00_00ff);
1728 let (bits, ty) = compact_bits(&v);
1729 bh.iter(|| {
1730 black_box(Value::from_compact_bits(
1731 &mut BitIter::new(bits.iter().copied()),
1732 ty,
1733 ))
1734 })
1735 }
1736
1737 #[bench]
1738 fn bench_value_create_u2048_compact(bh: &mut Bencher) {
1739 let v = Value::from_byte_array([0xcd; 2048]);
1740 let (bits, ty) = compact_bits(&v);
1741 bh.iter(|| {
1742 black_box(Value::from_compact_bits(
1743 &mut BitIter::new(bits.iter().copied()),
1744 ty,
1745 ))
1746 })
1747 }
1748
1749 #[bench]
1750 fn bench_value_create_deep_some_compact(bh: &mut Bencher) {
1751 let mut kilo = Value::from_byte_array([0xab; 1024]);
1752 for _ in 0..1000 {
1753 kilo = Value::some(kilo.shallow_clone());
1754 }
1755 let (bits, ty) = compact_bits(&kilo);
1756 bh.iter(|| {
1757 black_box(Value::from_compact_bits(
1758 &mut BitIter::new(bits.iter().copied()),
1759 ty,
1760 ))
1761 })
1762 }
1763
1764 #[bench]
1765 fn bench_value_create_64k_compact(bh: &mut Bencher) {
1766 let mut kilo = Value::from_byte_array([0xab; 1024]);
1767 for _ in 0..5 {
1768 kilo = Value::product(kilo.shallow_clone(), kilo.shallow_clone());
1769 }
1770 let (bits, ty) = compact_bits(&kilo);
1771 bh.iter(|| {
1772 black_box(Value::from_compact_bits(
1773 &mut BitIter::new(bits.iter().copied()),
1774 ty,
1775 ))
1776 })
1777 }
1778
1779 #[bench]
1780 fn bench_value_create_512_256_compact(bh: &mut Bencher) {
1781 let mut s512_256 = Value::product(
1783 Value::from_byte_array([0x12; 64]),
1784 Value::from_byte_array([0x23; 32]),
1785 );
1786 for _ in 0..5 {
1787 s512_256 = Value::product(s512_256.shallow_clone(), s512_256.shallow_clone());
1788 }
1789 let (bits, ty) = compact_bits(&s512_256);
1790 bh.iter(|| {
1791 black_box(Value::from_compact_bits(
1792 &mut BitIter::new(bits.iter().copied()),
1793 ty,
1794 ))
1795 })
1796 }
1797
1798 #[bench]
1800 fn bench_value_display_u64(bh: &mut Bencher) {
1801 let v = Value::u64(0xff00_00ff_ff00_00ff);
1802 bh.iter(|| black_box(format!("{}", v)))
1803 }
1804
1805 #[bench]
1806 fn bench_value_display_u2024(bh: &mut Bencher) {
1807 let v = Value::from_byte_array([0xcd; 2048]);
1808 bh.iter(|| black_box(format!("{}", v)))
1809 }
1810
1811 #[bench]
1812 fn bench_value_display_deep_some(bh: &mut Bencher) {
1813 let mut kilo = Value::from_byte_array([0xab; 1024]);
1814 for _ in 0..1000 {
1815 kilo = Value::some(kilo.shallow_clone());
1816 }
1817 bh.iter(|| black_box(format!("{}", kilo)))
1818 }
1819
1820 #[bench]
1821 fn bench_value_display_64k(bh: &mut Bencher) {
1822 let mut kilo = Value::from_byte_array([0xab; 1024]);
1823 for _ in 0..5 {
1824 kilo = Value::product(kilo.shallow_clone(), kilo.shallow_clone());
1825 }
1826 bh.iter(|| black_box(format!("{}", kilo)))
1827 }
1828
1829 #[bench]
1830 fn bench_value_display_512_256(bh: &mut Bencher) {
1831 let mut s512_256 = Value::product(
1833 Value::from_byte_array([0x12; 64]),
1834 Value::from_byte_array([0x23; 32]),
1835 );
1836 for _ in 0..5 {
1837 s512_256 = Value::product(s512_256.shallow_clone(), s512_256.shallow_clone());
1838 }
1839 bh.iter(|| black_box(format!("{}", s512_256)))
1840 }
1841
1842 }