{-# OPTIONS_HADDOCK hide                #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE FlexibleInstances          #-}
{-# LANGUAGE ForeignFunctionInterface   #-}
{-# LANGUAGE DataKinds                  #-}
{-# LANGUAGE ConstraintKinds            #-}
{-# LANGUAGE TypeFamilies               #-}
{-# LANGUAGE CPP                        #-}


-- | This module exposes types that builds in type safety into some of
-- the low level pointer operations. The functions here are pretty low
-- level and will be required only by developers of the core of the
-- library.
module Raaz.Core.Types.Pointer
       ( -- * Pointers, offsets, and alignment
         -- $basics$
         -- ** Type safe length units.
         LengthUnit(..)
       , BYTES(..)
         -- *** Some length functions.
       , atLeast, atLeastAligned, atMost
       --  ** Type safe functions on Ptr
       , Ptr
       , sizeOf, alignment, alignedSizeOf
       , movePtr, alignPtr, nextLocation
       , peekAligned, pokeAligned

         -- ** The class of pointer types.
       , Pointer(..), unsafeWithPointer, unsafeWithPointerCast
       , AlignedPtr (..) , ptrAlignment, nextAlignedPtr
       , allocaBuffer, allocaSecure
         -- ** Some low level pointer actions
       , wipeMemory
       , memset
       , memcpy
       , hFillBuf
       ) where



import           Control.Exception     ( bracket_ )

import           Data.Vector.Unboxed         ( MVector(..), Vector, Unbox )
import           Foreign.Marshal.Alloc
import           Foreign.Ptr           ( Ptr, castPtr         )
import qualified Foreign.Ptr           as FP
import           Foreign.Storable      ( Storable, peek, poke )
import qualified Foreign.Storable      as FS
import           GHC.TypeLits

import qualified Data.Vector.Generic         as GV
import qualified Data.Vector.Generic.Mutable as GVM

import Raaz.Core.Prelude
import Raaz.Core.Types.Equality
import Raaz.Core.Types.Copying

-- $basics$
--
-- The main concepts introduced here are the following
--
-- [`Pointer`:] The generic pointer type that is used through the
-- library.
--
-- [`LengthUnit`:] This class captures types units of length.
--
-- [`Alignment`:] A dedicated type that is used to keep track of
-- alignment constraints.  offsets in We have the generic pointer type
-- `Pointer` and distinguish between different length units at the
-- type level. This helps in to avoid a lot of length conversion
-- errors.

-------------------------- Length Units --------- -------------------

-- | In cryptographic settings, we need to measure pointer offsets and
-- buffer sizes. The smallest of length/offset that we have is bytes
-- measured using the type `BYTES`. In various other circumstances, it
-- would be more natural to measure these in multiples of bytes. For
-- example, when allocating buffer to use encrypt using a block cipher
-- it makes sense to measure the buffer size in multiples of block of
-- the cipher. Explicit conversion between these length units, while
-- allocating or moving pointers, involves a lot of low level scaling
-- that is also error prone. To avoid these errors due to unit
-- conversions, we distinguish between different length units at the
-- type level. This type class capturing all such types, i.e. types
-- that stand of length units. Allocation functions and pointer
-- arithmetic are generalised to these length units.
--
-- All instances of a `LengthUnit` are required to be instances of
-- `Monoid` where the monoid operation gives these types the natural
-- size/offset addition semantics: i.e. shifting a pointer by offset
-- @a `mappend` b@ is same as shifting it by @a@ and then by @b@.
class (Enum u, Monoid u) => LengthUnit u where
  -- | Express the length units in bytes.
  inBytes :: u -> BYTES Int

-- | Type safe lengths/offsets in units of bytes.
newtype BYTES a  = BYTES a
        deriving ( Int -> BYTES a -> ShowS
[BYTES a] -> ShowS
BYTES a -> String
(Int -> BYTES a -> ShowS)
-> (BYTES a -> String) -> ([BYTES a] -> ShowS) -> Show (BYTES a)
forall a. Show a => Int -> BYTES a -> ShowS
forall a. Show a => [BYTES a] -> ShowS
forall a. Show a => BYTES a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BYTES a] -> ShowS
$cshowList :: forall a. Show a => [BYTES a] -> ShowS
show :: BYTES a -> String
$cshow :: forall a. Show a => BYTES a -> String
showsPrec :: Int -> BYTES a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> BYTES a -> ShowS
Show, BYTES a -> BYTES a -> Bool
(BYTES a -> BYTES a -> Bool)
-> (BYTES a -> BYTES a -> Bool) -> Eq (BYTES a)
forall a. Eq a => BYTES a -> BYTES a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BYTES a -> BYTES a -> Bool
$c/= :: forall a. Eq a => BYTES a -> BYTES a -> Bool
== :: BYTES a -> BYTES a -> Bool
$c== :: forall a. Eq a => BYTES a -> BYTES a -> Bool
Eq, BYTES a -> BYTES a -> Result
(BYTES a -> BYTES a -> Result) -> Equality (BYTES a)
forall a. Equality a => BYTES a -> BYTES a -> Result
forall a. (a -> a -> Result) -> Equality a
eq :: BYTES a -> BYTES a -> Result
$ceq :: forall a. Equality a => BYTES a -> BYTES a -> Result
Equality, Eq (BYTES a)
Eq (BYTES a)
-> (BYTES a -> BYTES a -> Ordering)
-> (BYTES a -> BYTES a -> Bool)
-> (BYTES a -> BYTES a -> Bool)
-> (BYTES a -> BYTES a -> Bool)
-> (BYTES a -> BYTES a -> Bool)
-> (BYTES a -> BYTES a -> BYTES a)
-> (BYTES a -> BYTES a -> BYTES a)
-> Ord (BYTES a)
BYTES a -> BYTES a -> Bool
BYTES a -> BYTES a -> Ordering
BYTES a -> BYTES a -> BYTES a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (BYTES a)
forall a. Ord a => BYTES a -> BYTES a -> Bool
forall a. Ord a => BYTES a -> BYTES a -> Ordering
forall a. Ord a => BYTES a -> BYTES a -> BYTES a
min :: BYTES a -> BYTES a -> BYTES a
$cmin :: forall a. Ord a => BYTES a -> BYTES a -> BYTES a
max :: BYTES a -> BYTES a -> BYTES a
$cmax :: forall a. Ord a => BYTES a -> BYTES a -> BYTES a
>= :: BYTES a -> BYTES a -> Bool
$c>= :: forall a. Ord a => BYTES a -> BYTES a -> Bool
> :: BYTES a -> BYTES a -> Bool
$c> :: forall a. Ord a => BYTES a -> BYTES a -> Bool
<= :: BYTES a -> BYTES a -> Bool
$c<= :: forall a. Ord a => BYTES a -> BYTES a -> Bool
< :: BYTES a -> BYTES a -> Bool
$c< :: forall a. Ord a => BYTES a -> BYTES a -> Bool
compare :: BYTES a -> BYTES a -> Ordering
$ccompare :: forall a. Ord a => BYTES a -> BYTES a -> Ordering
$cp1Ord :: forall a. Ord a => Eq (BYTES a)
Ord, Int -> BYTES a
BYTES a -> Int
BYTES a -> [BYTES a]
BYTES a -> BYTES a
BYTES a -> BYTES a -> [BYTES a]
BYTES a -> BYTES a -> BYTES a -> [BYTES a]
(BYTES a -> BYTES a)
-> (BYTES a -> BYTES a)
-> (Int -> BYTES a)
-> (BYTES a -> Int)
-> (BYTES a -> [BYTES a])
-> (BYTES a -> BYTES a -> [BYTES a])
-> (BYTES a -> BYTES a -> [BYTES a])
-> (BYTES a -> BYTES a -> BYTES a -> [BYTES a])
-> Enum (BYTES a)
forall a. Enum a => Int -> BYTES a
forall a. Enum a => BYTES a -> Int
forall a. Enum a => BYTES a -> [BYTES a]
forall a. Enum a => BYTES a -> BYTES a
forall a. Enum a => BYTES a -> BYTES a -> [BYTES a]
forall a. Enum a => BYTES a -> BYTES a -> BYTES a -> [BYTES a]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: BYTES a -> BYTES a -> BYTES a -> [BYTES a]
$cenumFromThenTo :: forall a. Enum a => BYTES a -> BYTES a -> BYTES a -> [BYTES a]
enumFromTo :: BYTES a -> BYTES a -> [BYTES a]
$cenumFromTo :: forall a. Enum a => BYTES a -> BYTES a -> [BYTES a]
enumFromThen :: BYTES a -> BYTES a -> [BYTES a]
$cenumFromThen :: forall a. Enum a => BYTES a -> BYTES a -> [BYTES a]
enumFrom :: BYTES a -> [BYTES a]
$cenumFrom :: forall a. Enum a => BYTES a -> [BYTES a]
fromEnum :: BYTES a -> Int
$cfromEnum :: forall a. Enum a => BYTES a -> Int
toEnum :: Int -> BYTES a
$ctoEnum :: forall a. Enum a => Int -> BYTES a
pred :: BYTES a -> BYTES a
$cpred :: forall a. Enum a => BYTES a -> BYTES a
succ :: BYTES a -> BYTES a
$csucc :: forall a. Enum a => BYTES a -> BYTES a
Enum, Enum (BYTES a)
Real (BYTES a)
Real (BYTES a)
-> Enum (BYTES a)
-> (BYTES a -> BYTES a -> BYTES a)
-> (BYTES a -> BYTES a -> BYTES a)
-> (BYTES a -> BYTES a -> BYTES a)
-> (BYTES a -> BYTES a -> BYTES a)
-> (BYTES a -> BYTES a -> (BYTES a, BYTES a))
-> (BYTES a -> BYTES a -> (BYTES a, BYTES a))
-> (BYTES a -> Integer)
-> Integral (BYTES a)
BYTES a -> Integer
BYTES a -> BYTES a -> (BYTES a, BYTES a)
BYTES a -> BYTES a -> BYTES a
forall a. Integral a => Enum (BYTES a)
forall a. Integral a => Real (BYTES a)
forall a. Integral a => BYTES a -> Integer
forall a. Integral a => BYTES a -> BYTES a -> (BYTES a, BYTES a)
forall a. Integral a => BYTES a -> BYTES a -> BYTES a
forall a.
Real a
-> Enum a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
toInteger :: BYTES a -> Integer
$ctoInteger :: forall a. Integral a => BYTES a -> Integer
divMod :: BYTES a -> BYTES a -> (BYTES a, BYTES a)
$cdivMod :: forall a. Integral a => BYTES a -> BYTES a -> (BYTES a, BYTES a)
quotRem :: BYTES a -> BYTES a -> (BYTES a, BYTES a)
$cquotRem :: forall a. Integral a => BYTES a -> BYTES a -> (BYTES a, BYTES a)
mod :: BYTES a -> BYTES a -> BYTES a
$cmod :: forall a. Integral a => BYTES a -> BYTES a -> BYTES a
div :: BYTES a -> BYTES a -> BYTES a
$cdiv :: forall a. Integral a => BYTES a -> BYTES a -> BYTES a
rem :: BYTES a -> BYTES a -> BYTES a
$crem :: forall a. Integral a => BYTES a -> BYTES a -> BYTES a
quot :: BYTES a -> BYTES a -> BYTES a
$cquot :: forall a. Integral a => BYTES a -> BYTES a -> BYTES a
$cp2Integral :: forall a. Integral a => Enum (BYTES a)
$cp1Integral :: forall a. Integral a => Real (BYTES a)
Integral
                 , Num (BYTES a)
Ord (BYTES a)
Num (BYTES a)
-> Ord (BYTES a) -> (BYTES a -> Rational) -> Real (BYTES a)
BYTES a -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
forall a. Real a => Num (BYTES a)
forall a. Real a => Ord (BYTES a)
forall a. Real a => BYTES a -> Rational
toRational :: BYTES a -> Rational
$ctoRational :: forall a. Real a => BYTES a -> Rational
$cp2Real :: forall a. Real a => Ord (BYTES a)
$cp1Real :: forall a. Real a => Num (BYTES a)
Real, Integer -> BYTES a
BYTES a -> BYTES a
BYTES a -> BYTES a -> BYTES a
(BYTES a -> BYTES a -> BYTES a)
-> (BYTES a -> BYTES a -> BYTES a)
-> (BYTES a -> BYTES a -> BYTES a)
-> (BYTES a -> BYTES a)
-> (BYTES a -> BYTES a)
-> (BYTES a -> BYTES a)
-> (Integer -> BYTES a)
-> Num (BYTES a)
forall a. Num a => Integer -> BYTES a
forall a. Num a => BYTES a -> BYTES a
forall a. Num a => BYTES a -> BYTES a -> BYTES a
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> BYTES a
$cfromInteger :: forall a. Num a => Integer -> BYTES a
signum :: BYTES a -> BYTES a
$csignum :: forall a. Num a => BYTES a -> BYTES a
abs :: BYTES a -> BYTES a
$cabs :: forall a. Num a => BYTES a -> BYTES a
negate :: BYTES a -> BYTES a
$cnegate :: forall a. Num a => BYTES a -> BYTES a
* :: BYTES a -> BYTES a -> BYTES a
$c* :: forall a. Num a => BYTES a -> BYTES a -> BYTES a
- :: BYTES a -> BYTES a -> BYTES a
$c- :: forall a. Num a => BYTES a -> BYTES a -> BYTES a
+ :: BYTES a -> BYTES a -> BYTES a
$c+ :: forall a. Num a => BYTES a -> BYTES a -> BYTES a
Num, Ptr b -> Int -> IO (BYTES a)
Ptr b -> Int -> BYTES a -> IO ()
Ptr (BYTES a) -> IO (BYTES a)
Ptr (BYTES a) -> Int -> IO (BYTES a)
Ptr (BYTES a) -> Int -> BYTES a -> IO ()
Ptr (BYTES a) -> BYTES a -> IO ()
BYTES a -> Int
(BYTES a -> Int)
-> (BYTES a -> Int)
-> (Ptr (BYTES a) -> Int -> IO (BYTES a))
-> (Ptr (BYTES a) -> Int -> BYTES a -> IO ())
-> (forall b. Ptr b -> Int -> IO (BYTES a))
-> (forall b. Ptr b -> Int -> BYTES a -> IO ())
-> (Ptr (BYTES a) -> IO (BYTES a))
-> (Ptr (BYTES a) -> BYTES a -> IO ())
-> Storable (BYTES a)
forall b. Ptr b -> Int -> IO (BYTES a)
forall b. Ptr b -> Int -> BYTES a -> IO ()
forall a. Storable a => Ptr (BYTES a) -> IO (BYTES a)
forall a. Storable a => Ptr (BYTES a) -> Int -> IO (BYTES a)
forall a. Storable a => Ptr (BYTES a) -> Int -> BYTES a -> IO ()
forall a. Storable a => Ptr (BYTES a) -> BYTES a -> IO ()
forall a. Storable a => BYTES a -> Int
forall a b. Storable a => Ptr b -> Int -> IO (BYTES a)
forall a b. Storable a => Ptr b -> Int -> BYTES a -> IO ()
forall a.
(a -> Int)
-> (a -> Int)
-> (Ptr a -> Int -> IO a)
-> (Ptr a -> Int -> a -> IO ())
-> (forall b. Ptr b -> Int -> IO a)
-> (forall b. Ptr b -> Int -> a -> IO ())
-> (Ptr a -> IO a)
-> (Ptr a -> a -> IO ())
-> Storable a
poke :: Ptr (BYTES a) -> BYTES a -> IO ()
$cpoke :: forall a. Storable a => Ptr (BYTES a) -> BYTES a -> IO ()
peek :: Ptr (BYTES a) -> IO (BYTES a)
$cpeek :: forall a. Storable a => Ptr (BYTES a) -> IO (BYTES a)
pokeByteOff :: Ptr b -> Int -> BYTES a -> IO ()
$cpokeByteOff :: forall a b. Storable a => Ptr b -> Int -> BYTES a -> IO ()
peekByteOff :: Ptr b -> Int -> IO (BYTES a)
$cpeekByteOff :: forall a b. Storable a => Ptr b -> Int -> IO (BYTES a)
pokeElemOff :: Ptr (BYTES a) -> Int -> BYTES a -> IO ()
$cpokeElemOff :: forall a. Storable a => Ptr (BYTES a) -> Int -> BYTES a -> IO ()
peekElemOff :: Ptr (BYTES a) -> Int -> IO (BYTES a)
$cpeekElemOff :: forall a. Storable a => Ptr (BYTES a) -> Int -> IO (BYTES a)
alignment :: BYTES a -> Int
$calignment :: forall a. Storable a => BYTES a -> Int
sizeOf :: BYTES a -> Int
$csizeOf :: forall a. Storable a => BYTES a -> Int
Storable, BYTES a
BYTES a -> BYTES a -> Bounded (BYTES a)
forall a. a -> a -> Bounded a
forall a. Bounded a => BYTES a
maxBound :: BYTES a
$cmaxBound :: forall a. Bounded a => BYTES a
minBound :: BYTES a
$cminBound :: forall a. Bounded a => BYTES a
Bounded, Eq (BYTES a)
BYTES a
Eq (BYTES a)
-> (BYTES a -> BYTES a -> BYTES a)
-> (BYTES a -> BYTES a -> BYTES a)
-> (BYTES a -> BYTES a -> BYTES a)
-> (BYTES a -> BYTES a)
-> (BYTES a -> Int -> BYTES a)
-> (BYTES a -> Int -> BYTES a)
-> BYTES a
-> (Int -> BYTES a)
-> (BYTES a -> Int -> BYTES a)
-> (BYTES a -> Int -> BYTES a)
-> (BYTES a -> Int -> BYTES a)
-> (BYTES a -> Int -> Bool)
-> (BYTES a -> Maybe Int)
-> (BYTES a -> Int)
-> (BYTES a -> Bool)
-> (BYTES a -> Int -> BYTES a)
-> (BYTES a -> Int -> BYTES a)
-> (BYTES a -> Int -> BYTES a)
-> (BYTES a -> Int -> BYTES a)
-> (BYTES a -> Int -> BYTES a)
-> (BYTES a -> Int -> BYTES a)
-> (BYTES a -> Int)
-> Bits (BYTES a)
Int -> BYTES a
BYTES a -> Bool
BYTES a -> Int
BYTES a -> Maybe Int
BYTES a -> BYTES a
BYTES a -> Int -> Bool
BYTES a -> Int -> BYTES a
BYTES a -> BYTES a -> BYTES a
forall a.
Eq a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> a
-> (Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> Bool)
-> (a -> Maybe Int)
-> (a -> Int)
-> (a -> Bool)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int)
-> Bits a
forall a. Bits a => Eq (BYTES a)
forall a. Bits a => BYTES a
forall a. Bits a => Int -> BYTES a
forall a. Bits a => BYTES a -> Bool
forall a. Bits a => BYTES a -> Int
forall a. Bits a => BYTES a -> Maybe Int
forall a. Bits a => BYTES a -> BYTES a
forall a. Bits a => BYTES a -> Int -> Bool
forall a. Bits a => BYTES a -> Int -> BYTES a
forall a. Bits a => BYTES a -> BYTES a -> BYTES a
popCount :: BYTES a -> Int
$cpopCount :: forall a. Bits a => BYTES a -> Int
rotateR :: BYTES a -> Int -> BYTES a
$crotateR :: forall a. Bits a => BYTES a -> Int -> BYTES a
rotateL :: BYTES a -> Int -> BYTES a
$crotateL :: forall a. Bits a => BYTES a -> Int -> BYTES a
unsafeShiftR :: BYTES a -> Int -> BYTES a
$cunsafeShiftR :: forall a. Bits a => BYTES a -> Int -> BYTES a
shiftR :: BYTES a -> Int -> BYTES a
$cshiftR :: forall a. Bits a => BYTES a -> Int -> BYTES a
unsafeShiftL :: BYTES a -> Int -> BYTES a
$cunsafeShiftL :: forall a. Bits a => BYTES a -> Int -> BYTES a
shiftL :: BYTES a -> Int -> BYTES a
$cshiftL :: forall a. Bits a => BYTES a -> Int -> BYTES a
isSigned :: BYTES a -> Bool
$cisSigned :: forall a. Bits a => BYTES a -> Bool
bitSize :: BYTES a -> Int
$cbitSize :: forall a. Bits a => BYTES a -> Int
bitSizeMaybe :: BYTES a -> Maybe Int
$cbitSizeMaybe :: forall a. Bits a => BYTES a -> Maybe Int
testBit :: BYTES a -> Int -> Bool
$ctestBit :: forall a. Bits a => BYTES a -> Int -> Bool
complementBit :: BYTES a -> Int -> BYTES a
$ccomplementBit :: forall a. Bits a => BYTES a -> Int -> BYTES a
clearBit :: BYTES a -> Int -> BYTES a
$cclearBit :: forall a. Bits a => BYTES a -> Int -> BYTES a
setBit :: BYTES a -> Int -> BYTES a
$csetBit :: forall a. Bits a => BYTES a -> Int -> BYTES a
bit :: Int -> BYTES a
$cbit :: forall a. Bits a => Int -> BYTES a
zeroBits :: BYTES a
$czeroBits :: forall a. Bits a => BYTES a
rotate :: BYTES a -> Int -> BYTES a
$crotate :: forall a. Bits a => BYTES a -> Int -> BYTES a
shift :: BYTES a -> Int -> BYTES a
$cshift :: forall a. Bits a => BYTES a -> Int -> BYTES a
complement :: BYTES a -> BYTES a
$ccomplement :: forall a. Bits a => BYTES a -> BYTES a
xor :: BYTES a -> BYTES a -> BYTES a
$cxor :: forall a. Bits a => BYTES a -> BYTES a -> BYTES a
.|. :: BYTES a -> BYTES a -> BYTES a
$c.|. :: forall a. Bits a => BYTES a -> BYTES a -> BYTES a
.&. :: BYTES a -> BYTES a -> BYTES a
$c.&. :: forall a. Bits a => BYTES a -> BYTES a -> BYTES a
$cp1Bits :: forall a. Bits a => Eq (BYTES a)
Bits
                 )

instance Functor BYTES where
   fmap :: (a -> b) -> BYTES a -> BYTES b
fmap a -> b
f (BYTES a
x) = b -> BYTES b
forall a. a -> BYTES a
BYTES (a -> b
f a
x)

instance Num a => Semigroup (BYTES a) where
  <> :: BYTES a -> BYTES a -> BYTES a
(<>) = BYTES a -> BYTES a -> BYTES a
forall a. Num a => a -> a -> a
(+)

instance Num a => Monoid (BYTES a) where
  mempty :: BYTES a
mempty  = BYTES a
0
  mappend :: BYTES a -> BYTES a -> BYTES a
mappend = BYTES a -> BYTES a -> BYTES a
forall a. Semigroup a => a -> a -> a
(<>)

------------------------ Alignment --------------------------------

-- | Types to measure alignment in units of bytes.
newtype Alignment = Alignment { Alignment -> Int
unAlignment :: Int }
        deriving ( Int -> Alignment -> ShowS
[Alignment] -> ShowS
Alignment -> String
(Int -> Alignment -> ShowS)
-> (Alignment -> String)
-> ([Alignment] -> ShowS)
-> Show Alignment
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Alignment] -> ShowS
$cshowList :: [Alignment] -> ShowS
show :: Alignment -> String
$cshow :: Alignment -> String
showsPrec :: Int -> Alignment -> ShowS
$cshowsPrec :: Int -> Alignment -> ShowS
Show, Alignment -> Alignment -> Bool
(Alignment -> Alignment -> Bool)
-> (Alignment -> Alignment -> Bool) -> Eq Alignment
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Alignment -> Alignment -> Bool
$c/= :: Alignment -> Alignment -> Bool
== :: Alignment -> Alignment -> Bool
$c== :: Alignment -> Alignment -> Bool
Eq, Eq Alignment
Eq Alignment
-> (Alignment -> Alignment -> Ordering)
-> (Alignment -> Alignment -> Bool)
-> (Alignment -> Alignment -> Bool)
-> (Alignment -> Alignment -> Bool)
-> (Alignment -> Alignment -> Bool)
-> (Alignment -> Alignment -> Alignment)
-> (Alignment -> Alignment -> Alignment)
-> Ord Alignment
Alignment -> Alignment -> Bool
Alignment -> Alignment -> Ordering
Alignment -> Alignment -> Alignment
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Alignment -> Alignment -> Alignment
$cmin :: Alignment -> Alignment -> Alignment
max :: Alignment -> Alignment -> Alignment
$cmax :: Alignment -> Alignment -> Alignment
>= :: Alignment -> Alignment -> Bool
$c>= :: Alignment -> Alignment -> Bool
> :: Alignment -> Alignment -> Bool
$c> :: Alignment -> Alignment -> Bool
<= :: Alignment -> Alignment -> Bool
$c<= :: Alignment -> Alignment -> Bool
< :: Alignment -> Alignment -> Bool
$c< :: Alignment -> Alignment -> Bool
compare :: Alignment -> Alignment -> Ordering
$ccompare :: Alignment -> Alignment -> Ordering
$cp1Ord :: Eq Alignment
Ord, Int -> Alignment
Alignment -> Int
Alignment -> [Alignment]
Alignment -> Alignment
Alignment -> Alignment -> [Alignment]
Alignment -> Alignment -> Alignment -> [Alignment]
(Alignment -> Alignment)
-> (Alignment -> Alignment)
-> (Int -> Alignment)
-> (Alignment -> Int)
-> (Alignment -> [Alignment])
-> (Alignment -> Alignment -> [Alignment])
-> (Alignment -> Alignment -> [Alignment])
-> (Alignment -> Alignment -> Alignment -> [Alignment])
-> Enum Alignment
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: Alignment -> Alignment -> Alignment -> [Alignment]
$cenumFromThenTo :: Alignment -> Alignment -> Alignment -> [Alignment]
enumFromTo :: Alignment -> Alignment -> [Alignment]
$cenumFromTo :: Alignment -> Alignment -> [Alignment]
enumFromThen :: Alignment -> Alignment -> [Alignment]
$cenumFromThen :: Alignment -> Alignment -> [Alignment]
enumFrom :: Alignment -> [Alignment]
$cenumFrom :: Alignment -> [Alignment]
fromEnum :: Alignment -> Int
$cfromEnum :: Alignment -> Int
toEnum :: Int -> Alignment
$ctoEnum :: Int -> Alignment
pred :: Alignment -> Alignment
$cpred :: Alignment -> Alignment
succ :: Alignment -> Alignment
$csucc :: Alignment -> Alignment
Enum)

instance Semigroup Alignment where
  <> :: Alignment -> Alignment -> Alignment
(<>) Alignment
a Alignment
b = Int -> Alignment
Alignment (Int -> Alignment) -> Int -> Alignment
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int
forall a. Integral a => a -> a -> a
lcm (Alignment -> Int
unAlignment Alignment
a) (Alignment -> Int
unAlignment Alignment
b)

instance Monoid Alignment where
  mempty :: Alignment
mempty  = Int -> Alignment
Alignment Int
1
  mappend :: Alignment -> Alignment -> Alignment
mappend = Alignment -> Alignment -> Alignment
forall a. Semigroup a => a -> a -> a
(<>)

---------- Type safe versions of some pointer functions -----------------

-- | Compute the size of a storable element.
sizeOf :: Storable a => Proxy a -> BYTES Int
sizeOf :: Proxy a -> BYTES Int
sizeOf = Int -> BYTES Int
forall a. a -> BYTES a
BYTES (Int -> BYTES Int) -> (Proxy a -> Int) -> Proxy a -> BYTES Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Int
forall a. Storable a => a -> Int
FS.sizeOf (a -> Int) -> (Proxy a -> a) -> Proxy a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Proxy a -> a
forall a (proxy :: * -> *). a -> proxy a -> a
asProxyTypeOf a
forall a. HasCallStack => a
undefined

-- | Compute the alignment for a storable object.
alignment :: Storable a => Proxy a -> Alignment
alignment :: Proxy a -> Alignment
alignment =  Int -> Alignment
Alignment (Int -> Alignment) -> (Proxy a -> Int) -> Proxy a -> Alignment
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Int
forall a. Storable a => a -> Int
FS.alignment (a -> Int) -> (Proxy a -> a) -> Proxy a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Proxy a -> a
forall a (proxy :: * -> *). a -> proxy a -> a
asProxyTypeOf a
forall a. HasCallStack => a
undefined

-- | Move the given pointer with a specific offset.
movePtr :: LengthUnit l => Ptr a -> l -> Ptr a
movePtr :: Ptr a -> l -> Ptr a
movePtr Ptr a
ptr l
l = Ptr a -> Int -> Ptr a
forall a b. Ptr a -> Int -> Ptr b
FP.plusPtr Ptr a
ptr Int
offset
  where BYTES Int
offset = l -> BYTES Int
forall u. LengthUnit u => u -> BYTES Int
inBytes l
l

-- | Align pointer to the next alignment
alignPtr :: Storable a => Ptr a -> Alignment -> Ptr a
alignPtr :: Ptr a -> Alignment -> Ptr a
alignPtr Ptr a
ptr = Ptr a -> Int -> Ptr a
forall a. Ptr a -> Int -> Ptr a
FP.alignPtr Ptr a
ptr (Int -> Ptr a) -> (Alignment -> Int) -> Alignment -> Ptr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Alignment -> Int
unAlignment

-- | Size of the buffer to be allocated to store an element of type
-- @a@ so as to guarantee that there exist enough space to store the
-- element after aligning the pointer.
alignedSizeOf  :: Storable a => Proxy a -> BYTES Int
alignedSizeOf :: Proxy a -> BYTES Int
alignedSizeOf Proxy a
aproxy =  BYTES Int -> Alignment -> BYTES Int
forall l. LengthUnit l => l -> Alignment -> BYTES Int
atLeastAligned (Proxy a -> BYTES Int
forall a. Storable a => Proxy a -> BYTES Int
sizeOf Proxy a
aproxy) (Alignment -> BYTES Int) -> Alignment -> BYTES Int
forall a b. (a -> b) -> a -> b
$ Proxy a -> Alignment
forall a. Storable a => Proxy a -> Alignment
alignment Proxy a
aproxy

-- | Compute the next aligned pointer starting from the given pointer
-- location.
nextLocation :: Storable a => Ptr a -> Ptr a
nextLocation :: Ptr a -> Ptr a
nextLocation Ptr a
ptr = Ptr a -> Alignment -> Ptr a
forall a. Storable a => Ptr a -> Alignment -> Ptr a
alignPtr Ptr a
ptr (Alignment -> Ptr a) -> Alignment -> Ptr a
forall a b. (a -> b) -> a -> b
$ Proxy a -> Alignment
forall a. Storable a => Proxy a -> Alignment
alignment (Proxy a -> Alignment) -> Proxy a -> Alignment
forall a b. (a -> b) -> a -> b
$ Ptr a -> Proxy a
forall b. Ptr b -> Proxy b
getProxy Ptr a
ptr
  where getProxy :: Ptr b -> Proxy b
        getProxy :: Ptr b -> Proxy b
getProxy  = Proxy b -> Ptr b -> Proxy b
forall a b. a -> b -> a
const Proxy b
forall k (t :: k). Proxy t
Proxy

-- | Peek the element from the next aligned location.
peekAligned :: Storable a => Ptr a -> IO a
peekAligned :: Ptr a -> IO a
peekAligned = Ptr a -> IO a
forall a. Storable a => Ptr a -> IO a
peek (Ptr a -> IO a) -> (Ptr a -> Ptr a) -> Ptr a -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr a -> Ptr a
forall a. Storable a => Ptr a -> Ptr a
nextLocation

-- | Poke the element from the next aligned location.
pokeAligned     :: Storable a => Ptr a -> a -> IO ()
pokeAligned :: Ptr a -> a -> IO ()
pokeAligned Ptr a
ptr =  Ptr a -> a -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke (Ptr a -> a -> IO ()) -> Ptr a -> a -> IO ()
forall a b. (a -> b) -> a -> b
$ Ptr a -> Ptr a
forall a. Storable a => Ptr a -> Ptr a
nextLocation Ptr a
ptr

instance LengthUnit (BYTES Int) where
  inBytes :: BYTES Int -> BYTES Int
inBytes = BYTES Int -> BYTES Int
forall a. a -> a
id
  {-# INLINE inBytes #-}

-- | Express length unit @src@ in terms of length unit @dest@ rounding
-- upwards.
atLeast :: ( LengthUnit src
           , LengthUnit dest
           )
        => src
        -> dest
atLeast :: src -> dest
atLeast src
src | BYTES Int
r BYTES Int -> BYTES Int -> Bool
forall a. Eq a => a -> a -> Bool
== BYTES Int
0    = dest
u
            | Bool
otherwise = dest -> dest
forall a. Enum a => a -> a
succ dest
u
    where (dest
u , BYTES Int
r) = BYTES Int -> (dest, BYTES Int)
forall u. LengthUnit u => BYTES Int -> (u, BYTES Int)
bytesQuotRem (BYTES Int -> (dest, BYTES Int)) -> BYTES Int -> (dest, BYTES Int)
forall a b. (a -> b) -> a -> b
$ src -> BYTES Int
forall u. LengthUnit u => u -> BYTES Int
inBytes src
src


-- | Often we want to allocate a buffer of size @l@. We also want to
-- make sure that the buffer starts at an alignment boundary
-- @a@. However, the standard word allocation functions might return a
-- pointer that is not aligned as desired. The @atLeastAligned l a@
-- returns a length @n@ such the length @n@ is big enough to ensure
-- that there is at least @l@ length of valid buffer starting at the
-- next pointer aligned at boundary @a@. If the alignment required in
-- @a@ then allocating @l + a@ should do the trick.
--
-- NOTE: Let us say that the next allocation happens at a pointer ptr
-- whose address is r mod a. Then if we allocate a buffer of size s,
-- the buffer will be spanning the address ptr, ptr + 1, ... ptr + s
-- -1.  Assume that r ≠ 0, then the next address at which our buffer
-- can start is at ptr + a - r. Therefore the size of the buffer
-- available at this location is (ptr + s - 1) - (ptr + a - r ) + 1 =
-- s - a + r, which should at least l. Therefore, we have s - a - r =
-- l, which means s >= l + a - r. This is maximised when r = 1.  This
-- analysis means that we need to allocate only l + a - 1 bytes but
-- that seems to be creating problems for our copy. May be it is a
-- memcpy vs memmove problem.
atLeastAligned :: LengthUnit l => l -> Alignment -> BYTES Int
atLeastAligned :: l -> Alignment -> BYTES Int
atLeastAligned l
l Alignment
a = BYTES Int
n BYTES Int -> BYTES Int -> BYTES Int
forall a. Semigroup a => a -> a -> a
<> BYTES Int
pad
  where n :: BYTES Int
n    = l -> BYTES Int
forall src dest. (LengthUnit src, LengthUnit dest) => src -> dest
atLeast l
l
        pad :: BYTES Int
pad  = Int -> BYTES Int
forall a. a -> BYTES a
BYTES (Int -> BYTES Int) -> Int -> BYTES Int
forall a b. (a -> b) -> a -> b
$ Alignment -> Int
unAlignment Alignment
a

-- | Express length unit @src@ in terms of length unit @dest@ rounding
-- downwards.
atMost :: ( LengthUnit src
          , LengthUnit dest
          )
       => src
       -> dest
atMost :: src -> dest
atMost = (dest, BYTES Int) -> dest
forall a b. (a, b) -> a
fst ((dest, BYTES Int) -> dest)
-> (src -> (dest, BYTES Int)) -> src -> dest
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BYTES Int -> (dest, BYTES Int)
forall u. LengthUnit u => BYTES Int -> (u, BYTES Int)
bytesQuotRem (BYTES Int -> (dest, BYTES Int))
-> (src -> BYTES Int) -> src -> (dest, BYTES Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. src -> BYTES Int
forall u. LengthUnit u => u -> BYTES Int
inBytes

-- | A length unit @u@ is usually a multiple of bytes. The function
-- `bytesQuotRem` is like `quotRem`: the value @byteQuotRem bytes@ is
-- a tuple @(x,r)@, where @x@ is @bytes@ expressed in the unit @u@
-- with @r@ being the reminder.
bytesQuotRem :: LengthUnit u
             => BYTES Int
             -> (u , BYTES Int)
bytesQuotRem :: BYTES Int -> (u, BYTES Int)
bytesQuotRem BYTES Int
bytes = (u
u , BYTES Int
r)
  where divisor :: BYTES Int
divisor       = u -> BYTES Int
forall u. LengthUnit u => u -> BYTES Int
inBytes (Int -> u
forall a. Enum a => Int -> a
toEnum Int
1 u -> u -> u
forall a. a -> a -> a
`asTypeOf` u
u)
        (BYTES Int
q, BYTES Int
r)  = BYTES Int
bytes BYTES Int -> BYTES Int -> (BYTES Int, BYTES Int)
forall a. Integral a => a -> a -> (a, a)
`quotRem` BYTES Int
divisor
        u :: u
u             = Int -> u
forall a. Enum a => Int -> a
toEnum Int
q

-- | Depending on the constraints of various pointers, raaz expose a
-- variety of pointer types. This type class capturing such types. The
-- main operation of interest to use is casting and allocation. All of
-- these types have an underlying pointer which you can also be
-- accessed.
class Pointer (ptr :: Type -> Type) where

  -- | Convert pointers of one type to another.
  castPointer  :: ptr a -> ptr b


  -- | The `alloca` variant for this pointer type. The action
  -- @allocaPointer l action@ allocates a buffer of size @l@ and
  -- passes it on to @action@. No explicit de-allocation is required
  -- just like in the case of `alloca`
  allocaPointer :: BYTES Int        -- size to allocate
                -> (ptr a  -> IO b) -- action to run
                -> IO b
  --
  -- | Recover the underlying raw pointer.
  unsafeRawPtr :: ptr a -> Ptr a

instance Pointer Ptr where
  unsafeRawPtr :: Ptr a -> Ptr a
unsafeRawPtr             = Ptr a -> Ptr a
forall a. a -> a
id
  {-# INLINE  unsafeRawPtr #-}
  castPointer :: Ptr a -> Ptr b
castPointer              = Ptr a -> Ptr b
forall a b. Ptr a -> Ptr b
castPtr
  {-# INLINE castPointer   #-}
  allocaPointer :: BYTES Int -> (Ptr a -> IO b) -> IO b
allocaPointer (BYTES Int
sz) = Int -> (Ptr a -> IO b) -> IO b
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes Int
sz

-- | Lifts raw pointer actions to the given pointer type.
unsafeWithPointer :: Pointer ptr => (Ptr a -> b) -> ptr a -> b
unsafeWithPointer :: (Ptr a -> b) -> ptr a -> b
unsafeWithPointer Ptr a -> b
action = Ptr a -> b
action (Ptr a -> b) -> (ptr a -> Ptr a) -> ptr a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ptr a -> Ptr a
forall (ptr :: * -> *) a. Pointer ptr => ptr a -> Ptr a
unsafeRawPtr

-- | Lifts raw pointer actions to a pointer action of a different type.
unsafeWithPointerCast :: Pointer ptr => (Ptr a -> b) -> ptr something -> b
unsafeWithPointerCast :: (Ptr a -> b) -> ptr something -> b
unsafeWithPointerCast Ptr a -> b
action = (Ptr a -> b) -> ptr a -> b
forall (ptr :: * -> *) a b.
Pointer ptr =>
(Ptr a -> b) -> ptr a -> b
unsafeWithPointer Ptr a -> b
action (ptr a -> b) -> (ptr something -> ptr a) -> ptr something -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ptr something -> ptr a
forall (ptr :: * -> *) a b. Pointer ptr => ptr a -> ptr b
castPointer

-- | Allocate a buffer for an action that expects a generic
-- pointer. Length can be specified in any length units.
allocaBuffer :: ( LengthUnit l, Pointer ptr)
             => l                        -- ^ buffer length
             -> (ptr something -> IO b)  -- ^ the action to run
             -> IO b
allocaBuffer :: l -> (ptr something -> IO b) -> IO b
allocaBuffer = BYTES Int -> (ptr something -> IO b) -> IO b
forall (ptr :: * -> *) a b.
Pointer ptr =>
BYTES Int -> (ptr a -> IO b) -> IO b
allocaPointer (BYTES Int -> (ptr something -> IO b) -> IO b)
-> (l -> BYTES Int) -> l -> (ptr something -> IO b) -> IO b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. l -> BYTES Int
forall u. LengthUnit u => u -> BYTES Int
inBytes


----------------- Secure allocation ---------------------------------

-- | Variant of `allocaBuffer` that allocates a locked buffer of a
-- given size and runs the action. The associated memory (1) exists
-- for the duration of the action (2) will not be swapped during the
-- action as guaranteed by the memlock function of the operating
-- system and (3) will be wiped clean and deallocated when the action
-- terminates either directly or indirectly via errors. While this is
-- mostly secure, there are still edge cases in multi-threaded
-- applications where the memory will not be cleaned. For example, if
-- you run a crypto-sensitive action inside a child thread and the
-- main thread gets exists, then the child thread is killed (due to
-- the demonic nature of threads in GHC haskell) immediately and might
-- not give it chance to wipe the memory clean. See
-- <https://ghc.haskell.org/trac/ghc/ticket/13891> on this problem and
-- possible workarounds.
--
allocaSecure :: ( LengthUnit l, Pointer ptr)
             => l
             -> (ptr a -> IO b)
             -> IO b
allocaSecure :: l -> (ptr a -> IO b) -> IO b
allocaSecure l
l ptr a -> IO b
action = l -> (ptr a -> IO b) -> IO b
forall l (ptr :: * -> *) something b.
(LengthUnit l, Pointer ptr) =>
l -> (ptr something -> IO b) -> IO b
allocaBuffer l
l ptr a -> IO b
actual
    where actual :: ptr a -> IO b
actual ptr a
ptr    = IO () -> IO () -> IO b -> IO b
forall a b c. IO a -> IO b -> IO c -> IO c
bracket_ (ptr a -> IO ()
lockIt ptr a
ptr) (ptr a -> IO ()
releaseIt ptr a
ptr) (IO b -> IO b) -> IO b -> IO b
forall a b. (a -> b) -> a -> b
$ ptr a -> IO b
action ptr a
ptr
          lockIt :: ptr a -> IO ()
lockIt ptr a
ptr    = do Int
c <- ptr a -> l -> IO Int
forall l (ptr :: * -> *) a.
(LengthUnit l, Pointer ptr) =>
ptr a -> l -> IO Int
memlock ptr a
ptr l
l
                             Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
c Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
0) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> IO ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"secure memory: unable to lock memory"
                             -- TODO: Is this the best way to fail
                             -- when no secure memory is available ?
          releaseIt :: ptr a -> IO ()
releaseIt ptr a
ptr = ptr a -> l -> IO ()
forall l (ptr :: * -> *) a.
(LengthUnit l, Pointer ptr) =>
ptr a -> l -> IO ()
wipeMemory ptr a
ptr l
l IO () -> IO () -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>  ptr a -> l -> IO ()
forall l (ptr :: * -> *) a.
(LengthUnit l, Pointer ptr) =>
ptr a -> l -> IO ()
memunlock ptr a
ptr l
l

foreign import ccall unsafe "raaz/core/memory.h raazMemorylock"
  c_mlock :: Ptr a -> BYTES Int -> IO Int

foreign import ccall unsafe "raaz/core/memory.h raazMemoryunlock"
  c_munlock :: Ptr a -> BYTES Int -> IO ()

foreign import ccall unsafe "raazWipeMemory" c_wipe_memory
    :: Ptr a -> BYTES Int -> IO ()

memlock :: (LengthUnit l, Pointer ptr)
        => ptr a
        -> l
        -> IO Int
memlock :: ptr a -> l -> IO Int
memlock   ptr a
ptr = (Ptr a -> BYTES Int -> IO Int) -> ptr a -> BYTES Int -> IO Int
forall (ptr :: * -> *) a b.
Pointer ptr =>
(Ptr a -> b) -> ptr a -> b
unsafeWithPointer Ptr a -> BYTES Int -> IO Int
forall a. Ptr a -> BYTES Int -> IO Int
c_mlock ptr a
ptr (BYTES Int -> IO Int) -> (l -> BYTES Int) -> l -> IO Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. l -> BYTES Int
forall u. LengthUnit u => u -> BYTES Int
inBytes

memunlock :: (LengthUnit l, Pointer ptr)
          => ptr a
          -> l
          -> IO ()
memunlock :: ptr a -> l -> IO ()
memunlock ptr a
ptr = (Ptr a -> BYTES Int -> IO ()) -> ptr a -> BYTES Int -> IO ()
forall (ptr :: * -> *) a b.
Pointer ptr =>
(Ptr a -> b) -> ptr a -> b
unsafeWithPointer Ptr a -> BYTES Int -> IO ()
forall a. Ptr a -> BYTES Int -> IO ()
c_munlock ptr a
ptr (BYTES Int -> IO ()) -> (l -> BYTES Int) -> l -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. l -> BYTES Int
forall u. LengthUnit u => u -> BYTES Int
inBytes

-- | Cleanup the given pointer of any sensitive data. This is a tricky
-- function to write as compilers are known to optimise this away. In
-- our case we try to use the platform specific one if it exists.
wipeMemory :: (LengthUnit l, Pointer ptr)
            => ptr a   -- ^ buffer to wipe
            -> l       -- ^ buffer length
            -> IO ()
wipeMemory :: ptr a -> l -> IO ()
wipeMemory ptr a
p = IO () -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO () -> IO ()) -> (l -> IO ()) -> l -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Ptr a -> BYTES Int -> IO ()) -> ptr a -> BYTES Int -> IO ()
forall (ptr :: * -> *) a b.
Pointer ptr =>
(Ptr a -> b) -> ptr a -> b
unsafeWithPointer Ptr a -> BYTES Int -> IO ()
forall a. Ptr a -> BYTES Int -> IO ()
c_wipe_memory ptr a
p (BYTES Int -> IO ()) -> (l -> BYTES Int) -> l -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. l -> BYTES Int
forall u. LengthUnit u => u -> BYTES Int
inBytes

{-# SPECIALIZE memlock    :: Ptr a -> BYTES Int -> IO Int  #-}
{-# SPECIALIZE memunlock  :: Ptr a -> BYTES Int -> IO ()   #-}
{-# SPECIALISE wipeMemory :: Ptr a -> BYTES Int -> IO ()   #-}



-------------------- Low level pointer operations ------------------

-- | A version of `hGetBuf` which works for any type safe length units.
hFillBuf :: (LengthUnit bufSize, Pointer ptr)
         => Handle
         -> ptr a
         -> bufSize
         -> IO (BYTES Int)
{-# INLINE hFillBuf #-}
hFillBuf :: Handle -> ptr a -> bufSize -> IO (BYTES Int)
hFillBuf Handle
handle ptr a
ptr bufSize
bufSize = Int -> BYTES Int
forall a. a -> BYTES a
BYTES (Int -> BYTES Int) -> IO Int -> IO (BYTES Int)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Handle -> Ptr a -> Int -> IO Int
forall a. Handle -> Ptr a -> Int -> IO Int
hGetBuf Handle
handle (ptr a -> Ptr a
forall (ptr :: * -> *) a. Pointer ptr => ptr a -> Ptr a
unsafeRawPtr ptr a
ptr) Int
bytes
  where BYTES Int
bytes = bufSize -> BYTES Int
forall u. LengthUnit u => u -> BYTES Int
inBytes bufSize
bufSize

------------------- Copy move and set contents ----------------------------

-- | Some common PTR functions abstracted over type safe length.
foreign import ccall unsafe "string.h memcpy" c_memcpy
    :: Dest (Ptr dest) -> Src (Ptr src) -> BYTES Int -> IO (Ptr ())

-- | Copy between pointers.
memcpy :: (LengthUnit l, Pointer ptrS, Pointer ptrD)
       => Dest (ptrD dest) -- ^ destination
       -> Src  (ptrS src)  -- ^ src
       -> l               -- ^ Number of Bytes to copy
       -> IO ()
memcpy :: Dest (ptrD dest) -> Src (ptrS src) -> l -> IO ()
memcpy Dest (ptrD dest)
dest Src (ptrS src)
src = IO (Ptr ()) -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO (Ptr ()) -> IO ()) -> (l -> IO (Ptr ())) -> l -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Dest (Ptr dest) -> Src (Ptr src) -> BYTES Int -> IO (Ptr ())
forall dest src.
Dest (Ptr dest) -> Src (Ptr src) -> BYTES Int -> IO (Ptr ())
c_memcpy Dest (Ptr dest)
destRaw Src (Ptr src)
srcRaw (BYTES Int -> IO (Ptr ())) -> (l -> BYTES Int) -> l -> IO (Ptr ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. l -> BYTES Int
forall u. LengthUnit u => u -> BYTES Int
inBytes
  where destRaw :: Dest (Ptr dest)
destRaw = ptrD dest -> Ptr dest
forall (ptr :: * -> *) a. Pointer ptr => ptr a -> Ptr a
unsafeRawPtr (ptrD dest -> Ptr dest) -> Dest (ptrD dest) -> Dest (Ptr dest)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Dest (ptrD dest)
dest
        srcRaw :: Src (Ptr src)
srcRaw  = ptrS src -> Ptr src
forall (ptr :: * -> *) a. Pointer ptr => ptr a -> Ptr a
unsafeRawPtr (ptrS src -> Ptr src) -> Src (ptrS src) -> Src (Ptr src)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Src (ptrS src)
src

{-# SPECIALIZE memcpy :: Dest (Ptr dest) -> Src (Ptr src) -> BYTES Int -> IO () #-}

foreign import ccall unsafe "string.h memset" c_memset
    :: Ptr buf -> Word8 -> BYTES Int -> IO (Ptr ())

-- | Sets the given number of Bytes to the specified value.
memset :: (LengthUnit l, Pointer ptr)
       => ptr a     -- ^ Target
       -> Word8     -- ^ Value byte to set
       -> l         -- ^ Number of bytes to set
       -> IO ()
memset :: ptr a -> Word8 -> l -> IO ()
memset ptr a
p Word8
w = IO (Ptr ()) -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO (Ptr ()) -> IO ()) -> (l -> IO (Ptr ())) -> l -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Ptr a -> Word8 -> BYTES Int -> IO (Ptr ()))
-> ptr a -> Word8 -> BYTES Int -> IO (Ptr ())
forall (ptr :: * -> *) a b.
Pointer ptr =>
(Ptr a -> b) -> ptr a -> b
unsafeWithPointer Ptr a -> Word8 -> BYTES Int -> IO (Ptr ())
forall buf. Ptr buf -> Word8 -> BYTES Int -> IO (Ptr ())
c_memset ptr a
p Word8
w (BYTES Int -> IO (Ptr ())) -> (l -> BYTES Int) -> l -> IO (Ptr ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. l -> BYTES Int
forall u. LengthUnit u => u -> BYTES Int
inBytes
{-# SPECIALIZE memset :: Ptr a -> Word8 -> BYTES Int -> IO () #-}

-- | The type @AlignedPtr n@ that captures pointers that are aligned
-- to @n@ byte boundary.
newtype AlignedPtr (n :: Nat) a = AlignedPtr { AlignedPtr n a -> Ptr a
forgetAlignment :: Ptr a}

instance KnownNat n => Pointer (AlignedPtr n) where
  unsafeRawPtr :: AlignedPtr n a -> Ptr a
unsafeRawPtr  = AlignedPtr n a -> Ptr a
forall (n :: Nat) a. AlignedPtr n a -> Ptr a
forgetAlignment
  {-# INLINE unsafeRawPtr #-}
  castPointer :: AlignedPtr n a -> AlignedPtr n b
castPointer   = Ptr b -> AlignedPtr n b
forall (n :: Nat) a. Ptr a -> AlignedPtr n a
AlignedPtr (Ptr b -> AlignedPtr n b)
-> (AlignedPtr n a -> Ptr b) -> AlignedPtr n a -> AlignedPtr n b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr a -> Ptr b
forall a b. Ptr a -> Ptr b
castPtr (Ptr a -> Ptr b)
-> (AlignedPtr n a -> Ptr a) -> AlignedPtr n a -> Ptr b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AlignedPtr n a -> Ptr a
forall (n :: Nat) a. AlignedPtr n a -> Ptr a
forgetAlignment
  {-# INLINE castPointer #-}

  allocaPointer :: BYTES Int -> (AlignedPtr n a -> IO b) -> IO b
allocaPointer (BYTES Int
sz) AlignedPtr n a -> IO b
action =
    Int -> Int -> (Ptr a -> IO b) -> IO b
forall a b. Int -> Int -> (Ptr a -> IO b) -> IO b
allocaBytesAligned Int
sz Int
algn (AlignedPtr n a -> IO b
action (AlignedPtr n a -> IO b)
-> (Ptr a -> AlignedPtr n a) -> Ptr a -> IO b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr a -> AlignedPtr n a
forall (n :: Nat) a. Ptr a -> AlignedPtr n a
AlignedPtr)
    where algn :: Int
algn  = Integer -> Int
forall a. Enum a => a -> Int
fromEnum (Integer -> Int) -> Integer -> Int
forall a b. (a -> b) -> a -> b
$ Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n -> Integer) -> Proxy n -> Integer
forall a b. (a -> b) -> a -> b
$ (AlignedPtr n a -> IO b) -> Proxy n
forall (n :: Nat) a b. (AlignedPtr n a -> IO b) -> Proxy n
getProxy AlignedPtr n a -> IO b
action
          getProxy :: (AlignedPtr n a -> IO b) -> Proxy n
          getProxy :: (AlignedPtr n a -> IO b) -> Proxy n
getProxy AlignedPtr n a -> IO b
_ = Proxy n
forall k (t :: k). Proxy t
Proxy

-- | Given a raw pointer (i.e. element of type `Ptr`), returns the
-- next pointer aligned to @n@-bytes boundary.
nextAlignedPtr :: (Storable a, KnownNat n) => Ptr a -> AlignedPtr n a
nextAlignedPtr :: Ptr a -> AlignedPtr n a
nextAlignedPtr = Ptr a -> AlignedPtr n a
forall a (n :: Nat).
(Storable a, KnownNat n) =>
Ptr a -> AlignedPtr n a
alignIt
  where alignIt :: Ptr a -> AlignedPtr n a
alignIt Ptr a
ptr = Ptr a -> AlignedPtr n a
forall (n :: Nat) a. Ptr a -> AlignedPtr n a
AlignedPtr
                      (Ptr a -> AlignedPtr n a) -> Ptr a -> AlignedPtr n a
forall a b. (a -> b) -> a -> b
$ Ptr a -> Alignment -> Ptr a
forall a. Storable a => Ptr a -> Alignment -> Ptr a
alignPtr Ptr a
ptr
                      (Alignment -> Ptr a) -> Alignment -> Ptr a
forall a b. (a -> b) -> a -> b
$ Proxy (AlignedPtr n a) -> Alignment
forall (n :: Nat) a.
KnownNat n =>
Proxy (AlignedPtr n a) -> Alignment
ptrAlignment
                      (Proxy (AlignedPtr n a) -> Alignment)
-> Proxy (AlignedPtr n a) -> Alignment
forall a b. (a -> b) -> a -> b
$ (Ptr a -> AlignedPtr n a) -> Proxy (AlignedPtr n a)
forall a (n :: Nat).
(Ptr a -> AlignedPtr n a) -> Proxy (AlignedPtr n a)
getProxy Ptr a -> AlignedPtr n a
alignIt
        getProxy :: (Ptr a -> AlignedPtr n a) -> Proxy (AlignedPtr n a)
        getProxy :: (Ptr a -> AlignedPtr n a) -> Proxy (AlignedPtr n a)
getProxy Ptr a -> AlignedPtr n a
_  = Proxy (AlignedPtr n a)
forall k (t :: k). Proxy t
Proxy

-- | Compute the alignment restriction.
ptrAlignment :: KnownNat n => Proxy (AlignedPtr n a) -> Alignment
ptrAlignment :: Proxy (AlignedPtr n a) -> Alignment
ptrAlignment = Int -> Alignment
Alignment (Int -> Alignment)
-> (Proxy (AlignedPtr n a) -> Int)
-> Proxy (AlignedPtr n a)
-> Alignment
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Int
forall a. Enum a => a -> Int
fromEnum (Integer -> Int)
-> (Proxy (AlignedPtr n a) -> Integer)
-> Proxy (AlignedPtr n a)
-> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n -> Integer)
-> (Proxy (AlignedPtr n a) -> Proxy n)
-> Proxy (AlignedPtr n a)
-> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy (AlignedPtr n a) -> Proxy n
forall (n :: Nat) a. Proxy (AlignedPtr n a) -> Proxy n
coerce
  where coerce :: Proxy (AlignedPtr n a) -> Proxy n
        coerce :: Proxy (AlignedPtr n a) -> Proxy n
coerce = Proxy n -> Proxy (AlignedPtr n a) -> Proxy n
forall a b. a -> b -> a
const Proxy n
forall k (t :: k). Proxy t
Proxy
--------------------------

instance Unbox w => Unbox (BYTES w)
newtype instance MVector s (BYTES w) = MV_BYTES (MVector s w)
newtype instance Vector    (BYTES w) = V_BYTES  (Vector w)

instance Unbox w => GVM.MVector MVector (BYTES w) where
  {-# INLINE basicLength #-}
  {-# INLINE basicUnsafeSlice #-}
  {-# INLINE basicOverlaps #-}
  {-# INLINE basicUnsafeNew #-}
  {-# INLINE basicUnsafeReplicate #-}
  {-# INLINE basicUnsafeRead #-}
  {-# INLINE basicUnsafeWrite #-}
  {-# INLINE basicClear #-}
  {-# INLINE basicSet #-}
  {-# INLINE basicUnsafeCopy #-}
  {-# INLINE basicUnsafeGrow #-}
  basicLength :: MVector s (BYTES w) -> Int
basicLength          (MV_BYTES v)           = MVector s w -> Int
forall (v :: * -> * -> *) a s. MVector v a => v s a -> Int
GVM.basicLength MVector s w
v
  basicUnsafeSlice :: Int -> Int -> MVector s (BYTES w) -> MVector s (BYTES w)
basicUnsafeSlice Int
i Int
n (MV_BYTES v)           = MVector s w -> MVector s (BYTES w)
forall s w. MVector s w -> MVector s (BYTES w)
MV_BYTES (MVector s w -> MVector s (BYTES w))
-> MVector s w -> MVector s (BYTES w)
forall a b. (a -> b) -> a -> b
$ Int -> Int -> MVector s w -> MVector s w
forall (v :: * -> * -> *) a s.
MVector v a =>
Int -> Int -> v s a -> v s a
GVM.basicUnsafeSlice Int
i Int
n MVector s w
v
  basicOverlaps :: MVector s (BYTES w) -> MVector s (BYTES w) -> Bool
basicOverlaps (MV_BYTES v1) (MV_BYTES v2)   = MVector s w -> MVector s w -> Bool
forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> v s a -> Bool
GVM.basicOverlaps MVector s w
v1 MVector s w
v2

  basicUnsafeRead :: MVector (PrimState m) (BYTES w) -> Int -> m (BYTES w)
basicUnsafeRead  (MV_BYTES v) Int
i             = w -> BYTES w
forall a. a -> BYTES a
BYTES (w -> BYTES w) -> m w -> m (BYTES w)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MVector (PrimState m) w -> Int -> m w
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
v (PrimState m) a -> Int -> m a
GVM.basicUnsafeRead MVector (PrimState m) w
v Int
i
  basicUnsafeWrite :: MVector (PrimState m) (BYTES w) -> Int -> BYTES w -> m ()
basicUnsafeWrite (MV_BYTES v) Int
i (BYTES w
x)   = MVector (PrimState m) w -> Int -> w -> m ()
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
v (PrimState m) a -> Int -> a -> m ()
GVM.basicUnsafeWrite MVector (PrimState m) w
v Int
i w
x

  basicClear :: MVector (PrimState m) (BYTES w) -> m ()
basicClear (MV_BYTES v)                     = MVector (PrimState m) w -> m ()
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
v (PrimState m) a -> m ()
GVM.basicClear MVector (PrimState m) w
v
  basicSet :: MVector (PrimState m) (BYTES w) -> BYTES w -> m ()
basicSet   (MV_BYTES v)         (BYTES w
x)   = MVector (PrimState m) w -> w -> m ()
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
v (PrimState m) a -> a -> m ()
GVM.basicSet MVector (PrimState m) w
v w
x

  basicUnsafeNew :: Int -> m (MVector (PrimState m) (BYTES w))
basicUnsafeNew Int
n                            = MVector (PrimState m) w -> MVector (PrimState m) (BYTES w)
forall s w. MVector s w -> MVector s (BYTES w)
MV_BYTES (MVector (PrimState m) w -> MVector (PrimState m) (BYTES w))
-> m (MVector (PrimState m) w)
-> m (MVector (PrimState m) (BYTES w))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> m (MVector (PrimState m) w)
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
Int -> m (v (PrimState m) a)
GVM.basicUnsafeNew Int
n
  basicUnsafeReplicate :: Int -> BYTES w -> m (MVector (PrimState m) (BYTES w))
basicUnsafeReplicate Int
n     (BYTES w
x)        = MVector (PrimState m) w -> MVector (PrimState m) (BYTES w)
forall s w. MVector s w -> MVector s (BYTES w)
MV_BYTES (MVector (PrimState m) w -> MVector (PrimState m) (BYTES w))
-> m (MVector (PrimState m) w)
-> m (MVector (PrimState m) (BYTES w))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> w -> m (MVector (PrimState m) w)
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
Int -> a -> m (v (PrimState m) a)
GVM.basicUnsafeReplicate Int
n w
x
  basicUnsafeCopy :: MVector (PrimState m) (BYTES w)
-> MVector (PrimState m) (BYTES w) -> m ()
basicUnsafeCopy (MV_BYTES v1) (MV_BYTES v2) = MVector (PrimState m) w -> MVector (PrimState m) w -> m ()
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
v (PrimState m) a -> v (PrimState m) a -> m ()
GVM.basicUnsafeCopy MVector (PrimState m) w
v1 MVector (PrimState m) w
v2
  basicUnsafeGrow :: MVector (PrimState m) (BYTES w)
-> Int -> m (MVector (PrimState m) (BYTES w))
basicUnsafeGrow (MV_BYTES v)   Int
n            = MVector (PrimState m) w -> MVector (PrimState m) (BYTES w)
forall s w. MVector s w -> MVector s (BYTES w)
MV_BYTES (MVector (PrimState m) w -> MVector (PrimState m) (BYTES w))
-> m (MVector (PrimState m) w)
-> m (MVector (PrimState m) (BYTES w))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MVector (PrimState m) w -> Int -> m (MVector (PrimState m) w)
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
v (PrimState m) a -> Int -> m (v (PrimState m) a)
GVM.basicUnsafeGrow MVector (PrimState m) w
v Int
n
  basicInitialize :: MVector (PrimState m) (BYTES w) -> m ()
basicInitialize (MV_BYTES v)                = MVector (PrimState m) w -> m ()
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
v (PrimState m) a -> m ()
GVM.basicInitialize MVector (PrimState m) w
v



instance Unbox w => GV.Vector Vector (BYTES w) where
  {-# INLINE basicUnsafeFreeze #-}
  {-# INLINE basicUnsafeThaw #-}
  {-# INLINE basicLength #-}
  {-# INLINE basicUnsafeSlice #-}
  {-# INLINE basicUnsafeIndexM #-}
  {-# INLINE elemseq #-}
  basicUnsafeFreeze :: Mutable Vector (PrimState m) (BYTES w) -> m (Vector (BYTES w))
basicUnsafeFreeze (MV_BYTES v)            = Vector w -> Vector (BYTES w)
forall w. Vector w -> Vector (BYTES w)
V_BYTES  (Vector w -> Vector (BYTES w))
-> m (Vector w) -> m (Vector (BYTES w))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Mutable Vector (PrimState m) w -> m (Vector w)
forall (v :: * -> *) a (m :: * -> *).
(Vector v a, PrimMonad m) =>
Mutable v (PrimState m) a -> m (v a)
GV.basicUnsafeFreeze MVector (PrimState m) w
Mutable Vector (PrimState m) w
v
  basicUnsafeThaw :: Vector (BYTES w) -> m (Mutable Vector (PrimState m) (BYTES w))
basicUnsafeThaw (V_BYTES v)               = MVector (PrimState m) w -> MVector (PrimState m) (BYTES w)
forall s w. MVector s w -> MVector s (BYTES w)
MV_BYTES (MVector (PrimState m) w -> MVector (PrimState m) (BYTES w))
-> m (MVector (PrimState m) w)
-> m (MVector (PrimState m) (BYTES w))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Vector w -> m (Mutable Vector (PrimState m) w)
forall (v :: * -> *) a (m :: * -> *).
(Vector v a, PrimMonad m) =>
v a -> m (Mutable v (PrimState m) a)
GV.basicUnsafeThaw Vector w
v
  basicLength :: Vector (BYTES w) -> Int
basicLength (V_BYTES v)                   = Vector w -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
GV.basicLength Vector w
v
  basicUnsafeSlice :: Int -> Int -> Vector (BYTES w) -> Vector (BYTES w)
basicUnsafeSlice Int
i Int
n (V_BYTES v)          = Vector w -> Vector (BYTES w)
forall w. Vector w -> Vector (BYTES w)
V_BYTES (Vector w -> Vector (BYTES w)) -> Vector w -> Vector (BYTES w)
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Vector w -> Vector w
forall (v :: * -> *) a. Vector v a => Int -> Int -> v a -> v a
GV.basicUnsafeSlice Int
i Int
n Vector w
v
  basicUnsafeIndexM :: Vector (BYTES w) -> Int -> m (BYTES w)
basicUnsafeIndexM (V_BYTES v) Int
i           = w -> BYTES w
forall a. a -> BYTES a
BYTES   (w -> BYTES w) -> m w -> m (BYTES w)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>  Vector w -> Int -> m w
forall (v :: * -> *) a (m :: * -> *).
(Vector v a, Monad m) =>
v a -> Int -> m a
GV.basicUnsafeIndexM Vector w
v Int
i

  basicUnsafeCopy :: Mutable Vector (PrimState m) (BYTES w) -> Vector (BYTES w) -> m ()
basicUnsafeCopy (MV_BYTES mv) (V_BYTES v) = Mutable Vector (PrimState m) w -> Vector w -> m ()
forall (v :: * -> *) a (m :: * -> *).
(Vector v a, PrimMonad m) =>
Mutable v (PrimState m) a -> v a -> m ()
GV.basicUnsafeCopy MVector (PrimState m) w
Mutable Vector (PrimState m) w
mv Vector w
v
  elemseq :: Vector (BYTES w) -> BYTES w -> b -> b
elemseq Vector (BYTES w)
_ (BYTES w
x)                       = Vector w -> w -> b -> b
forall (v :: * -> *) a b. Vector v a => v a -> a -> b -> b
GV.elemseq (forall a. Vector a
forall a. HasCallStack => a
undefined :: Vector a) w
x