{-# LANGUAGE RecordWildCards #-}

-- | A dense, fast `Int` map implemented as a 64-ary tree that covers an interval \([0, n)\).
--
-- ==== __Example__
-- Create an `IntMap` with capacity \(10\):
--
-- >>> import AtCoder.Extra.IntMap qualified as IM
-- >>> im <- IM.new @_ @Int 10
--
-- `insert`, `delete`, `lookup` and other functions are available:
--
-- >>> IM.insert im 0 100
-- >>> IM.insert im 9 101
-- >>> IM.delete im 0
-- True
--
-- >>> IM.size im
-- 1
--
-- >>> IM.lookup im 9
-- Just 101
--
-- >>> IM.lookup im 1
-- Nothing
--
-- >>> IM.lookupGT im 5
-- Just (9,101)
--
-- @since 1.1.0.0
module AtCoder.Extra.IntMap
  ( -- * IntMap
    IntMap,

    -- * Constructors
    new,
    build,

    -- * Metadata
    capacity,
    size,
    null,

    -- * Lookups
    lookup,
    member,
    notMember,

    -- ** Compartive lookups
    lookupGE,
    lookupGT,
    lookupLE,
    lookupLT,

    -- ** Max/Min lookups
    lookupMin,
    lookupMax,

    -- * Modifications

    -- ** Insertions
    insert,
    insertWith,

    -- ** Updates
    modify,
    modifyM,

    -- ** Deletions
    delete,
    delete_,
    deleteMin,
    deleteMax,

    -- * Conversions
    keys,
    elems,
    assocs,
  )
where

import AtCoder.Extra.IntSet qualified as IS
import Control.Monad (when)
import Control.Monad.Primitive (PrimMonad, PrimState)
import Data.Maybe (fromJust)
import Data.Vector.Generic.Mutable qualified as VGM
import Data.Vector.Unboxed qualified as VU
import Data.Vector.Unboxed.Mutable qualified as VUM
import GHC.Stack (HasCallStack)
import Prelude hiding (lookup, null)

-- | A dense, fast `Int` map implemented as a 64-ary tree that covers an interval \([0, n)\).
--
-- @since 1.1.0.0
data IntMap s a = IntMap
  { forall s a. IntMap s a -> IntSet s
setIM :: !(IS.IntSet s),
    forall s a. IntMap s a -> MVector s a
valIM :: !(VUM.MVector s a)
  }

-- | \(O(n)\) Creates an `IntMap` for an interval \([0, n)\).
--
-- @since 1.1.0.0
{-# INLINE new #-}
new :: (PrimMonad m, VU.Unbox a) => Int -> m (IntMap (PrimState m) a)
new :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (IntMap (PrimState m) a)
new Int
cap = do
  IntSet (PrimState m)
setIM <- Int -> m (IntSet (PrimState m))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (IntSet (PrimState m))
IS.new Int
cap
  MVector (PrimState m) a
valIM <- Int -> m (MVector (PrimState m) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
VUM.unsafeNew Int
cap
  IntMap (PrimState m) a -> m (IntMap (PrimState m) a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure IntMap {MVector (PrimState m) a
IntSet (PrimState m)
setIM :: IntSet (PrimState m)
valIM :: MVector (PrimState m) a
setIM :: IntSet (PrimState m)
valIM :: MVector (PrimState m) a
..}

-- | \(O(n + m \log n)\) Creates an `IntMap` for an interval \([0, n)\) with initial values.
--
-- @since 1.1.0.0
{-# INLINE build #-}
build :: (PrimMonad m, VU.Unbox a) => Int -> VU.Vector (Int, a) -> m (IntMap (PrimState m) a)
build :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> Vector (Int, a) -> m (IntMap (PrimState m) a)
build Int
cap Vector (Int, a)
xs = do
  IntMap (PrimState m) a
im <- Int -> m (IntMap (PrimState m) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (IntMap (PrimState m) a)
new Int
cap
  Vector (Int, a) -> ((Int, a) -> m ()) -> m ()
forall (m :: * -> *) a b.
(Monad m, Unbox a) =>
Vector a -> (a -> m b) -> m ()
VU.forM_ Vector (Int, a)
xs (((Int, a) -> m ()) -> m ()) -> ((Int, a) -> m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \(!Int
k, !a
v) -> do
    IntMap (PrimState m) a -> Int -> a -> m ()
forall (m :: * -> *) a.
(HasCallStack, PrimMonad m, Unbox a) =>
IntMap (PrimState m) a -> Int -> a -> m ()
insert IntMap (PrimState m) a
im Int
k a
v
  IntMap (PrimState m) a -> m (IntMap (PrimState m) a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure IntMap (PrimState m) a
im

-- | \(O(1)\) Returns the capacity \(n\), where the interval \([0, n)\) is covered by the map.
--
-- @since 1.1.0.0
{-# INLINE capacity #-}
capacity :: IntMap s a -> Int
capacity :: forall s a. IntMap s a -> Int
capacity = IntSet s -> Int
forall s. IntSet s -> Int
IS.capacity (IntSet s -> Int) -> (IntMap s a -> IntSet s) -> IntMap s a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntMap s a -> IntSet s
forall s a. IntMap s a -> IntSet s
setIM

-- | \(O(1)\) Returns the number of elements in the map.
--
-- @since 1.1.0.0
{-# INLINE size #-}
size :: (PrimMonad m) => IntMap (PrimState m) a -> m Int
size :: forall (m :: * -> *) a.
PrimMonad m =>
IntMap (PrimState m) a -> m Int
size = IntSet (PrimState m) -> m Int
forall (m :: * -> *). PrimMonad m => IntSet (PrimState m) -> m Int
IS.size (IntSet (PrimState m) -> m Int)
-> (IntMap (PrimState m) a -> IntSet (PrimState m))
-> IntMap (PrimState m) a
-> m Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntMap (PrimState m) a -> IntSet (PrimState m)
forall s a. IntMap s a -> IntSet s
setIM

-- | \(O(1)\) Returns whether the map is empty.
--
-- @since 1.1.0.0
{-# INLINE null #-}
null :: (PrimMonad m) => IntMap (PrimState m) a -> m Bool
null :: forall (m :: * -> *) a.
PrimMonad m =>
IntMap (PrimState m) a -> m Bool
null = IntSet (PrimState m) -> m Bool
forall (m :: * -> *). PrimMonad m => IntSet (PrimState m) -> m Bool
IS.null (IntSet (PrimState m) -> m Bool)
-> (IntMap (PrimState m) a -> IntSet (PrimState m))
-> IntMap (PrimState m) a
-> m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntMap (PrimState m) a -> IntSet (PrimState m)
forall s a. IntMap s a -> IntSet s
setIM

-- | \(O(\log n)\) Looks up the value for a key.
--
-- @since 1.1.0.0
{-# INLINE lookup #-}
lookup :: (PrimMonad m, VU.Unbox a) => IntMap (PrimState m) a -> Int -> m (Maybe a)
lookup :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
IntMap (PrimState m) a -> Int -> m (Maybe a)
lookup im :: IntMap (PrimState m) a
im@IntMap {MVector (PrimState m) a
IntSet (PrimState m)
setIM :: forall s a. IntMap s a -> IntSet s
valIM :: forall s a. IntMap s a -> MVector s a
setIM :: IntSet (PrimState m)
valIM :: MVector (PrimState m) a
..} Int
k = do
  IntMap (PrimState m) a -> Int -> m Bool
forall (m :: * -> *) a.
PrimMonad m =>
IntMap (PrimState m) a -> Int -> m Bool
member IntMap (PrimState m) a
im Int
k m Bool -> (Bool -> m (Maybe a)) -> m (Maybe a)
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Bool
True -> a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> m a -> m (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MVector (PrimState m) a -> Int -> m a
forall (m :: * -> *) (v :: * -> * -> *) a.
(HasCallStack, PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
VGM.read MVector (PrimState m) a
valIM Int
k
    Bool
False -> Maybe a -> m (Maybe a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
forall a. Maybe a
Nothing

-- | \(O(\log n)\) Tests whether a key \(k\) is in the map.
--
-- @since 1.1.0.0
{-# INLINE member #-}
member :: (PrimMonad m) => IntMap (PrimState m) a -> Int -> m Bool
member :: forall (m :: * -> *) a.
PrimMonad m =>
IntMap (PrimState m) a -> Int -> m Bool
member = IntSet (PrimState m) -> Int -> m Bool
forall (m :: * -> *).
PrimMonad m =>
IntSet (PrimState m) -> Int -> m Bool
IS.member (IntSet (PrimState m) -> Int -> m Bool)
-> (IntMap (PrimState m) a -> IntSet (PrimState m))
-> IntMap (PrimState m) a
-> Int
-> m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntMap (PrimState m) a -> IntSet (PrimState m)
forall s a. IntMap s a -> IntSet s
setIM

-- | \(O(\log n)\) Tests whether a key \(k\) is not in the map.
--
-- @since 1.1.0.0
{-# INLINE notMember #-}
notMember :: (PrimMonad m) => IntMap (PrimState m) a -> Int -> m Bool
notMember :: forall (m :: * -> *) a.
PrimMonad m =>
IntMap (PrimState m) a -> Int -> m Bool
notMember = IntSet (PrimState m) -> Int -> m Bool
forall (m :: * -> *).
PrimMonad m =>
IntSet (PrimState m) -> Int -> m Bool
IS.notMember (IntSet (PrimState m) -> Int -> m Bool)
-> (IntMap (PrimState m) a -> IntSet (PrimState m))
-> IntMap (PrimState m) a
-> Int
-> m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntMap (PrimState m) a -> IntSet (PrimState m)
forall s a. IntMap s a -> IntSet s
setIM

-- | \(O(\log n)\) Looks up the \((k, v)\) pair with the smallest key \(k\) such that \(k \ge k_0\).
--
-- @since 1.1.0.0
{-# INLINE lookupGE #-}
lookupGE :: (PrimMonad m, VU.Unbox a) => IntMap (PrimState m) a -> Int -> m (Maybe (Int, a))
lookupGE :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
IntMap (PrimState m) a -> Int -> m (Maybe (Int, a))
lookupGE IntMap {MVector (PrimState m) a
IntSet (PrimState m)
setIM :: forall s a. IntMap s a -> IntSet s
valIM :: forall s a. IntMap s a -> MVector s a
setIM :: IntSet (PrimState m)
valIM :: MVector (PrimState m) a
..} Int
k = do
  IntSet (PrimState m) -> Int -> m (Maybe Int)
forall (m :: * -> *).
PrimMonad m =>
IntSet (PrimState m) -> Int -> m (Maybe Int)
IS.lookupGE IntSet (PrimState m)
setIM Int
k m (Maybe Int)
-> (Maybe Int -> m (Maybe (Int, a))) -> m (Maybe (Int, a))
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Just Int
i -> (Int, a) -> Maybe (Int, a)
forall a. a -> Maybe a
Just ((Int, a) -> Maybe (Int, a))
-> (a -> (Int, a)) -> a -> Maybe (Int, a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int
i,) (a -> Maybe (Int, a)) -> m a -> m (Maybe (Int, a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MVector (PrimState m) a -> Int -> m a
forall (m :: * -> *) (v :: * -> * -> *) a.
(HasCallStack, PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
VGM.read MVector (PrimState m) a
valIM Int
i
    Maybe Int
Nothing -> Maybe (Int, a) -> m (Maybe (Int, a))
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (Int, a)
forall a. Maybe a
Nothing

-- | \(O(\log n)\) Looks up the \((k, v)\) pair with the smallest \(k\) such that \(k \gt k_0\).
--
-- @since 1.1.0.0
{-# INLINE lookupGT #-}
lookupGT :: (PrimMonad m, VU.Unbox a) => IntMap (PrimState m) a -> Int -> m (Maybe (Int, a))
lookupGT :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
IntMap (PrimState m) a -> Int -> m (Maybe (Int, a))
lookupGT IntMap (PrimState m) a
is Int
k = IntMap (PrimState m) a -> Int -> m (Maybe (Int, a))
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
IntMap (PrimState m) a -> Int -> m (Maybe (Int, a))
lookupGE IntMap (PrimState m) a
is (Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)

-- | \(O(\log n)\) Looks up the \((k, v)\) pair with the largest key \(k\) such that \(k \le k_0\).
--
-- @since 1.1.0.0
{-# INLINE lookupLE #-}
lookupLE :: (HasCallStack, PrimMonad m, VU.Unbox a) => IntMap (PrimState m) a -> Int -> m (Maybe (Int, a))
lookupLE :: forall (m :: * -> *) a.
(HasCallStack, PrimMonad m, Unbox a) =>
IntMap (PrimState m) a -> Int -> m (Maybe (Int, a))
lookupLE IntMap {MVector (PrimState m) a
IntSet (PrimState m)
setIM :: forall s a. IntMap s a -> IntSet s
valIM :: forall s a. IntMap s a -> MVector s a
setIM :: IntSet (PrimState m)
valIM :: MVector (PrimState m) a
..} Int
k = do
  IntSet (PrimState m) -> Int -> m (Maybe Int)
forall (m :: * -> *).
PrimMonad m =>
IntSet (PrimState m) -> Int -> m (Maybe Int)
IS.lookupLE IntSet (PrimState m)
setIM Int
k m (Maybe Int)
-> (Maybe Int -> m (Maybe (Int, a))) -> m (Maybe (Int, a))
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Just Int
i -> (Int, a) -> Maybe (Int, a)
forall a. a -> Maybe a
Just ((Int, a) -> Maybe (Int, a))
-> (a -> (Int, a)) -> a -> Maybe (Int, a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int
i,) (a -> Maybe (Int, a)) -> m a -> m (Maybe (Int, a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MVector (PrimState m) a -> Int -> m a
forall (m :: * -> *) (v :: * -> * -> *) a.
(HasCallStack, PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
VGM.read MVector (PrimState m) a
valIM Int
i
    Maybe Int
Nothing -> Maybe (Int, a) -> m (Maybe (Int, a))
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (Int, a)
forall a. Maybe a
Nothing

-- | \(O(\log n)\) Looks up the \((k, v)\) pair with the largest key \(k\) such that \(k \lt k_0\).
--
-- @since 1.1.0.0
{-# INLINE lookupLT #-}
lookupLT :: (PrimMonad m, VU.Unbox a) => IntMap (PrimState m) a -> Int -> m (Maybe (Int, a))
lookupLT :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
IntMap (PrimState m) a -> Int -> m (Maybe (Int, a))
lookupLT IntMap (PrimState m) a
is Int
k = IntMap (PrimState m) a -> Int -> m (Maybe (Int, a))
forall (m :: * -> *) a.
(HasCallStack, PrimMonad m, Unbox a) =>
IntMap (PrimState m) a -> Int -> m (Maybe (Int, a))
lookupLE IntMap (PrimState m) a
is (Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)

-- | \(O(\log n)\) Looks up the \((k, v)\) pair with the minimum key \(k\).
--
-- @since 1.1.0.0
{-# INLINE lookupMin #-}
lookupMin :: (PrimMonad m, VU.Unbox a) => IntMap (PrimState m) a -> m (Maybe (Int, a))
lookupMin :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
IntMap (PrimState m) a -> m (Maybe (Int, a))
lookupMin IntMap (PrimState m) a
is = IntMap (PrimState m) a -> Int -> m (Maybe (Int, a))
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
IntMap (PrimState m) a -> Int -> m (Maybe (Int, a))
lookupGE IntMap (PrimState m) a
is Int
0

-- | \(O(\log n)\) Looks up the \((k, v)\) pair with the maximum key \(k\).
--
-- @since 1.1.0.0
{-# INLINE lookupMax #-}
lookupMax :: (PrimMonad m, VU.Unbox a) => IntMap (PrimState m) a -> m (Maybe (Int, a))
lookupMax :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
IntMap (PrimState m) a -> m (Maybe (Int, a))
lookupMax IntMap (PrimState m) a
im = IntMap (PrimState m) a -> Int -> m (Maybe (Int, a))
forall (m :: * -> *) a.
(HasCallStack, PrimMonad m, Unbox a) =>
IntMap (PrimState m) a -> Int -> m (Maybe (Int, a))
lookupLE IntMap (PrimState m) a
im (IntSet (PrimState m) -> Int
forall s. IntSet s -> Int
IS.capacity (IntMap (PrimState m) a -> IntSet (PrimState m)
forall s a. IntMap s a -> IntSet s
setIM IntMap (PrimState m) a
im) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)

-- | \(O(\log n)\) Inserts a \((k, v)\) pair into the map. If an entry with the same key already
-- exists, it is overwritten.
--
-- @since 1.1.0.0
{-# INLINE insert #-}
insert :: (HasCallStack, PrimMonad m, VU.Unbox a) => IntMap (PrimState m) a -> Int -> a -> m ()
insert :: forall (m :: * -> *) a.
(HasCallStack, PrimMonad m, Unbox a) =>
IntMap (PrimState m) a -> Int -> a -> m ()
insert IntMap {MVector (PrimState m) a
IntSet (PrimState m)
setIM :: forall s a. IntMap s a -> IntSet s
valIM :: forall s a. IntMap s a -> MVector s a
setIM :: IntSet (PrimState m)
valIM :: MVector (PrimState m) a
..} Int
k a
v = do
  IntSet (PrimState m) -> Int -> m ()
forall (m :: * -> *).
(HasCallStack, PrimMonad m) =>
IntSet (PrimState m) -> Int -> m ()
IS.insert IntSet (PrimState m)
setIM Int
k
  MVector (PrimState m) a -> Int -> a -> m ()
forall (m :: * -> *) (v :: * -> * -> *) a.
(HasCallStack, PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> a -> m ()
VGM.write MVector (PrimState m) a
valIM Int
k a
v

-- | \(O(\log n)\) Inserts a \((k, v)\) pair into the map. If an entry with the same key already
-- exists, it overwritten with \(f(v_{\mathrm{new}}, v_{\mathrm{old}})\).
--
-- @since 1.1.0.0
{-# INLINE insertWith #-}
insertWith :: (HasCallStack, PrimMonad m, VU.Unbox a) => IntMap (PrimState m) a -> (a -> a -> a) -> Int -> a -> m ()
insertWith :: forall (m :: * -> *) a.
(HasCallStack, PrimMonad m, Unbox a) =>
IntMap (PrimState m) a -> (a -> a -> a) -> Int -> a -> m ()
insertWith IntMap {MVector (PrimState m) a
IntSet (PrimState m)
setIM :: forall s a. IntMap s a -> IntSet s
valIM :: forall s a. IntMap s a -> MVector s a
setIM :: IntSet (PrimState m)
valIM :: MVector (PrimState m) a
..} a -> a -> a
f Int
k a
v = do
  Bool
b <- IntSet (PrimState m) -> Int -> m Bool
forall (m :: * -> *).
PrimMonad m =>
IntSet (PrimState m) -> Int -> m Bool
IS.member IntSet (PrimState m)
setIM Int
k
  if Bool
b
    then do
      MVector (PrimState m) a -> (a -> a) -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) a.
(HasCallStack, PrimMonad m, MVector v a) =>
v (PrimState m) a -> (a -> a) -> Int -> m ()
VGM.modify MVector (PrimState m) a
valIM (a -> a -> a
f a
v) Int
k
    else do
      IntSet (PrimState m) -> Int -> m ()
forall (m :: * -> *).
(HasCallStack, PrimMonad m) =>
IntSet (PrimState m) -> Int -> m ()
IS.insert IntSet (PrimState m)
setIM Int
k
      MVector (PrimState m) a -> Int -> a -> m ()
forall (m :: * -> *) (v :: * -> * -> *) a.
(HasCallStack, PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> a -> m ()
VGM.write MVector (PrimState m) a
valIM Int
k a
v

-- | \(O(\log n)\) Modifies the value associated with a key. If an entry with the same key already
-- does not exist, nothing is performed.
--
-- @since 1.1.0.0
{-# INLINE modify #-}
modify :: (HasCallStack, PrimMonad m, VU.Unbox a) => IntMap (PrimState m) a -> (a -> a) -> Int -> m ()
modify :: forall (m :: * -> *) a.
(HasCallStack, PrimMonad m, Unbox a) =>
IntMap (PrimState m) a -> (a -> a) -> Int -> m ()
modify IntMap {MVector (PrimState m) a
IntSet (PrimState m)
setIM :: forall s a. IntMap s a -> IntSet s
valIM :: forall s a. IntMap s a -> MVector s a
setIM :: IntSet (PrimState m)
valIM :: MVector (PrimState m) a
..} a -> a
f Int
k = do
  Bool
b <- IntSet (PrimState m) -> Int -> m Bool
forall (m :: * -> *).
PrimMonad m =>
IntSet (PrimState m) -> Int -> m Bool
IS.member IntSet (PrimState m)
setIM Int
k
  Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
b (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
    MVector (PrimState m) a -> (a -> a) -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) a.
(HasCallStack, PrimMonad m, MVector v a) =>
v (PrimState m) a -> (a -> a) -> Int -> m ()
VGM.modify MVector (PrimState m) a
valIM a -> a
f Int
k

-- | \(O(\log n)\) Modifies the value associated with a key. If an entry with the same key already
-- does not exist, nothing is performed.
--
-- @since 1.1.0.0
{-# INLINE modifyM #-}
modifyM :: (HasCallStack, PrimMonad m, VU.Unbox a) => IntMap (PrimState m) a -> (a -> m a) -> Int -> m ()
modifyM :: forall (m :: * -> *) a.
(HasCallStack, PrimMonad m, Unbox a) =>
IntMap (PrimState m) a -> (a -> m a) -> Int -> m ()
modifyM IntMap {MVector (PrimState m) a
IntSet (PrimState m)
setIM :: forall s a. IntMap s a -> IntSet s
valIM :: forall s a. IntMap s a -> MVector s a
setIM :: IntSet (PrimState m)
valIM :: MVector (PrimState m) a
..} a -> m a
f Int
k = do
  Bool
b <- IntSet (PrimState m) -> Int -> m Bool
forall (m :: * -> *).
PrimMonad m =>
IntSet (PrimState m) -> Int -> m Bool
IS.member IntSet (PrimState m)
setIM Int
k
  Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
b (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
    MVector (PrimState m) a -> (a -> m a) -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) a.
(HasCallStack, PrimMonad m, MVector v a) =>
v (PrimState m) a -> (a -> m a) -> Int -> m ()
VGM.modifyM MVector (PrimState m) a
valIM a -> m a
f Int
k

-- | \(O(\log n)\) Deletes the \((k, v)\) pair with the key \(k\) from the map. Does nothing if no
-- such key exists. Returns whether the key existed.
--
-- @since 1.1.0.0
{-# INLINE delete #-}
delete :: (PrimMonad m) => IntMap (PrimState m) a -> Int -> m Bool
delete :: forall (m :: * -> *) a.
PrimMonad m =>
IntMap (PrimState m) a -> Int -> m Bool
delete IntMap (PrimState m) a
im = IntSet (PrimState m) -> Int -> m Bool
forall (m :: * -> *).
PrimMonad m =>
IntSet (PrimState m) -> Int -> m Bool
IS.delete (IntMap (PrimState m) a -> IntSet (PrimState m)
forall s a. IntMap s a -> IntSet s
setIM IntMap (PrimState m) a
im)

-- | \(O(\log n)\) Deletes the \((k, v)\) pair with the key \(k\) from the map. Does nothing if no
-- such key exists.
--
-- @since 1.1.0.0
{-# INLINE delete_ #-}
delete_ :: (PrimMonad m) => IntMap (PrimState m) a -> Int -> m ()
delete_ :: forall (m :: * -> *) a.
PrimMonad m =>
IntMap (PrimState m) a -> Int -> m ()
delete_ IntMap (PrimState m) a
im = IntSet (PrimState m) -> Int -> m ()
forall (m :: * -> *).
PrimMonad m =>
IntSet (PrimState m) -> Int -> m ()
IS.delete_ (IntMap (PrimState m) a -> IntSet (PrimState m)
forall s a. IntMap s a -> IntSet s
setIM IntMap (PrimState m) a
im)

-- | \(O(\log n)\) Deletes the \((k, v)\) pair with the minimum key \(k\) in the map.
--
-- @since 1.1.0.0
{-# INLINE deleteMin #-}
deleteMin :: (HasCallStack, PrimMonad m, VU.Unbox a) => IntMap (PrimState m) a -> m (Maybe (Int, a))
deleteMin :: forall (m :: * -> *) a.
(HasCallStack, PrimMonad m, Unbox a) =>
IntMap (PrimState m) a -> m (Maybe (Int, a))
deleteMin IntMap (PrimState m) a
is = do
  IntMap (PrimState m) a -> m (Maybe (Int, a))
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
IntMap (PrimState m) a -> m (Maybe (Int, a))
lookupMin IntMap (PrimState m) a
is
    m (Maybe (Int, a))
-> (Maybe (Int, a) -> m (Maybe (Int, a))) -> m (Maybe (Int, a))
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ((Int, a) -> m (Int, a)) -> Maybe (Int, a) -> m (Maybe (Int, a))
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Maybe a -> m (Maybe b)
mapM
      ( \(!Int
key, !a
val) -> do
          IntMap (PrimState m) a -> Int -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
IntMap (PrimState m) a -> Int -> m ()
delete_ IntMap (PrimState m) a
is Int
key
          (Int, a) -> m (Int, a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
key, a
val)
      )

-- | \(O(\log n)\) Deletes the \((k, v)\) pair with maximum key \(k\) in the map.
--
-- @since 1.1.0.0
{-# INLINE deleteMax #-}
deleteMax :: (HasCallStack, PrimMonad m, VU.Unbox a) => IntMap (PrimState m) a -> m (Maybe (Int, a))
deleteMax :: forall (m :: * -> *) a.
(HasCallStack, PrimMonad m, Unbox a) =>
IntMap (PrimState m) a -> m (Maybe (Int, a))
deleteMax IntMap (PrimState m) a
is = do
  IntMap (PrimState m) a -> m (Maybe (Int, a))
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
IntMap (PrimState m) a -> m (Maybe (Int, a))
lookupMax IntMap (PrimState m) a
is
    m (Maybe (Int, a))
-> (Maybe (Int, a) -> m (Maybe (Int, a))) -> m (Maybe (Int, a))
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ((Int, a) -> m (Int, a)) -> Maybe (Int, a) -> m (Maybe (Int, a))
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Maybe a -> m (Maybe b)
mapM
      ( \(!Int
k, !a
v) -> do
          IntMap (PrimState m) a -> Int -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
IntMap (PrimState m) a -> Int -> m ()
delete_ IntMap (PrimState m) a
is Int
k
          (Int, a) -> m (Int, a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
k, a
v)
      )

-- | \(O(n \log n)\) Enumerates the keys in the map.
--
-- @since 1.1.0.0
{-# INLINE keys #-}
keys :: (PrimMonad m) => IntMap (PrimState m) a -> m (VU.Vector Int)
keys :: forall (m :: * -> *) a.
PrimMonad m =>
IntMap (PrimState m) a -> m (Vector Int)
keys = IntSet (PrimState m) -> m (Vector Int)
forall (m :: * -> *).
PrimMonad m =>
IntSet (PrimState m) -> m (Vector Int)
IS.keys (IntSet (PrimState m) -> m (Vector Int))
-> (IntMap (PrimState m) a -> IntSet (PrimState m))
-> IntMap (PrimState m) a
-> m (Vector Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntMap (PrimState m) a -> IntSet (PrimState m)
forall s a. IntMap s a -> IntSet s
setIM

-- | \(O(n \log n)\) Enumerates the elements (values) in the map.
--
-- @since 1.1.0.0
{-# INLINE elems #-}
elems :: (PrimMonad m, VU.Unbox a) => IntMap (PrimState m) a -> m (VU.Vector a)
elems :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
IntMap (PrimState m) a -> m (Vector a)
elems im :: IntMap (PrimState m) a
im@IntMap {MVector (PrimState m) a
IntSet (PrimState m)
setIM :: forall s a. IntMap s a -> IntSet s
valIM :: forall s a. IntMap s a -> MVector s a
setIM :: IntSet (PrimState m)
valIM :: MVector (PrimState m) a
..} = do
  Int
n <- IntSet (PrimState m) -> m Int
forall (m :: * -> *). PrimMonad m => IntSet (PrimState m) -> m Int
IS.size IntSet (PrimState m)
setIM
  Int -> (Int -> m (a, Int)) -> Int -> m (Vector a)
forall (m :: * -> *) a b.
(Monad m, Unbox a) =>
Int -> (b -> m (a, b)) -> b -> m (Vector a)
VU.unfoldrExactNM
    Int
n
    ( \Int
i -> do
        (!Int
i', !a
x') <- Maybe (Int, a) -> (Int, a)
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe (Int, a) -> (Int, a)) -> m (Maybe (Int, a)) -> m (Int, a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IntMap (PrimState m) a -> Int -> m (Maybe (Int, a))
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
IntMap (PrimState m) a -> Int -> m (Maybe (Int, a))
lookupGT IntMap (PrimState m) a
im Int
i
        (a, Int) -> m (a, Int)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a
x', Int
i')
    )
    (-Int
1)

-- | \(O(n \log n)\) Enumerates the key-value pairs in the map.
--
-- @since 1.1.0.0
{-# INLINE assocs #-}
assocs :: (PrimMonad m, VU.Unbox a) => IntMap (PrimState m) a -> m (VU.Vector (Int, a))
assocs :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
IntMap (PrimState m) a -> m (Vector (Int, a))
assocs im :: IntMap (PrimState m) a
im@IntMap {MVector (PrimState m) a
IntSet (PrimState m)
setIM :: forall s a. IntMap s a -> IntSet s
valIM :: forall s a. IntMap s a -> MVector s a
setIM :: IntSet (PrimState m)
valIM :: MVector (PrimState m) a
..} = do
  Int
n <- IntSet (PrimState m) -> m Int
forall (m :: * -> *). PrimMonad m => IntSet (PrimState m) -> m Int
IS.size IntSet (PrimState m)
setIM
  Int -> (Int -> m ((Int, a), Int)) -> Int -> m (Vector (Int, a))
forall (m :: * -> *) a b.
(Monad m, Unbox a) =>
Int -> (b -> m (a, b)) -> b -> m (Vector a)
VU.unfoldrExactNM
    Int
n
    ( \Int
i -> do
        (!Int
i', !a
x') <- Maybe (Int, a) -> (Int, a)
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe (Int, a) -> (Int, a)) -> m (Maybe (Int, a)) -> m (Int, a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IntMap (PrimState m) a -> Int -> m (Maybe (Int, a))
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
IntMap (PrimState m) a -> Int -> m (Maybe (Int, a))
lookupGT IntMap (PrimState m) a
im Int
i
        ((Int, a), Int) -> m ((Int, a), Int)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Int
i', a
x'), Int
i')
    )
    (-Int
1)