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

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

-----------------------------------------------------------------------------
-- |
-- Module      :  Data.Int.Int24
-- Copyright   :  (c) The University of Glasgow 1997-2002
-- License     :  see src/Data/LICENSE
--
-- Stability   :  experimental
-- Portability :  non-portable (GHC Extensions)
--
-- The 24 bit integral datatype, 'Int24'.
--
-----------------------------------------------------------------------------

module Data.Int.Int24 (
  -- * Int24 type
  Int24(..)
  -- * Internal helper
  , narrow24Int#
  ) where

import           Data.Bits
import           Data.Data
import           Data.Maybe
import           Data.Word.Word24
import           Foreign.Storable

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

import           Control.DeepSeq

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

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

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

-- | 24-bit signed integer type
data Int24 = I24# Int# deriving (Int24 -> Int24 -> Bool
(Int24 -> Int24 -> Bool) -> (Int24 -> Int24 -> Bool) -> Eq Int24
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Int24 -> Int24 -> Bool
== :: Int24 -> Int24 -> Bool
$c/= :: Int24 -> Int24 -> Bool
/= :: Int24 -> Int24 -> Bool
Eq, Eq Int24
Eq Int24 =>
(Int24 -> Int24 -> Ordering)
-> (Int24 -> Int24 -> Bool)
-> (Int24 -> Int24 -> Bool)
-> (Int24 -> Int24 -> Bool)
-> (Int24 -> Int24 -> Bool)
-> (Int24 -> Int24 -> Int24)
-> (Int24 -> Int24 -> Int24)
-> Ord Int24
Int24 -> Int24 -> Bool
Int24 -> Int24 -> Ordering
Int24 -> Int24 -> Int24
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 :: Int24 -> Int24 -> Ordering
compare :: Int24 -> Int24 -> Ordering
$c< :: Int24 -> Int24 -> Bool
< :: Int24 -> Int24 -> Bool
$c<= :: Int24 -> Int24 -> Bool
<= :: Int24 -> Int24 -> Bool
$c> :: Int24 -> Int24 -> Bool
> :: Int24 -> Int24 -> Bool
$c>= :: Int24 -> Int24 -> Bool
>= :: Int24 -> Int24 -> Bool
$cmax :: Int24 -> Int24 -> Int24
max :: Int24 -> Int24 -> Int24
$cmin :: Int24 -> Int24 -> Int24
min :: Int24 -> Int24 -> Int24
Ord)

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

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

int24Type :: DataType
int24Type :: DataType
int24Type = String -> DataType
mkIntType String
"Data.Word.Int24.Int24"

instance Data Int24 where
  toConstr :: Int24 -> Constr
toConstr Int24
x = DataType -> Int24 -> Constr
forall a. (Integral a, Show a) => DataType -> a -> Constr
mkIntegralConstr DataType
int24Type Int24
x
  gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Int24
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) -> Int24 -> c Int24
forall r. r -> c r
z (Integer -> Int24
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
x)
                    ConstrRep
_ -> String -> c Int24
forall a. HasCallStack => String -> a
error (String -> c Int24) -> String -> c Int24
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 Int24."
  dataTypeOf :: Int24 -> DataType
dataTypeOf Int24
_ = DataType
int24Type

-- the narrowings are primops in GHC; I don't have that luxury.
-- if the 24th bit (from right) is on, the value is negative, so
-- fill the uppermost bits with 1s.  Otherwise clear them to 0s.
narrow24Int# :: Int# -> Int#
narrow24Int# :: Int# -> Int#
narrow24Int# Int#
x# = if Int# -> Bool
isTrue# ((Word#
x'# Word# -> Word# -> Word#
`and#` Word#
mask#) Word# -> Word# -> Int#
`eqWord#` Word#
mask#)
    then Word# -> Int#
word2Int# (Word#
x'# Word# -> Word# -> Word#
`or#`  Int# -> Word#
int2Word# Int#
m1#)
    else Word# -> Int#
word2Int# (Word#
x'# Word# -> Word# -> Word#
`and#` Int# -> Word#
int2Word# Int#
m2#)
  where
    !x'# :: Word#
x'#   = Int# -> Word#
int2Word# Int#
x#
    !mask# :: Word#
mask# = Int# -> Word#
int2Word# Int#
0x00800000#
    !(I# Int#
m1#) = -Int
8388608
    !(I# Int#
m2#) = Int
16777215

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

instance Num Int24 where
    (I24# Int#
x#) + :: Int24 -> Int24 -> Int24
+ (I24# Int#
y#)  = Int# -> Int24
I24# (Int# -> Int#
narrow24Int# (Int#
x# Int# -> Int# -> Int#
+# Int#
y#))
    (I24# Int#
x#) - :: Int24 -> Int24 -> Int24
- (I24# Int#
y#)  = Int# -> Int24
I24# (Int# -> Int#
narrow24Int# (Int#
x# Int# -> Int# -> Int#
-# Int#
y#))
    (I24# Int#
x#) * :: Int24 -> Int24 -> Int24
* (I24# Int#
y#)  = Int# -> Int24
I24# (Int# -> Int#
narrow24Int# (Int#
x# Int# -> Int# -> Int#
*# Int#
y#))
    negate :: Int24 -> Int24
negate (I24# Int#
x#)       = Int# -> Int24
I24# (Int# -> Int#
narrow24Int# (Int# -> Int#
negateInt# Int#
x#))
    abs :: Int24 -> Int24
abs Int24
x | Int24
x Int24 -> Int24 -> Bool
forall a. Ord a => a -> a -> Bool
>= Int24
0         = Int24
x
          | Bool
otherwise      = Int24 -> Int24
forall a. Num a => a -> a
negate Int24
x
    signum :: Int24 -> Int24
signum Int24
x | Int24
x Int24 -> Int24 -> Bool
forall a. Ord a => a -> a -> Bool
> Int24
0       = Int24
1
    signum Int24
0               = Int24
0
    signum Int24
_               = -Int24
1
    fromInteger :: Integer -> Int24
fromInteger Integer
i          = Int# -> Int24
I24# (Int# -> Int#
narrow24Int# (Integer -> Int#
integerToInt Integer
i))

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

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

instance Integral Int24 where
    quot :: Int24 -> Int24 -> Int24
quot    x :: Int24
x@(I24# Int#
x#) y :: Int24
y@(I24# Int#
y#)
        | Int24
y Int24 -> Int24 -> Bool
forall a. Eq a => a -> a -> Bool
== Int24
0                     = Int24
forall a. a
divZeroError
        | Int24
x Int24 -> Int24 -> Bool
forall a. Eq a => a -> a -> Bool
== Int24
forall a. Bounded a => a
minBound Bool -> Bool -> Bool
&& Int24
y Int24 -> Int24 -> Bool
forall a. Eq a => a -> a -> Bool
== (-Int24
1) = Int24
forall a. a
overflowError
        | Bool
otherwise                  = Int# -> Int24
I24# (Int# -> Int#
narrow24Int# (Int#
x# Int# -> Int# -> Int#
`quotInt#` Int#
y#))
    rem :: Int24 -> Int24 -> Int24
rem     x :: Int24
x@(I24# Int#
x#) y :: Int24
y@(I24# Int#
y#)
        | Int24
y Int24 -> Int24 -> Bool
forall a. Eq a => a -> a -> Bool
== Int24
0                     = Int24
forall a. a
divZeroError
        | Int24
x Int24 -> Int24 -> Bool
forall a. Eq a => a -> a -> Bool
== Int24
forall a. Bounded a => a
minBound Bool -> Bool -> Bool
&& Int24
y Int24 -> Int24 -> Bool
forall a. Eq a => a -> a -> Bool
== (-Int24
1) = Int24
forall a. a
overflowError
        | Bool
otherwise                  = Int# -> Int24
I24# (Int# -> Int#
narrow24Int# (Int#
x# Int# -> Int# -> Int#
`remInt#` Int#
y#))
    div :: Int24 -> Int24 -> Int24
div     x :: Int24
x@(I24# Int#
x#) y :: Int24
y@(I24# Int#
y#)
        | Int24
y Int24 -> Int24 -> Bool
forall a. Eq a => a -> a -> Bool
== Int24
0                     = Int24
forall a. a
divZeroError
        | Int24
x Int24 -> Int24 -> Bool
forall a. Eq a => a -> a -> Bool
== Int24
forall a. Bounded a => a
minBound Bool -> Bool -> Bool
&& Int24
y Int24 -> Int24 -> Bool
forall a. Eq a => a -> a -> Bool
== (-Int24
1) = Int24
forall a. a
overflowError
        | Bool
otherwise                  = Int# -> Int24
I24# (Int# -> Int#
narrow24Int# (Int#
x# Int# -> Int# -> Int#
`divInt#` Int#
y#))
    mod :: Int24 -> Int24 -> Int24
mod     x :: Int24
x@(I24# Int#
x#) y :: Int24
y@(I24# Int#
y#)
        | Int24
y Int24 -> Int24 -> Bool
forall a. Eq a => a -> a -> Bool
== Int24
0                     = Int24
forall a. a
divZeroError
        | Int24
x Int24 -> Int24 -> Bool
forall a. Eq a => a -> a -> Bool
== Int24
forall a. Bounded a => a
minBound Bool -> Bool -> Bool
&& Int24
y Int24 -> Int24 -> Bool
forall a. Eq a => a -> a -> Bool
== (-Int24
1) = Int24
forall a. a
overflowError
        | Bool
otherwise                  = Int# -> Int24
I24# (Int# -> Int#
narrow24Int# (Int#
x# Int# -> Int# -> Int#
`modInt#` Int#
y#))
    quotRem :: Int24 -> Int24 -> (Int24, Int24)
quotRem x :: Int24
x@(I24# Int#
x#) y :: Int24
y@(I24# Int#
y#)
        | Int24
y Int24 -> Int24 -> Bool
forall a. Eq a => a -> a -> Bool
== Int24
0                     = (Int24, Int24)
forall a. a
divZeroError
        | Int24
x Int24 -> Int24 -> Bool
forall a. Eq a => a -> a -> Bool
== Int24
forall a. Bounded a => a
minBound Bool -> Bool -> Bool
&& Int24
y Int24 -> Int24 -> Bool
forall a. Eq a => a -> a -> Bool
== (-Int24
1) = (Int24, Int24)
forall a. a
overflowError
        | Bool
otherwise                  = (Int# -> Int24
I24# (Int# -> Int#
narrow24Int# (Int#
x# Int# -> Int# -> Int#
`quotInt#` Int#
y#)),
                                        Int# -> Int24
I24# (Int# -> Int#
narrow24Int# (Int#
x# Int# -> Int# -> Int#
`remInt#` Int#
y#)))
    divMod :: Int24 -> Int24 -> (Int24, Int24)
divMod  x :: Int24
x@(I24# Int#
x#) y :: Int24
y@(I24# Int#
y#)
        | Int24
y Int24 -> Int24 -> Bool
forall a. Eq a => a -> a -> Bool
== Int24
0                     = (Int24, Int24)
forall a. a
divZeroError
        | Int24
x Int24 -> Int24 -> Bool
forall a. Eq a => a -> a -> Bool
== Int24
forall a. Bounded a => a
minBound Bool -> Bool -> Bool
&& Int24
y Int24 -> Int24 -> Bool
forall a. Eq a => a -> a -> Bool
== (-Int24
1) = (Int24, Int24)
forall a. a
overflowError
        | Bool
otherwise                  = (Int# -> Int24
I24# (Int# -> Int#
narrow24Int# (Int#
x# Int# -> Int# -> Int#
`divInt#` Int#
y#)),
                                        Int# -> Int24
I24# (Int# -> Int#
narrow24Int# (Int#
x# Int# -> Int# -> Int#
`modInt#` Int#
y#)))
    toInteger :: Int24 -> Integer
toInteger (I24# Int#
x#)              = Int# -> Integer
smallInteger Int#
x#

instance Bounded Int24 where
    minBound :: Int24
minBound = -Int24
0x800000
    maxBound :: Int24
maxBound =  Int24
0x7FFFFF

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

instance Read Int24 where
    readsPrec :: Int -> ReadS Int24
readsPrec Int
p String
s = [(Int -> Int24
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 Int24 where
    {-# INLINE shift #-}
    {-# INLINE bit #-}
    {-# INLINE testBit #-}

    (I24# Int#
x#) .&. :: Int24 -> Int24 -> Int24
.&.   (I24# Int#
y#)  = Int# -> Int24
I24# (Word# -> Int#
word2Int# (Int# -> Word#
int2Word# Int#
x# Word# -> Word# -> Word#
`and#` Int# -> Word#
int2Word# Int#
y#))
    (I24# Int#
x#) .|. :: Int24 -> Int24 -> Int24
.|.   (I24# Int#
y#)  = Int# -> Int24
I24# (Word# -> Int#
word2Int# (Int# -> Word#
int2Word# Int#
x# Word# -> Word# -> Word#
`or#`  Int# -> Word#
int2Word# Int#
y#))
    (I24# Int#
x#) xor :: Int24 -> Int24 -> Int24
`xor` (I24# Int#
y#)  = Int# -> Int24
I24# (Word# -> Int#
word2Int# (Int# -> Word#
int2Word# Int#
x# Word# -> Word# -> Word#
`xor#` Int# -> Word#
int2Word# Int#
y#))
    complement :: Int24 -> Int24
complement (I24# Int#
x#)       = Int# -> Int24
I24# (Word# -> Int#
word2Int# (Word# -> Word#
not# (Int# -> Word#
int2Word# Int#
x#)))
    (I24# Int#
x#) shift :: Int24 -> Int -> Int24
`shift` (I# Int#
i#)
        | Int# -> Bool
isTrue# (Int#
i# Int# -> Int# -> Int#
>=# Int#
0#)  = Int# -> Int24
I24# (Int# -> Int#
narrow24Int# (Int#
x# Int# -> Int# -> Int#
`iShiftL#` Int#
i#))
        | Bool
otherwise            = Int# -> Int24
I24# (Int#
x# Int# -> Int# -> Int#
`iShiftRA#` Int# -> Int#
negateInt# Int#
i#)
    (I24# Int#
x#) shiftL :: Int24 -> Int -> Int24
`shiftL`       (I# Int#
i#) = Int# -> Int24
I24# (Int# -> Int#
narrow24Int# (Int#
x# Int# -> Int# -> Int#
`iShiftL#` Int#
i#))
    (I24# Int#
x#) unsafeShiftL :: Int24 -> Int -> Int24
`unsafeShiftL` (I# Int#
i#) = Int# -> Int24
I24# (Int# -> Int#
narrow24Int# (Int#
x# Int# -> Int# -> Int#
`uncheckedIShiftL#` Int#
i#))
    (I24# Int#
x#) shiftR :: Int24 -> Int -> Int24
`shiftR`       (I# Int#
i#) = Int# -> Int24
I24# (Int#
x# Int# -> Int# -> Int#
`iShiftRA#` Int#
i#)
    (I24# Int#
x#) unsafeShiftR :: Int24 -> Int -> Int24
`unsafeShiftR` (I# Int#
i#) = Int# -> Int24
I24# (Int#
x# Int# -> Int# -> Int#
`uncheckedIShiftRA#` Int#
i#)
    (I24# Int#
x#) rotate :: Int24 -> Int -> Int24
`rotate` Int
i
        | Int# -> Bool
isTrue# (Int#
i'# Int# -> Int# -> Int#
==# Int#
0#) = Int# -> Int24
I24# Int#
x#
        | Bool
otherwise = Int# -> Int24
I24# (Int# -> Int#
narrow24Int# (Word# -> Int#
word2Int# ((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
        !x'# :: Word#
x'# = Word# -> Word#
narrow24Word# (Int# -> Word#
int2Word# Int#
x#)
        !(I# Int#
i'#) = Int
i Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
24
    bitSizeMaybe :: Int24 -> Maybe Int
bitSizeMaybe Int24
i             = Int -> Maybe Int
forall a. a -> Maybe a
Just (Int24 -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize Int24
i)
    bitSize :: Int24 -> Int
bitSize                    = Int24 -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize
    isSigned :: Int24 -> Bool
isSigned Int24
_                 = Bool
True
    popCount :: Int24 -> Int
popCount (I24# Int#
x#)         = Int# -> Int
I# (Word# -> Int#
word2Int# (Word# -> Word#
popCnt24# (Int# -> Word#
int2Word# Int#
x#)))
    bit :: Int -> Int24
bit                        = Int -> Int24
forall a. (Bits a, Num a) => Int -> a
bitDefault
    testBit :: Int24 -> Int -> Bool
testBit                    = Int24 -> Int -> Bool
forall a. (Bits a, Num a) => a -> Int -> Bool
testBitDefault

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

{-# RULES
"fromIntegral/Word8->Int24"   fromIntegral = \(W8# x#) -> I24# (word2Int# x#)
"fromIntegral/Word16->Int24"  fromIntegral = \(W16# x#) -> I24# (word2Int# x#)
"fromIntegral/Int8->Int24"    fromIntegral = \(I8# x#) -> I24# x#
"fromIntegral/Int16->Int24"   fromIntegral = \(I16# x#) -> I24# x#
"fromIntegral/Int24->Int24"   fromIntegral = id :: Int24 -> Int24
"fromIntegral/a->Int24"       fromIntegral = \x -> case fromIntegral x of I# x# -> I24# (narrow24Int# x#)
"fromIntegral/Int24->a"       fromIntegral = \(I24# x#) -> fromIntegral (I# x#)
  #-}

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

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

instance Storable Int24 where
  sizeOf :: Int24 -> Int
sizeOf Int24
_ = Int
3
  alignment :: Int24 -> Int
alignment Int24
_ = Int
3
  peek :: Ptr Int24 -> IO Int24
peek Ptr Int24
p = (Word24 -> Int24) -> IO Word24 -> IO Int24
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Word24 -> Int24
forall a b. (Integral a, Num b) => a -> b
fromIntegral (IO Word24 -> IO Int24) -> IO Word24 -> IO Int24
forall a b. (a -> b) -> a -> b
$ Ptr Word24 -> IO Word24
forall a. Storable a => Ptr a -> IO a
peek ((Ptr Int24 -> Ptr Word24
forall a b. Ptr a -> Ptr b
castPtr Ptr Int24
p) :: Ptr Word24)
  poke :: Ptr Int24 -> Int24 -> IO ()
poke Ptr Int24
p Int24
v = Ptr Word24 -> Word24 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke (Ptr Int24 -> Ptr Word24
forall a b. Ptr a -> Ptr b
castPtr Ptr Int24
p :: Ptr Word24) (Int24 -> Word24
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int24
v)