{-# LANGUAGE CPP #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module TextShow.Data.Integral (
showbIntegralPrec
, showbIntAtBase
, showbBin
, showbHex
, showbOct
) where
import Data.Char (intToDigit)
import Data.Int (Int8, Int16, Int32, Int64)
import Data.Text.Lazy.Builder (Builder, singleton)
import Data.Text.Lazy.Builder.Int (decimal)
import Data.Word (Word8, Word16, Word32, Word64)
import GHC.Exts (Int(I#), (<#), (>#))
#if __GLASGOW_HASKELL__ >= 708
import GHC.Exts (Int#, isTrue#)
#endif
import Prelude ()
import Prelude.Compat
import TextShow.Classes (TextShow(..))
import TextShow.Utils (toString)
showbIntegralPrec :: Integral a => Int -> a -> Builder
showbIntegralPrec :: Int -> a -> Builder
showbIntegralPrec p :: Int
p = Int -> Integer -> Builder
forall a. TextShow a => Int -> a -> Builder
showbPrec Int
p (Integer -> Builder) -> (a -> Integer) -> a -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Integer
forall a. Integral a => a -> Integer
toInteger
{-# INLINE showbIntegralPrec #-}
showbIntAtBase :: (Integral a, TextShow a) => a -> (Int -> Char) -> a -> Builder
{-# SPECIALIZE showbIntAtBase :: Int -> (Int -> Char) -> Int -> Builder #-}
{-# SPECIALIZE showbIntAtBase :: Int8 -> (Int -> Char) -> Int8 -> Builder #-}
{-# SPECIALIZE showbIntAtBase :: Int16 -> (Int -> Char) -> Int16 -> Builder #-}
{-# SPECIALIZE showbIntAtBase :: Int32 -> (Int -> Char) -> Int32 -> Builder #-}
{-# SPECIALIZE showbIntAtBase :: Int64 -> (Int -> Char) -> Int64 -> Builder #-}
{-# SPECIALIZE showbIntAtBase :: Integer -> (Int -> Char) -> Integer -> Builder #-}
{-# SPECIALIZE showbIntAtBase :: Word -> (Int -> Char) -> Word -> Builder #-}
{-# SPECIALIZE showbIntAtBase :: Word8 -> (Int -> Char) -> Word8 -> Builder #-}
{-# SPECIALIZE showbIntAtBase :: Word16 -> (Int -> Char) -> Word16 -> Builder #-}
{-# SPECIALIZE showbIntAtBase :: Word32 -> (Int -> Char) -> Word32 -> Builder #-}
{-# SPECIALIZE showbIntAtBase :: Word64 -> (Int -> Char) -> Word64 -> Builder #-}
showbIntAtBase :: a -> (Int -> Char) -> a -> Builder
showbIntAtBase base :: a
base toChr :: Int -> Char
toChr n0 :: a
n0
| a
base a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= 1 = [Char] -> Builder
forall a. HasCallStack => [Char] -> a
error ([Char] -> Builder) -> (Builder -> [Char]) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> [Char]
toString (Builder -> Builder) -> Builder -> Builder
forall a b. (a -> b) -> a -> b
$ "TextShow.Int.showbIntAtBase: applied to unsupported base" Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> a -> Builder
forall a. TextShow a => a -> Builder
showb a
base
| a
n0 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< 0 = [Char] -> Builder
forall a. HasCallStack => [Char] -> a
error ([Char] -> Builder) -> (Builder -> [Char]) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> [Char]
toString (Builder -> Builder) -> Builder -> Builder
forall a b. (a -> b) -> a -> b
$ "TextShow.Int.showbIntAtBase: applied to negative number " Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> a -> Builder
forall a. TextShow a => a -> Builder
showb a
n0
| Bool
otherwise = (a, a) -> Builder -> Builder
showbIt (a -> a -> (a, a)
forall a. Integral a => a -> a -> (a, a)
quotRem a
n0 a
base) Builder
forall a. Monoid a => a
mempty
where
showbIt :: (a, a) -> Builder -> Builder
showbIt (n :: a
n, d :: a
d) b :: Builder
b = Char -> Builder -> Builder
forall a b. a -> b -> b
seq Char
c (Builder -> Builder) -> Builder -> Builder
forall a b. (a -> b) -> a -> b
$
case a
n of
0 -> Builder
b'
_ -> (a, a) -> Builder -> Builder
showbIt (a -> a -> (a, a)
forall a. Integral a => a -> a -> (a, a)
quotRem a
n a
base) Builder
b'
where
c :: Char
c :: Char
c = Int -> Char
toChr (Int -> Char) -> Int -> Char
forall a b. (a -> b) -> a -> b
$ a -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
d
b' :: Builder
b' :: Builder
b' = Char -> Builder
singleton Char
c Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
b
showbBin :: (Integral a, TextShow a) => a -> Builder
showbBin :: a -> Builder
showbBin = a -> (Int -> Char) -> a -> Builder
forall a.
(Integral a, TextShow a) =>
a -> (Int -> Char) -> a -> Builder
showbIntAtBase 2 Int -> Char
intToDigit
{-# INLINE showbBin #-}
showbHex :: (Integral a, TextShow a) => a -> Builder
showbHex :: a -> Builder
showbHex = a -> (Int -> Char) -> a -> Builder
forall a.
(Integral a, TextShow a) =>
a -> (Int -> Char) -> a -> Builder
showbIntAtBase 16 Int -> Char
intToDigit
{-# INLINE showbHex #-}
showbOct :: (Integral a, TextShow a) => a -> Builder
showbOct :: a -> Builder
showbOct = a -> (Int -> Char) -> a -> Builder
forall a.
(Integral a, TextShow a) =>
a -> (Int -> Char) -> a -> Builder
showbIntAtBase 8 Int -> Char
intToDigit
{-# INLINE showbOct #-}
instance TextShow Int where
showbPrec :: Int -> Int -> Builder
showbPrec (I# p :: Int#
p) n' :: Int
n'@(I# n :: Int#
n)
| Int# -> Bool
isTrue (Int#
n Int# -> Int# -> Int#
<# 0#) Bool -> Bool -> Bool
&& Int# -> Bool
isTrue (Int#
p Int# -> Int# -> Int#
># 6#)
= Char -> Builder
singleton '(' Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Int -> Builder
forall a. Integral a => a -> Builder
decimal Int
n' Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Char -> Builder
singleton ')'
| Bool
otherwise
= Int -> Builder
forall a. Integral a => a -> Builder
decimal Int
n'
where
#if __GLASGOW_HASKELL__ >= 708
isTrue :: Int# -> Bool
isTrue :: Int# -> Bool
isTrue b :: Int#
b = Int# -> Bool
isTrue# Int#
b
#else
isTrue :: Bool -> Bool
isTrue = id
#endif
instance TextShow Int8 where
showbPrec :: Int -> Int8 -> Builder
showbPrec p :: Int
p x :: Int8
x = Int -> Int -> Builder
forall a. TextShow a => Int -> a -> Builder
showbPrec Int
p (Int8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int8
x :: Int)
{-# INLINE showbPrec #-}
instance TextShow Int16 where
showbPrec :: Int -> Int16 -> Builder
showbPrec p :: Int
p x :: Int16
x = Int -> Int -> Builder
forall a. TextShow a => Int -> a -> Builder
showbPrec Int
p (Int16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int16
x :: Int)
{-# INLINE showbPrec #-}
instance TextShow Int32 where
showbPrec :: Int -> Int32 -> Builder
showbPrec p :: Int
p x :: Int32
x = Int -> Int -> Builder
forall a. TextShow a => Int -> a -> Builder
showbPrec Int
p (Int32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
x :: Int)
{-# INLINE showbPrec #-}
instance TextShow Int64 where
#if WORD_SIZE_IN_BITS < 64
showbPrec :: Int -> Int64 -> Builder
showbPrec p :: Int
p = Int -> Integer -> Builder
forall a. TextShow a => Int -> a -> Builder
showbPrec Int
p (Integer -> Builder) -> (Int64 -> Integer) -> Int64 -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> Integer
forall a. Integral a => a -> Integer
toInteger
#else
showbPrec p x = showbPrec p (fromIntegral x :: Int)
#endif
{-# INLINE showbPrec #-}
instance TextShow Integer where
showbPrec :: Int -> Integer -> Builder
showbPrec p :: Int
p n :: Integer
n
| Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> 6 Bool -> Bool -> Bool
&& Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< 0 = Char -> Builder
singleton '(' Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Integer -> Builder
forall a. Integral a => a -> Builder
decimal Integer
n Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Char -> Builder
singleton ')'
| Bool
otherwise = Integer -> Builder
forall a. Integral a => a -> Builder
decimal Integer
n
{-# INLINE showbPrec #-}
instance TextShow Word where
showb :: Word -> Builder
showb = Word -> Builder
forall a. Integral a => a -> Builder
decimal
{-# INLINE showb #-}
instance TextShow Word8 where
showb :: Word8 -> Builder
showb = Word8 -> Builder
forall a. Integral a => a -> Builder
decimal
{-# INLINE showb #-}
instance TextShow Word16 where
showb :: Word16 -> Builder
showb = Word16 -> Builder
forall a. Integral a => a -> Builder
decimal
{-# INLINE showb #-}
instance TextShow Word32 where
showb :: Word32 -> Builder
showb = Word32 -> Builder
forall a. Integral a => a -> Builder
decimal
{-# INLINE showb #-}
instance TextShow Word64 where
showb :: Word64 -> Builder
showb = Word64 -> Builder
forall a. Integral a => a -> Builder
decimal
{-# INLINE showb #-}