module FWGL.Internal.STVectorLen where import Control.Applicative import Control.Monad (when) import Control.Monad.ST import Data.STRef import qualified Data.Vector.Storable as V import qualified Data.Vector.Storable.Mutable as M type STVectorLen s a = (STRef s (M.STVector s a), STRef s Int) new :: V.Storable a => ST s (STVectorLen s a) new = (,) <$> (M.new 256 >>= newSTRef) <*> newSTRef 0 (!) :: V.Storable a => STVectorLen s a -> Int -> ST s a (!) (vRef, _) i = readSTRef vRef >>= flip M.read i cons :: V.Storable a => a -> STVectorLen s a -> ST s () cons x (vRef, lenRef) = do len <- readSTRef lenRef v <- readSTRef vRef let maxLen = M.length v when (len >= maxLen) $ M.grow v (maxLen * 2) >>= writeSTRef vRef v' <- readSTRef vRef M.write v' len x writeSTRef lenRef $ len + 1 freeze :: V.Storable a => STVectorLen s a -> ST s (V.Vector a) freeze (vRef, lenRef) = do v <- readSTRef vRef >>= V.freeze len <- readSTRef lenRef return $ V.slice 0 len v