----------------------------------------------------------------------------
-- |
-- Module      :  Data.Emacs.Module.Value.Internal
-- Copyright   :  (c) Sergey Vinokurov 2018
-- License     :  Apache-2.0 (see LICENSE)
-- Maintainer  :  serg.foo@gmail.com
----------------------------------------------------------------------------

{-# LANGUAGE CPP                  #-}
{-# LANGUAGE DataKinds            #-}
{-# LANGUAGE DerivingVia          #-}
{-# LANGUAGE TypeFamilies         #-}
{-# LANGUAGE UndecidableInstances #-}

{-# LANGUAGE UnboxedTuples #-}

module Data.Emacs.Module.Value.Internal
  ( Value(..)
  ) where

import Control.DeepSeq
import Data.Primitive.Types
import Data.Vector.Generic qualified as G
import Data.Vector.Generic.Mutable qualified as GM
import Data.Vector.Primitive qualified as P
import Data.Vector.Unboxed qualified as U
#if !MIN_VERSION_vector(0, 13, 1)
import Data.Vector.Unboxed.Base qualified as U
#endif
import GHC.Generics (Generic)
import Prettyprinter (Pretty)

import Data.Emacs.Module.Raw.Value

-- | Value that is independent of environment ('Env') that produced it.
-- Incidentally, this implies that it's "protected" against Emacs GC and
-- thus will not unexpectedly go out of scope.
--
-- In order to prevent memory leaks, value is registered in the Emacs
-- monad than produced it and will be freed when the monad finishes.
-- To make the connection clear the value is tagged with parameter
-- @s@, which serves the same purpose as tag of the 'ST' monad. That
-- is, it ensures that value cannot leave the scope of the monad that
-- produced it.
newtype Value (s :: k) = Value
  { forall k (s :: k). Value s -> RawValue 'Regular
unValue :: RawValue 'Regular
  } deriving (Int -> Value s -> ShowS
[Value s] -> ShowS
Value s -> String
(Int -> Value s -> ShowS)
-> (Value s -> String) -> ([Value s] -> ShowS) -> Show (Value s)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall k (s :: k). Int -> Value s -> ShowS
forall k (s :: k). [Value s] -> ShowS
forall k (s :: k). Value s -> String
$cshowsPrec :: forall k (s :: k). Int -> Value s -> ShowS
showsPrec :: Int -> Value s -> ShowS
$cshow :: forall k (s :: k). Value s -> String
show :: Value s -> String
$cshowList :: forall k (s :: k). [Value s] -> ShowS
showList :: [Value s] -> ShowS
Show, Value s -> ()
(Value s -> ()) -> NFData (Value s)
forall a. (a -> ()) -> NFData a
forall k (s :: k). Value s -> ()
$crnf :: forall k (s :: k). Value s -> ()
rnf :: Value s -> ()
NFData, (forall x. Value s -> Rep (Value s) x)
-> (forall x. Rep (Value s) x -> Value s) -> Generic (Value s)
forall x. Rep (Value s) x -> Value s
forall x. Value s -> Rep (Value s) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall k (s :: k) x. Rep (Value s) x -> Value s
forall k (s :: k) x. Value s -> Rep (Value s) x
$cfrom :: forall k (s :: k) x. Value s -> Rep (Value s) x
from :: forall x. Value s -> Rep (Value s) x
$cto :: forall k (s :: k) x. Rep (Value s) x -> Value s
to :: forall x. Rep (Value s) x -> Value s
Generic, Addr# -> Int# -> Value s
ByteArray# -> Int# -> Value s
Proxy (Value s) -> Int#
Value s -> Int#
(Proxy (Value s) -> Int#)
-> (Value s -> Int#)
-> (Proxy (Value s) -> Int#)
-> (Value s -> Int#)
-> (ByteArray# -> Int# -> Value s)
-> (forall s.
    MutableByteArray# s -> Int# -> State# s -> (# State# s, Value s #))
-> (forall s.
    MutableByteArray# s -> Int# -> Value s -> State# s -> State# s)
-> (forall s.
    MutableByteArray# s
    -> Int# -> Int# -> Value s -> State# s -> State# s)
-> (Addr# -> Int# -> Value s)
-> (forall s. Addr# -> Int# -> State# s -> (# State# s, Value s #))
-> (forall s. Addr# -> Int# -> Value s -> State# s -> State# s)
-> (forall s.
    Addr# -> Int# -> Int# -> Value s -> State# s -> State# s)
-> Prim (Value s)
forall s. Addr# -> Int# -> Int# -> Value s -> State# s -> State# s
forall s. Addr# -> Int# -> State# s -> (# State# s, Value s #)
forall s. Addr# -> Int# -> Value s -> State# s -> State# s
forall s.
MutableByteArray# s
-> Int# -> Int# -> Value s -> State# s -> State# s
forall s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, Value s #)
forall s.
MutableByteArray# s -> Int# -> Value s -> State# s -> State# s
forall a.
(Proxy a -> Int#)
-> (a -> Int#)
-> (Proxy a -> Int#)
-> (a -> Int#)
-> (ByteArray# -> Int# -> a)
-> (forall s.
    MutableByteArray# s -> Int# -> State# s -> (# State# s, a #))
-> (forall s.
    MutableByteArray# s -> Int# -> a -> State# s -> State# s)
-> (forall s.
    MutableByteArray# s -> Int# -> Int# -> a -> State# s -> State# s)
-> (Addr# -> Int# -> a)
-> (forall s. Addr# -> Int# -> State# s -> (# State# s, a #))
-> (forall s. Addr# -> Int# -> a -> State# s -> State# s)
-> (forall s. Addr# -> Int# -> Int# -> a -> State# s -> State# s)
-> Prim a
forall k (s :: k). Addr# -> Int# -> Value s
forall k (s :: k). ByteArray# -> Int# -> Value s
forall k (s :: k). Proxy (Value s) -> Int#
forall k (s :: k). Value s -> Int#
forall k (s :: k) s.
Addr# -> Int# -> Int# -> Value s -> State# s -> State# s
forall k (s :: k) s.
Addr# -> Int# -> State# s -> (# State# s, Value s #)
forall k (s :: k) s.
Addr# -> Int# -> Value s -> State# s -> State# s
forall k (s :: k) s.
MutableByteArray# s
-> Int# -> Int# -> Value s -> State# s -> State# s
forall k (s :: k) s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, Value s #)
forall k (s :: k) s.
MutableByteArray# s -> Int# -> Value s -> State# s -> State# s
$csizeOfType# :: forall k (s :: k). Proxy (Value s) -> Int#
sizeOfType# :: Proxy (Value s) -> Int#
$csizeOf# :: forall k (s :: k). Value s -> Int#
sizeOf# :: Value s -> Int#
$calignmentOfType# :: forall k (s :: k). Proxy (Value s) -> Int#
alignmentOfType# :: Proxy (Value s) -> Int#
$calignment# :: forall k (s :: k). Value s -> Int#
alignment# :: Value s -> Int#
$cindexByteArray# :: forall k (s :: k). ByteArray# -> Int# -> Value s
indexByteArray# :: ByteArray# -> Int# -> Value s
$creadByteArray# :: forall k (s :: k) s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, Value s #)
readByteArray# :: forall s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, Value s #)
$cwriteByteArray# :: forall k (s :: k) s.
MutableByteArray# s -> Int# -> Value s -> State# s -> State# s
writeByteArray# :: forall s.
MutableByteArray# s -> Int# -> Value s -> State# s -> State# s
$csetByteArray# :: forall k (s :: k) s.
MutableByteArray# s
-> Int# -> Int# -> Value s -> State# s -> State# s
setByteArray# :: forall s.
MutableByteArray# s
-> Int# -> Int# -> Value s -> State# s -> State# s
$cindexOffAddr# :: forall k (s :: k). Addr# -> Int# -> Value s
indexOffAddr# :: Addr# -> Int# -> Value s
$creadOffAddr# :: forall k (s :: k) s.
Addr# -> Int# -> State# s -> (# State# s, Value s #)
readOffAddr# :: forall s. Addr# -> Int# -> State# s -> (# State# s, Value s #)
$cwriteOffAddr# :: forall k (s :: k) s.
Addr# -> Int# -> Value s -> State# s -> State# s
writeOffAddr# :: forall s. Addr# -> Int# -> Value s -> State# s -> State# s
$csetOffAddr# :: forall k (s :: k) s.
Addr# -> Int# -> Int# -> Value s -> State# s -> State# s
setOffAddr# :: forall s. Addr# -> Int# -> Int# -> Value s -> State# s -> State# s
Prim, (forall ann. Value s -> Doc ann)
-> (forall ann. [Value s] -> Doc ann) -> Pretty (Value s)
forall ann. [Value s] -> Doc ann
forall ann. Value s -> Doc ann
forall a.
(forall ann. a -> Doc ann)
-> (forall ann. [a] -> Doc ann) -> Pretty a
forall k (s :: k) ann. [Value s] -> Doc ann
forall k (s :: k) ann. Value s -> Doc ann
$cpretty :: forall k (s :: k) ann. Value s -> Doc ann
pretty :: forall ann. Value s -> Doc ann
$cprettyList :: forall k (s :: k) ann. [Value s] -> Doc ann
prettyList :: forall ann. [Value s] -> Doc ann
Pretty)

newtype instance U.MVector s (Value s') = MV_Value (P.MVector s (Value s'))
newtype instance U.Vector    (Value s') = V_Value  (P.Vector    (Value s'))

deriving via (U.UnboxViaPrim (Value s')) instance GM.MVector U.MVector (Value s')
deriving via (U.UnboxViaPrim (Value s')) instance G.Vector   U.Vector  (Value s')

instance U.Unbox (Value s')