@@ -1,6 +1,6 @@
1{-# LANGUAGE BangPatterns, CPP, MagicHash, UnboxedTuples #-}
1{-# LANGUAGE BangPatterns, CPP, MagicHash, UnboxedTuples #-}
3−-- Module: Data.Text.Lazy.Builder.Int
3+-- Module: Data.Text.Lazy.Builder.Intxo
4-- Copyright: (c) 2011 MailRank, Inc.
4-- Copyright: (c) 2011 MailRank, Inc.
5-- License: BSD3
5-- License: BSD3
6-- Maintainer: Bryan O'Sullivan <bos@serpentine.com>
6-- Maintainer: Bryan O'Sullivan <bos@serpentine.com>
@@ -19,6 +19,7 @@ import Data.Int (Int8, Int16, Int32, Int64)
19import Data.Monoid (mempty)
19import Data.Monoid (mempty)
20import Data.Text.Lazy.Builder.Functions ((<>), i2d)
20import Data.Text.Lazy.Builder.Functions ((<>), i2d)
21import Data.Text.Lazy.Builder
21import Data.Text.Lazy.Builder
22+import Data.Text.Lazy (pack)
22import Data.Word (Word, Word8, Word16, Word32, Word64)
23import Data.Word (Word, Word8, Word16, Word32, Word64)
23import GHC.Base (quotInt, remInt)
24import GHC.Base (quotInt, remInt)
24import GHC.Num (quotRemInteger)
25import GHC.Num (quotRemInteger)
@@ -43,23 +44,51 @@ import GHC.Integer
45decimal :: Integral a => a -> Builder
46decimal :: Integral a => a -> Builder
46−{-# SPECIALIZE decimal :: Int -> Builder #-}
47{-# SPECIALIZE decimal :: Int8 -> Builder #-}
47{-# SPECIALIZE decimal :: Int8 -> Builder #-}
48−{-# SPECIALIZE decimal :: Int16 -> Builder #-}
48+{-# RULES "decimal/Int" decimal = boundedDecimal :: Int -> Builder #-}
49+{-# RULES "decimal/Int16" decimal = boundedDecimal :: Int16 -> Builder #-}
49−{-# SPECIALIZE decimal :: Int32 -> Builder #-}
50+{-# RULES "decimal/Int32" decimal = boundedDecimal :: Int32 -> Builder #-}
50−{-# SPECIALIZE decimal :: Int64 -> Builder #-}
51+{-# RULES "decimal/Int64" decimal = boundedDecimal :: Int64 -> Builder #-}
51−{-# SPECIALIZE decimal :: Word -> Builder #-}
52+{-# RULES "decimal/Word" decimal = positive :: Word -> Builder #-}
52−{-# SPECIALIZE decimal :: Word8 -> Builder #-}
53+{-# RULES "decimal/Word8" decimal = positive :: Word8 -> Builder #-}
53−{-# SPECIALIZE decimal :: Word16 -> Builder #-}
54+{-# RULES "decimal/Word16" decimal = positive :: Word16 -> Builder #-}
54−{-# SPECIALIZE decimal :: Word32 -> Builder #-}
55+{-# RULES "decimal/Word32" decimal = positive :: Word32 -> Builder #-}
55−{-# SPECIALIZE decimal :: Word64 -> Builder #-}
56+{-# RULES "decimal/Word64" decimal = positive :: Word64 -> Builder #-}
56{-# RULES "decimal/Integer" decimal = integer 10 :: Integer -> Builder #-}
57{-# RULES "decimal/Integer" decimal = integer 10 :: Integer -> Builder #-}
59+ | i < 0 = singleton '-' <>
61+ then positive (-(i `quot` 10)) <> digit (-(i `rem` 10))
63+ | otherwise = positive i
65+boundedDecimal :: (Integral a, Bounded a) => a -> Builder
66+{-# SPECIALIZE boundedDecimal :: Int -> Builder #-}
67+{-# SPECIALIZE boundedDecimal :: Int8 -> Builder #-}
68+{-# SPECIALIZE boundedDecimal :: Int16 -> Builder #-}
69+{-# SPECIALIZE boundedDecimal :: Int32 -> Builder #-}
70+{-# SPECIALIZE boundedDecimal :: Int64 -> Builder #-}
58− | i < 0 = singleton '-' <> go (-i)
72+ | i < 0 = singleton '-' <>
74+ then positive (-(i `quot` 10)) <> digit (-(i `rem` 10))
59− | otherwise = go i
76+ | otherwise = positive i
78+positive :: (Integral a) => a -> Builder
79+{-# SPECIALIZE positive :: Int -> Builder #-}
80+{-# SPECIALIZE positive :: Int8 -> Builder #-}
81+{-# SPECIALIZE positive :: Int16 -> Builder #-}
82+{-# SPECIALIZE positive :: Int32 -> Builder #-}
83+{-# SPECIALIZE positive :: Int64 -> Builder #-}
84+{-# SPECIALIZE positive :: Word -> Builder #-}
85+{-# SPECIALIZE positive :: Word8 -> Builder #-}
86+{-# SPECIALIZE positive :: Word16 -> Builder #-}
87+{-# SPECIALIZE positive :: Word32 -> Builder #-}
88+{-# SPECIALIZE positive :: Word64 -> Builder #-}
61− go n | n < 10 = digit n
90+ where go n | n < 10 = digit n
62− | otherwise = go (n `quot` 10) <> digit (n `rem` 10)
91+ | otherwise = go (n `quot` 10) <> digit (n `rem` 10)
64hexadecimal :: Integral a => a -> Builder
93hexadecimal :: Integral a => a -> Builder
65{-# SPECIALIZE hexadecimal :: Int -> Builder #-}
94{-# SPECIALIZE hexadecimal :: Int -> Builder #-}
@@ -74,11 +103,12 @@ hexadecimal :: Integral a => a -> Builder
74{-# SPECIALIZE hexadecimal :: Word64 -> Builder #-}
103{-# SPECIALIZE hexadecimal :: Word64 -> Builder #-}
75{-# RULES "hexadecimal/Integer" hexadecimal = integer 16 :: Integer -> Builder #-}
104{-# RULES "hexadecimal/Integer" hexadecimal = integer 16 :: Integer -> Builder #-}
76hexadecimal i
105hexadecimal i
77− | i < 0 = singleton '-' <> go (-i)
106+ | i < 0 = error msg
78 | otherwise = go i
107 | otherwise = go i
80 go n | n < 16 = hexDigit n
109 go n | n < 16 = hexDigit n
81 | otherwise = go (n `quot` 16) <> hexDigit (n `rem` 16)
110 | otherwise = go (n `quot` 16) <> hexDigit (n `rem` 16)
111+ msg = "Data.Text.Lazy.Builder.Int.hexadecimal: applied to negative number"
83digit :: Integral a => a -> Builder
113digit :: Integral a => a -> Builder
84digit n = singleton $! i2d (fromIntegral n)
114digit n = singleton $! i2d (fromIntegral n)