{-# LANGUAGE BangPatterns, Safe #-}
module Data.RangeSet.Primitives (empty, member, insert, delete, fold) where

import Prelude
import Data.RangeSet.Internal

{-|
The empty `RangeSet`.

@since 0.0.1.0
-}
{-# INLINE empty #-}
empty :: RangeSet a
empty :: forall a. RangeSet a
empty = forall a. RangeSet a
Tip

{-|
Test whether or not a given value is found within the set.

@since 0.0.1.0
-}
{-# INLINEABLE member #-}
member :: Enum a => a -> RangeSet a -> Bool
member :: forall a. Enum a => a -> RangeSet a -> Bool
member !a
x = forall a. RangeSet a -> Bool
go
  where
    !x' :: Int
x' = forall a. Enum a => a -> Int
fromEnum a
x
    go :: RangeSet a -> Bool
    go :: forall a. RangeSet a -> Bool
go (Fork H
_ Int
l Int
u RangeSet a
lt RangeSet a
rt)
      | Int
l forall a. Ord a => a -> a -> Bool
<= Int
x'   = Int
x' forall a. Ord a => a -> a -> Bool
<= Int
u Bool -> Bool -> Bool
|| forall a. RangeSet a -> Bool
go RangeSet a
rt
      | Bool
otherwise = forall a. RangeSet a -> Bool
go RangeSet a
lt
    go RangeSet a
Tip = Bool
False

{-|
Insert a new element into the set.

@since 0.0.1.0
-}
{-# INLINEABLE insert #-}
insert :: Enum a => a -> RangeSet a -> RangeSet a
insert :: forall a. Enum a => a -> RangeSet a -> RangeSet a
insert = forall a. Int -> RangeSet a -> RangeSet a
insertE forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Enum a => a -> Int
fromEnum

{-|
Remove an element from the set, if it appears.

@since 0.0.1.0
-}
{-# INLINEABLE delete #-}
delete :: Enum a => a -> RangeSet a -> RangeSet a
delete :: forall a. Enum a => a -> RangeSet a -> RangeSet a
delete = forall a. Int -> RangeSet a -> RangeSet a
deleteE forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Enum a => a -> Int
fromEnum

{-|
Folds a range set.

@since 0.0.1.0
-}
{-# INLINEABLE fold #-}
fold :: Enum a
     => (a -> a -> b -> b -> b) -- ^ Function that combines the lower and upper values (inclusive) for a range with the folded left- and right-subtrees.
     -> b                       -- ^ Value to be substituted at the leaves.
     -> RangeSet a
     -> b
fold :: forall a b.
Enum a =>
(a -> a -> b -> b -> b) -> b -> RangeSet a -> b
fold a -> a -> b -> b -> b
fork = forall b a. (Int -> Int -> b -> b -> b) -> b -> RangeSet a -> b
foldE (\Int
l Int
u -> a -> a -> b -> b -> b
fork (forall a. Enum a => Int -> a
toEnum Int
l) (forall a. Enum a => Int -> a
toEnum Int
u))