1use std::{
19 collections::VecDeque,
20 mem::ManuallyDrop,
21 ops::{Deref, DerefMut},
22 sync::{Arc, Mutex},
23};
24
25#[derive(Debug)]
27pub struct ObjectPool<T> {
28 queue: Mutex<VecDeque<T>>,
30
31 capacity: Option<usize>,
34}
35
36impl<T> ObjectPool<T> {
37 pub fn new<A>(args: A, initial_size: usize, capacity: Option<usize>) -> Self
44 where
45 T: AsPooled<A>,
46 A: Clone,
47 {
48 let queue = (0..initial_size).map(|_| T::create(args.clone())).collect();
49
50 Self {
51 queue: Mutex::new(queue),
52 capacity,
53 }
54 }
55
56 pub fn with_capacity(capacity: Option<usize>) -> Self {
58 Self {
59 queue: Mutex::new(VecDeque::with_capacity(capacity.unwrap_or(0))),
60 capacity,
61 }
62 }
63
64 pub fn try_new<A>(
71 args: A,
72 initial_size: usize,
73 capacity: Option<usize>,
74 ) -> Result<Self, T::Error>
75 where
76 T: TryAsPooled<A>,
77 A: Clone,
78 {
79 let queue = (0..initial_size)
80 .map(|_| T::try_create(args.clone()))
81 .collect::<Result<_, _>>()?;
82 Ok(Self {
83 queue: Mutex::new(queue),
84 capacity,
85 })
86 }
87
88 pub fn try_get_ref<A>(&self, args: A) -> Result<PooledRef<'_, T>, T::Error>
95 where
96 T: TryAsPooled<A>,
97 {
98 let item = self.try_get_or_create(args)?;
99 Ok(PooledRef {
100 item: ManuallyDrop::new(item),
101 parent: self,
102 })
103 }
104
105 pub fn get_ref<A>(&self, args: A) -> PooledRef<'_, T>
114 where
115 T: AsPooled<A>,
116 {
117 let item = self.get_or_create(args);
118 PooledRef {
119 item: ManuallyDrop::new(item),
120 parent: self,
121 }
122 }
123
124 pub fn try_get<A>(self: &Arc<Self>, args: A) -> Result<PooledArc<T>, T::Error>
131 where
132 T: TryAsPooled<A>,
133 {
134 let item = self.try_get_or_create(args)?;
135 Ok(PooledArc {
136 item: ManuallyDrop::new(item),
137 parent: self.clone(),
138 })
139 }
140
141 pub fn get<A>(self: &Arc<Self>, args: A) -> PooledArc<T>
150 where
151 T: AsPooled<A>,
152 {
153 let item = self.get_or_create(args);
154 PooledArc {
155 item: ManuallyDrop::new(item),
156 parent: self.clone(),
157 }
158 }
159
160 pub fn len(&self) -> usize {
162 self.lock().len()
163 }
164
165 pub fn is_empty(&self) -> bool {
167 self.len() == 0
168 }
169
170 fn try_get_or_create<A>(&self, args: A) -> Result<T, T::Error>
175 where
176 T: TryAsPooled<A>,
177 {
178 let maybe = self.lock().pop_front();
182 if let Some(mut item) = maybe {
183 item.try_modify(args)?;
184 Ok(item)
185 } else {
186 T::try_create(args)
187 }
188 }
189
190 fn get_or_create<A>(&self, args: A) -> T
191 where
192 T: AsPooled<A>,
193 {
194 let maybe = self.lock().pop_front();
198 if let Some(mut item) = maybe {
199 item.modify(args);
200 item
201 } else {
202 T::create(args)
203 }
204 }
205
206 fn lock(&self) -> std::sync::MutexGuard<'_, VecDeque<T>> {
207 match self.queue.lock() {
208 Ok(guard) => guard,
209 Err(poisoned) => {
210 self.queue.clear_poison();
220 poisoned.into_inner()
221 }
222 }
223 }
224}
225
226pub trait TryAsPooled<A>
233where
234 Self: Sized,
235{
236 type Error;
238
239 fn try_create(args: A) -> Result<Self, Self::Error>;
241
242 fn try_modify(&mut self, args: A) -> Result<(), Self::Error>;
251}
252
253pub trait AsPooled<A> {
259 fn create(args: A) -> Self;
261
262 fn modify(&mut self, args: A);
271}
272
273#[derive(Debug, Clone, Copy)]
281pub struct Undef {
282 pub len: usize,
283}
284
285impl Undef {
286 pub fn new(len: usize) -> Self {
288 Self { len }
289 }
290}
291
292impl<T> AsPooled<Undef> for Vec<T>
293where
294 T: Default + Clone,
295{
296 fn create(undef: Undef) -> Self {
297 vec![T::default(); undef.len]
298 }
299
300 fn modify(&mut self, undef: Undef) {
301 self.resize(undef.len, T::default())
302 }
303}
304
305#[derive(Debug)]
309pub struct PooledRef<'a, T> {
310 item: ManuallyDrop<T>,
311 parent: &'a ObjectPool<T>,
312}
313
314impl<T> Drop for PooledRef<'_, T> {
315 fn drop(&mut self) {
316 let mut guard = self.parent.lock();
317 if guard.len() < self.parent.capacity.unwrap_or(usize::MAX) {
318 guard.push_back(unsafe { ManuallyDrop::take(&mut self.item) });
320 } else {
321 std::mem::drop(guard);
323
324 unsafe { ManuallyDrop::drop(&mut self.item) };
326 }
327 }
328}
329
330impl<T> Deref for PooledRef<'_, T> {
331 type Target = T;
332
333 fn deref(&self) -> &Self::Target {
334 &self.item
335 }
336}
337
338impl<T> DerefMut for PooledRef<'_, T> {
339 fn deref_mut(&mut self) -> &mut Self::Target {
340 &mut self.item
341 }
342}
343
344#[derive(Debug)]
350pub struct PooledArc<T> {
351 item: ManuallyDrop<T>,
352 parent: Arc<ObjectPool<T>>,
353}
354
355impl<T> Drop for PooledArc<T> {
356 fn drop(&mut self) {
357 let mut guard = self.parent.lock();
358 if guard.len() < self.parent.capacity.unwrap_or(usize::MAX) {
359 guard.push_back(unsafe { ManuallyDrop::take(&mut self.item) });
361 } else {
362 std::mem::drop(guard);
364
365 unsafe { ManuallyDrop::drop(&mut self.item) };
367 }
368 }
369}
370
371impl<T> Deref for PooledArc<T> {
372 type Target = T;
373
374 fn deref(&self) -> &Self::Target {
375 &self.item
376 }
377}
378
379impl<T> DerefMut for PooledArc<T> {
380 fn deref_mut(&mut self) -> &mut Self::Target {
381 &mut self.item
382 }
383}
384
385#[derive(Debug)]
388pub enum PoolOption<T> {
389 NonPooled(T),
390 Pooled(PooledArc<T>),
391}
392
393impl<T> PoolOption<T> {
394 pub fn non_pooled(item: T) -> Self {
395 PoolOption::NonPooled(item)
396 }
397
398 pub fn try_non_pooled_create<A>(args: A) -> Result<Self, T::Error>
399 where
400 T: TryAsPooled<A>,
401 {
402 Ok(PoolOption::NonPooled(T::try_create(args)?))
403 }
404
405 pub fn non_pooled_create<A>(args: A) -> Self
406 where
407 T: AsPooled<A>,
408 {
409 PoolOption::NonPooled(T::create(args))
410 }
411
412 pub fn pooled<A>(pool: &Arc<ObjectPool<T>>, args: A) -> Self
413 where
414 T: AsPooled<A>,
415 {
416 PoolOption::Pooled(pool.get(args))
417 }
418
419 pub fn try_pooled<A>(pool: &Arc<ObjectPool<T>>, args: A) -> Result<Self, T::Error>
420 where
421 T: TryAsPooled<A>,
422 {
423 Ok(PoolOption::Pooled(pool.try_get(args)?))
424 }
425
426 pub fn is_pooled(&self) -> bool {
427 matches!(self, PoolOption::Pooled(_))
428 }
429
430 pub fn is_non_pooled(&self) -> bool {
431 matches!(self, PoolOption::NonPooled(_))
432 }
433}
434
435impl<T> Deref for PoolOption<T> {
436 type Target = T;
437
438 fn deref(&self) -> &Self::Target {
439 match self {
440 PoolOption::NonPooled(item) => item,
441 PoolOption::Pooled(item) => item,
442 }
443 }
444}
445
446impl<T> DerefMut for PoolOption<T> {
447 fn deref_mut(&mut self) -> &mut Self::Target {
448 match self {
449 PoolOption::NonPooled(item) => item,
450 PoolOption::Pooled(item) => item,
451 }
452 }
453}
454
455#[cfg(test)]
460mod tests {
461 use super::*;
462
463 use crate::assert_contains;
464
465 #[derive(Debug)]
466 struct TestItem {
467 value: Box<u32>,
468 panic_on_drop: bool,
469 }
470
471 impl TestItem {
472 fn new(value: u32) -> Self {
473 Self {
474 value: Box::new(value),
475 panic_on_drop: false,
476 }
477 }
478 }
479
480 impl AsPooled<u32> for TestItem {
481 fn create(value: u32) -> Self {
482 TestItem::new(value)
483 }
484
485 fn modify(&mut self, value: u32) {
486 *self.value = value;
487 self.panic_on_drop = false;
488 }
489 }
490
491 impl TryAsPooled<i32> for TestItem {
492 type Error = ();
493
494 fn try_create(value: i32) -> Result<Self, Self::Error> {
495 match value.try_into() {
496 Ok(v) => Ok(TestItem::new(v)),
497 Err(_) => Err(()),
498 }
499 }
500
501 fn try_modify(&mut self, value: i32) -> Result<(), Self::Error> {
502 match value.try_into() {
503 Ok(v) => {
504 *self.value = v;
505 self.panic_on_drop = false;
506 Ok(())
507 }
508 Err(_) => Err(()),
509 }
510 }
511 }
512
513 impl Drop for TestItem {
514 fn drop(&mut self) {
515 if self.panic_on_drop {
516 panic!("panicking on drop");
517 }
518 }
519 }
520
521 struct TestPanic;
523
524 impl AsPooled<TestPanic> for TestItem {
525 fn create(_: TestPanic) -> Self {
526 panic!("panicking on create")
527 }
528
529 fn modify(&mut self, _: TestPanic) {
530 panic!("panicking on modify")
531 }
532 }
533
534 impl TryAsPooled<TestPanic> for TestItem {
535 type Error = ();
536
537 fn try_create(_: TestPanic) -> Result<Self, Self::Error> {
538 panic!("panicking on try_create")
539 }
540
541 fn try_modify(&mut self, _: TestPanic) -> Result<(), Self::Error> {
542 panic!("panicking on try_modify")
543 }
544 }
545
546 #[test]
547 fn test_pool_basic_tests() {
548 let pool = ObjectPool::<TestItem>::new(42, 2, None);
549 assert_eq!(pool.len(), 2);
550
551 let item1 = pool.get_ref(100);
552 assert_eq!(*item1.value, 100);
553 assert_eq!(pool.len(), 1);
554
555 let item2 = pool.get_ref(200);
556 assert_eq!(*item2.value, 200);
557 assert_eq!(pool.len(), 0);
558
559 let item = pool.get_ref(300);
560 assert_eq!(*item.value, 300);
561 assert_eq!(pool.len(), 0);
562 {
563 let item = pool.get_ref(400);
564 assert_eq!(*item.value, 400);
565 assert_eq!(pool.len(), 0);
566 }
567 assert_eq!(pool.len(), 1); {
569 let item_a = pool.get_ref(500);
570 assert_eq!(*item_a.value, 500);
571 assert_eq!(pool.len(), 0); let item_b = pool.get_ref(600);
573 assert_eq!(*item_b.value, 600);
574 assert_eq!(pool.len(), 0); }
576 assert_eq!(pool.len(), 2); let pool = ObjectPool::<TestItem>::new(42, 1, None);
579 let item = pool.get_ref(100);
580 assert_eq!(*item.value, 100);
581 }
582
583 #[test]
584 fn test_pool_with_capacity() {
585 let pool = ObjectPool::<TestItem>::with_capacity(Some(4));
586 assert!(pool.is_empty());
587
588 let _ = pool.get_ref(100);
589 assert_eq!(pool.len(), 1);
590
591 {
592 let _v0 = pool.get_ref(100);
593 let _v1 = pool.get_ref(100);
594 }
595 assert_eq!(pool.len(), 2);
596
597 {
598 let _v0 = pool.get_ref(100);
599 let _v1 = pool.get_ref(100);
600 let _v2 = pool.get_ref(100);
601 let _v3 = pool.get_ref(100);
602 let _v4 = pool.get_ref(100);
603 let _v5 = pool.get_ref(100);
604 }
605 assert_eq!(
606 pool.len(),
607 4,
608 "pool should max out at the requested capacity."
609 );
610 }
611
612 #[test]
613 fn test_pool_basic_tests_with_try() {
614 let pool_result = ObjectPool::<TestItem>::try_new(-1, 2, Some(100));
616 assert!(
617 pool_result.is_err(),
618 "Pool creation should fail with negative args"
619 );
620
621 let pool = ObjectPool::<TestItem>::try_new(42, 2, None).unwrap();
622 assert_eq!(pool.len(), 2);
623 let item1 = pool.try_get_ref(100).unwrap();
624 assert_eq!(*item1.value, 100);
625 assert_eq!(pool.len(), 1);
626 let item2 = pool.try_get_ref(200).unwrap();
627 assert_eq!(*item2.value, 200);
628 assert_eq!(pool.len(), 0);
629 let item = pool.try_get_ref(300).unwrap();
630 assert_eq!(*item.value, 300);
631 assert_eq!(pool.len(), 0);
632 {
633 let item = pool.try_get_ref(400).unwrap();
634 assert_eq!(*item.value, 400);
635 assert_eq!(pool.len(), 0);
636 }
637 assert_eq!(pool.len(), 1); {
639 let item_a = pool.try_get_ref(500).unwrap();
640 assert_eq!(*item_a.value, 500);
641 assert_eq!(pool.len(), 0); let item_b = pool.try_get_ref(600).unwrap();
643 assert_eq!(*item_b.value, 600);
644 assert_eq!(pool.len(), 0); }
646 assert_eq!(pool.len(), 2); let pool = ObjectPool::<TestItem>::try_new(42, 1, Some(100)).unwrap();
649 let item = pool.try_get_ref(100).unwrap();
650 assert_eq!(*item.value, 100);
651 }
652
653 #[test]
654 fn test_pool_with_arc() {
655 let pool = &Arc::new(ObjectPool::<TestItem>::new(42, 1, None));
656 let item = pool.get(100);
657 assert_eq!(*item.value, 100);
658 assert_eq!(pool.len(), 0);
659
660 let item = pool.get(200);
661 assert_eq!(*item.value, 200);
662 assert_eq!(pool.len(), 0);
663 {
664 let item = pool.get(400);
665 assert_eq!(*item.value, 400);
666 assert_eq!(pool.len(), 0);
667 }
668 assert_eq!(pool.len(), 1); let item = pool.try_get_ref(400).unwrap();
670 assert_eq!(*item.value, 400);
671 assert_eq!(pool.len(), 0); let item = pool.try_get(500).unwrap();
673 assert_eq!(*item.value, 500);
674 }
675
676 #[test]
677 fn test_pool_max_capacity_ref() {
678 let pool = ObjectPool::<TestItem>::new(42, 1, Some(1));
679 assert_eq!(pool.len(), 1);
680 assert!(!pool.is_empty());
681 assert_eq!(pool.len(), pool.capacity.unwrap()); {
683 let item = pool.get_ref(100);
684 assert_eq!(pool.len(), 0); assert!(pool.is_empty());
686 assert!(pool.len() < pool.capacity.unwrap()); assert_eq!(*item.value, 100);
688 }
689 assert_eq!(pool.len(), 1); assert_eq!(pool.len(), pool.capacity.unwrap()); {
692 let item1 = pool.get_ref(100);
693 assert_eq!(pool.len(), 0); let item2 = pool.get_ref(200);
695 assert_eq!(pool.len(), 0); let item3 = pool.get_ref(300);
697 assert_eq!(pool.len(), 0); assert!(*item1.value == 100 && *item2.value == 200 && *item3.value == 300);
699 }
701 assert_eq!(pool.len(), pool.capacity.unwrap()); assert_eq!(pool.len(), 1); }
704
705 #[test]
706 fn test_pool_max_capacity_pooled_item() {
707 let pool = &Arc::new(ObjectPool::<TestItem>::new(42, 1, Some(1)));
708 assert_eq!(pool.len(), 1);
709 assert_eq!(pool.len(), pool.capacity.unwrap()); {
711 let item = pool.get(100);
712 assert_eq!(pool.len(), 0); assert!(pool.len() < pool.capacity.unwrap()); assert_eq!(*item.value, 100);
715 }
716 assert_eq!(pool.len(), 1); assert_eq!(pool.len(), pool.capacity.unwrap()); {
719 let item1 = pool.get(100);
720 assert_eq!(pool.len(), 0); let item2 = pool.get(200);
722 assert_eq!(pool.len(), 0); let item3 = pool.get(300);
724 assert_eq!(pool.len(), 0); assert!(*item1.value == 100 && *item2.value == 200 && *item3.value == 300);
726 }
728 assert_eq!(pool.len(), pool.capacity.unwrap()); assert_eq!(pool.len(), 1); }
731
732 #[test]
733 fn test_pool_options() {
734 let item = PoolOption::non_pooled(TestItem::new(42));
736 assert_eq!(*item.value, 42);
737 assert!(item.is_non_pooled());
738 assert!(!item.is_pooled());
739
740 let item = PoolOption::<TestItem>::non_pooled_create(100);
741 assert_eq!(*item.value, 100);
742 assert!(item.is_non_pooled());
743
744 let pool = Arc::new(ObjectPool::<TestItem>::new(42, 1, None));
746 let item = PoolOption::pooled(&pool, 100);
747 assert_eq!(*item.value, 100);
748 assert!(item.is_pooled());
749 assert!(!item.is_non_pooled());
750
751 let item = PoolOption::try_pooled(&pool, 100).unwrap();
753 assert_eq!(*item.value, 100);
754 assert!(item.is_pooled());
755 let item = PoolOption::<TestItem>::try_non_pooled_create(200).unwrap();
756 assert_eq!(*item.value, 200);
757 assert!(item.is_non_pooled());
758 assert!(!item.is_pooled());
759 let item_result = PoolOption::<TestItem>::try_non_pooled_create(-200);
760 assert!(
761 item_result.is_err(),
762 "Creating non-pooled item with negative args should fail"
763 );
764 }
765
766 #[test]
767 fn test_pool_ref_deref_mut() {
768 let pool = ObjectPool::<TestItem>::new(42, 1, None);
770 let item = pool.get_ref(100);
771
772 assert_eq!(*item.value, 100);
773 let mut item = pool.get_ref(100);
774 *item.value = 200;
775 assert_eq!(*item.value, 200);
776
777 let item_ref: &TestItem = &item;
778 assert_eq!(*item_ref.value, 200);
779
780 let item_ref_mut: &mut TestItem = &mut item;
781 assert_eq!(*item_ref_mut.value, 200);
782
783 *item_ref_mut.value = 300;
784 assert_eq!(*item_ref_mut.value, 300);
785
786 let pool = &Arc::new(ObjectPool::<TestItem>::new(42, 1, None));
788 let mut item = pool.get_ref(100);
789 assert_eq!(*item.value, 100);
790
791 *item.value = 200;
792 assert_eq!(*item.value, 200);
793
794 let pool = Arc::new(ObjectPool::<TestItem>::new(42, 1, None));
796 let mut item = PoolOption::pooled(&pool, 100);
797 assert_eq!(*item.value, 100);
798
799 *item.value = 200;
800 assert_eq!(*item.value, 200);
801
802 let mut item = PoolOption::non_pooled(TestItem::new(42));
803 assert_eq!(*item.value, 42);
804
805 *item.value = 100;
806 assert_eq!(*item.value, 100);
807 }
808
809 fn check_error(err: &dyn std::any::Any, contains: &str) {
828 match err.downcast_ref::<&'static str>() {
829 Some(msg) => assert_contains!(msg, contains),
830 None => panic!("incorrect downcast type"),
831 }
832 }
833
834 #[test]
835 fn test_panic_during_create() {
836 let pool = ObjectPool::<TestItem>::new(0u32, 0, Some(1));
837
838 let err = std::panic::catch_unwind(|| {
840 let _ = pool.get_ref(TestPanic);
841 })
842 .unwrap_err();
843
844 check_error(&*err, "panicking on create");
845
846 assert!(
847 !pool.queue.is_poisoned(),
848 "lock should be released while calling trait implementations"
849 );
850
851 assert_eq!(pool.len(), 0);
852 }
853
854 #[test]
855 fn test_panic_during_try_create() {
856 let pool = ObjectPool::<TestItem>::new(0u32, 0, Some(1));
857
858 let err = std::panic::catch_unwind(|| {
860 let _ = pool.try_get_ref(TestPanic);
861 })
862 .unwrap_err();
863
864 check_error(&*err, "panicking on try_create");
865
866 assert!(
867 !pool.queue.is_poisoned(),
868 "lock should be released while calling trait implementations"
869 );
870
871 assert_eq!(pool.len(), 0);
872 }
873
874 #[test]
875 fn test_panic_during_modify() {
876 let pool = ObjectPool::<TestItem>::new(0u32, 0, Some(1));
877
878 let _ = pool.get_ref(0u32);
880 assert_eq!(pool.len(), 1);
881
882 let err = std::panic::catch_unwind(|| {
883 let _ = pool.get_ref(TestPanic);
884 })
885 .unwrap_err();
886
887 check_error(&*err, "panicking on modify");
888
889 assert!(
890 !pool.queue.is_poisoned(),
891 "lock should be released while calling trait implementations"
892 );
893
894 assert_eq!(
895 pool.len(),
896 0,
897 "we should not return a potentially torn object to the pool"
898 );
899 }
900
901 #[test]
902 fn test_panic_during_try_modify() {
903 let pool = ObjectPool::<TestItem>::new(0u32, 0, Some(1));
904
905 let _ = pool.get_ref(0u32);
907 assert_eq!(pool.len(), 1);
908
909 let err = std::panic::catch_unwind(|| {
910 let _ = pool.try_get_ref(TestPanic);
911 })
912 .unwrap_err();
913
914 check_error(&*err, "panicking on try_modify");
915
916 assert!(
917 !pool.queue.is_poisoned(),
918 "lock should be released while calling trait implementations"
919 );
920
921 assert_eq!(
922 pool.len(),
923 0,
924 "we should not return a potentially torn object to the pool"
925 );
926 }
927
928 #[test]
930 fn test_panic_during_drop_ref() {
931 let pool = ObjectPool::<TestItem>::new(0u32, 0, Some(1));
932
933 let mut a = pool.get_ref(0u32);
936 let _ = pool.get_ref(1u32);
937 assert_eq!(pool.len(), 1);
938
939 a.panic_on_drop = true;
940 let err = std::panic::catch_unwind(move || std::mem::drop(a)).unwrap_err();
941 check_error(&*err, "panicking on drop");
942
943 assert!(
944 !pool.queue.is_poisoned(),
945 "lock should be released while calling object drop"
946 );
947 assert_eq!(pool.len(), 1);
948 }
949
950 #[test]
952 fn test_panic_during_drop_arc() {
953 let pool = Arc::new(ObjectPool::<TestItem>::new(0u32, 0, Some(1)));
954
955 let mut a = pool.get(0u32);
958 let _ = pool.get(1u32);
959 assert_eq!(pool.len(), 1);
960
961 a.panic_on_drop = true;
962 let err = std::panic::catch_unwind(move || std::mem::drop(a)).unwrap_err();
963 check_error(&*err, "panicking on drop");
964
965 assert!(
966 !pool.queue.is_poisoned(),
967 "lock should be released while calling object drop"
968 );
969 assert_eq!(pool.len(), 1);
970 }
971
972 #[test]
974 fn test_panic_recovery() {
975 let pool = ObjectPool::<TestItem>::new(0u32, 1, Some(1));
976
977 let err = std::panic::catch_unwind(|| {
978 let _guard = pool.queue.lock();
979 panic!("yeet");
980 })
981 .unwrap_err();
982
983 check_error(&*err, "yeet");
984
985 assert!(pool.queue.is_poisoned());
986
987 let _ = pool.get_ref(1u32);
988 assert!(!pool.queue.is_poisoned(), "poison should be cleared");
989 }
990
991 #[test]
996 fn test_undef() {
997 let mut x: Vec<f32> = Vec::<f32>::create(Undef::new(10));
998 assert_eq!(x.len(), 10);
999
1000 x.modify(Undef::new(0));
1001 assert_eq!(x.len(), 0);
1002
1003 x.modify(Undef::new(20));
1004 assert_eq!(x.len(), 20);
1005 }
1006}