1+ {-# LANGUAGE CPP #-}
12{-# LANGUAGE ForeignFunctionInterface #-}
23{-# LANGUAGE QuasiQuotes #-}
34{-# LANGUAGE TemplateHaskell #-}
@@ -19,8 +20,17 @@ import Data.Bits
1920import Data.Char
2021import Data.Int
2122import Data.Word
22- import Data.Set qualified as Set
23- import Data.Map.Strict qualified as Map
23+ import Data.Set qualified as Set
24+ import Data.Map.Strict qualified as Map
25+ import Data.Vector.Generic qualified as VG
26+ import Data.Vector.Generic.Mutable qualified as MVG
27+ import Data.Vector qualified as V
28+ #if MIN_VERSION_vector(0,13,2)
29+ import Data.Vector.Strict qualified as VV
30+ #endif
31+ import Data.Vector.Storable qualified as VS
32+ import Data.Vector.Primitive qualified as VP
33+ import Data.Vector.Unboxed qualified as VU
2434import Foreign.Ptr
2535import Foreign.C.Types
2636import Foreign.Storable
@@ -436,6 +446,43 @@ instance (FromPy k, FromPy v, Ord k) => FromPy (Map.Map k v) where
436446 pure $! Map. insert k v m)
437447 Map. empty
438448
449+ -- | Converts to python's list
450+ instance ToPy a => ToPy (V. Vector a ) where
451+ basicToPy = vectorToPy
452+ -- | Converts to python's list
453+ instance (ToPy a , VS. Storable a ) => ToPy (VS. Vector a ) where
454+ basicToPy = vectorToPy
455+ -- | Converts to python's list
456+ instance (ToPy a , VP. Prim a ) => ToPy (VP. Vector a ) where
457+ basicToPy = vectorToPy
458+ -- | Converts to python's list
459+ instance (ToPy a , VU. Unbox a ) => ToPy (VU. Vector a ) where
460+ basicToPy = vectorToPy
461+ #if MIN_VERSION_vector(0,13,2)
462+ -- | Converts to python's list
463+ instance (ToPy a ) => ToPy (VV. Vector a ) where
464+ basicToPy = vectorToPy
465+ #endif
466+
467+ -- | Accepts python's sequence (@len@ and indexing)
468+ instance FromPy a => FromPy (V. Vector a ) where
469+ basicFromPy = vectorFromPy
470+ -- | Accepts python's sequence (@len@ and indexing)
471+ instance (FromPy a , VS. Storable a ) => FromPy (VS. Vector a ) where
472+ basicFromPy = vectorFromPy
473+ -- | Accepts python's sequence (@len@ and indexing)
474+ instance (FromPy a , VP. Prim a ) => FromPy (VP. Vector a ) where
475+ basicFromPy = vectorFromPy
476+ -- | Accepts python's sequence (@len@ and indexing)
477+ instance (FromPy a , VU. Unbox a ) => FromPy (VU. Vector a ) where
478+ basicFromPy = vectorFromPy
479+ #if MIN_VERSION_vector(0,13,2)
480+ -- | Accepts python's sequence (@len@ and indexing)
481+ instance FromPy a => FromPy (VV. Vector a ) where
482+ basicFromPy = vectorFromPy
483+ #endif
484+
485+
439486-- | Fold over iterable. Function takes ownership over iterator.
440487foldPyIterable
441488 :: Ptr PyObject -- ^ Python iterator (not checked)
@@ -450,6 +497,39 @@ foldPyIterable p_iter step a0
450497 p -> loop =<< (step a p `finally` decref p)
451498
452499
500+ vectorFromPy :: (VG. Vector v a , FromPy a ) => Ptr PyObject -> Py (v a )
501+ {-# INLINE vectorFromPy #-}
502+ vectorFromPy p_seq = do
503+ len <- Py [CU. exp | long long { PySequence_Size($(PyObject* p_seq)) } |]
504+ when (len < 0 ) $ do
505+ Py [C. exp | void { PyErr_Clear() } |]
506+ throwM BadPyType
507+ -- Read data into vector
508+ buf <- MVG. generateM (fromIntegral len) $ \ i -> do
509+ let i_c = fromIntegral i
510+ Py [CU. exp | PyObject* { PySequence_GetItem($(PyObject* p_seq), $(long long i_c)) } |] >>= \ case
511+ NULL -> mustThrowPyError
512+ p -> basicFromPy p `finally` decref p
513+ VG. unsafeFreeze buf
514+
515+ vectorToPy :: (VG. Vector v a , ToPy a ) => v a -> Py (Ptr PyObject )
516+ vectorToPy vec = runProgram $ do
517+ p_list <- takeOwnership =<< checkNull (Py [CU. exp | PyObject* { PyList_New($(long long n_c)) } |])
518+ progPy $ do
519+ let loop i
520+ | i >= n = p_list <$ incref p_list
521+ | otherwise = basicToPy (VG. unsafeIndex vec i) >>= \ case
522+ NULL -> pure nullPtr
523+ p_a -> do
524+ let i_c = fromIntegral i :: CLLong
525+ -- NOTE: PyList_SET_ITEM steals reference
526+ Py [CU. exp | void { PyList_SET_ITEM($(PyObject* p_list), $(long long i_c), $(PyObject* p_a)) } |]
527+ loop (i+ 1 )
528+ loop 0
529+ where
530+ n = VG. length vec
531+ n_c = fromIntegral n :: CLLong
532+
453533----------------------------------------------------------------
454534-- Functions marshalling
455535----------------------------------------------------------------
0 commit comments