@@ -145,6 +145,24 @@ impl<T, D> PyArray<T, D> {
145145 self . as_ptr ( ) as _
146146 }
147147
148+ #[ inline( always) ]
149+ fn check_flag ( & self , flag : c_int ) -> bool {
150+ unsafe { ( * self . as_array_ptr ( ) ) . flags & flag == flag }
151+ }
152+
153+ pub fn is_contiguous ( & self ) -> bool {
154+ self . check_flag ( npyffi:: NPY_ARRAY_C_CONTIGUOUS )
155+ | self . check_flag ( npyffi:: NPY_ARRAY_F_CONTIGUOUS )
156+ }
157+
158+ pub fn is_forran_contiguous ( & self ) -> bool {
159+ self . check_flag ( npyffi:: NPY_ARRAY_F_CONTIGUOUS )
160+ }
161+
162+ pub fn is_c_contiguous ( & self ) -> bool {
163+ self . check_flag ( npyffi:: NPY_ARRAY_C_CONTIGUOUS )
164+ }
165+
148166 /// Get `Py<PyArray>` from `&PyArray`, which is the owned wrapper of PyObject.
149167 ///
150168 /// You can use this method when you have to avoid lifetime annotation to your function args
@@ -404,15 +422,23 @@ impl<T: TypeNum, D: Dimension> PyArray<T, D> {
404422 /// assert_eq!(py_array.as_slice(), &[0, 1, 2, 3]);
405423 /// # }
406424 /// ```
407- pub fn as_slice ( & self ) -> & [ T ] {
408- self . type_check_assert ( ) ;
409- unsafe { :: std:: slice:: from_raw_parts ( self . data ( ) , self . len ( ) ) }
425+ pub fn as_slice ( & self ) -> Result < & [ T ] , ErrorKind > {
426+ self . type_check ( ) ?;
427+ if !self . is_contiguous ( ) {
428+ Err ( ErrorKind :: NotContiguous )
429+ } else {
430+ Ok ( unsafe { :: std:: slice:: from_raw_parts ( self . data ( ) , self . len ( ) ) } )
431+ }
410432 }
411433
412434 /// Get the mmutable view of the internal data of `PyArray`, as slice.
413- pub fn as_slice_mut ( & self ) -> & mut [ T ] {
414- self . type_check_assert ( ) ;
415- unsafe { :: std:: slice:: from_raw_parts_mut ( self . data ( ) , self . len ( ) ) }
435+ pub fn as_slice_mut ( & self ) -> Result < & mut [ T ] , ErrorKind > {
436+ self . type_check ( ) ?;
437+ if !self . is_contiguous ( ) {
438+ Err ( ErrorKind :: NotContiguous )
439+ } else {
440+ Ok ( unsafe { :: std:: slice:: from_raw_parts_mut ( self . data ( ) , self . len ( ) ) } )
441+ }
416442 }
417443
418444 /// Construct PyArray from `ndarray::ArrayBase`.
@@ -614,10 +640,7 @@ impl<T: TypeNum + Clone, D: Dimension> PyArray<T, D> {
614640 /// # }
615641 /// ```
616642 pub fn to_owned_array ( & self ) -> Array < T , D > {
617- unsafe {
618- let vec = self . as_slice ( ) . to_vec ( ) ;
619- Array :: from_shape_vec_unchecked ( self . ndarray_shape ( ) , vec)
620- }
643+ self . as_array ( ) . to_owned ( )
621644 }
622645}
623646
0 commit comments