{-# LANGUAGE ConstraintKinds #-}

-- | Re-exports of types and functions used by generated code
--
-- This exports all functionality required by the generated code, with the
-- exception of GHC generics (name clash with @large-records@ generics).
--
-- This follows the structure of "Data.Record.Internal.Plugin.RuntimeNames".
module Data.Record.Plugin.Runtime (
    -- * base
    Any
  , Constraint
  , Eq((==))
  , Int
  , Ord(compare)
  , Proxy(Proxy)
  , Show(showsPrec)
  , Type
  , unsafeCoerce
  , error
    -- * vector
  , SmallArray
  , smallArrayFromList
  , smallArrayToList
  , indexSmallArray
  , updateSmallArray
    -- * record-hasfield
  , GRC.HasField(hasField)
    -- * large-generics
  , LR.Dict
  , LR.FieldMetadata(FieldMetadata)
  , LR.FieldStrictness(FieldLazy, FieldStrict)
  , LR.Generic(Constraints, MetadataOf, dict, from, metadata, to)
  , LR.Metadata(Metadata, recordConstructor, recordFieldMetadata, recordName, recordSize)
  , LR.Rep(Rep)
  , LR.ThroughLRGenerics(WrapThroughLRGenerics, unwrapThroughLRGenerics)
  , LR.gcompare
  , LR.geq
  , LR.gshowsPrec
  , LR.noInlineUnsafeCo
    -- * Auxiliary
  , dictFor
  , repFromVector
  , repToVector
  ) where

import Control.Monad (forM_)
import Data.Coerce (coerce)
import Data.Kind (Constraint, Type)
import Data.Primitive.SmallArray
import Data.Proxy (Proxy(Proxy))
import GHC.Exts (Any)
import Unsafe.Coerce (unsafeCoerce)

import qualified Data.Foldable                    as Foldable
import qualified Data.Record.Generic              as LR
import qualified Data.Record.Generic.Eq           as LR
import qualified Data.Record.Generic.GHC          as LR
import qualified Data.Record.Generic.Rep.Internal as LR
import qualified Data.Record.Generic.Show         as LR
import qualified GHC.Records.Compat               as GRC

{-------------------------------------------------------------------------------
  Auxiliary
-------------------------------------------------------------------------------}

dictFor :: c x => Proxy c -> Proxy x -> LR.Dict c x
dictFor :: Proxy c -> Proxy x -> Dict c x
dictFor Proxy c
_ Proxy x
_ = Dict c x
forall k (c :: k -> Constraint) (a :: k). c a => Dict c a
LR.Dict

repFromVector :: SmallArray Any -> LR.Rep LR.I a
repFromVector :: SmallArray Any -> Rep I a
repFromVector = SmallArray Any -> Rep I a
coerce

repToVector :: LR.Rep LR.I a -> SmallArray Any
repToVector :: Rep I a -> SmallArray Any
repToVector = Rep I a -> SmallArray Any
coerce

smallArrayToList :: SmallArray a -> [a]
smallArrayToList :: SmallArray a -> [a]
smallArrayToList = SmallArray a -> [a]
forall (t :: Type -> Type) a. Foldable t => t a -> [a]
Foldable.toList

updateSmallArray :: SmallArray a -> [(Int, a)] -> SmallArray a
updateSmallArray :: SmallArray a -> [(Int, a)] -> SmallArray a
updateSmallArray SmallArray a
v [(Int, a)]
updates = (forall s. ST s (SmallMutableArray s a)) -> SmallArray a
forall a. (forall s. ST s (SmallMutableArray s a)) -> SmallArray a
runSmallArray ((forall s. ST s (SmallMutableArray s a)) -> SmallArray a)
-> (forall s. ST s (SmallMutableArray s a)) -> SmallArray a
forall a b. (a -> b) -> a -> b
$ do
    SmallMutableArray s a
v' <- SmallArray a
-> Int -> Int -> ST s (SmallMutableArray (PrimState (ST s)) a)
forall (m :: Type -> Type) a.
PrimMonad m =>
SmallArray a -> Int -> Int -> m (SmallMutableArray (PrimState m) a)
thawSmallArray SmallArray a
v Int
0 (SmallArray a -> Int
forall a. SmallArray a -> Int
sizeofSmallArray SmallArray a
v)
    [(Int, a)] -> ((Int, a) -> ST s ()) -> ST s ()
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [(Int, a)]
updates (((Int, a) -> ST s ()) -> ST s ())
-> ((Int, a) -> ST s ()) -> ST s ()
forall a b. (a -> b) -> a -> b
$ \(Int
i, a
a) -> do
      SmallMutableArray (PrimState (ST s)) a -> Int -> a -> ST s ()
forall (m :: Type -> Type) a.
PrimMonad m =>
SmallMutableArray (PrimState m) a -> Int -> a -> m ()
writeSmallArray SmallMutableArray s a
SmallMutableArray (PrimState (ST s)) a
v' Int
i a
a
    SmallMutableArray s a -> ST s (SmallMutableArray s a)
forall (m :: Type -> Type) a. Monad m => a -> m a
return SmallMutableArray s a
v'