{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
module HaskellWorks.Data.AtIndex
( Container(..)
, AtIndex(..)
, Length(..)
, atIndexOr
, atIndexOrBeforeOrAfter
, atIndexOrBeforeOrLast
) where
import Data.Int
import Data.Word
import HaskellWorks.Data.Length
import HaskellWorks.Data.Positioning
import qualified Data.ByteString as BS
import qualified Data.Vector as DV
import qualified Data.Vector.Storable as DVS
class Length v => AtIndex v where
(!!!) :: v -> Position -> Elem v
atIndex :: v -> Position -> Elem v
instance AtIndex [a] where
(!!!) v i = v !! fromIntegral i
atIndex v i = v !! fromIntegral i
{-# INLINE (!!!) #-}
{-# INLINE atIndex #-}
instance AtIndex BS.ByteString where
(!!!) v i = BS.index v (fromIntegral i)
atIndex v i = BS.index v (fromIntegral i)
{-# INLINE (!!!) #-}
{-# INLINE atIndex #-}
instance AtIndex (DV.Vector Word8) where
#if !defined(BOUNDS_CHECKING_ENABLED)
(!!!) v i = DV.unsafeIndex v (fromIntegral i)
atIndex v i = DV.unsafeIndex v (fromIntegral i)
#else
(!!!) v i = v DV.! fromIntegral i
atIndex v i = v DV.! fromIntegral i
#endif
{-# INLINE (!!!) #-}
{-# INLINE atIndex #-}
instance AtIndex (DV.Vector Word16) where
#if !defined(BOUNDS_CHECKING_ENABLED)
(!!!) v i = DV.unsafeIndex v (fromIntegral i)
atIndex v i = DV.unsafeIndex v (fromIntegral i)
#else
(!!!) v i = v DV.! fromIntegral i
atIndex v i = v DV.! fromIntegral i
#endif
{-# INLINE (!!!) #-}
{-# INLINE atIndex #-}
instance AtIndex (DV.Vector Word32) where
#if !defined(BOUNDS_CHECKING_ENABLED)
(!!!) v i = DV.unsafeIndex v (fromIntegral i)
atIndex v i = DV.unsafeIndex v (fromIntegral i)
#else
(!!!) v i = v DV.! fromIntegral i
atIndex v i = v DV.! fromIntegral i
#endif
{-# INLINE (!!!) #-}
{-# INLINE atIndex #-}
instance AtIndex (DV.Vector Word64) where
#if !defined(BOUNDS_CHECKING_ENABLED)
(!!!) v i = DV.unsafeIndex v (fromIntegral i)
atIndex v i = DV.unsafeIndex v (fromIntegral i)
#else
(!!!) v i = v DV.! fromIntegral i
atIndex v i = v DV.! fromIntegral i
#endif
{-# INLINE (!!!) #-}
{-# INLINE atIndex #-}
instance AtIndex (DVS.Vector Word8) where
#if !defined(BOUNDS_CHECKING_ENABLED)
(!!!) v i = DVS.unsafeIndex v (fromIntegral i)
atIndex v i = DVS.unsafeIndex v (fromIntegral i)
#else
(!!!) v i = v DVS.! fromIntegral i
atIndex v i = v DVS.! fromIntegral i
#endif
{-# INLINE (!!!) #-}
{-# INLINE atIndex #-}
instance AtIndex (DVS.Vector Word16) where
#if !defined(BOUNDS_CHECKING_ENABLED)
(!!!) v i = DVS.unsafeIndex v (fromIntegral i)
atIndex v i = DVS.unsafeIndex v (fromIntegral i)
#else
(!!!) v i = v DVS.! fromIntegral i
atIndex v i = v DVS.! fromIntegral i
#endif
{-# INLINE (!!!) #-}
{-# INLINE atIndex #-}
instance AtIndex (DVS.Vector Word32) where
#if !defined(BOUNDS_CHECKING_ENABLED)
(!!!) v i = DVS.unsafeIndex v (fromIntegral i)
atIndex v i = DVS.unsafeIndex v (fromIntegral i)
#else
(!!!) v i = v DVS.! fromIntegral i
atIndex v i = v DVS.! fromIntegral i
#endif
{-# INLINE (!!!) #-}
{-# INLINE atIndex #-}
instance AtIndex (DVS.Vector Word64) where
#if !defined(BOUNDS_CHECKING_ENABLED)
(!!!) v i = DVS.unsafeIndex v (fromIntegral i)
atIndex v i = DVS.unsafeIndex v (fromIntegral i)
#else
(!!!) v i = v DVS.! fromIntegral i
atIndex v i = v DVS.! fromIntegral i
#endif
{-# INLINE (!!!) #-}
{-# INLINE atIndex #-}
instance AtIndex (DV.Vector Int8) where
#if !defined(BOUNDS_CHECKING_ENABLED)
(!!!) v i = DV.unsafeIndex v (fromIntegral i)
atIndex v i = DV.unsafeIndex v (fromIntegral i)
#else
(!!!) v i = v DV.! fromIntegral i
atIndex v i = v DV.! fromIntegral i
#endif
{-# INLINE (!!!) #-}
{-# INLINE atIndex #-}
instance AtIndex (DV.Vector Int16) where
#if !defined(BOUNDS_CHECKING_ENABLED)
(!!!) v i = DV.unsafeIndex v (fromIntegral i)
atIndex v i = DV.unsafeIndex v (fromIntegral i)
#else
(!!!) v i = v DV.! fromIntegral i
atIndex v i = v DV.! fromIntegral i
#endif
{-# INLINE (!!!) #-}
{-# INLINE atIndex #-}
instance AtIndex (DV.Vector Int32) where
#if !defined(BOUNDS_CHECKING_ENABLED)
(!!!) v i = DV.unsafeIndex v (fromIntegral i)
atIndex v i = DV.unsafeIndex v (fromIntegral i)
#else
(!!!) v i = v DV.! fromIntegral i
atIndex v i = v DV.! fromIntegral i
#endif
{-# INLINE (!!!) #-}
{-# INLINE atIndex #-}
instance AtIndex (DV.Vector Int64) where
#if !defined(BOUNDS_CHECKING_ENABLED)
(!!!) v i = DV.unsafeIndex v (fromIntegral i)
atIndex v i = DV.unsafeIndex v (fromIntegral i)
#else
(!!!) v i = v DV.! fromIntegral i
atIndex v i = v DV.! fromIntegral i
#endif
{-# INLINE (!!!) #-}
{-# INLINE atIndex #-}
instance AtIndex (DVS.Vector Int8) where
#if !defined(BOUNDS_CHECKING_ENABLED)
(!!!) v i = DVS.unsafeIndex v (fromIntegral i)
atIndex v i = DVS.unsafeIndex v (fromIntegral i)
#else
(!!!) v i = v DVS.! fromIntegral i
atIndex v i = v DVS.! fromIntegral i
#endif
{-# INLINE (!!!) #-}
{-# INLINE atIndex #-}
instance AtIndex (DVS.Vector Int16) where
#if !defined(BOUNDS_CHECKING_ENABLED)
(!!!) v i = DVS.unsafeIndex v (fromIntegral i)
atIndex v i = DVS.unsafeIndex v (fromIntegral i)
#else
(!!!) v i = v DVS.! fromIntegral i
atIndex v i = v DVS.! fromIntegral i
#endif
{-# INLINE (!!!) #-}
{-# INLINE atIndex #-}
instance AtIndex (DVS.Vector Int32) where
#if !defined(BOUNDS_CHECKING_ENABLED)
(!!!) v i = DVS.unsafeIndex v (fromIntegral i)
atIndex v i = DVS.unsafeIndex v (fromIntegral i)
#else
(!!!) v i = v DVS.! fromIntegral i
atIndex v i = v DVS.! fromIntegral i
#endif
{-# INLINE (!!!) #-}
{-# INLINE atIndex #-}
instance AtIndex (DVS.Vector Int64) where
#if !defined(BOUNDS_CHECKING_ENABLED)
(!!!) v i = DVS.unsafeIndex v (fromIntegral i)
atIndex v i = DVS.unsafeIndex v (fromIntegral i)
#else
(!!!) v i = v DVS.! fromIntegral i
atIndex v i = v DVS.! fromIntegral i
#endif
{-# INLINE (!!!) #-}
{-# INLINE atIndex #-}
instance AtIndex (DVS.Vector Int) where
#if !defined(BOUNDS_CHECKING_ENABLED)
(!!!) v i = DVS.unsafeIndex v (fromIntegral i)
atIndex v i = DVS.unsafeIndex v (fromIntegral i)
#else
(!!!) v i = v DVS.! fromIntegral i
atIndex v i = v DVS.! fromIntegral i
#endif
{-# INLINE (!!!) #-}
{-# INLINE atIndex #-}
atIndexOr :: AtIndex v => Elem v -> v -> Position -> Elem v
atIndexOr d v vi = if vi >= 0 && vi < end v
then v !!! vi
else d
{-# INLINE atIndexOr #-}
atIndexOrBeforeOrAfter :: AtIndex v => Elem v -> Elem v -> v -> Position -> Elem v
atIndexOrBeforeOrAfter before after v vi = if vi < end v
then if vi >= 0
then v !!! vi
else before
else after
{-# INLINE atIndexOrBeforeOrAfter #-}
atIndexOrBeforeOrLast :: (AtIndex v, Length v) => Elem v -> v -> Position -> Elem v
atIndexOrBeforeOrLast before v vi = if vi >= 0
then if vi < end v
then v !!! vi
else if end v /= 0
then v !!! (end v - 1)
else before
else before
{-# INLINE atIndexOrBeforeOrLast #-}