enumset (empty) → 0.0
raw patch · 5 files changed
+234/−0 lines, 5 filesdep +basedep +storable-recordsetup-changed
Dependencies added: base, storable-record
Files
- LICENSE +30/−0
- Setup.lhs +3/−0
- enumset.cabal +36/−0
- src/Data/EnumSet.hs +110/−0
- src/Data/EnumSet/PackedEnum.hs +55/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2011, Henning Thielemann+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are+met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Henning Thielemann nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.lhs view
@@ -0,0 +1,3 @@+#! /usr/bin/env runhaskell+> import Distribution.Simple+> main = defaultMain
+ enumset.cabal view
@@ -0,0 +1,36 @@+Name: enumset+Version: 0.0+License: BSD3+License-File: LICENSE+Author: Henning Thielemann <haskell@henning-thielemann.de>+Maintainer: Henning Thielemann <haskell@henning-thielemann.de>+Homepage: http://code.haskell.org/~thielema/enumset/+Category: Data, Foreign+Synopsis: Sets of enumeration values represented by machine words+Description:+ With this package you can create a type safe interface to flag sets.+ It is intended for interfacing to C libraries via FFI,+ where Word8, Word16, or Word32 types are commonly used to store bit vectors.+ E.g. the type @EnumSet Word16 Ordering@+ 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,+ however our implementation allows you to choose the embedding type+ and thus the maximum size of the set.+-- Portability: Haskell98+Cabal-Version: >=1.2+Tested-With: GHC==6.10.4, GHC==6.12.3+Build-Type: Simple++Library+ Build-Depends:+ storable-record >=0.0.1 && <0.1,+ base >= 4 && <6++ GHC-Options: -Wall+ Hs-Source-Dirs: src+ Exposed-Modules:+ Data.EnumSet+ Data.EnumSet.PackedEnum
+ src/Data/EnumSet.hs view
@@ -0,0 +1,110 @@+{- |+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.+-}+module Data.EnumSet (+ T(Cons, decons),+ fromEnum,+ fromEnums,+ toEnums,+ intToEnums,+ empty,+ (.&.),+ (.|.),+ xor,+ unions,+ get,+ put,+ set,+ clear,+ flip,+ fromBool,+ ) where++import qualified Data.Bits as B+import Data.Bits (Bits, )++import qualified Foreign.Storable.Newtype as Store+import Foreign.Storable (Storable(..), )++import qualified Prelude as P+import Prelude hiding (fromEnum, toEnum, flip, )+++newtype T word enum = Cons {decons :: word}+ deriving (Eq)++instance (Storable word, Enum enum) => Storable (T word enum) where+ sizeOf = Store.sizeOf decons+ alignment = Store.alignment decons+ peek = Store.peek Cons+ poke = Store.poke decons+++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 0 . 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 ..] . 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 ..] . iterate (P.flip div 2) .+ decons+++empty :: (Enum a, Bits w) => T w a+empty = Cons 0+++{-# 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..|.)+xor = lift2 B.xor++unions :: (Enum a, Bits w) => [T w a] -> T w a+unions = foldl (.|.) empty+++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+++{-# 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))++set :: (Enum a, Bits w) => a -> T w a -> T w a+set = lift1 B.setBit++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 (B.shiftL (fromIntegral $ P.fromEnum b) (P.fromEnum n))
+ src/Data/EnumSet/PackedEnum.hs view
@@ -0,0 +1,55 @@+{- |+Extract and inject an Enum value into an EnumSet.+-}+module Data.EnumSet.PackedEnum (T(Cons), unpack, pack, clear, put, ) where++import qualified Data.EnumSet as ES++import qualified Data.Bits as B+import Data.Bits (Bits, (.&.), )+++{- |+@ T w a b@ describes a contiguous set of bit indices into the word type @w@+where the indices are of type @a@ and the set of indices represent a value of type @b@.+-}+data T w a b = Cons w Int++{- |+Extract an enumeration value from the specified index set.+-}+unpack ::+ (Integral w, Bits w, Enum a, Enum b) =>+ T w a b -> ES.T w a -> b+unpack (Cons mask pos) =+ toEnum . fromIntegral . (mask .&.) .+ flip B.shiftR pos . ES.decons++{- |+Create an enumeration set, where an value of type @b@+is placed at the specified indices.+-}+pack ::+ (Bits w, Enum a, Enum b) =>+ T w a b -> b -> ES.T w a+pack (Cons mask pos) =+ ES.Cons . flip B.shiftL pos .+ (mask .&.) . fromIntegral . fromEnum++{- |+Clear all bits at the specified indices.+-}+clear ::+ (Bits w, Enum a, Enum b) =>+ T w a b -> ES.T w a -> ES.T w a+clear (Cons mask pos) =+ ES.Cons . (B.complement (B.shiftL mask pos) .&.) . ES.decons++{- |+Overwrite an enumset at the specified indices with the value of type @b@.+-}+put ::+ (Bits w, Enum a, Enum b) =>+ T w a b -> b -> ES.T w a -> ES.T w a+put set x =+ (pack set x ES..|.) . clear set