{-# LANGUAGE BangPatterns, FlexibleInstances #-}
module Unsafe.Unique.Prim
( Uniq, getUniq
, unsafeMkUniq, unsafeShowsPrecUniq, unsafeShowUniq
) where
import Control.Monad.Primitive
import Data.IORef
import System.IO.Unsafe
newtype Uniq s = Uniq Integer deriving (Uniq s -> Uniq s -> Bool
(Uniq s -> Uniq s -> Bool)
-> (Uniq s -> Uniq s -> Bool) -> Eq (Uniq s)
forall s. Uniq s -> Uniq s -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Uniq s -> Uniq s -> Bool
$c/= :: forall s. Uniq s -> Uniq s -> Bool
== :: Uniq s -> Uniq s -> Bool
$c== :: forall s. Uniq s -> Uniq s -> Bool
Eq, Eq (Uniq s)
Eq (Uniq s) =>
(Uniq s -> Uniq s -> Ordering)
-> (Uniq s -> Uniq s -> Bool)
-> (Uniq s -> Uniq s -> Bool)
-> (Uniq s -> Uniq s -> Bool)
-> (Uniq s -> Uniq s -> Bool)
-> (Uniq s -> Uniq s -> Uniq s)
-> (Uniq s -> Uniq s -> Uniq s)
-> Ord (Uniq s)
Uniq s -> Uniq s -> Bool
Uniq s -> Uniq s -> Ordering
Uniq s -> Uniq s -> Uniq s
forall s. Eq (Uniq s)
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall s. Uniq s -> Uniq s -> Bool
forall s. Uniq s -> Uniq s -> Ordering
forall s. Uniq s -> Uniq s -> Uniq s
min :: Uniq s -> Uniq s -> Uniq s
$cmin :: forall s. Uniq s -> Uniq s -> Uniq s
max :: Uniq s -> Uniq s -> Uniq s
$cmax :: forall s. Uniq s -> Uniq s -> Uniq s
>= :: Uniq s -> Uniq s -> Bool
$c>= :: forall s. Uniq s -> Uniq s -> Bool
> :: Uniq s -> Uniq s -> Bool
$c> :: forall s. Uniq s -> Uniq s -> Bool
<= :: Uniq s -> Uniq s -> Bool
$c<= :: forall s. Uniq s -> Uniq s -> Bool
< :: Uniq s -> Uniq s -> Bool
$c< :: forall s. Uniq s -> Uniq s -> Bool
compare :: Uniq s -> Uniq s -> Ordering
$ccompare :: forall s. Uniq s -> Uniq s -> Ordering
$cp1Ord :: forall s. Eq (Uniq s)
Ord)
instance Show (Uniq RealWorld) where
showsPrec :: Int -> Uniq RealWorld -> ShowS
showsPrec = Int -> Uniq RealWorld -> ShowS
forall s. Int -> Uniq s -> ShowS
unsafeShowsPrecUniq
{-# NOINLINE nextUniq #-}
nextUniq :: IORef Integer
nextUniq :: IORef Integer
nextUniq = IO (IORef Integer) -> IORef Integer
forall a. IO a -> a
unsafePerformIO (Integer -> IO (IORef Integer)
forall a. a -> IO (IORef a)
newIORef 0)
getUniq :: PrimMonad m => m (Uniq (PrimState m))
getUniq :: m (Uniq (PrimState m))
getUniq = IO (Uniq (PrimState m)) -> m (Uniq (PrimState m))
forall (m1 :: * -> *) (m2 :: * -> *) a.
(PrimBase m1, PrimMonad m2) =>
m1 a -> m2 a
unsafePrimToPrim (IORef Integer
-> (Integer -> (Integer, Uniq (PrimState m)))
-> IO (Uniq (PrimState m))
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' IORef Integer
nextUniq (\u :: Integer
u -> (Integer
uInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+1, Integer -> Uniq (PrimState m)
forall s. Integer -> Uniq s
Uniq Integer
u)))
unsafeMkUniq :: Integer -> Uniq s
unsafeMkUniq :: Integer -> Uniq s
unsafeMkUniq n :: Integer
n = Integer -> Uniq s
forall s. Integer -> Uniq s
Uniq Integer
n
unsafeShowsPrecUniq :: Int -> Uniq s -> ShowS
unsafeShowsPrecUniq :: Int -> Uniq s -> ShowS
unsafeShowsPrecUniq p :: Int
p (Uniq u :: Integer
u) = Int -> Integer -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
p Integer
u
unsafeShowUniq :: Uniq s -> String
unsafeShowUniq :: Uniq s -> String
unsafeShowUniq (Uniq u :: Integer
u) = Integer -> String
forall a. Show a => a -> String
show Integer
u