diff --git a/Data/Vector.hs b/Data/Vector.hs index e218f65c..a7cb4910 100644 --- a/Data/Vector.hs +++ b/Data/Vector.hs @@ -47,8 +47,9 @@ module Data.Vector ( unsafeIndexM, unsafeHeadM, unsafeLastM, -- ** Extracting subvectors (slicing) - slice, init, tail, take, drop, splitAt, + slice, init, tail, take, takeEnd, drop, dropEnd, splitAt, unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop, + unsafeTakeEnd, unsafeDropEnd, -- * Construction @@ -570,12 +571,24 @@ take :: Int -> Vector a -> Vector a {-# INLINE take #-} take = G.take +-- | /O(1)/ Yield the last @n@ elements without copying. The vector may +-- contain less than @n@ elements in which case it is returned unchanged. +takeEnd :: Int -> Vector a -> Vector a +{-# INLINE takeEnd #-} +takeEnd = G.takeEnd + -- | /O(1)/ Yield all but the first @n@ elements without copying. The vector may -- contain less than @n@ elements in which case an empty vector is returned. drop :: Int -> Vector a -> Vector a {-# INLINE drop #-} drop = G.drop +-- | /O(1)/ Yield all but the last @n@ elements without copying. The vector may +-- contain less than @n@ elements in which case an empty vector is returned. +dropEnd :: Int -> Vector a -> Vector a +{-# INLINE dropEnd #-} +dropEnd = G.dropEnd + -- | /O(1)/ Yield the first @n@ elements paired with the remainder without copying. -- -- Note that @'splitAt' n v@ is equivalent to @('take' n v, 'drop' n v)@ @@ -611,12 +624,24 @@ unsafeTake :: Int -> Vector a -> Vector a {-# INLINE unsafeTake #-} unsafeTake = G.unsafeTake +-- | /O(1)/ Yield the last @n@ elements without copying. The vector must +-- contain at least @n@ elements but this is not checked. +unsafeTakeEnd :: Int -> Vector a -> Vector a +{-# INLINE unsafeTakeEnd #-} +unsafeTakeEnd = G.unsafeTakeEnd + -- | /O(1)/ Yield all but the first @n@ elements without copying. The vector -- must contain at least @n@ elements but this is not checked. unsafeDrop :: Int -> Vector a -> Vector a {-# INLINE unsafeDrop #-} unsafeDrop = G.unsafeDrop +-- | /O(1)/ Yield all but the last @n@ elements without copying. The vector +-- must contain at least @n@ elements but this is not checked. +unsafeDropEnd :: Int -> Vector a -> Vector a +{-# INLINE unsafeDropEnd #-} +unsafeDropEnd = G.unsafeDropEnd + -- Initialisation -- -------------- diff --git a/Data/Vector/Generic.hs b/Data/Vector/Generic.hs index 43445f2b..0516fe6c 100644 --- a/Data/Vector/Generic.hs +++ b/Data/Vector/Generic.hs @@ -30,8 +30,9 @@ module Data.Vector.Generic ( unsafeIndexM, unsafeHeadM, unsafeLastM, -- ** Extracting subvectors (slicing) - slice, init, tail, take, drop, splitAt, + slice, init, tail, take, takeEnd, drop, dropEnd, splitAt, unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop, + unsafeTakeEnd, unsafeDropEnd, -- * Construction @@ -415,6 +416,16 @@ take :: Vector v a => Int -> v a -> v a take n v = unsafeSlice 0 (delay_inline min n' (length v)) v where n' = max n 0 +-- | /O(1)/ Yield the last @n@ elements without copying. The vector may +-- contain less than @n@ elements in which case it is returned unchanged. +takeEnd :: Vector v a => Int -> v a -> v a +{-# INLINE_FUSED takeEnd #-} +takeEnd n v = unsafeSlice i (delay_inline min n' m) v + where + n' = max n 0 + m = length v + i = delay_inline max 0 (m - n') + -- | /O(1)/ Yield all but the first @n@ elements without copying. The vector may -- contain less than @n@ elements in which case an empty vector is returned. drop :: Vector v a => Int -> v a -> v a @@ -424,6 +435,15 @@ drop n v = unsafeSlice (delay_inline min n' len) where n' = max n 0 len = length v +-- | /O(1)/ Yield all but the last @n@ elements without copying. The vector may +-- contain less than @n@ elements in which case an empty vector is returned. +dropEnd :: Vector v a => Int -> v a -> v a +{-# INLINE_FUSED dropEnd #-} +dropEnd n v = unsafeSlice 0 (delay_inline max 0 (m - n')) v + where + n' = max n 0 + m = length v + -- | /O(1)/ Yield the first @n@ elements paired with the remainder without copying. -- -- Note that @'splitAt' n v@ is equivalent to @('take' n v, 'drop' n v)@ @@ -466,12 +486,25 @@ unsafeTake :: Vector v a => Int -> v a -> v a {-# INLINE unsafeTake #-} unsafeTake n v = unsafeSlice 0 n v +-- | /O(1)/ Yield the last @n@ elements without copying. The vector must +-- contain at least @n@ elements but this is not checked. +unsafeTakeEnd :: Vector v a => Int -> v a -> v a +{-# INLINE unsafeTakeEnd #-} +unsafeTakeEnd n v = unsafeSlice (m - n) n v + where m = length v + -- | /O(1)/ Yield all but the first @n@ elements without copying. The vector -- must contain at least @n@ elements but this is not checked. unsafeDrop :: Vector v a => Int -> v a -> v a {-# INLINE unsafeDrop #-} unsafeDrop n v = unsafeSlice n (length v - n) v +-- | /O(1)/ Yield all but the last @n@ elements without copying. The vector +-- must contain at least @n@ elements but this is not checked. +unsafeDropEnd :: Vector v a => Int -> v a -> v a +{-# INLINE unsafeDropEnd #-} +unsafeDropEnd n v = unsafeSlice 0 (length v - n) v + {-# RULES "slice/new [Vector]" forall i n p. diff --git a/Data/Vector/Generic/Mutable.hs b/Data/Vector/Generic/Mutable.hs index a421ecda..3fdc979e 100644 --- a/Data/Vector/Generic/Mutable.hs +++ b/Data/Vector/Generic/Mutable.hs @@ -21,8 +21,9 @@ module Data.Vector.Generic.Mutable ( length, null, -- ** Extracting subvectors - slice, init, tail, take, drop, splitAt, + slice, init, tail, take, takeEnd, drop, dropEnd, splitAt, unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop, + unsafeTakeEnd, unsafeDropEnd, -- ** Overlapping overlaps, @@ -518,6 +519,14 @@ take :: MVector v a => Int -> v s a -> v s a {-# INLINE take #-} take n v = unsafeSlice 0 (min (max n 0) (length v)) v +takeEnd :: MVector v a => Int -> v s a -> v s a +{-# INLINE takeEnd #-} +takeEnd n v = unsafeSlice i (min n' m) v + where + n' = max n 0 + m = length v + i = max 0 (m - n') + drop :: MVector v a => Int -> v s a -> v s a {-# INLINE drop #-} drop n v = unsafeSlice (min m n') (max 0 (m - n')) v @@ -525,6 +534,13 @@ drop n v = unsafeSlice (min m n') (max 0 (m - n')) v n' = max n 0 m = length v +dropEnd :: MVector v a => Int -> v s a -> v s a +{-# INLINE dropEnd #-} +dropEnd n v = unsafeSlice 0 (max 0 (m - n')) v + where + n' = max n 0 + m = length v + {-# INLINE splitAt #-} splitAt :: MVector v a => Int -> v s a -> (v s a, v s a) splitAt n v = ( unsafeSlice 0 m v @@ -565,10 +581,19 @@ unsafeTake :: MVector v a => Int -> v s a -> v s a {-# INLINE unsafeTake #-} unsafeTake n v = unsafeSlice 0 n v +unsafeTakeEnd :: MVector v a => Int -> v s a -> v s a +{-# INLINE unsafeTakeEnd #-} +unsafeTakeEnd n v = unsafeSlice (m - n) n v + where m = length v + unsafeDrop :: MVector v a => Int -> v s a -> v s a {-# INLINE unsafeDrop #-} unsafeDrop n v = unsafeSlice n (length v - n) v +unsafeDropEnd :: MVector v a => Int -> v s a -> v s a +{-# INLINE unsafeDropEnd #-} +unsafeDropEnd n v = unsafeSlice 0 (length v - n) v + -- Overlapping -- ----------- diff --git a/Data/Vector/Generic/New.hs b/Data/Vector/Generic/New.hs index e94ce19e..35f54d20 100644 --- a/Data/Vector/Generic/New.hs +++ b/Data/Vector/Generic/New.hs @@ -15,7 +15,7 @@ module Data.Vector.Generic.New ( New(..), create, run, runPrim, apply, modify, modifyWithBundle, unstream, transform, unstreamR, transformR, - slice, init, tail, take, drop, + slice, init, tail, take, takeEnd, drop, dropEnd, unsafeSlice, unsafeInit, unsafeTail ) where @@ -132,10 +132,18 @@ take :: Vector v a => Int -> New v a -> New v a {-# INLINE_FUSED take #-} take n m = apply (MVector.take n) m +takeEnd :: Vector v a => Int -> New v a -> New v a +{-# INLINE_FUSED takeEnd #-} +takeEnd n m = apply (MVector.takeEnd n) m + drop :: Vector v a => Int -> New v a -> New v a {-# INLINE_FUSED drop #-} drop n m = apply (MVector.drop n) m +dropEnd :: Vector v a => Int -> New v a -> New v a +{-# INLINE_FUSED dropEnd #-} +dropEnd n m = apply (MVector.dropEnd n) m + unsafeSlice :: Vector v a => Int -> Int -> New v a -> New v a {-# INLINE_FUSED unsafeSlice #-} unsafeSlice i n m = apply (MVector.unsafeSlice i n) m diff --git a/Data/Vector/Mutable.hs b/Data/Vector/Mutable.hs index ba701afb..5a9a0084 100644 --- a/Data/Vector/Mutable.hs +++ b/Data/Vector/Mutable.hs @@ -22,8 +22,9 @@ module Data.Vector.Mutable ( length, null, -- ** Extracting subvectors - slice, init, tail, take, drop, splitAt, + slice, init, tail, take, takeEnd, drop, dropEnd, splitAt, unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop, + unsafeTakeEnd, unsafeDropEnd, -- ** Overlapping overlaps, @@ -212,10 +213,18 @@ take :: Int -> MVector s a -> MVector s a {-# INLINE take #-} take = G.take +takeEnd :: Int -> MVector s a -> MVector s a +{-# INLINE takeEnd #-} +takeEnd = G.takeEnd + drop :: Int -> MVector s a -> MVector s a {-# INLINE drop #-} drop = G.drop +dropEnd :: Int -> MVector s a -> MVector s a +{-# INLINE dropEnd #-} +dropEnd = G.dropEnd + {-# INLINE splitAt #-} splitAt :: Int -> MVector s a -> (MVector s a, MVector s a) splitAt = G.splitAt @@ -241,10 +250,18 @@ unsafeTake :: Int -> MVector s a -> MVector s a {-# INLINE unsafeTake #-} unsafeTake = G.unsafeTake +unsafeTakeEnd :: Int -> MVector s a -> MVector s a +{-# INLINE unsafeTakeEnd #-} +unsafeTakeEnd = G.unsafeTakeEnd + unsafeDrop :: Int -> MVector s a -> MVector s a {-# INLINE unsafeDrop #-} unsafeDrop = G.unsafeDrop +unsafeDropEnd :: Int -> MVector s a -> MVector s a +{-# INLINE unsafeDropEnd #-} +unsafeDropEnd = G.unsafeDropEnd + unsafeInit :: MVector s a -> MVector s a {-# INLINE unsafeInit #-} unsafeInit = G.unsafeInit diff --git a/Data/Vector/Primitive.hs b/Data/Vector/Primitive.hs index 742e4252..dbe797a1 100644 --- a/Data/Vector/Primitive.hs +++ b/Data/Vector/Primitive.hs @@ -33,8 +33,9 @@ module Data.Vector.Primitive ( unsafeIndexM, unsafeHeadM, unsafeLastM, -- ** Extracting subvectors (slicing) - slice, init, tail, take, drop, splitAt, + slice, init, tail, take, takeEnd, drop, dropEnd, splitAt, unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop, + unsafeTakeEnd, unsafeDropEnd, -- * Construction @@ -413,18 +414,30 @@ tail :: Prim a => Vector a -> Vector a {-# INLINE tail #-} tail = G.tail --- | /O(1)/ Yield at the first @n@ elements without copying. The vector may +-- | /O(1)/ Yield the first @n@ elements without copying. The vector may -- contain less than @n@ elements in which case it is returned unchanged. take :: Prim a => Int -> Vector a -> Vector a {-# INLINE take #-} take = G.take +-- | /O(1)/ Yield the last @n@ elements without copying. The vector may +-- contain less than @n@ elements in which case it is returned unchanged. +takeEnd :: Prim a => Int -> Vector a -> Vector a +{-# INLINE takeEnd #-} +takeEnd = G.takeEnd + -- | /O(1)/ Yield all but the first @n@ elements without copying. The vector may -- contain less than @n@ elements in which case an empty vector is returned. drop :: Prim a => Int -> Vector a -> Vector a {-# INLINE drop #-} drop = G.drop +-- | /O(1)/ Yield all but the last @n@ elements without copying. The vector may +-- contain less than @n@ elements in which case an empty vector is returned. +dropEnd :: Prim a => Int -> Vector a -> Vector a +{-# INLINE dropEnd #-} +dropEnd = G.dropEnd + -- | /O(1)/ Yield the first @n@ elements paired with the remainder without copying. -- -- Note that @'splitAt' n v@ is equivalent to @('take' n v, 'drop' n v)@ @@ -460,12 +473,24 @@ unsafeTake :: Prim a => Int -> Vector a -> Vector a {-# INLINE unsafeTake #-} unsafeTake = G.unsafeTake +-- | /O(1)/ Yield the last @n@ elements without copying. The vector must +-- contain at least @n@ elements but this is not checked. +unsafeTakeEnd :: Prim a => Int -> Vector a -> Vector a +{-# INLINE unsafeTakeEnd #-} +unsafeTakeEnd = G.unsafeTakeEnd + -- | /O(1)/ Yield all but the first @n@ elements without copying. The vector -- must contain at least @n@ elements but this is not checked. unsafeDrop :: Prim a => Int -> Vector a -> Vector a {-# INLINE unsafeDrop #-} unsafeDrop = G.unsafeDrop +-- | /O(1)/ Yield all but the last @n@ elements without copying. The vector +-- must contain at least @n@ elements but this is not checked. +unsafeDropEnd :: Prim a => Int -> Vector a -> Vector a +{-# INLINE unsafeDropEnd #-} +unsafeDropEnd = G.unsafeDropEnd + -- Initialisation -- -------------- diff --git a/Data/Vector/Primitive/Mutable.hs b/Data/Vector/Primitive/Mutable.hs index 33aca812..1a4286e1 100644 --- a/Data/Vector/Primitive/Mutable.hs +++ b/Data/Vector/Primitive/Mutable.hs @@ -22,8 +22,9 @@ module Data.Vector.Primitive.Mutable ( length, null, -- ** Extracting subvectors - slice, init, tail, take, drop, splitAt, + slice, init, tail, take, takeEnd, drop, dropEnd, splitAt, unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop, + unsafeTakeEnd, unsafeDropEnd, -- ** Overlapping overlaps, @@ -154,10 +155,18 @@ take :: Prim a => Int -> MVector s a -> MVector s a {-# INLINE take #-} take = G.take +takeEnd :: Prim a => Int -> MVector s a -> MVector s a +{-# INLINE takeEnd #-} +takeEnd = G.takeEnd + drop :: Prim a => Int -> MVector s a -> MVector s a {-# INLINE drop #-} drop = G.drop +dropEnd :: Prim a => Int -> MVector s a -> MVector s a +{-# INLINE dropEnd #-} +dropEnd = G.dropEnd + splitAt :: Prim a => Int -> MVector s a -> (MVector s a, MVector s a) {-# INLINE splitAt #-} splitAt = G.splitAt @@ -184,10 +193,18 @@ unsafeTake :: Prim a => Int -> MVector s a -> MVector s a {-# INLINE unsafeTake #-} unsafeTake = G.unsafeTake +unsafeTakeEnd :: Prim a => Int -> MVector s a -> MVector s a +{-# INLINE unsafeTakeEnd #-} +unsafeTakeEnd = G.unsafeTakeEnd + unsafeDrop :: Prim a => Int -> MVector s a -> MVector s a {-# INLINE unsafeDrop #-} unsafeDrop = G.unsafeDrop +unsafeDropEnd :: Prim a => Int -> MVector s a -> MVector s a +{-# INLINE unsafeDropEnd #-} +unsafeDropEnd = G.unsafeDropEnd + unsafeInit :: Prim a => MVector s a -> MVector s a {-# INLINE unsafeInit #-} unsafeInit = G.unsafeInit diff --git a/Data/Vector/Storable.hs b/Data/Vector/Storable.hs index 6089650d..b008cfbf 100644 --- a/Data/Vector/Storable.hs +++ b/Data/Vector/Storable.hs @@ -30,8 +30,9 @@ module Data.Vector.Storable ( unsafeIndexM, unsafeHeadM, unsafeLastM, -- ** Extracting subvectors (slicing) - slice, init, tail, take, drop, splitAt, + slice, init, tail, take, takeEnd, drop, dropEnd, splitAt, unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop, + unsafeTakeEnd, unsafeDropEnd, -- * Construction @@ -429,12 +430,24 @@ take :: Storable a => Int -> Vector a -> Vector a {-# INLINE take #-} take = G.take +-- | /O(1)/ Yield the last @n@ elements without copying. The vector may +-- contain less than @n@ elements in which case it is returned unchanged. +takeEnd :: Storable a => Int -> Vector a -> Vector a +{-# INLINE takeEnd #-} +takeEnd = G.takeEnd + -- | /O(1)/ Yield all but the first @n@ elements without copying. The vector may -- contain less than @n@ elements in which case an empty vector is returned. drop :: Storable a => Int -> Vector a -> Vector a {-# INLINE drop #-} drop = G.drop +-- | /O(1)/ Yield all but the last @n@ elements without copying. The vector may +-- contain less than @n@ elements in which case an empty vector is returned. +dropEnd :: Storable a => Int -> Vector a -> Vector a +{-# INLINE dropEnd #-} +dropEnd = G.dropEnd + -- | /O(1)/ Yield the first @n@ elements paired with the remainder without copying. -- -- Note that @'splitAt' n v@ is equivalent to @('take' n v, 'drop' n v)@ @@ -470,12 +483,24 @@ unsafeTake :: Storable a => Int -> Vector a -> Vector a {-# INLINE unsafeTake #-} unsafeTake = G.unsafeTake +-- | /O(1)/ Yield the last @n@ elements without copying. The vector must +-- contain at least @n@ elements but this is not checked. +unsafeTakeEnd :: Storable a => Int -> Vector a -> Vector a +{-# INLINE unsafeTakeEnd #-} +unsafeTakeEnd = G.unsafeTakeEnd + -- | /O(1)/ Yield all but the first @n@ elements without copying. The vector -- must contain at least @n@ elements but this is not checked. unsafeDrop :: Storable a => Int -> Vector a -> Vector a {-# INLINE unsafeDrop #-} unsafeDrop = G.unsafeDrop +-- | /O(1)/ Yield all but the last @n@ elements without copying. The vector +-- must contain at least @n@ elements but this is not checked. +unsafeDropEnd :: Storable a => Int -> Vector a -> Vector a +{-# INLINE unsafeDropEnd #-} +unsafeDropEnd = G.unsafeDropEnd + -- Initialisation -- -------------- diff --git a/Data/Vector/Storable/Mutable.hs b/Data/Vector/Storable/Mutable.hs index a1cd3f49..0b32541e 100644 --- a/Data/Vector/Storable/Mutable.hs +++ b/Data/Vector/Storable/Mutable.hs @@ -22,8 +22,9 @@ module Data.Vector.Storable.Mutable( length, null, -- ** Extracting subvectors - slice, init, tail, take, drop, splitAt, + slice, init, tail, take, takeEnd, drop, dropEnd, splitAt, unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop, + unsafeTakeEnd, unsafeDropEnd, -- ** Overlapping overlaps, @@ -255,10 +256,18 @@ take :: Storable a => Int -> MVector s a -> MVector s a {-# INLINE take #-} take = G.take +takeEnd :: Storable a => Int -> MVector s a -> MVector s a +{-# INLINE takeEnd #-} +takeEnd = G.takeEnd + drop :: Storable a => Int -> MVector s a -> MVector s a {-# INLINE drop #-} drop = G.drop +dropEnd :: Storable a => Int -> MVector s a -> MVector s a +{-# INLINE dropEnd #-} +dropEnd = G.dropEnd + splitAt :: Storable a => Int -> MVector s a -> (MVector s a, MVector s a) {-# INLINE splitAt #-} splitAt = G.splitAt @@ -285,10 +294,18 @@ unsafeTake :: Storable a => Int -> MVector s a -> MVector s a {-# INLINE unsafeTake #-} unsafeTake = G.unsafeTake +unsafeTakeEnd :: Storable a => Int -> MVector s a -> MVector s a +{-# INLINE unsafeTakeEnd #-} +unsafeTakeEnd = G.unsafeTakeEnd + unsafeDrop :: Storable a => Int -> MVector s a -> MVector s a {-# INLINE unsafeDrop #-} unsafeDrop = G.unsafeDrop +unsafeDropEnd :: Storable a => Int -> MVector s a -> MVector s a +{-# INLINE unsafeDropEnd #-} +unsafeDropEnd = G.unsafeDropEnd + unsafeInit :: Storable a => MVector s a -> MVector s a {-# INLINE unsafeInit #-} unsafeInit = G.unsafeInit diff --git a/Data/Vector/Unboxed.hs b/Data/Vector/Unboxed.hs index 44eba941..bbf79835 100644 --- a/Data/Vector/Unboxed.hs +++ b/Data/Vector/Unboxed.hs @@ -53,8 +53,9 @@ module Data.Vector.Unboxed ( unsafeIndexM, unsafeHeadM, unsafeLastM, -- ** Extracting subvectors (slicing) - slice, init, tail, take, drop, splitAt, + slice, init, tail, take, takeEnd, drop, dropEnd, splitAt, unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop, + unsafeTakeEnd, unsafeDropEnd, -- * Construction @@ -398,12 +399,24 @@ take :: Unbox a => Int -> Vector a -> Vector a {-# INLINE take #-} take = G.take +-- | /O(1)/ Yield the last @n@ elements without copying. The vector may +-- contain less than @n@ elements in which case it is returned unchanged. +takeEnd :: Unbox a => Int -> Vector a -> Vector a +{-# INLINE takeEnd #-} +takeEnd = G.takeEnd + -- | /O(1)/ Yield all but the first @n@ elements without copying. The vector may -- contain less than @n@ elements in which case an empty vector is returned. drop :: Unbox a => Int -> Vector a -> Vector a {-# INLINE drop #-} drop = G.drop +-- | /O(1)/ Yield all but the last @n@ elements without copying. The vector may +-- contain less than @n@ elements in which case an empty vector is returned. +dropEnd :: Unbox a => Int -> Vector a -> Vector a +{-# INLINE dropEnd #-} +dropEnd = G.dropEnd + -- | /O(1)/ Yield the first @n@ elements paired with the remainder without copying. -- -- Note that @'splitAt' n v@ is equivalent to @('take' n v, 'drop' n v)@ @@ -439,12 +452,24 @@ unsafeTake :: Unbox a => Int -> Vector a -> Vector a {-# INLINE unsafeTake #-} unsafeTake = G.unsafeTake +-- | /O(1)/ Yield the last @n@ elements without copying. The vector must +-- contain at least @n@ elements but this is not checked. +unsafeTakeEnd :: Unbox a => Int -> Vector a -> Vector a +{-# INLINE unsafeTakeEnd #-} +unsafeTakeEnd = G.unsafeTakeEnd + -- | /O(1)/ Yield all but the first @n@ elements without copying. The vector -- must contain at least @n@ elements but this is not checked. unsafeDrop :: Unbox a => Int -> Vector a -> Vector a {-# INLINE unsafeDrop #-} unsafeDrop = G.unsafeDrop +-- | /O(1)/ Yield all but the last @n@ elements without copying. The vector +-- must contain at least @n@ elements but this is not checked. +unsafeDropEnd :: Unbox a => Int -> Vector a -> Vector a +{-# INLINE unsafeDropEnd #-} +unsafeDropEnd = G.unsafeDropEnd + -- Initialisation -- -------------- diff --git a/Data/Vector/Unboxed/Mutable.hs b/Data/Vector/Unboxed/Mutable.hs index 4e649af7..ea039245 100644 --- a/Data/Vector/Unboxed/Mutable.hs +++ b/Data/Vector/Unboxed/Mutable.hs @@ -22,8 +22,9 @@ module Data.Vector.Unboxed.Mutable ( length, null, -- ** Extracting subvectors - slice, init, tail, take, drop, splitAt, + slice, init, tail, take, takeEnd, drop, dropEnd, splitAt, unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop, + unsafeTakeEnd, unsafeDropEnd, -- ** Overlapping overlaps, @@ -92,10 +93,18 @@ take :: Unbox a => Int -> MVector s a -> MVector s a {-# INLINE take #-} take = G.take +takeEnd :: Unbox a => Int -> MVector s a -> MVector s a +{-# INLINE takeEnd #-} +takeEnd = G.takeEnd + drop :: Unbox a => Int -> MVector s a -> MVector s a {-# INLINE drop #-} drop = G.drop +dropEnd :: Unbox a => Int -> MVector s a -> MVector s a +{-# INLINE dropEnd #-} +dropEnd = G.dropEnd + splitAt :: Unbox a => Int -> MVector s a -> (MVector s a, MVector s a) {-# INLINE splitAt #-} splitAt = G.splitAt @@ -122,10 +131,18 @@ unsafeTake :: Unbox a => Int -> MVector s a -> MVector s a {-# INLINE unsafeTake #-} unsafeTake = G.unsafeTake +unsafeTakeEnd :: Unbox a => Int -> MVector s a -> MVector s a +{-# INLINE unsafeTakeEnd #-} +unsafeTakeEnd = G.unsafeTakeEnd + unsafeDrop :: Unbox a => Int -> MVector s a -> MVector s a {-# INLINE unsafeDrop #-} unsafeDrop = G.unsafeDrop +unsafeDropEnd :: Unbox a => Int -> MVector s a -> MVector s a +{-# INLINE unsafeDropEnd #-} +unsafeDropEnd = G.unsafeDropEnd + unsafeInit :: Unbox a => MVector s a -> MVector s a {-# INLINE unsafeInit #-} unsafeInit = G.unsafeInit diff --git a/old-testsuite/Testsuite/Vector/AsList.hs b/old-testsuite/Testsuite/Vector/AsList.hs index 520dc48a..d2117348 100644 --- a/old-testsuite/Testsuite/Vector/AsList.hs +++ b/old-testsuite/Testsuite/Vector/AsList.hs @@ -12,6 +12,8 @@ import Testsuite.Utils.Generator import Test.QuickCheck import Text.Show.Functions () +import qualified Utilities as Util + instance Modelled (Vector a) where type Model (Vector a) = [a] @@ -43,10 +45,12 @@ prop_slice = forAll arbitrary $ \xs -> forAll (choose (0,length xs)) $ \i -> forAll (choose (0,length xs - i)) $ \n -> V.slice (V.fromList (xs :: [A])) i n ==? take n (drop i xs) -prop_init = arg (not . null) $ arg_ty [A] $ V.init ==? init -prop_tail = arg (not . null) $ arg_ty [A] $ V.tail ==? tail -prop_take = arg2_ty [A] $ V.take ==? take -prop_drop = arg2_ty [A] $ V.drop ==? drop +prop_init = arg (not . null) $ arg_ty [A] $ V.init ==? init +prop_tail = arg (not . null) $ arg_ty [A] $ V.tail ==? tail +prop_take = arg2_ty [A] $ V.take ==? take +prop_takeEnd = arg2_ty [A] $ V.takeEnd ==? Util.naiveTakeEnd +prop_drop = arg2_ty [A] $ V.drop ==? drop +prop_dropEnd = arg2_ty [A] $ V.drop ==? Util.naiveDropEnd prop_accum = forAll arbitrary $ \f -> forAll arbitrary $ \xs -> diff --git a/tests/Tests/Vector.hs b/tests/Tests/Vector.hs index e4fac216..63b154df 100644 --- a/tests/Tests/Vector.hs +++ b/tests/Tests/Vector.hs @@ -261,10 +261,12 @@ testPolymorphicFunctions _ = $(testProperties [ where prop :: P (Int -> Int -> v a -> v a) = V.slice `eq` slice - prop_tail :: P (v a -> v a) = not . V.null ===> V.tail `eq` tail - prop_init :: P (v a -> v a) = not . V.null ===> V.init `eq` init - prop_take :: P (Int -> v a -> v a) = V.take `eq` take - prop_drop :: P (Int -> v a -> v a) = V.drop `eq` drop + prop_tail :: P (v a -> v a) = not . V.null ===> V.tail `eq` tail + prop_init :: P (v a -> v a) = not . V.null ===> V.init `eq` init + prop_take :: P (Int -> v a -> v a) = V.take `eq` take + prop_takeEnd :: P (Int -> v a -> v a) = V.take `eq` Util.naiveTakeEnd + prop_drop :: P (Int -> v a -> v a) = V.drop `eq` drop + prop_dropEnd :: P (Int -> v a -> v a) = V.drop `eq` Util.naiveDropEnd prop_splitAt :: P (Int -> v a -> (v a, v a)) = V.splitAt `eq` splitAt prop_accum = \f xs -> diff --git a/tests/Utilities.hs b/tests/Utilities.hs index 9a563eb9..53bd0478 100644 --- a/tests/Utilities.hs +++ b/tests/Utilities.hs @@ -360,3 +360,9 @@ limitUnfolds f (theirs, ours) | ours >= 0 , Just (out, theirs') <- f theirs = Just (out, (theirs', ours - 1)) | otherwise = Nothing + +naiveTakeEnd :: Int -> [a] -> [a] +naiveTakeEnd n = reverse . take n . reverse + +naiveDropEnd :: Int -> [a] -> [a] +naiveDropEnd n = reverse . drop n . reverse