{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} module Clang.Internal.BitFlags ( BitFlags (..) , orFlags , andFlags , unFlags ) where import Data.Bits import Data.List class (Bits (FlagInt a), Num (FlagInt a)) => BitFlags a where type FlagInt a :: * type FlagInt a = Int toBit :: a -> FlagInt a orFlags :: BitFlags a => [a] -> FlagInt a orFlags [] = 0 orFlags fs = foldl1' (.|.) $ map toBit fs andFlags :: BitFlags a => [a] -> FlagInt a andFlags [] = 0 andFlags fs = foldl1' (.&.) $ map toBit fs unFlags :: forall a. (BitFlags a, Bounded a, Enum a) => FlagInt a -> [a] unFlags v = filter (checkFlag v) allFlags where checkFlag i f = (i .&. toBit f) /= 0 allFlags = enumFrom (minBound :: a)