{- Copyright 2016-2018 NGLess Authors - License: MIT -} {-# LANGUAGE ScopedTypeVariables #-} module Utils.IntGroups ( IntGroups(..) , fromList , toList , empty , length , null , forM_ ) where import qualified Data.Vector.Unboxed as VU import qualified Control.Monad import Control.DeepSeq (NFData(..)) import qualified Prelude import Prelude hiding (length, null) -- | IntGroups are a faster, strict, representation of [[Int]] data IntGroups = IntGroups !(VU.Vector Int) !(VU.Vector Int) instance NFData IntGroups where rnf (IntGroups !_ !_) = () fromList :: [[Int]] -> IntGroups fromList gs = IntGroups values indices where values = VU.fromList (concat gs) indices = VU.fromList (scanl (+) 0 $ map Prelude.length gs) toList :: IntGroups -> [VU.Vector Int] toList (IntGroups values indices) = go 0 where go ix | ix == VU.length indices - 1 = [] | otherwise = VU.slice st n values:go (ix+1) where st = indices VU.! ix e = indices VU.! (ix + 1) n = e - st {-# INLINE toList #-} length (IntGroups _ indices) = VU.length indices - 1 {-# INLINE length #-} null (IntGroups values _) = VU.null values {-# INLINE null #-} empty = IntGroups VU.empty VU.empty forM_ :: (Monad m) => IntGroups -> ((VU.Vector Int) -> m ()) -> m () forM_ vs = Control.Monad.forM_ (toList vs) {-# INLINE forM_ #-}