Add unsafeCast for Storable vectors (based on a patch by Bas van Dijk)
authorRoman Leshchinskiy <rl@cse.unsw.edu.au>
Fri, 17 Jun 2011 23:11:45 +0000 (23:11 +0000)
committerRoman Leshchinskiy <rl@cse.unsw.edu.au>
Fri, 17 Jun 2011 23:11:45 +0000 (23:11 +0000)
Data/Vector/Storable.hs
Data/Vector/Storable/Mutable.hs

index 0b8d0cb..1991886 100644 (file)
@@ -1,4 +1,4 @@
-{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, TypeFamilies, Rank2Types #-}
+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, TypeFamilies, Rank2Types, ScopedTypeVariables #-}
 
 -- |
 -- Module      : Data.Vector.Storable
@@ -124,7 +124,7 @@ module Data.Vector.Storable (
   toList, fromList, fromListN,
 
   -- ** Other vector types
-  G.convert,
+  G.convert, unsafeCast,
 
   -- ** Mutable vectors
   freeze, thaw, copy, unsafeFreeze, unsafeThaw, unsafeCopy,
@@ -1277,6 +1277,24 @@ fromListN :: Storable a => Int -> [a] -> Vector a
 {-# INLINE fromListN #-}
 fromListN = G.fromListN
 
+-- Conversions - Unsafe casts
+-- --------------------------
+
+-- | /O(1)/ Unsafely cast a vector from one element type to another.
+-- The operation just changes the type of the underlying pointer and does not
+-- modify the elements.
+--
+-- The resulting vector contains as many elements as can fit into the
+-- underlying memory block.
+--
+unsafeCast :: forall a b. (Storable a, Storable b) => Vector a -> Vector b
+{-# INLINE unsafeCast #-}
+unsafeCast (Vector p n fp)
+  = Vector (castPtr p)
+           ((n * sizeOf (undefined :: a)) `div` sizeOf (undefined :: b))
+           (castForeignPtr fp)
+
+
 -- Conversions - Mutable vectors
 -- -----------------------------
 
index 991f003..6d0dc0a 100644 (file)
@@ -1,4 +1,4 @@
-{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, ScopedTypeVariables #-}
 
 -- |
 -- Module      : Data.Vector.Storable.Mutable
@@ -48,6 +48,9 @@ module Data.Vector.Storable.Mutable(
   -- ** Filling and copying
   set, copy, move, unsafeCopy, unsafeMove,
 
+  -- * Unsafe conversions
+  unsafeCast,
+
   -- * Raw pointers
   unsafeFromForeignPtr, unsafeToForeignPtr, unsafeWith,
 
@@ -364,6 +367,24 @@ unsafeMove :: (PrimMonad m, Storable a)
 {-# INLINE unsafeMove #-}
 unsafeMove = G.unsafeMove
 
+-- Unsafe conversions
+-- ------------------
+
+-- | /O(1)/ Unsafely cast a mutable vector from one element type to another.
+-- The operation just changes the type of the underlying pointer and does not
+-- modify the elements.
+--
+-- The resulting vector contains as many elements as can fit into the
+-- underlying memory block.
+--
+unsafeCast :: forall a b s.
+              (Storable a, Storable b) => MVector s a -> MVector s b
+{-# INLINE unsafeCast #-}
+unsafeCast (MVector p n fp)
+  = MVector (castPtr p)
+            ((n * sizeOf (undefined :: a)) `div` sizeOf (undefined :: b))
+            (castForeignPtr fp)
+
 -- Raw pointers
 -- ------------