{-# 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
$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
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
$ccompare :: forall s. Uniq s -> Uniq s -> Ordering
compare :: Uniq s -> Uniq s -> Ordering
$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
>= :: Uniq s -> Uniq s -> Bool
$cmax :: forall s. Uniq s -> Uniq s -> Uniq s
max :: Uniq s -> Uniq s -> Uniq s
$cmin :: forall s. Uniq s -> Uniq s -> Uniq s
min :: Uniq s -> Uniq s -> 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 Integer
0)
getUniq :: PrimMonad m => m (Uniq (PrimState m))
getUniq :: forall (m :: * -> *). PrimMonad m => 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 (\Integer
u -> (Integer
uInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
1, Integer -> Uniq (PrimState m)
forall s. Integer -> Uniq s
Uniq Integer
u)))
unsafeMkUniq :: Integer -> Uniq s
unsafeMkUniq :: forall s. Integer -> Uniq s
unsafeMkUniq Integer
n = Integer -> Uniq s
forall s. Integer -> Uniq s
Uniq Integer
n
unsafeShowsPrecUniq :: Int -> Uniq s -> ShowS
unsafeShowsPrecUniq :: forall s. Int -> Uniq s -> ShowS
unsafeShowsPrecUniq Int
p (Uniq Integer
u) = Int -> Integer -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
p Integer
u
unsafeShowUniq :: Uniq s -> String
unsafeShowUniq :: forall s. Uniq s -> String
unsafeShowUniq (Uniq Integer
u) = Integer -> String
forall a. Show a => a -> String
show Integer
u