{-# LANGUAGE BangPatterns, CPP, MagicHash, RankNTypes,
 RecordWildCards, UnboxedTuples, UnliftedFFITypes #-}{-# OPTIONS_GHC -fno-warn-unused-matches #-}-- |-- Module : Data.Text.Array-- Copyright : (c) 2009, 2010, 2011 Bryan O'Sullivan---- License : BSD-style-- Maintainer : bos@serpentine.com-- Portability : portable---- Packed, unboxed, heap-resident arrays. Suitable for performance-- critical use, both in terms of large data quantities and high-- speed.---- This module is intended to be imported @qualified@, to avoid name-- clashes with "Prelude" functions, e.g.---- > import qualified Data.Text.Array as A---- The names in this module resemble those in the 'Data.Array' family-- of modules, but are shorter due to the assumption of qualified-- naming.moduleData.Text.Array(-- * TypesArray (..),MArray (..)-- * Functions,resizeM ,shrinkM ,copyM ,copyI ,copyFromPointer ,copyToPointer ,empty ,equal ,compare ,run ,run2 ,toList ,unsafeFreeze ,unsafeIndex ,new ,newPinned ,newFilled ,unsafeWrite ,tile ,getSizeofMArray )where
#if defined(ASSERTS)
importGHC.Stack(HasCallStack)
#endif
#if !MIN_VERSION_base(4,11,0)
importForeign.C.Types(CInt(..))
#endif
importGHC.Extshiding(toList)importGHC.ST(ST(..),runST)importGHC.Word(Word8(..))importqualifiedPreludeimportPreludehiding(length,read,compare)-- | Immutable array type.dataArray =ByteArray ByteArray#-- | Mutable array type, for use in the ST monad.dataMArray s =MutableByteArray (MutableByteArray#s )-- | Create an uninitialized mutable array.new ::foralls .Int->STs (MArray s )new :: forall s. Int -> ST s (MArray s)
new (I#Int#
len# )
#if defined(ASSERTS)
|I#len#<0=error"Data.Text.Array.new: size overflow"
#endif
|Bool
otherwise=forall s a. STRep s a -> ST s a
STforall a b. (a -> b) -> a -> b
$\State# s
s1# ->caseforall d. Int# -> State# d -> (# State# d, MutableByteArray# d #)
newByteArray#Int#
len# State# s
s1# of(#State# s
s2# ,MutableByteArray# s
marr# #)->(#State# s
s2# ,forall s. MutableByteArray# s -> MArray s
MutableByteArray MutableByteArray# s
marr# #){-# INLINEnew #-}-- | Create an uninitialized mutable pinned array.---- @since 2.0newPinned ::foralls .Int->STs (MArray s )newPinned :: forall s. Int -> ST s (MArray s)
newPinned (I#Int#
len# )
#if defined(ASSERTS)
|I#len#<0=error"Data.Text.Array.newPinned: size overflow"
#endif
|Bool
otherwise=forall s a. STRep s a -> ST s a
STforall a b. (a -> b) -> a -> b
$\State# s
s1# ->caseforall d. Int# -> State# d -> (# State# d, MutableByteArray# d #)
newPinnedByteArray#Int#
len# State# s
s1# of(#State# s
s2# ,MutableByteArray# s
marr# #)->(#State# s
s2# ,forall s. MutableByteArray# s -> MArray s
MutableByteArray MutableByteArray# s
marr# #){-# INLINEnewPinned #-}-- | @since 2.0newFilled ::Int->Int->STs (MArray s )newFilled :: forall s. Int -> Int -> ST s (MArray s)
newFilled (I#Int#
len# )(I#Int#
c# )=forall s a. STRep s a -> ST s a
STforall a b. (a -> b) -> a -> b
$\State# s
s1# ->caseforall d. Int# -> State# d -> (# State# d, MutableByteArray# d #)
newByteArray#Int#
len# State# s
s1# of(#State# s
s2# ,MutableByteArray# s
marr# #)->caseforall d.
MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d
setByteArray#MutableByteArray# s
marr# Int#
0#Int#
len# Int#
c# State# s
s2# ofState# s
s3# ->(#State# s
s3# ,forall s. MutableByteArray# s -> MArray s
MutableByteArray MutableByteArray# s
marr# #){-# INLINEnewFilled #-}-- | @since 2.0tile ::MArray s ->Int->STs ()tile :: forall s. MArray s -> Int -> ST s ()
tile MArray s
marr Int
tileLen =doInt
totalLen <-forall s. MArray s -> ST s Int
getSizeofMArray MArray s
marr letgo :: Int -> ST s ()
go Int
l |Int
2forall a. Num a => a -> a -> a
*Int
l forall a. Ord a => a -> a -> Bool
>Int
totalLen =forall s. MArray s -> Int -> MArray s -> Int -> Int -> ST s ()
copyM MArray s
marr Int
l MArray s
marr Int
0(Int
totalLen forall a. Num a => a -> a -> a
-Int
l )|Bool
otherwise=forall s. MArray s -> Int -> MArray s -> Int -> Int -> ST s ()
copyM MArray s
marr Int
l MArray s
marr Int
0Int
l forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>Int -> ST s ()
go (Int
2forall a. Num a => a -> a -> a
*Int
l )Int -> ST s ()
go Int
tileLen {-# INLINEtile #-}-- | Freeze a mutable array. Do not mutate the 'MArray' afterwards!unsafeFreeze ::MArray s ->STs Array unsafeFreeze :: forall s. MArray s -> ST s Array
unsafeFreeze (MutableByteArray MutableByteArray# s
marr )=forall s a. STRep s a -> ST s a
STforall a b. (a -> b) -> a -> b
$\State# s
s1# ->caseforall d.
MutableByteArray# d -> State# d -> (# State# d, ByteArray# #)
unsafeFreezeByteArray#MutableByteArray# s
marr State# s
s1# of(#State# s
s2# ,ByteArray#
ba# #)->(#State# s
s2# ,ByteArray# -> Array
ByteArray ByteArray#
ba# #){-# INLINEunsafeFreeze #-}-- | Unchecked read of an immutable array. May return garbage or-- crash on an out-of-bounds access.unsafeIndex ::
#if defined(ASSERTS)
HasCallStack=>
#endif
Array ->Int->Word8unsafeIndex :: Array -> Int -> Word8
unsafeIndex (ByteArray ByteArray#
arr )i :: Int
i @(I#Int#
i# )=
#if defined(ASSERTS)
letword8len=I#(sizeofByteArray#arr)inifi<0||i>=word8lenthenerror("Data.Text.Array.unsafeIndex: bounds error, offset "++showi++", length "++showword8len)else
#endif
caseByteArray# -> Int# -> Word8#
indexWord8Array#ByteArray#
arr Int#
i# ofWord8#
r# ->(Word8# -> Word8
W8#Word8#
r# ){-# INLINEunsafeIndex #-}-- | @since 2.0getSizeofMArray ::MArray s ->STs IntgetSizeofMArray :: forall s. MArray s -> ST s Int
getSizeofMArray (MutableByteArray MutableByteArray# s
marr )=forall s a. STRep s a -> ST s a
STforall a b. (a -> b) -> a -> b
$\State# s
s0# ->-- Cannot simply use (deprecated) 'sizeofMutableByteArray#', because it is-- unsafe in the presence of 'shrinkMutableByteArray#' and 'resizeMutableByteArray#'.caseforall d. MutableByteArray# d -> State# d -> (# State# d, Int# #)
getSizeofMutableByteArray#MutableByteArray# s
marr State# s
s0# of(#State# s
s1# ,Int#
word8len# #)->(#State# s
s1# ,Int# -> Int
I#Int#
word8len# #)
#if defined(ASSERTS)
checkBoundsM::HasCallStack=>MArrays->Int->Int->STs()checkBoundsMmaielSize=dolen<-getSizeofMArraymaifi<0||i+elSize>lenthenerror("bounds error, offset "++showi++", length "++showlen)elsereturn()
#endif
-- | Unchecked write of a mutable array. May return garbage or crash-- on an out-of-bounds access.unsafeWrite ::
#if defined(ASSERTS)
HasCallStack=>
#endif
MArray s ->Int->Word8->STs ()unsafeWrite :: forall s. MArray s -> Int -> Word8 -> ST s ()
unsafeWrite ma :: MArray s
ma @(MutableByteArray MutableByteArray# s
marr )i :: Int
i @(I#Int#
i# )(W8#Word8#
e# )=
#if defined(ASSERTS)
checkBoundsMmai1>>
#endif
(forall s a. STRep s a -> ST s a
STforall a b. (a -> b) -> a -> b
$\State# s
s1# ->caseforall d.
MutableByteArray# d -> Int# -> Word8# -> State# d -> State# d
writeWord8Array#MutableByteArray# s
marr Int#
i# Word8#
e# State# s
s1# ofState# s
s2# ->(#State# s
s2# ,()#)){-# INLINEunsafeWrite #-}-- | Convert an immutable array to a list.toList ::Array ->Int->Int->[Word8]toList :: Array -> Int -> Int -> [Word8]
toList Array
ary Int
off Int
len =Int -> [Word8]
loop Int
0whereloop :: Int -> [Word8]
loop Int
i |Int
i forall a. Ord a => a -> a -> Bool
<Int
len =Array -> Int -> Word8
unsafeIndex Array
ary (Int
off forall a. Num a => a -> a -> a
+Int
i )forall a. a -> [a] -> [a]
:Int -> [Word8]
loop (Int
i forall a. Num a => a -> a -> a
+Int
1)|Bool
otherwise=[]-- | An empty immutable array.empty ::Array empty :: Array
empty =forall a. (forall s. ST s a) -> a
runST(forall s. Int -> ST s (MArray s)
new Int
0forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=forall s. MArray s -> ST s Array
unsafeFreeze )-- | Run an action in the ST monad and return an immutable array of-- its result.run ::(foralls .STs (MArray s ))->Array run :: (forall s. ST s (MArray s)) -> Array
run forall s. ST s (MArray s)
k =forall a. (forall s. ST s a) -> a
runST(forall s. ST s (MArray s)
k forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=forall s. MArray s -> ST s Array
unsafeFreeze )-- | Run an action in the ST monad and return an immutable array of-- its result paired with whatever else the action returns.run2 ::(foralls .STs (MArray s ,a ))->(Array ,a )run2 :: forall a. (forall s. ST s (MArray s, a)) -> (Array, a)
run2 forall s. ST s (MArray s, a)
k =forall a. (forall s. ST s a) -> a
runST(do(MArray s
marr ,a
b )<-forall s. ST s (MArray s, a)
k Array
arr <-forall s. MArray s -> ST s Array
unsafeFreeze MArray s
marr forall (m :: * -> *) a. Monad m => a -> m a
return(Array
arr ,a
b )){-# INLINErun2 #-}-- | @since 2.0resizeM ::MArray s ->Int->STs (MArray s )resizeM :: forall s. MArray s -> Int -> ST s (MArray s)
resizeM (MutableByteArray MutableByteArray# s
ma )i :: Int
i @(I#Int#
i# )=forall s a. STRep s a -> ST s a
STforall a b. (a -> b) -> a -> b
$\State# s
s1# ->caseforall d.
MutableByteArray# d
-> Int# -> State# d -> (# State# d, MutableByteArray# d #)
resizeMutableByteArray#MutableByteArray# s
ma Int#
i# State# s
s1# of(#State# s
s2# ,MutableByteArray# s
newArr #)->(#State# s
s2# ,forall s. MutableByteArray# s -> MArray s
MutableByteArray MutableByteArray# s
newArr #){-# INLINEresizeM #-}-- | @since 2.0shrinkM ::
#if defined(ASSERTS)
HasCallStack=>
#endif
MArray s ->Int->STs ()shrinkM :: forall s. MArray s -> Int -> ST s ()
shrinkM (MutableByteArray MutableByteArray# s
marr )i :: Int
i @(I#Int#
newSize )=do
#if defined(ASSERTS)
oldSize<-getSizeofMArray(MutableByteArraymarr)ifI#newSize>oldSizethenerror$"shrinkM: shrink cannot grow "++showoldSize++" to "++show(I#newSize)elsereturn()
#endif
forall s a. STRep s a -> ST s a
STforall a b. (a -> b) -> a -> b
$\State# s
s1# ->caseforall d. MutableByteArray# d -> Int# -> State# d -> State# d
shrinkMutableByteArray#MutableByteArray# s
marr Int#
newSize State# s
s1# ofState# s
s2# ->(#State# s
s2# ,()#){-# INLINEshrinkM #-}-- | Copy some elements of a mutable array.copyM ::MArray s -- ^ Destination->Int-- ^ Destination offset->MArray s -- ^ Source->Int-- ^ Source offset->Int-- ^ Count->STs ()copyM :: forall s. MArray s -> Int -> MArray s -> Int -> Int -> ST s ()
copyM dst :: MArray s
dst @(MutableByteArray MutableByteArray# s
dst# )dstOff :: Int
dstOff @(I#Int#
dstOff# )src :: MArray s
src @(MutableByteArray MutableByteArray# s
src# )srcOff :: Int
srcOff @(I#Int#
srcOff# )count :: Int
count @(I#Int#
count# )
#if defined(ASSERTS)
|count<0=error$"copyM: count must be >= 0, but got "++showcount
#endif
|Bool
otherwise=do
#if defined(ASSERTS)
srcLen<-getSizeofMArraysrcdstLen<-getSizeofMArraydstifsrcOff+count>srcLenthenerror"copyM: source is too short"elsereturn()ifdstOff+count>dstLenthenerror"copyM: destination is too short"elsereturn()
#endif
forall s a. STRep s a -> ST s a
STforall a b. (a -> b) -> a -> b
$\State# s
s1# ->caseforall d.
MutableByteArray# d
-> Int#
-> MutableByteArray# d
-> Int#
-> Int#
-> State# d
-> State# d
copyMutableByteArray#MutableByteArray# s
src# Int#
srcOff# MutableByteArray# s
dst# Int#
dstOff# Int#
count# State# s
s1# ofState# s
s2# ->(#State# s
s2# ,()#){-# INLINEcopyM #-}-- | Copy some elements of an immutable array.copyI ::Int-- ^ Count->MArray s -- ^ Destination->Int-- ^ Destination offset->Array -- ^ Source->Int-- ^ Source offset->STs ()copyI :: forall s. Int -> MArray s -> Int -> Array -> Int -> ST s ()
copyI count :: Int
count @(I#Int#
count# )(MutableByteArray MutableByteArray# s
dst# )dstOff :: Int
dstOff @(I#Int#
dstOff# )(ByteArray ByteArray#
src# )(I#Int#
srcOff# )
#if defined(ASSERTS)
|count<0=error$"copyI: count must be >= 0, but got "++showcount
#endif
|Bool
otherwise=forall s a. STRep s a -> ST s a
STforall a b. (a -> b) -> a -> b
$\State# s
s1# ->caseforall d.
ByteArray#
-> Int#
-> MutableByteArray# d
-> Int#
-> Int#
-> State# d
-> State# d
copyByteArray#ByteArray#
src# Int#
srcOff# MutableByteArray# s
dst# Int#
dstOff# Int#
count# State# s
s1# ofState# s
s2# ->(#State# s
s2# ,()#){-# INLINEcopyI #-}-- | Copy from pointer.---- @since 2.0copyFromPointer ::MArray s -- ^ Destination->Int-- ^ Destination offset->PtrWord8-- ^ Source->Int-- ^ Count->STs ()copyFromPointer :: forall s. MArray s -> Int -> Ptr Word8 -> Int -> ST s ()
copyFromPointer (MutableByteArray MutableByteArray# s
dst# )dstOff :: Int
dstOff @(I#Int#
dstOff# )(PtrAddr#
src# )count :: Int
count @(I#Int#
count# )
#if defined(ASSERTS)
|count<0=error$"copyFromPointer: count must be >= 0, but got "++showcount
#endif
|Bool
otherwise=forall s a. STRep s a -> ST s a
STforall a b. (a -> b) -> a -> b
$\State# s
s1# ->caseforall d.
Addr#
-> MutableByteArray# d -> Int# -> Int# -> State# d -> State# d
copyAddrToByteArray#Addr#
src# MutableByteArray# s
dst# Int#
dstOff# Int#
count# State# s
s1# ofState# s
s2# ->(#State# s
s2# ,()#){-# INLINEcopyFromPointer #-}-- | Copy to pointer.---- @since 2.0copyToPointer ::Array -- ^ Source->Int-- ^ Source offset->PtrWord8-- ^ Destination->Int-- ^ Count->STs ()copyToPointer :: forall s. Array -> Int -> Ptr Word8 -> Int -> ST s ()
copyToPointer (ByteArray ByteArray#
src# )srcOff :: Int
srcOff @(I#Int#
srcOff# )(PtrAddr#
dst# )count :: Int
count @(I#Int#
count# )
#if defined(ASSERTS)
|count<0=error$"copyToPointer: count must be >= 0, but got "++showcount
#endif
|Bool
otherwise=forall s a. STRep s a -> ST s a
STforall a b. (a -> b) -> a -> b
$\State# s
s1# ->caseforall d.
ByteArray# -> Int# -> Addr# -> Int# -> State# d -> State# d
copyByteArrayToAddr#ByteArray#
src# Int#
srcOff# Addr#
dst# Int#
count# State# s
s1# ofState# s
s2# ->(#State# s
s2# ,()#){-# INLINEcopyToPointer #-}-- | Compare portions of two arrays for equality. No bounds checking-- is performed.equal ::Array ->Int->Array ->Int->Int->Boolequal :: Array -> Int -> Array -> Int -> Int -> Bool
equal Array
src1 Int
off1 Array
src2 Int
off2 Int
count =Array -> Int -> Array -> Int -> Int -> Int
compareInternal Array
src1 Int
off1 Array
src2 Int
off2 Int
count forall a. Eq a => a -> a -> Bool
==Int
0{-# INLINEequal #-}-- | Compare portions of two arrays. No bounds checking is performed.---- @since 2.0compare ::Array ->Int->Array ->Int->Int->Orderingcompare :: Array -> Int -> Array -> Int -> Int -> Ordering
compare Array
src1 Int
off1 Array
src2 Int
off2 Int
count =Array -> Int -> Array -> Int -> Int -> Int
compareInternal Array
src1 Int
off1 Array
src2 Int
off2 Int
count forall a. Ord a => a -> a -> Ordering
`Prelude.compare`Int
0{-# INLINEcompare #-}compareInternal ::Array -- ^ First->Int-- ^ Offset into first->Array -- ^ Second->Int-- ^ Offset into second->Int-- ^ Count->IntcompareInternal :: Array -> Int -> Array -> Int -> Int -> Int
compareInternal (ByteArray ByteArray#
src1# )(I#Int#
off1# )(ByteArray ByteArray#
src2# )(I#Int#
off2# )(I#Int#
count# )=Int
i where
#if MIN_VERSION_base(4,11,0)
i :: Int
i =Int# -> Int
I#(ByteArray# -> Int# -> ByteArray# -> Int# -> Int# -> Int#
compareByteArrays#ByteArray#
src1# Int#
off1# ByteArray#
src2# Int#
off2# Int#
count# )
#else
i=fromIntegral(memcmpsrc1#off1#src2#off2#count#)foreignimportccallunsafe"_hs_text_memcmp2"memcmp::ByteArray#->Int#->ByteArray#->Int#->Int#->CInt
#endif
{-# INLINEcompareInternal #-}

AltStyle によって変換されたページ (->オリジナル) /