primitive-offset (empty) → 0.1.0.0
raw patch · 6 files changed
+148/−0 lines, 6 filesdep +basedep +primitivesetup-changed
Dependencies added: base, primitive
Files
- CHANGELOG.md +5/−0
- LICENSE +30/−0
- Setup.hs +2/−0
- primitive-offset.cabal +23/−0
- src/Data/Primitive/ByteArray/Offset.hs +23/−0
- src/Data/Primitive/PrimArray/Offset.hs +65/−0
+ CHANGELOG.md view
@@ -0,0 +1,5 @@+# Revision history for primitive-element++## 0.1.0.0 -- YYYY-mm-dd++* First version. Released on an unsuspecting world.
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2019, Andrew Martin++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Andrew Martin nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ primitive-offset.cabal view
@@ -0,0 +1,23 @@+cabal-version: 2.2+name: primitive-offset+version: 0.1.0.0+synopsis: Types for offsets into unboxed arrays+homepage: https://github.com/andrewthad/primitive-offset+bug-reports: https://github.com/andrewthad/primitive-offset/issues+license: BSD-3-Clause+license-file: LICENSE+author: Andrew Martin+maintainer: andrew.thaddeus@gmail.com+copyright: 2019 Andrew Martin+category: Data+extra-source-files: CHANGELOG.md++library+ exposed-modules:+ Data.Primitive.PrimArray.Offset+ Data.Primitive.ByteArray.Offset+ build-depends:+ , base >=4.11.1.0 && <5+ , primitive >= 0.6.4+ hs-source-dirs: src+ default-language: Haskell2010
+ src/Data/Primitive/ByteArray/Offset.hs view
@@ -0,0 +1,23 @@+{-# language DuplicateRecordFields #-}+module Data.Primitive.ByteArray.Offset+ ( -- * Types+ ByteArrayOffset(..)+ , MutableByteArrayOffset(..)+ ) where++import Control.Monad.Primitive (PrimMonad,PrimState)+import Data.Primitive (ByteArray,MutableByteArray)++-- | A byte array and an index into the array. The element+-- type is understood to be byte (an 8-bit word).+data ByteArrayOffset = ByteArrayOffset+ { array :: {-# UNPACK #-} !ByteArray+ , index :: {-# UNPACK #-} !Int+ }++-- | A mutable byte array and an index into the array. The element+-- type is understood to be byte (an 8-bit word).+data MutableByteArrayOffset s = MutableByteArrayOffset+ { array :: {-# UNPACK #-} !(MutableByteArray s)+ , index :: {-# UNPACK #-} !Int+ }
+ src/Data/Primitive/PrimArray/Offset.hs view
@@ -0,0 +1,65 @@+{-# language DuplicateRecordFields #-}++-- | Data types for describing an array paired with an index+-- into it. This is intended to be used in wrappers for @unsafe@+-- FFI calls. For example, the POSIX function @recvfrom@ takes+-- a @socklen_t*@ argument. (Let us assume that @socklen_t@+-- is equivalant to @int@ for this example.) How is this argument best+-- described by a Haskell type? When working with pinned memory,+-- the best option @'Ptr' 'CInt'@.+-- It works equally well regardless of whether we originally had an+-- array of 'CInt' or a pointer to a single 'CInt'. This works because+-- of functions like 'Data.Primitive.advancePtr' and+-- 'Foreign.Ptr.plusPtr' that effectively index into an array.+-- Unpinned memory, however, is trickier. We want to have the full+-- flexibility (handling both a single-element or+-- multi-element buffer) that @'Ptr' 'CInt'@ affords. We cannot+-- offset into a 'MutablePrimArray' to get a new one like we+-- could with 'Ptr'. (Such a function is not possible because+-- unpinned memory can be relocated.) So, the offseting must+-- be done in the C function wrapped by the @unsafe@ FFI. This+-- means that the offset must be passed together with the+-- 'MutablePrimArray'. This is the precisely the product that+-- 'MutablePrimArrayOffset' represents. In a type signature, it+-- provides additional clarity about the meaning of the offset.+--+-- This library is used in the extensively in the @posix-api@+-- library to clarify intent in a number of type signatures.+module Data.Primitive.PrimArray.Offset+ ( -- * Types+ PrimArrayOffset(..)+ , MutablePrimArrayOffset(..)+ -- * Resolution+ , indexOffset+ , readOffset+ ) where++import Control.Monad.Primitive (PrimMonad,PrimState)+import Data.Primitive (Prim,PrimArray,MutablePrimArray)+import Data.Primitive (indexPrimArray,readPrimArray)++-- | A primitive array and an index into the array.+data PrimArrayOffset a = PrimArrayOffset+ { array :: {-# UNPACK #-} !(PrimArray a)+ , index :: {-# UNPACK #-} !Int+ }++-- | A mutable primitive array and an index into the array.+data MutablePrimArrayOffset s a = MutablePrimArrayOffset+ { array :: {-# UNPACK #-} !(MutablePrimArray s a)+ , index :: {-# UNPACK #-} !Int+ }++-- | Recover the element in the primitive array.+indexOffset :: Prim a+ => PrimArrayOffset a+ -> a+{-# inline indexOffset #-}+indexOffset (PrimArrayOffset arr ix) = indexPrimArray arr ix++-- | Recover the element in the mutable primitive array.+readOffset :: (PrimMonad m, Prim a)+ => MutablePrimArrayOffset (PrimState m) a+ -> m a+{-# inline readOffset #-}+readOffset (MutablePrimArrayOffset arr ix) = readPrimArray arr ix