module Language.Fortran.Repr.Value.Scalar.Real where

import Language.Fortran.Repr.Type.Scalar.Real
import Language.Fortran.Repr.Value.Scalar.Common
import GHC.Float ( float2Double )

import GHC.Generics ( Generic )
import Data.Data ( Data )
import Data.Binary ( Binary )
import Text.PrettyPrint.GenericPretty ( Out )

data FReal
  = FReal4 {- ^ @REAL(4)@ -} Float
  | FReal8 {- ^ @REAL(8)@ -} Double
    deriving stock (Int -> FReal -> ShowS
[FReal] -> ShowS
FReal -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FReal] -> ShowS
$cshowList :: [FReal] -> ShowS
show :: FReal -> String
$cshow :: FReal -> String
showsPrec :: Int -> FReal -> ShowS
$cshowsPrec :: Int -> FReal -> ShowS
Show, forall x. Rep FReal x -> FReal
forall x. FReal -> Rep FReal x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep FReal x -> FReal
$cfrom :: forall x. FReal -> Rep FReal x
Generic, Typeable FReal
FReal -> DataType
FReal -> Constr
(forall b. Data b => b -> b) -> FReal -> FReal
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> FReal -> u
forall u. (forall d. Data d => d -> u) -> FReal -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> FReal -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> FReal -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> FReal -> m FReal
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FReal -> m FReal
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c FReal
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> FReal -> c FReal
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c FReal)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c FReal)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FReal -> m FReal
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FReal -> m FReal
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FReal -> m FReal
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FReal -> m FReal
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> FReal -> m FReal
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> FReal -> m FReal
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> FReal -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> FReal -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> FReal -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> FReal -> [u]
gmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> FReal -> r
$cgmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> FReal -> r
gmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> FReal -> r
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> FReal -> r
gmapT :: (forall b. Data b => b -> b) -> FReal -> FReal
$cgmapT :: (forall b. Data b => b -> b) -> FReal -> FReal
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c FReal)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c FReal)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c FReal)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c FReal)
dataTypeOf :: FReal -> DataType
$cdataTypeOf :: FReal -> DataType
toConstr :: FReal -> Constr
$ctoConstr :: FReal -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c FReal
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c FReal
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> FReal -> c FReal
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> FReal -> c FReal
Data)
    deriving anyclass (Get FReal
[FReal] -> Put
FReal -> Put
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
putList :: [FReal] -> Put
$cputList :: [FReal] -> Put
get :: Get FReal
$cget :: Get FReal
put :: FReal -> Put
$cput :: FReal -> Put
Binary, Int -> FReal -> Doc
[FReal] -> Doc
FReal -> Doc
forall a. (Int -> a -> Doc) -> (a -> Doc) -> ([a] -> Doc) -> Out a
docList :: [FReal] -> Doc
$cdocList :: [FReal] -> Doc
doc :: FReal -> Doc
$cdoc :: FReal -> Doc
docPrec :: Int -> FReal -> Doc
$cdocPrec :: Int -> FReal -> Doc
Out)

instance FKinded FReal where
    type FKindedT FReal = FTReal
    type FKindedC FReal a = RealFloat a
    fKind :: FReal -> FKindedT FReal
fKind = \case
      FReal4{} -> FTReal
FTReal4
      FReal8{} -> FTReal
FTReal8

instance Eq FReal where == :: FReal -> FReal -> Bool
(==) = forall r.
(forall a. FKindedC FReal a => a -> a -> r) -> FReal -> FReal -> r
fRealBOp forall a. Eq a => a -> a -> Bool
(==)

fRealUOp'
    :: (Float  -> r)
    -> (Double -> r)
    -> FReal -> r
fRealUOp' :: forall r. (Float -> r) -> (Double -> r) -> FReal -> r
fRealUOp' Float -> r
k4f Double -> r
k8f = \case
  FReal4 Float
fl -> Float -> r
k4f Float
fl
  FReal8 Double
db -> Double -> r
k8f Double
db

fRealBOp'
    :: (Float  -> Float  -> r)
    -> (Double -> Double -> r)
    -> FReal -> FReal -> r
fRealBOp' :: forall r.
(Float -> Float -> r)
-> (Double -> Double -> r) -> FReal -> FReal -> r
fRealBOp' Float -> Float -> r
k4f Double -> Double -> r
k8f FReal
l FReal
r = case (FReal
l, FReal
r) of
  (FReal4 Float
lr, FReal4 Float
rr) -> Float -> Float -> r
k4f Float
lr Float
rr
  (FReal8 Double
lr, FReal8 Double
rr) -> Double -> Double -> r
k8f Double
lr Double
rr
  (FReal4 Float
lr, FReal8 Double
rr) -> Double -> Double -> r
k8f (Float -> Double
float2Double Float
lr) Double
rr
  (FReal8 Double
lr, FReal4 Float
rr) -> Double -> Double -> r
k8f Double
lr (Float -> Double
float2Double Float
rr)

fRealUOpInplace'
    :: (Float  -> Float)
    -> (Double -> Double)
    -> FReal -> FReal
fRealUOpInplace' :: (Float -> Float) -> (Double -> Double) -> FReal -> FReal
fRealUOpInplace' Float -> Float
k4f Double -> Double
k8f = forall r. (Float -> r) -> (Double -> r) -> FReal -> r
fRealUOp' (Float -> FReal
FReal4 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Float -> Float
k4f) (Double -> FReal
FReal8 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
k8f)

fRealBOpInplace'
    :: (Float  -> Float  -> Float)
    -> (Double -> Double -> Double)
    -> FReal -> FReal -> FReal
fRealBOpInplace' :: (Float -> Float -> Float)
-> (Double -> Double -> Double) -> FReal -> FReal -> FReal
fRealBOpInplace' Float -> Float -> Float
k4f Double -> Double -> Double
k8f = forall r.
(Float -> Float -> r)
-> (Double -> Double -> r) -> FReal -> FReal -> r
fRealBOp' (forall {a} {b} {t} {t}. (a -> b) -> (t -> t -> a) -> t -> t -> b
f Float -> FReal
FReal4 Float -> Float -> Float
k4f) (forall {a} {b} {t} {t}. (a -> b) -> (t -> t -> a) -> t -> t -> b
f Double -> FReal
FReal8 Double -> Double -> Double
k8f)
  where f :: (a -> b) -> (t -> t -> a) -> t -> t -> b
f a -> b
cstr t -> t -> a
bop t
l t
r = a -> b
cstr forall a b. (a -> b) -> a -> b
$ t -> t -> a
bop t
l t
r

fRealUOp
    :: (forall a. FKindedC FReal a => a -> r)
    -> FReal -> r
fRealUOp :: forall r. (forall a. FKindedC FReal a => a -> r) -> FReal -> r
fRealUOp forall a. FKindedC FReal a => a -> r
f = forall r. (Float -> r) -> (Double -> r) -> FReal -> r
fRealUOp' forall a. FKindedC FReal a => a -> r
f forall a. FKindedC FReal a => a -> r
f

fRealUOpInplace
    :: (forall a. FKindedC FReal a => a -> a)
    -> FReal -> FReal
fRealUOpInplace :: (forall a. FKindedC FReal a => a -> a) -> FReal -> FReal
fRealUOpInplace forall a. FKindedC FReal a => a -> a
f = (Float -> Float) -> (Double -> Double) -> FReal -> FReal
fRealUOpInplace' forall a. FKindedC FReal a => a -> a
f forall a. FKindedC FReal a => a -> a
f

fRealBOp
    :: (forall a. FKindedC FReal a => a -> a -> r)
    -> FReal -> FReal -> r
fRealBOp :: forall r.
(forall a. FKindedC FReal a => a -> a -> r) -> FReal -> FReal -> r
fRealBOp forall a. FKindedC FReal a => a -> a -> r
f = forall r.
(Float -> Float -> r)
-> (Double -> Double -> r) -> FReal -> FReal -> r
fRealBOp' forall a. FKindedC FReal a => a -> a -> r
f forall a. FKindedC FReal a => a -> a -> r
f

fRealBOpInplace
    :: (forall a. FKindedC FReal a => a -> a -> a)
    -> FReal -> FReal -> FReal
fRealBOpInplace :: (forall a. FKindedC FReal a => a -> a -> a)
-> FReal -> FReal -> FReal
fRealBOpInplace forall a. FKindedC FReal a => a -> a -> a
f = (Float -> Float -> Float)
-> (Double -> Double -> Double) -> FReal -> FReal -> FReal
fRealBOpInplace' forall a. FKindedC FReal a => a -> a -> a
f forall a. FKindedC FReal a => a -> a -> a
f