---------------------------------------------------------------------------- -- | -- Module : Data.Emacs.Module.Raw.Value.Internal -- Copyright : (c) Sergey Vinokurov 2022 -- License : Apache-2.0 (see LICENSE) -- Maintainer : serg.foo@gmail.com ---------------------------------------------------------------------------- {-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE DerivingVia #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UnboxedTuples #-} module Data.Emacs.Module.Raw.Value.Internal ( RawValue(..) , Pinning(..) , toUnknown ) where import Control.DeepSeq import Data.Coerce 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 Foreign import GHC.Generics (Generic) import Prettyprinter (Pretty(..)) data Pinning -- | Tag for global values are independent of environment ('Env') that produced it. -- -- Can be used to e.g. cache values that are expensive to compute from scratch. = Pinned -- | Tag denoting regular Emacs values. Will go away after control -- returns to Emacs. | Regular -- | Tag denoting either global or regular emacs values. Cannot tell -- them apart, just pass to Emacs. | Unknown toUnknown :: RawValue p -> RawValue 'Unknown toUnknown = coerce -- | Basic handle on an Emacs value. newtype RawValue (p :: Pinning) = RawValue { unRawValue :: Ptr (RawValue p) } deriving (Show, NFData, Generic, Storable, Prim) instance Pretty (RawValue p) where pretty = pretty . show . unRawValue newtype instance U.MVector s (RawValue p) = MV_RawValue (P.MVector s (RawValue p)) newtype instance U.Vector (RawValue p) = V_RawValue (P.Vector (RawValue p)) deriving via (U.UnboxViaPrim (RawValue p)) instance GM.MVector U.MVector (RawValue p) deriving via (U.UnboxViaPrim (RawValue p)) instance G.Vector U.Vector (RawValue p) instance U.Unbox (RawValue p)