module VectorBuilder.Core.Builder where
import qualified Data.Vector.Generic as B
import qualified Data.Vector.Generic.Mutable as C
import qualified VectorBuilder.Core.Update as A
import VectorBuilder.Prelude hiding (concat, empty)
data Builder element
= Builder !Int !(A.Update element)
{-# INLINE size #-}
size :: Builder element -> Int
size :: Builder element -> Int
size (Builder Int
s Update element
_) = Int
s
{-# INLINE empty #-}
empty :: Builder element
empty :: Builder element
empty =
Int -> Update element -> Builder element
forall element. Int -> Update element -> Builder element
Builder Int
0 Update element
forall element. Update element
A.empty
{-# INLINE singleton #-}
singleton :: element -> Builder element
singleton :: element -> Builder element
singleton element
element =
Int -> Update element -> Builder element
forall element. Int -> Update element -> Builder element
Builder Int
1 (element -> Update element
forall element. element -> Update element
A.write element
element)
{-# INLINE vector #-}
vector :: B.Vector vector element => vector element -> Builder element
vector :: vector element -> Builder element
vector vector element
vector =
Int -> Update element -> Builder element
forall element. Int -> Update element -> Builder element
Builder (vector element -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
B.length vector element
vector) (vector element -> Update element
forall (vector :: * -> *) element.
Vector vector element =>
vector element -> Update element
A.writeMany vector element
vector)
{-# INLINE foldable #-}
foldable :: Foldable foldable => foldable element -> Builder element
foldable :: foldable element -> Builder element
foldable foldable element
foldable =
Int -> Update element -> Builder element
forall element. Int -> Update element -> Builder element
Builder (foldable element -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length foldable element
foldable) (foldable element -> Update element
forall (foldable :: * -> *) element.
Foldable foldable =>
foldable element -> Update element
A.writeFoldable foldable element
foldable)
{-# INLINE snoc #-}
snoc :: element -> Builder element -> Builder element
snoc :: element -> Builder element -> Builder element
snoc element
element (Builder Int
size Update element
update) =
Int -> Update element -> Builder element
forall element. Int -> Update element -> Builder element
Builder (Int -> Int
forall a. Enum a => a -> a
succ Int
size) (Int -> Update element -> Update element -> Update element
forall element.
Int -> Update element -> Update element -> Update element
A.prepend Int
size Update element
update (element -> Update element
forall element. element -> Update element
A.write element
element))
{-# INLINE cons #-}
cons :: element -> Builder element -> Builder element
cons :: element -> Builder element -> Builder element
cons element
element (Builder Int
size Update element
update) =
Int -> Update element -> Builder element
forall element. Int -> Update element -> Builder element
Builder (Int -> Int
forall a. Enum a => a -> a
succ Int
size) (Int -> Update element -> Update element -> Update element
forall element.
Int -> Update element -> Update element -> Update element
A.prepend Int
1 (element -> Update element
forall element. element -> Update element
A.write element
element) Update element
update)
{-# INLINE prepend #-}
prepend :: Builder element -> Builder element -> Builder element
prepend :: Builder element -> Builder element -> Builder element
prepend (Builder Int
leftSize Update element
leftUpdate) (Builder Int
rightSize Update element
rightUpdate) =
Int -> Update element -> Builder element
forall element. Int -> Update element -> Builder element
Builder (Int
leftSize Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
rightSize) (Int -> Update element -> Update element -> Update element
forall element.
Int -> Update element -> Update element -> Update element
A.prepend Int
leftSize Update element
leftUpdate Update element
rightUpdate)
{-# INLINE append #-}
append :: Builder element -> Builder element -> Builder element
append :: Builder element -> Builder element -> Builder element
append =
(Builder element -> Builder element -> Builder element)
-> Builder element -> Builder element -> Builder element
forall a b c. (a -> b -> c) -> b -> a -> c
flip Builder element -> Builder element -> Builder element
forall element.
Builder element -> Builder element -> Builder element
prepend
{-# INLINE concat #-}
concat :: Foldable foldable => foldable (Builder element) -> Builder element
concat :: foldable (Builder element) -> Builder element
concat foldable (Builder element)
builders =
Int -> Update element -> Builder element
forall element. Int -> Update element -> Builder element
Builder
( let step :: Int -> Builder element -> Int
step Int
size (Builder Int
builderSize Update element
_) = Int
size Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
builderSize
in (Int -> Builder element -> Int)
-> Int -> foldable (Builder element) -> Int
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Int -> Builder element -> Int
forall element. Int -> Builder element -> Int
step Int
0 foldable (Builder element)
builders
)
( (forall s (vector :: * -> * -> *).
MVector vector element =>
vector s element -> Int -> ST s ())
-> Update element
forall element.
(forall s (vector :: * -> * -> *).
MVector vector element =>
vector s element -> Int -> ST s ())
-> Update element
A.Update
( \vector s element
mVector Int
offset ->
(Int -> Builder element -> ST s Int)
-> Int -> foldable (Builder element) -> ST s ()
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m ()
foldM_
( \Int
index (Builder Int
size (A.Update forall s (vector :: * -> * -> *).
MVector vector element =>
vector s element -> Int -> ST s ()
st)) ->
vector s element -> Int -> ST s ()
forall s (vector :: * -> * -> *).
MVector vector element =>
vector s element -> Int -> ST s ()
st vector s element
mVector Int
index ST s () -> Int -> ST s Int
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Int
index Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
size
)
Int
offset
foldable (Builder element)
builders
)
)
instance Semigroup (Builder element) where
{-# INLINE (<>) #-}
<> :: Builder element -> Builder element -> Builder element
(<>) =
Builder element -> Builder element -> Builder element
forall element.
Builder element -> Builder element -> Builder element
prepend
sconcat :: NonEmpty (Builder element) -> Builder element
sconcat =
NonEmpty (Builder element) -> Builder element
forall (foldable :: * -> *) element.
Foldable foldable =>
foldable (Builder element) -> Builder element
concat
instance Monoid (Builder element) where
{-# INLINE mempty #-}
mempty :: Builder element
mempty =
Builder element
forall element. Builder element
empty
{-# INLINE mappend #-}
mappend :: Builder element -> Builder element -> Builder element
mappend =
Builder element -> Builder element -> Builder element
forall a. Semigroup a => a -> a -> a
(<>)
{-# INLINE mconcat #-}
mconcat :: [Builder element] -> Builder element
mconcat =
[Builder element] -> Builder element
forall (foldable :: * -> *) element.
Foldable foldable =>
foldable (Builder element) -> Builder element
concat