{-# 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 -- | 'Address' is the type used for addressing into the underlying memory buffers -- of numerical arrays, Used for Dense Rank n arrays, and 1dim sparse arrays. newtype Address = Address Int deriving (Eq,Ord,Show,Read,Typeable,Generic,Data,Store.Storable) -- | 'LogicalAddress' is -- possibly dead code newtype LogicalAddress = LogicalAddress Int deriving (Eq,Ord,Show,Read,Typeable,Generic,Data,Store.Storable) -- todo, add unboxed for -- | this m --newtype LogicalExtent -- sparse address seems to be dead atm data SparseAddress = SparseAddress { outerIndex :: {-# UNPACK #-} !Int ,innerIndex :: {-# UNPACK #-} !Int } deriving (Eq,Show,Data,Generic,Typeable) {- At some point decouple logical and physical address Logical Address should always be Int64 -- maybe even MORE?! physical address should be native IntPtr (aka Int) -} 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" {- note that -} {- note that i don't think these vector instances ever matter -} 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