packages feed

emacs-module-0.2.1: src/Data/Emacs/Module/Value/Internal.hs

----------------------------------------------------------------------------
-- |
-- 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
  { unValue :: RawValue 'Regular
  } deriving (Show, NFData, Generic, Prim, 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')