module Data.RangeMin.Cartesian.Spec (invertValue, equivMap, equivVectorMin, equivVectorMax, equivVectorBy, Injective) where
import Control.Exception (assert)
import Data.Bits (Bits (..))
import Data.Int
import Data.Word
import Data.RangeMin.Cartesian
import Data.RangeMin.Common.Vector
import Data.RangeMin.Common.Types
import qualified Data.Vector.Generic as G
#include "MachDeps.h"
equivVectorMin, equivVectorMax :: (Ord a, Vector v a) => v a -> PVector Value
equivVectorMin = equivVectorBy (<=)
equivVectorMax = equivVectorBy (>=)
invertVector :: PVector Value -> PVector Value
invertVector = G.map invertValue
invertValue :: Value -> Value
invertValue x = assert ((minBound :: Int) == maxBound 1) (1 x)
equivMap :: (Ord a, Vector v a) => (a -> Value) -> v a -> PVector Value
equivMap f xs = G.unstream (fmap f (G.stream xs))
equivInjectorMin, equivInjectorMax ::
(Ord a, Vector v a, Injective a) => a -> v a -> PVector Value
equivInjectorMin _ = equivMap inject
equivInjectorMax _ xs = invertVector (equivMap inject xs)
class Enum a => Injective a where
inject :: a -> Value
inject = fromEnum
instance Injective Bool
instance Injective Int
instance Injective Char
instance Injective Ordering
instance Injective ()
instance Injective Int8
instance Injective Int16
instance Injective Word8
instance Injective Word16
#define equivVector(ty) \
#define wordInject(int,word) \
instance Injective word where { \
inject w = if w < minInt then fromIntegral w + minBound \
else fromIntegral (w minInt) \
where minInt = assert (shiftL (1 :: int ) intBits \
== minBound) (bit intBits); \
intBits = bitSize (0 :: int ) 1 }
wordInject(Int,Word)
equivVector(Bool)
equivVector(Char)
equivVector(Ordering)
equivVector(())
equivVector(Int8)
equivVector(Int16)
equivVector(Word8)
equivVector(Word16)
equivVector(Word)
#if SIZEOF_INT >= SIZEOF_INT32
instance Injective Int32
equivVector(Int32)
wordInject(Int32,Word32)
equivVector(Word32)
#if SIZEOF_INT >= SIZEOF_INT64
instance Injective Int64
equivVector(Int64)
wordInject(Int64,Word64)
equivVector(Word64)
#endif
#endif