packages feed

enumset 0.0.1 → 0.0.2

raw patch · 4 files changed

+223/−12 lines, 4 filesdep +data-accessorPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: data-accessor

API changes (from Hackage documentation)

- Data.EnumSet: instance (Storable word, Enum enum) => Storable (T word enum)
- Data.EnumSet: instance Eq word => Eq (T word enum)
+ Data.EnumSet: (.-.) :: (Enum a, Bits w) => T w a -> T w a -> T w a
+ Data.EnumSet: accessor :: (Enum a, Bits w) => a -> T (T w a) Bool
+ Data.EnumSet: disjoint :: (Enum a, Bits w) => T w a -> T w a -> Bool
+ Data.EnumSet: instance (Enum a, Bits w) => Monoid (T w a)
+ Data.EnumSet: instance (Enum a, Storable w) => Storable (T w a)
+ Data.EnumSet: instance Eq word => Eq (T word index)
+ Data.EnumSet: mostSignificantPosition :: (Bits w, Storable w) => T w a -> Int
+ Data.EnumSet: singleton :: (Enum a, Bits w) => a -> T w a
+ Data.EnumSet: singletonByPosition :: Bits w => Int -> T w a
+ Data.FlagSet: Cons :: word -> T word a
+ Data.FlagSet: Mask :: w -> Mask w a b
+ Data.FlagSet: MaskedValue :: w -> w -> MaskedValue w a
+ Data.FlagSet: Value :: w -> Value w b
+ Data.FlagSet: accessor :: (Enum a, Bits w) => Mask w a b -> T (T w a) (Value w b)
+ Data.FlagSet: class Enum a
+ Data.FlagSet: compose :: (Enum a, Enum a, Bits w) => [a] -> T w a
+ Data.FlagSet: data MaskedValue w a
+ Data.FlagSet: decompose :: (Bounded a, Enum a, Enum a, Bits w) => T w a -> [a]
+ Data.FlagSet: decons :: T word a -> word
+ Data.FlagSet: fromEnum :: (Enum a, Bits w) => a -> MaskedValue w a
+ Data.FlagSet: fromMaskedValue :: MaskedValue w a -> T w a
+ Data.FlagSet: get :: (Enum a, Bits w) => Mask w a b -> T w a -> Value w b
+ Data.FlagSet: instance Bits w => Monoid (MaskedValue w a)
+ Data.FlagSet: instance Eq w => Eq (Mask w a b)
+ Data.FlagSet: instance Eq w => Eq (MaskedValue w a)
+ Data.FlagSet: instance Eq w => Eq (Value w b)
+ Data.FlagSet: instance Eq word => Eq (T word a)
+ Data.FlagSet: instance Show w => Show (Mask w a b)
+ Data.FlagSet: instance Show w => Show (MaskedValue w a)
+ Data.FlagSet: instance Show w => Show (Value w b)
+ Data.FlagSet: instance Storable w => Storable (T w a)
+ Data.FlagSet: maskValue :: Mask w a b -> Value w b -> MaskedValue w a
+ Data.FlagSet: match :: Bits w => T w a -> MaskedValue w a -> Bool
+ Data.FlagSet: newtype Mask w a b
+ Data.FlagSet: newtype T word a
+ Data.FlagSet: newtype Value w b
+ Data.FlagSet: put :: (Enum a, Bits w) => Mask w a b -> Value w b -> T w a -> T w a
+ Data.FlagSet: unmask :: Mask w a b -> w
+ Data.FlagSet: unvalue :: Value w b -> w
- Data.EnumSet: Cons :: word -> T word enum
+ Data.EnumSet: Cons :: word -> T word index
- Data.EnumSet: decons :: T word enum -> word
+ Data.EnumSet: decons :: T word index -> word
- Data.EnumSet: newtype T word enum
+ Data.EnumSet: newtype T word index

Files

enumset.cabal view
@@ -1,5 +1,6 @@+-- would also be useful as type-safe alternative in wx, wxcore Name:             enumset-Version:          0.0.1+Version:          0.0.2 License:          BSD3 License-File:     LICENSE Author:           Henning Thielemann <haskell@henning-thielemann.de>@@ -14,17 +15,16 @@   represents a flag set stored in a Word16   that supports the flags @LT@, @EQ@, @GT@.   .-  This package is similar to the @bitset@ package-  the @Data.Edison.Coll.EnumSet@ module in the edison package,+  This package is similar to the @bitset@ package and+  the @Data.Edison.Coll.EnumSet@ module in the @edison@ package,   however our implementation allows you to choose the embedding type   and thus the maximum size of the set.--- Portability:      Haskell98-Cabal-Version:    >=1.6+Cabal-Version:    >=1.10 Tested-With:      GHC==6.10.4, GHC==6.12.3 Build-Type:       Simple  Source-Repository this-  Tag:         0.0.1+  Tag:         0.0.2   Type:        darcs   Location:    http://code.haskell.org/~thielema/enumset/ @@ -33,7 +33,9 @@   Location:    http://code.haskell.org/~thielema/enumset/  Library+  Default-Language: Haskell98   Build-Depends:+    data-accessor >=0.2.1 && <0.3,     storable-record >=0.0.1 && <0.1,     base >= 4 && <5 @@ -42,3 +44,4 @@   Exposed-Modules:     Data.EnumSet     Data.EnumSet.PackedEnum+    Data.FlagSet
src/Data/EnumSet.hs view
@@ -2,6 +2,9 @@ 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),@@ -9,14 +12,20 @@    fromEnums,    toEnums,    intToEnums,+   mostSignificantPosition,+   singletonByPosition,    null,    empty,+   singleton,+   disjoint,    (.&.),+   (.-.),    (.|.),    xor,    unions,    get,    put,+   accessor,    set,    clear,    flip,@@ -26,23 +35,36 @@ import qualified Data.Bits as B import Data.Bits (Bits, ) +import Data.Monoid (Monoid(mempty, mappend), )+ import qualified Foreign.Storable.Newtype as Store-import Foreign.Storable (Storable(..), )+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 enum = Cons {decons :: word}+newtype T word index = Cons {decons :: word}    deriving (Eq) -instance (Storable word, Enum enum) => Storable (T word enum) where+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 +{- |+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 @@ -62,24 +84,59 @@    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 == 0+               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 0++ null :: (Enum a, Bits w) => T w a -> Bool null (Cons x)  =  x==0  empty :: (Enum a, Bits w) => T w a empty = Cons 0 +disjoint :: (Enum a, Bits w) => T w a -> T w a -> Bool+disjoint 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 7 .&., .-. infixl 5 .|. -(.&.), (.|.), xor :: (Enum a, Bits w) => T w a -> T w a -> T w a+(.&.), (.-.), (.|.), 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@@ -93,12 +150,18 @@ 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  set :: (Enum a, Bits w) => a -> T w a -> T w a set = lift1 B.setBit
src/Data/EnumSet/PackedEnum.hs view
@@ -1,7 +1,10 @@ {- | Extract and inject an Enum value into an EnumSet. -}-module Data.EnumSet.PackedEnum (T(Cons), unpack, pack, clear, put, ) where+module Data.EnumSet.PackedEnum+   {-# DEPRECATED "use Data.FlagSet instead" #-}+   (T(Cons), unpack, pack, clear, put, )+   where  import qualified Data.EnumSet as ES 
+ src/Data/FlagSet.hs view
@@ -0,0 +1,142 @@+{- |+A bit vector that represents a record in a bit-packed way.+-}+module Data.FlagSet (+   T(Cons, decons),+   fromMaskedValue, match,+   Enum(fromEnum),+   compose, decompose,+   Mask(Mask, unmask), maskValue,+   Value(Value, unvalue),+   MaskedValue(MaskedValue),+   get, put, accessor,+   ) where++import qualified Data.Bits as B+import Data.Bits (Bits, (.&.), (.|.), )++import Data.Monoid (Monoid(mempty, mappend, mconcat), )++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 (Enum, fromEnum, toEnum, null, flip, )+++{- |+The basic bit vector data type.+It does not provide a lot of functionality,+since that could not be done in a safe way.++The type @a@ identifies the maintained flags.+It may be an empty type+but it may also be an enumeration+of record fields with concrete values.+In the latter case you are encouraged to define an 'Enum' instance+for this enumeration.+Be aware that it is different from 'P.Enum' of Prelude.+-}+newtype T word a = Cons {decons :: word}+   deriving (Eq)++instance (Storable w) => Storable (T w a) where+   sizeOf = Store.sizeOf decons+   alignment = Store.alignment decons+   peek = Store.peek Cons+   poke = Store.poke decons+++{- |+@Mask w a b@ describes a field of a @T w a@ that has type @Value w b@.+On the machine level a 'Mask' value is a vector of bits,+where set bits represent the bits belonging to one record field.+There must be only one mask value for every pair of types @(a,b)@.+-}+newtype Mask w a b = Mask {unmask :: w}+   deriving (Eq, Show)++newtype Value w b = Value {unvalue :: w}+   deriving (Eq, Show)+++get :: (Enum a, Bits w) => Mask w a b -> T w a -> Value w b+get (Mask m) (Cons fs) = Value (m .&. fs)++put :: (Enum a, Bits w) => Mask w a b -> Value w b -> T w a -> T w a+put (Mask m) (Value v) (Cons fs) =+   Cons $ (fs .-. m) .|. v++accessor :: (Enum a, Bits w) => Mask w a b -> Acc.T (T w a) (Value w b)+accessor m = Acc.fromSetGet (put m) (get m)++++{- |+Combines a mask with a value, that matches this mask.+In @MaskedValue mask value@, @value@ must be a subset of @mask@.+-}+data MaskedValue w a = MaskedValue w w+   deriving (Eq, Show)+++fromMaskedValue :: MaskedValue w a -> T w a+fromMaskedValue (MaskedValue _m v) = Cons v++match :: (Bits w) => T w a -> MaskedValue w a -> Bool+match (Cons fs) (MaskedValue m v) =+   m .&. fs  ==  v+++maskValue :: Mask w a b -> Value w b -> MaskedValue w a+maskValue (Mask m) (Value v) = MaskedValue m v+++{- |+@mappend a b@ means that values stored in @b@ overwrite corresponding values in @a@.+-}+instance (Bits w) => Monoid (MaskedValue w a) where+   mempty = MaskedValue 0 0+   mappend (MaskedValue mx vx) (MaskedValue my vy) =+      MaskedValue (mx .|. my) (vx .-. my  .|.  vy)+++class Enum a where+   {- |+   'P.fromEnum' should return an integer+   that represents the position of the @a@ value+   in the list of all enumeration items.+   In contrast to that,+   'fromEnum' must return the according bit pattern.+   -}+   fromEnum :: (Bits w) => a -> MaskedValue w a++{- |+Decompose a flag set into flags.+The flags are generated using the 'Bounded' and 'Enum' instance.+We do not recommend to use the result list for further processing,+since testing of flags is much faster using 'match'.+However you may find it useful to 'show' the list.+-}+decompose :: (Bounded a, Enum a, P.Enum a, Bits w) => T w a -> [a]+decompose x =+   filter (match x . fromEnum) [minBound .. maxBound]++{- |+Compose a flag set from a list of flags.+However you may prefer to assemble flags+using 'mconcat' or 'mappend' on 'MaskedValue's.+-}+compose :: (Enum a, P.Enum a, Bits w) => [a] -> T w a+compose xs =+   fromMaskedValue $ mconcat $ map fromEnum xs++++-- fixity like .&.+infixl 7 .-.++(.-.) :: (Bits w) => w -> w -> w+x .-. y = x .&. B.complement y