{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MonoLocalBinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
module Test.Massiv.Array.Load
  ( -- * Spec for loadable representations
    loadSpec
  ) where


import Data.Massiv.Array as A
import Test.Massiv.Core.Common ()
import Test.Massiv.Utils as T

prop_replicate ::
     forall r ix e.
     ( Eq e
     , Show e
     , Load r ix e
     , Ragged L ix e
     )
  => Comp
  -> Sz ix
  -> e
  -> Property
prop_replicate :: Comp -> Sz ix -> e -> Property
prop_replicate Comp
comp Sz ix
sz e
e = IO () -> Property
forall a. Testable a => IO a -> Property
propIO (IO () -> Property) -> IO () -> Property
forall a b. (a -> b) -> a -> b
$ do
  B -> Array r ix e -> Array B ix e
forall r e r' ix.
(Manifest r e, Load r' ix e) =>
r -> Array r' ix e -> Array r ix e
computeAs B
B (Comp -> Sz ix -> e -> Array r ix e
forall r ix e. Load r ix e => Comp -> Sz ix -> e -> Array r ix e
A.replicate @r Comp
comp Sz ix
sz e
e) Array B ix e -> Array B ix e -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe`
    B -> Array r ix e -> Array B ix e
forall r e r' ix.
(Manifest r e, Load r' ix e) =>
r -> Array r' ix e -> Array r ix e
computeAs B
B (Comp -> Sz ix -> (Int -> e) -> Array r ix e
forall r ix e.
Load r ix e =>
Comp -> Sz ix -> (Int -> e) -> Array r ix e
makeArrayLinear @r Comp
comp Sz ix
sz (e -> Int -> e
forall a b. a -> b -> a
const e
e))

prop_makeArray ::
     forall r ix e.
     ( Eq e
     , Show e
     , Load r ix e
     , Ragged L ix e
     )
  => Comp
  -> Sz ix
  -> Fun ix e
  -> Property
prop_makeArray :: Comp -> Sz ix -> Fun ix e -> Property
prop_makeArray Comp
comp Sz ix
sz Fun ix e
f = IO () -> Property
forall a. Testable a => IO a -> Property
propIO (IO () -> Property) -> IO () -> Property
forall a b. (a -> b) -> a -> b
$ do
  let barr :: Array B ix e
barr = Comp -> Sz ix -> (ix -> e) -> Array B ix e
forall r ix e.
Load r ix e =>
Comp -> Sz ix -> (ix -> e) -> Array r ix e
makeArray @B Comp
comp Sz ix
sz (Fun ix e -> ix -> e
forall a b. Fun a b -> a -> b
applyFun Fun ix e
f)
  B -> Array r ix e -> Array B ix e
forall r e r' ix.
(Manifest r e, Load r' ix e) =>
r -> Array r' ix e -> Array r ix e
computeAs B
B (Comp -> Sz ix -> (ix -> e) -> Array r ix e
forall r ix e.
Load r ix e =>
Comp -> Sz ix -> (ix -> e) -> Array r ix e
makeArray @r Comp
comp Sz ix
sz (Fun ix e -> ix -> e
forall a b. Fun a b -> a -> b
applyFun Fun ix e
f)) Array B ix e -> Array B ix e -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Array B ix e
barr
  B -> Array r ix e -> Array B ix e
forall r e r' ix.
(Manifest r e, Load r' ix e) =>
r -> Array r' ix e -> Array r ix e
computeAs B
B (Comp -> Sz ix -> (Int -> e) -> Array r ix e
forall r ix e.
Load r ix e =>
Comp -> Sz ix -> (Int -> e) -> Array r ix e
makeArrayLinear @r Comp
comp Sz ix
sz (Fun ix e -> ix -> e
forall a b. Fun a b -> a -> b
applyFun Fun ix e
f (ix -> e) -> (Int -> ix) -> Int -> e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sz ix -> Int -> ix
forall ix. Index ix => Sz ix -> Int -> ix
fromLinearIndex Sz ix
sz)) Array B ix e -> Array B ix e -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Array B ix e
barr


loadSpec ::
     forall r ix e.
     ( Eq e
     , Show e
     , Typeable e
     , Arbitrary e
     , Function ix
     , Arbitrary ix
     , CoArbitrary ix
     , Ragged L ix e
     , Load r ix e
     )
  => Spec
loadSpec :: Spec
loadSpec = do
  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe ((String
"LoadSpec "  String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Typeable r, Typeable ix, Typeable e) => String -> String
forall r ix e.
(Typeable r, Typeable ix, Typeable e) =>
String -> String
showsArrayType @r @ix @e (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String
"") (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    String -> (Comp -> Sz ix -> e -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"replicate" ((Comp -> Sz ix -> e -> Property) -> Spec)
-> (Comp -> Sz ix -> e -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ (Eq e, Show e, Load r ix e, Ragged L ix e) =>
Comp -> Sz ix -> e -> Property
forall r ix e.
(Eq e, Show e, Load r ix e, Ragged L ix e) =>
Comp -> Sz ix -> e -> Property
prop_replicate @r @ix @e
    String -> (Comp -> Sz ix -> Fun ix e -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"makeArray" ((Comp -> Sz ix -> Fun ix e -> Property) -> Spec)
-> (Comp -> Sz ix -> Fun ix e -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ (Eq e, Show e, Load r ix e, Ragged L ix e) =>
Comp -> Sz ix -> Fun ix e -> Property
forall r ix e.
(Eq e, Show e, Load r ix e, Ragged L ix e) =>
Comp -> Sz ix -> Fun ix e -> Property
prop_makeArray @r @ix @e