/// `count_append` is borrowed from Jane Street Base, and applies two
/// optimizations for `append`: loop unrolling, and dynamic switching
/// between stack and arena allocation.
///
/// The loop-unrolling is straightforward, we just unroll 5 levels of the
/// loop. This should make each iteration faster, and also reduces the
/// number of stack frames consumed per list element.
///
/// The dynamic switching is done by counting the number of stack frames,
/// and then switching to the "slow" implementation when we exceed a given
/// limit. This means that short lists use the fast stack-allocation method,
/// and long lists use a slower one that doesn't require stack space.
`count_append` is borrowed from Jane Street Base, and applies two
optimizations for `append`: loop unrolling, and dynamic switching
between stack and arena allocation.

The loop-unrolling is straightforward, we just unroll 5 levels of the
loop. This should make each iteration faster, and also reduces the
number of stack frames consumed per list element.

The dynamic switching is done by counting the number of stack frames,
and then switching to the "slow" implementation when we exceed a given
limit. This means that short lists use the fast stack-allocation method,
and long lists use a slower one that doesn't require stack space.
` count_append ` is borrowed from Jane Street Base and applies two optimizations for ` append ` : loop unrolling and dynamic switching between stack and arena allocation . The loop - unrolling is straightforward we just unroll 5 levels of the loop . This should make each iteration faster and also reduces the number of stack frames consumed per list element . The dynamic switching is done by counting the number of stack frames and then switching to the " slow " implementation when we exceed a given limit . This means that short lists use the fast stack - allocation method and long lists use a slower one that doesn ' t require stack space .
fn count_append<A: Arena>(self, other: Self, count: usize, arena: &'a A) -> Self
    where
        T: Clone + TrivialDrop,
    {
        if other.is_empty() {
            return self;
        }
        let a = arena;
        match self {
            Nil => other,
            Cons((x1, Nil)) => Self::cons(x1.clone(), other, a),
            Cons((x1, Cons((x2, Nil)))) => {
                let x1 = x1.clone();
                let x2 = x2.clone();
                Self::cons(x1, Self::cons(x2, other, a), a)
            }
            Cons((x1, Cons((x2, Cons((x3, Nil)))))) => {
                let x1 = x1.clone();
                let x2 = x2.clone();
                let x3 = x3.clone();
                Self::cons(x1, Self::cons(x2, Self::cons(x3, other, a), a), a)
            }
            Cons((x1, Cons((x2, Cons((x3, Cons((x4, Nil)))))))) => {
                let x1 = x1.clone();
                let x2 = x2.clone();
                let x3 = x3.clone();
                let x4 = x4.clone();
                Self::cons(
                    x1,
                    Self::cons(x2, Self::cons(x3, Self::cons(x4, other, a), a), a),
                    a,
                )
            }
            Cons((x1, Cons((x2, Cons((x3, Cons((x4, Cons((x5, tl)))))))))) => {
                let tl = if count > 1000 {
                    tl.slow_append(other, a)
                } else {
                    tl.count_append(other, count + 1, a)
                };
                let x1 = x1.clone();
                let x2 = x2.clone();
                let x3 = x3.clone();
                let x4 = x4.clone();
                let x5 = x5.clone();
                Self::cons(
                    x1,
                    Self::cons(
                        x2,
                        Self::cons(x3, Self::cons(x4, Self::cons(x5, tl, a), a), a),
                        a,
                    ),
                    a,
                )
            }
        }
    }
fn count_append < A : Arena > ( self , other : Self , count : usize , arena : & ' a A ) -> Self where T : Clone + TrivialDrop , { if other . is_empty ( ) { return self ; } let a = arena ; match self { Nil => other , Cons ( ( x1 , Nil ) ) => Self :: cons ( x1 . clone ( ) , other , a ) , Cons ( ( x1 , Cons ( ( x2 , Nil ) ) ) ) => { let x1 = x1 . clone ( ) ; let x2 = x2 . clone ( ) ; Self :: cons ( x1 , Self :: cons ( x2 , other , a ) , a ) } Cons ( ( x1 , Cons ( ( x2 , Cons ( ( x3 , Nil ) ) ) ) ) ) => { let x1 = x1 . clone ( ) ; let x2 = x2 . clone ( ) ; let x3 = x3 . clone ( ) ; Self :: cons ( x1 , Self :: cons ( x2 , Self :: cons ( x3 , other , a ) , a ) , a ) } Cons ( ( x1 , Cons ( ( x2 , Cons ( ( x3 , Cons ( ( x4 , Nil ) ) ) ) ) ) ) ) => { let x1 = x1 . clone ( ) ; let x2 = x2 . clone ( ) ; let x3 = x3 . clone ( ) ; let x4 = x4 . clone ( ) ; Self :: cons ( x1 , Self :: cons ( x2 , Self :: cons ( x3 , Self :: cons ( x4 , other , a ) , a ) , a ) , a , ) } Cons ( ( x1 , Cons ( ( x2 , Cons ( ( x3 , Cons ( ( x4 , Cons ( ( x5 , tl ) ) ) ) ) ) ) ) ) ) => { let tl = if count > 1000 { tl . slow_append ( other , a ) } else { tl . count_append ( other , count + 1 , a ) } ; let x1 = x1 . clone ( ) ; let x2 = x2 . clone ( ) ; let x3 = x3 . clone ( ) ; let x4 = x4 . clone ( ) ; let x5 = x5 . clone ( ) ; Self :: cons ( x1 , Self :: cons ( x2 , Self :: cons ( x3 , Self :: cons ( x4 , Self :: cons ( x5 , tl , a ) , a ) , a ) , a , ) , a , ) } } }
`count_append` is borrowed from Jane Street Base, and applies two
optimizations for `append`: loop unrolling, and dynamic switching
between stack and arena allocation.
` count_append ` is borrowed from Jane Street Base and applies two optimizations for ` append ` : loop unrolling and dynamic switching between stack and arena allocation .
self
other
Self
count
usize
arena
&'a A