enumset 0.0.4.1 → 0.0.5
raw patch · 4 files changed
+211/−200 lines, 4 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Data.EnumSet: (.&.) :: (Enum a, Bits w) => T w a -> T w a -> T w a
- Data.EnumSet: (.-.) :: (Enum a, Bits w) => T w a -> T w a -> T w a
- Data.EnumSet: (.|.) :: (Enum a, Bits w) => T w a -> T w a -> T w a
- Data.EnumSet: Cons :: word -> T word index
- Data.EnumSet: [decons] :: T word index -> word
- Data.EnumSet: accessor :: (Enum a, Bits w) => a -> T (T w a) Bool
- Data.EnumSet: clear :: (Enum a, Bits w) => a -> T w a -> T w a
- Data.EnumSet: disjoint :: (Enum a, Bits w) => T w a -> T w a -> Bool
- Data.EnumSet: empty :: (Enum a, Bits w) => T w a
- Data.EnumSet: flip :: (Enum a, Bits w) => a -> T w a -> T w a
- Data.EnumSet: fromBool :: (Enum a, Bits w) => a -> Bool -> T w a
- Data.EnumSet: fromEnum :: (Enum a, Bits w) => a -> T w a
- Data.EnumSet: fromEnums :: (Enum a, Bits w) => [a] -> T w a
- Data.EnumSet: get :: (Enum a, Bits w) => a -> T w a -> Bool
- Data.EnumSet: infixl 5 .|.
- Data.EnumSet: infixl 7 .-.
- Data.EnumSet: instance (GHC.Enum.Enum a, Data.Bits.Bits w) => Data.Semigroup.Semigroup (Data.EnumSet.T w a)
- Data.EnumSet: instance (GHC.Enum.Enum a, Data.Bits.Bits w) => GHC.Base.Monoid (Data.EnumSet.T w a)
- Data.EnumSet: instance (GHC.Enum.Enum a, Foreign.Storable.Storable w) => Foreign.Storable.Storable (Data.EnumSet.T w a)
- Data.EnumSet: instance GHC.Classes.Eq word => GHC.Classes.Eq (Data.EnumSet.T word index)
- Data.EnumSet: intToEnums :: (Enum a, Integral w) => T w a -> [a]
- Data.EnumSet: mostSignificantPosition :: (Bits w, Storable w) => T w a -> Int
- Data.EnumSet: newtype T word index
- Data.EnumSet: null :: (Enum a, Bits w) => T w a -> Bool
- Data.EnumSet: put :: (Enum a, Bits w) => a -> Bool -> T w a -> T w a
- Data.EnumSet: set :: (Enum a, Bits w) => a -> T w a -> T w a
- Data.EnumSet: singleton :: (Enum a, Bits w) => a -> T w a
- Data.EnumSet: singletonByPosition :: (Bits w) => Int -> T w a
- Data.EnumSet: subset :: (Enum a, Bits w) => T w a -> T w a -> Bool
- Data.EnumSet: toEnums :: (Enum a, Bits w) => T w a -> [a]
- Data.EnumSet: unions :: (Enum a, Bits w) => [T w a] -> T w a
- Data.EnumSet: xor :: (Enum a, Bits w) => T w a -> T w a -> T w a
- Data.FlagSet: instance Data.Bits.Bits w => Data.Semigroup.Semigroup (Data.FlagSet.MaskedValue w a)
+ Data.EnumBitSet: (.&.) :: (Enum a, Bits w) => T w a -> T w a -> T w a
+ Data.EnumBitSet: (.-.) :: (Enum a, Bits w) => T w a -> T w a -> T w a
+ Data.EnumBitSet: (.|.) :: (Enum a, Bits w) => T w a -> T w a -> T w a
+ Data.EnumBitSet: Cons :: word -> T word index
+ Data.EnumBitSet: [decons] :: T word index -> word
+ Data.EnumBitSet: accessor :: (Enum a, Bits w) => a -> T (T w a) Bool
+ Data.EnumBitSet: clear :: (Enum a, Bits w) => a -> T w a -> T w a
+ Data.EnumBitSet: disjoint :: (Enum a, Bits w) => T w a -> T w a -> Bool
+ Data.EnumBitSet: empty :: (Enum a, Bits w) => T w a
+ Data.EnumBitSet: flip :: (Enum a, Bits w) => a -> T w a -> T w a
+ Data.EnumBitSet: fromBool :: (Enum a, Bits w) => a -> Bool -> T w a
+ Data.EnumBitSet: fromEnum :: (Enum a, Bits w) => a -> T w a
+ Data.EnumBitSet: fromEnums :: (Enum a, Bits w) => [a] -> T w a
+ Data.EnumBitSet: get :: (Enum a, Bits w) => a -> T w a -> Bool
+ Data.EnumBitSet: infixl 5 .|.
+ Data.EnumBitSet: infixl 7 .-.
+ Data.EnumBitSet: instance (GHC.Enum.Enum a, Data.Bits.Bits w) => GHC.Base.Monoid (Data.EnumBitSet.T w a)
+ Data.EnumBitSet: instance (GHC.Enum.Enum a, Data.Bits.Bits w) => GHC.Base.Semigroup (Data.EnumBitSet.T w a)
+ Data.EnumBitSet: instance (GHC.Enum.Enum a, Foreign.Storable.Storable w) => Foreign.Storable.Storable (Data.EnumBitSet.T w a)
+ Data.EnumBitSet: instance GHC.Classes.Eq word => GHC.Classes.Eq (Data.EnumBitSet.T word index)
+ Data.EnumBitSet: intToEnums :: (Enum a, Integral w) => T w a -> [a]
+ Data.EnumBitSet: mostSignificantPosition :: (Bits w, Storable w) => T w a -> Int
+ Data.EnumBitSet: newtype T word index
+ Data.EnumBitSet: null :: (Enum a, Bits w) => T w a -> Bool
+ Data.EnumBitSet: put :: (Enum a, Bits w) => a -> Bool -> T w a -> T w a
+ Data.EnumBitSet: set :: (Enum a, Bits w) => a -> T w a -> T w a
+ Data.EnumBitSet: singleton :: (Enum a, Bits w) => a -> T w a
+ Data.EnumBitSet: singletonByPosition :: Bits w => Int -> T w a
+ Data.EnumBitSet: subset :: (Enum a, Bits w) => T w a -> T w a -> Bool
+ Data.EnumBitSet: toEnums :: (Enum a, Bits w) => T w a -> [a]
+ Data.EnumBitSet: unions :: (Enum a, Bits w) => [T w a] -> T w a
+ Data.EnumBitSet: xor :: (Enum a, Bits w) => T w a -> T w a -> T w a
+ Data.FlagSet: instance Data.Bits.Bits w => GHC.Base.Semigroup (Data.FlagSet.MaskedValue w a)
- Data.FlagSet: fromEnum :: (Enum a, (Bits w)) => a -> MaskedValue w a
+ Data.FlagSet: fromEnum :: (Enum a, Bits w) => a -> MaskedValue w a
- Data.FlagSet: match :: (Bits w) => T w a -> MaskedValue w a -> Bool
+ Data.FlagSet: match :: Bits w => T w a -> MaskedValue w a -> Bool
Files
- enumset.cabal +5/−4
- src/Data/EnumBitSet.hs +198/−0
- src/Data/EnumSet.hs +7/−195
- src/Data/EnumSet/PackedEnum.hs +1/−1
enumset.cabal view
@@ -1,5 +1,5 @@ Name: enumset-Version: 0.0.4.1+Version: 0.0.5 License: BSD3 License-File: LICENSE Author: Henning Thielemann <haskell@henning-thielemann.de>@@ -21,11 +21,11 @@ . See also @data-flags@ and @Data.EnumSet@ in @enummapset@. Cabal-Version: >=1.10-Tested-With: GHC==7.4.2, GHC==7.6.3, GHC==8.4.1+Tested-With: GHC==7.4.2, GHC==7.6.3, GHC==8.4.4, GHC==8.6.5 Build-Type: Simple Source-Repository this- Tag: 0.0.4.1+ Tag: 0.0.5 Type: darcs Location: http://code.haskell.org/~thielema/enumset/ @@ -39,11 +39,12 @@ data-accessor >=0.2.1 && <0.3, storable-record >=0.0.1 && <0.1, semigroups >=0.1 && <1.0,- base >= 4 && <5+ base >=4 && <5 GHC-Options: -Wall Hs-Source-Dirs: src Exposed-Modules:+ Data.EnumBitSet Data.EnumSet Data.EnumSet.PackedEnum Data.FlagSet
+ src/Data/EnumBitSet.hs view
@@ -0,0 +1,198 @@+{- |+Similar to Data.Edison.Coll.EnumSet+but it allows to choose the underlying type for bit storage.+This is really a low-level module for type-safe foreign function interfaces.++The integer representation of the enumeration type+is the bit position of the flag within the bitvector.+-}+module Data.EnumBitSet (+ T(Cons, decons),+ fromEnum,+ fromEnums,+ toEnums,+ intToEnums,+ mostSignificantPosition,+ singletonByPosition,+ null,+ empty,+ singleton,+ disjoint,+ subset,+ (.&.),+ (.-.),+ (.|.),+ xor,+ unions,+ get,+ put,+ accessor,+ set,+ clear,+ flip,+ fromBool,+ ) where++import qualified Data.EnumSet.Utility as U+import qualified Data.Bits as B+import Data.Bits (Bits, )++import Data.Monoid (Monoid(mempty, mappend), )+import Data.Semigroup (Semigroup((<>)), )++import qualified Foreign.Storable.Newtype as Store+import Foreign.Storable (Storable(sizeOf, alignment, peek, poke), )++import qualified Data.Accessor.Basic as Acc++import qualified Prelude as P+import Prelude hiding (fromEnum, toEnum, null, flip, )+++newtype T word index = Cons {decons :: word}+ deriving (Eq)++instance (Enum a, Storable w) => Storable (T w a) where+ sizeOf = Store.sizeOf decons+ alignment = Store.alignment decons+ peek = Store.peek Cons+ poke = Store.poke decons+++instance (Enum a, Bits w) => Semigroup (T w a) where+ (<>) = (.|.)++{- |+Since this data type is intended for constructing flags,+we choose the set union as 'mappend'.+For intersection we would also not have a canonical identity element.+-}+instance (Enum a, Bits w) => Monoid (T w a) where+ mempty = empty+ mappend = (.|.)+++fromEnum :: (Enum a, Bits w) => a -> T w a+fromEnum = Cons . B.bit . P.fromEnum++fromEnums :: (Enum a, Bits w) => [a] -> T w a+fromEnums = Cons . foldl B.setBit U.empty . map P.fromEnum++toEnums :: (Enum a, Bits w) => T w a -> [a]+toEnums =+ map fst . filter (P.flip B.testBit 0 . snd) .+ zip [P.toEnum 0 ..] .+ takeWhile (U.empty /= ) . iterate (P.flip B.shiftR 1) .+ decons++intToEnums :: (Enum a, Integral w) => T w a -> [a]+intToEnums =+ map fst . filter (odd . snd) .+ zip [P.toEnum 0 ..] .+ takeWhile (0/=) . iterate (P.flip div 2) .+ decons+++{- |+floor of binary logarithm -+Intended for getting the position of a single set bit.+This in turn is intended for implementing an 'Enum' instance+if you only know masks but no bit positions.+-}+{-# INLINE mostSignificantPosition #-}+mostSignificantPosition :: (Bits w, Storable w) => T w a -> Int+mostSignificantPosition (Cons x) =+ snd $+ foldl+ (\(x0,pos) testPos ->+ let x1 = B.shiftR x0 testPos+ in if x1 == U.empty+ then (x0, pos)+ else (x1, pos+testPos))+ (x,0) $+ reverse $+ takeWhile (< sizeOf x * 8) $+ iterate (2*) 1++{- |+set a bit -+Intended for implementing an 'Enum' instance+if you only know masks but no bit positions.+-}+{-# INLINE singletonByPosition #-}+singletonByPosition :: (Bits w) => Int -> T w a+singletonByPosition = Cons . B.setBit U.empty+++null :: (Enum a, Bits w) => T w a -> Bool+null (Cons x) = x==U.empty++empty :: (Enum a, Bits w) => T w a+empty = Cons U.empty++disjoint :: (Enum a, Bits w) => T w a -> T w a -> Bool+disjoint x y = null (x .&. y)++{- |+@subset a b@ is 'True' if @a@ is a subset of @b@.+-}+subset :: (Enum a, Bits w) => T w a -> T w a -> Bool+subset x y = null (x .-. y)+++{-# INLINE lift2 #-}+lift2 :: (w -> w -> w) -> (T w a -> T w a -> T w a)+lift2 f (Cons x) (Cons y) = Cons (f x y)++-- fixities like in Data.Bits+infixl 7 .&., .-.+infixl 5 .|.++(.&.), (.-.), (.|.), xor :: (Enum a, Bits w) => T w a -> T w a -> T w a+(.&.) = lift2 (B..&.)+(.|.) = lift2 (B..|.)+(.-.) = lift2 (\x y -> x B..&. B.complement y)+xor = lift2 B.xor++unions :: (Enum a, Bits w) => [T w a] -> T w a+unions = foldl (.|.) empty+++-- | could also be named @member@ like in @Set@ or @elem@ as in '[]'+get :: (Enum a, Bits w) => a -> T w a -> Bool+get n = P.flip B.testBit (P.fromEnum n) . decons++put :: (Enum a, Bits w) => a -> Bool -> T w a -> T w a+put n b s =+ fromBool n b .|. clear n s++accessor :: (Enum a, Bits w) => a -> Acc.T (T w a) Bool+accessor x = Acc.fromSetGet (put x) (get x)+++{-# INLINE lift1 #-}+lift1 ::+ (Enum a, Bits w) =>+ (w -> Int -> w) -> (a -> T w a -> T w a)+lift1 f n (Cons vec) = Cons (f vec (P.fromEnum n))++singleton :: (Enum a, Bits w) => a -> T w a+singleton = P.flip set empty++-- | could also be named @insert@ like in @Set@+set :: (Enum a, Bits w) => a -> T w a -> T w a+set = lift1 B.setBit++-- | could also be named @delete@ like in @Set@+clear :: (Enum a, Bits w) => a -> T w a -> T w a+clear = lift1 B.clearBit++flip :: (Enum a, Bits w) => a -> T w a -> T w a+flip = lift1 B.complementBit++fromBool :: (Enum a, Bits w) => a -> Bool -> T w a+fromBool n b =+ Cons $ if b then B.bit (P.fromEnum n) else U.empty+{- requires Num instance+ Cons (B.shiftL (fromIntegral $ P.fromEnum b) (P.fromEnum n))+-}
src/Data/EnumSet.hs view
@@ -1,198 +1,10 @@ {- |-Similar to Data.Edison.Coll.EnumSet-but it allows to choose the underlying type for bit storage.-This is really a low-level module for type-safe foreign function interfaces.--The integer representation of the enumeration type-is the bit position of the flag within the bitvector.--}-module Data.EnumSet (- T(Cons, decons),- fromEnum,- fromEnums,- toEnums,- intToEnums,- mostSignificantPosition,- singletonByPosition,- null,- empty,- singleton,- disjoint,- subset,- (.&.),- (.-.),- (.|.),- xor,- unions,- get,- put,- accessor,- set,- clear,- flip,- fromBool,- ) where--import qualified Data.Bits as B-import Data.Bits (Bits, )-import qualified Data.EnumSet.Utility as U--import Data.Monoid (Monoid(mempty, mappend), )-import Data.Semigroup (Semigroup((<>)), )--import qualified Foreign.Storable.Newtype as Store-import Foreign.Storable (Storable(sizeOf, alignment, peek, poke), )--import qualified Data.Accessor.Basic as Acc--import qualified Prelude as P-import Prelude hiding (fromEnum, toEnum, null, flip, )---newtype T word index = Cons {decons :: word}- deriving (Eq)--instance (Enum a, Storable w) => Storable (T w a) where- sizeOf = Store.sizeOf decons- alignment = Store.alignment decons- peek = Store.peek Cons- poke = Store.poke decons---instance (Enum a, Bits w) => Semigroup (T w a) where- (<>) = (.|.)--{- |-Since this data type is intended for constructing flags,-we choose the set union as 'mappend'.-For intersection we would also not have a canonical identity element.--}-instance (Enum a, Bits w) => Monoid (T w a) where- mempty = empty- mappend = (.|.)---fromEnum :: (Enum a, Bits w) => a -> T w a-fromEnum = Cons . B.bit . P.fromEnum--fromEnums :: (Enum a, Bits w) => [a] -> T w a-fromEnums = Cons . foldl B.setBit U.empty . map P.fromEnum--toEnums :: (Enum a, Bits w) => T w a -> [a]-toEnums =- map fst . filter (P.flip B.testBit 0 . snd) .- zip [P.toEnum 0 ..] .- takeWhile (U.empty /= ) . iterate (P.flip B.shiftR 1) .- decons--intToEnums :: (Enum a, Integral w) => T w a -> [a]-intToEnums =- map fst . filter (odd . snd) .- zip [P.toEnum 0 ..] .- takeWhile (0/=) . iterate (P.flip div 2) .- decons---{- |-floor of binary logarithm --Intended for getting the position of a single set bit.-This in turn is intended for implementing an 'Enum' instance-if you only know masks but no bit positions.--}-{-# INLINE mostSignificantPosition #-}-mostSignificantPosition :: (Bits w, Storable w) => T w a -> Int-mostSignificantPosition (Cons x) =- snd $- foldl- (\(x0,pos) testPos ->- let x1 = B.shiftR x0 testPos- in if x1 == U.empty- then (x0, pos)- else (x1, pos+testPos))- (x,0) $- reverse $- takeWhile (< sizeOf x * 8) $- iterate (2*) 1--{- |-set a bit --Intended for implementing an 'Enum' instance-if you only know masks but no bit positions.--}-{-# INLINE singletonByPosition #-}-singletonByPosition :: (Bits w) => Int -> T w a-singletonByPosition = Cons . B.setBit U.empty---null :: (Enum a, Bits w) => T w a -> Bool-null (Cons x) = x==U.empty--empty :: (Enum a, Bits w) => T w a-empty = Cons U.empty--disjoint :: (Enum a, Bits w) => T w a -> T w a -> Bool-disjoint x y = null (x .&. y)--{- |-@subset a b@ is 'True' if @a@ is a subset of @b@.+The module name clashes with a module from the package @enummapset@.+Thus we will remove this module in favor of "Data.EnumBitSet". -}-subset :: (Enum a, Bits w) => T w a -> T w a -> Bool-subset x y = null (x .-. y)---{-# INLINE lift2 #-}-lift2 :: (w -> w -> w) -> (T w a -> T w a -> T w a)-lift2 f (Cons x) (Cons y) = Cons (f x y)---- fixities like in Data.Bits-infixl 7 .&., .-.-infixl 5 .|.--(.&.), (.-.), (.|.), xor :: (Enum a, Bits w) => T w a -> T w a -> T w a-(.&.) = lift2 (B..&.)-(.|.) = lift2 (B..|.)-(.-.) = lift2 (\x y -> x B..&. B.complement y)-xor = lift2 B.xor--unions :: (Enum a, Bits w) => [T w a] -> T w a-unions = foldl (.|.) empty----- | could also be named @member@ like in @Set@ or @elem@ as in '[]'-get :: (Enum a, Bits w) => a -> T w a -> Bool-get n = P.flip B.testBit (P.fromEnum n) . decons--put :: (Enum a, Bits w) => a -> Bool -> T w a -> T w a-put n b s =- fromBool n b .|. clear n s--accessor :: (Enum a, Bits w) => a -> Acc.T (T w a) Bool-accessor x = Acc.fromSetGet (put x) (get x)---{-# INLINE lift1 #-}-lift1 ::- (Enum a, Bits w) =>- (w -> Int -> w) -> (a -> T w a -> T w a)-lift1 f n (Cons vec) = Cons (f vec (P.fromEnum n))--singleton :: (Enum a, Bits w) => a -> T w a-singleton = P.flip set empty---- | could also be named @insert@ like in @Set@-set :: (Enum a, Bits w) => a -> T w a -> T w a-set = lift1 B.setBit---- | could also be named @delete@ like in @Set@-clear :: (Enum a, Bits w) => a -> T w a -> T w a-clear = lift1 B.clearBit--flip :: (Enum a, Bits w) => a -> T w a -> T w a-flip = lift1 B.complementBit+module Data.EnumSet+ {-# DEPRECATED "use Data.EnumBitSet instead" #-}+ (module Data.EnumBitSet)+ where -fromBool :: (Enum a, Bits w) => a -> Bool -> T w a-fromBool n b =- Cons $ if b then B.bit (P.fromEnum n) else U.empty-{- requires Num instance- Cons (B.shiftL (fromIntegral $ P.fromEnum b) (P.fromEnum n))--}+import Data.EnumBitSet
src/Data/EnumSet/PackedEnum.hs view
@@ -6,7 +6,7 @@ (T(Cons), unpack, pack, clear, put, ) where -import qualified Data.EnumSet as ES+import qualified Data.EnumBitSet as ES import qualified Data.Bits as B import Data.Bits (Bits, (.&.), )