{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RoleAnnotations #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE UndecidableInstances #-}
module Proto3.Wire.Reverse.Prim
(
AssocPlusNat(..)
, CommPlusNat(..)
, PChoose(..)
, Max
, AssocMaxNat(..)
, CommMaxNat(..)
, StoreMethod(..)
, storeMethod
, ByteOrder(..)
, systemByteOrder
, BoundedPrim(..)
, liftBoundedPrim
, composeBoundedPrim
, unsafeBuildBoundedPrim
, FixedPrim
, liftFixedPrim
, word8
, word16
, word16Native
, word16BE
, word16LE
, word32
, word32Native
, word32BE
, word32LE
, word64
, word64Native
, word64BE
, word64LE
, int8
, int16
, int16Native
, int16BE
, int16LE
, int32
, int32Native
, int32BE
, int32LE
, int64
, int64Native
, int64BE
, int64LE
, float
, floatNative
, floatBE
, floatLE
, double
, doubleNative
, doubleBE
, doubleLE
, charUtf8
, wordBase128LEVar
, wordBase128LEVar_inline
, word32Base128LEVar
, word32Base128LEVar_inline
, word64Base128LEVar
, word64Base128LEVar_inline
, vectorFixedPrim
) where
import Data.Bits ( Bits(..) )
import Data.Bool ( bool )
import Data.Char ( ord )
import Data.Int ( Int8, Int16, Int32, Int64 )
import Data.Kind ( Type )
import qualified Data.Vector.Generic
import Data.Word ( Word16,
byteSwap16, byteSwap32,
byteSwap64 )
import Foreign ( Storable(..) )
import GHC.Exts ( Addr#, Int#, Proxy#,
RealWorld, State#, (+#),
and#, inline, or#,
plusAddr#, plusWord#, proxy#,
uncheckedShiftRL# )
import GHC.IO ( IO(..) )
import GHC.Int ( Int(..) )
import GHC.Ptr ( Ptr(..) )
import GHC.TypeLits ( KnownNat, Nat,
type (+), natVal' )
import GHC.Word ( Word(..), Word8(..),
Word32(..), Word64(..) )
import Parameterized.Data.Semigroup ( PNullary, PSemigroup(..),
(&<>) )
import Parameterized.Data.Monoid ( PMEmpty(..) )
import Proto3.Wire.Reverse.Internal
import Proto3.Wire.Reverse.Width ( AssocPlusNat(..),
CommPlusNat(..),
PChoose(..),
Max, AssocMaxNat(..),
CommMaxNat(..) )
#include <MachDeps.h> /* for WORDS_BIGENDIAN and WORD_SIZE_IN_BITS */
#if WORD_SIZE_IN_BITS < 64
import GHC.IntWord64 (Word64#)
type WORD64 = Word64#
#else
import GHC.Exts (Word#)
type WORD64 = Word#
#endif
data StoreMethod = StoreAligned | StoreUnaligned
deriving (Eq, Show)
storeMethod :: StoreMethod
#if defined(UNALIGNED_POKES)
storeMethod = StoreUnaligned
#else
storeMethod = StoreAligned
#endif
data ByteOrder
= BigEndian
| LittleEndian
deriving (Eq, Show)
systemByteOrder :: ByteOrder
#if defined(WORDS_BIGENDIAN)
systemByteOrder = BigEndian
#else
systemByteOrder = LittleEndian
#endif
newtype BoundedPrim (w :: Nat) = BoundedPrim BuildR
type role BoundedPrim nominal
type instance PNullary BoundedPrim width = BoundedPrim width
instance (w1 + w2) ~ w3 =>
PSemigroup BoundedPrim w1 w2 w3
where
pmappend = composeBoundedPrim
{-# INLINE CONLIKE pmappend #-}
instance AssocPlusNat BoundedPrim u v w
where
assocLPlusNat = assocLPlusNatBoundedPrim
{-# INLINE CONLIKE assocLPlusNat #-}
assocRPlusNat = assocRPlusNatBoundedPrim
{-# INLINE CONLIKE assocRPlusNat #-}
instance CommPlusNat BoundedPrim u v
where
commPlusNat _ (BoundedPrim f) = BoundedPrim f
{-# INLINE CONLIKE commPlusNat #-}
instance PMEmpty BoundedPrim 0
where
pmempty = BoundedPrim mempty
{-# INLINE CONLIKE pmempty #-}
instance Max u v ~ w =>
PChoose BoundedPrim u v w
where
pbool = \(BoundedPrim f) (BoundedPrim g) -> BoundedPrim . bool f g
{-# INLINE CONLIKE pbool #-}
instance AssocMaxNat BoundedPrim u v w
where
assocLMaxNat = \_ (BoundedPrim f) -> BoundedPrim f
{-# INLINE CONLIKE assocLMaxNat #-}
assocRMaxNat = \_ (BoundedPrim f) -> BoundedPrim f
{-# INLINE CONLIKE assocRMaxNat #-}
instance CommMaxNat BoundedPrim u v
where
commMaxNat = \_ (BoundedPrim f) -> BoundedPrim f
{-# INLINE CONLIKE commMaxNat #-}
assocLPlusNatBoundedPrim ::
forall u v w .
Proxy# '(u, v, w) -> BoundedPrim (u + (v + w)) -> BoundedPrim ((u + v) + w)
assocLPlusNatBoundedPrim = \_ (BoundedPrim f) -> BoundedPrim f
{-# INLINE CONLIKE assocLPlusNatBoundedPrim #-}
assocRPlusNatBoundedPrim ::
forall u v w .
Proxy# '(u, v, w) -> BoundedPrim ((u + v) + w) -> BoundedPrim (u + (v + w))
assocRPlusNatBoundedPrim = \_ (BoundedPrim f) -> BoundedPrim f
{-# INLINE CONLIKE assocRPlusNatBoundedPrim #-}
composeBoundedPrim :: BoundedPrim v -> BoundedPrim w -> BoundedPrim (v + w)
composeBoundedPrim =
\(BoundedPrim f) (BoundedPrim g) -> BoundedPrim (f <> g)
{-# INLINE CONLIKE [1] composeBoundedPrim #-}
unsafeBuildBoundedPrim :: BoundedPrim w -> BuildR
unsafeBuildBoundedPrim (BoundedPrim build) = build
liftBoundedPrim :: forall w . KnownNat w => BoundedPrim w -> BuildR
liftBoundedPrim = case fromInteger (natVal' (proxy# :: Proxy# w)) of
I# w -> unsafeLiftBoundedPrim w
{-# INLINE CONLIKE liftBoundedPrim #-}
unsafeLiftBoundedPrim :: Int# -> BoundedPrim w -> BuildR
unsafeLiftBoundedPrim = \w (BoundedPrim f) -> ensure# w f
{-# INLINE CONLIKE [1] unsafeLiftBoundedPrim #-}
{-# RULES
"appendBuildR/unsafeLiftBoundedPrim" forall w1 w2 f1 f2 .
appendBuildR (unsafeLiftBoundedPrim w1 f1) (unsafeLiftBoundedPrim w2 f2)
= unsafeLiftBoundedPrim (w1 +# w2) (composeBoundedPrim f1 f2)
"appendBuildR/unsafeLiftBoundedPrim/assoc_r" forall w1 w2 f1 f2 b .
appendBuildR (unsafeLiftBoundedPrim w1 f1)
(appendBuildR (unsafeLiftBoundedPrim w2 f2) b)
= appendBuildR (unsafeLiftBoundedPrim (w1 +# w2) (composeBoundedPrim f1 f2)) b
"appendBuildR/unsafeLiftBoundedPrim/assoc_l" forall w1 w2 f1 f2 b .
appendBuildR (appendBuildR b (unsafeLiftBoundedPrim w1 f1))
(unsafeLiftBoundedPrim w2 f2)
= appendBuildR b (unsafeLiftBoundedPrim (w1 +# w2) (composeBoundedPrim f1 f2))
#-}
newtype FixedPrim (w :: Nat) = FixedPrim
( Addr# -> Int# -> State# RealWorld -> Int# ->
(# Addr#, Int#, State# RealWorld #)
)
type role FixedPrim nominal
type instance PNullary FixedPrim width = FixedPrim width
instance ((w1 + w2) ~ w3, KnownNat w1) =>
PSemigroup FixedPrim w1 w2 w3
where
pmappend = \(FixedPrim f) (FixedPrim g) ->
case fromInteger (natVal' (proxy# :: Proxy# w1)) of
I# w1 -> FixedPrim
( \v0 u0 s0 o -> case g v0 u0 s0 (o +# w1) of
(# v1, u1, s1 #) -> f v1 u1 s1 o )
{-# INLINE CONLIKE pmappend #-}
instance AssocPlusNat FixedPrim u v w
where
assocLPlusNat = \_ (FixedPrim f) -> FixedPrim f
{-# INLINE CONLIKE assocLPlusNat #-}
assocRPlusNat = \_ (FixedPrim f) -> FixedPrim f
{-# INLINE CONLIKE assocRPlusNat #-}
instance CommPlusNat FixedPrim u v
where
commPlusNat = \_ (FixedPrim f) -> FixedPrim f
{-# INLINE CONLIKE commPlusNat #-}
instance PMEmpty FixedPrim 0
where
pmempty = FixedPrim (\v u s _ -> (# v, u, s #))
{-# INLINE CONLIKE pmempty #-}
liftFixedPrim :: forall w . KnownNat w => FixedPrim w -> BoundedPrim w
liftFixedPrim = \(FixedPrim f) -> BoundedPrim (BuildR (g f))
where
!(I# o) = - fromInteger (natVal' (proxy# :: Proxy# w))
g = \f v0 u0 s0 -> case f v0 u0 s0 o of
(# v1, u1, s1 #) -> (# plusAddr# v1 o, u1 +# o, s1 #)
{-# INLINE g #-}
{-# INLINE CONLIKE [1] liftFixedPrim #-}
{-# RULES
"composeBoundedPrim/liftFixedPrim"
forall (f1 :: KnownNat w1 => FixedPrim w1)
(f2 :: KnownNat (w1 + w2) => FixedPrim w2).
composeBoundedPrim (liftFixedPrim f1) (liftFixedPrim f2)
= liftFixedPrim (pmappend f1 f2)
"composeBoundedPrim/liftFixedPrim/assoc_r"
forall (f1 :: KnownNat w1 => FixedPrim w1)
(f2 :: KnownNat (w1 + w2) => FixedPrim w2)
(b3 :: BoundedPrim w3) .
composeBoundedPrim (liftFixedPrim f1)
(composeBoundedPrim (liftFixedPrim f2) b3)
= assocRPlusNatBoundedPrim (proxy# :: Proxy# '(w1, w2, w3))
(composeBoundedPrim (liftFixedPrim (pmappend f1 f2)) b3)
"composeBoundedPrim/liftFixedPrim/assoc_l"
forall (b1 :: BoundedPrim w1)
(f2 :: KnownNat w2 => FixedPrim w2)
(f3 :: KnownNat (w2 + w3) => FixedPrim w3) .
composeBoundedPrim (composeBoundedPrim b1 (liftFixedPrim f2))
(liftFixedPrim f3)
= assocLPlusNatBoundedPrim (proxy# :: Proxy# '(w1, w2, w3))
(composeBoundedPrim b1 (liftFixedPrim (pmappend f2 f3)))
"withLengthOf#/unsafeLiftBoundedPrim/liftFixedPrim" forall f w g .
withLengthOf# f (unsafeLiftBoundedPrim w (liftFixedPrim g))
= appendBuildR (f w) (unsafeLiftBoundedPrim w (liftFixedPrim g))
#-}
type family StorableWidth (a :: Type) :: Nat
type instance StorableWidth Word8 = 1
type instance StorableWidth Word16 = 2
type instance StorableWidth Word32 = 4
type instance StorableWidth Word64 = 8
type instance StorableWidth Int8 = 1
type instance StorableWidth Int16 = 2
type instance StorableWidth Int32 = 4
type instance StorableWidth Int64 = 8
type instance StorableWidth Float = 4
type instance StorableWidth Double = 8
primPoke :: Storable x => x -> FixedPrim (StorableWidth x)
primPoke !x = FixedPrim p
where
p v u s0 o =
let IO q = pokeByteOff (Ptr v) (I# o) x
in case q s0 of (# s1, (_ :: ()) #) -> (# v, u, s1 #)
word8 :: Word8 -> FixedPrim 1
word8 = primPoke
word8Shift :: Int -> Word -> FixedPrim 1
word8Shift s x = word8 (fromIntegral (shiftR x s))
word16Shift :: ByteOrder -> Int -> Word -> FixedPrim 2
word16Shift bo = case bo of
BigEndian -> \(!s) (!x) -> p (s + h) x &<> p s x
LittleEndian -> \(!s) (!x) -> p s x &<> p (s + h) x
where
h = 8
p = word8Shift
word32Shift :: ByteOrder -> Word -> FixedPrim 4
word32Shift bo = case bo of
BigEndian -> \(!x) -> p h x &<> p 0 x
LittleEndian -> \(!x) -> p 0 x &<> p h x
where
h = 16
p = word16Shift bo
word64Shift :: ByteOrder -> Word64 -> FixedPrim 8
word64Shift bo = case bo of
BigEndian -> \(!x) -> p (h x) &<> p x
LittleEndian -> \(!x) -> p x &<> p (h x)
where
h x = shiftR x 32
p = word32Shift bo . fromIntegral @Word64 @Word
word16 :: ByteOrder -> Word16 -> FixedPrim 2
word16 !bo !x = case storeMethod of
StoreAligned -> word16Shift bo 0 (fromIntegral x)
StoreUnaligned
| systemByteOrder == bo -> primPoke x
| otherwise -> primPoke (byteSwap16 x)
word16Native :: Word16 -> FixedPrim 2
word16Native = word16 systemByteOrder
word16BE :: Word16 -> FixedPrim 2
word16BE = word16 BigEndian
word16LE :: Word16 -> FixedPrim 2
word16LE = word16 LittleEndian
word32 :: ByteOrder -> Word32 -> FixedPrim 4
word32 !bo !x = case storeMethod of
StoreAligned -> word32Shift bo (fromIntegral x)
StoreUnaligned
| systemByteOrder == bo -> primPoke x
| otherwise -> primPoke (byteSwap32 x)
word32Native :: Word32 -> FixedPrim 4
word32Native = word32 systemByteOrder
word32BE :: Word32 -> FixedPrim 4
word32BE = word32 BigEndian
word32LE :: Word32 -> FixedPrim 4
word32LE = word32 LittleEndian
word64 :: ByteOrder -> Word64 -> FixedPrim 8
word64 !bo !x = case storeMethod of
StoreAligned -> word64Shift bo (fromIntegral x)
StoreUnaligned
| systemByteOrder == bo -> primPoke x
| otherwise -> primPoke (byteSwap64 x)
word64Native :: Word64 -> FixedPrim 8
word64Native = word64 systemByteOrder
word64BE :: Word64 -> FixedPrim 8
word64BE = word64 BigEndian
word64LE :: Word64 -> FixedPrim 8
word64LE = word64 LittleEndian
int8 :: Int8 -> FixedPrim 1
int8 = word8 . fromIntegral
int16 :: ByteOrder -> Int16 -> FixedPrim 2
int16 !bo = word16 bo . fromIntegral
int16Native :: Int16 -> FixedPrim 2
int16Native = word16Native . fromIntegral
int16BE :: Int16 -> FixedPrim 2
int16BE = word16BE . fromIntegral
int16LE :: Int16 -> FixedPrim 2
int16LE = word16LE . fromIntegral
int32 :: ByteOrder -> Int32 -> FixedPrim 4
int32 bo = word32 bo . fromIntegral
int32Native :: Int32 -> FixedPrim 4
int32Native = word32Native . fromIntegral
int32BE :: Int32 -> FixedPrim 4
int32BE = word32BE . fromIntegral
int32LE :: Int32 -> FixedPrim 4
int32LE = word32LE . fromIntegral
int64 :: ByteOrder -> Int64 -> FixedPrim 8
int64 bo = word64 bo . fromIntegral
int64Native :: Int64 -> FixedPrim 8
int64Native = word64Native . fromIntegral
int64BE :: Int64 -> FixedPrim 8
int64BE = word64BE . fromIntegral
int64LE :: Int64 -> FixedPrim 8
int64LE = word64LE . fromIntegral
float :: ByteOrder -> Float -> FixedPrim 4
float BigEndian = floatBE
float LittleEndian = floatLE
floatNative :: Float -> FixedPrim 4
floatNative = float systemByteOrder
floatBE :: Float -> FixedPrim 4
floatBE !x = FixedPrim g
where
g v u s0 o = case floatToWord32 (Ptr v) (I# u) x of
IO h -> case h s0 of
(# s1, y #) ->
let FixedPrim f = word32BE y
in f v u s1 o
floatLE :: Float -> FixedPrim 4
floatLE !x = FixedPrim g
where
g v u s0 o = case floatToWord32 (Ptr v) (I# u) x of
IO h -> case h s0 of
(# s1, y #) ->
let FixedPrim f = word32LE y
in f v u s1 o
double :: ByteOrder -> Double -> FixedPrim 8
double BigEndian = doubleBE
double LittleEndian = doubleLE
doubleNative :: Double -> FixedPrim 8
doubleNative = double systemByteOrder
doubleBE :: Double -> FixedPrim 8
doubleBE !x = FixedPrim g
where
g v u s0 o = case doubleToWord64 (Ptr v) (I# u) x of
IO h -> case h s0 of
(# s1, y #) ->
let FixedPrim f = word64BE y
in f v u s1 o
doubleLE :: Double -> FixedPrim 8
doubleLE !x = FixedPrim g
where
g v u s0 o = case doubleToWord64 (Ptr v) (I# u) x of
IO h -> case h s0 of
(# s1, y #) ->
let FixedPrim f = word64LE y
in f v u s1 o
charUtf8 :: Char -> BoundedPrim 4
charUtf8 = \ch -> case fromIntegral (ord ch) of W# x -> wordUtf8 x
where
wordUtf8 :: Word# -> BoundedPrim 4
wordUtf8 =
choose 0x7F p1 $
choose 0x7FF p2 $
choose 0xFFFF p3 $
(\y -> liftFixedPrim (p4 y))
{-# INLINE wordUtf8 #-}
choose ::
forall v w .
(KnownNat v, KnownNat w) =>
Word ->
(Word# -> FixedPrim v) ->
(Word# -> BoundedPrim w) ->
Word# -> BoundedPrim (Max w v)
choose = \t f g x -> pif (W# x <= t) (liftFixedPrim (f x)) (g x)
{-# INLINE choose #-}
lsb ::
KnownNat n =>
(Word# -> FixedPrim n) ->
Word# ->
FixedPrim (n + 1)
lsb = \p x -> p (uncheckedShiftRL# x 6#) &<>
word8 (W8# (plusWord# 0x80## (and# x 0x3F##)))
{-# INLINE lsb #-}
p1 :: Word# -> FixedPrim 1
p2 :: Word# -> FixedPrim 2
p3 :: Word# -> FixedPrim 3
p4 :: Word# -> FixedPrim 4
p1 x = word8 (W8# x)
p2 = lsb (\x -> word8 (W8# (plusWord# 0xC0## x)))
p3 = lsb (lsb (\x -> word8 (W8# (plusWord# 0xE0## x))))
p4 = lsb (lsb (lsb (\x -> word8 (W8# (plusWord# 0xF0## x)))))
{-# INLINE p1 #-}
{-# INLINE p2 #-}
{-# INLINE p3 #-}
{-# INLINE p4 #-}
{-# INLINE charUtf8 #-}
#if WORD_SIZE_IN_BITS < 64
wordBase128LEVar :: Word -> BoundedPrim 5
wordBase128LEVar (W# w) = word32Base128LEVar (W32# w)
#else
wordBase128LEVar :: Word -> BoundedPrim 10
wordBase128LEVar (W# w) = word64Base128LEVar (W64# w)
#endif
{-# INLINE wordBase128LEVar #-}
#if WORD_SIZE_IN_BITS < 64
wordBase128LEVar_inline :: Word -> BoundedPrim 5
wordBase128LEVar_inline (W# w) = word32Base128LEVar_inline (W32# w)
#else
wordBase128LEVar_inline :: Word -> BoundedPrim 10
wordBase128LEVar_inline (W# w) = word64Base128LEVar_inline (W64# w)
#endif
{-# INLINE wordBase128LEVar_inline #-}
word32Base128LEVar :: Word32 -> BoundedPrim 5
word32Base128LEVar = word32Base128LEVar_inline
{-# INLINE word32Base128LEVar #-}
word32Base128LEVar_inline :: Word32 -> BoundedPrim 5
word32Base128LEVar_inline = \(W32# x0) ->
( wordBase128LEVar_choose 1 wordBase128LE_p1 $
wordBase128LEVar_choose 2 wordBase128LE_p2 $
wordBase128LEVar_choose 3 wordBase128LE_p3 $
wordBase128LEVar_choose 4 wordBase128LE_p4 $
(\x -> liftFixedPrim (wordBase128LE_p5 0## x))
) x0
{-# INLINE word32Base128LEVar_inline #-}
wordBase128LEVar_choose ::
forall v w .
(KnownNat v, KnownNat w) =>
Int ->
(Word# -> Word# -> FixedPrim v) ->
(Word# -> BoundedPrim w) ->
Word# -> BoundedPrim (Max w v)
wordBase128LEVar_choose = \d f g x ->
pif (W# x <= shiftL 1 (7 * d) - 1) (liftFixedPrim (f 0## x)) (g x)
{-# INLINE wordBase128LEVar_choose #-}
wordBase128LE_msb ::
forall n .
KnownNat n =>
(Word# -> Word# -> FixedPrim n) ->
Word# -> Word# -> FixedPrim (n + 1)
wordBase128LE_msb = \p m x ->
p 0x80## x &<> word8 (W8# (or# m (uncheckedShiftRL# x s)))
where
!(I# s) = 7 * fromInteger (natVal' (proxy# :: Proxy# n))
{-# INLINE wordBase128LE_msb #-}
wordBase128LE_p1 :: Word# -> Word# -> FixedPrim 1
wordBase128LE_p1 = \m x -> word8 (W8# (or# m x))
{-# INLINE wordBase128LE_p1 #-}
wordBase128LE_p2 :: Word# -> Word# -> FixedPrim 2
wordBase128LE_p2 = wordBase128LE_msb wordBase128LE_p1
{-# INLINE wordBase128LE_p2 #-}
wordBase128LE_p3 :: Word# -> Word# -> FixedPrim 3
wordBase128LE_p3 = wordBase128LE_msb wordBase128LE_p2
{-# INLINE wordBase128LE_p3 #-}
wordBase128LE_p4 :: Word# -> Word# -> FixedPrim 4
wordBase128LE_p4 = wordBase128LE_msb wordBase128LE_p3
{-# INLINE wordBase128LE_p4 #-}
wordBase128LE_p5 :: Word# -> Word# -> FixedPrim 5
wordBase128LE_p5 = wordBase128LE_msb wordBase128LE_p4
{-# INLINE wordBase128LE_p5 #-}
word14Base128LEVar :: Word# -> BoundedPrim 2
word14Base128LEVar = \x0 ->
( wordBase128LEVar_choose 1 wordBase128LE_p1 $
(\x -> liftFixedPrim (wordBase128LE_p2 0## x))
) x0
{-# INLINE word14Base128LEVar #-}
word28Base128LE :: Word# -> FixedPrim 4
word28Base128LE = wordBase128LE_p4 0x80##
{-# INLINE word28Base128LE #-}
word64Base128LEVar :: Word64 -> BoundedPrim 10
word64Base128LEVar = \(W64# x) ->
pif (W64# x <= fromIntegral (maxBound :: Word32))
(word32Base128LEVar (fromIntegral (W64# x)))
(word64Base128LEVar_big x)
{-# INLINE word64Base128LEVar #-}
word64Base128LEVar_inline :: Word64 -> BoundedPrim 10
word64Base128LEVar_inline = \(W64# x) ->
pif (W64# x <= fromIntegral (maxBound :: Word32))
(word32Base128LEVar (fromIntegral (W64# x)))
(inline (word64Base128LEVar_big x))
{-# INLINE word64Base128LEVar_inline #-}
word64Base128LEVar_big :: WORD64 -> BoundedPrim 10
word64Base128LEVar_big x = pif (W64# x <= shiftL 1 60 - 1) p60 p64
where
p60 = liftFixedPrim (word28Base128LE x32) &<>
word32Base128LEVar (W32# (shR 28))
p64 = ( liftFixedPrim (word28Base128LE x32) &<>
liftFixedPrim (word28Base128LE (shR 28)) ) &<>
word14Base128LEVar (shR 56)
x32 = case fromIntegral (W64# x) of W32# y -> y
shR s = case fromIntegral (shiftR (W64# x) s) of W32# y -> y
{-# NOINLINE word64Base128LEVar_big #-}
vectorFixedPrim ::
forall w v a .
(KnownNat w, Data.Vector.Generic.Vector v a) =>
(a -> FixedPrim w) ->
v a ->
BuildR
vectorFixedPrim f = etaBuildR $ \v ->
let op acc x = acc <> unsafeBuildBoundedPrim (liftFixedPrim (f x))
in ensure (w * Data.Vector.Generic.length v) (foldlRVector op mempty v)
where
w = fromInteger (natVal' (proxy# :: Proxy# w))
{-# INLINE vectorFixedPrim #-}