{-# language CPP #-}
{-# language GeneralizedNewtypeDeriving #-}
{-# language UndecidableSuperClasses #-}
#ifndef HLINT
{-# language FunctionalDependencies #-}
#endif
{-# language QuantifiedConstraints #-}
{-# language MultiParamTypeClasses #-}
{-# language AllowAmbiguousTypes #-}
{-# language ScopedTypeVariables #-}
{-# language DeriveDataTypeable #-}
{-# language FlexibleContexts #-}
{-# language TypeApplications #-}
{-# language ConstraintKinds #-}
{-# language TypeOperators #-}
{-# language TypeFamilies #-}
{-# language RankNTypes #-}
{-# language PolyKinds #-}
module Data.Const.Unsafe
( Constable
, ConstPtr(..)
, ConstForeignPtr(..)
, ConstArray(..)
, ConstByteArray(..)
, ConstPrimArray(..)
, ConstMutVar(..)
, ConstIORef(..)
, ConstSTRef(..)
, SmallConstArray(..)
, ConstCString
, ConstCStringLen
, ConstCWString
, ConstCWStringLen
, constant, unsafeConstantCoercion
, APtr, unsafePtr, unsafePtrCoercion
, AForeignPtr, unsafeForeignPtr, unsafeForeignPtrCoercion
, AnArray, unsafeArray, unsafeArrayCoercion
, AByteArray, unsafeByteArray, unsafeByteArrayCoercion
, APrimArray, unsafePrimArray, unsafePrimArrayCoercion
, ASmallArray, unsafeSmallArray, unsafeSmallArrayCoercion
, AMutVar, unsafeMutVar, unsafeMutVarCoercion
, AnIORef, unsafeIORef, unsafeIORefCoercion
, AnSTRef, unsafeSTRef, unsafeSTRefCoercion
, ACString, unsafeCStringCoercion
, ACWString, unsafeCWStringCoercion
) where
import Data.Coerce
import Data.Data
import Data.IORef
import Data.Primitive.Array
import Data.Primitive.ByteArray
import Data.Primitive.PrimArray
import Data.Primitive.SmallArray
import Data.Primitive.MutVar
import Data.STRef
import Data.Type.Coercion
import Foreign.C.String
import Foreign.C.Types
import Foreign.Ptr
import Foreign.Ptr.Diff
import Foreign.ForeignPtr
import Foreign.Storable
import Control.Category
import Prelude hiding (id,(.))
#ifndef HLINT
class (Constable q q, forall a. Coercible (q a) (p a)) => Constable q p | p -> q
#endif
constant :: forall p a q. Constable q p => p a -> q a
constant = coerceWith (sym unsafeConstantCoercion)
{-# inline constant #-}
unsafeConstantCoercion :: forall p a q. Constable q p => Coercion (q a) (p a)
unsafeConstantCoercion = Coercion
{-# inline unsafeConstantCoercion #-}
uncoerceWith :: Coercion a b -> b -> a
uncoerceWith = coerceWith . sym
{-# inline uncoerceWith #-}
newtype ConstPtr a = ConstPtr { unsafeConstPtrPtr :: Ptr a } deriving (Eq,Ord,Show,Data,Storable,DiffTorsor)
instance Constable ConstPtr Ptr
instance Constable ConstPtr ConstPtr
type APtr = Constable ConstPtr
unsafePtrCoercion :: forall p a. APtr p => Coercion (Ptr a) (p a)
unsafePtrCoercion = unsafeConstantCoercion @p @a . Coercion
{-# inline unsafePtrCoercion #-}
unsafePtr :: forall p a. APtr p => p a -> Ptr a
unsafePtr = uncoerceWith (unsafePtrCoercion @p)
{-# inline unsafePtr #-}
newtype ConstForeignPtr a = ConstForeignPtr { unsafeConstForeignPtrForeignPtr :: ForeignPtr a } deriving (Eq,Ord,Show,Data,DiffTorsor)
instance Constable ConstForeignPtr ForeignPtr
instance Constable ConstForeignPtr ConstForeignPtr
type AForeignPtr = Constable ConstForeignPtr
unsafeForeignPtrCoercion :: forall p a. AForeignPtr p => Coercion (ForeignPtr a) (p a)
unsafeForeignPtrCoercion = unsafeConstantCoercion @p @a . Coercion
{-# inline unsafeForeignPtrCoercion #-}
unsafeForeignPtr :: forall p a. AForeignPtr p => p a -> ForeignPtr a
unsafeForeignPtr = coerceWith (sym (unsafeForeignPtrCoercion @p))
{-# inline unsafeForeignPtr #-}
newtype ConstIORef a = ConstIORef { unsafeConstIORefIORef :: IORef a } deriving Eq
instance Constable ConstIORef IORef
instance Constable ConstIORef ConstIORef
type AnIORef = Constable ConstIORef
unsafeIORefCoercion :: forall p a. AnIORef p => Coercion (IORef a) (p a)
unsafeIORefCoercion = unsafeConstantCoercion @p @a . Coercion
{-# inline unsafeIORefCoercion #-}
unsafeIORef :: forall p a. AnIORef p => p a -> IORef a
unsafeIORef = uncoerceWith (unsafeIORefCoercion @p)
{-# inline unsafeIORef #-}
newtype ConstArray s a = ConstArray { unsafeConstArrayMutableArray :: MutableArray s a } deriving Eq
instance Constable (ConstArray s) (MutableArray s)
instance Constable (ConstArray s) (ConstArray s)
type AnArray s = Constable (ConstArray s)
unsafeArrayCoercion :: forall s p a. AnArray s p => Coercion (MutableArray s a) (p a)
unsafeArrayCoercion = unsafeConstantCoercion @p @a . Coercion
{-# inline unsafeArrayCoercion #-}
unsafeArray :: forall s p a. AnArray s p => p a -> MutableArray s a
unsafeArray = uncoerceWith (unsafeArrayCoercion @s @p)
{-# inline unsafeArray #-}
newtype ConstByteArray s = ConstByteArray { unsafeConstByteArrayMutableByteArray :: MutableByteArray s }
instance Eq (ConstByteArray s) where
(==) = coerce (sameMutableByteArray @s)
instance Constable ConstByteArray MutableByteArray
instance Constable ConstByteArray ConstByteArray
type AByteArray = Constable ConstByteArray
unsafeByteArrayCoercion :: forall p s. AByteArray p => Coercion (MutableByteArray s) (p s)
unsafeByteArrayCoercion = unsafeConstantCoercion @p @s. Coercion
{-# inline unsafeByteArrayCoercion #-}
unsafeByteArray :: forall s p. AByteArray p => p s -> MutableByteArray s
unsafeByteArray = uncoerceWith (unsafeByteArrayCoercion @p @s)
{-# inline unsafeByteArray #-}
newtype ConstPrimArray s a = ConstPrimArray { unsafeConstPrimArrayMutablePrimArray :: MutablePrimArray s a }
instance Eq (ConstPrimArray s a) where
(==) = coerce (sameMutablePrimArray @s)
instance Constable (ConstPrimArray s) (MutablePrimArray s)
instance Constable (ConstPrimArray s) (ConstPrimArray s)
type APrimArray s = Constable (ConstPrimArray s)
unsafePrimArrayCoercion :: forall s p a. APrimArray s p => Coercion (MutablePrimArray s a) (p a)
unsafePrimArrayCoercion = unsafeConstantCoercion @p @a . Coercion
{-# inline unsafePrimArrayCoercion #-}
unsafePrimArray :: forall s p a. APrimArray s p => p a -> MutablePrimArray s a
unsafePrimArray = uncoerceWith (unsafePrimArrayCoercion @s @p)
{-# inline unsafePrimArray #-}
newtype SmallConstArray s a = SmallConstArray { unsafeSmallConstArraySmallMutableArray :: SmallMutableArray s a } deriving Eq
instance Constable (SmallConstArray s) (SmallMutableArray s)
instance Constable (SmallConstArray s) (SmallConstArray s)
type ASmallArray s = Constable (SmallConstArray s)
unsafeSmallArrayCoercion :: forall s p a. ASmallArray s p => Coercion (SmallMutableArray s a) (p a)
unsafeSmallArrayCoercion = unsafeConstantCoercion @p @a . Coercion
{-# inline unsafeSmallArrayCoercion #-}
unsafeSmallArray :: forall s p a. ASmallArray s p => p a -> SmallMutableArray s a
unsafeSmallArray = uncoerceWith (unsafeSmallArrayCoercion @s @p)
{-# inline unsafeSmallArray #-}
newtype ConstMutVar s a = ConstMutVar { unsafeConstMutVarMutVar :: MutVar s a } deriving Eq
instance Constable (ConstMutVar s) (MutVar s)
instance Constable (ConstMutVar s) (ConstMutVar s)
type AMutVar s = Constable (ConstMutVar s)
unsafeMutVarCoercion :: forall s p a. AMutVar s p => Coercion (MutVar s a) (p a)
unsafeMutVarCoercion = unsafeConstantCoercion @p @a . Coercion
{-# inline unsafeMutVarCoercion #-}
unsafeMutVar :: forall s p a. AMutVar s p => p a -> MutVar s a
unsafeMutVar = uncoerceWith (unsafeMutVarCoercion @s @p)
{-# inline unsafeMutVar #-}
newtype ConstSTRef s a = ConstSTRef { unsafeConstSTRefSTRef :: STRef s a } deriving Eq
instance Constable (ConstSTRef s) (STRef s)
instance Constable (ConstSTRef s) (ConstSTRef s)
type AnSTRef s = Constable (ConstSTRef s)
unsafeSTRefCoercion :: forall s p a. AnSTRef s p => Coercion (STRef s a) (p a)
unsafeSTRefCoercion = unsafeConstantCoercion @p @a . Coercion
{-# inline unsafeSTRefCoercion #-}
unsafeSTRef :: forall s p a. AnSTRef s p => p a -> STRef s a
unsafeSTRef = uncoerceWith (unsafeSTRefCoercion @s @p)
{-# inline unsafeSTRef #-}
type family Unapply s :: * -> * where
Unapply (p CChar) = p
type ConstCString = ConstPtr CChar
type ConstCStringLen = (ConstCString, Int)
type ConstCWString = ConstPtr CWchar
type ConstCWStringLen = (ConstCWString, Int)
type ACWString s = (s ~ Unapply s CWchar, APtr (Unapply s))
type ACString s = (s ~ Unapply s CChar, APtr (Unapply s))
unsafeCStringCoercion :: forall s. ACString s => Coercion CString s
unsafeCStringCoercion = unsafePtrCoercion @(Unapply s) @CChar
{-# inline unsafeCStringCoercion #-}
unsafeCWStringCoercion :: forall s. ACWString s => Coercion CWString s
unsafeCWStringCoercion = unsafePtrCoercion @(Unapply s) @CWchar
{-# inline unsafeCWStringCoercion #-}