blob: ba2439c897081a80c5b24241166bfa2f848dbefc (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
{-# OPTIONS -O2 -XBangPatterns #-}
-- The thing to look for here is that the implementation
-- of 'length' does not allocate in the inner loop
--
-- See Trac #3116
module T3116 where
import Foreign
data SByteString
= BS {-# UNPACK #-} !(ForeignPtr Word8) -- payload
{-# UNPACK #-} !Int -- offset
{-# UNPACK #-} !Int -- length
data ByteString
= Empty
| Chunk {-# UNPACK #-} !SByteString ByteString
bnull :: ByteString -> Bool
bnull Empty = True
bnull _ = False
btail :: ByteString -> ByteString
btail Empty = error "empty tail"
btail (Chunk (BS fp s 1) cs) = cs
btail (Chunk (BS fp s l) cs) = Chunk (BS fp (s+1) (l-1)) cs
length :: ByteString -> Int
length = go 0
where
go !n bs | bnull bs = n
| otherwise = go (n+1) (btail bs)
|