{-
Alternative to PointerPrivate implemented at a higher level.
-}
module Data.StorableVector.Lazy.PointerPrivateIndex where

import qualified Data.StorableVector as V
import qualified Data.StorableVector.Base as VB

import Foreign.Storable (Storable)


data Pointer a =
   Pointer {forall a. Pointer a -> [Vector a]
chunks :: ![VB.Vector a], forall a. Pointer a -> Int
index :: !Int}


{-# INLINE cons #-}
cons :: Storable a => [VB.Vector a] -> Pointer a
cons :: forall a. Storable a => [Vector a] -> Pointer a
cons = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. [Vector a] -> Int -> Pointer a
Pointer Int
0

{-# INLINE viewL #-}
viewL :: Storable a => Pointer a -> Maybe (a, Pointer a)
viewL :: forall a. Storable a => Pointer a -> Maybe (a, Pointer a)
viewL = forall a b.
Storable a =>
b -> (a -> Pointer a -> b) -> Pointer a -> b
switchL forall a. Maybe a
Nothing (forall a b c. ((a, b) -> c) -> a -> b -> c
curry forall a. a -> Maybe a
Just)

{-# INLINE switchL #-}
switchL :: Storable a =>
   b -> (a -> Pointer a -> b) -> Pointer a -> b
switchL :: forall a b.
Storable a =>
b -> (a -> Pointer a -> b) -> Pointer a -> b
switchL b
n a -> Pointer a -> b
j =
   let recourse :: Pointer a -> b
recourse Pointer a
p =
          let s :: [Vector a]
s = forall a. Pointer a -> [Vector a]
chunks Pointer a
p
          in  case [Vector a]
s of
                 [] -> b
n
                 (Vector a
c:[Vector a]
cs) ->
                    let i :: Int
i = forall a. Pointer a -> Int
index Pointer a
p
                        d :: Int
d = Int
i forall a. Num a => a -> a -> a
- forall a. Vector a -> Int
V.length Vector a
c
                    in  if Int
d forall a. Ord a => a -> a -> Bool
< Int
0
                          then a -> Pointer a -> b
j (forall a. Storable a => Vector a -> Int -> a
VB.unsafeIndex Vector a
c Int
i) (forall a. [Vector a] -> Int -> Pointer a
Pointer [Vector a]
s (Int
iforall a. Num a => a -> a -> a
+Int
1))
                          else Pointer a -> b
recourse (forall a. [Vector a] -> Int -> Pointer a
Pointer [Vector a]
cs Int
d)
   in  Pointer a -> b
recourse