Skip to content

Commit afb189a

Browse files
authored
Merge pull request #434 from haskell/access-to-vector-internal
Add `unsafeToArray` function for getting the underlying boxed `Array`
2 parents 2ec9d87 + 9ed2f75 commit afb189a

File tree

4 files changed

+70
-23
lines changed

4 files changed

+70
-23
lines changed

.github/workflows/ci.yml

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,28 @@ jobs:
1818
matrix:
1919
include:
2020
# Linux
21-
- { cabal: "3.4", os: ubuntu-latest, ghc: "8.0.2" }
22-
- { cabal: "3.4", os: ubuntu-latest, ghc: "8.2.2" }
23-
- { cabal: "3.4", os: ubuntu-latest, ghc: "8.4.4" }
24-
- { cabal: "3.4", os: ubuntu-latest, ghc: "8.6.5" }
25-
- { cabal: "3.4", os: ubuntu-latest, ghc: "8.8.4" }
26-
- { cabal: "3.4", os: ubuntu-latest, ghc: "8.10.7" }
27-
- { cabal: "3.4", os: ubuntu-latest, ghc: "9.0.1" }
28-
- { cabal: "3.4", os: ubuntu-latest, ghc: "9.2.1" }
21+
- { cabal: "3.6", os: ubuntu-latest, ghc: "8.0.2" }
22+
- { cabal: "3.6", os: ubuntu-latest, ghc: "8.2.2" }
23+
- { cabal: "3.6", os: ubuntu-latest, ghc: "8.4.4" }
24+
- { cabal: "3.6", os: ubuntu-latest, ghc: "8.6.5" }
25+
- { cabal: "3.6", os: ubuntu-latest, ghc: "8.8.4" }
26+
- { cabal: "3.6", os: ubuntu-latest, ghc: "8.10.7" }
27+
- { cabal: "3.6", os: ubuntu-latest, ghc: "9.0.1" }
28+
- { cabal: "3.6", os: ubuntu-latest, ghc: "9.2.1" }
2929
# Win
30-
- { cabal: "3.2", os: windows-latest, ghc: "8.4.4" }
31-
- { cabal: "3.2", os: windows-latest, ghc: "8.6.5" }
30+
- { cabal: "3.6", os: windows-latest, ghc: "8.4.4" }
3231
# OOM when building tests
33-
# - { cabal: "3.4", os: windows-latest, ghc: "8.8.4" }
34-
# - { cabal: "3.4", os: windows-latest, ghc: "8.10.4" }
32+
# - { cabal: "3.6", os: windows-latest, ghc: "8.6.5" }
33+
# - { cabal: "3.6", os: windows-latest, ghc: "8.8.4" }
34+
# - { cabal: "3.6", os: windows-latest, ghc: "8.10.4" }
3535
# Too flaky:
36-
# - { cabal: "3.4", os: windows-latest, ghc: "9.0.1" }
36+
# - { cabal: "3.6", os: windows-latest, ghc: "9.0.1" }
3737
# MacOS
38-
- { cabal: "3.2", os: macOS-latest, ghc: "8.4.4" }
39-
- { cabal: "3.2", os: macOS-latest, ghc: "8.6.5" }
40-
- { cabal: "3.2", os: macOS-latest, ghc: "8.8.4" }
41-
- { cabal: "3.2", os: macOS-latest, ghc: "8.10.7" }
42-
- { cabal: "3.4", os: macOS-latest, ghc: "9.0.1" }
38+
- { cabal: "3.6", os: macOS-latest, ghc: "8.4.4" }
39+
- { cabal: "3.6", os: macOS-latest, ghc: "8.6.5" }
40+
- { cabal: "3.6", os: macOS-latest, ghc: "8.8.4" }
41+
- { cabal: "3.6", os: macOS-latest, ghc: "8.10.7" }
42+
- { cabal: "3.6", os: macOS-latest, ghc: "9.0.1" }
4343
fail-fast: false
4444

4545
steps:

vector/changelog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747
* Add `groupBy` and `group` for `Data.Vector.Generic` and the specialized
4848
version in `Data.Vector`, `Data.Vector.Unboxed`, `Data.Vector.Storable` and
4949
`Data.Vector.Primitive`.
50+
* Add `toArraySlice` and `unsafeFromArraySlice` functions for conversion to and
51+
from the underlying boxed `Array`.
5052

5153
# Changes in version 0.12.3.1
5254

vector/src/Data/Vector.hs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ module Data.Vector (
163163
toList, Data.Vector.fromList, Data.Vector.fromListN,
164164

165165
-- ** Arrays
166-
fromArray, toArray,
166+
toArray, fromArray, toArraySlice, unsafeFromArraySlice,
167167

168168
-- ** Other vector types
169169
G.convert,
@@ -2136,16 +2136,43 @@ fromListN = G.fromListN
21362136
-- @since 0.12.2.0
21372137
fromArray :: Array a -> Vector a
21382138
{-# INLINE fromArray #-}
2139-
fromArray x = Vector 0 (sizeofArray x) x
2139+
fromArray arr = Vector 0 (sizeofArray arr) arr
21402140

21412141
-- | /O(n)/ Convert a vector to an array.
21422142
--
21432143
-- @since 0.12.2.0
21442144
toArray :: Vector a -> Array a
21452145
{-# INLINE toArray #-}
2146-
toArray (Vector offset size arr)
2147-
| offset == 0 && size == sizeofArray arr = arr
2148-
| otherwise = cloneArray arr offset size
2146+
toArray (Vector offset len arr)
2147+
| offset == 0 && len == sizeofArray arr = arr
2148+
| otherwise = cloneArray arr offset len
2149+
2150+
-- | /O(1)/ Extract the underlying `Array`, offset where vector starts and the
2151+
-- total number of elements in the vector. Below property always holds:
2152+
--
2153+
-- > let (array, offset, len) = toArraySlice v
2154+
-- > v === unsafeFromArraySlice len offset array
2155+
--
2156+
-- @since 0.13.0.0
2157+
toArraySlice :: Vector a -> (Array a, Int, Int)
2158+
{-# INLINE toArraySlice #-}
2159+
toArraySlice (Vector offset len arr) = (arr, offset, len)
2160+
2161+
2162+
-- | /O(1)/ Convert an array slice to a vector. This function is very unsafe,
2163+
-- because constructing an invalid vector can yield almost all other safe
2164+
-- functions in this module unsafe. These are equivalent:
2165+
--
2166+
-- > unsafeFromArraySlice len offset === unsafeTake len . unsafeDrop offset . fromArray
2167+
--
2168+
-- @since 0.13.0.0
2169+
unsafeFromArraySlice ::
2170+
Array a -- ^ Immutable boxed array.
2171+
-> Int -- ^ Offset
2172+
-> Int -- ^ Length
2173+
-> Vector a
2174+
{-# INLINE unsafeFromArraySlice #-}
2175+
unsafeFromArraySlice arr offset len = Vector offset len arr
21492176

21502177
-- Conversions - Mutable vectors
21512178
-- -----------------------------

vector/tests/Tests/Vector/UnitTests.hs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ tests =
9191
, testGroup "Data.Vector"
9292
[ testCase "MonadFix" checkMonadFix
9393
, testCase "toFromArray" toFromArray
94+
, testCase "toFromArraySlice" toFromArraySlice
95+
, testCase "toFromArraySliceUnsafe" toFromArraySliceUnsafe
9496
, testCase "toFromMutableArray" toFromMutableArray
9597
]
9698
]
@@ -202,6 +204,22 @@ toFromArray =
202204
mkArrayRoundtrip $ \name v ->
203205
assertEqual name v $ Boxed.fromArray (Boxed.toArray v)
204206

207+
toFromArraySlice :: Assertion
208+
toFromArraySlice =
209+
mkArrayRoundtrip $ \name v ->
210+
case Boxed.toArraySlice v of
211+
(arr, off, n) ->
212+
assertEqual name v $
213+
Boxed.take n (Boxed.drop off (Boxed.fromArray arr))
214+
215+
toFromArraySliceUnsafe :: Assertion
216+
toFromArraySliceUnsafe =
217+
mkArrayRoundtrip $ \name v ->
218+
case Boxed.toArraySlice v of
219+
(arr, off, n) ->
220+
assertEqual name v $
221+
Boxed.unsafeFromArraySlice arr off n
222+
205223
toFromMutableArray :: Assertion
206224
toFromMutableArray = mkArrayRoundtrip assetRoundtrip
207225
where

0 commit comments

Comments
 (0)