packages feed

fixed-storable-array 0.1.0.0 → 0.2.0.0

raw patch · 3 files changed

+302/−300 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Data.Array.FixedStorableArray: N :: N
- Data.Array.FixedStorableArray: bounds :: Bounds d => FixedStorableArray d e -> (Bound d, Bound d)
- Data.Array.FixedStorableArray: class Bounds d where type family Bound d :: *
- Data.Array.FixedStorableArray: data FixedStorableArray dimensions e
- Data.Array.FixedStorableArray: data N (n :: Nat)
- Data.Array.FixedStorableArray: fromNat :: SingI n => proxy n -> Int
- Data.Array.FixedStorableArray: instance (Bounds d, Ix (Bound d), Storable e) => Storable (FixedStorableArray d e)
- Data.Array.FixedStorableArray: instance (SingI Nat a, SingI Nat b) => Bounds (N a, N b)
- Data.Array.FixedStorableArray: instance (SingI Nat a, SingI Nat b, SingI Nat c) => Bounds (N a, N b, N c)
- Data.Array.FixedStorableArray: instance (SingI Nat a, SingI Nat b, SingI Nat c, SingI Nat d) => Bounds (N a, N b, N c, N d)
- Data.Array.FixedStorableArray: instance (SingI Nat a, SingI Nat b, SingI Nat c, SingI Nat d, SingI Nat e) => Bounds (N a, N b, N c, N d, N e)
- Data.Array.FixedStorableArray: instance (SingI Nat a, SingI Nat b, SingI Nat c, SingI Nat d, SingI Nat e, SingI Nat f) => Bounds (N a, N b, N c, N d, N e, N f)
- Data.Array.FixedStorableArray: instance (SingI Nat a, SingI Nat b, SingI Nat c, SingI Nat d, SingI Nat e, SingI Nat f, SingI Nat g) => Bounds (N a, N b, N c, N d, N e, N f, N g)
- Data.Array.FixedStorableArray: instance (SingI Nat a, SingI Nat b, SingI Nat c, SingI Nat d, SingI Nat e, SingI Nat f, SingI Nat g, SingI Nat h) => Bounds (N a, N b, N c, N d, N e, N f, N g, N h)
- Data.Array.FixedStorableArray: instance (SingI Nat a, SingI Nat b, SingI Nat c, SingI Nat d, SingI Nat e, SingI Nat f, SingI Nat g, SingI Nat h, SingI Nat i) => Bounds (N a, N b, N c, N d, N e, N f, N g, N h, N i)
- Data.Array.FixedStorableArray: instance (SingI Nat a, SingI Nat b, SingI Nat c, SingI Nat d, SingI Nat e, SingI Nat f, SingI Nat g, SingI Nat h, SingI Nat i, SingI Nat j) => Bounds (N a, N b, N c, N d, N e, N f, N g, N h, N i, N j)
- Data.Array.FixedStorableArray: instance (SingI Nat a, SingI Nat b, SingI Nat c, SingI Nat d, SingI Nat e, SingI Nat f, SingI Nat g, SingI Nat h, SingI Nat i, SingI Nat j, SingI Nat k) => Bounds (N a, N b, N c, N d, N e, N f, N g, N h, N i, N j, N k)
- Data.Array.FixedStorableArray: instance (SingI Nat a, SingI Nat b, SingI Nat c, SingI Nat d, SingI Nat e, SingI Nat f, SingI Nat g, SingI Nat h, SingI Nat i, SingI Nat j, SingI Nat k, SingI Nat l) => Bounds (N a, N b, N c, N d, N e, N f, N g, N h, N i, N j, N k, N l)
- Data.Array.FixedStorableArray: instance (SingI Nat a, SingI Nat b, SingI Nat c, SingI Nat d, SingI Nat e, SingI Nat f, SingI Nat g, SingI Nat h, SingI Nat i, SingI Nat j, SingI Nat k, SingI Nat l, SingI Nat m) => Bounds (N a, N b, N c, N d, N e, N f, N g, N h, N i, N j, N k, N l, N m)
- Data.Array.FixedStorableArray: instance Enum (N n)
- Data.Array.FixedStorableArray: instance Eq (N n)
- Data.Array.FixedStorableArray: instance Ord (N n)
- Data.Array.FixedStorableArray: instance SingI Nat a => Bounds (N a)
- Data.Array.FixedStorableArray: instance SingI Nat n => Show (N n)
- Data.Array.FixedStorableArray: newFixedStorableArray :: (Bounds d, Ix (Bound d), Storable e) => e -> IO (FixedStorableArray d e)
- Data.Array.FixedStorableArray: newFixedStorableArray_ :: (Bounds d, Ix (Bound d), Storable e) => IO (FixedStorableArray d e)
- Data.Array.FixedStorableArray: toStorableArray :: FixedStorableArray dimensions e -> StorableArray (Bound dimensions) e
+ Foreign.Marshal.FixedStorableArray: N :: N
+ Foreign.Marshal.FixedStorableArray: bounds :: HasBounds d => FixedStorableArray d e -> (Bound d, Bound d)
+ Foreign.Marshal.FixedStorableArray: class HasBounds d where type family Bound d :: *
+ Foreign.Marshal.FixedStorableArray: data FixedStorableArray dimensions e
+ Foreign.Marshal.FixedStorableArray: data N (n :: Nat)
+ Foreign.Marshal.FixedStorableArray: fromNat :: SingI n => proxy n -> Int
+ Foreign.Marshal.FixedStorableArray: instance (HasBounds d, Ix (Bound d), Storable e) => Storable (FixedStorableArray d e)
+ Foreign.Marshal.FixedStorableArray: instance (SingI Nat a, SingI Nat b) => HasBounds (N a, N b)
+ Foreign.Marshal.FixedStorableArray: instance (SingI Nat a, SingI Nat b, SingI Nat c) => HasBounds (N a, N b, N c)
+ Foreign.Marshal.FixedStorableArray: instance (SingI Nat a, SingI Nat b, SingI Nat c, SingI Nat d) => HasBounds (N a, N b, N c, N d)
+ Foreign.Marshal.FixedStorableArray: instance (SingI Nat a, SingI Nat b, SingI Nat c, SingI Nat d, SingI Nat e) => HasBounds (N a, N b, N c, N d, N e)
+ Foreign.Marshal.FixedStorableArray: instance (SingI Nat a, SingI Nat b, SingI Nat c, SingI Nat d, SingI Nat e, SingI Nat f) => HasBounds (N a, N b, N c, N d, N e, N f)
+ Foreign.Marshal.FixedStorableArray: instance (SingI Nat a, SingI Nat b, SingI Nat c, SingI Nat d, SingI Nat e, SingI Nat f, SingI Nat g) => HasBounds (N a, N b, N c, N d, N e, N f, N g)
+ Foreign.Marshal.FixedStorableArray: instance (SingI Nat a, SingI Nat b, SingI Nat c, SingI Nat d, SingI Nat e, SingI Nat f, SingI Nat g, SingI Nat h) => HasBounds (N a, N b, N c, N d, N e, N f, N g, N h)
+ Foreign.Marshal.FixedStorableArray: instance (SingI Nat a, SingI Nat b, SingI Nat c, SingI Nat d, SingI Nat e, SingI Nat f, SingI Nat g, SingI Nat h, SingI Nat i) => HasBounds (N a, N b, N c, N d, N e, N f, N g, N h, N i)
+ Foreign.Marshal.FixedStorableArray: instance (SingI Nat a, SingI Nat b, SingI Nat c, SingI Nat d, SingI Nat e, SingI Nat f, SingI Nat g, SingI Nat h, SingI Nat i, SingI Nat j) => HasBounds (N a, N b, N c, N d, N e, N f, N g, N h, N i, N j)
+ Foreign.Marshal.FixedStorableArray: instance (SingI Nat a, SingI Nat b, SingI Nat c, SingI Nat d, SingI Nat e, SingI Nat f, SingI Nat g, SingI Nat h, SingI Nat i, SingI Nat j, SingI Nat k) => HasBounds (N a, N b, N c, N d, N e, N f, N g, N h, N i, N j, N k)
+ Foreign.Marshal.FixedStorableArray: instance (SingI Nat a, SingI Nat b, SingI Nat c, SingI Nat d, SingI Nat e, SingI Nat f, SingI Nat g, SingI Nat h, SingI Nat i, SingI Nat j, SingI Nat k, SingI Nat l) => HasBounds (N a, N b, N c, N d, N e, N f, N g, N h, N i, N j, N k, N l)
+ Foreign.Marshal.FixedStorableArray: instance (SingI Nat a, SingI Nat b, SingI Nat c, SingI Nat d, SingI Nat e, SingI Nat f, SingI Nat g, SingI Nat h, SingI Nat i, SingI Nat j, SingI Nat k, SingI Nat l, SingI Nat m) => HasBounds (N a, N b, N c, N d, N e, N f, N g, N h, N i, N j, N k, N l, N m)
+ Foreign.Marshal.FixedStorableArray: instance Enum (N n)
+ Foreign.Marshal.FixedStorableArray: instance Eq (N n)
+ Foreign.Marshal.FixedStorableArray: instance Ord (N n)
+ Foreign.Marshal.FixedStorableArray: instance SingI Nat a => HasBounds (N a)
+ Foreign.Marshal.FixedStorableArray: instance SingI Nat n => Show (N n)
+ Foreign.Marshal.FixedStorableArray: newFixedStorableArray :: (HasBounds d, Ix (Bound d), Storable e) => e -> IO (FixedStorableArray d e)
+ Foreign.Marshal.FixedStorableArray: newFixedStorableArray_ :: (HasBounds d, Ix (Bound d), Storable e) => IO (FixedStorableArray d e)
+ Foreign.Marshal.FixedStorableArray: toStorableArray :: FixedStorableArray dimensions e -> StorableArray (Bound dimensions) e

Files

− Data/Array/FixedStorableArray.hs
@@ -1,297 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE RecursiveDo #-}-{-|--This module exposes 'FixedStorableArray', a simple wrapper around-'StorableArray' that uses the @DataKinds@ extension to get type-level-numeric literals. These allow dimensions to be fully set by the type-at compile time. This has the added benefit of providing a 'Storable'-instance that significantly eases writing FFI bindings to fixed-size-native arrays.--For example, @'FixedStorableArray' ('N' 10) CInt@ has-a 'Storable' instance that is directly compatible with @int foo[10]@-in native code.--Multidimensional native arrays are also-supported. @'FixedStorableArray' ('N' 10, 'N' 20, 'N' 100) CUChar@ is compatible with @unsigned char foo[10][20][100]@.--Other than the 'Storable' instance, 'newFixedStorableArray', and-'newFixedStorableArray_', the only way to work with a-'FixedStorableArray' is to use 'toStorableArray' and operate on the-underlying 'StorableArray'. 'toStorableArray' generates a-'StorableArray' with the correct type and index values already in-place. For instance, the result of 'toStorableArray' on a-@'FixedStorableArray' ('N' 10, 'N' 20, 'N' 100) CUChar@ is a-@'StorableArray' (Int, Int, Int) CUChar@ with its bounds set-to @((0,0,0),(9,19,99))@.---}-module Data.Array.FixedStorableArray-       ( FixedStorableArray-       , newFixedStorableArray-       , newFixedStorableArray_-       , toStorableArray-       , N(..)-       , fromNat-       , Bounds(..)-       ) where--import GHC.TypeLits--import Data.Array.Storable-import Data.Functor          ((<$>))--import Foreign.Storable      (Storable(..))-import Foreign.Marshal.Array (copyArray)-import Foreign.Ptr           (castPtr)----- | This is a simple proxy type for type-level naturals. All--- dimension types use this type to store the size along that--- dimension.-data N (n :: Nat) = N deriving (Eq, Ord, Enum)-instance SingI n => Show (N n) where-    show N = "<N " ++ show (fromNat (N :: N n)) ++ ">"---- | A conversion function for converting type-level naturals to--- value-level. This is being exposed to aid in the creation of--- additional 'Bounds' instances for those who might desire to do--- so. Haddock is currently eating the important qualification that--- the type variable @n@ must have the kind 'Nat'.-fromNat :: forall (proxy :: Nat -> *) (n :: Nat). SingI n => proxy n -> Int-fromNat _ = fromInteger $ fromSing (sing :: Sing n)----- | A minimal wrapper for 'StorableArray' that encodes the full--- dimensions of the array in the type. Intended for interfacing with--- (possibly-)multidimensional arrays of fixed size in native code. To--- get most functionality, use 'toStorableArray'.-newtype FixedStorableArray dimensions e =-    FixedStorableArray {-        -- | Returns the backing 'StorableArray' of this-        -- 'FixedStorableArray'. The backing array is shared across-        -- all invocations of this. Modifications to it will be seen-        -- across all uses of this 'FixedStorableArray'.-        toStorableArray :: StorableArray (Bound dimensions) e }---- | This class connects dimension descriptions with 'StorableArray'--- index types and values.-class Bounds d where-    -- | The bounding type for this dimension description-    type Bound d :: *-    -- | The concrete bounds for this dimension-    bounds :: FixedStorableArray d e -> (Bound d, Bound d)---- | Create a 'FixedStorableArray' and populate it with copies of the--- element passed in. Dimensions will be determined from the return--- type.-newFixedStorableArray :: (Bounds d, Ix (Bound d), Storable e) =>-                         e -> IO (FixedStorableArray d e)-newFixedStorableArray x = do-    rec let b = bounds ma-        ma <- FixedStorableArray <$> newArray b x-    return ma---- | Create a 'FixedStorableArray' and don't populate it with anything--- in particular. Contents may or may not be initialized to anything--- at all. Dimensions will be determined from the return type.-newFixedStorableArray_ :: (Bounds d, Ix (Bound d), Storable e) =>-                          IO (FixedStorableArray d e)-newFixedStorableArray_ = do-    rec let b = bounds ma-        ma <- FixedStorableArray <$> newArray_ b-    return ma--instance (Bounds d, Ix (Bound d), Storable e) =>-         Storable (FixedStorableArray d e) where-    sizeOf a = sizeOf (undefined :: e) * rangeSize (bounds a)-    alignment _ = alignment (undefined :: e)-    peek src' = do-        ma <- newFixedStorableArray_-        let sa = toStorableArray ma-            src = castPtr src'-        count <- rangeSize <$> getBounds sa-        withStorableArray sa $ \dst -> copyArray dst src count-        return ma-    poke dst' ma = do-        let sa = toStorableArray ma-            dst = castPtr dst'-        count <- rangeSize <$> getBounds sa-        withStorableArray sa $ \src -> copyArray dst src count---------------------------------------------------------------------------------- Bounds instances. More can be written, trivially - it's just a matter--- of whether they'll ever actually be used.--instance SingI a => Bounds (N a) where-    type Bound (N a) = Int-    bounds _ = (0, fromNat (N :: N a) - 1)--instance (SingI a, SingI b) => Bounds (N a, N b) where-    type Bound (N a, N b) = (Int, Int)-    bounds _ = ((0, 0),-                (fromNat (N :: N a) - 1,-                 fromNat (N :: N b) - 1))--instance (SingI a, SingI b, SingI c) => Bounds (N a, N b, N c) where-    type Bound (N a, N b, N c) = (Int, Int, Int)-    bounds _ = ((0, 0, 0),-                (fromNat (N :: N a) - 1,-                 fromNat (N :: N b) - 1,-                 fromNat (N :: N c) - 1))--instance (SingI a, SingI b, SingI c, SingI d) => Bounds (N a, N b, N c, N d) where-    type Bound (N a, N b, N c, N d) = (Int, Int, Int, Int)-    bounds _ = ((0, 0, 0, 0),-                (fromNat (N :: N a) - 1,-                 fromNat (N :: N b) - 1,-                 fromNat (N :: N c) - 1,-                 fromNat (N :: N d) - 1))--instance (SingI a, SingI b, SingI c, SingI d, SingI e) =>-         Bounds (N a, N b, N c, N d, N e) where-    type Bound (N a, N b, N c, N d, N e) = (Int, Int, Int, Int, Int)-    bounds _ = ((0, 0, 0, 0, 0),-                (fromNat (N :: N a) - 1,-                 fromNat (N :: N b) - 1,-                 fromNat (N :: N c) - 1,-                 fromNat (N :: N d) - 1,-                 fromNat (N :: N e) - 1))--instance (SingI a, SingI b, SingI c, SingI d, SingI e, SingI f) =>-         Bounds (N a, N b, N c, N d, N e, N f) where-    type Bound (N a, N b, N c, N d, N e, N f) = (Int, Int, Int, Int, Int, Int)-    bounds _ = ((0, 0, 0, 0, 0, 0),-                (fromNat (N :: N a) - 1,-                 fromNat (N :: N b) - 1,-                 fromNat (N :: N c) - 1,-                 fromNat (N :: N d) - 1,-                 fromNat (N :: N e) - 1,-                 fromNat (N :: N f) - 1))--instance (SingI a, SingI b, SingI c, SingI d, SingI e, SingI f, SingI g) =>-         Bounds (N a, N b, N c, N d, N e, N f, N g) where-    type Bound (N a, N b, N c, N d, N e, N f, N g) =-        (Int, Int, Int, Int, Int, Int, Int)-    bounds _ = ((0, 0, 0, 0, 0, 0, 0),-                (fromNat (N :: N a) - 1,-                 fromNat (N :: N b) - 1,-                 fromNat (N :: N c) - 1,-                 fromNat (N :: N d) - 1,-                 fromNat (N :: N e) - 1,-                 fromNat (N :: N f) - 1,-                 fromNat (N :: N g) - 1))--instance (SingI a, SingI b, SingI c, SingI d, SingI e, SingI f, SingI g,-          SingI h) =>-         Bounds (N a, N b, N c, N d, N e, N f, N g, N h) where-    type Bound (N a, N b, N c, N d, N e, N f, N g, N h) =-        (Int, Int, Int, Int, Int, Int, Int, Int)-    bounds _ = ((0, 0, 0, 0, 0, 0, 0, 0),-                (fromNat (N :: N a) - 1,-                 fromNat (N :: N b) - 1,-                 fromNat (N :: N c) - 1,-                 fromNat (N :: N d) - 1,-                 fromNat (N :: N e) - 1,-                 fromNat (N :: N f) - 1,-                 fromNat (N :: N g) - 1,-                 fromNat (N :: N h) - 1))--instance (SingI a, SingI b, SingI c, SingI d, SingI e, SingI f, SingI g,-          SingI h, SingI i) =>-         Bounds (N a, N b, N c, N d, N e, N f, N g, N h, N i) where-    type Bound (N a, N b, N c, N d, N e, N f, N g, N h, N i) =-        (Int, Int, Int, Int, Int, Int, Int, Int, Int)-    bounds _ = ((0, 0, 0, 0, 0, 0, 0, 0, 0),-                (fromNat (N :: N a) - 1,-                 fromNat (N :: N b) - 1,-                 fromNat (N :: N c) - 1,-                 fromNat (N :: N d) - 1,-                 fromNat (N :: N e) - 1,-                 fromNat (N :: N f) - 1,-                 fromNat (N :: N g) - 1,-                 fromNat (N :: N h) - 1,-                 fromNat (N :: N i) - 1))--instance (SingI a, SingI b, SingI c, SingI d, SingI e, SingI f, SingI g,-          SingI h, SingI i, SingI j) =>-         Bounds (N a, N b, N c, N d, N e, N f, N g, N h, N i, N j) where-    type Bound (N a, N b, N c, N d, N e, N f, N g, N h, N i, N j) =-        (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)-    bounds _ = ((0, 0, 0, 0, 0, 0, 0, 0, 0, 0),-                (fromNat (N :: N a) - 1,-                 fromNat (N :: N b) - 1,-                 fromNat (N :: N c) - 1,-                 fromNat (N :: N d) - 1,-                 fromNat (N :: N e) - 1,-                 fromNat (N :: N f) - 1,-                 fromNat (N :: N g) - 1,-                 fromNat (N :: N h) - 1,-                 fromNat (N :: N i) - 1,-                 fromNat (N :: N j) - 1))--instance (SingI a, SingI b, SingI c, SingI d, SingI e, SingI f, SingI g,-          SingI h, SingI i, SingI j, SingI k) =>-         Bounds (N a, N b, N c, N d, N e, N f, N g, N h, N i, N j, N k) where-    type Bound (N a, N b, N c, N d, N e, N f, N g, N h, N i, N j, N k) =-        (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)-    bounds _ = ((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),-                (fromNat (N :: N a) - 1,-                 fromNat (N :: N b) - 1,-                 fromNat (N :: N c) - 1,-                 fromNat (N :: N d) - 1,-                 fromNat (N :: N e) - 1,-                 fromNat (N :: N f) - 1,-                 fromNat (N :: N g) - 1,-                 fromNat (N :: N h) - 1,-                 fromNat (N :: N i) - 1,-                 fromNat (N :: N j) - 1,-                 fromNat (N :: N k) - 1))--instance (SingI a, SingI b, SingI c, SingI d, SingI e, SingI f, SingI g,-          SingI h, SingI i, SingI j, SingI k, SingI l) =>-         Bounds (N a, N b, N c, N d, N e, N f, N g, N h, N i, N j, N k,-                 N l) where-    type Bound (N a, N b, N c, N d, N e, N f, N g, N h, N i, N j, N k, N l) =-        (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)-    bounds _ = ((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),-                (fromNat (N :: N a) - 1,-                 fromNat (N :: N b) - 1,-                 fromNat (N :: N c) - 1,-                 fromNat (N :: N d) - 1,-                 fromNat (N :: N e) - 1,-                 fromNat (N :: N f) - 1,-                 fromNat (N :: N g) - 1,-                 fromNat (N :: N h) - 1,-                 fromNat (N :: N i) - 1,-                 fromNat (N :: N j) - 1,-                 fromNat (N :: N k) - 1,-                 fromNat (N :: N l) - 1))--instance (SingI a, SingI b, SingI c, SingI d, SingI e, SingI f, SingI g,-          SingI h, SingI i, SingI j, SingI k, SingI l, SingI m) =>-         Bounds (N a, N b, N c, N d, N e, N f, N g, N h, N i, N j, N k, N l,-                 N m) where-    type Bound (N a, N b, N c, N d, N e, N f, N g, N h, N i, N j, N k, N l,-                N m) =-         (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)-    bounds _ = ((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),-                (fromNat (N :: N a) - 1,-                 fromNat (N :: N b) - 1,-                 fromNat (N :: N c) - 1,-                 fromNat (N :: N d) - 1,-                 fromNat (N :: N e) - 1,-                 fromNat (N :: N f) - 1,-                 fromNat (N :: N g) - 1,-                 fromNat (N :: N h) - 1,-                 fromNat (N :: N i) - 1,-                 fromNat (N :: N j) - 1,-                 fromNat (N :: N k) - 1,-                 fromNat (N :: N l) - 1,-                 fromNat (N :: N m) - 1))
+ Foreign/Marshal/FixedStorableArray.hs view
@@ -0,0 +1,299 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE RecursiveDo #-}+{-|++This module exposes 'FixedStorableArray', a simple wrapper around+'StorableArray' that uses the @DataKinds@ extension to get type-level+numeric literals. These allow dimensions to be fully set by the type+at compile time. 'FixedStorableArray' provides a 'Storable' instance+that significantly eases writing FFI bindings to fixed-size native+arrays.++For example, @'FixedStorableArray' ('N' 10) CInt@ has+a 'Storable' instance that is directly compatible with @int foo[10]@+in native code.++Multidimensional native arrays are also+supported. @'FixedStorableArray' ('N' 10, 'N' 20, 'N' 100) CUChar@ is+compatible with @unsigned char foo[10][20][100]@.++Other than the 'Storable' instance, 'newFixedStorableArray', and+'newFixedStorableArray_', the only way to work with a+'FixedStorableArray' is to use 'toStorableArray' and operate on the+underlying 'StorableArray'. 'toStorableArray' generates a+'StorableArray' with the correct type and index values already in+place. For instance, the result of 'toStorableArray' on a+@'FixedStorableArray' ('N' 10, 'N' 20, 'N' 100) CUChar@ is a+@'StorableArray' (Int, Int, Int) CUChar@ with its bounds set+to @((0,0,0),(9,19,99))@.++-}+module Foreign.Marshal.FixedStorableArray+       ( FixedStorableArray+       , newFixedStorableArray+       , newFixedStorableArray_+       , toStorableArray+       , N(..)+       , fromNat+       , HasBounds(..)+       ) where++import GHC.TypeLits++import Data.Array.Storable+import Data.Functor          ((<$>))++import Foreign.Storable      (Storable(..))+import Foreign.Marshal.Array (copyArray)+import Foreign.Ptr           (castPtr)+++-- | This is a simple proxy type for type-level naturals. All+-- dimension types use this type to store the size along that+-- dimension.+data N (n :: Nat) = N deriving (Eq, Ord, Enum)+instance SingI n => Show (N n) where+    show N = "<N " ++ show (fromNat (N :: N n)) ++ ">"++-- | A conversion function for converting type-level naturals to+-- value-level. This is being exposed to aid in the creation of+-- additional 'HasBounds' instances for those who might desire to do+-- so. Haddock is currently eating the important qualification that+-- the type variable @n@ must have the kind 'Nat'.+fromNat :: forall (proxy :: Nat -> *) (n :: Nat). SingI n => proxy n -> Int+fromNat _ = fromInteger $ fromSing (sing :: Sing n)+++-- | A minimal wrapper for 'StorableArray' that encodes the full+-- dimensions of the array in the type. Intended for interfacing with+-- (possibly-)multidimensional arrays of fixed size in native code. To+-- get most functionality, use 'toStorableArray'.+newtype FixedStorableArray dimensions e =+    FixedStorableArray {+        -- | Returns the backing 'StorableArray' of this+        -- 'FixedStorableArray'. The backing array is shared across+        -- all invocations of this. Modifications to it will be seen+        -- across all uses of this 'FixedStorableArray'.+        toStorableArray :: StorableArray (Bound dimensions) e }++-- | This class connects dimension descriptions with 'StorableArray'+-- index types and values.+class HasBounds d where+    -- | The bounding type for this dimension description+    type Bound d :: *+    -- | The concrete bounds for this dimension+    bounds :: FixedStorableArray d e -> (Bound d, Bound d)++-- | Create a 'FixedStorableArray' and populate it with copies of the+-- element passed in. Dimensions will be determined from the return+-- type.+newFixedStorableArray :: (HasBounds d, Ix (Bound d), Storable e) =>+                         e -> IO (FixedStorableArray d e)+newFixedStorableArray x = do+    rec let b = bounds ma+        ma <- FixedStorableArray <$> newArray b x+    return ma++-- | Create a 'FixedStorableArray' and don't populate it with anything+-- in particular. Contents may or may not be initialized to anything+-- at all. Dimensions will be determined from the return type.+newFixedStorableArray_ :: (HasBounds d, Ix (Bound d), Storable e) =>+                          IO (FixedStorableArray d e)+newFixedStorableArray_ = do+    rec let b = bounds ma+        ma <- FixedStorableArray <$> newArray_ b+    return ma++instance (HasBounds d, Ix (Bound d), Storable e) =>+         Storable (FixedStorableArray d e) where+    sizeOf a = sizeOf (undefined :: e) * rangeSize (bounds a)+    alignment _ = alignment (undefined :: e)+    peek src' = do+        ma <- newFixedStorableArray_+        let sa = toStorableArray ma+            src = castPtr src'+        count <- rangeSize <$> getBounds sa+        withStorableArray sa $ \dst -> copyArray dst src count+        return ma+    poke dst' ma = do+        let sa = toStorableArray ma+            dst = castPtr dst'+        count <- rangeSize <$> getBounds sa+        withStorableArray sa $ \src -> copyArray dst src count+++----------------------------------------------------------------------------+-- HasBounds instances. More can be written, trivially - it's just a matter+-- of whether they'll ever actually be used.++instance SingI a => HasBounds (N a) where+    type Bound (N a) = Int+    bounds _ = (0, fromNat (N :: N a) - 1)++instance (SingI a, SingI b) => HasBounds (N a, N b) where+    type Bound (N a, N b) = (Int, Int)+    bounds _ = ((0, 0),+                (fromNat (N :: N a) - 1,+                 fromNat (N :: N b) - 1))++instance (SingI a, SingI b, SingI c) => HasBounds (N a, N b, N c) where+    type Bound (N a, N b, N c) = (Int, Int, Int)+    bounds _ = ((0, 0, 0),+                (fromNat (N :: N a) - 1,+                 fromNat (N :: N b) - 1,+                 fromNat (N :: N c) - 1))++instance (SingI a, SingI b, SingI c, SingI d) =>+         HasBounds (N a, N b, N c, N d) where+    type Bound (N a, N b, N c, N d) = (Int, Int, Int, Int)+    bounds _ = ((0, 0, 0, 0),+                (fromNat (N :: N a) - 1,+                 fromNat (N :: N b) - 1,+                 fromNat (N :: N c) - 1,+                 fromNat (N :: N d) - 1))++instance (SingI a, SingI b, SingI c, SingI d, SingI e) =>+         HasBounds (N a, N b, N c, N d, N e) where+    type Bound (N a, N b, N c, N d, N e) = (Int, Int, Int, Int, Int)+    bounds _ = ((0, 0, 0, 0, 0),+                (fromNat (N :: N a) - 1,+                 fromNat (N :: N b) - 1,+                 fromNat (N :: N c) - 1,+                 fromNat (N :: N d) - 1,+                 fromNat (N :: N e) - 1))++instance (SingI a, SingI b, SingI c, SingI d, SingI e, SingI f) =>+         HasBounds (N a, N b, N c, N d, N e, N f) where+    type Bound (N a, N b, N c, N d, N e, N f) = (Int, Int, Int, Int, Int, Int)+    bounds _ = ((0, 0, 0, 0, 0, 0),+                (fromNat (N :: N a) - 1,+                 fromNat (N :: N b) - 1,+                 fromNat (N :: N c) - 1,+                 fromNat (N :: N d) - 1,+                 fromNat (N :: N e) - 1,+                 fromNat (N :: N f) - 1))++instance (SingI a, SingI b, SingI c, SingI d, SingI e, SingI f, SingI g) =>+         HasBounds (N a, N b, N c, N d, N e, N f, N g) where+    type Bound (N a, N b, N c, N d, N e, N f, N g) =+        (Int, Int, Int, Int, Int, Int, Int)+    bounds _ = ((0, 0, 0, 0, 0, 0, 0),+                (fromNat (N :: N a) - 1,+                 fromNat (N :: N b) - 1,+                 fromNat (N :: N c) - 1,+                 fromNat (N :: N d) - 1,+                 fromNat (N :: N e) - 1,+                 fromNat (N :: N f) - 1,+                 fromNat (N :: N g) - 1))++instance (SingI a, SingI b, SingI c, SingI d, SingI e, SingI f, SingI g,+          SingI h) =>+         HasBounds (N a, N b, N c, N d, N e, N f, N g, N h) where+    type Bound (N a, N b, N c, N d, N e, N f, N g, N h) =+        (Int, Int, Int, Int, Int, Int, Int, Int)+    bounds _ = ((0, 0, 0, 0, 0, 0, 0, 0),+                (fromNat (N :: N a) - 1,+                 fromNat (N :: N b) - 1,+                 fromNat (N :: N c) - 1,+                 fromNat (N :: N d) - 1,+                 fromNat (N :: N e) - 1,+                 fromNat (N :: N f) - 1,+                 fromNat (N :: N g) - 1,+                 fromNat (N :: N h) - 1))++instance (SingI a, SingI b, SingI c, SingI d, SingI e, SingI f, SingI g,+          SingI h, SingI i) =>+         HasBounds (N a, N b, N c, N d, N e, N f, N g, N h, N i) where+    type Bound (N a, N b, N c, N d, N e, N f, N g, N h, N i) =+        (Int, Int, Int, Int, Int, Int, Int, Int, Int)+    bounds _ = ((0, 0, 0, 0, 0, 0, 0, 0, 0),+                (fromNat (N :: N a) - 1,+                 fromNat (N :: N b) - 1,+                 fromNat (N :: N c) - 1,+                 fromNat (N :: N d) - 1,+                 fromNat (N :: N e) - 1,+                 fromNat (N :: N f) - 1,+                 fromNat (N :: N g) - 1,+                 fromNat (N :: N h) - 1,+                 fromNat (N :: N i) - 1))++instance (SingI a, SingI b, SingI c, SingI d, SingI e, SingI f, SingI g,+          SingI h, SingI i, SingI j) =>+         HasBounds (N a, N b, N c, N d, N e, N f, N g, N h, N i, N j) where+    type Bound (N a, N b, N c, N d, N e, N f, N g, N h, N i, N j) =+        (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)+    bounds _ = ((0, 0, 0, 0, 0, 0, 0, 0, 0, 0),+                (fromNat (N :: N a) - 1,+                 fromNat (N :: N b) - 1,+                 fromNat (N :: N c) - 1,+                 fromNat (N :: N d) - 1,+                 fromNat (N :: N e) - 1,+                 fromNat (N :: N f) - 1,+                 fromNat (N :: N g) - 1,+                 fromNat (N :: N h) - 1,+                 fromNat (N :: N i) - 1,+                 fromNat (N :: N j) - 1))++instance (SingI a, SingI b, SingI c, SingI d, SingI e, SingI f, SingI g,+          SingI h, SingI i, SingI j, SingI k) =>+         HasBounds (N a, N b, N c, N d, N e, N f, N g, N h, N i, N j, N k) where+    type Bound (N a, N b, N c, N d, N e, N f, N g, N h, N i, N j, N k) =+        (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)+    bounds _ = ((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),+                (fromNat (N :: N a) - 1,+                 fromNat (N :: N b) - 1,+                 fromNat (N :: N c) - 1,+                 fromNat (N :: N d) - 1,+                 fromNat (N :: N e) - 1,+                 fromNat (N :: N f) - 1,+                 fromNat (N :: N g) - 1,+                 fromNat (N :: N h) - 1,+                 fromNat (N :: N i) - 1,+                 fromNat (N :: N j) - 1,+                 fromNat (N :: N k) - 1))++instance (SingI a, SingI b, SingI c, SingI d, SingI e, SingI f, SingI g,+          SingI h, SingI i, SingI j, SingI k, SingI l) =>+         HasBounds (N a, N b, N c, N d, N e, N f, N g, N h, N i, N j, N k,+                    N l) where+    type Bound (N a, N b, N c, N d, N e, N f, N g, N h, N i, N j, N k, N l) =+        (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)+    bounds _ = ((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),+                (fromNat (N :: N a) - 1,+                 fromNat (N :: N b) - 1,+                 fromNat (N :: N c) - 1,+                 fromNat (N :: N d) - 1,+                 fromNat (N :: N e) - 1,+                 fromNat (N :: N f) - 1,+                 fromNat (N :: N g) - 1,+                 fromNat (N :: N h) - 1,+                 fromNat (N :: N i) - 1,+                 fromNat (N :: N j) - 1,+                 fromNat (N :: N k) - 1,+                 fromNat (N :: N l) - 1))++instance (SingI a, SingI b, SingI c, SingI d, SingI e, SingI f, SingI g,+          SingI h, SingI i, SingI j, SingI k, SingI l, SingI m) =>+         HasBounds (N a, N b, N c, N d, N e, N f, N g, N h, N i, N j, N k, N l,+                    N m) where+    type Bound (N a, N b, N c, N d, N e, N f, N g, N h, N i, N j, N k, N l,+                N m) =+         (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)+    bounds _ = ((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),+                (fromNat (N :: N a) - 1,+                 fromNat (N :: N b) - 1,+                 fromNat (N :: N c) - 1,+                 fromNat (N :: N d) - 1,+                 fromNat (N :: N e) - 1,+                 fromNat (N :: N f) - 1,+                 fromNat (N :: N g) - 1,+                 fromNat (N :: N h) - 1,+                 fromNat (N :: N i) - 1,+                 fromNat (N :: N j) - 1,+                 fromNat (N :: N k) - 1,+                 fromNat (N :: N l) - 1,+                 fromNat (N :: N m) - 1))
fixed-storable-array.cabal view
@@ -1,5 +1,5 @@ name:                fixed-storable-array-version:             0.1.0.0+version:             0.2.0.0 synopsis:            Fixed-size wrapper for StorableArrays, with its own                      Storable instance description:         Uses type-level numeric literals to wrap @StorableArray@@@ -11,7 +11,7 @@ license-file:        LICENSE author:              Carl Howells maintainer:          chowells79@gmail.com-category:            Data+category:            FFI build-type:          Simple cabal-version:       >=1.8 @@ -20,6 +20,6 @@   location:          https://github.com/chowells79/fixed-storable-array.git  library-  exposed-modules:   Data.Array.FixedStorableArray+  exposed-modules:   Foreign.Marshal.FixedStorableArray   build-depends:     base ==4.6.*, array ==0.4.*   ghc-options:       -Wall