{-# LANGUAGE MultiParamTypeClasses #-} 

module OpenCascade.Inheritance 
( SubTypeOf (..)
, DiscriminatedSubTypeOf (..)
, unsafeDowncast
) where

import Foreign.Ptr

class SubTypeOf a b where
    upcast :: Ptr b -> Ptr a
    upcast = Ptr b -> Ptr a
forall a b. Ptr a -> Ptr b
castPtr

class SubTypeOf a b => DiscriminatedSubTypeOf a b where
    downcast :: Ptr a -> IO (Maybe (Ptr b))

unsafeDowncast :: DiscriminatedSubTypeOf a b => Ptr a -> IO (Ptr b)
unsafeDowncast :: forall a b. DiscriminatedSubTypeOf a b => Ptr a -> IO (Ptr b)
unsafeDowncast Ptr a
p = do
    Maybe (Ptr b)
maybeT <- Ptr a -> IO (Maybe (Ptr b))
forall a b.
DiscriminatedSubTypeOf a b =>
Ptr a -> IO (Maybe (Ptr b))
downcast Ptr a
p
    IO (Ptr b) -> (Ptr b -> IO (Ptr b)) -> Maybe (Ptr b) -> IO (Ptr b)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ([Char] -> IO (Ptr b)
forall a. HasCallStack => [Char] -> a
error [Char]
"Incorrect subtype in cast") Ptr b -> IO (Ptr b)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (Ptr b)
maybeT