{-# LANGUAGE BangPatterns      #-}
{-# LANGUAGE CPP               #-}
{-# LANGUAGE MagicHash         #-}
{-# LANGUAGE NoImplicitPrelude #-}

#if !MIN_VERSION_base(4,8,0)
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE StandaloneDeriving #-}
#endif

-- |
-- Module      : Data.Word.Word24
-- License     : see  src/Data/LICENSE
-- Stability   : experimental
-- Portability : non-portable (GHC Extensions)

-- Provide a 24-bit unsigned integral type: 'Word24', analagous to Word8,
-- Word16, etc.
--

module Data.Word.Word24 (
  -- * Word24 type
    Word24(..)
  , byteSwap24
  , byteSwap24#
  -- * Internal helpers
  , narrow24Word#
#if MIN_VERSION_base(4,8,0)
  , clz24#
  , ctz24#
#endif
  , popCnt24#
  )

where

import           Data.Bits
import           Data.Data
import           Data.Maybe
import           Foreign.Storable

import           GHC.Arr
import           GHC.Base
import           GHC.Enum
import           GHC.Num hiding (integerToWord)
import           GHC.Ptr
import           GHC.Read
import           GHC.Real
import           GHC.Show
import           GHC.Word.Compat
import           GHC.Integer (smallInteger, integerToWord)

import           Control.DeepSeq

#if !MIN_VERSION_base(4,8,0)
import           Data.Typeable
#endif

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

-- Word24 is represented in the same way as Word.  Operations may assume and
-- must ensure that it holds only values in its logical range.

-- | 24-bit unsigned integer type
--
data Word24 = W24# Word# deriving (Word24 -> Word24 -> Bool
(Word24 -> Word24 -> Bool)
-> (Word24 -> Word24 -> Bool) -> Eq Word24
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Word24 -> Word24 -> Bool
== :: Word24 -> Word24 -> Bool
$c/= :: Word24 -> Word24 -> Bool
/= :: Word24 -> Word24 -> Bool
Eq, Eq Word24
Eq Word24 =>
(Word24 -> Word24 -> Ordering)
-> (Word24 -> Word24 -> Bool)
-> (Word24 -> Word24 -> Bool)
-> (Word24 -> Word24 -> Bool)
-> (Word24 -> Word24 -> Bool)
-> (Word24 -> Word24 -> Word24)
-> (Word24 -> Word24 -> Word24)
-> Ord Word24
Word24 -> Word24 -> Bool
Word24 -> Word24 -> Ordering
Word24 -> Word24 -> Word24
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Word24 -> Word24 -> Ordering
compare :: Word24 -> Word24 -> Ordering
$c< :: Word24 -> Word24 -> Bool
< :: Word24 -> Word24 -> Bool
$c<= :: Word24 -> Word24 -> Bool
<= :: Word24 -> Word24 -> Bool
$c> :: Word24 -> Word24 -> Bool
> :: Word24 -> Word24 -> Bool
$c>= :: Word24 -> Word24 -> Bool
>= :: Word24 -> Word24 -> Bool
$cmax :: Word24 -> Word24 -> Word24
max :: Word24 -> Word24 -> Word24
$cmin :: Word24 -> Word24 -> Word24
min :: Word24 -> Word24 -> Word24
Ord)

#if !MIN_VERSION_base(4,8,0)
deriving instance Typeable Word24
#endif

instance NFData Word24 where rnf :: Word24 -> ()
rnf !Word24
_ = ()

word24Type :: DataType
word24Type :: DataType
word24Type = String -> DataType
mkIntType String
"Data.Word.Word24.Word24"

instance Data Word24 where
  toConstr :: Word24 -> Constr
toConstr Word24
x = DataType -> Word24 -> Constr
forall a. (Integral a, Show a) => DataType -> a -> Constr
mkIntegralConstr DataType
word24Type Word24
x
  gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Word24
gunfold forall b r. Data b => c (b -> r) -> c r
_ forall r. r -> c r
z Constr
c = case Constr -> ConstrRep
constrRep Constr
c of
                    (IntConstr Integer
x) -> Word24 -> c Word24
forall r. r -> c r
z (Integer -> Word24
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
x)
                    ConstrRep
_ -> String -> c Word24
forall a. HasCallStack => String -> a
error (String -> c Word24) -> String -> c Word24
forall a b. (a -> b) -> a -> b
$ String
"Data.Data.gunfold: Constructor " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Constr -> String
forall a. Show a => a -> String
show Constr
c
                                 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" is not of type Word24."
  dataTypeOf :: Word24 -> DataType
dataTypeOf Word24
_ = DataType
word24Type

-- | narrowings represented as primop 'and#' in GHC.
narrow24Word# :: Word# -> Word#
narrow24Word# :: Word# -> Word#
narrow24Word# = Word# -> Word# -> Word#
and# Word#
0xFFFFFF##

#if MIN_VERSION_base(4,8,0)
-- | count leading zeros
--
clz24# :: Word# -> Word#
clz24# :: Word# -> Word#
clz24# Word#
w# = Word# -> Word#
clz32# (Word# -> Word#
narrow24Word# Word#
w#) Word# -> Word# -> Word#
`minusWord#` Word#
8##

-- | count trailing zeros
--
ctz24# :: Word# -> Word#
ctz24# :: Word# -> Word#
ctz24# Word#
w# = Word# -> Word#
ctz# (Word#
w# Word# -> Word# -> Word#
`or#` Word#
0x1000000##)
#endif

-- | the number of set bits
--
popCnt24# :: Word# -> Word#
popCnt24# :: Word# -> Word#
popCnt24# Word#
w# = Word# -> Word#
popCnt# (Word# -> Word#
narrow24Word# Word#
w#)

instance Show Word24 where
  showsPrec :: Int -> Word24 -> String -> String
showsPrec Int
p Word24
x = Int -> Int -> String -> String
forall a. Show a => Int -> a -> String -> String
showsPrec Int
p (Word24 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word24
x :: Int)

instance Num Word24 where
  (W24# Word#
x#) + :: Word24 -> Word24 -> Word24
+ (W24# Word#
y#) = Word# -> Word24
W24# (Word# -> Word#
narrow24Word# (Word#
x# Word# -> Word# -> Word#
`plusWord#` Word#
y#))
  (W24# Word#
x#) - :: Word24 -> Word24 -> Word24
- (W24# Word#
y#) = Word# -> Word24
W24# (Word# -> Word#
narrow24Word# (Word#
x# Word# -> Word# -> Word#
`minusWord#` Word#
y#))
  (W24# Word#
x#) * :: Word24 -> Word24 -> Word24
* (W24# Word#
y#) = Word# -> Word24
W24# (Word# -> Word#
narrow24Word# (Word#
x# Word# -> Word# -> Word#
`timesWord#` Word#
y#))
  negate :: Word24 -> Word24
negate (W24# Word#
x#)      = Word# -> Word24
W24# (Word# -> Word#
narrow24Word# (Int# -> Word#
int2Word# (Int# -> Int#
negateInt# (Word# -> Int#
word2Int# Word#
x#))))
  abs :: Word24 -> Word24
abs Word24
x                 = Word24
x
  signum :: Word24 -> Word24
signum Word24
0              = Word24
0
  signum Word24
_              = Word24
1
  fromInteger :: Integer -> Word24
fromInteger Integer
i         = Word# -> Word24
W24# (Word# -> Word#
narrow24Word# (Integer -> Word#
integerToWord Integer
i))

instance Real Word24 where
  toRational :: Word24 -> Rational
toRational Word24
x = Word24 -> Integer
forall a. Integral a => a -> Integer
toInteger Word24
x Integer -> Integer -> Rational
forall a. Integral a => a -> a -> Ratio a
% Integer
1

instance Enum Word24 where
  succ :: Word24 -> Word24
succ Word24
x
    | Word24
x Word24 -> Word24 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word24
forall a. Bounded a => a
maxBound  = Word24
x Word24 -> Word24 -> Word24
forall a. Num a => a -> a -> a
+ Word24
1
    | Bool
otherwise      = String -> Word24
forall a. String -> a
succError String
"Word24"
  pred :: Word24 -> Word24
pred Word24
x
    | Word24
x Word24 -> Word24 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word24
forall a. Bounded a => a
minBound  = Word24
x Word24 -> Word24 -> Word24
forall a. Num a => a -> a -> a
- Word24
1
    | Bool
otherwise      = String -> Word24
forall a. String -> a
predError String
"Word24"
  toEnum :: Int -> Word24
toEnum i :: Int
i@(I# Int#
i#)
    | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Word24 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word24
forall a. Bounded a => a
maxBound :: Word24)
                     = Word# -> Word24
W24# (Int# -> Word#
int2Word# Int#
i#)
    | Bool
otherwise      = String -> Int -> (Word24, Word24) -> Word24
forall a b. Show a => String -> Int -> (a, a) -> b
toEnumError String
"Word24" Int
i (Word24
forall a. Bounded a => a
minBound::Word24, Word24
forall a. Bounded a => a
maxBound::Word24)
  fromEnum :: Word24 -> Int
fromEnum (W24# Word#
x#) = Int# -> Int
I# (Word# -> Int#
word2Int# Word#
x#)
  enumFrom :: Word24 -> [Word24]
enumFrom           = Word24 -> [Word24]
forall a. (Enum a, Bounded a) => a -> [a]
boundedEnumFrom
  enumFromThen :: Word24 -> Word24 -> [Word24]
enumFromThen       = Word24 -> Word24 -> [Word24]
forall a. (Enum a, Bounded a) => a -> a -> [a]
boundedEnumFromThen

instance Integral Word24 where
  quot :: Word24 -> Word24 -> Word24
quot (W24# Word#
x#) y :: Word24
y@(W24# Word#
y#)
    | Word24
y Word24 -> Word24 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word24
0                 = Word# -> Word24
W24# (Word#
x# Word# -> Word# -> Word#
`quotWord#` Word#
y#)
    | Bool
otherwise              = Word24
forall a. a
divZeroError
  rem :: Word24 -> Word24 -> Word24
rem (W24# Word#
x#) y :: Word24
y@(W24# Word#
y#)
    | Word24
y Word24 -> Word24 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word24
0                 = Word# -> Word24
W24# (Word#
x# Word# -> Word# -> Word#
`remWord#` Word#
y#)
    | Bool
otherwise              = Word24
forall a. a
divZeroError
  div :: Word24 -> Word24 -> Word24
div (W24# Word#
x#) y :: Word24
y@(W24# Word#
y#)
    | Word24
y Word24 -> Word24 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word24
0                 = Word# -> Word24
W24# (Word#
x# Word# -> Word# -> Word#
`quotWord#` Word#
y#)
    | Bool
otherwise              = Word24
forall a. a
divZeroError
  mod :: Word24 -> Word24 -> Word24
mod (W24# Word#
x#) y :: Word24
y@(W24# Word#
y#)
    | Word24
y Word24 -> Word24 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word24
0                 = Word# -> Word24
W24# (Word#
x# Word# -> Word# -> Word#
`remWord#` Word#
y#)
    | Bool
otherwise              = Word24
forall a. a
divZeroError
  quotRem :: Word24 -> Word24 -> (Word24, Word24)
quotRem (W24# Word#
x#) y :: Word24
y@(W24# Word#
y#)
    | Word24
y Word24 -> Word24 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word24
0                 = (Word# -> Word24
W24# (Word#
x# Word# -> Word# -> Word#
`quotWord#` Word#
y#), Word# -> Word24
W24# (Word#
x# Word# -> Word# -> Word#
`remWord#` Word#
y#))
    | Bool
otherwise              = (Word24, Word24)
forall a. a
divZeroError
  divMod :: Word24 -> Word24 -> (Word24, Word24)
divMod (W24# Word#
x#) y :: Word24
y@(W24# Word#
y#)
    | Word24
y Word24 -> Word24 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word24
0                 = (Word# -> Word24
W24# (Word#
x# Word# -> Word# -> Word#
`quotWord#` Word#
y#), Word# -> Word24
W24# (Word#
x# Word# -> Word# -> Word#
`remWord#` Word#
y#))
    | Bool
otherwise              = (Word24, Word24)
forall a. a
divZeroError
  toInteger :: Word24 -> Integer
toInteger (W24# Word#
x#)        = Int# -> Integer
smallInteger (Word# -> Int#
word2Int# Word#
x#)

instance Bounded Word24 where
  minBound :: Word24
minBound = Word24
0
  maxBound :: Word24
maxBound = Word24
0xFFFFFF

instance Ix Word24 where
  range :: (Word24, Word24) -> [Word24]
range (Word24
m,Word24
n)         = [Word24
m..Word24
n]
  unsafeIndex :: (Word24, Word24) -> Word24 -> Int
unsafeIndex (Word24
m,Word24
_) Word24
i = Word24 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word24
i Word24 -> Word24 -> Word24
forall a. Num a => a -> a -> a
- Word24
m)
  inRange :: (Word24, Word24) -> Word24 -> Bool
inRange (Word24
m,Word24
n) Word24
i     = Word24
m Word24 -> Word24 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word24
i Bool -> Bool -> Bool
&& Word24
i Word24 -> Word24 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word24
n

instance Read Word24 where
  readsPrec :: Int -> ReadS Word24
readsPrec Int
p String
s = [(Int -> Word24
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
x::Int), String
r) | (Int
x, String
r) <- Int -> ReadS Int
forall a. Read a => Int -> ReadS a
readsPrec Int
p String
s]

instance Bits Word24 where
    {-# INLINE shift #-}
    {-# INLINE bit #-}
    {-# INLINE testBit #-}

    (W24# Word#
x#) .&. :: Word24 -> Word24 -> Word24
.&.   (W24# Word#
y#)  = Word# -> Word24
W24# (Word#
x# Word# -> Word# -> Word#
`and#` Word#
y#)
    (W24# Word#
x#) .|. :: Word24 -> Word24 -> Word24
.|.   (W24# Word#
y#)  = Word# -> Word24
W24# (Word#
x# Word# -> Word# -> Word#
`or#`  Word#
y#)
    (W24# Word#
x#) xor :: Word24 -> Word24 -> Word24
`xor` (W24# Word#
y#)  = Word# -> Word24
W24# (Word#
x# Word# -> Word# -> Word#
`xor#` Word#
y#)
    complement :: Word24 -> Word24
complement (W24# Word#
x#)       = Word# -> Word24
W24# (Word#
x# Word# -> Word# -> Word#
`xor#` Word#
mb#) where !(W24# Word#
mb#) = Word24
forall a. Bounded a => a
maxBound
    (W24# Word#
x#) shift :: Word24 -> Int -> Word24
`shift` (I# Int#
i#)
        | Int# -> Bool
isTrue# (Int#
i# Int# -> Int# -> Int#
>=# Int#
0#)  = Word# -> Word24
W24# (Word# -> Word#
narrow24Word# (Word#
x# Word# -> Int# -> Word#
`shiftL#` Int#
i#))
        | Bool
otherwise            = Word# -> Word24
W24# (Word#
x# Word# -> Int# -> Word#
`shiftRL#` Int# -> Int#
negateInt# Int#
i#)
    (W24# Word#
x#) shiftL :: Word24 -> Int -> Word24
`shiftL` (I# Int#
i#)       = Word# -> Word24
W24# (Word# -> Word#
narrow24Word# (Word#
x# Word# -> Int# -> Word#
`shiftL#` Int#
i#))
    (W24# Word#
x#) unsafeShiftL :: Word24 -> Int -> Word24
`unsafeShiftL` (I# Int#
i#) =
        Word# -> Word24
W24# (Word# -> Word#
narrow24Word# (Word#
x# Word# -> Int# -> Word#
`uncheckedShiftL#` Int#
i#))
    (W24# Word#
x#) shiftR :: Word24 -> Int -> Word24
`shiftR`       (I# Int#
i#) = Word# -> Word24
W24# (Word#
x# Word# -> Int# -> Word#
`shiftRL#` Int#
i#)
    (W24# Word#
x#) unsafeShiftR :: Word24 -> Int -> Word24
`unsafeShiftR` (I# Int#
i#) = Word# -> Word24
W24# (Word#
x# Word# -> Int# -> Word#
`uncheckedShiftRL#` Int#
i#)
    (W24# Word#
x#) rotate :: Word24 -> Int -> Word24
`rotate`       Int
i
        | Int# -> Bool
isTrue# (Int#
i'# Int# -> Int# -> Int#
==# Int#
0#) = Word# -> Word24
W24# Word#
x#
        | Bool
otherwise  = Word# -> Word24
W24# (Word# -> Word#
narrow24Word# ((Word#
x# Word# -> Int# -> Word#
`uncheckedShiftL#` Int#
i'#) Word# -> Word# -> Word#
`or#`
                                            (Word#
x# Word# -> Int# -> Word#
`uncheckedShiftRL#` (Int#
24# Int# -> Int# -> Int#
-# Int#
i'#))))
      where
        !(I# Int#
i'#) = Int
i Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
24
    bitSizeMaybe :: Word24 -> Maybe Int
bitSizeMaybe Word24
i            = Int -> Maybe Int
forall a. a -> Maybe a
Just (Word24 -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize Word24
i)
    bitSize :: Word24 -> Int
bitSize                   = Word24 -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize
    isSigned :: Word24 -> Bool
isSigned Word24
_                = Bool
False
    popCount :: Word24 -> Int
popCount (W24# Word#
x#)        = Int# -> Int
I# (Word# -> Int#
word2Int# (Word# -> Word#
popCnt24# Word#
x#))
    bit :: Int -> Word24
bit                       = Int -> Word24
forall a. (Bits a, Num a) => Int -> a
bitDefault
    testBit :: Word24 -> Int -> Bool
testBit                   = Word24 -> Int -> Bool
forall a. (Bits a, Num a) => a -> Int -> Bool
testBitDefault

instance FiniteBits Word24 where
    finiteBitSize :: Word24 -> Int
finiteBitSize Word24
_ = Int
24
#if MIN_VERSION_base(4,8,0)
    countLeadingZeros :: Word24 -> Int
countLeadingZeros  (W24# Word#
x#) = Int# -> Int
I# (Word# -> Int#
word2Int# (Word# -> Word#
clz24# Word#
x#))
    countTrailingZeros :: Word24 -> Int
countTrailingZeros (W24# Word#
x#) = Int# -> Int
I# (Word# -> Int#
word2Int# (Word# -> Word#
ctz24# Word#
x#))
#endif

-- | Swap bytes in 'Word24'.
--
byteSwap24 :: Word24 -> Word24
byteSwap24 :: Word24 -> Word24
byteSwap24 (W24# Word#
w#) = Word# -> Word24
W24# (Word# -> Word#
byteSwap24# Word#
w#)

byteSwap24# :: Word# -> Word#
byteSwap24# :: Word# -> Word#
byteSwap24# Word#
w# = let byte0 :: Word#
byte0 = Word# -> Int# -> Word#
uncheckedShiftL# (Word# -> Word# -> Word#
and# Word#
w# Word#
0x0000ff##) Int#
16#
                     byte1 :: Word#
byte1 = Word# -> Word# -> Word#
and# Word#
w# Word#
0x00ff00##
                     byte2 :: Word#
byte2 = Word# -> Int# -> Word#
uncheckedShiftRL# (Word# -> Word# -> Word#
and# Word#
w# Word#
0xff0000##) Int#
16#
                 in Word#
byte0 Word# -> Word# -> Word#
`or#` Word#
byte1 Word# -> Word# -> Word#
`or#` Word#
byte2

{-# RULES
"fromIntegral/Word8->Word24"    fromIntegral = \(W8# x#) -> W24# x#
"fromIntegral/Word16->Word24"   fromIntegral = \(W16# x#) -> W24# x#
"fromIntegral/Word24->Word24"   fromIntegral = id :: Word24 -> Word24
"fromIntegral/Word24->Integer"  fromIntegral = toInteger :: Word24 -> Integer
"fromIntegral/a->Word24"        fromIntegral = \x -> case fromIntegral x of W# x# -> W24# (narrow24Word# x#)
"fromIntegral/Word24->a"        fromIntegral = \(W24# x#) -> fromIntegral (W# x#)
  #-}

{-# RULES
"properFraction/Float->(Word24,Float)"
    properFraction = \x ->
                      case properFraction x of {
                        (n, y) -> ((fromIntegral :: Int -> Word24) n, y :: Float) }
"truncate/Float->Word24"
    truncate = (fromIntegral :: Int -> Word24) . (truncate :: Float -> Int)
"floor/Float->Word24"
    floor    = (fromIntegral :: Int -> Word24) . (floor :: Float -> Int)
"ceiling/Float->Word24"
    ceiling  = (fromIntegral :: Int -> Word24) . (ceiling :: Float -> Int)
"round/Float->Word24"
    round    = (fromIntegral :: Int -> Word24) . (round  :: Float -> Int)
  #-}

{-# RULES
"properFraction/Double->(Word24,Double)"
    properFraction = \x ->
                      case properFraction x of {
                        (n, y) -> ((fromIntegral :: Int -> Word24) n, y :: Double) }
"truncate/Double->Word24"
    truncate = (fromIntegral :: Int -> Word24) . (truncate :: Double -> Int)
"floor/Double->Word24"
    floor    = (fromIntegral :: Int -> Word24) . (floor :: Double -> Int)
"ceiling/Double->Word24"
    ceiling  = (fromIntegral :: Int -> Word24) . (ceiling :: Double -> Int)
"round/Double->Word24"
    round    = (fromIntegral :: Int -> Word24) . (round  :: Double -> Int)
  #-}

readWord24OffPtr :: Ptr Word24 -> IO Word24
readWord24OffPtr :: Ptr Word24 -> IO Word24
readWord24OffPtr Ptr Word24
p = do
  let p' :: Ptr Word8
p' = Ptr Word24 -> Ptr Word8
forall a b. Ptr a -> Ptr b
castPtr Ptr Word24
p :: Ptr Word8
  Word8
w1 <- Ptr Word8 -> Int -> IO Word8
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Word8
p' Int
0
  Word8
w2 <- Ptr Word8 -> Int -> IO Word8
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Word8
p' Int
1
  Word8
w3 <- Ptr Word8 -> Int -> IO Word8
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Word8
p' Int
2
  let w1' :: Word24
w1' = (Word8 -> Word24
forall a b. (Integral a, Num b) => a -> b
fromIntegral :: (Word8 -> Word24)) Word8
w1
      w2' :: Word24
w2' = (Word8 -> Word24
forall a b. (Integral a, Num b) => a -> b
fromIntegral :: (Word8 -> Word24)) Word8
w2
      w3' :: Word24
w3' = (Word8 -> Word24
forall a b. (Integral a, Num b) => a -> b
fromIntegral :: (Word8 -> Word24)) Word8
w3
      w :: Word24
w = Word24
w1' Word24 -> Word24 -> Word24
forall a. Bits a => a -> a -> a
.|. (Word24
w2' Word24 -> Int -> Word24
forall a. Bits a => a -> Int -> a
`shiftL` Int
8) Word24 -> Word24 -> Word24
forall a. Bits a => a -> a -> a
.|. (Word24
w3' Word24 -> Int -> Word24
forall a. Bits a => a -> Int -> a
`shiftL` Int
16)
  Word24 -> IO Word24
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Word24
w

writeWord24ToPtr :: Ptr Word24 -> Word24 -> IO ()
writeWord24ToPtr :: Ptr Word24 -> Word24 -> IO ()
writeWord24ToPtr Ptr Word24
p Word24
v = do
    let w1 :: Word8
w1 = Word24 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word24
v Word24 -> Word24 -> Word24
forall a. Bits a => a -> a -> a
.&. Word24
0x0000FF) :: Word8
        w2 :: Word8
w2 = Word24 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral ((Word24
v Word24 -> Word24 -> Word24
forall a. Bits a => a -> a -> a
.&. Word24
0x00FF00) Word24 -> Int -> Word24
forall a. Bits a => a -> Int -> a
`shiftR` Int
8) :: Word8
        w3 :: Word8
w3 = Word24 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral ((Word24
v Word24 -> Word24 -> Word24
forall a. Bits a => a -> a -> a
.&. Word24
0xFF0000) Word24 -> Int -> Word24
forall a. Bits a => a -> Int -> a
`shiftR` Int
16) :: Word8
    Ptr Word24 -> Int -> Word8 -> IO ()
forall b. Ptr b -> Int -> Word8 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr Word24
p Int
0 Word8
w1
    Ptr Word24 -> Int -> Word8 -> IO ()
forall b. Ptr b -> Int -> Word8 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr Word24
p Int
1 Word8
w2
    Ptr Word24 -> Int -> Word8 -> IO ()
forall b. Ptr b -> Int -> Word8 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr Word24
p Int
2 Word8
w3

instance Storable Word24 where
  sizeOf :: Word24 -> Int
sizeOf Word24
_    = Int
3
  alignment :: Word24 -> Int
alignment Word24
_ = Int
3
  peek :: Ptr Word24 -> IO Word24
peek        = Ptr Word24 -> IO Word24
readWord24OffPtr
  poke :: Ptr Word24 -> Word24 -> IO ()
poke        = Ptr Word24 -> Word24 -> IO ()
writeWord24ToPtr