% -----------------------------------------------------------------------------
-% $Id: PrelArr.lhs,v 1.28 2001/05/01 09:16:56 qrczak Exp $
+% $Id: PrelArr.lhs,v 1.29 2001/08/29 09:34:05 simonmar Exp $
%
% (c) The University of Glasgow, 1994-2000
%
%*********************************************************
\begin{code}
-class (Ord a) => Ix a where
+class Ix a where
range :: (a,a) -> [a]
index, unsafeIndex :: (a,a) -> a -> Int
inRange :: (a,a) -> a -> Bool
+ rangeSize :: (a,a) -> Int
+ unsafeRangeSize :: (a,a) -> Int
-- Must specify one of index, unsafeIndex
index b i | inRange b i = unsafeIndex b i
| otherwise = error "Error in array index"
unsafeIndex b i = index b i
+
+ -- As long as you don't override the default rangeSize,
+ -- you can specify unsafeRangeSize as follows, to speed up
+ -- some operations:
+ --
+ -- unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
+ --
+ rangeSize b@(_l,h) | inRange b h = unsafeIndex b h + 1
+ | otherwise = 0
+ unsafeRangeSize b = rangeSize b
\end{code}
+Note that the following is NOT right
+ rangeSize (l,h) | l <= h = index b h + 1
+ | otherwise = 0
+
+Because it might be the case that l<h, but the range
+is nevertheless empty. Consider
+ ((1,2),(2,1))
+Here l<h, but the second index ranges from 2..1 and
+hence is empty
%*********************************************************
%* *
inRange (m,n) i = m <= i && i <= n
+ unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
+
----------------------------------------------------------------------
instance Ix Int where
{-# INLINE range #-}
{-# INLINE inRange #-}
inRange (I# m,I# n) (I# i) = m <=# i && i <=# n
+ unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
+
----------------------------------------------------------------------
instance Ix Integer where
{-# INLINE range #-}
inRange (m,n) i = m <= i && i <= n
+ unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
----------------------------------------------------------------------
instance Ix Bool where -- as derived
inRange (l,u) i = fromEnum i >= fromEnum l && fromEnum i <= fromEnum u
+ unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
+
----------------------------------------------------------------------
instance Ix Ordering where -- as derived
{-# INLINE range #-}
inRange (l,u) i = fromEnum i >= fromEnum l && fromEnum i <= fromEnum u
+ unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
+
----------------------------------------------------------------------
instance Ix () where
{-# INLINE range #-}
{-# INLINE index #-}
index b i = unsafeIndex b i
+ unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
----------------------------------------------------------------------
instance (Ix a, Ix b) => Ix (a, b) where -- as derived
inRange ((l1,l2),(u1,u2)) (i1,i2) =
inRange (l1,u1) i1 && inRange (l2,u2) i2
+ unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
+
-- Default method for index
----------------------------------------------------------------------
inRange (l1,u1) i1 && inRange (l2,u2) i2 &&
inRange (l3,u3) i3
+ unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
+
-- Default method for index
----------------------------------------------------------------------
inRange (l1,u1) i1 && inRange (l2,u2) i2 &&
inRange (l3,u3) i3 && inRange (l4,u4) i4
+ unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
+
-- Default method for index
instance (Ix a1, Ix a2, Ix a3, Ix a4, Ix a5) => Ix (a1,a2,a3,a4,a5) where
inRange (l3,u3) i3 && inRange (l4,u4) i4 &&
inRange (l5,u5) i5
- -- Default method for index
-\end{code}
-
+ unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
-%********************************************************
-%* *
-\subsection{Size of @Ix@ interval}
-%* *
-%********************************************************
-
-The @rangeSize@ operator returns the number of elements
-in the range for an @Ix@ pair.
-
-\begin{code}
-{-# SPECIALISE unsafeRangeSize :: (Int,Int) -> Int #-}
-{-# SPECIALISE unsafeRangeSize :: ((Int,Int),(Int,Int)) -> Int #-}
-unsafeRangeSize :: (Ix a) => (a,a) -> Int
-unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
-
-{-# SPECIALISE rangeSize :: (Int,Int) -> Int #-}
-{-# SPECIALISE rangeSize :: ((Int,Int),(Int,Int)) -> Int #-}
-rangeSize :: (Ix a) => (a,a) -> Int
-rangeSize b@(_l,h) | inRange b h = unsafeIndex b h + 1
- | otherwise = 0
-
--- Note that the following is NOT right
--- rangeSize (l,h) | l <= h = index b h + 1
--- | otherwise = 0
---
--- Because it might be the case that l<h, but the range
--- is nevertheless empty. Consider
--- ((1,2),(2,1))
--- Here l<h, but the second index ranges from 2..1 and
--- hence is empty
+ -- Default method for index
\end{code}
unsafeArray (l,u) [(unsafeIndex (l,u) i, arr ! f i) | i <- range (l,u)]
{-# INLINE eqArray #-}
-eqArray :: (Ix i, Eq e) => Array i e -> Array i e -> Bool
+eqArray :: (Ix i, Eq i, Eq e) => Array i e -> Array i e -> Bool
eqArray arr1@(Array l1 u1 _) arr2@(Array l2 u2 _) =
if rangeSize (l1,u1) == 0 then rangeSize (l2,u2) == 0 else
l1 == l2 && u1 == u2 &&
and [unsafeAt arr1 i == unsafeAt arr2 i | i <- [0 .. rangeSize (l1,u1) - 1]]
{-# INLINE cmpArray #-}
-cmpArray :: (Ix i, Ord e) => Array i e -> Array i e -> Ordering
+cmpArray :: (Ix i, Ord i, Ord e) => Array i e -> Array i e -> Ordering
cmpArray arr1 arr2 = compare (assocs arr1) (assocs arr2)
{-# INLINE cmpIntArray #-}
instance Ix i => Functor (Array i) where
fmap = amap
-instance (Ix i, Eq e) => Eq (Array i e) where
+instance (Ix i, Eq i, Eq e) => Eq (Array i e) where
(==) = eqArray
-instance (Ix i, Ord e) => Ord (Array i e) where
+instance (Ix i, Ord i, Ord e) => Ord (Array i e) where
compare = cmpArray
instance (Ix a, Show a, Show b) => Show (Array a b) where
maxBound = 0x7F
instance Ix Int8 where
- range (m,n) = [m..n]
- index b@(m,_) i
- | inRange b i = fromIntegral (i - m)
- | otherwise = indexError b i "Int8"
- inRange (m,n) i = m <= i && i <= n
+ range (m,n) = [m..n]
+ unsafeIndex b@(m,_) i = fromIntegral (i - m)
+ inRange (m,n) i = m <= i && i <= n
+ unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
instance Read Int8 where
readsPrec p s = [(fromIntegral (x::Int), r) | (x, r) <- readsPrec p s]
maxBound = 0x7FFF
instance Ix Int16 where
- range (m,n) = [m..n]
- index b@(m,_) i
- | inRange b i = fromIntegral (i - m)
- | otherwise = indexError b i "Int16"
- inRange (m,n) i = m <= i && i <= n
+ range (m,n) = [m..n]
+ unsafeIndex b@(m,_) i = fromIntegral (i - m)
+ inRange (m,n) i = m <= i && i <= n
+ unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
instance Read Int16 where
readsPrec p s = [(fromIntegral (x::Int), r) | (x, r) <- readsPrec p s]
maxBound = 0x7FFFFFFF
instance Ix Int32 where
- range (m,n) = [m..n]
- index b@(m,_) i
- | inRange b i = fromIntegral (i - m)
- | otherwise = indexError b i "Int32"
- inRange (m,n) i = m <= i && i <= n
+ range (m,n) = [m..n]
+ unsafeIndex b@(m,_) i = fromIntegral (i - m)
+ inRange (m,n) i = m <= i && i <= n
+ unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
------------------------------------------------------------------------
-- type Int64
maxBound = 0x7FFFFFFFFFFFFFFF
instance Ix Int64 where
- range (m,n) = [m..n]
- index b@(m,_) i
- | inRange b i = fromIntegral (i - m)
- | otherwise = indexError b i "Int64"
- inRange (m,n) i = m <= i && i <= n
+ range (m,n) = [m..n]
+ unsafeIndex b@(m,_) i = fromIntegral (i - m)
+ inRange (m,n) i = m <= i && i <= n
+ unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
\end{code}
#endif
instance Ix Word where
- range (m,n) = [m..n]
- index b@(m,_) i
- | inRange b i = fromIntegral (i - m)
- | otherwise = indexError b i "Word"
- inRange (m,n) i = m <= i && i <= n
+ range (m,n) = [m..n]
+ unsafeIndex b@(m,_) i = fromIntegral (i - m)
+ inRange (m,n) i = m <= i && i <= n
+ unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
instance Read Word where
readsPrec p s = [(fromInteger x, r) | (x, r) <- readsPrec p s]
maxBound = 0xFF
instance Ix Word8 where
- range (m,n) = [m..n]
- index b@(m,_) i
- | inRange b i = fromIntegral (i - m)
- | otherwise = indexError b i "Word8"
- inRange (m,n) i = m <= i && i <= n
+ range (m,n) = [m..n]
+ unsafeIndex b@(m,_) i = fromIntegral (i - m)
+ inRange (m,n) i = m <= i && i <= n
+ unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
instance Read Word8 where
readsPrec p s = [(fromIntegral (x::Int), r) | (x, r) <- readsPrec p s]
maxBound = 0xFFFF
instance Ix Word16 where
- range (m,n) = [m..n]
- index b@(m,_) i
- | inRange b i = fromIntegral (i - m)
- | otherwise = indexError b i "Word16"
- inRange (m,n) i = m <= i && i <= n
+ range (m,n) = [m..n]
+ unsafeIndex b@(m,_) i = fromIntegral (i - m)
+ inRange (m,n) i = m <= i && i <= n
+ unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
instance Read Word16 where
readsPrec p s = [(fromIntegral (x::Int), r) | (x, r) <- readsPrec p s]
maxBound = 0xFFFFFFFF
instance Ix Word32 where
- range (m,n) = [m..n]
- index b@(m,_) i
- | inRange b i = fromIntegral (i - m)
- | otherwise = indexError b i "Word32"
- inRange (m,n) i = m <= i && i <= n
+ range (m,n) = [m..n]
+ unsafeIndex b@(m,_) i = fromIntegral (i - m)
+ inRange (m,n) i = m <= i && i <= n
+ unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
instance Read Word32 where
#if WORD_SIZE_IN_BITS < 33
maxBound = 0xFFFFFFFFFFFFFFFF
instance Ix Word64 where
- range (m,n) = [m..n]
- index b@(m,_) i
- | inRange b i = fromIntegral (i - m)
- | otherwise = indexError b i "Word64"
- inRange (m,n) i = m <= i && i <= n
+ range (m,n) = [m..n]
+ unsafeIndex b@(m,_) i = fromIntegral (i - m)
+ inRange (m,n) i = m <= i && i <= n
+ unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
instance Read Word64 where
readsPrec p s = [(fromInteger x, r) | (x, r) <- readsPrec p s]