text:
{-# LANGUAGE FunctionalDependencies #-}

module Distribution (
    Dist, pdf, logpdf, samplefrom,
    Uniform(..), Normal(..), Bernoulli(..),
    Exponential(..), Gamma(..), Poisson(..),
    Binomial(..), Beta(..),
    Prob, Weight, Weighted
) where

import Randomness ( Random(..), uniform, Prob, Weight, Weighted )
import Numeric.Log ( Log(..) )
import qualified Data.Random.Distribution.Uniform as R ( uniform )
import qualified Data.Random.Distribution.Normal as R ( normal )
import qualified Data.Random.Distribution.Bernoulli as R ( bernoulli )
import qualified Data.Random.Distribution.Binomial as R ( binomial )
import qualified Data.Random.Distribution.Poisson as R ( poisson )
import qualified Statistics.Distribution as S ( ContDistr(density, logDensity, quantile), DiscreteDistr(probability, logProbability) )
import qualified Statistics.Distribution.Uniform as S ( uniformDistr )
import qualified Statistics.Distribution.Normal as S ( normalDistr )
import qualified Statistics.Distribution.Binomial as S ( binomial )
import qualified Statistics.Distribution.Poisson as S ( poisson )
import qualified Statistics.Distribution.Gamma as S ( gammaDistr )
import qualified Statistics.Distribution.Exponential as S ( exponential )
import qualified Statistics.Distribution.Binomial as S ( binomial )
import qualified Statistics.Distribution.Beta as S ( betaDistr )
import qualified Statistics.Distribution.DiscreteUniform as S ( discreteUniformAB )

class Dist d a | d -> a where
    samplefrom :: d -> Random a

    pdf :: d -> a -> Double
    pdf d = exp . ln . logpdf d

    logpdf :: d -> a -> Weight
    logpdf d = Exp . log . pdf d

data Uniform = Uniform Double Double
-- data DiscreteUniform = DiscreteUniform Int Int
data Normal = Normal Double Double
data Bernoulli = Bernoulli Prob
data Exponential = Exponential Double
data Gamma = Gamma Double Double
data Poisson = Poisson Double
data Binomial = Binomial Int Prob
data Beta = Beta Double Double

instance Dist Uniform Double where
    pdf (Uniform a b) = S.density $ S.uniformDistr a b
    logpdf (Uniform a b) = Exp . S.logDensity (S.uniformDistr a b)
    samplefrom (Uniform a b) = do
        u <- uniform
        return $ a + u * (b - a)

{-
instance Dist DiscreteUniform Int where
    pdf (DiscreteUniform a b) = S.probability $ S.discreteUniformAB a b
    logpdf (DiscreteUniform a b) = Exp . S.logProbability (S.discreteUniformAB a b)
    samplefrom (DiscreteUniform a b) = uniform (a, b)
-}

instance Dist Normal Double where
    pdf (Normal mu sig) = S.density $ S.normalDistr mu sig
    logpdf (Normal mu sig) = Exp . S.logDensity (S.normalDistr mu sig)
    samplefrom (Normal mu sig) = S.quantile (S.normalDistr mu sig) <$> uniform

instance Dist Bernoulli Bool where
    pdf (Bernoulli p) b = if b then p else 1-p
    logpdf (Bernoulli p) b = if b then Exp $ log p else Exp $ log (1-p)
    samplefrom (Bernoulli p) = (<= p) <$> uniform

instance Dist Gamma Double where
    pdf (Gamma k theta) = S.density $ S.gammaDistr k theta
    logpdf (Gamma k theta) = Exp . S.logDensity (S.gammaDistr k theta)
    samplefrom (Gamma k theta) = S.quantile (S.gammaDistr k theta) <$> uniform

instance Dist Exponential Double where
    pdf (Exponential lambda) = S.density $ S.exponential lambda
    logpdf (Exponential lambda) = Exp . S.logDensity (S.exponential lambda)
    samplefrom (Exponential lambda) = S.quantile (S.exponential lambda) <$> uniform

instance Dist Beta Double where
    pdf (Beta a b) = S.density $ S.betaDistr a b
    logpdf (Beta a b) = Exp . S.logDensity (S.betaDistr a b)
    samplefrom (Beta a b) = do
        x <- samplefrom (Gamma a 1)
        y <- samplefrom (Gamma b 1)
        return $ x / (x+y)

instance Dist Poisson Int where
    pdf (Poisson lambda) = S.probability $ S.poisson lambda
    logpdf (Poisson lambda) = Exp . S.logProbability (S.poisson lambda)
    samplefrom (Poisson lambda) = step 0 1.0
        where
            l = exp (-lambda)
            step k p = do
                u <- uniform
                let p' = p*u
                if p' <= l then return k
                           else step (k+1) p'

instance Dist Binomial Int where
    pdf (Binomial n p) = S.probability $ S.binomial n p
    logpdf (Binomial n p) = Exp . S.logProbability (S.binomial n p)
    samplefrom d@(Binomial n p) | n <= 10 = sumBernoullis n 0
                                | otherwise = do
        let a = 1 + n `div` 2
        let b = 1 + n - a
        x <- samplefrom $ Beta (fromIntegral a) (fromIntegral b)
        if x >= p
            then samplefrom $ Binomial (a-1) (p/x)
            else do
                s <- samplefrom (Binomial (b-1) ((p-x)/(1-x)))
                return (s + a)
        where
            sumBernoullis 0 s = return s
            sumBernoullis n s = do
                u <- uniform
                if u <= p then sumBernoullis (n-1) (s+1) else sumBernoullis (n-1) s

max_stars_repo_name: kai-pischke/ppl

max_issues_repo_name: kai-pischke/ppl

max_forks_repo_name: kai-pischke/ppl


text:
module OrientationAnalysisShape where

import           Control.Monad           as M
import           Data.Array.Repa         as R
import           Data.Complex
import           Data.List               as L
import           DFT.Plan
import           Filter.Pinwheel
import           FokkerPlanck.MonteCarlo
import           FokkerPlanck.Pinwheel
import           Image.IO
import           STC
import           STC.OrientationScaleAnalysis
import           System.Directory
import           System.Environment
import           System.FilePath

main = do
  args@(numPointStr:theta0FreqsStr:alphaStr:idxStr:numOrientationSampleStr:shapeStr:whiteBackgroundFlagStr:numThreadStr:_) <-
    getArgs
  print args
  let numPoint = read numPointStr :: Int
      theta0Freq = read theta0FreqsStr :: Double
      theta0Freqs = [-theta0Freq .. theta0Freq]
      alpha = read alphaStr :: Double
      idx = read idxStr :: (Int, Int)
      numOrientationSample = read numOrientationSampleStr :: Int
      whiteBackgroundFlag = read whiteBackgroundFlagStr :: Bool
      numThread = read numThreadStr :: Int
      pinwheelParams =
        PinwheelParams numPoint numPoint alpha (exp 1) theta0Freqs [0]
      shape2D = read shapeStr :: Shape2D
      shapeArr' =
        makeShape2DContrast numPoint numPoint (ContrastArea whiteBackgroundFlag shape2D)
      folderPath = "output/test/OrientationAnalysisShape"
  createDirectoryIfMissing True folderPath
  shapeArr <- computeUnboxedP shapeArr'

  (plan1, imgF) <-
    makeImagePlan emptyPlan .
    computeS .
    R.map fromIntegral .
    R.backpermute
      (Z :. (3 :: Int) :. numPoint :. numPoint)
      (\(Z :. _ :. i :. j) -> (Z :. i :. j)) $
    shapeArr
  (plan, filterF, filterPIF) <- pinwheelFilter plan1 pinwheelParams
  convolvedImg <-
    fmap (\x -> R.slice x (Z :. All :. (0 :: Int) :. All :. All)) $
    convolvePinwheel plan filterF (R.slice imgF (Z :. (0 :: Int) :. All :. All))
  idx' <- plotMagnitudeOrientation
            folderPath
            numOrientationSample
            theta0Freqs
            convolvedImg
            idx
  plotImageRepa (folderPath </> "Shape.png") .
    ImageRepa 8 .
    computeS .
    R.traverse
      shapeArr
      (\(Z :. cols :. rows) -> (Z :. (3 :: Int) :. cols :. rows)) $
    (\f (Z :. k :. i :. j) ->
       if (i, j) == idx'
         then if k == 0
                then 255
                else 0
         else fromIntegral $ f (Z :. i :. j))

ext: hs

max_stars_repo_name: XinhuaZhang/Stochastic-Completion-Field

max_issues_repo_name: XinhuaZhang/Stochastic-Completion-Field

max_forks_repo_name: XinhuaZhang/Stochastic-Completion-Field


text:
{-# LANGUAGE TemplateHaskell #-}

-- | Inhabited types

module Data.Inhabited where

import Data.Complex
import Data.Int
import Data.Word

import Data.Inhabited.TH

-- | Inhabited types
class Inhabited a
  where
    -- | Example value. An example value does not have to be an agreed-upon
    -- default value. It can really be any value whatsoever.
    example :: a

instance Inhabited Bool             where example = False
instance Inhabited Int8             where example = 0
instance Inhabited Int16            where example = 0
instance Inhabited Int32            where example = 0
instance Inhabited Int64            where example = 0
instance Inhabited Word8            where example = 0
instance Inhabited Word16           where example = 0
instance Inhabited Word32           where example = 0
instance Inhabited Word64           where example = 0
instance Inhabited Float            where example = 0
instance Inhabited Double           where example = 0
instance Inhabited (Complex Float)  where example = 0
instance Inhabited (Complex Double) where example = 0

inhabitedTupleInstances 15

max_stars_repo_name: Abhiroop/mu-feldspar

max_issues_repo_name: Abhiroop/mu-feldspar

max_forks_repo_name: Abhiroop/mu-feldspar


text:
module DistanceGeometry
  (
  -- * Steps of algorithm
    generateDistBoundsMatr
  , triangleSmooth
  , randomDistMatr
  , distMatrToMetricMatr
  , largestEigValVec
  , generateCoorFromEigValVec
  , coordMatrToDistMatr
  , updateCoord

  -- * Error Functions
  , distanceErrorFunction
  , chiralErrorFunction
  ) where

import           Control.Lens
import           Control.Monad.State
import           Data.List                   (foldl', zipWith3)
import           Numeric.LinearAlgebra
import           Numeric.LinearAlgebra.Data
import           Numeric.LinearAlgebra.Devel
import           System.Random
import           Types

-- * Steps of algorithm
-- | Generate of a distance bounds matrix
generateDistBoundsMatr :: Molecule -> [Bond] -> (Matrix Double, Matrix Double)
generateDistBoundsMatr molecule bonds =
  let n = views atoms length molecule
      upperDist _ _ = 100
      lowerDist i j = getAtom i molecule ^. avdwrad +
                      getAtom j molecule ^. avdwrad
      fixedDist i j = sqrt $ (xj - xi) ^ 2 + (yj - yi) ^ 2 + (zj - zi) ^ 2
        where
          (Point xi yi zi) = getAtom i molecule ^. acoordin
          (Point xj yj zj) = getAtom j molecule ^. acoordin
      upper = build (n, n) (\i' j' ->
        let (i, j) = (fromEnum i', fromEnum j')
        in if i == j
           then 0
           else if isBonded i j bonds
                then fixedDist i j
                else upperDist i j)
      lower = build (n, n) (\i' j' ->
        let (i, j) = (fromEnum i', fromEnum j')
        in if i == j
           then 0
           else if isBonded i j bonds
                then fixedDist i j
                else lowerDist i j)
   in (upper, lower)

-- | Triangle Inequality Bounds Smoothing
-- triangleSmooth :: Matrix Double -> Either String (Matrix Double)
triangleSmooth :: (Matrix Double, Matrix Double) -> (Matrix Double, Matrix Double)
triangleSmooth (upper, lower) =
  let n = rows upper
      kij = [ (k, i, j)
       | k <- [0 .. n - 1]
       , i <- [0 .. n - 2]
       , j <- [i + 1 .. n - 1]
       ]
      smoothing (u0, l0) (k, i, j) = do
        let (u1, l1) = if e1 > e2 + e3
                       then (changeMatrix u0 (i, j) (e2 + e3), l0)
                       else (u0, l0)
                       where
                        e1 = u0 `atIndex` (i, j)
                        e2 = u0 `atIndex` (i, k)
                        e3 = u0 `atIndex` (k, j)
        let (u2, l2) = if e1 < e2 - e3
                       then (u1, changeMatrix l1 (i, j) (e2 - e3))
                       else (u1, l1)
                       where
                        e1 = l1 `atIndex` (i, j)
                        e2 = l1 `atIndex` (i, k)
                        e3 = u1 `atIndex` (k, j)
        let (u3, l3) = if e1 < e2 - e3
                       then (u2, changeMatrix l2 (i, j) (e2 - e3))
                       else (u2, l2)
                       where
                        e1 = l2 `atIndex` (i, j)
                        e2 = l2 `atIndex` (j, k)
                        e3 = u2 `atIndex` (k, i)
        if l3 ! i ! j > u3 ! i ! j
        then error "Erroneous Bounds"
        else (u3, l3)
      (upper', lower') = foldl' smoothing (upper, lower) kij
      newUpper = build (n, n) (\i' j' ->
        let (i, j) = (fromEnum i', fromEnum j')
        in if i < j
           then upper' `atIndex` (i, j)
           else upper' `atIndex` (j, i))
      newLower = build (n, n) (\i' j' ->
        let (i, j) = (fromEnum i', fromEnum j')
        in if i < j
           then lower' `atIndex` (i, j)
           else lower' `atIndex` (j, i))
   in (newUpper, newLower)

-- | Generation of a distance matrix by random selection
-- of distances between the bounds.
randomDistMatr :: (Matrix Double, Matrix Double) -> IO (Matrix Double)
randomDistMatr (upper, lower) = do
  let n = rows upper
  distanceVector <- sequence [ r
   | i <- [0 .. n - 1]
   , j <- [0 .. n - 1]
   , let a = lower `atIndex` (i, j)
         b = upper `atIndex` (i, j)
         r = if j <= i
             then return 0
             else randomRIO (a, b)
             ]
  let distanceMatrix = matrix n distanceVector
  return $ distanceMatrix `add` tr' distanceMatrix

-- | Improving Random Sampling: Metrization
metrization :: Matrix Double -> Matrix Double
metrization matrix = undefined

-- | Improving Random Sampling: Partial Metrization
partialMetrization :: Matrix Double -> Matrix Double
partialMetrization matrix = undefined

-- | Conversion of the distance matrix to a metric matrix
distMatrToMetricMatr :: Matrix Double -> Matrix Double
distMatrToMetricMatr matr =
  let n = rows matr
      m = fromIntegral n
      uTriangleMatr = build (n, n) (\i' j' ->
        let (i, j) = (fromEnum i', fromEnum j')
        in if j <= i
           then 0
           else matr `atIndex` (i, j))
      d0 i = (1 / m) * sumElements ((matr ! i) ^ 2) -
             (1 / m ^ 2) * sumElements (uTriangleMatr ^ 2)
  in build (n, n) (\i' j' ->
    let (i, j) = (fromEnum i', fromEnum j')
        a = d0 i
        b = d0 j
        c = matr `atIndex` (i, j)
    in (a + b - c ^ 2) / 2)

-- | distanceToMetricMatrix is symmetric matrix => eigenvalues is real
-- Function return @k@ pairs of eigenvalues and eigenvectors (as columns)
-- in descending order
largestEigValVec :: Matrix Double -> (Vector Double, Matrix Double)
largestEigValVec matr =
  if (not . isSymmetric) matr
  then error "The matrix is not symmetric"
  else (subVector 0 k eigval, takeColumns k eigvec)
  where
    (eigval, eigvec) = (eigSH . trustSym) matr
    k = min 3 (size eigval)

-- | Generation of three-dimensional coordinates from
-- eigenvalues and eigenvectors.
generateCoorFromEigValVec ::
  (Vector Double, Matrix Double) -> Matrix Double
generateCoorFromEigValVec (val, vec) =
  vec Numeric.LinearAlgebra.<> (sqrt . diag) val

-- | Convert coordinate matrix to
-- distance matrix.
coordMatrToDistMatr :: Matrix Double -> Matrix Double
coordMatrToDistMatr matr =
  let n = rows matr
      dist i j = sqrt $ (xj - xi) ^ 2 + (yj - yi) ^ 2 + (zj - zi) ^ 2
        where
          [xi, yi, zi] = toList $ matr ! i
          [xj, yj, zj] = toList $ matr ! j
      dmatr = build (n, n) (\i' j' ->
       let (i, j) = (fromEnum i', fromEnum j')
       in if j <= i
          then 0
          else dist i j)
  in dmatr `add` tr' dmatr

-- | Update coordinates
updateCoord :: Matrix Double -> Molecule -> Molecule
updateCoord coord mol = set atoms newatoms mol
  where
    newatoms = zipWith updatec (toRows coord) (view atoms mol)
    updatec coord' =
      execState
        (do acoordin . x .= coord' ! 0
            acoordin . y .= coord' ! 1
            acoordin . z .= coord' ! 2)

-- * Error Functions
-- | Distance error function.
distanceErrorFunction ::
     Matrix Double -> Matrix Double -> Matrix Double -> [Bond] -> Double
distanceErrorFunction coord upper lower bonds =
  let n = rows coord
      dist = coordMatrToDistMatr coord
      [d2, u2, l2] = map (^2) [dist, upper, lower]
      ij' = [(i, j) | i <- [0 .. n - 2], j <- [i + 1 .. n - 1]]
      ij = filter (\(i,j) -> not $ isBonded i j bonds) ij'
      f1 (i, j) =
        (+) $ max 0 (d2 ! i ! j - u2 ! i ! j) ^ 2 +
        max 0 (l2 ! i ! j ^ 2 - d2 ! i ! j) ^ 2
      f2 (i, j) =
        (+) $ max 0 (d2 ! i ! j / u2 ! i ! j - 1) ^ 2 +
        max 0 (l2 ! i ! j / d2 ! i ! j - 1) ^ 2
      f3 (i, j) =
        (+) $ max 0 (d2 ! i ! j / u2 ! i ! j - 1) ^ 2 +
        max 0 (2 * l2 ! i ! j / (l2 ! i ! j + d2 ! i ! j) - 1) ^ 2
   in foldr f1 0 ij + foldr f2 0 ij + foldr f3 0 ij

-- | Chiral error function.
chiralErrorFunction ::
     Matrix Double -> Matrix Double -> Matrix Double -> [Bond] -> Double
chiralErrorFunction coord upper lower bonds =
  let n = rows coord
      dist = coordMatrToDistMatr coord
      ijkm' = [(i,j,k,m) | i <- [0..n-1], j <- [i+1..n-1],
                           k <- [j+1..n-1], m <- [k+1..n-1]]
      ijkm = filter (isTetrahedra dist) ijkm'
        where
          isTetrahedra d (i,j,k,m) = all (isTriangle d) [(i,j,k), (i,j,m), (i,k,m), (j,k,m)] && all (checkAngles d) [(i,j,k,m)]-- (j,k,m,i), (k,m,i,j), (m,i,j,k)]
            where isTriangle d (i,j,k) = and [a + b > c, b + c > a, c + a > b]
                   where a = d ! i ! j
                         b = d ! i ! k
                         c = d ! j ! k
                  checkAngles d (i,j,k,m) = and [b1 + b2 > b3, b1 + b3 > b2, b2 + b3 > b1]
                   where a1 = d ! i ! j; a2 = d ! i ! k
                         a3 = d ! i ! m; a4 = d ! j ! k
                         a5 = d ! j ! m; a6 = d ! k ! m
                         b1 = acos $ (a1^2 + a2^2 - a4^2) / (2*a1*a2)
                         b2 = acos $ (a1^2 + a3^2 - a5^2) / (2*a1*a3)
                         b3 = acos $ (a2^2 + a3^2 - a6^2) / (2*a2*a3)
      vol (i,j,k,m) = (xj - xi) `dot` ((xk - xi) `cross` (xm - xi))
        where [xi,xj,xk,xm] = map (coord !) [i,j,k,m]
      u (i,j,k,m) = (sum . map (atIndex upper)) [(i, j), (j, k), (k, m), (m, i)]
      l (i,j,k,m) = (sum . map (atIndex lower)) [(i, j), (j, k), (k, m), (m, i)]
      f x@(i,j,k,m) = (+) $ max 0 (vol x - u x) ^ 2 + max 0 (l x - vol x)
  in foldr f 0 ijkm

-- * Utils.
-- | Изменяет значение матрицы @m@ по индексам (@i@,@j@) на указанное @v@
changeMatrix :: Matrix Double -> (Int, Int) -> Double -> Matrix Double
changeMatrix m (i, j) v =
  runSTMatrix $ do
    m' <- thawMatrix m
    writeMatrix m' i j v
    return m'

-- | Check the symmetric matrix
isSymmetric :: Matrix Double -> Bool
isSymmetric matr =
  let r = rows matr
      c = cols matr
      s = [matr ! i ! j == matr ! j ! i | i <- [0 .. r - 1], j <- [i .. c - 1]]
  in r == c && and s

-- | Определяет, связаны ли атомы
isBonded :: Serial -> Serial -> [Bond] -> Bool
isBonded n m s = (n, m) `elem` bonds s || (m, n) `elem` bonds s
  where bonds = map (\x -> (view bfid x, view bsid x))

-- | Get atom from molecule
getAtom :: Serial -> Molecule -> Atom
getAtom i = views atoms (!! i)

max_stars_repo_name: wurthel/distance-geometry

max_issues_repo_name: wurthel/distance-geometry

max_forks_repo_name: wurthel/distance-geometry


text:
{-# LANGUAGE Trustworthy, CPP, MagicHash, UnboxedTuples, BangPatterns #-}
{-# LANGUAGE FlexibleInstances, FlexibleContexts, TypeOperators #-}

{- |
    Module      :  SDP.Unboxed
    Copyright   :  (c) Andrey Mulik 2019-2021
    License     :  BSD-style
    Maintainer  :  work.a.mulik@gmail.com
    Portability :  non-portable (GHC extensions)

    "SDP.Unboxed" provide service class 'Unboxed', that needed for
    "SDP.Prim.SBytes"-based structures.
-}
module SDP.Unboxed
(
  -- * Unboxed
  Unboxed (..), cloneUnboxed#, cloneUnboxedM#, thawUnboxed#, freezeUnboxed#,

  -- ** Kind @(Type -> Type)@ proxies
  fromProxy, psizeof#, psizeof, pnewUnboxed, pcopyUnboxed, pcopyUnboxedM,
  pcloneUnboxed, pcloneUnboxedM, pthawUnboxed, pfreezeUnboxed,

  -- ** Kind @(Type -> Type -> Type)@ proxies
  fromProxy1, pnewUnboxed1, pcloneUnboxed1, pcopyUnboxed1, pcopyUnboxedM1,
  cloneUnboxed1#, pcloneUnboxedM1,

  -- Wrap helper
  Wrap (..), lzero#, single#, fromList#, fromFoldable#, fromListN#,
  newLinear#, newLinearN#, fromFoldableM#, concat#, pconcat
)
where

import Prelude ()
import SDP.SafePrelude
import SDP.Nullable
import SDP.Finite
import SDP.Shape
import SDP.Ratio

import GHC.Stable
import GHC.Base   hiding ( (.), foldr )
import GHC.Word
import GHC.Int
import GHC.Ptr
import GHC.ST

import Data.Complex

import Foreign.C.Types

#include "MachDeps.h"

default ()

--------------------------------------------------------------------------------

{- |
  'Unboxed' is a layer between untyped raw data and parameterized unboxed data
  structures. Also it prevents direct interaction with primitives.
-}
class (Eq e) => Unboxed e
  where
    {-# MINIMAL (sizeof#|sizeof), (!#), (!>#), writeByteArray#, newUnboxed #-}

    {- |
      @sizeof e n@ returns the length (in bytes) of primitive, where @n@ - count
      of elements, @e@ - type parameter.
    -}
    {-# INLINE sizeof #-}
    sizeof :: e -> Int -> Int
    sizeof e (I# c#) = I# (sizeof# e c#)

    -- | 'sizeof#' is unboxed 'sizeof'.
    {-# INLINE sizeof# #-}
    sizeof# :: e -> Int# -> Int#
    sizeof# e c# = case sizeof e (I# c#) of I# n# -> n#

    -- | Unsafe 'ByteArray#' reader with overloaded result type.
    (!#) :: ByteArray# -> Int# -> e

    -- | Unsafe 'MutableByteArray#' reader with overloaded result type.
    (!>#) :: MutableByteArray# s -> Int# -> State# s -> (# State# s, e #)

    -- | Unsafe 'MutableByteArray#' writer.
    writeByteArray# :: MutableByteArray# s -> Int# -> e -> State# s -> State# s

    {-# INLINE fillByteArray# #-}
    -- | Procedure for filling the array with the default value (like calloc).
    fillByteArray# :: MutableByteArray# s -> Int# -> e -> State# s -> State# s
    fillByteArray# mbytes# n# e = I# n# > 0 ? go (n# -# 1#) $ \ s1# -> s1#
      where
        go 0# s2# = writeByteArray# mbytes# 0# e s2#
        go c# s2# = go (c# -# 1#) (writeByteArray# mbytes# c# e s2#)

    {- |
      'newUnboxed' creates new 'MutableByteArray#' of given count of elements.
      First argument used as type variable.
    -}
    newUnboxed :: e -> Int# -> State# s -> (# State# s, MutableByteArray# s #)

    {-# INLINE newUnboxed' #-}
    {- |
      'newUnboxed'' is version of 'newUnboxed', that use first argument as
      initial value. May fail when trying to write 'error' or 'undefined'.
    -}
    newUnboxed' :: e -> Int# -> State# s -> (# State# s, MutableByteArray# s #)
    newUnboxed' e n# = \ s1# -> case newByteArray# (sizeof# e n#) s1# of
      (# s2#, mbytes# #) -> case fillByteArray# mbytes# n# e s2# of
        s3# -> (# s3#, mbytes# #)

    {- |
      @'copyUnboxed#' e bytes\# o1\# mbytes\# o2\# n\#@ unsafely writes elements
      from @bytes\#@ to @mbytes\#@, where o1\# and o2\# - offsets (element
      count), @n\#@ - count of elements to copy.
    -}
    copyUnboxed# :: e -> ByteArray# -> Int# -> MutableByteArray# s -> Int# -> Int# -> State# s -> State# s
    copyUnboxed# e bytes# o1# mbytes# o2# n# = copyByteArray# bytes# (sizeof# e o1#) mbytes# (sizeof# e o2#) (sizeof# e n#)

    {- |
      @'copyUnboxedM#' e msrc\# o1\# mbytes\# o2\# n\#@ unsafely writes elements
      from @msrc\#@ to @mbytes\#@, where o1\# and o2\# - offsets (element
      count), @n\#@ - count of elements to copy.
    -}
    copyUnboxedM# :: e -> MutableByteArray# s -> Int# -> MutableByteArray# s -> Int# -> Int# -> State# s -> State# s
    copyUnboxedM# e msrc# o1# mbytes# o2# n# = copyMutableByteArray# msrc# (sizeof# e o1#) mbytes# (sizeof# e o2#) (sizeof# e n#)

    {- |
      @'hashUnboxedWith' e len# off# bytes# salt@ returns @bytes#@ @FNV-1@ hash,
      where @off#@ and @len#@ is offset and length (in elements).

      Note: the standard definition of this function is written in Haskell using
      low-level functions, but this implementation mayn't be as efficient as the
      foreign procedure in the @hashable@ package.
    -}
    hashUnboxedWith :: e -> Int# -> Int# -> ByteArray# -> Int# -> Int#
    hashUnboxedWith e len# off# bytes# = go (sizeof# e off#) (sizeof# e len#)
      where
        go _  0# salt# = salt#
        go o# n# salt# = go (o# +# 1#) (n# -# 1#) (word2Int# hash#)
          where
            prod# = int2Word# (salt# *# 16777619#)
            elem# = indexWord8Array# bytes# o#
            hash# = prod# `xor#` elem#

--------------------------------------------------------------------------------

{- Unboxed helpers. -}

{- |
  @since 0.2
  @cloneUnboxed# e bytes# o# c#@ creates new @c#@-element length immutable slice
  of @bytes#@ beginning from @o#@-th element.
-}
cloneUnboxed# :: (Unboxed e) => e -> ByteArray# -> Int# -> Int# -> ByteArray#
cloneUnboxed# e bytes# o# c# = unwrap $ runST $ ST $
  \ s1# -> case newUnboxed e c# s1# of
    (# s2#, mbytes# #) -> case copyUnboxed# e bytes# o# mbytes# 0# c# s2# of
      s3# -> case unsafeFreezeByteArray# mbytes# s3# of
        (# s4#, bytes'# #) -> (# s4#, (Wrap bytes'#) #)

{- |
  @since 0.2.1
  @cloneUnboxedM# e mbytes# o# c#@ creates new @c#@-element length mutable slice
  of @bytes#@ beginning from @o#@-th element.
-}
cloneUnboxedM# :: (Unboxed e) => e -> MutableByteArray# s -> Int# -> Int# ->
  State# s -> (# State# s, MutableByteArray# s #)
cloneUnboxedM# e mbytes# o# n# = \ s1# -> case newByteArray# (sizeof# e n#) s1# of
  (# s2#, copy# #) -> case copyUnboxedM# e mbytes# o# copy# 0# n# s2# of
    s3# -> (# s3#, copy# #)

{- |
  @since 0.2.1
  @'thawUnboxed#' e bytes# c#@ creates new @sizeof# e c#@ bytes length
  'MutableByteArray#' and copy @bytes#@ to it.
-}
thawUnboxed# :: (Unboxed e) => e -> ByteArray# -> Int# ->
  State# s -> (# State# s, MutableByteArray# s #)
thawUnboxed# e bytes# c# = \ s1# -> case newByteArray# n# s1# of
    (# s2#, mbytes# #) -> case copyByteArray# bytes# 0# mbytes# 0# n# s2# of
      s3# -> (# s3#, mbytes# #)
  where
    n# = sizeof# e c#

{- |
  @since 0.2.1
  @'freezeUnboxed#' e mbytes# c#@ creates new @sizeof# e c#@ bytes length
  'ByteArray#' and copy @mbytes#@ to it.
-}
freezeUnboxed# :: (Unboxed e) => e -> MutableByteArray# s -> Int# ->
  State# s -> (# State# s, ByteArray# #)
freezeUnboxed# e mbytes# n# = \ s1# -> case cloneUnboxedM# e mbytes# 0# n# s1# of
  (# s2#, copy# #) -> unsafeFreezeByteArray# copy# s2#

--------------------------------------------------------------------------------

{- Rank 1 Unboxed proxies. -}

-- | Returns 'undefined' of suitable type.
fromProxy :: proxy e -> e
fromProxy =  const undefined

{- |
  @since 0.2.1
  'psizeof#' is proxy version of 'sizeof#'.
-}
psizeof# :: (Unboxed e) => proxy e -> Int# -> Int#
psizeof# =  sizeof# . fromProxy

{- |
  @since 0.2
  'psizeof' is proxy version of 'sizeof'.
-}
psizeof :: (Unboxed e) => proxy e -> Int -> Int
psizeof =  sizeof . fromProxy

{- |
  @since 0.2
  Kind @(Type -> Type)@ proxy version of 'newUnboxed'.
-}
pnewUnboxed :: (Unboxed e) => proxy e -> Int# ->
  State# s -> (# State# s, MutableByteArray# s #)
pnewUnboxed =  newUnboxed . fromProxy

{- |
  @since 0.2
  Kind @(Type -> Type)@ proxy version if 'copyUnboxed#'.
-}
pcopyUnboxed :: (Unboxed e) => proxy e -> ByteArray# -> Int# ->
  MutableByteArray# s -> Int# -> Int# -> State# s -> State# s
pcopyUnboxed =  copyUnboxed# . fromProxy

{- |
  @since 0.2
  Kind @(Type -> Type)@ proxy version if 'copyUnboxedM#'.
-}
pcopyUnboxedM :: (Unboxed e) => proxy e -> MutableByteArray# s -> Int# ->
  MutableByteArray# s -> Int# -> Int# -> State# s -> State# s
pcopyUnboxedM =  copyUnboxedM# . fromProxy

{- |
  @since 0.2
  Kind @(Type -> Type)@ proxy version of 'cloneUnboxed#'.
-}
cloneUnboxed1# :: (Unboxed e) => proxy e -> ByteArray# -> Int# -> Int# -> ByteArray#
cloneUnboxed1# =  cloneUnboxed# . fromProxy

{- |
  @since 0.2.1
  Same as @sdp-0.2@ 'cloneUnboxed1#'. Use only if you don't need @sdp-0.2@
  compatibility.
-}
pcloneUnboxed :: (Unboxed e) => proxy e -> ByteArray# -> Int# -> Int# -> ByteArray#
pcloneUnboxed =  cloneUnboxed1#

{- |
  @since 0.2.1
  Kind @(Type -> Type)@ proxy version of 'cloneUnboxed#'.
-}
pcloneUnboxedM :: (Unboxed e) => proxy e -> MutableByteArray# s -> Int# -> Int# ->
  State# s -> (# State# s, MutableByteArray# s #)
pcloneUnboxedM =  cloneUnboxedM# . fromProxy

{- |
  @since 0.2.1
  Kind @(Type -> Type)@ proxy version of 'thawUnboxed#'.
-}
pthawUnboxed :: (Unboxed e) => proxy e -> ByteArray# -> Int# ->
  State# s -> (# State# s, MutableByteArray# s #)
pthawUnboxed =  thawUnboxed# . fromProxy

{- |
  @since 0.2.1
  Kind @(Type -> Type)@ proxy version of 'pfreezeUnboxed'.
-}
pfreezeUnboxed :: (Unboxed e) => proxy e -> MutableByteArray# s -> Int# ->
  State# s -> (# State# s, ByteArray# #)
pfreezeUnboxed =  freezeUnboxed# . fromProxy

--------------------------------------------------------------------------------

{- (Type -> Type -> Type)-kind Unboxed proxies. -}

-- | Returns 'undefined' of suitable type.
fromProxy1 :: m (proxy e) -> e
fromProxy1 =  const undefined

{- |
  @since 0.2
  Kind @(Type -> Type -> Type)@ proxy version of 'newUnboxed'.
-}
pnewUnboxed1 :: (Unboxed e) => p (proxy e) -> Int# ->
  State# s -> (# State# s, MutableByteArray# s #)
pnewUnboxed1 =  newUnboxed . fromProxy1

{- |
  @since 0.2
  Kind @(Type -> Type -> Type)@ proxy version of 'copyUnboxed#'.
-}
pcopyUnboxed1 :: (Unboxed e) => p (proxy e) -> ByteArray# -> Int# ->
  MutableByteArray# s -> Int# -> Int# -> State# s -> State# s
pcopyUnboxed1 =  copyUnboxed# . fromProxy1

{- |
  @since 0.2.1
  Kind @(Type -> Type -> Type)@ proxy version of 'copyUnboxedM#'.
-}
pcopyUnboxedM1 :: (Unboxed e) => p (proxy e) -> MutableByteArray# s -> Int# ->
  MutableByteArray# s -> Int# -> Int# -> State# s -> State# s
pcopyUnboxedM1 =  copyUnboxedM# . fromProxy1

{- |
  @since 0.2.1
  Kind @(Type -> Type -> Type)@ proxy version of 'cloneUnboxed#'.
-}
pcloneUnboxed1 :: (Unboxed e) => p (proxy e) -> ByteArray# -> Int# -> Int# -> ByteArray#
pcloneUnboxed1 =  cloneUnboxed# . fromProxy1

{- |
  @since 0.2.1
  Kind @(Type -> Type -> Type)@ proxy version of 'cloneUnboxed#'.
-}
pcloneUnboxedM1 :: (Unboxed e) => p (proxy e) -> MutableByteArray# s -> Int# -> Int# ->
  State# s -> (# State# s, MutableByteArray# s #)
pcloneUnboxedM1 =  cloneUnboxedM# . fromProxy1

--------------------------------------------------------------------------------

{- Numeric instances. -}

instance Unboxed Int
  where
    {-# INLINE sizeof #-}
    sizeof _ n = max 0 n * SIZEOF_HSWORD

    {-# INLINE (!#) #-}
    bytes# !# i# = I# (indexIntArray# bytes# i#)

    {-# INLINE (!>#) #-}
    mbytes# !># i# = \ s1# -> case readIntArray# mbytes# i# s1# of
      (# s2#, e# #) -> (# s2#, I# e# #)

    {-# INLINE writeByteArray# #-}
    writeByteArray# mbytes# n# (I# e#) = writeIntArray# mbytes# n# e#

    {-# INLINE newUnboxed #-}
    newUnboxed _ = newUnboxed' (0 :: Int)

instance Unboxed Int8
  where
    {-# INLINE sizeof #-}
    sizeof _ n = max 0 n

    {-# INLINE (!#) #-}
    bytes# !# i# = I8# (indexInt8Array# bytes# i#)

    {-# INLINE (!>#) #-}
    mbytes# !># i# = \ s1# -> case readInt8Array# mbytes# i# s1# of
      (# s2#, e# #) -> (# s2#, I8# e# #)

    {-# INLINE writeByteArray# #-}
    writeByteArray# mbytes# n# (I8# e#) = writeInt8Array# mbytes# n# e#

    {-# INLINE newUnboxed #-}
    newUnboxed _ = newUnboxed' (0 :: Int8)

instance Unboxed Int16
  where
    {-# INLINE sizeof #-}
    sizeof _ n = max 0 n * 2

    {-# INLINE (!#) #-}
    bytes# !# i# = I16# (indexInt16Array# bytes# i#)

    {-# INLINE (!>#) #-}
    mbytes# !># i# = \ s1# -> case readInt16Array# mbytes# i# s1# of
      (# s2#, e# #) -> (# s2#, I16# e# #)

    {-# INLINE writeByteArray# #-}
    writeByteArray# mbytes# n# (I16# e#) = writeInt16Array# mbytes# n# e#

    {-# INLINE newUnboxed #-}
    newUnboxed _ = newUnboxed' (0 :: Int16)

instance Unboxed Int32
  where
    {-# INLINE sizeof #-}
    sizeof _ n = max 0 n * 4

    {-# INLINE (!#) #-}
    bytes# !# i# = I32# (indexInt32Array# bytes# i#)

    {-# INLINE (!>#) #-}
    mbytes# !># i# = \ s1# -> case readInt32Array# mbytes# i# s1# of
      (# s2#, e# #) -> (# s2#, I32# e# #)

    {-# INLINE writeByteArray# #-}
    writeByteArray# mbytes# n# (I32# e#) = writeInt32Array# mbytes# n# e#

    {-# INLINE newUnboxed #-}
    newUnboxed _ = newUnboxed' (0 :: Int32)

instance Unboxed Int64
  where
    {-# INLINE sizeof #-}
    sizeof _ n = max 0 n * 8

    {-# INLINE (!#) #-}
    bytes# !# i# = I64# (indexInt64Array# bytes# i#)

    {-# INLINE (!>#) #-}
    mbytes# !># i# = \ s1# -> case readInt64Array# mbytes# i# s1# of
      (# s2#, e# #) -> (# s2#, I64# e# #)

    {-# INLINE writeByteArray# #-}
    writeByteArray# mbytes# n# (I64# e#) = writeInt64Array# mbytes# n# e#

    {-# INLINE newUnboxed #-}
    newUnboxed _ = newUnboxed' (0 :: Int64)

instance Unboxed Word
  where
    {-# INLINE sizeof #-}
    sizeof _ n = max 0 n * SIZEOF_HSWORD

    {-# INLINE (!#) #-}
    bytes# !# i# = W# (indexWordArray# bytes# i#)

    {-# INLINE (!>#) #-}
    mbytes# !># i# = \ s1# -> case readWordArray# mbytes# i# s1# of
      (# s2#, e# #) -> (# s2#, W# e# #)

    {-# INLINE writeByteArray# #-}
    writeByteArray# mbytes# n# (W# e#) = writeWordArray# mbytes# n# e#

    {-# INLINE newUnboxed #-}
    newUnboxed _ = newUnboxed' (0 :: Word)

instance Unboxed Word8
  where
    {-# INLINE sizeof #-}
    sizeof _ n = max 0 n

    {-# INLINE (!#) #-}
    bytes# !# i# = W8# (indexWord8Array# bytes# i#)

    {-# INLINE (!>#) #-}
    mbytes# !># i# = \ s1# -> case readWord8Array# mbytes# i# s1# of
      (# s2#, e# #) -> (# s2#, W8# e# #)

    {-# INLINE writeByteArray# #-}
    writeByteArray# mbytes# n# (W8#  e#) = writeWord8Array# mbytes# n# e#

    {-# INLINE newUnboxed #-}
    newUnboxed _ = newUnboxed' (0 :: Word8)

instance Unboxed Word16
  where
    {-# INLINE sizeof #-}
    sizeof _ n = max 0 n * 2

    {-# INLINE (!#) #-}
    bytes# !# i# = W16# (indexWord16Array# bytes# i#)

    {-# INLINE (!>#) #-}
    mbytes# !># i# = \ s1# -> case readWord16Array# mbytes# i# s1# of
      (# s2#, e# #) -> (# s2#, W16# e# #)

    {-# INLINE writeByteArray# #-}
    writeByteArray# mbytes# n# (W16# e#) = writeWord16Array# mbytes# n# e#

    {-# INLINE newUnboxed #-}
    newUnboxed _ = newUnboxed' (0 :: Word16)

instance Unboxed Word32
  where
    {-# INLINE sizeof #-}
    sizeof _ n = max 0 n * 4

    {-# INLINE (!#) #-}
    bytes# !# i# = W32# (indexWord32Array# bytes# i#)

    {-# INLINE (!>#) #-}
    mbytes# !># i# = \ s1# -> case readWord32Array# mbytes# i# s1# of
      (# s2#, e# #) -> (# s2#, W32# e# #)

    {-# INLINE writeByteArray# #-}
    writeByteArray# mbytes# n# (W32# e#) = writeWord32Array# mbytes# n# e#

    {-# INLINE newUnboxed #-}
    newUnboxed _ = newUnboxed' (0 :: Word32)

instance Unboxed Word64
  where
    {-# INLINE sizeof #-}
    sizeof _ n = max 0 n * 8

    {-# INLINE (!#) #-}
    bytes# !# i# = W64# (indexWord64Array# bytes# i#)

    {-# INLINE (!>#) #-}
    mbytes# !># i# = \ s1# -> case readWord64Array# mbytes# i# s1# of
      (# s2#, e# #) -> (# s2#, W64# e# #)

    {-# INLINE writeByteArray# #-}
    writeByteArray# mbytes# n# (W64# e#) = writeWord64Array# mbytes# n# e#

    {-# INLINE newUnboxed #-}
    newUnboxed _ = newUnboxed' (0 :: Word64)

instance Unboxed Float
  where
    {-# INLINE sizeof #-}
    sizeof _ n = max 0 n * SIZEOF_HSFLOAT

    {-# INLINE (!#) #-}
    bytes# !# i# = F# (indexFloatArray# bytes# i#)

    {-# INLINE (!>#) #-}
    mbytes# !># i# = \ s1# -> case readFloatArray# mbytes# i# s1# of
      (# s2#, f# #) -> (# s2#, F# f# #)

    {-# INLINE writeByteArray# #-}
    writeByteArray# mbytes# n# (F# e#) = writeFloatArray# mbytes# n# e#

    {-# INLINE newUnboxed #-}
    newUnboxed _ = newUnboxed' (0 :: Float)

instance Unboxed Double
  where
    {-# INLINE sizeof #-}
    sizeof _ n = max 0 n * SIZEOF_HSDOUBLE

    {-# INLINE (!#) #-}
    bytes# !# i# = D# (indexDoubleArray# bytes# i#)

    {-# INLINE (!>#) #-}
    mbytes# !># i# = \ s1# -> case readDoubleArray# mbytes# i# s1# of
      (# s2#, d# #) -> (# s2#, D# d# #)

    {-# INLINE writeByteArray# #-}
    writeByteArray# mbytes# n# (D# e#) = writeDoubleArray# mbytes# n# e#

    {-# INLINE newUnboxed #-}
    newUnboxed _ = newUnboxed' (0 :: Double)

instance (Unboxed a, Integral a) => Unboxed (Ratio a)
  where
    sizeof e n = 2 * psizeof e n

    bytes# !# i# = bytes# !# i2# :% (bytes# !# (i2# +# 1#)) where i2# = 2# *# i#

    mbytes# !># i# = let i2# = 2# *# i# in \ s1# -> case (!>#) mbytes# i2# s1# of
      (# s2#, n #) -> case (!>#) mbytes# (i2# +# 1#) s2# of
        (# s3#, d #) -> (# s3#, n :% d #)

    {-# INLINE writeByteArray# #-}
    writeByteArray# mbytes# i# (n :% d) = let i2# = 2# *# i# in
      \ s1# -> case writeByteArray# mbytes# i2# n s1# of
        s2# -> writeByteArray# mbytes# (i2# +# 1#) d s2#

    {-# INLINE newUnboxed #-}
    newUnboxed e n# = pnewUnboxed e (2# *# n#)

instance (Unboxed a, Num a) => Unboxed (Complex a)
  where
    sizeof e n = 2 * psizeof e n

    bytes#  !#  i# = bytes# !# i2# :+ (bytes# !# (i2# +# 1#)) where i2# = 2# *# i#
    mbytes# !># i# = let i2# = 2# *# i# in \ s1# -> case (!>#) mbytes# i2# s1# of
      (# s2#, n #) -> case (!>#) mbytes# (i2# +# 1#) s2# of
        (# s3#, d #) -> (# s3#, n :+ d #)

    {-# INLINE writeByteArray# #-}
    writeByteArray# mbytes# i# (n :+ d) = let i2# = 2# *# i# in
      \ s1# -> case writeByteArray# mbytes# i2# n s1# of
        s2# -> writeByteArray# mbytes# (i2# +# 1#) d s2#

    {-# INLINE newUnboxed #-}
    newUnboxed e n# = pnewUnboxed e (2# *# n#)

--------------------------------------------------------------------------------

{- Pointer instances. -}

instance Unboxed (Ptr a)
  where
    {-# INLINE sizeof #-}
    sizeof _ n = max 0 n * SIZEOF_HSWORD

    {-# INLINE (!#) #-}
    bytes# !# i# = Ptr (indexAddrArray# bytes# i#)

    {-# INLINE (!>#) #-}
    mbytes# !># i# = \ s1# -> case readAddrArray# mbytes# i# s1# of
      (# s2#, e# #) -> (# s2#, Ptr e# #)

    {-# INLINE writeByteArray# #-}
    writeByteArray# mbytes# n# (Ptr e) = writeAddrArray# mbytes# n# e

    {-# INLINE newUnboxed #-}
    newUnboxed _ = newUnboxed' nullPtr

instance Unboxed (FunPtr a)
  where
    {-# INLINE sizeof #-}
    sizeof _ n = max 0 n * SIZEOF_HSWORD

    {-# INLINE (!#) #-}
    bytes#  !#  i# = FunPtr (indexAddrArray# bytes# i#)

    {-# INLINE (!>#) #-}
    mbytes# !># i# = \ s1# -> case readAddrArray# mbytes# i# s1# of
      (# s2#, e# #) -> (# s2#, FunPtr e# #)

    {-# INLINE writeByteArray# #-}
    writeByteArray# mbytes# n# (FunPtr e) = writeAddrArray# mbytes# n# e

    {-# INLINE newUnboxed #-}
    newUnboxed e = newUnboxed' (NULL `asTypeOf` e)

instance Unboxed (StablePtr a)
  where
    {-# INLINE sizeof #-}
    sizeof _ n = max 0 n * SIZEOF_HSWORD

    {-# INLINE (!#) #-}
    bytes# !# i# = StablePtr (indexStablePtrArray# bytes# i#)

    {-# INLINE (!>#) #-}
    mbytes# !># i# = \ s1# -> case readStablePtrArray# mbytes# i# s1# of
      (# s2#, e# #) -> (# s2#, StablePtr e# #)

    {-# INLINE writeByteArray# #-}
    writeByteArray# mbytes# n# (StablePtr e) = writeStablePtrArray# mbytes# n# e

    {-# INLINE newUnboxed #-}
    newUnboxed e = newUnboxed' (NULL `asTypeOf` e)

--------------------------------------------------------------------------------

{- Foreign C instances. -}

#define deriving_instance_Unboxed(Type)\
instance Unboxed Type where\
{\
  sizeof e = sizeof (consSizeof Type e);\
  arr# !# i# = Type ( arr# !# i# );\
  marr# !># i# = \ s1# -> case (!>#) marr# i# s1# of {(# s2#, e #) -> (# s2#, Type e #)};\
  writeByteArray# marr# i# (Type e) = writeByteArray# marr# i# e;\
  fillByteArray#  marr# i# (Type e) = fillByteArray#  marr# i# e;\
  newUnboxed  (Type e) = newUnboxed  e;\
  newUnboxed' (Type e) = newUnboxed' e;\
}

deriving_instance_Unboxed(CChar)
deriving_instance_Unboxed(CSChar)
deriving_instance_Unboxed(CWchar)
deriving_instance_Unboxed(CShort)
deriving_instance_Unboxed(CUShort)

deriving_instance_Unboxed(CInt)
deriving_instance_Unboxed(CUInt)
deriving_instance_Unboxed(CLong)
deriving_instance_Unboxed(CULong)
deriving_instance_Unboxed(CLLong)
deriving_instance_Unboxed(CULLong)
deriving_instance_Unboxed(CIntPtr)
deriving_instance_Unboxed(CUIntPtr)
deriving_instance_Unboxed(CIntMax)
deriving_instance_Unboxed(CUIntMax)
deriving_instance_Unboxed(CPtrdiff)

deriving_instance_Unboxed(CTime)
deriving_instance_Unboxed(CClock)
deriving_instance_Unboxed(CUSeconds)
deriving_instance_Unboxed(CSUSeconds)

deriving_instance_Unboxed(CSize)

#if MIN_VERSION_base(4,10,0)
-- | @since base-4.10.0.0
deriving_instance_Unboxed(CBool)
#endif

deriving_instance_Unboxed(CFloat)
deriving_instance_Unboxed(CDouble)
deriving_instance_Unboxed(CSigAtomic)

#undef deriving_instance_Unboxed

--------------------------------------------------------------------------------

{- Other instances. -}

instance Unboxed Bool
  where
    {-# INLINE sizeof #-}
    sizeof _ c = d == 0 ? n $ n + 1 where (n, d) = max 0 c `divMod` 8

    {-# INLINE (!#) #-}
    bytes# !# i# = isTrue# ((indexWordArray# bytes# (bool_index i#) `and#` bool_bit i#) `neWord#` int2Word# 0#)

    {-# INLINE (!>#) #-}
    mbytes# !># i# = \ s1# -> case readWordArray# mbytes# (bool_index i#) s1# of
      (# s2#, e# #) -> (# s2#, isTrue# ((e# `and#` bool_bit i#) `neWord#` int2Word# 0#) #)

    {-# INLINE writeByteArray# #-}
    writeByteArray# mbytes# n# e = \ s1# -> case readWordArray# mbytes# i# s1# of
        (# s2#, old_byte# #) -> writeWordArray# mbytes# i# (bitWrite old_byte#) s2#
      where
        bitWrite old_byte# = if e then old_byte# `or#` bool_bit n# else old_byte# `and#` bool_not_bit n#
        i# = bool_index n#

    {-# INLINE newUnboxed #-}
    newUnboxed _ = newUnboxed' False

    fillByteArray# mbytes# n# e =
      setByteArray# mbytes# 0# (bool_scale n#) (if e then 0xff# else 0#)

    copyUnboxed# e bytes# o1# mbytes# o2# c# = isTrue# (c# <# 1#) ? (\ s1# -> s1#) $
      \ s1# -> case writeByteArray# mbytes# o2# ((bytes# !# o1#) `asTypeOf` e) s1# of
        s2# -> copyUnboxed# e bytes# (o1# +# 1#) mbytes# (o2# +# 1#) (c# -# 1#) s2#

    copyUnboxedM# e src# o1# mbytes# o2# n# = \ s1# -> case (!>#) src# o1# s1# of
      (# s2#, x #) -> case writeByteArray# mbytes# o2# (x `asTypeOf` e) s2# of
        s3# -> copyUnboxedM# e src# (o1# +# 1#) mbytes# (o2# +# 1#) (n# -# 1#) s3#

    hashUnboxedWith e len# off# bytes#
        | isTrue#   (len# <# 1#)    = \ salt# -> salt#
        | isTrue#   (off# <# 0#)    = hashUnboxedWith e len# 0# bytes#
        | isTrue# (bit_off# ==# 0#) = go0 byte_cnt# byte_off#
        |            True           = goo byte_cnt# (byte_off# +# 1#) (indexWord8Array# bytes# byte_off#)
      where
        go0 0# _  salt# = salt#
        go0 1# o# salt# = hash# salt# (indexWord8Array# bytes# o# `and#` mask#)
        go0 n# o# salt# = go0 (n# -# 1#) (o# +# 1#) (salt# `hash#` indexWord8Array# bytes# o#)

        goo 0# _    _   salt# = salt#
        goo 1# _  temp# salt# = hash# salt# (shiftRL# temp# bit_off# `and#` mask#)
        goo n# o# temp# salt# = goo (n# -# 1#) (o# +# 1#) byte# (hash# salt# curr#)
          where
            curr# = shiftRL# temp# bit_off# `or#` shiftL# byte# (8# -# bit_off#)
            byte# = indexWord8Array# bytes# o#

        hash# = \ s# v# -> word2Int# (int2Word# (s# *# 16777619#) `xor#` v#)
        mask# = int2Word# 0xff# `shiftRL#` bit_rest#

        !(I# byte_off#, I# bit_off#) = I# off# `divMod` 8
        !(I# bit_len#) = I# len# `mod` 8

        bit_rest# = if isTrue# (bit_len# ==# 0#) then 0# else 8# -# bit_len#
        byte_cnt# = sizeof# e len#

instance Unboxed Char
  where
    {-# INLINE sizeof #-}
    sizeof _ n = max 0 n * 4

    {-# INLINE (!#) #-}
    bytes# !# i# = C# (indexWideCharArray# bytes# i#)

    {-# INLINE (!>#) #-}
    mbytes# !># i# = \ s1# -> case readWideCharArray# mbytes# i# s1# of
      (# s2#, c# #) -> (# s2#, C# c# #)

    {-# INLINE writeByteArray# #-}
    writeByteArray# mbytes# n# (C# e#) = writeWideCharArray# mbytes# n# e#

    {-# INLINE newUnboxed #-}
    newUnboxed e n# = \ s1# -> case newByteArray# (sizeof# e n#) s1# of
      (# s2#, mbytes# #) -> case fillByteArray# mbytes# n# '\0' s2# of
        s3# -> (# s3#, mbytes# #)

instance Unboxed E
  where
    {-# INLINE sizeof #-}
    sizeof _ _ = 0

    {-# INLINE (!#) #-}
    (!>#) = \ _ _ s# -> (# s#, E #)
    (!#)  = \ _ _ -> E

    newUnboxed  _ _ = newByteArray# 0#
    newUnboxed' _ _ = newByteArray# 0#

    writeByteArray# _ _ = \ _ s# -> s#
    fillByteArray#  _ _ = \ _ s# -> s#

instance (Unboxed e) => Unboxed (I1 e)
  where
    sizeof# = psizeof#
    sizeof  = psizeof

    bytes# !#  i# = E :& (bytes# !# i#)
    bytes# !># i# = \ s1# -> case (!>#) bytes# i# s1# of
      (# s2#, e #) -> (# s2#, E :& e #)

    writeByteArray# bytes# n# (E :& e) = writeByteArray# bytes# n# e
    fillByteArray#  bytes# n# (E :& e) = fillByteArray#  bytes# n# e

    newUnboxed' = \ (E :& i) -> newUnboxed i
    newUnboxed  = pnewUnboxed

instance (Enum e, Shape e, Bounded e, Unboxed e, Shape (e' :& e), Unboxed (e' :& e)) => Unboxed (e' :& e :& e)
  where
    sizeof# e n# = psizeof# e (rank# e *# n#)
    sizeof  e  n = psizeof  e (rank  e *   n)

    bytes# !# i# = go undefined
      where
        go t =
          let r# = rank# t; o# = i#*#r# +# i#
          in  ((bytes# !# o#) `asTypeOf` t) :& (bytes# !# (o# +# r#))

    bytes# !># i# = go undefined
      where
        go t = let r# = rank# t; o# = i#*#r# +# i# in
          \ s1# -> case (!>#) bytes# o# s1# of
            (# s2#, es #) -> case (!>#) bytes# (o# +# r#) s2# of
              (# s3#, e #) -> (# s3#, (es `asTypeOf` t) :& e #)

    writeByteArray# bytes# i# (es :& e) = let r# = rank# es; o# = i#*#r# +# i# in
      \ s1# -> case writeByteArray# bytes# o# es s1# of
        s2# -> writeByteArray# bytes# (o# +# r#) e s2#

    newUnboxed e n# = pnewUnboxed e (rank# e *# n#)

--------------------------------------------------------------------------------

{- Tuple instances. -}

instance Unboxed ()
  where
    {-# INLINE sizeof #-}
    sizeof _ _ = 0

    {-# INLINE (!#) #-}
    (!>#) = \ _ _ s# -> (# s#, () #)
    (!#)  = \ _ _ -> ()

    newUnboxed  _ _ = newByteArray# 0#
    newUnboxed' _ _ = newByteArray# 0#

    writeByteArray# _ _ = \ _ s# -> s#
    fillByteArray#  _ _ = \ _ s# -> s#

instance (Unboxed e) => Unboxed (T2 e)
  where
    sizeof  e2 n  = psizeof  e2 (2  *   n)
    sizeof# e2 n# = psizeof# e2 (2# *# n#)

    bytes# !#  n# = let o# = 2# *# n# in (bytes# !# o#, bytes# !# (o#+#1#))
    bytes# !># n# = let o# = 2# *# n# in \ s1# -> case (!>#) bytes# o# s1# of
      (# s2#, e1 #) -> case (!>#) bytes# (o# +# 1#) s2# of
        (# s3#, e2 #) -> (# s3#, (e1,e2) #)

    writeByteArray# mbytes# n# (e1,e2) = let o# = 2# *# n# in
      \ s1# -> case writeByteArray# mbytes# o# e1 s1# of
        s2# -> writeByteArray# mbytes# (o# +# 1#) e2 s2#

    newUnboxed e n# = pnewUnboxed e (2# *# n#)

instance (Unboxed e) => Unboxed (T3 e)
  where
    sizeof  e2 n  = psizeof  e2 (3  *   n)
    sizeof# e2 n# = psizeof# e2 (3# *# n#)

    bytes# !# n# =
      let o# = 3# *# n#
      in  (bytes# !# o#, bytes# !# (o#+#1#), bytes# !# (o#+#2#))

    bytes# !># n# = let o# = 3# *# n# in \ s1# -> case (!>#) bytes# o# s1# of
      (# s2#, e1 #) -> case (!>#) bytes# (o# +# 1#) s2# of
        (# s3#, e2 #) -> case (!>#) bytes# (o# +# 2#) s3# of
          (# s4#, e3 #) -> (# s4#, (e1,e2,e3) #)

    writeByteArray# mbytes# n# (e1,e2,e3) = let o# = 3# *# n# in
      \ s1# -> case writeByteArray# mbytes# o# e1 s1# of
        s2# -> case writeByteArray# mbytes# (o# +# 1#) e2 s2# of
          s3# -> writeByteArray# mbytes# (o# +# 2#) e3 s3#

    newUnboxed e n# = pnewUnboxed e (3# *# n#)

instance (Unboxed e) => Unboxed (T4 e)
  where
    sizeof  e2 n  = psizeof  e2 (4  *   n)
    sizeof# e2 n# = psizeof# e2 (4# *# n#)

    bytes# !# n# =
      let o# = 4# *# n#
      in  (bytes# !# o#, bytes# !# (o#+#1#), bytes# !# (o#+#2#), bytes# !# (o#+#3#))

    bytes# !># n# = let o# = 4# *# n# in \ s1# -> case (!>#) bytes# o# s1# of
      (# s2#, e1 #) -> case (!>#) bytes# (o# +# 1#) s2# of
        (# s3#, e2 #) -> case (!>#) bytes# (o# +# 2#) s3# of
          (# s4#, e3 #) -> case (!>#) bytes# (o# +# 3#) s4# of
            (# s5#, e4 #) -> (# s5#, (e1,e2,e3,e4) #)

    writeByteArray# mbytes# n# (e1,e2,e3,e4) = let o# = 4# *# n# in
      \ s1# -> case writeByteArray# mbytes# o# e1 s1# of
        s2# -> case writeByteArray# mbytes# (o# +# 1#) e2 s2# of
          s3# -> case writeByteArray# mbytes# (o# +# 2#) e3 s3# of
            s4# -> writeByteArray# mbytes# (o# +# 3#) e4 s4#

    newUnboxed e n# = pnewUnboxed e (4# *# n#)

instance (Unboxed e) => Unboxed (T5 e)
  where
    sizeof  e2 n  = psizeof  e2 (5  *   n)
    sizeof# e2 n# = psizeof# e2 (5# *# n#)

    bytes# !# n# =
      let o# = 5# *# n#
      in
        (
          bytes# !#       o#, bytes# !# (o#+#1#), bytes# !# (o#+#2#),
          bytes# !# (o#+#3#), bytes# !# (o#+#4#)
        )

    bytes# !># n# = let o# = 5# *# n# in \ s1# -> case (!>#) bytes# o# s1# of
      (# s2#, e1 #) -> case (!>#) bytes# (o# +# 1#) s2# of
        (# s3#, e2 #) -> case (!>#) bytes# (o# +# 2#) s3# of
          (# s4#, e3 #) -> case (!>#) bytes# (o# +# 3#) s4# of
            (# s5#, e4 #) -> case (!>#) bytes# (o# +# 4#) s5# of
              (# s6#, e5 #) -> (# s6#, (e1,e2,e3,e4,e5) #)

    writeByteArray# mbytes# n# (e1,e2,e3,e4,e5) = let o# = 5# *# n# in
      \ s1# -> case writeByteArray# mbytes# o# e1 s1# of
        s2# -> case writeByteArray# mbytes# (o# +# 1#) e2 s2# of
          s3# -> case writeByteArray# mbytes# (o# +# 2#) e3 s3# of
            s4# -> case writeByteArray# mbytes# (o# +# 3#) e4 s4# of
              s5# -> writeByteArray# mbytes# (o# +# 4#) e5 s5#

    newUnboxed e n# = pnewUnboxed e (5# *# n#)

instance (Unboxed e) => Unboxed (T6 e)
  where
    sizeof  e2 n  = psizeof  e2 (6  *   n)
    sizeof# e2 n# = psizeof# e2 (6# *# n#)

    bytes# !# n# =
      let o# = 6# *# n#
      in
        (
          bytes# !#       o#, bytes# !# (o#+#1#), bytes# !# (o#+#2#),
          bytes# !# (o#+#3#), bytes# !# (o#+#4#), bytes# !# (o#+#5#)
        )

    bytes# !># n# = let o# = 6# *# n# in \ s1# -> case (!>#) bytes# o# s1# of
      (# s2#, e1 #) -> case (!>#) bytes# (o# +# 1#) s2# of
        (# s3#, e2 #) -> case (!>#) bytes# (o# +# 2#) s3# of
          (# s4#, e3 #) -> case (!>#) bytes# (o# +# 3#) s4# of
            (# s5#, e4 #) -> case (!>#) bytes# (o# +# 4#) s5# of
              (# s6#, e5 #) -> case (!>#) bytes# (o# +# 5#) s6# of
                (# s7#, e6 #) -> (# s7#, (e1,e2,e3,e4,e5,e6) #)

    writeByteArray# mbytes# n# (e1,e2,e3,e4,e5,e6) = let o# = 6# *# n# in
      \ s1# -> case writeByteArray# mbytes# o# e1 s1# of
        s2# -> case writeByteArray# mbytes# (o# +# 1#) e2 s2# of
          s3# -> case writeByteArray# mbytes# (o# +# 2#) e3 s3# of
            s4# -> case writeByteArray# mbytes# (o# +# 3#) e4 s4# of
              s5# -> case writeByteArray# mbytes# (o# +# 4#) e5 s5# of
                s6# -> writeByteArray# mbytes# (o# +# 5#) e6 s6#

    newUnboxed e n# = pnewUnboxed e (6# *# n#)

instance (Unboxed e) => Unboxed (T7 e)
  where
    sizeof  e2 n  = psizeof  e2 (7  *   n)
    sizeof# e2 n# = psizeof# e2 (7# *# n#)

    bytes# !# n# =
      let o# = 7# *# n#
      in
        (
          bytes# !#       o#, bytes# !# (o#+#1#), bytes# !# (o#+#2#),
          bytes# !# (o#+#3#), bytes# !# (o#+#4#), bytes# !# (o#+#5#),
          bytes# !# (o#+#6#)
        )

    bytes# !># n# = let o# = 7# *# n# in \ s1# -> case (!>#) bytes# o# s1# of
      (# s2#, e1 #) -> case (!>#) bytes# (o# +# 1#) s2# of
        (# s3#, e2 #) -> case (!>#) bytes# (o# +# 2#) s3# of
          (# s4#, e3 #) -> case (!>#) bytes# (o# +# 3#) s4# of
            (# s5#, e4 #) -> case (!>#) bytes# (o# +# 4#) s5# of
              (# s6#, e5 #) -> case (!>#) bytes# (o# +# 5#) s6# of
                (# s7#, e6 #) -> case (!>#) bytes# (o# +# 6#) s7# of
                  (# s8#, e7 #) -> (# s8#, (e1,e2,e3,e4,e5,e6,e7) #)

    writeByteArray# mbytes# n# (e1,e2,e3,e4,e5,e6,e7) = let o# = 7# *# n# in
      \ s1# -> case writeByteArray# mbytes# o# e1 s1# of
        s2# -> case writeByteArray# mbytes# (o# +# 1#) e2 s2# of
          s3# -> case writeByteArray# mbytes# (o# +# 2#) e3 s3# of
            s4# -> case writeByteArray# mbytes# (o# +# 3#) e4 s4# of
              s5# -> case writeByteArray# mbytes# (o# +# 4#) e5 s5# of
                s6# -> case writeByteArray# mbytes# (o# +# 5#) e6 s6# of
                  s7# -> writeByteArray# mbytes# (o# +# 6#) e7 s7#

    newUnboxed e n# = pnewUnboxed e (7# *# n#)

instance (Unboxed e) => Unboxed (T8 e)
  where
    sizeof  e2 n  = psizeof  e2 (8  *   n)
    sizeof# e2 n# = psizeof# e2 (8# *# n#)

    bytes# !# n# =
      let o# = 8# *# n#
      in
        (
          bytes# !#       o#, bytes# !# (o#+#1#), bytes# !# (o#+#2#),
          bytes# !# (o#+#3#), bytes# !# (o#+#4#), bytes# !# (o#+#5#),
          bytes# !# (o#+#6#), bytes# !# (o#+#7#)
        )

    bytes# !># n# = let o# = 8# *# n# in \ s1# -> case (!>#) bytes# o# s1# of
      (# s2#, e1 #) -> case (!>#) bytes# (o# +# 1#) s2# of
        (# s3#, e2 #) -> case (!>#) bytes# (o# +# 2#) s3# of
          (# s4#, e3 #) -> case (!>#) bytes# (o# +# 3#) s4# of
            (# s5#, e4 #) -> case (!>#) bytes# (o# +# 4#) s5# of
              (# s6#, e5 #) -> case (!>#) bytes# (o# +# 5#) s6# of
                (# s7#, e6 #) -> case (!>#) bytes# (o# +# 6#) s7# of
                  (# s8#, e7 #) -> case (!>#) bytes# (o# +# 7#) s8# of
                    (# s9#, e8 #) -> (# s9#, (e1,e2,e3,e4,e5,e6,e7,e8) #)

    writeByteArray# mbytes# n# (e1,e2,e3,e4,e5,e6,e7,e8) = let o# = 8# *# n# in
      \ s1# -> case writeByteArray# mbytes# o# e1 s1# of
        s2# -> case writeByteArray# mbytes# (o# +# 1#) e2 s2# of
          s3# -> case writeByteArray# mbytes# (o# +# 2#) e3 s3# of
            s4# -> case writeByteArray# mbytes# (o# +# 3#) e4 s4# of
              s5# -> case writeByteArray# mbytes# (o# +# 4#) e5 s5# of
                s6# -> case writeByteArray# mbytes# (o# +# 5#) e6 s6# of
                  s7# -> case writeByteArray# mbytes# (o# +# 6#) e7 s7# of
                    s8# -> writeByteArray# mbytes# (o# +# 7#) e8 s8#

    newUnboxed e n# = pnewUnboxed e (8# *# n#)

instance (Unboxed e) => Unboxed (T9 e)
  where
    sizeof  e2 n  = psizeof  e2 (9  *   n)
    sizeof# e2 n# = psizeof# e2 (9# *# n#)

    bytes# !# n# =
      let o# = 9# *# n#
      in
        (
          bytes# !#       o#, bytes# !# (o#+#1#), bytes# !# (o#+#2#),
          bytes# !# (o#+#3#), bytes# !# (o#+#4#), bytes# !# (o#+#5#),
          bytes# !# (o#+#6#), bytes# !# (o#+#7#), bytes# !# (o#+#8#)
        )

    bytes# !># n# = let o# = 9# *# n# in \ s1# -> case (!>#) bytes# o# s1# of
      (# s2#, e1 #) -> case (!>#) bytes# (o# +# 1#) s2# of
        (# s3#, e2 #) -> case (!>#) bytes# (o# +# 2#) s3# of
          (# s4#, e3 #) -> case (!>#) bytes# (o# +# 3#) s4# of
            (# s5#, e4 #) -> case (!>#) bytes# (o# +# 4#) s5# of
              (# s6#, e5 #) -> case (!>#) bytes# (o# +# 5#) s6# of
                (# s7#, e6 #) -> case (!>#) bytes# (o# +# 6#) s7# of
                  (# s8#, e7 #) -> case (!>#) bytes# (o# +# 7#) s8# of
                    (# s9#, e8 #) -> case (!>#) bytes# (o# +# 8#) s9# of
                      (# s10#, e9 #) -> (# s10#, (e1,e2,e3,e4,e5,e6,e7,e8,e9) #)

    writeByteArray# mbytes# n# (e1,e2,e3,e4,e5,e6,e7,e8,e9) = let o# = 9# *# n# in
      \ s1# -> case writeByteArray# mbytes# o# e1 s1# of
        s2# -> case writeByteArray# mbytes# (o# +# 1#) e2 s2# of
          s3# -> case writeByteArray# mbytes# (o# +# 2#) e3 s3# of
            s4# -> case writeByteArray# mbytes# (o# +# 3#) e4 s4# of
              s5# -> case writeByteArray# mbytes# (o# +# 4#) e5 s5# of
                s6# -> case writeByteArray# mbytes# (o# +# 5#) e6 s6# of
                  s7# -> case writeByteArray# mbytes# (o# +# 6#) e7 s7# of
                    s8# -> case writeByteArray# mbytes# (o# +# 7#) e8 s8# of
                      s9# -> writeByteArray# mbytes# (o# +# 8#) e9 s9#

    newUnboxed e n# = pnewUnboxed e (9# *# n#)

instance (Unboxed e) => Unboxed (T10 e)
  where
    sizeof  e2 n  = psizeof  e2 (10  *   n)
    sizeof# e2 n# = psizeof# e2 (10# *# n#)

    bytes# !# n# =
      let o# = 10# *# n#
      in
        (
          bytes# !#       o#, bytes# !# (o#+#1#), bytes# !# (o#+#2#),
          bytes# !# (o#+#3#), bytes# !# (o#+#4#), bytes# !# (o#+#5#),
          bytes# !# (o#+#6#), bytes# !# (o#+#7#), bytes# !# (o#+#8#),
          bytes# !# (o#+#9#)
        )

    bytes# !># n# = let o# = 10# *# n# in \ s1# -> case (!>#) bytes# o# s1# of
      (# s2#, e1 #) -> case (!>#) bytes# (o# +# 1#) s2# of
        (# s3#, e2 #) -> case (!>#) bytes# (o# +# 2#) s3# of
          (# s4#, e3 #) -> case (!>#) bytes# (o# +# 3#) s4# of
            (# s5#, e4 #) -> case (!>#) bytes# (o# +# 4#) s5# of
              (# s6#, e5 #) -> case (!>#) bytes# (o# +# 5#) s6# of
                (# s7#, e6 #) -> case (!>#) bytes# (o# +# 6#) s7# of
                  (# s8#, e7 #) -> case (!>#) bytes# (o# +# 7#) s8# of
                    (# s9#, e8 #) -> case (!>#) bytes# (o# +# 8#) s9# of
                      (# s10#, e9 #) -> case (!>#) bytes# (o# +# 9#) s10# of
                        (# s11#, e10 #) -> (# s11#, (e1,e2,e3,e4,e5,e6,e7,e8,e9,e10) #)

    writeByteArray# mbytes# n# (e1,e2,e3,e4,e5,e6,e7,e8,e9,e10) = let o# = 10# *# n# in
      \ s1# -> case writeByteArray# mbytes# o# e1 s1# of
        s2# -> case writeByteArray# mbytes# (o# +# 1#) e2 s2# of
          s3# -> case writeByteArray# mbytes# (o# +# 2#) e3 s3# of
            s4# -> case writeByteArray# mbytes# (o# +# 3#) e4 s4# of
              s5# -> case writeByteArray# mbytes# (o# +# 4#) e5 s5# of
                s6# -> case writeByteArray# mbytes# (o# +# 5#) e6 s6# of
                  s7# -> case writeByteArray# mbytes# (o# +# 6#) e7 s7# of
                    s8# -> case writeByteArray# mbytes# (o# +# 7#) e8 s8# of
                      s9# -> case writeByteArray# mbytes# (o# +# 8#) e9 s9# of
                        s10# -> writeByteArray# mbytes# (o# +# 9#) e10 s10#

    newUnboxed e n# = pnewUnboxed e (10# *# n#)

instance (Unboxed e) => Unboxed (T11 e)
  where
    sizeof  e2 n  = psizeof  e2 (11  *   n)
    sizeof# e2 n# = psizeof# e2 (11# *# n#)

    bytes# !# n# =
      let o# = 11# *# n#
      in
        (
          bytes# !#       o#, bytes# !# (o#+#1#), bytes# !# (o#+#2#),
          bytes# !# (o#+#3#), bytes# !# (o#+#4#), bytes# !# (o#+#5#),
          bytes# !# (o#+#6#), bytes# !# (o#+#7#), bytes# !# (o#+#8#),
          bytes# !# (o#+#9#), bytes# !# (o#+#10#)
        )

    bytes# !># n# = let o# = 11# *# n# in \ s1# -> case (!>#) bytes# o# s1# of
      (# s2#, e1 #) -> case (!>#) bytes# (o# +# 1#) s2# of
        (# s3#, e2 #) -> case (!>#) bytes# (o# +# 2#) s3# of
          (# s4#, e3 #) -> case (!>#) bytes# (o# +# 3#) s4# of
            (# s5#, e4 #) -> case (!>#) bytes# (o# +# 4#) s5# of
              (# s6#, e5 #) -> case (!>#) bytes# (o# +# 5#) s6# of
                (# s7#, e6 #) -> case (!>#) bytes# (o# +# 6#) s7# of
                  (# s8#, e7 #) -> case (!>#) bytes# (o# +# 7#) s8# of
                    (# s9#, e8 #) -> case (!>#) bytes# (o# +# 8#) s9# of
                      (# s10#, e9 #) -> case (!>#) bytes# (o# +# 9#) s10# of
                        (# s11#, e10 #) -> case (!>#) bytes# (o# +# 10#) s11# of
                          (# s12#, e11 #) -> (# s12#, (e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11) #)

    writeByteArray# mbytes# n# (e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11) = let o# = 11# *# n# in
      \ s1# -> case writeByteArray# mbytes# o# e1 s1# of
        s2# -> case writeByteArray# mbytes# (o# +# 1#) e2 s2# of
          s3# -> case writeByteArray# mbytes# (o# +# 2#) e3 s3# of
            s4# -> case writeByteArray# mbytes# (o# +# 3#) e4 s4# of
              s5# -> case writeByteArray# mbytes# (o# +# 4#) e5 s5# of
                s6# -> case writeByteArray# mbytes# (o# +# 5#) e6 s6# of
                  s7# -> case writeByteArray# mbytes# (o# +# 6#) e7 s7# of
                    s8# -> case writeByteArray# mbytes# (o# +# 7#) e8 s8# of
                      s9# -> case writeByteArray# mbytes# (o# +# 8#) e9 s9# of
                        s10# -> case writeByteArray# mbytes# (o# +# 9#) e10 s10# of
                          s11# -> writeByteArray# mbytes# (o# +# 10#) e11 s11#

    newUnboxed e n# = pnewUnboxed e (11# *# n#)

instance (Unboxed e) => Unboxed (T12 e)
  where
    sizeof  e2 n  = psizeof  e2 (12  *   n)
    sizeof# e2 n# = psizeof# e2 (12# *# n#)

    bytes# !# n# =
      let o# = 12# *# n#
      in
        (
          bytes# !#       o#, bytes# !#  (o#+#1#), bytes# !#  (o#+#2#),
          bytes# !# (o#+#3#), bytes# !#  (o#+#4#), bytes# !#  (o#+#5#),
          bytes# !# (o#+#6#), bytes# !#  (o#+#7#), bytes# !#  (o#+#8#),
          bytes# !# (o#+#9#), bytes# !# (o#+#10#), bytes# !# (o#+#11#)
        )

    bytes# !># n# = let o# = 12# *# n# in \ s1# -> case (!>#) bytes# o# s1# of
      (# s2#, e1 #) -> case (!>#) bytes# (o# +# 1#) s2# of
        (# s3#, e2 #) -> case (!>#) bytes# (o# +# 2#) s3# of
          (# s4#, e3 #) -> case (!>#) bytes# (o# +# 3#) s4# of
            (# s5#, e4 #) -> case (!>#) bytes# (o# +# 4#) s5# of
              (# s6#, e5 #) -> case (!>#) bytes# (o# +# 5#) s6# of
                (# s7#, e6 #) -> case (!>#) bytes# (o# +# 6#) s7# of
                  (# s8#, e7 #) -> case (!>#) bytes# (o# +# 7#) s8# of
                    (# s9#, e8 #) -> case (!>#) bytes# (o# +# 8#) s9# of
                      (# s10#, e9 #) -> case (!>#) bytes# (o# +# 9#) s10# of
                        (# s11#, e10 #) -> case (!>#) bytes# (o# +# 10#) s11# of
                          (# s12#, e11 #) -> case (!>#) bytes# (o# +# 11#) s12# of
                            (# s13#, e12 #) -> (# s13#, (e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12) #)

    writeByteArray# mbytes# n# (e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12) = let o# = 12# *# n# in
      \ s1# -> case writeByteArray# mbytes# o# e1 s1# of
        s2# -> case writeByteArray# mbytes# (o# +# 1#) e2 s2# of
          s3# -> case writeByteArray# mbytes# (o# +# 2#) e3 s3# of
            s4# -> case writeByteArray# mbytes# (o# +# 3#) e4 s4# of
              s5# -> case writeByteArray# mbytes# (o# +# 4#) e5 s5# of
                s6# -> case writeByteArray# mbytes# (o# +# 5#) e6 s6# of
                  s7# -> case writeByteArray# mbytes# (o# +# 6#) e7 s7# of
                    s8# -> case writeByteArray# mbytes# (o# +# 7#) e8 s8# of
                      s9# -> case writeByteArray# mbytes# (o# +# 8#) e9 s9# of
                        s10# -> case writeByteArray# mbytes# (o# +# 9#) e10 s10# of
                          s11# -> case writeByteArray# mbytes# (o# +# 10#) e11 s11# of
                            s12# -> writeByteArray# mbytes# (o# +# 11#) e12 s12#

    newUnboxed e n# = pnewUnboxed e (12# *# n#)

instance (Unboxed e) => Unboxed (T13 e)
  where
    sizeof  e2 n  = psizeof  e2 (13  *   n)
    sizeof# e2 n# = psizeof# e2 (13# *# n#)

    bytes# !# n# =
      let o# = 13# *# n#
      in
        (
          bytes# !#        o#, bytes# !#  (o#+#1#), bytes# !#  (o#+#2#),
          bytes# !#  (o#+#3#), bytes# !#  (o#+#4#), bytes# !#  (o#+#5#),
          bytes# !#  (o#+#6#), bytes# !#  (o#+#7#), bytes# !#  (o#+#8#),
          bytes# !#  (o#+#9#), bytes# !# (o#+#10#), bytes# !# (o#+#11#),
          bytes# !# (o#+#12#)
        )

    bytes# !># n# = let o# = 13# *# n# in \ s1# -> case (!>#) bytes# o# s1# of
      (# s2#, e1 #) -> case (!>#) bytes# (o# +# 1#) s2# of
        (# s3#, e2 #) -> case (!>#) bytes# (o# +# 2#) s3# of
          (# s4#, e3 #) -> case (!>#) bytes# (o# +# 3#) s4# of
            (# s5#, e4 #) -> case (!>#) bytes# (o# +# 4#) s5# of
              (# s6#, e5 #) -> case (!>#) bytes# (o# +# 5#) s6# of
                (# s7#, e6 #) -> case (!>#) bytes# (o# +# 6#) s7# of
                  (# s8#, e7 #) -> case (!>#) bytes# (o# +# 7#) s8# of
                    (# s9#, e8 #) -> case (!>#) bytes# (o# +# 8#) s9# of
                      (# s10#, e9 #) -> case (!>#) bytes# (o# +# 9#) s10# of
                        (# s11#, e10 #) -> case (!>#) bytes# (o# +# 10#) s11# of
                          (# s12#, e11 #) -> case (!>#) bytes# (o# +# 11#) s12# of
                            (# s13#, e12 #) -> case (!>#) bytes# (o# +# 12#) s13# of
                              (# s14#, e13 #) -> (# s14#, (e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13) #)

    writeByteArray# mbytes# n# (e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13) = let o# = 13# *# n# in
      \ s1# -> case writeByteArray# mbytes# o# e1 s1# of
        s2# -> case writeByteArray# mbytes# (o# +# 1#) e2 s2# of
          s3# -> case writeByteArray# mbytes# (o# +# 2#) e3 s3# of
            s4# -> case writeByteArray# mbytes# (o# +# 3#) e4 s4# of
              s5# -> case writeByteArray# mbytes# (o# +# 4#) e5 s5# of
                s6# -> case writeByteArray# mbytes# (o# +# 5#) e6 s6# of
                  s7# -> case writeByteArray# mbytes# (o# +# 6#) e7 s7# of
                    s8# -> case writeByteArray# mbytes# (o# +# 7#) e8 s8# of
                      s9# -> case writeByteArray# mbytes# (o# +# 8#) e9 s9# of
                        s10# -> case writeByteArray# mbytes# (o# +# 9#) e10 s10# of
                          s11# -> case writeByteArray# mbytes# (o# +# 10#) e11 s11# of
                            s12# -> case writeByteArray# mbytes# (o# +# 11#) e12 s12# of
                              s13# -> writeByteArray# mbytes# (o# +# 12#) e13 s13#

    newUnboxed e n# = pnewUnboxed e (13# *# n#)

instance (Unboxed e) => Unboxed (T14 e)
  where
    sizeof  e2 n  = psizeof  e2 (14  *   n)
    sizeof# e2 n# = psizeof# e2 (14# *# n#)

    bytes# !# n# =
      let o# = 14# *# n#
      in
        (
          bytes# !#        o#, bytes# !#  (o#+#1#), bytes# !#  (o#+#2#),
          bytes# !#  (o#+#3#), bytes# !#  (o#+#4#), bytes# !#  (o#+#5#),
          bytes# !#  (o#+#6#), bytes# !#  (o#+#7#), bytes# !#  (o#+#8#),
          bytes# !#  (o#+#9#), bytes# !# (o#+#10#), bytes# !# (o#+#11#),
          bytes# !# (o#+#12#), bytes# !# (o#+#13#)
        )

    bytes# !># n# = let o# = 14# *# n# in \ s1# -> case (!>#) bytes# o# s1# of
      (# s2#, e1 #) -> case (!>#) bytes# (o# +# 1#) s2# of
        (# s3#, e2 #) -> case (!>#) bytes# (o# +# 2#) s3# of
          (# s4#, e3 #) -> case (!>#) bytes# (o# +# 3#) s4# of
            (# s5#, e4 #) -> case (!>#) bytes# (o# +# 4#) s5# of
              (# s6#, e5 #) -> case (!>#) bytes# (o# +# 5#) s6# of
                (# s7#, e6 #) -> case (!>#) bytes# (o# +# 6#) s7# of
                  (# s8#, e7 #) -> case (!>#) bytes# (o# +# 7#) s8# of
                    (# s9#, e8 #) -> case (!>#) bytes# (o# +# 8#) s9# of
                      (# s10#, e9 #) -> case (!>#) bytes# (o# +# 9#) s10# of
                        (# s11#, e10 #) -> case (!>#) bytes# (o# +# 10#) s11# of
                          (# s12#, e11 #) -> case (!>#) bytes# (o# +# 11#) s12# of
                            (# s13#, e12 #) -> case (!>#) bytes# (o# +# 12#) s13# of
                              (# s14#, e13 #) -> case (!>#) bytes# (o# +# 13#) s14# of
                                (# s15#, e14 #) -> (# s15#, (e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14) #)

    writeByteArray# mbytes# n# (e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14) =
      \ s1# -> let o# = 14# *# n# in case writeByteArray# mbytes# o# e1 s1# of
        s2# -> case writeByteArray# mbytes# (o# +# 1#) e2 s2# of
          s3# -> case writeByteArray# mbytes# (o# +# 2#) e3 s3# of
            s4# -> case writeByteArray# mbytes# (o# +# 3#) e4 s4# of
              s5# -> case writeByteArray# mbytes# (o# +# 4#) e5 s5# of
                s6# -> case writeByteArray# mbytes# (o# +# 5#) e6 s6# of
                  s7# -> case writeByteArray# mbytes# (o# +# 6#) e7 s7# of
                    s8# -> case writeByteArray# mbytes# (o# +# 7#) e8 s8# of
                      s9# -> case writeByteArray# mbytes# (o# +# 8#) e9 s9# of
                        s10# -> case writeByteArray# mbytes# (o# +# 9#) e10 s10# of
                          s11# -> case writeByteArray# mbytes# (o# +# 10#) e11 s11# of
                            s12# -> case writeByteArray# mbytes# (o# +# 11#) e12 s12# of
                              s13# -> case writeByteArray# mbytes# (o# +# 12#) e13 s13# of
                                s14# -> writeByteArray# mbytes# (o# +# 13#) e14 s14#

    newUnboxed e n# = pnewUnboxed e (14# *# n#)

instance (Unboxed e) => Unboxed (T15 e)
  where
    sizeof  e2 n  = psizeof  e2 (15  *   n)
    sizeof# e2 n# = psizeof# e2 (15# *# n#)

    bytes# !# n# =
      let o# = 15# *# n#
      in
        (
          bytes# !#        o#, bytes# !#  (o#+#1#), bytes# !#  (o#+#2#),
          bytes# !#  (o#+#3#), bytes# !#  (o#+#4#), bytes# !#  (o#+#5#),
          bytes# !#  (o#+#6#), bytes# !#  (o#+#7#), bytes# !#  (o#+#8#),
          bytes# !#  (o#+#9#), bytes# !# (o#+#10#), bytes# !# (o#+#11#),
          bytes# !# (o#+#12#), bytes# !# (o#+#13#), bytes# !# (o#+#14#)
        )

    bytes# !># n# = let o# = 15# *# n# in \ s1# -> case (!>#) bytes# o# s1# of
      (# s2#, e1 #) -> case (!>#) bytes# (o# +# 1#) s2# of
        (# s3#, e2 #) -> case (!>#) bytes# (o# +# 2#) s3# of
          (# s4#, e3 #) -> case (!>#) bytes# (o# +# 3#) s4# of
            (# s5#, e4 #) -> case (!>#) bytes# (o# +# 4#) s5# of
              (# s6#, e5 #) -> case (!>#) bytes# (o# +# 5#) s6# of
                (# s7#, e6 #) -> case (!>#) bytes# (o# +# 6#) s7# of
                  (# s8#, e7 #) -> case (!>#) bytes# (o# +# 7#) s8# of
                    (# s9#, e8 #) -> case (!>#) bytes# (o# +# 8#) s9# of
                      (# s10#, e9 #) -> case (!>#) bytes# (o# +# 9#) s10# of
                        (# s11#, e10 #) -> case (!>#) bytes# (o# +# 10#) s11# of
                          (# s12#, e11 #) -> case (!>#) bytes# (o# +# 11#) s12# of
                            (# s13#, e12 #) -> case (!>#) bytes# (o# +# 12#) s13# of
                              (# s14#, e13 #) -> case (!>#) bytes# (o# +# 13#) s14# of
                                (# s15#, e14 #) -> case (!>#) bytes# (o# +# 14#) s15# of
                                  (# s16#, e15 #) -> (# s16#, (e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15) #)

    writeByteArray# mbytes# n# (e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15) =
      \ s1# -> let o# = 15# *# n# in case writeByteArray# mbytes# o# e1 s1# of
        s2# -> case writeByteArray# mbytes# (o# +# 1#) e2 s2# of
          s3# -> case writeByteArray# mbytes# (o# +# 2#) e3 s3# of
            s4# -> case writeByteArray# mbytes# (o# +# 3#) e4 s4# of
              s5# -> case writeByteArray# mbytes# (o# +# 4#) e5 s5# of
                s6# -> case writeByteArray# mbytes# (o# +# 5#) e6 s6# of
                  s7# -> case writeByteArray# mbytes# (o# +# 6#) e7 s7# of
                    s8# -> case writeByteArray# mbytes# (o# +# 7#) e8 s8# of
                      s9# -> case writeByteArray# mbytes# (o# +# 8#) e9 s9# of
                        s10# -> case writeByteArray# mbytes# (o# +# 9#) e10 s10# of
                          s11# -> case writeByteArray# mbytes# (o# +# 10#) e11 s11# of
                            s12# -> case writeByteArray# mbytes# (o# +# 11#) e12 s12# of
                              s13# -> case writeByteArray# mbytes# (o# +# 12#) e13 s13# of
                                s14# -> case writeByteArray# mbytes# (o# +# 13#) e14 s14# of
                                  s15# -> writeByteArray# mbytes# (o# +# 14#) e15 s15#

    newUnboxed e n# = pnewUnboxed e (15# *# n#)

--------------------------------------------------------------------------------

-- | 'ByteArray#' wrapper.
data Wrap = Wrap {unwrap :: ByteArray#}

{- |
  @since 0.2.1
  Wrapped empty 'ByteArray#'.
-}
lzero# :: Wrap
lzero# =  runST $ ST $ \ s1# -> case newByteArray# 0# s1# of
  (# s2#, marr# #) -> case unsafeFreezeByteArray# marr# s2# of
    (# s3#, arr# #) -> (# s3#, Wrap arr# #)

{- |
  @since 0.2.1
  'ByteArray#' singleton.
-}
single# :: (Unboxed e) => e -> ByteArray#
single# e = unwrap $ runST $ ST $ \ s1# -> case newUnboxed' e 1# s1# of
  (# s2#, marr# #) -> case unsafeFreezeByteArray# marr# s2# of
    (# s3#, arr# #) -> (# s3#, Wrap arr# #)

{- |
  @since 0.2.1
  Create immutable 'Unboxed' array from given list.
-}
fromList# :: (Unboxed e) => [e] -> ByteArray#
fromList# es = let !(I# n#) = length es in fromListN# n# es

{- |
  @since 0.2.1
  Create immutable 'Unboxed' array from 'Foldable' stream.
-}
fromFoldable# :: (Foldable f, Unboxed e) => f e -> (# Int, ByteArray# #)
fromFoldable# es = unpack' $ runST $ ST $ \ s1# -> case fromFoldableM# es s1# of
    (# s2#, n, marr# #) -> case unsafeFreezeByteArray# marr# s2# of
      (# s3#, arr# #) -> (# s3#, (n, Wrap arr#) #)
  where
    unpack' (i, Wrap arr#) = (# i, arr# #)

{- |
  @since 0.2.1
  Create immutable 'Unboxed' array from known size list.
-}
fromListN# :: (Unboxed e) => Int# -> [e] -> ByteArray#
fromListN# n# es = unwrap $ runST $ ST $ \ s1# -> case newLinearN# n# es s1# of
  (# s2#, marr# #) -> case unsafeFreezeByteArray# marr# s2# of
    (# s3#, arr# #) -> (# s3#, Wrap arr# #)

{- |
  @since 0.2.1
  Create mutable 'Unboxed' array from given list.
-}
newLinear# :: (Unboxed e) => [e] -> State# s ->
  (# State# s, MutableByteArray# s #)
newLinear# es = let !(I# n#) = length es in newLinearN# n# es

{- |
  @since 0.2.1
  Create mutable 'Unboxed' array from known size list.
-}
newLinearN# :: (Unboxed e) => Int# -> [e] -> State# s ->
  (# State# s, MutableByteArray# s #)
newLinearN# c# es = \ s1# -> case pnewUnboxed es n# s1# of
    (# s2#, marr# #) ->
      let
        go y r = \ i# s4# -> case writeByteArray# marr# i# y s4# of
          s5# -> if isTrue# (i# ==# n# -# 1#) then s5# else r (i# +# 1#) s5#
      in case if n == 0 then s2# else foldr go (\ _ s# -> s#) es 0# s2# of
          s3# -> (# s3#, marr# #)
  where
    !n@(I# n#) = max 0 (I# c#)

{- |
  @since 0.2.1
  Create mutable 'Unboxed' array from 'Foldable' stream.
-}
fromFoldableM# :: (Foldable f, Unboxed e) => f e -> State# s ->
  (# State# s, Int, MutableByteArray# s #)
fromFoldableM# es = \ s1# -> case pnewUnboxed es n# s1# of
    (# s2#, marr# #) ->
      let
        go y r = \ i# s4# -> case writeByteArray# marr# i# y s4# of
          s5# -> if isTrue# (i# ==# n# -# 1#) then s5# else r (i# +# 1#) s5#
      in case if n == 0 then s2# else foldr go (\ _ s# -> s#) es 0# s2# of
          s3# -> (# s3#, n, marr# #)
  where
    !n@(I# n#) = length es

{- |
  @since 0.2.1
  Concatenation of two 'Unboxed' arrays.
-}
concat# :: (Unboxed e) => e ->
  ByteArray# -> Int# -> Int# ->
  ByteArray# -> Int# -> Int# -> State# s ->
  (# State# s, Int#, MutableByteArray# s #)
concat# e arr1# n1# o1# arr2# n2# o2# = \ s1# -> case newUnboxed e n# s1# of
    (# s2#, marr# #) -> case copyUnboxed# e arr1# o1# marr# 0# n1# s2# of
      s3# -> case copyUnboxed# e arr2# o2# marr# n1# n2# s3# of
        s4# -> (# s4#, n#, marr# #)
  where
    n# = n1# +# n2#

-- | Proxy concatenation of two byte arrays representing 'Unboxed' structures.
pconcat :: (Unboxed e) => proxy e ->
  ByteArray# -> Int# -> Int# -> ByteArray# -> Int# -> Int# ->
  State# s -> (# State# s, Int#, MutableByteArray# s #)
pconcat = concat# . fromProxy

--------------------------------------------------------------------------------

rank# :: (Shape i) => i -> Int#
rank# i = case rank i of I# r# -> r#

{-# INLINE bool_scale #-}
bool_scale :: Int# -> Int#
bool_scale n# = (n# +# 7#) `uncheckedIShiftRA#` 3#

{-# INLINE bool_bit #-}
bool_bit :: Int# -> Word#
bool_bit n# = case (SIZEOF_HSWORD * 8 - 1) of
  W# mask# -> int2Word# 1# `uncheckedShiftL#` word2Int# (int2Word# n# `and#` mask#)

{-# INLINE bool_not_bit #-}
bool_not_bit :: Int# -> Word#
bool_not_bit n# = case maxBound of W# mb# -> bool_bit n# `xor#` mb#

{-# INLINE bool_index #-}
bool_index :: Int# -> Int#
#if   SIZEOF_HSWORD == 4
bool_index =  (`uncheckedIShiftRA#` 5#)
#elif SIZEOF_HSWORD == 8
bool_index =  (`uncheckedIShiftRA#` 6#)
#endif

consSizeof :: (a -> b) -> b -> a
consSizeof =  \ _ _ -> undefined

max_stars_repo_name: jhhuh/sdp

max_issues_repo_name: jhhuh/sdp

max_forks_repo_name: jhhuh/sdp