{-# LANGUAGE MagicHash, TypeOperators, UndecidableInstances #-}

{- |
    Module      :  Test.SDP.Arbitrary
    Copyright   :  (c) Andrey Mulik 2020
    License     :  BSD-style
    Maintainer  :  work.a.mulik@gmail.com
    Portability :  non-portable (GHC extensions)
    
    @Test.SDP.Arbitrary@ is service module that provides 'Arbitrary' instances
    for @sdp@ structures.
-}
module Test.SDP.Arbitrary
(
  -- * Exports
  module Test.QuickCheck,
  
  SArray#, SBytes#, AnyBorder (..), AnyChunks
)
where

import Prelude ()
import SDP.SafePrelude
import SDP.Unboxed

import SDP.Templates.AnyBorder
import SDP.Templates.AnyChunks
import SDP.Prim.SArray
import SDP.Prim.SBytes

import Test.QuickCheck

default ()

--------------------------------------------------------------------------------

instance Arbitrary E where arbitrary :: Gen E
arbitrary = E -> Gen E
forall (m :: * -> *) a. Monad m => a -> m a
return E
E

instance (Arbitrary i, Arbitrary i') => Arbitrary (i' :& i)
  where
    arbitrary :: Gen (i' :& i)
arbitrary = (i' -> i -> i' :& i) -> Gen (i' :& i)
forall a b r. (Arbitrary a, Arbitrary b) => (a -> b -> r) -> Gen r
applyArbitrary2 i' -> i -> i' :& i
forall tail head. tail -> head -> tail :& head
(:&)

--------------------------------------------------------------------------------

instance (Arbitrary e) => Arbitrary (SArray# e)
  where
    arbitrary :: Gen (SArray# e)
arbitrary = [e] -> SArray# e
forall l e. Linear l e => [e] -> l
fromList ([e] -> SArray# e) -> Gen [e] -> Gen (SArray# e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen [e]
forall a. Arbitrary a => Gen a
arbitrary

instance (Unboxed e, Arbitrary e) => Arbitrary (SBytes# e)
  where
    arbitrary :: Gen (SBytes# e)
arbitrary = [e] -> SBytes# e
forall l e. Linear l e => [e] -> l
fromList ([e] -> SBytes# e) -> Gen [e] -> Gen (SBytes# e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen [e]
forall a. Arbitrary a => Gen a
arbitrary

--------------------------------------------------------------------------------

-- TODO: rewrite as arbitrary chunk list generator (needs sdp improvements).

instance (Bordered1 rep Int e, Linear1 rep e, Arbitrary e) => Arbitrary (AnyChunks rep e)
  where
    arbitrary :: Gen (AnyChunks rep e)
arbitrary = [e] -> AnyChunks rep e
forall l e. Linear l e => [e] -> l
fromList ([e] -> AnyChunks rep e) -> Gen [e] -> Gen (AnyChunks rep e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen [e]
forall a. Arbitrary a => Gen a
arbitrary

instance (Index i, Bordered1 rep Int e, Arbitrary (rep e)) => Arbitrary (AnyBorder rep i e)
  where
    arbitrary :: Gen (AnyBorder rep i e)
arbitrary = (\ rep e
es -> (i -> i -> rep e -> AnyBorder rep i e)
-> (i, i) -> rep e -> AnyBorder rep i e
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry i -> i -> rep e -> AnyBorder rep i e
forall (rep :: * -> *) i e. i -> i -> rep e -> AnyBorder rep i e
AnyBorder (Int -> (i, i)
forall i. Index i => Int -> (i, i)
defaultBounds (Int -> (i, i)) -> Int -> (i, i)
forall a b. (a -> b) -> a -> b
$ rep e -> Int
forall b i. Bordered b i => b -> Int
sizeOf rep e
es) rep e
es) (rep e -> AnyBorder rep i e)
-> Gen (rep e) -> Gen (AnyBorder rep i e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (rep e)
forall a. Arbitrary a => Gen a
arbitrary