{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Numerical.Array.Address(
Address(..)
,SparseAddress(..)
) where
import Data.Data
import Control.Monad (liftM)
import qualified Foreign.Storable as Store
import qualified Data.Vector.Unboxed as UV
import qualified Data.Vector.Generic as GV
import qualified Data.Vector.Generic.Mutable as GMV
import GHC.Generics
newtype Address = Address Int
deriving (Eq,Ord,Show,Read,Typeable,Generic,Data,Store.Storable)
newtype LogicalAddress = LogicalAddress Int
deriving (Eq,Ord,Show,Read,Typeable,Generic,Data,Store.Storable)
data SparseAddress = SparseAddress {
outerIndex :: {-# UNPACK #-} !Int
,innerIndex :: {-# UNPACK #-} !Int }
deriving (Eq,Show,Data,Generic,Typeable)
instance Num Address where
{-# INLINE (+) #-}
(+) (Address a) (Address b) = Address (a+b)
{-# INLINE (-) #-}
(-) (Address a) (Address b) = Address (a-b)
(*) _ _ = error "you cant multiply Addresses"
negate _ = error "you cant Apply Negate to An Address"
signum _ = error "error you cant take signum of an Address"
abs _ = error "error you cant take abs of an Address"
fromInteger _ = error "you cant use Integer Literals or fromInteger to form an Address"
newtype instance UV.MVector s Address = MV_Address (UV.MVector s Int)
newtype instance UV.Vector Address = V_Address (UV.Vector Int)
instance UV.Unbox Address where
instance GMV.MVector UV.MVector Address where
{-# INLINE basicLength #-}
{-# INLINE basicUnsafeSlice #-}
{-# INLINE basicOverlaps #-}
{-# INLINE basicUnsafeNew #-}
{-# INLINE basicUnsafeReplicate #-}
{-# INLINE basicUnsafeRead #-}
{-# INLINE basicUnsafeWrite #-}
{-# INLINE basicClear #-}
{-# INLINE basicSet #-}
{-# INLINE basicUnsafeCopy #-}
{-# INLINE basicUnsafeGrow #-}
{-# INLINE basicInitialize #-}
basicInitialize = \ (MV_Address mva) -> GMV.basicInitialize mva
basicLength (MV_Address v) = GMV.basicLength v
basicUnsafeSlice i n (MV_Address v) = MV_Address $ GMV.basicUnsafeSlice i n v
basicOverlaps (MV_Address v1) (MV_Address v2) = GMV.basicOverlaps v1 v2
basicUnsafeNew n = MV_Address `liftM` GMV.basicUnsafeNew n
basicUnsafeReplicate n (Address a) = MV_Address `liftM` GMV.basicUnsafeReplicate n a
basicUnsafeRead (MV_Address v) i = Address `liftM` GMV.basicUnsafeRead v i
basicUnsafeWrite (MV_Address v) i (Address a) = GMV.basicUnsafeWrite v i a
basicClear (MV_Address v) = GMV.basicClear v
basicSet (MV_Address v) (Address a) = GMV.basicSet v a
basicUnsafeCopy (MV_Address v1) (MV_Address v2) = GMV.basicUnsafeCopy v1 v2
basicUnsafeMove (MV_Address v1) (MV_Address v2) = GMV.basicUnsafeMove v1 v2
basicUnsafeGrow (MV_Address v) n = MV_Address `liftM` GMV.basicUnsafeGrow v n
instance GV.Vector UV.Vector Address where
{-# INLINE basicUnsafeFreeze #-}
{-# INLINE basicUnsafeThaw #-}
{-# INLINE basicLength #-}
{-# INLINE basicUnsafeSlice #-}
{-# INLINE basicUnsafeIndexM #-}
{-# INLINE elemseq #-}
basicUnsafeFreeze (MV_Address v) = V_Address `liftM` GV.basicUnsafeFreeze v
basicUnsafeThaw (V_Address v) = MV_Address`liftM` GV.basicUnsafeThaw v
basicLength (V_Address v) = GV.basicLength v
basicUnsafeSlice i n (V_Address v) = V_Address $ GV.basicUnsafeSlice i n v
basicUnsafeIndexM (V_Address v) i
= Address `liftM` GV.basicUnsafeIndexM v i
basicUnsafeCopy (MV_Address mv) (V_Address v)
= GV.basicUnsafeCopy mv v
elemseq _ (Address a) z = GV.elemseq (undefined :: UV.Vector a) a z