{-# LANGUAGE BangPatterns               #-}
{-# LANGUAGE BlockArguments             #-}
{-# LANGUAGE DataKinds                  #-}
{-# LANGUAGE DeriveDataTypeable         #-}
{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE PolyKinds                  #-}
{-# LANGUAGE ScopedTypeVariables        #-}
{-# LANGUAGE TypeFamilies               #-}
{-# LANGUAGE UnboxedTuples              #-}
{-# LANGUAGE UnicodeSyntax              #-}

-- | Efficient sets over bounded enumerations, using bitwise operations based on

-- [containers](https://hackage.haskell.org/package/containers-0.6.0.1/docs/src/Data.IntSet.Internal.html)

-- and

-- [EdisonCore](https://hackage.haskell.org/package/EdisonCore-1.3.2.1/docs/src/Data-Edison-Coll-EnumSet.html).

-- In many cases, @EnumSet@s may be optimised away entirely by constant folding

-- at compile-time. For example, in the following code:

--

-- @

--

-- import Data.Enum.Set.Base as E

--

-- data Foo = A | B | C | D | E | F | G | H deriving (Bounded, Enum, Eq, Ord, Show)

--

-- addFoos :: E.EnumSet Word Foo -> E.EnumSet Word Foo

-- addFoos = E.delete A . E.insert B

--

-- bar :: E.EnumSet Word Foo

-- bar = addFoos $ E.fromFoldable [A, C, E]

--

-- barHasB :: Bool

-- barHasB = E.member A bar

--

-- @

--

-- With @-O@ or @-O2@, @bar@ will compile to @GHC.Types.W\# 22\#\#@ and

-- @barHasA@ will compile to @GHC.Types.False@.

--

-- For type @EnumSet W E@, @W@ should be a 'Word'-like type that implements

-- 'Bits' and 'Num', and @E@ should be a type that implements 'Eq' and 'Enum'

-- equivalently and is a bijection to 'Int' over its range.

-- @EnumSet W E@ can only store a value of @E@ if the result of applying

-- 'fromEnum' to the value is positive and less than the number of bits in @W@.

-- For this reason, it is preferable for @E@ to be a type that derives 'Eq' and

-- 'Enum', and for @W@ to have more bits than the number of constructors of @E@.

--

-- For type @EnumSet W E@, if the highest @fromEnum@ value of @E@ is 29,

-- @W@ should be 'Data.Word.Word', because it always has at least 30 bits.

-- Otherwise, options include 'Data.Word.Word32', 'Data.Word.Word64', and the

-- [wide-word](https://hackage.haskell.org/package/wide-word-0.1.0.8/) package's

-- [Data.WideWord.Word128](https://hackage.haskell.org/package/wide-word-0.1.0.8/docs/Data-WideWord-Word128.html).

-- Foreign types may also be used.

--

-- "Data.Enum.Set" provides an alternate type alias that moves the underlying

-- representation to an associated type token, so that e.g.

-- @EnumSet Word64 MyEnum@ is replaced by @EnumSet MyEnum@, and reexports this

-- module with adjusted type signatures.

--

-- Note: complexity calculations assume that @W@ implements 'Bits' with

-- constant-time functions, as is the case with 'Data.Word.Word' etc. If this

-- is not the case, the complexity of those operations should be added to the

-- complexity of 'EnumSet' functions.

module Data.Enum.Set.Base
  ( -- * Set type

    EnumSet

    -- * Construction

  , empty
  , singleton
  , fromFoldable

  -- * Insertion

  , insert

  -- * Deletion

  , delete

  -- * Query

  , member
  , notMember
  , null
  , size
  , isSubsetOf

  -- * Combine

  , union
  , difference
  , (\\)
  , symmetricDifference
  , intersection

  -- * Filter

  , filter
  , partition

  -- * Map

  , map
  , map'

  -- * Folds

  , foldl, foldl', foldr, foldr'
  , foldl1, foldl1', foldr1, foldr1'

  -- ** Special folds

  , foldMap
  , traverse
  , any
  , all

   -- * Min/Max

  , minimum
  , maximum
  , deleteMin
  , deleteMax
  , minView
  , maxView

  -- * Conversion

  , toList
  , fromRaw
  ) where

import qualified GHC.Exts
import qualified Data.Foldable as F

import Prelude hiding (all, any, filter, foldl, foldl1, foldMap, foldr, foldr1, map, maximum, minimum, null, traverse)

import Control.Applicative (liftA2)
import Control.DeepSeq (NFData)
import Data.Aeson (ToJSON(..))
import Data.Bits
import Data.Data (Data)
import Data.Vector.Unboxed (Vector, MVector, Unbox)
import Foreign.Storable (Storable)
import GHC.Exts (IsList(Item), build)
import Text.Read

import qualified Data.Vector.Generic as G
import qualified Data.Vector.Generic.Mutable as M
import qualified Data.Vector.Primitive as P

import qualified Data.Containers
import           Data.Containers (SetContainer, IsSet)
import qualified Data.MonoTraversable
import           Data.MonoTraversable (Element, GrowingAppend, MonoFoldable, MonoFunctor, MonoPointed, MonoTraversable)

{--------------------------------------------------------------------
  Set type
--------------------------------------------------------------------}

-- | A set of values @a@ with representation @word@,

-- implemented as bitwise operations.

newtype EnumSet word a = EnumSet word
    deriving (EnumSet word a -> EnumSet word a -> Bool
(EnumSet word a -> EnumSet word a -> Bool)
-> (EnumSet word a -> EnumSet word a -> Bool)
-> Eq (EnumSet word a)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall word k (a :: k).
Eq word =>
EnumSet word a -> EnumSet word a -> Bool
/= :: EnumSet word a -> EnumSet word a -> Bool
$c/= :: forall word k (a :: k).
Eq word =>
EnumSet word a -> EnumSet word a -> Bool
== :: EnumSet word a -> EnumSet word a -> Bool
$c== :: forall word k (a :: k).
Eq word =>
EnumSet word a -> EnumSet word a -> Bool
Eq, Eq (EnumSet word a)
Eq (EnumSet word a)
-> (EnumSet word a -> EnumSet word a -> Ordering)
-> (EnumSet word a -> EnumSet word a -> Bool)
-> (EnumSet word a -> EnumSet word a -> Bool)
-> (EnumSet word a -> EnumSet word a -> Bool)
-> (EnumSet word a -> EnumSet word a -> Bool)
-> (EnumSet word a -> EnumSet word a -> EnumSet word a)
-> (EnumSet word a -> EnumSet word a -> EnumSet word a)
-> Ord (EnumSet word a)
EnumSet word a -> EnumSet word a -> Bool
EnumSet word a -> EnumSet word a -> Ordering
EnumSet word a -> EnumSet word a -> EnumSet word a
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 word k (a :: k). Ord word => Eq (EnumSet word a)
forall word k (a :: k).
Ord word =>
EnumSet word a -> EnumSet word a -> Bool
forall word k (a :: k).
Ord word =>
EnumSet word a -> EnumSet word a -> Ordering
forall word k (a :: k).
Ord word =>
EnumSet word a -> EnumSet word a -> EnumSet word a
min :: EnumSet word a -> EnumSet word a -> EnumSet word a
$cmin :: forall word k (a :: k).
Ord word =>
EnumSet word a -> EnumSet word a -> EnumSet word a
max :: EnumSet word a -> EnumSet word a -> EnumSet word a
$cmax :: forall word k (a :: k).
Ord word =>
EnumSet word a -> EnumSet word a -> EnumSet word a
>= :: EnumSet word a -> EnumSet word a -> Bool
$c>= :: forall word k (a :: k).
Ord word =>
EnumSet word a -> EnumSet word a -> Bool
> :: EnumSet word a -> EnumSet word a -> Bool
$c> :: forall word k (a :: k).
Ord word =>
EnumSet word a -> EnumSet word a -> Bool
<= :: EnumSet word a -> EnumSet word a -> Bool
$c<= :: forall word k (a :: k).
Ord word =>
EnumSet word a -> EnumSet word a -> Bool
< :: EnumSet word a -> EnumSet word a -> Bool
$c< :: forall word k (a :: k).
Ord word =>
EnumSet word a -> EnumSet word a -> Bool
compare :: EnumSet word a -> EnumSet word a -> Ordering
$ccompare :: forall word k (a :: k).
Ord word =>
EnumSet word a -> EnumSet word a -> Ordering
$cp1Ord :: forall word k (a :: k). Ord word => Eq (EnumSet word a)
Ord, Typeable (EnumSet word a)
DataType
Constr
Typeable (EnumSet word a)
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> EnumSet word a -> c (EnumSet word a))
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (EnumSet word a))
-> (EnumSet word a -> Constr)
-> (EnumSet word a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (EnumSet word a)))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (EnumSet word a)))
-> ((forall b. Data b => b -> b)
    -> EnumSet word a -> EnumSet word a)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> EnumSet word a -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> EnumSet word a -> r)
-> (forall u.
    (forall d. Data d => d -> u) -> EnumSet word a -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> EnumSet word a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> EnumSet word a -> m (EnumSet word a))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> EnumSet word a -> m (EnumSet word a))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> EnumSet word a -> m (EnumSet word a))
-> Data (EnumSet word a)
EnumSet word a -> DataType
EnumSet word a -> Constr
(forall b. Data b => b -> b) -> EnumSet word a -> EnumSet word a
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> EnumSet word a -> c (EnumSet word a)
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (EnumSet word a)
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u.
Int -> (forall d. Data d => d -> u) -> EnumSet word a -> u
forall u. (forall d. Data d => d -> u) -> EnumSet word a -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> EnumSet word a -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> EnumSet word a -> r
forall word k (a :: k).
(Typeable a, Typeable k, Data word) =>
Typeable (EnumSet word a)
forall word k (a :: k).
(Typeable a, Typeable k, Data word) =>
EnumSet word a -> DataType
forall word k (a :: k).
(Typeable a, Typeable k, Data word) =>
EnumSet word a -> Constr
forall word k (a :: k).
(Typeable a, Typeable k, Data word) =>
(forall b. Data b => b -> b) -> EnumSet word a -> EnumSet word a
forall word k (a :: k) u.
(Typeable a, Typeable k, Data word) =>
Int -> (forall d. Data d => d -> u) -> EnumSet word a -> u
forall word k (a :: k) u.
(Typeable a, Typeable k, Data word) =>
(forall d. Data d => d -> u) -> EnumSet word a -> [u]
forall word k (a :: k) r r'.
(Typeable a, Typeable k, Data word) =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> EnumSet word a -> r
forall word k (a :: k) r r'.
(Typeable a, Typeable k, Data word) =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> EnumSet word a -> r
forall word k (a :: k) (m :: * -> *).
(Typeable a, Typeable k, Data word, Monad m) =>
(forall d. Data d => d -> m d)
-> EnumSet word a -> m (EnumSet word a)
forall word k (a :: k) (m :: * -> *).
(Typeable a, Typeable k, Data word, MonadPlus m) =>
(forall d. Data d => d -> m d)
-> EnumSet word a -> m (EnumSet word a)
forall word k (a :: k) (c :: * -> *).
(Typeable a, Typeable k, Data word) =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (EnumSet word a)
forall word k (a :: k) (c :: * -> *).
(Typeable a, Typeable k, Data word) =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> EnumSet word a -> c (EnumSet word a)
forall word k (a :: k) (t :: * -> *) (c :: * -> *).
(Typeable a, Typeable k, Data word, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (EnumSet word a))
forall word k (a :: k) (t :: * -> * -> *) (c :: * -> *).
(Typeable a, Typeable k, Data word, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (EnumSet word a))
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> EnumSet word a -> m (EnumSet word a)
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> EnumSet word a -> m (EnumSet word a)
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (EnumSet word a)
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> EnumSet word a -> c (EnumSet word a)
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (EnumSet word a))
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (EnumSet word a))
$cEnumSet :: Constr
$tEnumSet :: DataType
gmapMo :: (forall d. Data d => d -> m d)
-> EnumSet word a -> m (EnumSet word a)
$cgmapMo :: forall word k (a :: k) (m :: * -> *).
(Typeable a, Typeable k, Data word, MonadPlus m) =>
(forall d. Data d => d -> m d)
-> EnumSet word a -> m (EnumSet word a)
gmapMp :: (forall d. Data d => d -> m d)
-> EnumSet word a -> m (EnumSet word a)
$cgmapMp :: forall word k (a :: k) (m :: * -> *).
(Typeable a, Typeable k, Data word, MonadPlus m) =>
(forall d. Data d => d -> m d)
-> EnumSet word a -> m (EnumSet word a)
gmapM :: (forall d. Data d => d -> m d)
-> EnumSet word a -> m (EnumSet word a)
$cgmapM :: forall word k (a :: k) (m :: * -> *).
(Typeable a, Typeable k, Data word, Monad m) =>
(forall d. Data d => d -> m d)
-> EnumSet word a -> m (EnumSet word a)
gmapQi :: Int -> (forall d. Data d => d -> u) -> EnumSet word a -> u
$cgmapQi :: forall word k (a :: k) u.
(Typeable a, Typeable k, Data word) =>
Int -> (forall d. Data d => d -> u) -> EnumSet word a -> u
gmapQ :: (forall d. Data d => d -> u) -> EnumSet word a -> [u]
$cgmapQ :: forall word k (a :: k) u.
(Typeable a, Typeable k, Data word) =>
(forall d. Data d => d -> u) -> EnumSet word a -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> EnumSet word a -> r
$cgmapQr :: forall word k (a :: k) r r'.
(Typeable a, Typeable k, Data word) =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> EnumSet word a -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> EnumSet word a -> r
$cgmapQl :: forall word k (a :: k) r r'.
(Typeable a, Typeable k, Data word) =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> EnumSet word a -> r
gmapT :: (forall b. Data b => b -> b) -> EnumSet word a -> EnumSet word a
$cgmapT :: forall word k (a :: k).
(Typeable a, Typeable k, Data word) =>
(forall b. Data b => b -> b) -> EnumSet word a -> EnumSet word a
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (EnumSet word a))
$cdataCast2 :: forall word k (a :: k) (t :: * -> * -> *) (c :: * -> *).
(Typeable a, Typeable k, Data word, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (EnumSet word a))
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c (EnumSet word a))
$cdataCast1 :: forall word k (a :: k) (t :: * -> *) (c :: * -> *).
(Typeable a, Typeable k, Data word, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (EnumSet word a))
dataTypeOf :: EnumSet word a -> DataType
$cdataTypeOf :: forall word k (a :: k).
(Typeable a, Typeable k, Data word) =>
EnumSet word a -> DataType
toConstr :: EnumSet word a -> Constr
$ctoConstr :: forall word k (a :: k).
(Typeable a, Typeable k, Data word) =>
EnumSet word a -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (EnumSet word a)
$cgunfold :: forall word k (a :: k) (c :: * -> *).
(Typeable a, Typeable k, Data word) =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (EnumSet word a)
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> EnumSet word a -> c (EnumSet word a)
$cgfoldl :: forall word k (a :: k) (c :: * -> *).
(Typeable a, Typeable k, Data word) =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> EnumSet word a -> c (EnumSet word a)
$cp1Data :: forall word k (a :: k).
(Typeable a, Typeable k, Data word) =>
Typeable (EnumSet word a)
Data, Ptr b -> Int -> IO (EnumSet word a)
Ptr b -> Int -> EnumSet word a -> IO ()
Ptr (EnumSet word a) -> IO (EnumSet word a)
Ptr (EnumSet word a) -> Int -> IO (EnumSet word a)
Ptr (EnumSet word a) -> Int -> EnumSet word a -> IO ()
Ptr (EnumSet word a) -> EnumSet word a -> IO ()
EnumSet word a -> Int
(EnumSet word a -> Int)
-> (EnumSet word a -> Int)
-> (Ptr (EnumSet word a) -> Int -> IO (EnumSet word a))
-> (Ptr (EnumSet word a) -> Int -> EnumSet word a -> IO ())
-> (forall b. Ptr b -> Int -> IO (EnumSet word a))
-> (forall b. Ptr b -> Int -> EnumSet word a -> IO ())
-> (Ptr (EnumSet word a) -> IO (EnumSet word a))
-> (Ptr (EnumSet word a) -> EnumSet word a -> IO ())
-> Storable (EnumSet word a)
forall b. Ptr b -> Int -> IO (EnumSet word a)
forall b. Ptr b -> Int -> EnumSet word a -> IO ()
forall a.
(a -> Int)
-> (a -> Int)
-> (Ptr a -> Int -> IO a)
-> (Ptr a -> Int -> a -> IO ())
-> (forall b. Ptr b -> Int -> IO a)
-> (forall b. Ptr b -> Int -> a -> IO ())
-> (Ptr a -> IO a)
-> (Ptr a -> a -> IO ())
-> Storable a
forall word k (a :: k).
Storable word =>
Ptr (EnumSet word a) -> IO (EnumSet word a)
forall word k (a :: k).
Storable word =>
Ptr (EnumSet word a) -> Int -> IO (EnumSet word a)
forall word k (a :: k).
Storable word =>
Ptr (EnumSet word a) -> Int -> EnumSet word a -> IO ()
forall word k (a :: k).
Storable word =>
Ptr (EnumSet word a) -> EnumSet word a -> IO ()
forall word k (a :: k). Storable word => EnumSet word a -> Int
forall word k (a :: k) b.
Storable word =>
Ptr b -> Int -> IO (EnumSet word a)
forall word k (a :: k) b.
Storable word =>
Ptr b -> Int -> EnumSet word a -> IO ()
poke :: Ptr (EnumSet word a) -> EnumSet word a -> IO ()
$cpoke :: forall word k (a :: k).
Storable word =>
Ptr (EnumSet word a) -> EnumSet word a -> IO ()
peek :: Ptr (EnumSet word a) -> IO (EnumSet word a)
$cpeek :: forall word k (a :: k).
Storable word =>
Ptr (EnumSet word a) -> IO (EnumSet word a)
pokeByteOff :: Ptr b -> Int -> EnumSet word a -> IO ()
$cpokeByteOff :: forall word k (a :: k) b.
Storable word =>
Ptr b -> Int -> EnumSet word a -> IO ()
peekByteOff :: Ptr b -> Int -> IO (EnumSet word a)
$cpeekByteOff :: forall word k (a :: k) b.
Storable word =>
Ptr b -> Int -> IO (EnumSet word a)
pokeElemOff :: Ptr (EnumSet word a) -> Int -> EnumSet word a -> IO ()
$cpokeElemOff :: forall word k (a :: k).
Storable word =>
Ptr (EnumSet word a) -> Int -> EnumSet word a -> IO ()
peekElemOff :: Ptr (EnumSet word a) -> Int -> IO (EnumSet word a)
$cpeekElemOff :: forall word k (a :: k).
Storable word =>
Ptr (EnumSet word a) -> Int -> IO (EnumSet word a)
alignment :: EnumSet word a -> Int
$calignment :: forall word k (a :: k). Storable word => EnumSet word a -> Int
sizeOf :: EnumSet word a -> Int
$csizeOf :: forall word k (a :: k). Storable word => EnumSet word a -> Int
Storable, EnumSet word a -> ()
(EnumSet word a -> ()) -> NFData (EnumSet word a)
forall a. (a -> ()) -> NFData a
forall word k (a :: k). NFData word => EnumSet word a -> ()
rnf :: EnumSet word a -> ()
$crnf :: forall word k (a :: k). NFData word => EnumSet word a -> ()
NFData, Addr# -> Int# -> EnumSet word a
Addr# -> Int# -> Int# -> EnumSet word a -> State# s -> State# s
Addr# -> Int# -> State# s -> (# State# s, EnumSet word a #)
Addr# -> Int# -> EnumSet word a -> State# s -> State# s
ByteArray# -> Int# -> EnumSet word a
MutableByteArray# s
-> Int# -> State# s -> (# State# s, EnumSet word a #)
MutableByteArray# s
-> Int# -> EnumSet word a -> State# s -> State# s
MutableByteArray# s
-> Int# -> Int# -> EnumSet word a -> State# s -> State# s
EnumSet word a -> Int#
(EnumSet word a -> Int#)
-> (EnumSet word a -> Int#)
-> (ByteArray# -> Int# -> EnumSet word a)
-> (forall s.
    MutableByteArray# s
    -> Int# -> State# s -> (# State# s, EnumSet word a #))
-> (forall s.
    MutableByteArray# s
    -> Int# -> EnumSet word a -> State# s -> State# s)
-> (forall s.
    MutableByteArray# s
    -> Int# -> Int# -> EnumSet word a -> State# s -> State# s)
-> (Addr# -> Int# -> EnumSet word a)
-> (forall s.
    Addr# -> Int# -> State# s -> (# State# s, EnumSet word a #))
-> (forall s.
    Addr# -> Int# -> EnumSet word a -> State# s -> State# s)
-> (forall s.
    Addr# -> Int# -> Int# -> EnumSet word a -> State# s -> State# s)
-> Prim (EnumSet word a)
forall s.
Addr# -> Int# -> Int# -> EnumSet word a -> State# s -> State# s
forall s.
Addr# -> Int# -> State# s -> (# State# s, EnumSet word a #)
forall s. Addr# -> Int# -> EnumSet word a -> State# s -> State# s
forall s.
MutableByteArray# s
-> Int# -> Int# -> EnumSet word a -> State# s -> State# s
forall s.
MutableByteArray# s
-> Int# -> State# s -> (# State# s, EnumSet word a #)
forall s.
MutableByteArray# s
-> Int# -> EnumSet word a -> State# s -> State# s
forall a.
(a -> Int#)
-> (a -> Int#)
-> (ByteArray# -> Int# -> a)
-> (forall s.
    MutableByteArray# s -> Int# -> State# s -> (# State# s, a #))
-> (forall s.
    MutableByteArray# s -> Int# -> a -> State# s -> State# s)
-> (forall s.
    MutableByteArray# s -> Int# -> Int# -> a -> State# s -> State# s)
-> (Addr# -> Int# -> a)
-> (forall s. Addr# -> Int# -> State# s -> (# State# s, a #))
-> (forall s. Addr# -> Int# -> a -> State# s -> State# s)
-> (forall s. Addr# -> Int# -> Int# -> a -> State# s -> State# s)
-> Prim a
forall word k (a :: k).
Prim word =>
Addr# -> Int# -> EnumSet word a
forall word k (a :: k).
Prim word =>
ByteArray# -> Int# -> EnumSet word a
forall word k (a :: k). Prim word => EnumSet word a -> Int#
forall word k (a :: k) s.
Prim word =>
Addr# -> Int# -> Int# -> EnumSet word a -> State# s -> State# s
forall word k (a :: k) s.
Prim word =>
Addr# -> Int# -> State# s -> (# State# s, EnumSet word a #)
forall word k (a :: k) s.
Prim word =>
Addr# -> Int# -> EnumSet word a -> State# s -> State# s
forall word k (a :: k) s.
Prim word =>
MutableByteArray# s
-> Int# -> Int# -> EnumSet word a -> State# s -> State# s
forall word k (a :: k) s.
Prim word =>
MutableByteArray# s
-> Int# -> State# s -> (# State# s, EnumSet word a #)
forall word k (a :: k) s.
Prim word =>
MutableByteArray# s
-> Int# -> EnumSet word a -> State# s -> State# s
setOffAddr# :: Addr# -> Int# -> Int# -> EnumSet word a -> State# s -> State# s
$csetOffAddr# :: forall word k (a :: k) s.
Prim word =>
Addr# -> Int# -> Int# -> EnumSet word a -> State# s -> State# s
writeOffAddr# :: Addr# -> Int# -> EnumSet word a -> State# s -> State# s
$cwriteOffAddr# :: forall word k (a :: k) s.
Prim word =>
Addr# -> Int# -> EnumSet word a -> State# s -> State# s
readOffAddr# :: Addr# -> Int# -> State# s -> (# State# s, EnumSet word a #)
$creadOffAddr# :: forall word k (a :: k) s.
Prim word =>
Addr# -> Int# -> State# s -> (# State# s, EnumSet word a #)
indexOffAddr# :: Addr# -> Int# -> EnumSet word a
$cindexOffAddr# :: forall word k (a :: k).
Prim word =>
Addr# -> Int# -> EnumSet word a
setByteArray# :: MutableByteArray# s
-> Int# -> Int# -> EnumSet word a -> State# s -> State# s
$csetByteArray# :: forall word k (a :: k) s.
Prim word =>
MutableByteArray# s
-> Int# -> Int# -> EnumSet word a -> State# s -> State# s
writeByteArray# :: MutableByteArray# s
-> Int# -> EnumSet word a -> State# s -> State# s
$cwriteByteArray# :: forall word k (a :: k) s.
Prim word =>
MutableByteArray# s
-> Int# -> EnumSet word a -> State# s -> State# s
readByteArray# :: MutableByteArray# s
-> Int# -> State# s -> (# State# s, EnumSet word a #)
$creadByteArray# :: forall word k (a :: k) s.
Prim word =>
MutableByteArray# s
-> Int# -> State# s -> (# State# s, EnumSet word a #)
indexByteArray# :: ByteArray# -> Int# -> EnumSet word a
$cindexByteArray# :: forall word k (a :: k).
Prim word =>
ByteArray# -> Int# -> EnumSet word a
alignment# :: EnumSet word a -> Int#
$calignment# :: forall word k (a :: k). Prim word => EnumSet word a -> Int#
sizeOf# :: EnumSet word a -> Int#
$csizeOf# :: forall word k (a :: k). Prim word => EnumSet word a -> Int#
P.Prim, Vector Vector (EnumSet word a)
MVector MVector (EnumSet word a)
Vector Vector (EnumSet word a)
-> MVector MVector (EnumSet word a) -> Unbox (EnumSet word a)
forall a. Vector Vector a -> MVector MVector a -> Unbox a
forall word k (a :: k). Prim word => Vector Vector (EnumSet word a)
forall word k (a :: k).
Prim word =>
MVector MVector (EnumSet word a)
$cp2Unbox :: forall word k (a :: k).
Prim word =>
MVector MVector (EnumSet word a)
$cp1Unbox :: forall word k (a :: k). Prim word => Vector Vector (EnumSet word a)
Unbox)

newtype instance MVector s (EnumSet word a) = MV_EnumSet (P.MVector s (EnumSet word a))
newtype instance Vector    (EnumSet word a) = V_EnumSet  (P.Vector    (EnumSet word a))

instance P.Prim word => M.MVector MVector (EnumSet word a) where
    basicLength :: MVector s (EnumSet word a) -> Int
basicLength (MV_EnumSet v) = MVector s (EnumSet word a) -> Int
forall (v :: * -> * -> *) a s. MVector v a => v s a -> Int
M.basicLength MVector s (EnumSet word a)
v
    {-# INLINE basicLength #-}
    basicUnsafeSlice :: Int
-> Int -> MVector s (EnumSet word a) -> MVector s (EnumSet word a)
basicUnsafeSlice Int
i Int
n (MV_EnumSet v) = MVector s (EnumSet word a) -> MVector s (EnumSet word a)
forall k s word (a :: k).
MVector s (EnumSet word a) -> MVector s (EnumSet word a)
MV_EnumSet (MVector s (EnumSet word a) -> MVector s (EnumSet word a))
-> MVector s (EnumSet word a) -> MVector s (EnumSet word a)
forall a b. (a -> b) -> a -> b
$ Int
-> Int -> MVector s (EnumSet word a) -> MVector s (EnumSet word a)
forall (v :: * -> * -> *) a s.
MVector v a =>
Int -> Int -> v s a -> v s a
M.basicUnsafeSlice Int
i Int
n MVector s (EnumSet word a)
v
    {-# INLINE basicUnsafeSlice #-}
    basicOverlaps :: MVector s (EnumSet word a) -> MVector s (EnumSet word a) -> Bool
basicOverlaps (MV_EnumSet v1) (MV_EnumSet v2) = MVector s (EnumSet word a) -> MVector s (EnumSet word a) -> Bool
forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> v s a -> Bool
M.basicOverlaps MVector s (EnumSet word a)
v1 MVector s (EnumSet word a)
v2
    {-# INLINE basicOverlaps #-}
    basicUnsafeNew :: Int -> m (MVector (PrimState m) (EnumSet word a))
basicUnsafeNew Int
n = MVector (PrimState m) (EnumSet word a)
-> MVector (PrimState m) (EnumSet word a)
forall k s word (a :: k).
MVector s (EnumSet word a) -> MVector s (EnumSet word a)
MV_EnumSet (MVector (PrimState m) (EnumSet word a)
 -> MVector (PrimState m) (EnumSet word a))
-> m (MVector (PrimState m) (EnumSet word a))
-> m (MVector (PrimState m) (EnumSet word a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> m (MVector (PrimState m) (EnumSet word a))
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
Int -> m (v (PrimState m) a)
M.basicUnsafeNew Int
n
    {-# INLINE basicUnsafeNew #-}
    basicInitialize :: MVector (PrimState m) (EnumSet word a) -> m ()
basicInitialize (MV_EnumSet v) = MVector (PrimState m) (EnumSet word a) -> m ()
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
v (PrimState m) a -> m ()
M.basicInitialize MVector (PrimState m) (EnumSet word a)
v
    {-# INLINE basicInitialize #-}
    basicUnsafeReplicate :: Int -> EnumSet word a -> m (MVector (PrimState m) (EnumSet word a))
basicUnsafeReplicate Int
n EnumSet word a
x = MVector (PrimState m) (EnumSet word a)
-> MVector (PrimState m) (EnumSet word a)
forall k s word (a :: k).
MVector s (EnumSet word a) -> MVector s (EnumSet word a)
MV_EnumSet (MVector (PrimState m) (EnumSet word a)
 -> MVector (PrimState m) (EnumSet word a))
-> m (MVector (PrimState m) (EnumSet word a))
-> m (MVector (PrimState m) (EnumSet word a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> EnumSet word a -> m (MVector (PrimState m) (EnumSet word a))
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
Int -> a -> m (v (PrimState m) a)
M.basicUnsafeReplicate Int
n EnumSet word a
x
    {-# INLINE basicUnsafeReplicate #-}
    basicUnsafeRead :: MVector (PrimState m) (EnumSet word a) -> Int -> m (EnumSet word a)
basicUnsafeRead (MV_EnumSet v) Int
i = MVector (PrimState m) (EnumSet word a) -> Int -> m (EnumSet word a)
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
v (PrimState m) a -> Int -> m a
M.basicUnsafeRead MVector (PrimState m) (EnumSet word a)
v Int
i
    {-# INLINE basicUnsafeRead #-}
    basicUnsafeWrite :: MVector (PrimState m) (EnumSet word a)
-> Int -> EnumSet word a -> m ()
basicUnsafeWrite (MV_EnumSet v) Int
i EnumSet word a
x = MVector (PrimState m) (EnumSet word a)
-> Int -> EnumSet word a -> m ()
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
v (PrimState m) a -> Int -> a -> m ()
M.basicUnsafeWrite MVector (PrimState m) (EnumSet word a)
v Int
i EnumSet word a
x
    {-# INLINE basicUnsafeWrite #-}
    basicClear :: MVector (PrimState m) (EnumSet word a) -> m ()
basicClear (MV_EnumSet v) = MVector (PrimState m) (EnumSet word a) -> m ()
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
v (PrimState m) a -> m ()
M.basicClear MVector (PrimState m) (EnumSet word a)
v
    {-# INLINE basicClear #-}
    basicSet :: MVector (PrimState m) (EnumSet word a) -> EnumSet word a -> m ()
basicSet (MV_EnumSet v) EnumSet word a
x = MVector (PrimState m) (EnumSet word a) -> EnumSet word a -> m ()
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
v (PrimState m) a -> a -> m ()
M.basicSet MVector (PrimState m) (EnumSet word a)
v EnumSet word a
x
    {-# INLINE basicSet #-}
    basicUnsafeCopy :: MVector (PrimState m) (EnumSet word a)
-> MVector (PrimState m) (EnumSet word a) -> m ()
basicUnsafeCopy (MV_EnumSet v1) (MV_EnumSet v2) = MVector (PrimState m) (EnumSet word a)
-> MVector (PrimState m) (EnumSet word a) -> m ()
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
v (PrimState m) a -> v (PrimState m) a -> m ()
M.basicUnsafeCopy MVector (PrimState m) (EnumSet word a)
v1 MVector (PrimState m) (EnumSet word a)
v2
    {-# INLINE basicUnsafeCopy #-}
    basicUnsafeMove :: MVector (PrimState m) (EnumSet word a)
-> MVector (PrimState m) (EnumSet word a) -> m ()
basicUnsafeMove (MV_EnumSet v1) (MV_EnumSet v2) = MVector (PrimState m) (EnumSet word a)
-> MVector (PrimState m) (EnumSet word a) -> m ()
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
v (PrimState m) a -> v (PrimState m) a -> m ()
M.basicUnsafeMove MVector (PrimState m) (EnumSet word a)
v1 MVector (PrimState m) (EnumSet word a)
v2
    {-# INLINE basicUnsafeMove #-}
    basicUnsafeGrow :: MVector (PrimState m) (EnumSet word a)
-> Int -> m (MVector (PrimState m) (EnumSet word a))
basicUnsafeGrow (MV_EnumSet v) Int
n = MVector (PrimState m) (EnumSet word a)
-> MVector (PrimState m) (EnumSet word a)
forall k s word (a :: k).
MVector s (EnumSet word a) -> MVector s (EnumSet word a)
MV_EnumSet (MVector (PrimState m) (EnumSet word a)
 -> MVector (PrimState m) (EnumSet word a))
-> m (MVector (PrimState m) (EnumSet word a))
-> m (MVector (PrimState m) (EnumSet word a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MVector (PrimState m) (EnumSet word a)
-> Int -> m (MVector (PrimState m) (EnumSet word a))
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
v (PrimState m) a -> Int -> m (v (PrimState m) a)
M.basicUnsafeGrow MVector (PrimState m) (EnumSet word a)
v Int
n
    {-# INLINE basicUnsafeGrow #-}


instance P.Prim word => G.Vector Vector (EnumSet word a) where
    basicUnsafeFreeze :: Mutable Vector (PrimState m) (EnumSet word a)
-> m (Vector (EnumSet word a))
basicUnsafeFreeze (MV_EnumSet v) = Vector (EnumSet word a) -> Vector (EnumSet word a)
forall k word (a :: k).
Vector (EnumSet word a) -> Vector (EnumSet word a)
V_EnumSet (Vector (EnumSet word a) -> Vector (EnumSet word a))
-> m (Vector (EnumSet word a)) -> m (Vector (EnumSet word a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Mutable Vector (PrimState m) (EnumSet word a)
-> m (Vector (EnumSet word a))
forall (v :: * -> *) a (m :: * -> *).
(Vector v a, PrimMonad m) =>
Mutable v (PrimState m) a -> m (v a)
G.basicUnsafeFreeze MVector (PrimState m) (EnumSet word a)
Mutable Vector (PrimState m) (EnumSet word a)
v
    {-# INLINE basicUnsafeFreeze #-}
    basicUnsafeThaw :: Vector (EnumSet word a)
-> m (Mutable Vector (PrimState m) (EnumSet word a))
basicUnsafeThaw (V_EnumSet v) = MVector (PrimState m) (EnumSet word a)
-> MVector (PrimState m) (EnumSet word a)
forall k s word (a :: k).
MVector s (EnumSet word a) -> MVector s (EnumSet word a)
MV_EnumSet (MVector (PrimState m) (EnumSet word a)
 -> MVector (PrimState m) (EnumSet word a))
-> m (MVector (PrimState m) (EnumSet word a))
-> m (MVector (PrimState m) (EnumSet word a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Vector (EnumSet word a)
-> m (Mutable Vector (PrimState m) (EnumSet word a))
forall (v :: * -> *) a (m :: * -> *).
(Vector v a, PrimMonad m) =>
v a -> m (Mutable v (PrimState m) a)
G.basicUnsafeThaw Vector (EnumSet word a)
v
    {-# INLINE basicUnsafeThaw #-}
    basicLength :: Vector (EnumSet word a) -> Int
basicLength (V_EnumSet v) = Vector (EnumSet word a) -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
G.basicLength Vector (EnumSet word a)
v
    {-# INLINE basicLength #-}
    basicUnsafeSlice :: Int -> Int -> Vector (EnumSet word a) -> Vector (EnumSet word a)
basicUnsafeSlice Int
i Int
n (V_EnumSet v) = Vector (EnumSet word a) -> Vector (EnumSet word a)
forall k word (a :: k).
Vector (EnumSet word a) -> Vector (EnumSet word a)
V_EnumSet (Vector (EnumSet word a) -> Vector (EnumSet word a))
-> Vector (EnumSet word a) -> Vector (EnumSet word a)
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Vector (EnumSet word a) -> Vector (EnumSet word a)
forall (v :: * -> *) a. Vector v a => Int -> Int -> v a -> v a
G.basicUnsafeSlice Int
i Int
n Vector (EnumSet word a)
v
    {-# INLINE basicUnsafeSlice #-}
    basicUnsafeIndexM :: Vector (EnumSet word a) -> Int -> m (EnumSet word a)
basicUnsafeIndexM (V_EnumSet v) Int
i = Vector (EnumSet word a) -> Int -> m (EnumSet word a)
forall (v :: * -> *) a (m :: * -> *).
(Vector v a, Monad m) =>
v a -> Int -> m a
G.basicUnsafeIndexM Vector (EnumSet word a)
v Int
i
    {-# INLINE basicUnsafeIndexM #-}
    basicUnsafeCopy :: Mutable Vector (PrimState m) (EnumSet word a)
-> Vector (EnumSet word a) -> m ()
basicUnsafeCopy (MV_EnumSet mv) (V_EnumSet v) = Mutable Vector (PrimState m) (EnumSet word a)
-> Vector (EnumSet word a) -> m ()
forall (v :: * -> *) a (m :: * -> *).
(Vector v a, PrimMonad m) =>
Mutable v (PrimState m) a -> v a -> m ()
G.basicUnsafeCopy MVector (PrimState m) (EnumSet word a)
Mutable Vector (PrimState m) (EnumSet word a)
mv Vector (EnumSet word a)
v
    {-# INLINE basicUnsafeCopy #-}
    elemseq :: Vector (EnumSet word a) -> EnumSet word a -> b -> b
elemseq Vector (EnumSet word a)
_ = EnumSet word a -> b -> b
seq
    {-# INLINE elemseq #-}

instance Bits w => Semigroup (EnumSet w a) where
    <> :: EnumSet w a -> EnumSet w a -> EnumSet w a
(<>) = EnumSet w a -> EnumSet w a -> EnumSet w a
forall k w (a :: k).
Bits w =>
EnumSet w a -> EnumSet w a -> EnumSet w a
union
    {-# INLINE (<>) #-}

instance Bits w => Monoid (EnumSet w a) where
    mempty :: EnumSet w a
mempty = EnumSet w a
forall k w (a :: k). Bits w => EnumSet w a
empty
    {-# INLINE mempty #-}

instance (Bits w, Enum a) => MonoPointed (EnumSet w a) where
    opoint :: Element (EnumSet w a) -> EnumSet w a
opoint = Element (EnumSet w a) -> EnumSet w a
forall w a. (Bits w, Enum a) => a -> EnumSet w a
singleton
    {-# INLINE opoint #-}

instance (FiniteBits w, Num w, Enum a) => IsList (EnumSet w a) where
    type Item (EnumSet w a) = a
    fromList :: [Item (EnumSet w a)] -> EnumSet w a
fromList = [Item (EnumSet w a)] -> EnumSet w a
forall (f :: * -> *) w a.
(Foldable f, Bits w, Enum a) =>
f a -> EnumSet w a
fromFoldable
    {-# INLINE fromList #-}
    toList :: EnumSet w a -> [Item (EnumSet w a)]
toList = EnumSet w a -> [Item (EnumSet w a)]
forall w a. (FiniteBits w, Num w, Enum a) => EnumSet w a -> [a]
toList
    {-# INLINE toList #-}

instance (FiniteBits w, Num w, Enum a, ToJSON a) => ToJSON (EnumSet w a) where
    toJSON :: EnumSet w a -> Value
toJSON = [a] -> Value
forall a. ToJSON a => a -> Value
toJSON ([a] -> Value) -> (EnumSet w a -> [a]) -> EnumSet w a -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EnumSet w a -> [a]
forall w a. (FiniteBits w, Num w, Enum a) => EnumSet w a -> [a]
toList
    {-# INLINE toJSON #-}
    toEncoding :: EnumSet w a -> Encoding
toEncoding = [a] -> Encoding
forall a. ToJSON a => a -> Encoding
toEncoding ([a] -> Encoding)
-> (EnumSet w a -> [a]) -> EnumSet w a -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EnumSet w a -> [a]
forall w a. (FiniteBits w, Num w, Enum a) => EnumSet w a -> [a]
toList
    {-# INLINE toEncoding #-}

type instance Element (EnumSet w a) = a

instance (FiniteBits w, Num w, Enum a) => MonoFunctor (EnumSet w a) where
    omap :: (Element (EnumSet w a) -> Element (EnumSet w a))
-> EnumSet w a -> EnumSet w a
omap = (Element (EnumSet w a) -> Element (EnumSet w a))
-> EnumSet w a -> EnumSet w a
forall w a b.
(FiniteBits w, Num w, Enum a, Enum b) =>
(a -> b) -> EnumSet w a -> EnumSet w b
map
    {-# INLINE omap #-}

instance (FiniteBits w, Num w, Enum a) => MonoFoldable (EnumSet w a) where
    ofoldMap :: (Element (EnumSet w a) -> m) -> EnumSet w a -> m
ofoldMap = (Element (EnumSet w a) -> m) -> EnumSet w a -> m
forall m w a.
(Monoid m, FiniteBits w, Num w, Enum a) =>
(a -> m) -> EnumSet w a -> m
foldMap
    {-# INLINE ofoldMap #-}
    ofoldr :: (Element (EnumSet w a) -> b -> b) -> b -> EnumSet w a -> b
ofoldr = (Element (EnumSet w a) -> b -> b) -> b -> EnumSet w a -> b
forall w a b.
(FiniteBits w, Num w, Enum a) =>
(a -> b -> b) -> b -> EnumSet w a -> b
foldr
    {-# INLINE ofoldr #-}
    ofoldl' :: (a -> Element (EnumSet w a) -> a) -> a -> EnumSet w a -> a
ofoldl' = (a -> Element (EnumSet w a) -> a) -> a -> EnumSet w a -> a
forall w a b.
(FiniteBits w, Num w, Enum a) =>
(b -> a -> b) -> b -> EnumSet w a -> b
foldl'
    {-# INLINE ofoldl' #-}
    ofoldr1Ex :: (Element (EnumSet w a)
 -> Element (EnumSet w a) -> Element (EnumSet w a))
-> EnumSet w a -> Element (EnumSet w a)
ofoldr1Ex = (Element (EnumSet w a)
 -> Element (EnumSet w a) -> Element (EnumSet w a))
-> EnumSet w a -> Element (EnumSet w a)
forall w a.
(FiniteBits w, Num w, Enum a) =>
(a -> a -> a) -> EnumSet w a -> a
foldr1
    {-# INLINE ofoldr1Ex #-}
    ofoldl1Ex' :: (Element (EnumSet w a)
 -> Element (EnumSet w a) -> Element (EnumSet w a))
-> EnumSet w a -> Element (EnumSet w a)
ofoldl1Ex' = (Element (EnumSet w a)
 -> Element (EnumSet w a) -> Element (EnumSet w a))
-> EnumSet w a -> Element (EnumSet w a)
forall w a.
(FiniteBits w, Num w, Enum a) =>
(a -> a -> a) -> EnumSet w a -> a
foldl1'
    {-# INLINE ofoldl1Ex' #-}
    otoList :: EnumSet w a -> [Element (EnumSet w a)]
otoList = EnumSet w a -> [Element (EnumSet w a)]
forall w a. (FiniteBits w, Num w, Enum a) => EnumSet w a -> [a]
toList
    {-# INLINE otoList #-}
    oall :: (Element (EnumSet w a) -> Bool) -> EnumSet w a -> Bool
oall = (Element (EnumSet w a) -> Bool) -> EnumSet w a -> Bool
forall w a.
(FiniteBits w, Num w, Enum a) =>
(a -> Bool) -> EnumSet w a -> Bool
all
    {-# INLINE oall #-}
    oany :: (Element (EnumSet w a) -> Bool) -> EnumSet w a -> Bool
oany = (Element (EnumSet w a) -> Bool) -> EnumSet w a -> Bool
forall w a.
(FiniteBits w, Num w, Enum a) =>
(a -> Bool) -> EnumSet w a -> Bool
any
    {-# INLINE oany #-}
    onull :: EnumSet w a -> Bool
onull = EnumSet w a -> Bool
forall k w (a :: k). Bits w => EnumSet w a -> Bool
null
    {-# INLINE onull #-}
    olength :: EnumSet w a -> Int
olength = EnumSet w a -> Int
forall k w (a :: k). (Bits w, Num w) => EnumSet w a -> Int
size
    {-# INLINE olength #-}
    olength64 :: EnumSet w a -> Int64
olength64 EnumSet w a
w = Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Int64) -> Int -> Int64
forall a b. (a -> b) -> a -> b
$ EnumSet w a -> Int
forall k w (a :: k). (Bits w, Num w) => EnumSet w a -> Int
size EnumSet w a
w
    {-# INLINE olength64 #-}
    headEx :: EnumSet w a -> Element (EnumSet w a)
headEx = EnumSet w a -> Element (EnumSet w a)
forall w a. (FiniteBits w, Num w, Enum a) => EnumSet w a -> a
minimum
    {-# INLINE headEx #-}
    lastEx :: EnumSet w a -> Element (EnumSet w a)
lastEx = EnumSet w a -> Element (EnumSet w a)
forall w a. (FiniteBits w, Num w, Enum a) => EnumSet w a -> a
maximum
    {-# INLINE lastEx #-}
    oelem :: Element (EnumSet w a) -> EnumSet w a -> Bool
oelem = Element (EnumSet w a) -> EnumSet w a -> Bool
forall w a. (Bits w, Enum a) => a -> EnumSet w a -> Bool
member
    {-# INLINE oelem #-}
    onotElem :: Element (EnumSet w a) -> EnumSet w a -> Bool
onotElem Element (EnumSet w a)
x = Bool -> Bool
not (Bool -> Bool) -> (EnumSet w a -> Bool) -> EnumSet w a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> EnumSet w a -> Bool
forall w a. (Bits w, Enum a) => a -> EnumSet w a -> Bool
member a
Element (EnumSet w a)
x
    {-# INLINE onotElem #-}

instance (FiniteBits w, Num w, Enum a) => GrowingAppend (EnumSet w a)

instance (FiniteBits w, Num w, Enum a) => MonoTraversable (EnumSet w a) where
    otraverse :: (Element (EnumSet w a) -> f (Element (EnumSet w a)))
-> EnumSet w a -> f (EnumSet w a)
otraverse = (Element (EnumSet w a) -> f (Element (EnumSet w a)))
-> EnumSet w a -> f (EnumSet w a)
forall (f :: * -> *) w a.
(Applicative f, FiniteBits w, Num w, Enum a) =>
(a -> f a) -> EnumSet w a -> f (EnumSet w a)
traverse
    {-# INLINE otraverse #-}

instance (FiniteBits w, Num w, Eq a, Enum a) => SetContainer (EnumSet w a) where
    type ContainerKey (EnumSet w a) = a
    member :: ContainerKey (EnumSet w a) -> EnumSet w a -> Bool
member = ContainerKey (EnumSet w a) -> EnumSet w a -> Bool
forall w a. (Bits w, Enum a) => a -> EnumSet w a -> Bool
member
    {-# INLINE member #-}
    notMember :: ContainerKey (EnumSet w a) -> EnumSet w a -> Bool
notMember = ContainerKey (EnumSet w a) -> EnumSet w a -> Bool
forall w a. (Bits w, Enum a) => a -> EnumSet w a -> Bool
notMember
    {-# INLINE notMember #-}
    union :: EnumSet w a -> EnumSet w a -> EnumSet w a
union = EnumSet w a -> EnumSet w a -> EnumSet w a
forall k w (a :: k).
Bits w =>
EnumSet w a -> EnumSet w a -> EnumSet w a
union
    {-# INLINE union #-}
    difference :: EnumSet w a -> EnumSet w a -> EnumSet w a
difference = EnumSet w a -> EnumSet w a -> EnumSet w a
forall k w (a :: k).
Bits w =>
EnumSet w a -> EnumSet w a -> EnumSet w a
difference
    {-# INLINE difference #-}
    intersection :: EnumSet w a -> EnumSet w a -> EnumSet w a
intersection = EnumSet w a -> EnumSet w a -> EnumSet w a
forall k w (a :: k).
Bits w =>
EnumSet w a -> EnumSet w a -> EnumSet w a
intersection
    {-# INLINE intersection #-}
    keys :: EnumSet w a -> [ContainerKey (EnumSet w a)]
keys = EnumSet w a -> [ContainerKey (EnumSet w a)]
forall w a. (FiniteBits w, Num w, Enum a) => EnumSet w a -> [a]
toList
    {-# INLINE keys #-}

instance (FiniteBits w, Num w, Eq a, Enum a) => IsSet (EnumSet w a) where
    insertSet :: Element (EnumSet w a) -> EnumSet w a -> EnumSet w a
insertSet = Element (EnumSet w a) -> EnumSet w a -> EnumSet w a
forall w a. (Bits w, Enum a) => a -> EnumSet w a -> EnumSet w a
insert
    {-# INLINE insertSet #-}
    deleteSet :: Element (EnumSet w a) -> EnumSet w a -> EnumSet w a
deleteSet = Element (EnumSet w a) -> EnumSet w a -> EnumSet w a
forall w a. (Bits w, Enum a) => a -> EnumSet w a -> EnumSet w a
delete
    {-# INLINE deleteSet #-}
    singletonSet :: Element (EnumSet w a) -> EnumSet w a
singletonSet = Element (EnumSet w a) -> EnumSet w a
forall w a. (Bits w, Enum a) => a -> EnumSet w a
singleton
    {-# INLINE singletonSet #-}
    setFromList :: [Element (EnumSet w a)] -> EnumSet w a
setFromList = [Element (EnumSet w a)] -> EnumSet w a
forall (f :: * -> *) w a.
(Foldable f, Bits w, Enum a) =>
f a -> EnumSet w a
fromFoldable
    {-# INLINE setFromList #-}
    setToList :: EnumSet w a -> [Element (EnumSet w a)]
setToList = EnumSet w a -> [Element (EnumSet w a)]
forall w a. (FiniteBits w, Num w, Enum a) => EnumSet w a -> [a]
toList
    {-# INLINE setToList #-}
    filterSet :: (Element (EnumSet w a) -> Bool) -> EnumSet w a -> EnumSet w a
filterSet = (Element (EnumSet w a) -> Bool) -> EnumSet w a -> EnumSet w a
forall w a.
(FiniteBits w, Num w, Enum a) =>
(a -> Bool) -> EnumSet w a -> EnumSet w a
filter
    {-# INLINE filterSet #-}

instance (FiniteBits w, Num w, Enum x, Show x) => Show (EnumSet w x) where
    showsPrec :: Int -> EnumSet w x -> ShowS
showsPrec Int
p EnumSet w x
xs = Bool -> ShowS -> ShowS
showParen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
        String -> ShowS
showString String
"fromList " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [x] -> ShowS
forall a. Show a => a -> ShowS
shows (EnumSet w x -> [x]
forall w a. (FiniteBits w, Num w, Enum a) => EnumSet w a -> [a]
toList EnumSet w x
xs)
    {-# INLINABLE showsPrec #-}

instance (Bits w, Num w, Enum x, Read x) => Read (EnumSet w x) where
    readPrec :: ReadPrec (EnumSet w x)
readPrec = ReadPrec (EnumSet w x) -> ReadPrec (EnumSet w x)
forall a. ReadPrec a -> ReadPrec a
parens (ReadPrec (EnumSet w x) -> ReadPrec (EnumSet w x))
-> ReadPrec (EnumSet w x) -> ReadPrec (EnumSet w x)
forall a b. (a -> b) -> a -> b
$ Int -> ReadPrec (EnumSet w x) -> ReadPrec (EnumSet w x)
forall a. Int -> ReadPrec a -> ReadPrec a
prec Int
10 do
        Ident String
"fromList" <- ReadPrec Lexeme
lexP
        [x] -> EnumSet w x
forall (f :: * -> *) w a.
(Foldable f, Bits w, Enum a) =>
f a -> EnumSet w a
fromFoldable ([x] -> EnumSet w x) -> ReadPrec [x] -> ReadPrec (EnumSet w x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ReadPrec [x]
forall a. Read a => ReadPrec a
readPrec :: ReadPrec [x])
    {-# INLINABLE readPrec #-}
    readListPrec :: ReadPrec [EnumSet w x]
readListPrec = ReadPrec [EnumSet w x]
forall a. Read a => ReadPrec [a]
readListPrecDefault
    {-# INLINABLE readListPrec #-}

{--------------------------------------------------------------------
  Construction
--------------------------------------------------------------------}

-- | /O(1)/. The empty set.

empty ::  w a. Bits w
      => EnumSet w a
empty :: EnumSet w a
empty = w -> EnumSet w a
forall k word (a :: k). word -> EnumSet word a
EnumSet w
forall a. Bits a => a
zeroBits
{-# INLINE empty #-}

-- | /O(1)/. A set of one element.

singleton ::  w a. (Bits w, Enum a)
          => a -> EnumSet w a
singleton :: a -> EnumSet w a
singleton = w -> EnumSet w a
forall k word (a :: k). word -> EnumSet word a
EnumSet (w -> EnumSet w a) -> (a -> w) -> a -> EnumSet w a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> w
forall a. Bits a => Int -> a
bit (Int -> w) -> (a -> Int) -> a -> w
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Int
forall a. Enum a => a -> Int
fromEnum
{-# INLINE singleton #-}

-- | /O(n)/. Create a set from a finite foldable data structure.

fromFoldable ::  f w a. (Foldable f, Bits w, Enum a)
             => f a -> EnumSet w a
fromFoldable :: f a -> EnumSet w a
fromFoldable = w -> EnumSet w a
forall k word (a :: k). word -> EnumSet word a
EnumSet (w -> EnumSet w a) -> (f a -> w) -> f a -> EnumSet w a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (w -> a -> w) -> w -> f a -> w
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
F.foldl' ((a -> w -> w) -> w -> a -> w
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((a -> w -> w) -> w -> a -> w) -> (a -> w -> w) -> w -> a -> w
forall a b. (a -> b) -> a -> b
$ w -> w -> w
forall a. Bits a => a -> a -> a
(.|.) (w -> w -> w) -> (a -> w) -> a -> w -> w
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> w
forall a. Bits a => Int -> a
bit (Int -> w) -> (a -> Int) -> a -> w
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Int
forall a. Enum a => a -> Int
fromEnum) w
forall a. Bits a => a
zeroBits

{--------------------------------------------------------------------
  Insertion
--------------------------------------------------------------------}

-- | /O(1)/. Add a value to the set.

insert ::  w a. (Bits w, Enum a)
       => a -> EnumSet w a -> EnumSet w a
insert :: a -> EnumSet w a -> EnumSet w a
insert !a
x (EnumSet w
w) = w -> EnumSet w a
forall k word (a :: k). word -> EnumSet word a
EnumSet (w -> EnumSet w a) -> (Int -> w) -> Int -> EnumSet w a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. w -> Int -> w
forall a. Bits a => a -> Int -> a
setBit w
w (Int -> EnumSet w a) -> Int -> EnumSet w a
forall a b. (a -> b) -> a -> b
$ a -> Int
forall a. Enum a => a -> Int
fromEnum a
x

{--------------------------------------------------------------------
  Deletion
--------------------------------------------------------------------}

-- | /O(1)/. Delete a value in the set.

delete ::  w a. (Bits w, Enum a)
       => a -> EnumSet w a -> EnumSet w a
delete :: a -> EnumSet w a -> EnumSet w a
delete !a
x (EnumSet w
w) = w -> EnumSet w a
forall k word (a :: k). word -> EnumSet word a
EnumSet (w -> EnumSet w a) -> (Int -> w) -> Int -> EnumSet w a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. w -> Int -> w
forall a. Bits a => a -> Int -> a
clearBit w
w (Int -> EnumSet w a) -> Int -> EnumSet w a
forall a b. (a -> b) -> a -> b
$ a -> Int
forall a. Enum a => a -> Int
fromEnum a
x

{--------------------------------------------------------------------
  Query
--------------------------------------------------------------------}

-- | /O(1)/. Is the value a member of the set?

member ::  w a. (Bits w, Enum a)
       => a -> EnumSet w a -> Bool
member :: a -> EnumSet w a -> Bool
member !a
x (EnumSet w
w) = w -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit w
w (Int -> Bool) -> Int -> Bool
forall a b. (a -> b) -> a -> b
$ a -> Int
forall a. Enum a => a -> Int
fromEnum a
x

-- | /O(1)/. Is the value not in the set?

notMember ::  w a. (Bits w, Enum a)
          => a -> EnumSet w a -> Bool
notMember :: a -> EnumSet w a -> Bool
notMember !a
x = Bool -> Bool
not (Bool -> Bool) -> (EnumSet w a -> Bool) -> EnumSet w a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> EnumSet w a -> Bool
forall w a. (Bits w, Enum a) => a -> EnumSet w a -> Bool
member a
x

-- | /O(1)/. Is this the empty set?

null ::  w a. Bits w
     => EnumSet w a -> Bool
null :: EnumSet w a -> Bool
null (EnumSet w
w) = w
forall a. Bits a => a
zeroBits w -> w -> Bool
forall a. Eq a => a -> a -> Bool
== w
w
{-# INLINE null #-}

-- | /O(1)/. The number of elements in the set.

size ::  w a. (Bits w, Num w)
     => EnumSet w a -> Int
size :: EnumSet w a -> Int
size (EnumSet !w
w) = w -> Int
forall a. Bits a => a -> Int
popCount w
w

-- | /O(1)/. Is this a subset?

-- @(s1 \`isSubsetOf\` s2)@ tells whether @s1@ is a subset of @s2@.

isSubsetOf ::  w a. (Bits w)
           => EnumSet w a -> EnumSet w a -> Bool
isSubsetOf :: EnumSet w a -> EnumSet w a -> Bool
isSubsetOf (EnumSet w
x) (EnumSet w
y) = w
x w -> w -> w
forall a. Bits a => a -> a -> a
.|. w
y w -> w -> Bool
forall a. Eq a => a -> a -> Bool
== w
y
{-# INLINE isSubsetOf #-}

{--------------------------------------------------------------------
  Combine
--------------------------------------------------------------------}

-- | /O(1)/. The union of two sets.

union ::  w a. Bits w
      => EnumSet w a -> EnumSet w a -> EnumSet w a
union :: EnumSet w a -> EnumSet w a -> EnumSet w a
union (EnumSet w
x) (EnumSet w
y) = w -> EnumSet w a
forall k word (a :: k). word -> EnumSet word a
EnumSet (w -> EnumSet w a) -> w -> EnumSet w a
forall a b. (a -> b) -> a -> b
$ w
x w -> w -> w
forall a. Bits a => a -> a -> a
.|. w
y
{-# INLINE union #-}

-- | /O(1)/. Difference between two sets.

difference ::  w a. Bits w
           => EnumSet w a -> EnumSet w a -> EnumSet w a
difference :: EnumSet w a -> EnumSet w a -> EnumSet w a
difference (EnumSet w
x) (EnumSet w
y) = w -> EnumSet w a
forall k word (a :: k). word -> EnumSet word a
EnumSet (w -> EnumSet w a) -> w -> EnumSet w a
forall a b. (a -> b) -> a -> b
$ (w
x w -> w -> w
forall a. Bits a => a -> a -> a
.|. w
y) w -> w -> w
forall a. Bits a => a -> a -> a
`xor` w
y
{-# INLINE difference #-}

-- | /O(1)/. See 'difference'.

(\\) ::  w a. Bits w
     => EnumSet w a -> EnumSet w a -> EnumSet w a
\\ :: EnumSet w a -> EnumSet w a -> EnumSet w a
(\\) = EnumSet w a -> EnumSet w a -> EnumSet w a
forall k w (a :: k).
Bits w =>
EnumSet w a -> EnumSet w a -> EnumSet w a
difference
infixl 9 \\
{-# INLINE (\\) #-}

-- | /O(1)/. Elements which are in either set, but not both.

symmetricDifference ::  w a. Bits w
                    => EnumSet w a -> EnumSet w a -> EnumSet w a
symmetricDifference :: EnumSet w a -> EnumSet w a -> EnumSet w a
symmetricDifference (EnumSet w
x) (EnumSet w
y) = w -> EnumSet w a
forall k word (a :: k). word -> EnumSet word a
EnumSet (w -> EnumSet w a) -> w -> EnumSet w a
forall a b. (a -> b) -> a -> b
$ w
x w -> w -> w
forall a. Bits a => a -> a -> a
`xor` w
y
{-# INLINE symmetricDifference #-}

-- | /O(1)/. The intersection of two sets.

intersection ::  w a. Bits w
             => EnumSet w a -> EnumSet w a -> EnumSet w a
intersection :: EnumSet w a -> EnumSet w a -> EnumSet w a
intersection (EnumSet w
x) (EnumSet w
y) = w -> EnumSet w a
forall k word (a :: k). word -> EnumSet word a
EnumSet (w -> EnumSet w a) -> w -> EnumSet w a
forall a b. (a -> b) -> a -> b
$ w
x w -> w -> w
forall a. Bits a => a -> a -> a
.&. w
y
{-# INLINE intersection #-}

{--------------------------------------------------------------------
  Filter
--------------------------------------------------------------------}

-- | /O(n)/. Filter all elements that satisfy some predicate.

filter ::  w a. (FiniteBits w, Num w, Enum a)
       => (a -> Bool) -> EnumSet w a -> EnumSet w a
filter :: (a -> Bool) -> EnumSet w a -> EnumSet w a
filter a -> Bool
p (EnumSet w
w) = w -> EnumSet w a
forall k word (a :: k). word -> EnumSet word a
EnumSet (w -> EnumSet w a) -> w -> EnumSet w a
forall a b. (a -> b) -> a -> b
$ (w -> Int -> w) -> w -> w -> w
forall w a. (FiniteBits w, Num w) => (a -> Int -> a) -> a -> w -> a
foldlBits' w -> Int -> w
f w
0 w
w
    where
      f :: w -> Int -> w
f w
z Int
i
        | a -> Bool
p (a -> Bool) -> a -> Bool
forall a b. (a -> b) -> a -> b
$ Int -> a
forall a. Enum a => Int -> a
toEnum Int
i = w -> Int -> w
forall a. Bits a => a -> Int -> a
setBit w
z Int
i
        | Bool
otherwise    = w
z
      {-# INLINE f #-}

-- | /O(n)/. Partition the set according to some predicate.

-- The first set contains all elements that satisfy the predicate,

-- the second all elements that fail the predicate.

partition ::  w a. (FiniteBits w, Num w, Enum a)
          => (a -> Bool) -> EnumSet w a -> (EnumSet w a, EnumSet w a)
partition :: (a -> Bool) -> EnumSet w a -> (EnumSet w a, EnumSet w a)
partition a -> Bool
p (EnumSet w
w) = (w -> EnumSet w a
forall k word (a :: k). word -> EnumSet word a
EnumSet w
yay, w -> EnumSet w a
forall k word (a :: k). word -> EnumSet word a
EnumSet w
nay)
    where
      (w
yay, w
nay) = ((w, w) -> Int -> (w, w)) -> (w, w) -> w -> (w, w)
forall w a. (FiniteBits w, Num w) => (a -> Int -> a) -> a -> w -> a
foldlBits' (w, w) -> Int -> (w, w)
f (w
0, w
0) w
w
      f :: (w, w) -> Int -> (w, w)
f (w
x, w
y) Int
i
          | a -> Bool
p (a -> Bool) -> a -> Bool
forall a b. (a -> b) -> a -> b
$ Int -> a
forall a. Enum a => Int -> a
toEnum Int
i = (w -> Int -> w
forall a. Bits a => a -> Int -> a
setBit w
x Int
i, w
y)
          | Bool
otherwise    = (w
x, w -> Int -> w
forall a. Bits a => a -> Int -> a
setBit w
y Int
i)
      {-# INLINE f #-}

{--------------------------------------------------------------------
  Map
--------------------------------------------------------------------}

-- | /O(n)/.

-- @'map' f s@ is the set obtained by applying @f@ to each element of @s@.

--

-- It's worth noting that the size of the result may be smaller if,

-- for some @(x,y)@, @x \/= y && f x == f y@.

map ::  w a b. (FiniteBits w, Num w, Enum a, Enum b)
    => (a -> b) -> EnumSet w a -> EnumSet w b
map :: (a -> b) -> EnumSet w a -> EnumSet w b
map = (a -> b) -> EnumSet w a -> EnumSet w b
forall v w a b.
(FiniteBits v, FiniteBits w, Num v, Num w, Enum a, Enum b) =>
(a -> b) -> EnumSet v a -> EnumSet w b
map'
{-# INLINE map #-}

-- | /O(n)/. Apply 'map' while converting the underlying representation of the

-- set to some other representation.

map' ::  v w a b. (FiniteBits v, FiniteBits w, Num v, Num w, Enum a, Enum b)
     => (a -> b) -> EnumSet v a -> EnumSet w b
map' :: (a -> b) -> EnumSet v a -> EnumSet w b
map' a -> b
f0 (EnumSet v
w) = w -> EnumSet w b
forall k word (a :: k). word -> EnumSet word a
EnumSet (w -> EnumSet w b) -> w -> EnumSet w b
forall a b. (a -> b) -> a -> b
$ (w -> Int -> w) -> w -> v -> w
forall w a. (FiniteBits w, Num w) => (a -> Int -> a) -> a -> w -> a
foldlBits' w -> Int -> w
f w
0 v
w
    where
      f :: w -> Int -> w
f w
z Int
i = w -> Int -> w
forall a. Bits a => a -> Int -> a
setBit w
z (Int -> w) -> Int -> w
forall a b. (a -> b) -> a -> b
$ b -> Int
forall a. Enum a => a -> Int
fromEnum (b -> Int) -> b -> Int
forall a b. (a -> b) -> a -> b
$ a -> b
f0 (Int -> a
forall a. Enum a => Int -> a
toEnum Int
i)
      {-# INLINE f #-}

{--------------------------------------------------------------------
  Folds
--------------------------------------------------------------------}

-- | /O(n)/. Left fold.

foldl ::  w a b. (FiniteBits w, Num w, Enum a)
      => (b -> a -> b) -> b -> EnumSet w a -> b
foldl :: (b -> a -> b) -> b -> EnumSet w a -> b
foldl b -> a -> b
f b
z (EnumSet w
w) = (b -> Int -> b) -> b -> w -> b
forall w a. (FiniteBits w, Num w) => (a -> Int -> a) -> a -> w -> a
foldlBits (((a -> b) -> (Int -> a) -> Int -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> a
forall a. Enum a => Int -> a
toEnum) ((a -> b) -> Int -> b) -> (b -> a -> b) -> b -> Int -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> a -> b
f) b
z w
w
{-# INLINE foldl #-}

-- | /O(n)/. Left fold with strict accumulator.

foldl' ::  w a b. (FiniteBits w, Num w, Enum a)
       => (b -> a -> b) -> b -> EnumSet w a -> b
foldl' :: (b -> a -> b) -> b -> EnumSet w a -> b
foldl' b -> a -> b
f b
z (EnumSet w
w) = (b -> Int -> b) -> b -> w -> b
forall w a. (FiniteBits w, Num w) => (a -> Int -> a) -> a -> w -> a
foldlBits' (((a -> b) -> (Int -> a) -> Int -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> a
forall a. Enum a => Int -> a
toEnum) ((a -> b) -> Int -> b) -> (b -> a -> b) -> b -> Int -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> a -> b
f) b
z w
w
{-# INLINE foldl' #-}

-- | /O(n)/. Right fold.

foldr ::  w a b. (FiniteBits w, Num w, Enum a)
      => (a -> b -> b) -> b -> EnumSet w a -> b
foldr :: (a -> b -> b) -> b -> EnumSet w a -> b
foldr a -> b -> b
f b
z (EnumSet w
w) = (Int -> b -> b) -> b -> w -> b
forall w a. (FiniteBits w, Num w) => (Int -> a -> a) -> a -> w -> a
foldrBits (a -> b -> b
f (a -> b -> b) -> (Int -> a) -> Int -> b -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> a
forall a. Enum a => Int -> a
toEnum) b
z w
w
{-# INLINE foldr #-}

-- | /O(n)/. Right fold with strict accumulator.

foldr' ::  w a b. (FiniteBits w, Num w,  Enum a)
       => (a -> b -> b) -> b -> EnumSet w a -> b
foldr' :: (a -> b -> b) -> b -> EnumSet w a -> b
foldr' a -> b -> b
f b
z (EnumSet w
w) = (Int -> b -> b) -> b -> w -> b
forall w a. (FiniteBits w, Num w) => (Int -> a -> a) -> a -> w -> a
foldrBits' (a -> b -> b
f (a -> b -> b) -> (Int -> a) -> Int -> b -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> a
forall a. Enum a => Int -> a
toEnum) b
z w
w
{-# INLINE foldr' #-}

-- | /O(n)/. Left fold on non-empty sets.

foldl1 ::  w a. (FiniteBits w, Num w, Enum a)
       => (a -> a -> a) -> EnumSet w a -> a
foldl1 :: (a -> a -> a) -> EnumSet w a -> a
foldl1 a -> a -> a
f = (w -> Int) -> (a -> w -> a) -> EnumSet w a -> a
forall w a.
(Bits w, Num w, Enum a) =>
(w -> Int) -> (a -> w -> a) -> EnumSet w a -> a
fold1Aux w -> Int
forall w. (FiniteBits w, Num w) => w -> Int
lsb ((a -> w -> a) -> EnumSet w a -> a)
-> (a -> w -> a) -> EnumSet w a -> a
forall a b. (a -> b) -> a -> b
$ (a -> Int -> a) -> a -> w -> a
forall w a. (FiniteBits w, Num w) => (a -> Int -> a) -> a -> w -> a
foldlBits (((a -> a) -> (Int -> a) -> Int -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> a
forall a. Enum a => Int -> a
toEnum) ((a -> a) -> Int -> a) -> (a -> a -> a) -> a -> Int -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a -> a
f)
{-# INLINE foldl1 #-}

-- | /O(n)/. Left fold on non-empty sets with strict accumulator.

foldl1' ::  w a. (FiniteBits w, Num w, Enum a)
        => (a -> a -> a) -> EnumSet w a -> a
foldl1' :: (a -> a -> a) -> EnumSet w a -> a
foldl1' a -> a -> a
f = (w -> Int) -> (a -> w -> a) -> EnumSet w a -> a
forall w a.
(Bits w, Num w, Enum a) =>
(w -> Int) -> (a -> w -> a) -> EnumSet w a -> a
fold1Aux w -> Int
forall w. (FiniteBits w, Num w) => w -> Int
lsb ((a -> w -> a) -> EnumSet w a -> a)
-> (a -> w -> a) -> EnumSet w a -> a
forall a b. (a -> b) -> a -> b
$ (a -> Int -> a) -> a -> w -> a
forall w a. (FiniteBits w, Num w) => (a -> Int -> a) -> a -> w -> a
foldlBits' (((a -> a) -> (Int -> a) -> Int -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Int -> a
forall a. Enum a => Int -> a
toEnum) ((a -> a) -> Int -> a) -> (a -> a -> a) -> a -> Int -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a -> a
f)
{-# INLINE foldl1' #-}

-- | /O(n)/. Right fold on non-empty sets.

foldr1 ::  w a. (FiniteBits w, Num w, Enum a)
       => (a -> a -> a) -> EnumSet w a -> a
foldr1 :: (a -> a -> a) -> EnumSet w a -> a
foldr1 a -> a -> a
f = (w -> Int) -> (a -> w -> a) -> EnumSet w a -> a
forall w a.
(Bits w, Num w, Enum a) =>
(w -> Int) -> (a -> w -> a) -> EnumSet w a -> a
fold1Aux w -> Int
forall w. (FiniteBits w, Num w) => w -> Int
msb ((a -> w -> a) -> EnumSet w a -> a)
-> (a -> w -> a) -> EnumSet w a -> a
forall a b. (a -> b) -> a -> b
$ (Int -> a -> a) -> a -> w -> a
forall w a. (FiniteBits w, Num w) => (Int -> a -> a) -> a -> w -> a
foldrBits (a -> a -> a
f (a -> a -> a) -> (Int -> a) -> Int -> a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> a
forall a. Enum a => Int -> a
toEnum)
{-# INLINE foldr1 #-}

-- | /O(n)/. Right fold on non-empty sets with strict accumulator.

foldr1' ::  w a. (FiniteBits w, Num w, Enum a)
        => (a -> a -> a) -> EnumSet w a -> a
foldr1' :: (a -> a -> a) -> EnumSet w a -> a
foldr1' a -> a -> a
f = (w -> Int) -> (a -> w -> a) -> EnumSet w a -> a
forall w a.
(Bits w, Num w, Enum a) =>
(w -> Int) -> (a -> w -> a) -> EnumSet w a -> a
fold1Aux w -> Int
forall w. (FiniteBits w, Num w) => w -> Int
msb ((a -> w -> a) -> EnumSet w a -> a)
-> (a -> w -> a) -> EnumSet w a -> a
forall a b. (a -> b) -> a -> b
$ (Int -> a -> a) -> a -> w -> a
forall w a. (FiniteBits w, Num w) => (Int -> a -> a) -> a -> w -> a
foldrBits' (a -> a -> a
f (a -> a -> a) -> (Int -> a) -> Int -> a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> a
forall a. Enum a => Int -> a
toEnum)
{-# INLINE foldr1' #-}

-- | /O(n)/. Map each element of the structure to a monoid, and combine the

-- results.

foldMap ::  m w a. (Monoid m, FiniteBits w, Num w, Enum a)
        => (a -> m) -> EnumSet w a -> m
foldMap :: (a -> m) -> EnumSet w a -> m
foldMap a -> m
f (EnumSet w
w) = (Int -> m -> m) -> m -> w -> m
forall w a. (FiniteBits w, Num w) => (Int -> a -> a) -> a -> w -> a
foldrBits (m -> m -> m
forall a. Monoid a => a -> a -> a
mappend (m -> m -> m) -> (Int -> m) -> Int -> m -> m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> m
f (a -> m) -> (Int -> a) -> Int -> m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> a
forall a. Enum a => Int -> a
toEnum) m
forall a. Monoid a => a
mempty w
w
{-# INLINE foldMap #-}

traverse ::  f w a. (Applicative f, FiniteBits w, Num w, Enum a)
         => (a -> f a) -> EnumSet w a -> f (EnumSet w a)
traverse :: (a -> f a) -> EnumSet w a -> f (EnumSet w a)
traverse a -> f a
f (EnumSet w
w) = w -> EnumSet w a
forall k word (a :: k). word -> EnumSet word a
EnumSet (w -> EnumSet w a) -> f w -> f (EnumSet w a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                         (Int -> f w -> f w) -> f w -> w -> f w
forall w a. (FiniteBits w, Num w) => (Int -> a -> a) -> a -> w -> a
foldrBits
                         ((Int -> w -> w) -> f Int -> f w -> f w
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 ((w -> Int -> w) -> Int -> w -> w
forall a b c. (a -> b -> c) -> b -> a -> c
flip w -> Int -> w
forall a. Bits a => a -> Int -> a
setBit) (f Int -> f w -> f w) -> (Int -> f Int) -> Int -> f w -> f w
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Int) -> f a -> f Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> Int
forall a. Enum a => a -> Int
fromEnum (f a -> f Int) -> (Int -> f a) -> Int -> f Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> f a
f (a -> f a) -> (Int -> a) -> Int -> f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> a
forall a. Enum a => Int -> a
toEnum)
                         (w -> f w
forall (f :: * -> *) a. Applicative f => a -> f a
pure w
forall a. Bits a => a
zeroBits)
                         w
w
{-# INLINE traverse #-}

-- | /O(n)/. Check if all elements satisfy some predicate.

all ::  w a. (FiniteBits w, Num w, Enum a)
    => (a -> Bool) -> EnumSet w a -> Bool
all :: (a -> Bool) -> EnumSet w a -> Bool
all a -> Bool
p (EnumSet w
w) = let lb :: Int
lb = w -> Int
forall w. (FiniteBits w, Num w) => w -> Int
lsb w
w in Int -> w -> Bool
go Int
lb (w
w w -> Int -> w
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
lb)
  where
    go :: Int -> w -> Bool
go !Int
_ w
0 = Bool
True
    go Int
bi w
n
      | w
n w -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
`testBit` Int
0 Bool -> Bool -> Bool
&& Bool -> Bool
not (a -> Bool
p (a -> Bool) -> a -> Bool
forall a b. (a -> b) -> a -> b
$ Int -> a
forall a. Enum a => Int -> a
toEnum Int
bi) = Bool
False
      | Bool
otherwise = Int -> w -> Bool
go (Int
bi Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (w
n w -> Int -> w
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
1)

-- | /O(n)/. Check if any element satisfies some predicate.

any ::  w a. (FiniteBits w, Num w, Enum a)
    => (a -> Bool) -> EnumSet w a -> Bool
any :: (a -> Bool) -> EnumSet w a -> Bool
any a -> Bool
p (EnumSet w
w) = let lb :: Int
lb = w -> Int
forall w. (FiniteBits w, Num w) => w -> Int
lsb w
w in Int -> w -> Bool
go Int
lb (w
w w -> Int -> w
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
lb)
  where
    go :: Int -> w -> Bool
go !Int
_ w
0 = Bool
False
    go Int
bi w
n
      | w
n w -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
`testBit` Int
0 Bool -> Bool -> Bool
&& a -> Bool
p (Int -> a
forall a. Enum a => Int -> a
toEnum Int
bi) = Bool
True
      | Bool
otherwise = Int -> w -> Bool
go (Int
bi Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (w
n w -> Int -> w
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
1)

{--------------------------------------------------------------------
  Min/Max
--------------------------------------------------------------------}

-- | /O(1)/. The minimal element of a non-empty set.

minimum ::  w a. (FiniteBits w, Num w, Enum a)
        => EnumSet w a -> a
minimum :: EnumSet w a -> a
minimum (EnumSet w
0) = a
forall a. a
errorEmpty
minimum (EnumSet w
w) = Int -> a
forall a. Enum a => Int -> a
toEnum (Int -> a) -> Int -> a
forall a b. (a -> b) -> a -> b
$ w -> Int
forall w. (FiniteBits w, Num w) => w -> Int
lsb w
w

-- | /O(1)/. The maximal element of a non-empty set.

maximum ::  w a. (FiniteBits w, Num w, Enum a)
        => EnumSet w a -> a
maximum :: EnumSet w a -> a
maximum (EnumSet w
0) = a
forall a. a
errorEmpty
maximum (EnumSet w
w) = Int -> a
forall a. Enum a => Int -> a
toEnum (Int -> a) -> Int -> a
forall a b. (a -> b) -> a -> b
$ w -> Int
forall w. (FiniteBits w, Num w) => w -> Int
msb w
w

-- | /O(1)/. Delete the minimal element.

deleteMin ::  w a. (FiniteBits w, Num w)
          => EnumSet w a -> EnumSet w a
deleteMin :: EnumSet w a -> EnumSet w a
deleteMin (EnumSet w
0) = w -> EnumSet w a
forall k word (a :: k). word -> EnumSet word a
EnumSet w
0
deleteMin (EnumSet w
w) = w -> EnumSet w a
forall k word (a :: k). word -> EnumSet word a
EnumSet (w -> EnumSet w a) -> w -> EnumSet w a
forall a b. (a -> b) -> a -> b
$ w -> Int -> w
forall a. Bits a => a -> Int -> a
clearBit w
w (Int -> w) -> Int -> w
forall a b. (a -> b) -> a -> b
$ w -> Int
forall w. (FiniteBits w, Num w) => w -> Int
lsb w
w

-- | /O(1)/. Delete the maximal element.

deleteMax ::  w a. (FiniteBits w, Num w)
          => EnumSet w a -> EnumSet w a
deleteMax :: EnumSet w a -> EnumSet w a
deleteMax (EnumSet w
0) = w -> EnumSet w a
forall k word (a :: k). word -> EnumSet word a
EnumSet w
0
deleteMax (EnumSet w
w) = w -> EnumSet w a
forall k word (a :: k). word -> EnumSet word a
EnumSet (w -> EnumSet w a) -> w -> EnumSet w a
forall a b. (a -> b) -> a -> b
$ w -> Int -> w
forall a. Bits a => a -> Int -> a
clearBit w
w (Int -> w) -> Int -> w
forall a b. (a -> b) -> a -> b
$ w -> Int
forall w. (FiniteBits w, Num w) => w -> Int
msb w
w

-- | /O(1)/. Retrieves the minimal element of the set,

-- and the set stripped of that element,

-- or Nothing if passed an empty set.

minView ::  w a. (FiniteBits w, Num w, Enum a)
        => EnumSet w a -> Maybe (a, EnumSet w a)
minView :: EnumSet w a -> Maybe (a, EnumSet w a)
minView (EnumSet w
0) = Maybe (a, EnumSet w a)
forall a. Maybe a
Nothing
minView (EnumSet w
w) = let i :: Int
i = w -> Int
forall w. (FiniteBits w, Num w) => w -> Int
lsb w
w in (a, EnumSet w a) -> Maybe (a, EnumSet w a)
forall a. a -> Maybe a
Just (Int -> a
forall a. Enum a => Int -> a
toEnum Int
i, w -> EnumSet w a
forall k word (a :: k). word -> EnumSet word a
EnumSet (w -> EnumSet w a) -> w -> EnumSet w a
forall a b. (a -> b) -> a -> b
$ w -> Int -> w
forall a. Bits a => a -> Int -> a
clearBit w
w Int
i)

-- | /O(1)/. Retrieves the maximal element of the set,

-- and the set stripped of that element,

-- or Nothing if passed an empty set.

maxView ::  w a. (FiniteBits w, Num w, Enum a)
        => EnumSet w a -> Maybe (a, EnumSet w a)
maxView :: EnumSet w a -> Maybe (a, EnumSet w a)
maxView (EnumSet w
0) = Maybe (a, EnumSet w a)
forall a. Maybe a
Nothing
maxView (EnumSet w
w) = let i :: Int
i = w -> Int
forall w. (FiniteBits w, Num w) => w -> Int
msb w
w in (a, EnumSet w a) -> Maybe (a, EnumSet w a)
forall a. a -> Maybe a
Just (Int -> a
forall a. Enum a => Int -> a
toEnum Int
i, w -> EnumSet w a
forall k word (a :: k). word -> EnumSet word a
EnumSet (w -> EnumSet w a) -> w -> EnumSet w a
forall a b. (a -> b) -> a -> b
$ w -> Int -> w
forall a. Bits a => a -> Int -> a
clearBit w
w Int
i)

{--------------------------------------------------------------------
  Conversion
--------------------------------------------------------------------}

-- | /O(n)/. Convert the set to a list of values.

toList ::  w a. (FiniteBits w, Num w, Enum a)
       => EnumSet w a -> [a]
toList :: EnumSet w a -> [a]
toList (EnumSet w
w) = (forall b. (a -> b -> b) -> b -> b) -> [a]
forall a. (forall b. (a -> b -> b) -> b -> b) -> [a]
build \a -> b -> b
c b
n -> (Int -> b -> b) -> b -> w -> b
forall w a. (FiniteBits w, Num w) => (Int -> a -> a) -> a -> w -> a
foldrBits (a -> b -> b
c (a -> b -> b) -> (Int -> a) -> Int -> b -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> a
forall a. Enum a => Int -> a
toEnum) b
n w
w
{-# INLINE toList #-}

-- | /O(1)/. Convert a representation into an @EnumSet@.

-- Intended for use with foreign types.

fromRaw ::  w a. w -> EnumSet w a
fromRaw :: w -> EnumSet w a
fromRaw = w -> EnumSet w a
forall k word (a :: k). word -> EnumSet word a
EnumSet
{-# INLINE fromRaw #-}

{--------------------------------------------------------------------
  Utility functions
--------------------------------------------------------------------}

-- | Least significant bit. 

lsb ::  w. (FiniteBits w, Num w) => w -> Int
lsb :: w -> Int
lsb = w -> Int
forall b. FiniteBits b => b -> Int
countTrailingZeros
{-# INLINE lsb #-}

-- | Most significant bit.

msb ::  w. (FiniteBits w, Num w) => w -> Int
msb :: w -> Int
msb w
w = w -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize w
w Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
- w -> Int
forall b. FiniteBits b => b -> Int
countLeadingZeros w
w
{-# INLINE msb #-}

-- These folding algorithms are similar to those of [IntSet](https://hackage.haskell.org/package/containers-0.6.0.1/docs/src/Data.IntSet.Internal.html),

-- but generalized to work with any FiniteBits type.


-- | Left fold over bits.

foldlBits ::  w a. (FiniteBits w, Num w) => (a -> Int -> a) -> a -> w -> a
foldlBits :: (a -> Int -> a) -> a -> w -> a
foldlBits a -> Int -> a
f a
z w
w = let lb :: Int
lb = w -> Int
forall w. (FiniteBits w, Num w) => w -> Int
lsb w
w in Int -> a -> w -> a
go Int
lb a
z (w
w w -> Int -> w
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
lb)
  where
    go :: Int -> a -> w -> a
go !Int
_ a
acc w
0 = a
acc
    go Int
bi a
acc w
n
      | w
n w -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
`testBit` Int
0 = Int -> a -> w -> a
go (Int
bi Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (a -> Int -> a
f a
acc Int
bi) (w
n w -> Int -> w
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
1)
      | Bool
otherwise     = Int -> a -> w -> a
go (Int
bi Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)    a
acc     (w
n w -> Int -> w
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
1)
{-# INLINE foldlBits #-}

-- | Left fold over bits. The accumulator is evaluated to WHNF at every step.

foldlBits' ::  w a. (FiniteBits w, Num w) => (a -> Int -> a) -> a -> w -> a
foldlBits' :: (a -> Int -> a) -> a -> w -> a
foldlBits' a -> Int -> a
f a
z w
w = let lb :: Int
lb = w -> Int
forall w. (FiniteBits w, Num w) => w -> Int
lsb w
w in Int -> a -> w -> a
go Int
lb a
z (w
w w -> Int -> w
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
lb)
  where
    go :: Int -> a -> w -> a
go !Int
_ !a
acc w
0 = a
acc
    go Int
bi a
acc w
n
      | w
n w -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
`testBit` Int
0 = Int -> a -> w -> a
go (Int
bi Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (a -> Int -> a
f a
acc Int
bi) (w
n w -> Int -> w
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
1)
      | Bool
otherwise     = Int -> a -> w -> a
go (Int
bi Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)    a
acc     (w
n w -> Int -> w
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
1)
{-# INLINE foldlBits' #-}

-- | Right fold over bits.

foldrBits ::  w a. (FiniteBits w, Num w) => (Int -> a -> a) -> a -> w -> a
foldrBits :: (Int -> a -> a) -> a -> w -> a
foldrBits Int -> a -> a
f a
z w
w = let lb :: Int
lb = w -> Int
forall w. (FiniteBits w, Num w) => w -> Int
lsb w
w in Int -> w -> a
go Int
lb (w
w w -> Int -> w
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
lb)
  where
    go :: Int -> w -> a
go !Int
_ w
0 = a
z
    go Int
bi w
n
      | w
n w -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
`testBit` Int
0 = Int -> a -> a
f Int
bi (Int -> w -> a
go (Int
bi Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (w
n w -> Int -> w
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
1))
      | Bool
otherwise     =       Int -> w -> a
go (Int
bi Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (w
n w -> Int -> w
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
1)
{-# INLINE foldrBits #-}

-- | Right fold over bits. The accumulator is evaluated to WHNF at every step.

foldrBits' ::  w a. (FiniteBits w, Num w) => (Int -> a -> a) -> a -> w -> a
foldrBits' :: (Int -> a -> a) -> a -> w -> a
foldrBits' Int -> a -> a
f a
z w
w = let lb :: Int
lb = w -> Int
forall w. (FiniteBits w, Num w) => w -> Int
lsb w
w in Int -> w -> a
go Int
lb (w
w w -> Int -> w
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
lb)
  where
    go :: Int -> w -> a
go !Int
_ w
0 = a
z
    go Int
bi w
n
      | w
n w -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
`testBit` Int
0 = Int -> a -> a
f Int
bi (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$! Int -> w -> a
go (Int
bi Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (w
n w -> Int -> w
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
1)
      | Bool
otherwise     =         Int -> w -> a
go (Int
bi Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (w
n w -> Int -> w
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
1)
{-# INLINE foldrBits' #-}

fold1Aux ::  w a. (Bits w, Num w, Enum a)
         => (w -> Int) -> (a -> w -> a) -> EnumSet w a -> a
fold1Aux :: (w -> Int) -> (a -> w -> a) -> EnumSet w a -> a
fold1Aux w -> Int
_      a -> w -> a
_ (EnumSet w
0) = a
forall a. a
errorEmpty
fold1Aux w -> Int
getBit a -> w -> a
f (EnumSet w
w) = a -> w -> a
f (Int -> a
forall a. Enum a => Int -> a
toEnum Int
gotBit) (w -> Int -> w
forall a. Bits a => a -> Int -> a
clearBit w
w Int
gotBit)
  where
    gotBit :: Int
gotBit = w -> Int
getBit w
w
{-# INLINE fold1Aux #-}

errorEmpty :: a
errorEmpty :: a
errorEmpty = String -> a
forall a. HasCallStack => String -> a
error String
"Data.Enum.Set: empty EnumSet"