    {-# LANGUAGE BangPatterns, CPP, MagicHash, RankNTypes, ScopedTypeVariables,
        UnboxedTuples #-}
    {-# LANGUAGE Trustworthy #-}

    -- Module:      Data.Text.Lazy.Builder.Int
    -- Copyright:   (c) 2013 Bryan O'Sullivan
    --              (c) 2011 MailRank, Inc.
    -- License:     BSD-style
    -- Maintainer:  Bryan O'Sullivan <bos@serpentine.com>
    -- Portability: portable
    --
    -- Efficiently write an integral value to a 'Builder'.

    module Data.Text.Lazy.Builder.Int
        (
          decimal
        , hexadecimal
        ) where

    import Data.Int (Int8, Int16, Int32, Int64)
    import Data.Monoid (mempty)
    import qualified Data.ByteString.Unsafe as B
    import Data.Text.Internal.Builder.Functions ((<>), i2d)
    import Data.Text.Internal.Builder
    import Data.Text.Internal.Builder.Int.Digits (digits)
    import Data.Text.Array
    import Data.Word (Word, Word8, Word16, Word32, Word64)
    import GHC.Base (quotInt, remInt)
    import Control.Monad.ST
    #if MIN_VERSION_base(4,11,0)
    import Prelude hiding ((<>))
    #endif

    decimal :: Integral a => a -> Builder
    {-# RULES "decimal/Int8" decimal = boundedDecimal :: Int8 -> Builder #-}
    {-# RULES "decimal/Int" decimal = boundedDecimal :: Int -> Builder #-}
    {-# RULES "decimal/Int16" decimal = boundedDecimal :: Int16 -> Builder #-}
    {-# RULES "decimal/Int32" decimal = boundedDecimal :: Int32 -> Builder #-}
    {-# RULES "decimal/Int64" decimal = boundedDecimal :: Int64 -> Builder #-}
    {-# RULES "decimal/Word" decimal = positive :: Data.Word.Word -> Builder #-}
    {-# RULES "decimal/Word8" decimal = positive :: Word8 -> Builder #-}
    {-# RULES "decimal/Word16" decimal = positive :: Word16 -> Builder #-}
    {-# RULES "decimal/Word32" decimal = positive :: Word32 -> Builder #-}
    {-# RULES "decimal/Word64" decimal = positive :: Word64 -> Builder #-}
    {-# RULES "decimal/Integer" decimal = integer 10 :: Integer -> Builder #-}
    decimal :: forall a. Integral a => a -> Builder
    decimal a
    i = (a -> Bool) -> a -> Builder
    forall a. Integral a => (a -> Bool) -> a -> Builder
    decimal' (a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    <= -a
    128) a
    i
    {-# NOINLINE decimal #-}

    boundedDecimal :: (Integral a, Bounded a) => a -> Builder
    {-# SPECIALIZE boundedDecimal :: Int -> Builder #-}
    {-# SPECIALIZE boundedDecimal :: Int8 -> Builder #-}
    {-# SPECIALIZE boundedDecimal :: Int16 -> Builder #-}
    {-# SPECIALIZE boundedDecimal :: Int32 -> Builder #-}
    {-# SPECIALIZE boundedDecimal :: Int64 -> Builder #-}
    boundedDecimal :: forall a. (Integral a, Bounded a) => a -> Builder
    boundedDecimal a
    i = (a -> Bool) -> a -> Builder
    forall a. Integral a => (a -> Bool) -> a -> Builder
    decimal' (a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == a
    forall a. Bounded a => a
    minBound) a
    i

    decimal' :: (Integral a) => (a -> Bool) -> a -> Builder
    {-# INLINE decimal' #-}
    decimal' :: forall a. Integral a => (a -> Bool) -> a -> Builder
    decimal' a -> Bool
    p a
    i
        | a
    i a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    < a
    0 = if a -> Bool
    p a
    i
                  then let (a
    q, a
    r) = a
    i a -> a -> (a, a)
    forall a. Integral a => a -> a -> (a, a)
    `quotRem` a
    10
                           qq :: a
    qq = -a
    q
                           !n :: Int
    n = a -> Int
    forall a. Integral a => a -> Int
    countDigits a
    qq
                       in Int -> (forall s. MArray s -> Int -> ST s ()) -> Builder
    writeN (Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    2) ((forall s. MArray s -> Int -> ST s ()) -> Builder)
    -> (forall s. MArray s -> Int -> ST s ()) -> Builder
    forall a b. (a -> b) -> a -> b
    $ \MArray s
    marr Int
    off -> do
                           MArray s -> Int -> Word8 -> ST s ()
    forall s. MArray s -> Int -> Word8 -> ST s ()
    unsafeWrite MArray s
    marr Int
    off Word8
    minus
                           MArray s -> Int -> Int -> a -> ST s ()
    forall a s. Integral a => MArray s -> Int -> Int -> a -> ST s ()
    forall s. MArray s -> Int -> Int -> a -> ST s ()
    posDecimal MArray s
    marr (Int
    offInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    1) Int
    n a
    qq
                           MArray s -> Int -> Word8 -> ST s ()
    forall s. MArray s -> Int -> Word8 -> ST s ()
    unsafeWrite MArray s
    marr (Int
    offInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    nInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    1) (a -> Word8
    forall a. Integral a => a -> Word8
    i2w (-a
    r))
                  else let j :: a
    j = -a
    i
                           !n :: Int
    n = a -> Int
    forall a. Integral a => a -> Int
    countDigits a
    j
                       in Int -> (forall s. MArray s -> Int -> ST s ()) -> Builder
    writeN (Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1) ((forall s. MArray s -> Int -> ST s ()) -> Builder)
    -> (forall s. MArray s -> Int -> ST s ()) -> Builder
    forall a b. (a -> b) -> a -> b
    $ \MArray s
    marr Int
    off ->
                           MArray s -> Int -> Word8 -> ST s ()
    forall s. MArray s -> Int -> Word8 -> ST s ()
    unsafeWrite MArray s
    marr Int
    off Word8
    minus ST s () -> ST s () -> ST s ()
    forall a b. ST s a -> ST s b -> ST s b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> MArray s -> Int -> Int -> a -> ST s ()
    forall a s. Integral a => MArray s -> Int -> Int -> a -> ST s ()
    forall s. MArray s -> Int -> Int -> a -> ST s ()
    posDecimal MArray s
    marr (Int
    offInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    1) Int
    n a
    j
        | Bool
    otherwise = a -> Builder
    forall a. Integral a => a -> Builder
    positive a
    i

    positive :: (Integral a) => a -> Builder
    {-# SPECIALIZE positive :: Int -> Builder #-}
    {-# SPECIALIZE positive :: Int8 -> Builder #-}
    {-# SPECIALIZE positive :: Int16 -> Builder #-}
    {-# SPECIALIZE positive :: Int32 -> Builder #-}
    {-# SPECIALIZE positive :: Int64 -> Builder #-}
    {-# SPECIALIZE positive :: Word -> Builder #-}
    {-# SPECIALIZE positive :: Word8 -> Builder #-}
    {-# SPECIALIZE positive :: Word16 -> Builder #-}
    {-# SPECIALIZE positive :: Word32 -> Builder #-}
    {-# SPECIALIZE positive :: Word64 -> Builder #-}
    positive :: forall a. Integral a => a -> Builder
    positive a
    i
        | a
    i a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    < a
    10    = Int -> (forall s. MArray s -> Int -> ST s ()) -> Builder
    writeN Int
    1 ((forall s. MArray s -> Int -> ST s ()) -> Builder)
    -> (forall s. MArray s -> Int -> ST s ()) -> Builder
    forall a b. (a -> b) -> a -> b
    $ \MArray s
    marr Int
    off -> MArray s -> Int -> Word8 -> ST s ()
    forall s. MArray s -> Int -> Word8 -> ST s ()
    unsafeWrite MArray s
    marr Int
    off (a -> Word8
    forall a. Integral a => a -> Word8
    i2w a
    i)
        | Bool
    otherwise = let !n :: Int
    n = a -> Int
    forall a. Integral a => a -> Int
    countDigits a
    i
                      in Int -> (forall s. MArray s -> Int -> ST s ()) -> Builder
    writeN Int
    n ((forall s. MArray s -> Int -> ST s ()) -> Builder)
    -> (forall s. MArray s -> Int -> ST s ()) -> Builder
    forall a b. (a -> b) -> a -> b
    $ \MArray s
    marr Int
    off -> MArray s -> Int -> Int -> a -> ST s ()
    forall a s. Integral a => MArray s -> Int -> Int -> a -> ST s ()
    forall s. MArray s -> Int -> Int -> a -> ST s ()
    posDecimal MArray s
    marr Int
    off Int
    n a
    i

    posDecimal :: (Integral a) =>
                  forall s. MArray s -> Int -> Int -> a -> ST s ()
    {-# INLINE posDecimal #-}
    posDecimal :: forall a s. Integral a => MArray s -> Int -> Int -> a -> ST s ()
    posDecimal MArray s
    marr Int
    off0 Int
    ds a
    v0 = Int -> a -> ST s ()
    forall {p}. Integral p => Int -> p -> ST s ()
    go (Int
    off0 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    ds Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    1) a
    v0
      where go :: Int -> p -> ST s ()
    go Int
    off p
    v
               | p
    v p -> p -> Bool
    forall a. Ord a => a -> a -> Bool
    >= p
    100 = do
                   let (p
    q, p
    r) = p
    v p -> p -> (p, p)
    forall a. Integral a => a -> a -> (a, a)
    `quotRem` p
    100
                   Int -> p -> ST s ()
    forall {p}. Integral p => Int -> p -> ST s ()
    write2 Int
    off p
    r
                   Int -> p -> ST s ()
    go (Int
    off Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    2) p
    q
               | p
    v p -> p -> Bool
    forall a. Ord a => a -> a -> Bool
    < p
    10    = MArray s -> Int -> Word8 -> ST s ()
    forall s. MArray s -> Int -> Word8 -> ST s ()
    unsafeWrite MArray s
    marr Int
    off (p -> Word8
    forall a. Integral a => a -> Word8
    i2w p
    v)
               | Bool
    otherwise = Int -> p -> ST s ()
    forall {p}. Integral p => Int -> p -> ST s ()
    write2 Int
    off p
    v
            write2 :: Int -> p -> ST s ()
    write2 Int
    off p
    i0 = do
              let i :: Int
    i = p -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral p
    i0; j :: Int
    j = Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    i
              MArray s -> Int -> Word8 -> ST s ()
    forall s. MArray s -> Int -> Word8 -> ST s ()
    unsafeWrite MArray s
    marr Int
    off (Word8 -> ST s ()) -> Word8 -> ST s ()
    forall a b. (a -> b) -> a -> b
    $ Int -> Word8
    get (Int
    j Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1)
              MArray s -> Int -> Word8 -> ST s ()
    forall s. MArray s -> Int -> Word8 -> ST s ()
    unsafeWrite MArray s
    marr (Int
    off Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    1) (Word8 -> ST s ()) -> Word8 -> ST s ()
    forall a b. (a -> b) -> a -> b
    $ Int -> Word8
    get Int
    j
            get :: Int -> Word8
    get = ByteString -> Int -> Word8
    B.unsafeIndex ByteString
    digits

    minus, zero :: Word8
    {-# INLINE minus #-}
    {-# INLINE zero #-}
    minus :: Word8
    minus = Word8
    45
    zero :: Word8
    zero = Word8
    48

    i2w :: (Integral a) => a -> Word8
    {-# INLINE i2w #-}
    i2w :: forall a. Integral a => a -> Word8
    i2w a
    v = Word8
    zero Word8 -> Word8 -> Word8
    forall a. Num a => a -> a -> a
    + a -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral a
    v

    countDigits :: (Integral a) => a -> Int
    {-# INLINE countDigits #-}
    countDigits :: forall a. Integral a => a -> Int
    countDigits a
    v0
      | Word64 -> a
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word64
    v64 a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == a
    v0 = Int -> Word64 -> Int
    forall {t}. Num t => t -> Word64 -> t
    go Int
    1 Word64
    v64
      | Bool
    otherwise              = Int -> Integer -> Int
    forall {t}. Num t => t -> Integer -> t
    goBig Int
    1 (a -> Integer
    forall a. Integral a => a -> Integer
    toInteger a
    v0)
      where v64 :: Word64
    v64 = a -> Word64
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral a
    v0
            goBig :: t -> Integer -> t
    goBig !t
    k (Integer
    v :: Integer)
               | Integer
    v Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    > Integer
    big   = t -> Integer -> t
    goBig (t
    k t -> t -> t
    forall a. Num a => a -> a -> a
    + t
    19) (Integer
    v Integer -> Integer -> Integer
    forall a. Integral a => a -> a -> a
    `quot` Integer
    big)
               | Bool
    otherwise = t -> Word64 -> t
    forall {t}. Num t => t -> Word64 -> t
    go t
    k (Integer -> Word64
    forall a. Num a => Integer -> a
    fromInteger Integer
    v)
            big :: Integer
    big = Integer
    10000000000000000000
            go :: t -> Word64 -> t
    go !t
    k (Word64
    v :: Word64)
               | Word64
    v Word64 -> Word64 -> Bool
    forall a. Ord a => a -> a -> Bool
    < Word64
    10    = t
    k
               | Word64
    v Word64 -> Word64 -> Bool
    forall a. Ord a => a -> a -> Bool
    < Word64
    100   = t
    k t -> t -> t
    forall a. Num a => a -> a -> a
    + t
    1
               | Word64
    v Word64 -> Word64 -> Bool
    forall a. Ord a => a -> a -> Bool
    < Word64
    1000  = t
    k t -> t -> t
    forall a. Num a => a -> a -> a
    + t
    2
               | Word64
    v Word64 -> Word64 -> Bool
    forall a. Ord a => a -> a -> Bool
    < Word64
    1000000000000 =
                   t
    k t -> t -> t
    forall a. Num a => a -> a -> a
    + if Word64
    v Word64 -> Word64 -> Bool
    forall a. Ord a => a -> a -> Bool
    < Word64
    100000000
                       then if Word64
    v Word64 -> Word64 -> Bool
    forall a. Ord a => a -> a -> Bool
    < Word64
    1000000
                            then if Word64
    v Word64 -> Word64 -> Bool
    forall a. Ord a => a -> a -> Bool
    < Word64
    10000
                                 then t
    3
                                 else t
    4 t -> t -> t
    forall a. Num a => a -> a -> a
    + Word64 -> Word64 -> t
    forall {a} {a}. (Ord a, Num a) => a -> a -> a
    fin Word64
    v Word64
    100000
                            else t
    6 t -> t -> t
    forall a. Num a => a -> a -> a
    + Word64 -> Word64 -> t
    forall {a} {a}. (Ord a, Num a) => a -> a -> a
    fin Word64
    v Word64
    10000000
                       else if Word64
    v Word64 -> Word64 -> Bool
    forall a. Ord a => a -> a -> Bool
    < Word64
    10000000000
                            then t
    8 t -> t -> t
    forall a. Num a => a -> a -> a
    + Word64 -> Word64 -> t
    forall {a} {a}. (Ord a, Num a) => a -> a -> a
    fin Word64
    v Word64
    1000000000
                            else t
    10 t -> t -> t
    forall a. Num a => a -> a -> a
    + Word64 -> Word64 -> t
    forall {a} {a}. (Ord a, Num a) => a -> a -> a
    fin Word64
    v Word64
    100000000000
               | Bool
    otherwise = t -> Word64 -> t
    go (t
    k t -> t -> t
    forall a. Num a => a -> a -> a
    + t
    12) (Word64
    v Word64 -> Word64 -> Word64
    forall a. Integral a => a -> a -> a
    `quot` Word64
    1000000000000)
            fin :: a -> a -> a
    fin a
    v a
    n = if a
    v a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    >= a
    n then a
    1 else a
    0

    hexadecimal :: Integral a => a -> Builder
    {-# SPECIALIZE hexadecimal :: Int -> Builder #-}
    {-# SPECIALIZE hexadecimal :: Int8 -> Builder #-}
    {-# SPECIALIZE hexadecimal :: Int16 -> Builder #-}
    {-# SPECIALIZE hexadecimal :: Int32 -> Builder #-}
    {-# SPECIALIZE hexadecimal :: Int64 -> Builder #-}
    {-# SPECIALIZE hexadecimal :: Word -> Builder #-}
    {-# SPECIALIZE hexadecimal :: Word8 -> Builder #-}
    {-# SPECIALIZE hexadecimal :: Word16 -> Builder #-}
    {-# SPECIALIZE hexadecimal :: Word32 -> Builder #-}
    {-# SPECIALIZE hexadecimal :: Word64 -> Builder #-}
    {-# RULES "hexadecimal/Integer"
        hexadecimal = hexInteger :: Integer -> Builder #-}
    hexadecimal :: forall a. Integral a => a -> Builder
    hexadecimal a
    i
        | a
    i a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    < a
    0     = [Char] -> Builder
    forall a. HasCallStack => [Char] -> a
    error [Char]
    hexErrMsg
        | Bool
    otherwise = a -> Builder
    forall a. Integral a => a -> Builder
    go a
    i
      where
        go :: a -> Builder
    go a
    n | a
    n a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    < a
    16    = a -> Builder
    forall a. Integral a => a -> Builder
    hexDigit a
    n
             | Bool
    otherwise = a -> Builder
    go (a
    n a -> a -> a
    forall a. Integral a => a -> a -> a
    `quot` a
    16) Builder -> Builder -> Builder
    <> a -> Builder
    forall a. Integral a => a -> Builder
    hexDigit (a
    n a -> a -> a
    forall a. Integral a => a -> a -> a
    `rem` a
    16)
    {-# NOINLINE[0] hexadecimal #-}

    hexInteger :: Integer -> Builder
    hexInteger :: Integer -> Builder
    hexInteger Integer
    i
        | Integer
    i Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    < Integer
    0     = [Char] -> Builder
    forall a. HasCallStack => [Char] -> a
    error [Char]
    hexErrMsg
        | Bool
    otherwise = Int -> Integer -> Builder
    integer Int
    16 Integer
    i

    hexErrMsg :: String
    hexErrMsg :: [Char]
    hexErrMsg = [Char]
    "Data.Text.Lazy.Builder.Int.hexadecimal: applied to negative number"

    hexDigit :: Integral a => a -> Builder
    hexDigit :: forall a. Integral a => a -> Builder
    hexDigit a
    n
        | a
    n a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    <= a
    9    = Char -> Builder
    singleton (Char -> Builder) -> Char -> Builder
    forall a b. (a -> b) -> a -> b
    $! Int -> Char
    i2d (a -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral a
    n)
        | Bool
    otherwise = Char -> Builder
    singleton (Char -> Builder) -> Char -> Builder
    forall a b. (a -> b) -> a -> b
    $! Int -> Char
    forall a. Enum a => Int -> a
    toEnum (a -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral a
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    87)
    {-# INLINE hexDigit #-}

    data T = T !Integer !Int

    integer :: Int -> Integer -> Builder
    integer :: Int -> Integer -> Builder
    integer Int
    10 Integer
    i
        | Int
    i' <- Integer -> Int
    forall a. Num a => Integer -> a
    fromInteger Integer
    i, Int -> Integer
    forall a. Integral a => a -> Integer
    toInteger Int
    i' Integer -> Integer -> Bool
    forall a. Eq a => a -> a -> Bool
    == Integer
    i = Int -> Builder
    forall a. Integral a => a -> Builder
    decimal (Int
    i' :: Int)
    integer Int
    16 Integer
    i
        | Int
    i' <- Integer -> Int
    forall a. Num a => Integer -> a
    fromInteger Integer
    i, Int -> Integer
    forall a. Integral a => a -> Integer
    toInteger Int
    i' Integer -> Integer -> Bool
    forall a. Eq a => a -> a -> Bool
    == Integer
    i = Int -> Builder
    forall a. Integral a => a -> Builder
    hexadecimal (Int
    i' :: Int)
    integer Int
    base Integer
    i
        | Integer
    i Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    < Integer
    0     = Char -> Builder
    singleton Char
    '-' Builder -> Builder -> Builder
    <> Integer -> Builder
    go (-Integer
    i)
        | Bool
    otherwise = Integer -> Builder
    go Integer
    i
      where
        go :: Integer -> Builder
    go Integer
    n | Integer
    n Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    < Integer
    maxInt = Int -> Builder
    int (Integer -> Int
    forall a. Num a => Integer -> a
    fromInteger Integer
    n)
             | Bool
    otherwise  = [Integer] -> Builder
    putH (Integer -> Integer -> [Integer]
    forall {t}. Integral t => t -> t -> [t]
    splitf (Integer
    maxInt Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    * Integer
    maxInt) Integer
    n)

        splitf :: t -> t -> [t]
    splitf t
    p t
    n
          | t
    p t -> t -> Bool
    forall a. Ord a => a -> a -> Bool
    > t
    n       = [t
    n]
          | Bool
    otherwise   = t -> [t] -> [t]
    forall {a}. Integral a => a -> [a] -> [a]
    splith t
    p (t -> t -> [t]
    splitf (t
    pt -> t -> t
    forall a. Num a => a -> a -> a
    *t
    p) t
    n)

        splith :: a -> [a] -> [a]
    splith a
    p (a
    n:[a]
    ns) = case a
    n a -> a -> (a, a)
    forall a. Integral a => a -> a -> (a, a)
    `quotRem` a
    p of
                            (a
    q, a
    r) | a
    q a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    > a
    0     -> a
    q a -> [a] -> [a]
    forall a. a -> [a] -> [a]
    : a
    r a -> [a] -> [a]
    forall a. a -> [a] -> [a]
    : a -> [a] -> [a]
    forall {a}. Integral a => a -> [a] -> [a]
    splitb a
    p [a]
    ns
                                   | Bool
    otherwise -> a
    r a -> [a] -> [a]
    forall a. a -> [a] -> [a]
    : a -> [a] -> [a]
    forall {a}. Integral a => a -> [a] -> [a]
    splitb a
    p [a]
    ns
        splith a
    _ [a]
    _      = [Char] -> [a]
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "splith: the impossible happened."

        splitb :: t -> [t] -> [t]
    splitb t
    p (t
    n:[t]
    ns) = case t
    n t -> t -> (t, t)
    forall a. Integral a => a -> a -> (a, a)
    `quotRem` t
    p of
                            (t
    q, t
    r) -> t
    q t -> [t] -> [t]
    forall a. a -> [a] -> [a]
    : t
    r t -> [t] -> [t]
    forall a. a -> [a] -> [a]
    : t -> [t] -> [t]
    splitb t
    p [t]
    ns
        splitb t
    _ [t]
    _      = []

        T Integer
    maxInt10 Int
    maxDigits10 =
            (T -> Bool) -> (T -> T) -> T -> T
    forall a. (a -> Bool) -> (a -> a) -> a -> a
    until ((Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    >Integer
    mi) (Integer -> Bool) -> (T -> Integer) -> T -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    *Integer
    10) (Integer -> Integer) -> (T -> Integer) -> T -> Integer
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . T -> Integer
    fstT) (\(T Integer
    n Int
    d) -> Integer -> Int -> T
    T (Integer
    nInteger -> Integer -> Integer
    forall a. Num a => a -> a -> a
    *Integer
    10) (Int
    dInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    1)) (Integer -> Int -> T
    T Integer
    10 Int
    1)
          where mi :: Integer
    mi = Int -> Integer
    forall a. Integral a => a -> Integer
    toInteger (Int
    forall a. Bounded a => a
    maxBound :: Int)
        T Integer
    maxInt16 Int
    maxDigits16 =
            (T -> Bool) -> (T -> T) -> T -> T
    forall a. (a -> Bool) -> (a -> a) -> a -> a
    until ((Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    >Integer
    mi) (Integer -> Bool) -> (T -> Integer) -> T -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    *Integer
    16) (Integer -> Integer) -> (T -> Integer) -> T -> Integer
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . T -> Integer
    fstT) (\(T Integer
    n Int
    d) -> Integer -> Int -> T
    T (Integer
    nInteger -> Integer -> Integer
    forall a. Num a => a -> a -> a
    *Integer
    16) (Int
    dInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    1)) (Integer -> Int -> T
    T Integer
    16 Int
    1)
          where mi :: Integer
    mi = Int -> Integer
    forall a. Integral a => a -> Integer
    toInteger (Int
    forall a. Bounded a => a
    maxBound :: Int)

        fstT :: T -> Integer
    fstT (T Integer
    a Int
    _) = Integer
    a

        maxInt :: Integer
    maxInt | Int
    base Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    10 = Integer
    maxInt10
               | Bool
    otherwise  = Integer
    maxInt16
        maxDigits :: Int
    maxDigits | Int
    base Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    10 = Int
    maxDigits10
                  | Bool
    otherwise  = Int
    maxDigits16

        putH :: [Integer] -> Builder
    putH (Integer
    n:[Integer]
    ns) = case Integer
    n Integer -> Integer -> (Integer, Integer)
    forall a. Integral a => a -> a -> (a, a)
    `quotRem` Integer
    maxInt of
                        (Integer
    x, Integer
    y)
                            | Int
    q Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    0     -> Int -> Builder
    int Int
    q Builder -> Builder -> Builder
    <> Int -> Builder
    pblock Int
    r Builder -> Builder -> Builder
    <> [Integer] -> Builder
    putB [Integer]
    ns
                            | Bool
    otherwise -> Int -> Builder
    int Int
    r Builder -> Builder -> Builder
    <> [Integer] -> Builder
    putB [Integer]
    ns
                            where q :: Int
    q = Integer -> Int
    forall a. Num a => Integer -> a
    fromInteger Integer
    x
                                  r :: Int
    r = Integer -> Int
    forall a. Num a => Integer -> a
    fromInteger Integer
    y
        putH [Integer]
    _ = [Char] -> Builder
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "putH: the impossible happened"

        putB :: [Integer] -> Builder
    putB (Integer
    n:[Integer]
    ns) = case Integer
    n Integer -> Integer -> (Integer, Integer)
    forall a. Integral a => a -> a -> (a, a)
    `quotRem` Integer
    maxInt of
                        (Integer
    x, Integer
    y) -> Int -> Builder
    pblock Int
    q Builder -> Builder -> Builder
    <> Int -> Builder
    pblock Int
    r Builder -> Builder -> Builder
    <> [Integer] -> Builder
    putB [Integer]
    ns
                            where q :: Int
    q = Integer -> Int
    forall a. Num a => Integer -> a
    fromInteger Integer
    x
                                  r :: Int
    r = Integer -> Int
    forall a. Num a => Integer -> a
    fromInteger Integer
    y
        putB [Integer]
    _ = Builder
    forall a. Monoid a => a
    Data.Monoid.mempty

        int :: Int -> Builder
        int :: Int -> Builder
    int Int
    x | Int
    base Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    10 = Int -> Builder
    forall a. Integral a => a -> Builder
    decimal Int
    x
              | Bool
    otherwise  = Int -> Builder
    forall a. Integral a => a -> Builder
    hexadecimal Int
    x

        pblock :: Int -> Builder
    pblock = Int -> Int -> Builder
    forall {t}. (Eq t, Num t) => t -> Int -> Builder
    loop Int
    maxDigits
          where
            loop :: t -> Int -> Builder
    loop !t
    d !Int
    n
                | t
    d t -> t -> Bool
    forall a. Eq a => a -> a -> Bool
    == t
    1    = Int -> Builder
    forall a. Integral a => a -> Builder
    hexDigit Int
    n
                | Bool
    otherwise = t -> Int -> Builder
    loop (t
    dt -> t -> t
    forall a. Num a => a -> a -> a
    -t
    1) Int
    q Builder -> Builder -> Builder
    <> Int -> Builder
    forall a. Integral a => a -> Builder
    hexDigit Int
    r
                where q :: Int
    q = Int
    n Int -> Int -> Int
    `quotInt` Int
    base
                      r :: Int
    r = Int
    n Int -> Int -> Int
    `remInt` Int
    base