{-# 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
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Word24 -> Word24 -> Bool
$c/= :: Word24 -> Word24 -> Bool
== :: Word24 -> Word24 -> Bool
$c== :: Word24 -> Word24 -> Bool
Eq, Eq 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
min :: Word24 -> Word24 -> Word24
$cmin :: Word24 -> Word24 -> Word24
max :: Word24 -> Word24 -> Word24
$cmax :: Word24 -> Word24 -> Word24
>= :: Word24 -> Word24 -> Bool
$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
compare :: Word24 -> Word24 -> Ordering
$ccompare :: Word24 -> Word24 -> Ordering
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 = 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) -> forall r. r -> c r
z (forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
x)
                    ConstrRep
_ -> forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"Data.Data.gunfold: Constructor " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Constr
c
                                 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 -> ShowS
showsPrec Int
p Word24
x = forall a. Show a => Int -> a -> ShowS
showsPrec Int
p (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 = forall a. Integral a => a -> Integer
toInteger Word24
x forall a. Integral a => a -> a -> Ratio a
% Integer
1

instance Enum Word24 where
  succ :: Word24 -> Word24
succ Word24
x
    | Word24
x forall a. Eq a => a -> a -> Bool
/= forall a. Bounded a => a
maxBound  = Word24
x forall a. Num a => a -> a -> a
+ Word24
1
    | Bool
otherwise      = forall a. String -> a
succError String
"Word24"
  pred :: Word24 -> Word24
pred Word24
x
    | Word24
x forall a. Eq a => a -> a -> Bool
/= forall a. Bounded a => a
minBound  = Word24
x forall a. Num a => a -> a -> a
- Word24
1
    | Bool
otherwise      = forall a. String -> a
predError String
"Word24"
  toEnum :: Int -> Word24
toEnum i :: Int
i@(I# Int#
i#)
    | Int
i forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
i forall a. Ord a => a -> a -> Bool
<= forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a. Bounded a => a
maxBound :: Word24)
                     = Word# -> Word24
W24# (Int# -> Word#
int2Word# Int#
i#)
    | Bool
otherwise      = forall a b. Show a => String -> Int -> (a, a) -> b
toEnumError String
"Word24" Int
i (forall a. Bounded a => a
minBound::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           = forall a. (Enum a, Bounded a) => a -> [a]
boundedEnumFrom
  enumFromThen :: Word24 -> Word24 -> [Word24]
enumFromThen       = 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 forall a. Eq a => a -> a -> Bool
/= Word24
0                 = Word# -> Word24
W24# (Word#
x# Word# -> Word# -> Word#
`quotWord#` Word#
y#)
    | Bool
otherwise              = forall a. a
divZeroError
  rem :: Word24 -> Word24 -> Word24
rem (W24# Word#
x#) y :: Word24
y@(W24# Word#
y#)
    | Word24
y forall a. Eq a => a -> a -> Bool
/= Word24
0                 = Word# -> Word24
W24# (Word#
x# Word# -> Word# -> Word#
`remWord#` Word#
y#)
    | Bool
otherwise              = forall a. a
divZeroError
  div :: Word24 -> Word24 -> Word24
div (W24# Word#
x#) y :: Word24
y@(W24# Word#
y#)
    | Word24
y forall a. Eq a => a -> a -> Bool
/= Word24
0                 = Word# -> Word24
W24# (Word#
x# Word# -> Word# -> Word#
`quotWord#` Word#
y#)
    | Bool
otherwise              = forall a. a
divZeroError
  mod :: Word24 -> Word24 -> Word24
mod (W24# Word#
x#) y :: Word24
y@(W24# Word#
y#)
    | Word24
y forall a. Eq a => a -> a -> Bool
/= Word24
0                 = Word# -> Word24
W24# (Word#
x# Word# -> Word# -> Word#
`remWord#` Word#
y#)
    | Bool
otherwise              = forall a. a
divZeroError
  quotRem :: Word24 -> Word24 -> (Word24, Word24)
quotRem (W24# Word#
x#) y :: Word24
y@(W24# Word#
y#)
    | Word24
y 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              = forall a. a
divZeroError
  divMod :: Word24 -> Word24 -> (Word24, Word24)
divMod (W24# Word#
x#) y :: Word24
y@(W24# Word#
y#)
    | Word24
y 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              = 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 = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word24
i forall a. Num a => a -> a -> a
- Word24
m)
  inRange :: (Word24, Word24) -> Word24 -> Bool
inRange (Word24
m,Word24
n) Word24
i     = Word24
m forall a. Ord a => a -> a -> Bool
<= Word24
i Bool -> Bool -> Bool
&& Word24
i forall a. Ord a => a -> a -> Bool
<= Word24
n

instance Read Word24 where
  readsPrec :: Int -> ReadS Word24
readsPrec Int
p String
s = [(forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
x::Int), String
r) | (Int
x, String
r) <- 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#) = 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 forall a. Integral a => a -> a -> a
`mod` Int
24
    bitSizeMaybe :: Word24 -> Maybe Int
bitSizeMaybe Word24
i            = forall a. a -> Maybe a
Just (forall b. FiniteBits b => b -> Int
finiteBitSize Word24
i)
    bitSize :: Word24 -> Int
bitSize                   = 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                       = forall a. (Bits a, Num a) => Int -> a
bitDefault
    testBit :: Word24 -> Int -> Bool
testBit                   = 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' = forall a b. Ptr a -> Ptr b
castPtr Ptr Word24
p :: Ptr Word8
  Word8
w1 <- forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Word8
p' Int
0
  Word8
w2 <- forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Word8
p' Int
1
  Word8
w3 <- forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Word8
p' Int
2
  let w1' :: Word24
w1' = (forall a b. (Integral a, Num b) => a -> b
fromIntegral :: (Word8 -> Word24)) Word8
w1
      w2' :: Word24
w2' = (forall a b. (Integral a, Num b) => a -> b
fromIntegral :: (Word8 -> Word24)) Word8
w2
      w3' :: Word24
w3' = (forall a b. (Integral a, Num b) => a -> b
fromIntegral :: (Word8 -> Word24)) Word8
w3
      w :: Word24
w = Word24
w1' forall a. Bits a => a -> a -> a
.|. (Word24
w2' forall a. Bits a => a -> Int -> a
`shiftL` Int
8) forall a. Bits a => a -> a -> a
.|. (Word24
w3' forall a. Bits a => a -> Int -> a
`shiftL` Int
16)
  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 = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word24
v forall a. Bits a => a -> a -> a
.&. Word24
0x0000FF) :: Word8
        w2 :: Word8
w2 = forall a b. (Integral a, Num b) => a -> b
fromIntegral ((Word24
v forall a. Bits a => a -> a -> a
.&. Word24
0x00FF00) forall a. Bits a => a -> Int -> a
`shiftR` Int
8) :: Word8
        w3 :: Word8
w3 = forall a b. (Integral a, Num b) => a -> b
fromIntegral ((Word24
v forall a. Bits a => a -> a -> a
.&. Word24
0xFF0000) forall a. Bits a => a -> Int -> a
`shiftR` Int
16) :: Word8
    forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr Word24
p Int
0 Word8
w1
    forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr Word24
p Int
1 Word8
w2
    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