{-# LANGUAGE TypeFamilies #-}

module Data.Monoid.RangedSum where

import Control.Monad
import Data.Bits
import qualified Data.Foldable as F
import qualified Data.Vector.Generic as G
import qualified Data.Vector.Generic.Mutable as GM
import qualified Data.Vector.Unboxed as U
import qualified Data.Vector.Unboxed.Mutable as UM

data RangedSum a = RangedSum
  { forall a. RangedSum a -> a
getRangesSumSize :: !a
  , forall a. RangedSum a -> a
getRangedSum :: !a
  }
  deriving (RangedSum a -> RangedSum a -> Bool
(RangedSum a -> RangedSum a -> Bool)
-> (RangedSum a -> RangedSum a -> Bool) -> Eq (RangedSum a)
forall a. Eq a => RangedSum a -> RangedSum a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => RangedSum a -> RangedSum a -> Bool
== :: RangedSum a -> RangedSum a -> Bool
$c/= :: forall a. Eq a => RangedSum a -> RangedSum a -> Bool
/= :: RangedSum a -> RangedSum a -> Bool
Eq, Int -> RangedSum a -> ShowS
[RangedSum a] -> ShowS
RangedSum a -> String
(Int -> RangedSum a -> ShowS)
-> (RangedSum a -> String)
-> ([RangedSum a] -> ShowS)
-> Show (RangedSum a)
forall a. Show a => Int -> RangedSum a -> ShowS
forall a. Show a => [RangedSum a] -> ShowS
forall a. Show a => RangedSum a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> RangedSum a -> ShowS
showsPrec :: Int -> RangedSum a -> ShowS
$cshow :: forall a. Show a => RangedSum a -> String
show :: RangedSum a -> String
$cshowList :: forall a. Show a => [RangedSum a] -> ShowS
showList :: [RangedSum a] -> ShowS
Show)

instance (Num a) => Semigroup (RangedSum a) where
  (RangedSum a
len0 a
x) <> :: RangedSum a -> RangedSum a -> RangedSum a
<> (RangedSum a
len1 a
y) = a -> a -> RangedSum a
forall a. a -> a -> RangedSum a
RangedSum (a
len0 a -> a -> a
forall a. Num a => a -> a -> a
+ a
len1) (a
x a -> a -> a
forall a. Num a => a -> a -> a
+ a
y)

instance (Num a) => Monoid (RangedSum a) where
  mempty :: RangedSum a
mempty = a -> a -> RangedSum a
forall a. a -> a -> RangedSum a
RangedSum a
0 a
0
  mconcat :: [RangedSum a] -> RangedSum a
mconcat = (RangedSum a -> RangedSum a -> RangedSum a)
-> RangedSum a -> [RangedSum a] -> RangedSum a
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
F.foldl' RangedSum a -> RangedSum a -> RangedSum a
forall a. Semigroup a => a -> a -> a
(<>) RangedSum a
forall a. Monoid a => a
mempty

newtype instance UM.MVector s (RangedSum a) = MV_RangedSum (UM.MVector s a)
newtype instance U.Vector (RangedSum a) = V_RangedSum (U.Vector a)

instance (U.Unbox a) => U.Unbox (RangedSum a)

instance (U.Unbox a) => GM.MVector UM.MVector (RangedSum a) where
  basicLength :: forall s. MVector s (RangedSum a) -> Int
basicLength (MV_RangedSum MVector s a
v) = Int -> Int -> Int
forall a. Bits a => a -> Int -> a
unsafeShiftR (MVector s a -> Int
forall s. MVector s a -> Int
forall (v :: * -> * -> *) a s. MVector v a => v s a -> Int
GM.basicLength MVector s a
v) Int
1
  {-# INLINE basicLength #-}
  basicUnsafeSlice :: forall s.
Int -> Int -> MVector s (RangedSum a) -> MVector s (RangedSum a)
basicUnsafeSlice Int
i Int
n (MV_RangedSum MVector s a
v) = MVector s a -> MVector s (RangedSum a)
forall s a. MVector s a -> MVector s (RangedSum a)
MV_RangedSum (MVector s a -> MVector s (RangedSum a))
-> MVector s a -> MVector s (RangedSum a)
forall a b. (a -> b) -> a -> b
$ Int -> Int -> MVector s a -> MVector s a
forall s. Int -> Int -> MVector s a -> MVector s a
forall (v :: * -> * -> *) a s.
MVector v a =>
Int -> Int -> v s a -> v s a
GM.basicUnsafeSlice (Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
i) (Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
n) MVector s a
v
  {-# INLINE basicUnsafeSlice #-}
  basicOverlaps :: forall s.
MVector s (RangedSum a) -> MVector s (RangedSum a) -> Bool
basicOverlaps (MV_RangedSum MVector s a
v1) (MV_RangedSum MVector s a
v2) = MVector s a -> MVector s a -> Bool
forall s. MVector s a -> MVector s a -> Bool
forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> v s a -> Bool
GM.basicOverlaps MVector s a
v1 MVector s a
v2
  {-# INLINE basicOverlaps #-}
  basicUnsafeNew :: forall s. Int -> ST s (MVector s (RangedSum a))
basicUnsafeNew Int
n = MVector s a -> MVector s (RangedSum a)
forall s a. MVector s a -> MVector s (RangedSum a)
MV_RangedSum (MVector s a -> MVector s (RangedSum a))
-> ST s (MVector s a) -> ST s (MVector s (RangedSum a))
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` Int -> ST s (MVector s a)
forall s. Int -> ST s (MVector s a)
forall (v :: * -> * -> *) a s. MVector v a => Int -> ST s (v s a)
GM.basicUnsafeNew (Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
n)
  {-# INLINE basicUnsafeNew #-}
  basicInitialize :: forall s. MVector s (RangedSum a) -> ST s ()
basicInitialize (MV_RangedSum MVector s a
v) = MVector s a -> ST s ()
forall s. MVector s a -> ST s ()
forall (v :: * -> * -> *) a s. MVector v a => v s a -> ST s ()
GM.basicInitialize MVector s a
v
  {-# INLINE basicInitialize #-}
  basicUnsafeRead :: forall s. MVector s (RangedSum a) -> Int -> ST s (RangedSum a)
basicUnsafeRead (MV_RangedSum MVector s a
v) Int
i = (a -> a -> RangedSum a) -> ST s a -> ST s a -> ST s (RangedSum a)
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 a -> a -> RangedSum a
forall a. a -> a -> RangedSum a
RangedSum (MVector s a -> Int -> ST s a
forall s. MVector s a -> Int -> ST s a
forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> Int -> ST s a
GM.basicUnsafeRead MVector s a
v (Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
i)) (MVector s a -> Int -> ST s a
forall s. MVector s a -> Int -> ST s a
forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> Int -> ST s a
GM.basicUnsafeRead MVector s a
v (Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1))
  {-# INLINE basicUnsafeRead #-}
  basicUnsafeWrite :: forall s. MVector s (RangedSum a) -> Int -> RangedSum a -> ST s ()
basicUnsafeWrite (MV_RangedSum MVector s a
v) Int
i (RangedSum a
x a
y) = MVector s a -> Int -> a -> ST s ()
forall s. MVector s a -> Int -> a -> ST s ()
forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> Int -> a -> ST s ()
GM.basicUnsafeWrite MVector s a
v (Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
i) a
x ST s () -> ST s () -> ST s ()
forall a b. ST s a -> ST s b -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> MVector s a -> Int -> a -> ST s ()
forall s. MVector s a -> Int -> a -> ST s ()
forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> Int -> a -> ST s ()
GM.basicUnsafeWrite MVector s a
v (Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) a
y
  {-# INLINE basicUnsafeWrite #-}
  basicClear :: forall s. MVector s (RangedSum a) -> ST s ()
basicClear (MV_RangedSum MVector s a
v) = MVector s a -> ST s ()
forall s. MVector s a -> ST s ()
forall (v :: * -> * -> *) a s. MVector v a => v s a -> ST s ()
GM.basicClear MVector s a
v
  {-# INLINE basicClear #-}
  basicUnsafeCopy :: forall s.
MVector s (RangedSum a) -> MVector s (RangedSum a) -> ST s ()
basicUnsafeCopy (MV_RangedSum MVector s a
v1) (MV_RangedSum MVector s a
v2) = MVector s a -> MVector s a -> ST s ()
forall s. MVector s a -> MVector s a -> ST s ()
forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> v s a -> ST s ()
GM.basicUnsafeCopy MVector s a
v1 MVector s a
v2
  {-# INLINE basicUnsafeCopy #-}
  basicUnsafeMove :: forall s.
MVector s (RangedSum a) -> MVector s (RangedSum a) -> ST s ()
basicUnsafeMove (MV_RangedSum MVector s a
v1) (MV_RangedSum MVector s a
v2) = MVector s a -> MVector s a -> ST s ()
forall s. MVector s a -> MVector s a -> ST s ()
forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> v s a -> ST s ()
GM.basicUnsafeMove MVector s a
v1 MVector s a
v2
  {-# INLINE basicUnsafeMove #-}
  basicUnsafeGrow :: forall s.
MVector s (RangedSum a) -> Int -> ST s (MVector s (RangedSum a))
basicUnsafeGrow (MV_RangedSum MVector s a
v) Int
n = MVector s a -> MVector s (RangedSum a)
forall s a. MVector s a -> MVector s (RangedSum a)
MV_RangedSum (MVector s a -> MVector s (RangedSum a))
-> ST s (MVector s a) -> ST s (MVector s (RangedSum a))
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` MVector s a -> Int -> ST s (MVector s a)
forall s. MVector s a -> Int -> ST s (MVector s a)
forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> Int -> ST s (v s a)
GM.basicUnsafeGrow MVector s a
v (Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
n)
  {-# INLINE basicUnsafeGrow #-}

instance (U.Unbox a) => G.Vector U.Vector (RangedSum a) where
  basicUnsafeFreeze :: forall s.
Mutable Vector s (RangedSum a) -> ST s (Vector (RangedSum a))
basicUnsafeFreeze (MV_RangedSum MVector s a
v) = Vector a -> Vector (RangedSum a)
forall a. Vector a -> Vector (RangedSum a)
V_RangedSum (Vector a -> Vector (RangedSum a))
-> ST s (Vector a) -> ST s (Vector (RangedSum a))
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` Mutable Vector s a -> ST s (Vector a)
forall s. Mutable Vector s a -> ST s (Vector a)
forall (v :: * -> *) a s. Vector v a => Mutable v s a -> ST s (v a)
G.basicUnsafeFreeze MVector s a
Mutable Vector s a
v
  {-# INLINE basicUnsafeFreeze #-}
  basicUnsafeThaw :: forall s.
Vector (RangedSum a) -> ST s (Mutable Vector s (RangedSum a))
basicUnsafeThaw (V_RangedSum Vector a
v) = MVector s a -> MVector s (RangedSum a)
forall s a. MVector s a -> MVector s (RangedSum a)
MV_RangedSum (MVector s a -> MVector s (RangedSum a))
-> ST s (MVector s a) -> ST s (MVector s (RangedSum a))
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` Vector a -> ST s (Mutable Vector s a)
forall s. Vector a -> ST s (Mutable Vector s a)
forall (v :: * -> *) a s. Vector v a => v a -> ST s (Mutable v s a)
G.basicUnsafeThaw Vector a
v
  {-# INLINE basicUnsafeThaw #-}
  basicLength :: Vector (RangedSum a) -> Int
basicLength (V_RangedSum Vector a
v) = Int -> Int -> Int
forall a. Bits a => a -> Int -> a
unsafeShiftR (Vector a -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
G.basicLength Vector a
v) Int
1
  {-# INLINE basicLength #-}
  basicUnsafeSlice :: Int -> Int -> Vector (RangedSum a) -> Vector (RangedSum a)
basicUnsafeSlice Int
i Int
n (V_RangedSum Vector a
v) = Vector a -> Vector (RangedSum a)
forall a. Vector a -> Vector (RangedSum a)
V_RangedSum (Vector a -> Vector (RangedSum a))
-> Vector a -> Vector (RangedSum a)
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Vector a -> Vector a
forall (v :: * -> *) a. Vector v a => Int -> Int -> v a -> v a
G.basicUnsafeSlice (Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
i) (Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
n) Vector a
v
  {-# INLINE basicUnsafeSlice #-}
  basicUnsafeIndexM :: Vector (RangedSum a) -> Int -> Box (RangedSum a)
basicUnsafeIndexM (V_RangedSum Vector a
v) Int
i = (a -> a -> RangedSum a) -> Box a -> Box a -> Box (RangedSum a)
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 a -> a -> RangedSum a
forall a. a -> a -> RangedSum a
RangedSum (Vector a -> Int -> Box a
forall (v :: * -> *) a. Vector v a => v a -> Int -> Box a
G.basicUnsafeIndexM Vector a
v (Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
i)) (Vector a -> Int -> Box a
forall (v :: * -> *) a. Vector v a => v a -> Int -> Box a
G.basicUnsafeIndexM Vector a
v (Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1))
  {-# INLINE basicUnsafeIndexM #-}
  basicUnsafeCopy :: forall s.
Mutable Vector s (RangedSum a) -> Vector (RangedSum a) -> ST s ()
basicUnsafeCopy (MV_RangedSum MVector s a
mv) (V_RangedSum Vector a
v) = Mutable Vector s a -> Vector a -> ST s ()
forall s. Mutable Vector s a -> Vector a -> ST s ()
forall (v :: * -> *) a s.
Vector v a =>
Mutable v s a -> v a -> ST s ()
G.basicUnsafeCopy MVector s a
Mutable Vector s a
mv Vector a
v
  elemseq :: forall b. Vector (RangedSum a) -> RangedSum a -> b -> b
elemseq Vector (RangedSum a)
_ = RangedSum a -> b -> b
forall a b. a -> b -> b
seq
  {-# INLINE elemseq #-}