summaryrefslogtreecommitdiff
path: root/Data
diff options
context:
space:
mode:
authorRaphaelJavaux <>2014-04-16 22:11:00 (GMT)
committerhdiff <hdiff@hdiff.luite.com>2014-04-16 22:11:00 (GMT)
commita677ea01a1a27d4ce4d86602dc3ba685cb772b8f (patch)
treec379b3137628ccb51a71c3626d68bd474e291c10 /Data
parent693b1a852ca56fe37806f966c4cef0bbca0d62d1 (diff)
version 0.1.10.1.1
Diffstat (limited to 'Data')
-rw-r--r--Data/RatioInt.hs21
1 files changed, 21 insertions, 0 deletions
diff --git a/Data/RatioInt.hs b/Data/RatioInt.hs
index 30a0651..7c50954 100644
--- a/Data/RatioInt.hs
+++ b/Data/RatioInt.hs
@@ -1,11 +1,16 @@
{-# LANGUAGE BangPatterns #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
-- | Provides a specialised version of 'Data.Ratio' for 'Int'.
--
-- Runs about ten times faster than 'Data.Ratio' while being half as fast as
-- floating-point types.
module Data.RatioInt (RatioInt (numerator, denominator), (%)) where
+import Control.Applicative ((<$>), (<*>))
import qualified Data.Ratio as R
+import Foreign.Ptr (castPtr, plusPtr)
+import Foreign.Storable (Storable (..))
-- | Rational numbers, with numerator and denominator of the 'Int' type.
data RatioInt = RatioInt {
@@ -76,3 +81,19 @@ instance Enum RatioInt where
mid = (m - n) / 2
predicate | m >= n = (<= p + mid)
| otherwise = (>= p + mid)
+
+instance Storable RatioInt where
+ sizeOf _ = let !sizeOfInt = sizeOf (undefined :: Int)
+ in sizeOfInt + sizeOfInt
+ {-# INLINE sizeOf #-}
+
+ alignment _ = alignment (undefined :: Int)
+ {-# INLINE alignment #-}
+
+ peek !ptr = let !ptr' = castPtr ptr
+ in RatioInt <$> peek ptr' <*> peek (ptr' `plusPtr` 1)
+ {-# INLINE peek #-}
+
+ poke !ptr !(RatioInt x y) = let !ptr' = castPtr ptr
+ in poke ptr' x >> poke (ptr' `plusPtr` 1) y
+ {-# INLINE poke #-}