    {-# LANGUAGE CPP #-}
    {-# LANGUAGE DeriveDataTypeable #-}
    {-# LANGUAGE DeriveGeneric #-}
    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    {-# LANGUAGE MultiParamTypeClasses #-}
    {-# LANGUAGE StandaloneDeriving #-}
    {-# LANGUAGE TemplateHaskell #-}
    {-# LANGUAGE TypeFamilies #-}

    #include "thyme.h"

    -- | FOR INTERNAL USE ONLY.
    module Data.Thyme.Internal.Micro where

    import Prelude
    import Control.DeepSeq
    import Data.AdditiveGroup
    import Data.Basis
    import Data.Data
    import Data.Int
    import Data.Ix
    import Data.Ratio
    #if __GLASGOW_HASKELL__ == 704
    import qualified Data.Vector.Generic
    import qualified Data.Vector.Generic.Mutable
    #endif
    import Data.Vector.Unboxed.Deriving
    import Data.VectorSpace
    import GHC.Generics (Generic)
    import System.Random
    import Test.QuickCheck

    #if !SHOW_INTERNAL
    import Control.Monad
    import Data.Char
    import Data.Thyme.Format.Internal
    import Numeric
    import Text.ParserCombinators.ReadPrec
    import Text.ParserCombinators.ReadP
    import Text.Read
    #endif

    newtype Micro = Micro Int64 deriving (INSTANCES_MICRO)

    derivingUnbox "Micro" [t| Micro -> Int64 |]
        [| \ (Micro a) -> a |] [| Micro |]

    #if SHOW_INTERNAL
    deriving instance Show Micro
    deriving instance Read Micro
    #else
    instance Show Micro where
        {-# INLINEABLE showsPrec #-}
        showsPrec :: Int -> Micro -> ShowS
    showsPrec _ (Micro a :: Int64
    a) = ShowS
    sign ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int64 -> ShowS
    forall a. Show a => a -> ShowS
    shows Int64
    si ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ShowS
    frac where
            sign :: ShowS
    sign = if Int64
    a Int64 -> Int64 -> Bool
    forall a. Ord a => a -> a -> Bool
    < 0 then (:) '-' else ShowS
    forall a. a -> a
    id
            (si :: Int64
    si, su :: Int64
    su) = Int64 -> Int64
    forall a. Num a => a -> a
    abs Int64
    a Int64 -> Int64 -> (Int64, Int64)
    forall a. Integral a => a -> a -> (a, a)
    `divMod` 1000000
            frac :: ShowS
    frac = if Int64
    su Int64 -> Int64 -> Bool
    forall a. Eq a => a -> a -> Bool
    == 0 then ShowS
    forall a. a -> a
    id else (:) '.' ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int64 -> ShowS
    fills06 Int64
    su ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int64 -> ShowS
    drops0 Int64
    su

    instance Read Micro where
        {-# INLINEABLE readPrec #-}
        readPrec :: ReadPrec Micro
    readPrec = ReadP Micro -> ReadPrec Micro
    forall a. ReadP a -> ReadPrec a
    lift (ReadP Micro -> ReadPrec Micro) -> ReadP Micro -> ReadPrec Micro
    forall a b. (a -> b) -> a -> b
    $ do
            Int64 -> Int64
    sign <- (Char -> ReadP Char
    char '-' ReadP Char -> ReadP (Int64 -> Int64) -> ReadP (Int64 -> Int64)
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> (Int64 -> Int64) -> ReadP (Int64 -> Int64)
    forall (m :: * -> *) a. Monad m => a -> m a
    return Int64 -> Int64
    forall a. Num a => a -> a
    negate) ReadP (Int64 -> Int64)
    -> ReadP (Int64 -> Int64) -> ReadP (Int64 -> Int64)
    forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
    `mplus` (Int64 -> Int64) -> ReadP (Int64 -> Int64)
    forall (m :: * -> *) a. Monad m => a -> m a
    return Int64 -> Int64
    forall a. a -> a
    id
            Int64
    s <- ReadS Int64 -> ReadP Int64
    forall a. ReadS a -> ReadP a
    readS_to_P ReadS Int64
    forall a. (Eq a, Num a) => ReadS a
    readDec
            Int64
    us <- (ReadP Int64 -> ReadP Int64 -> ReadP Int64
    forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
    `mplus` Int64 -> ReadP Int64
    forall (m :: * -> *) a. Monad m => a -> m a
    return 0) (ReadP Int64 -> ReadP Int64) -> ReadP Int64 -> ReadP Int64
    forall a b. (a -> b) -> a -> b
    $ do
                Char
    _ <- Char -> ReadP Char
    char '.'
                [(us10 :: Int64
    us10, "")] <- (ReadS Int64
    forall a. (Eq a, Num a) => ReadS a
    readDec ReadS Int64 -> ShowS -> ReadS Int64
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> ShowS
    forall a. Int -> [a] -> [a]
    take 7 ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ "000000"))
                    ReadS Int64 -> ReadP String -> ReadP [(Int64, String)]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` (Char -> Bool) -> ReadP String
    munch1 Char -> Bool
    isDigit
                Int64 -> ReadP Int64
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Int64 -> Int64 -> Int64
    forall a. Integral a => a -> a -> a
    div (Int64
    us10 Int64 -> Int64 -> Int64
    forall a. Num a => a -> a -> a
    + 5) 10)
            Micro -> ReadP Micro
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Micro -> ReadP Micro) -> (Int64 -> Micro) -> Int64 -> ReadP Micro
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int64 -> Micro
    Micro (Int64 -> Micro) -> (Int64 -> Int64) -> Int64 -> Micro
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int64 -> Int64
    sign (Int64 -> ReadP Micro) -> Int64 -> ReadP Micro
    forall a b. (a -> b) -> a -> b
    $ Int64
    s Int64 -> Int64 -> Int64
    forall a. Num a => a -> a -> a
    * 1000000 Int64 -> Int64 -> Int64
    forall a. Num a => a -> a -> a
    + Int64
    us
    #endif

    {-# INLINE microQuotRem #-}
    {-# INLINE microDivMod #-}
    microQuotRem, microDivMod :: Micro -> Micro -> (Int64, Micro)
    microQuotRem :: Micro -> Micro -> (Int64, Micro)
    microQuotRem (Micro a :: Int64
    a) (Micro b :: Int64
    b) = (Int64
    n, Int64 -> Micro
    Micro Int64
    f) where (n :: Int64
    n, f :: Int64
    f) = Int64 -> Int64 -> (Int64, Int64)
    forall a. Integral a => a -> a -> (a, a)
    quotRem Int64
    a Int64
    b
    microDivMod :: Micro -> Micro -> (Int64, Micro)
    microDivMod  (Micro a :: Int64
    a) (Micro b :: Int64
    b) = (Int64
    n, Int64 -> Micro
    Micro Int64
    f) where (n :: Int64
    n, f :: Int64
    f) = Int64 -> Int64 -> (Int64, Int64)
    forall a. Integral a => a -> a -> (a, a)
    divMod Int64
    a Int64
    b

    instance AdditiveGroup Micro where
        {-# INLINE zeroV #-}
        zeroV :: Micro
    zeroV = Int64 -> Micro
    Micro 0
        {-# INLINE (^+^) #-}
        ^+^ :: Micro -> Micro -> Micro
    (^+^) = \ (Micro a :: Int64
    a) (Micro b :: Int64
    b) -> Int64 -> Micro
    Micro (Int64
    a Int64 -> Int64 -> Int64
    forall a. Num a => a -> a -> a
    + Int64
    b)
        {-# INLINE negateV #-}
        negateV :: Micro -> Micro
    negateV = \ (Micro a :: Int64
    a) -> Int64 -> Micro
    Micro (Int64 -> Int64
    forall a. Num a => a -> a
    negate Int64
    a)

    instance VectorSpace Micro where
        type Scalar Micro = Rational
        {-# INLINEABLE (*^) #-}
        s :: Scalar Micro
    s *^ :: Scalar Micro -> Micro -> Micro
    *^ Micro a :: Int64
    a = Int64 -> Micro
    Micro (Int64 -> Micro) -> (Integer -> Int64) -> Integer -> Micro
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Integer -> Int64
    forall a. Num a => Integer -> a
    fromInteger (Integer -> Micro) -> Integer -> Micro
    forall a b. (a -> b) -> a -> b
    $
            case Integer -> Integer -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare (2 Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    * Integer -> Integer
    forall a. Num a => a -> a
    abs Integer
    r) (Ratio Integer -> Integer
    forall a. Ratio a -> a
    denominator Ratio Integer
    Scalar Micro
    s) of
                LT -> Integer
    n
                EQ -> if Integer -> Bool
    forall a. Integral a => a -> Bool
    even Integer
    n then Integer
    n else Integer
    m
                GT -> Integer
    m
          where
            (n :: Integer
    n, r :: Integer
    r) = Integer -> Integer -> (Integer, Integer)
    forall a. Integral a => a -> a -> (a, a)
    quotRem (Int64 -> Integer
    forall a. Integral a => a -> Integer
    toInteger Int64
    a Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    * Ratio Integer -> Integer
    forall a. Ratio a -> a
    numerator Ratio Integer
    Scalar Micro
    s) (Ratio Integer -> Integer
    forall a. Ratio a -> a
    denominator Ratio Integer
    Scalar Micro
    s)
            m :: Integer
    m = if Integer
    r Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    < 0 then Integer
    n Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    - 1 else Integer
    n Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    + 1

    instance HasBasis Micro where
        type Basis Micro = ()
        {-# INLINE basisValue #-}
        basisValue :: Basis Micro -> Micro
    basisValue = \ _ -> Int64 -> Micro
    Micro 1000000
        {-# INLINE decompose #-}
        decompose :: Micro -> [(Basis Micro, Scalar Micro)]
    decompose = \ (Micro a :: Int64
    a) -> [((), Int64 -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int64
    a Integer -> Integer -> Ratio Integer
    forall a. Integral a => a -> a -> Ratio a
    % 1000000)]
        {-# INLINE decompose' #-}
        decompose' :: Micro -> Basis Micro -> Scalar Micro
    decompose' = \ (Micro a :: Int64
    a) _ -> Int64 -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int64
    a Integer -> Integer -> Ratio Integer
    forall a. Integral a => a -> a -> Ratio a
    % 1000000