36 #ifndef VIGRA_NUMPY_ARRAY_TRAITS_HXX
37 #define VIGRA_NUMPY_ARRAY_TRAITS_HXX
39 #include "numerictraits.hxx"
40 #include "multi_array.hxx"
41 #include "numpy_array_taggedshape.hxx"
65 struct NumericTraits<Singleband<T> >
66 :
public NumericTraits<T>
70 struct NumericTraits<Multiband<T> >
72 typedef Multiband<T> Type;
79 typedef Type ValueType;
81 typedef typename NumericTraits<T>::isIntegral isIntegral;
82 typedef VigraFalseType isScalar;
83 typedef typename NumericTraits<T>::isSigned isSigned;
84 typedef typename NumericTraits<T>::isSigned isOrdered;
85 typedef typename NumericTraits<T>::isSigned isComplex;
123 template<
class ValueType>
124 struct ERROR_NumpyArrayValuetypeTraits_not_specialized_for_ { };
126 template<
class ValueType>
127 struct NumpyArrayValuetypeTraits
129 static bool isValuetypeCompatible(PyArrayObject
const * obj)
131 return ERROR_NumpyArrayValuetypeTraits_not_specialized_for_<ValueType>();
134 static ERROR_NumpyArrayValuetypeTraits_not_specialized_for_<ValueType> typeCode;
136 static std::string typeName()
138 return std::string(
"ERROR: NumpyArrayValuetypeTraits not specialized for this case");
141 static std::string typeNameImpex()
143 return std::string(
"ERROR: NumpyArrayValuetypeTraits not specialized for this case");
146 static PyObject * typeObject()
148 return (PyObject *)0;
152 template<
class ValueType>
153 ERROR_NumpyArrayValuetypeTraits_not_specialized_for_<ValueType> NumpyArrayValuetypeTraits<ValueType>::typeCode;
155 #define VIGRA_NUMPY_VALUETYPE_TRAITS(type, typeID, numpyTypeName, impexTypeName) \
157 struct NumpyArrayValuetypeTraits<type > \
159 static bool isValuetypeCompatible(PyArrayObject const * obj) \
161 return PyArray_EquivTypenums(typeID, PyArray_DESCR((PyObject *)obj)->type_num) && \
162 PyArray_ITEMSIZE((PyObject *)obj) == sizeof(type); \
165 static NPY_TYPES const typeCode = typeID; \
167 static std::string typeName() \
169 return #numpyTypeName; \
172 static std::string typeNameImpex() \
174 return impexTypeName; \
177 static PyObject * typeObject() \
179 return PyArray_TypeObjectFromType(typeID); \
183 VIGRA_NUMPY_VALUETYPE_TRAITS(
bool, NPY_BOOL,
bool,
"UINT8")
184 VIGRA_NUMPY_VALUETYPE_TRAITS(
signed char, NPY_INT8, int8, "INT16")
185 VIGRA_NUMPY_VALUETYPE_TRAITS(
unsigned char, NPY_UINT8, uint8, "UINT8")
186 VIGRA_NUMPY_VALUETYPE_TRAITS(
short, NPY_INT16, int16, "INT16")
187 VIGRA_NUMPY_VALUETYPE_TRAITS(
unsigned short, NPY_UINT16, uint16, "UINT16")
189 #if VIGRA_BITSOF_LONG == 32
190 VIGRA_NUMPY_VALUETYPE_TRAITS(
long, NPY_INT32, int32,
"INT32")
191 VIGRA_NUMPY_VALUETYPE_TRAITS(
unsigned long, NPY_UINT32, uint32, "UINT32")
192 #elif VIGRA_BITSOF_LONG == 64
193 VIGRA_NUMPY_VALUETYPE_TRAITS(
long, NPY_INT64, int64,
"DOUBLE")
194 VIGRA_NUMPY_VALUETYPE_TRAITS(
unsigned long, NPY_UINT64, uint64, "DOUBLE")
197 #if VIGRA_BITSOF_INT == 32
198 VIGRA_NUMPY_VALUETYPE_TRAITS(
int, NPY_INT32, int32,
"INT32")
199 VIGRA_NUMPY_VALUETYPE_TRAITS(
unsigned int, NPY_UINT32, uint32, "UINT32")
200 #elif VIGRA_BITSOF_INT == 64
201 VIGRA_NUMPY_VALUETYPE_TRAITS(
int, NPY_INT64, int64,
"DOUBLE")
202 VIGRA_NUMPY_VALUETYPE_TRAITS(
unsigned int, NPY_UINT64, uint64, "DOUBLE")
206 # if VIGRA_BITSOF_LONG_LONG == 32
207 VIGRA_NUMPY_VALUETYPE_TRAITS(
long long, NPY_INT32, int32,
"INT32")
208 VIGRA_NUMPY_VALUETYPE_TRAITS(
unsigned long long, NPY_UINT32, uint32, "UINT32")
209 # elif VIGRA_BITSOF_LONG_LONG == 64
210 VIGRA_NUMPY_VALUETYPE_TRAITS(
long long, NPY_INT64, int64,
"DOUBLE")
211 VIGRA_NUMPY_VALUETYPE_TRAITS(
unsigned long long, NPY_UINT64, uint64, "DOUBLE")
215 VIGRA_NUMPY_VALUETYPE_TRAITS(npy_float32, NPY_FLOAT32, float32,
"FLOAT")
216 VIGRA_NUMPY_VALUETYPE_TRAITS(npy_float64, NPY_FLOAT64, float64, "DOUBLE")
217 #if NPY_SIZEOF_LONGDOUBLE != NPY_SIZEOF_DOUBLE
218 VIGRA_NUMPY_VALUETYPE_TRAITS(npy_longdouble, NPY_LONGDOUBLE, longdouble,
"")
220 VIGRA_NUMPY_VALUETYPE_TRAITS(npy_cfloat, NPY_CFLOAT, complex64,
"")
221 VIGRA_NUMPY_VALUETYPE_TRAITS(std::complex<npy_float>, NPY_CFLOAT, complex64, "")
222 VIGRA_NUMPY_VALUETYPE_TRAITS(npy_cdouble, NPY_CDOUBLE, complex128, "")
223 VIGRA_NUMPY_VALUETYPE_TRAITS(std::complex<npy_double>, NPY_CDOUBLE, complex128, "")
224 VIGRA_NUMPY_VALUETYPE_TRAITS(npy_clongdouble, NPY_CLONGDOUBLE, clongdouble, "")
225 #if NPY_SIZEOF_LONGDOUBLE != NPY_SIZEOF_DOUBLE
226 VIGRA_NUMPY_VALUETYPE_TRAITS(std::complex<npy_longdouble>, NPY_CLONGDOUBLE, clongdouble,
"")
229 #undef VIGRA_NUMPY_VALUETYPE_TRAITS
237 template<
unsigned int N,
class T,
class Str
ide>
238 struct NumpyArrayTraits;
242 template<
unsigned int N,
class T>
243 struct NumpyArrayTraits<N, T, StridedArrayTag>
246 typedef T value_type;
247 typedef NumpyArrayValuetypeTraits<T> ValuetypeTraits;
248 static NPY_TYPES
const typeCode = ValuetypeTraits::typeCode;
250 static bool isArray(PyObject * obj)
252 return obj && PyArray_Check(obj);
255 static bool isValuetypeCompatible(PyArrayObject * obj)
257 return ValuetypeTraits::isValuetypeCompatible(obj);
260 static bool isShapeCompatible(PyArrayObject * array)
262 PyObject * obj = (PyObject *)array;
263 int ndim = PyArray_NDIM(obj);
272 static bool isPropertyCompatible(PyArrayObject * obj)
274 return isShapeCompatible(obj) && isValuetypeCompatible(obj);
280 static TaggedShape taggedShape(TinyVector<U, N>
const & shape, PyAxisTags axistags)
282 return TaggedShape(shape, axistags);
289 static TaggedShape taggedShape(TinyVector<U, N>
const & shape,
290 std::string
const & =
"")
296 return TaggedShape(shape, PyAxisTags());
301 static void finalizeTaggedShape(TaggedShape & tagged_shape)
303 vigra_precondition(tagged_shape.size() == N,
304 "reshapeIfEmpty(): tagged_shape has wrong size.");
312 template <
class ARRAY>
313 static void permuteLikewise(python_ptr array, ARRAY
const & data, ARRAY & res)
315 vigra_precondition((
int)data.size() == N,
316 "NumpyArray::permuteLikewise(): size mismatch.");
318 ArrayVector<npy_intp> permute;
319 detail::getAxisPermutationImpl(permute, array,
"permutationToNormalOrder",
320 AxisInfo::AllAxes,
true);
322 if(permute.size() != 0)
324 applyPermutation(permute.begin(), permute.end(), data.begin(), res.begin());
331 static void permutationToSetupOrder(python_ptr array, ArrayVector<U> & permute)
333 detail::getAxisPermutationImpl(permute, array,
"permutationToNormalOrder",
334 AxisInfo::AllAxes,
true);
336 if(permute.size() == 0)
348 static python_ptr unsafeConstructorFromData(TinyVector<U, N>
const & shape,
349 T *data, TinyVector<U, N>
const & stride)
351 TinyVector<npy_intp, N> npyStride(stride *
sizeof(T));
352 return constructNumpyArrayFromData(shape, npyStride.begin(),
353 ValuetypeTraits::typeCode, data);
359 template<
unsigned int N,
class T>
360 struct NumpyArrayTraits<N, T, UnstridedArrayTag>
361 :
public NumpyArrayTraits<N, T, StridedArrayTag>
363 typedef NumpyArrayTraits<N, T, StridedArrayTag> BaseType;
364 typedef typename BaseType::ValuetypeTraits ValuetypeTraits;
366 static bool isShapeCompatible(PyArrayObject * array)
368 PyObject * obj = (PyObject *)array;
369 int ndim = PyArray_NDIM(obj);
370 long channelIndex = pythonGetAttr(obj,
"channelIndex", ndim);
371 long majorIndex = pythonGetAttr(obj,
"innerNonchannelIndex", ndim);
372 npy_intp * strides = PyArray_STRIDES(obj);
374 if(channelIndex < ndim)
377 return (ndim == N && strides[channelIndex] ==
sizeof(T));
379 else if(majorIndex < ndim)
383 return (ndim == N && strides[majorIndex] ==
sizeof(T));
388 return (ndim == N && strides[0] ==
sizeof(T));
392 static bool isPropertyCompatible(PyArrayObject * obj)
394 return isShapeCompatible(obj) && BaseType::isValuetypeCompatible(obj);
400 template<
unsigned int N,
class T>
401 struct NumpyArrayTraits<N, Singleband<T>, StridedArrayTag>
402 :
public NumpyArrayTraits<N, T, StridedArrayTag>
404 typedef NumpyArrayTraits<N, T, StridedArrayTag> BaseType;
405 typedef typename BaseType::ValuetypeTraits ValuetypeTraits;
407 static bool isShapeCompatible(PyArrayObject * array)
409 PyObject * obj = (PyObject *)array;
410 int ndim = PyArray_NDIM(obj);
411 long channelIndex = pythonGetAttr(obj,
"channelIndex", ndim);
415 if(channelIndex == ndim)
419 return ndim == N+1 && PyArray_DIM(obj, channelIndex) == 1;
422 static bool isPropertyCompatible(PyArrayObject * obj)
424 return isShapeCompatible(obj) && BaseType::isValuetypeCompatible(obj);
428 static TaggedShape taggedShape(TinyVector<U, N>
const & shape, PyAxisTags axistags)
430 return TaggedShape(shape, axistags).setChannelCount(1);
434 static TaggedShape taggedShape(TinyVector<U, N>
const & shape, std::string
const & order =
"")
436 return TaggedShape(shape,
437 PyAxisTags(detail::defaultAxistags(shape.size()+1, order))).setChannelCount(1);
440 static void finalizeTaggedShape(TaggedShape & tagged_shape)
442 if(tagged_shape.axistags.hasChannelAxis())
444 tagged_shape.setChannelCount(1);
445 vigra_precondition(tagged_shape.size() == N+1,
446 "reshapeIfEmpty(): tagged_shape has wrong size.");
450 tagged_shape.setChannelCount(0);
451 vigra_precondition(tagged_shape.size() == N,
452 "reshapeIfEmpty(): tagged_shape has wrong size.");
456 template <
class ARRAY>
457 static void permuteLikewise(python_ptr array, ARRAY
const & data, ARRAY & res)
459 vigra_precondition((
int)data.size() == N,
460 "NumpyArray::permuteLikewise(): size mismatch.");
462 ArrayVector<npy_intp> permute;
463 detail::getAxisPermutationImpl(permute, array,
"permutationToNormalOrder",
464 AxisInfo::NonChannel,
true);
466 if(permute.size() == 0)
472 applyPermutation(permute.begin(), permute.end(), data.begin(), res.begin());
476 static void permutationToSetupOrder(python_ptr array, ArrayVector<U> & permute)
478 detail::getAxisPermutationImpl(permute, array,
"permutationToNormalOrder",
479 AxisInfo::AllAxes,
true);
480 if(permute.size() == 0)
485 else if(permute.size() == N+1)
487 permute.erase(permute.begin());
494 template<
unsigned int N,
class T>
495 struct NumpyArrayTraits<N, Singleband<T>, UnstridedArrayTag>
496 :
public NumpyArrayTraits<N, Singleband<T>, StridedArrayTag>
498 typedef NumpyArrayTraits<N, T, UnstridedArrayTag> UnstridedTraits;
499 typedef NumpyArrayTraits<N, Singleband<T>, StridedArrayTag> BaseType;
500 typedef typename BaseType::ValuetypeTraits ValuetypeTraits;
502 static bool isShapeCompatible(PyArrayObject * array)
504 PyObject * obj = (PyObject *)array;
505 int ndim = PyArray_NDIM(obj);
506 long channelIndex = pythonGetAttr(obj,
"channelIndex", ndim);
507 long majorIndex = pythonGetAttr(obj,
"innerNonchannelIndex", ndim);
508 npy_intp * strides = PyArray_STRIDES(obj);
511 if(majorIndex == ndim)
512 return N == ndim && strides[0] ==
sizeof(T);
516 if(channelIndex == ndim)
517 return N == ndim && strides[majorIndex] ==
sizeof(T);
521 return ndim == N+1 && PyArray_DIM(obj, channelIndex) == 1 &&
522 strides[majorIndex] ==
sizeof(T);
525 static bool isPropertyCompatible(PyArrayObject * obj)
527 return isShapeCompatible(obj) && BaseType::isValuetypeCompatible(obj);
533 template<
unsigned int N,
class T>
534 struct NumpyArrayTraits<N, Multiband<T>, StridedArrayTag>
535 :
public NumpyArrayTraits<N, T, StridedArrayTag>
537 typedef NumpyArrayTraits<N, T, StridedArrayTag> BaseType;
538 typedef typename BaseType::ValuetypeTraits ValuetypeTraits;
540 static bool isShapeCompatible(PyArrayObject * array)
542 PyObject * obj = (PyObject*)array;
543 int ndim = PyArray_NDIM(obj);
544 long channelIndex = pythonGetAttr(obj,
"channelIndex", ndim);
545 long majorIndex = pythonGetAttr(obj,
"innerNonchannelIndex", ndim);
547 if(channelIndex < ndim)
552 else if(majorIndex < ndim)
560 return ndim == N || ndim == N-1;
564 static bool isPropertyCompatible(PyArrayObject * obj)
566 return isShapeCompatible(obj) && ValuetypeTraits::isValuetypeCompatible(obj);
570 static TaggedShape taggedShape(TinyVector<U, N>
const & shape, PyAxisTags axistags)
572 return TaggedShape(shape, axistags).setChannelIndexLast();
576 static TaggedShape taggedShape(TinyVector<U, N>
const & shape, std::string
const & order =
"")
578 return TaggedShape(shape,
579 PyAxisTags(detail::defaultAxistags(shape.size(), order))).setChannelIndexLast();
582 static void finalizeTaggedShape(TaggedShape & tagged_shape)
586 if(tagged_shape.channelCount() == 1 && !tagged_shape.axistags.hasChannelAxis())
588 tagged_shape.setChannelCount(0);
589 vigra_precondition(tagged_shape.size() == N-1,
590 "reshapeIfEmpty(): tagged_shape has wrong size.");
594 vigra_precondition(tagged_shape.size() == N,
595 "reshapeIfEmpty(): tagged_shape has wrong size.");
599 template <
class ARRAY>
600 static void permuteLikewise(python_ptr array, ARRAY
const & data, ARRAY & res)
602 ArrayVector<npy_intp> permute;
604 if((
int)data.size() == N)
606 vigra_precondition(PyArray_NDIM((PyArrayObject*)array.get()) == N,
607 "NumpyArray::permuteLikewise(): input array has no channel axis.");
609 detail::getAxisPermutationImpl(permute, array,
"permutationToNormalOrder",
610 AxisInfo::AllAxes,
true);
612 if(permute.size() == 0)
620 int channelIndex = permute[0];
621 for(
int k=1; k<N; ++k)
622 permute[k-1] = permute[k];
623 permute[N-1] = channelIndex;
628 vigra_precondition((
int)data.size() == N-1,
629 "NumpyArray::permuteLikewise(): size mismatch.");
631 detail::getAxisPermutationImpl(permute, array,
"permutationToNormalOrder",
632 AxisInfo::NonChannel,
true);
634 if(permute.size() == 0)
641 applyPermutation(permute.begin(), permute.end(), data.begin(), res.begin());
645 static void permutationToSetupOrder(python_ptr array, ArrayVector<U> & permute)
647 detail::getAxisPermutationImpl(permute, array,
"permutationToNormalOrder",
648 AxisInfo::AllAxes,
true);
650 if(permute.size() == 0)
652 permute.resize(PyArray_NDIM((PyArrayObject*)array.get()));
655 else if(permute.size() == N)
658 int channelIndex = permute[0];
659 for(
int k=1; k<N; ++k)
660 permute[k-1] = permute[k];
661 permute[N-1] = channelIndex;
668 template<
unsigned int N,
class T>
669 struct NumpyArrayTraits<N, Multiband<T>, UnstridedArrayTag>
670 :
public NumpyArrayTraits<N, Multiband<T>, StridedArrayTag>
672 typedef NumpyArrayTraits<N, Multiband<T>, StridedArrayTag> BaseType;
673 typedef typename BaseType::ValuetypeTraits ValuetypeTraits;
675 static bool isShapeCompatible(PyArrayObject * array)
677 PyObject * obj = (PyObject *)array;
678 int ndim = PyArray_NDIM(obj);
679 long channelIndex = pythonGetAttr(obj,
"channelIndex", ndim);
680 long majorIndex = pythonGetAttr(obj,
"innerNonchannelIndex", ndim);
681 npy_intp * strides = PyArray_STRIDES(obj);
683 if(channelIndex < ndim)
687 return ndim == N && strides[majorIndex] ==
sizeof(T);
689 else if(majorIndex < ndim)
693 return ndim == N-1 && strides[majorIndex] ==
sizeof(T);
699 return (ndim == N || ndim == N-1) && strides[0] ==
sizeof(T);
703 static bool isPropertyCompatible(PyArrayObject * obj)
705 return isShapeCompatible(obj) && BaseType::isValuetypeCompatible(obj);
711 template<
unsigned int N,
int M,
class T>
712 struct NumpyArrayTraits<N, TinyVector<T, M>, StridedArrayTag>
715 typedef TinyVector<T, M> value_type;
716 typedef NumpyArrayValuetypeTraits<T> ValuetypeTraits;
717 static NPY_TYPES
const typeCode = ValuetypeTraits::typeCode;
719 static bool isArray(PyObject * obj)
721 return obj && PyArray_Check(obj);
724 static bool isValuetypeCompatible(PyArrayObject * obj)
726 return ValuetypeTraits::isValuetypeCompatible(obj);
729 static bool isShapeCompatible(PyArrayObject * array)
731 PyObject * obj = (PyObject *)array;
734 if(PyArray_NDIM(obj) != N+1)
738 long channelIndex = pythonGetAttr(obj,
"channelIndex", N);
739 npy_intp * strides = PyArray_STRIDES(obj);
741 return PyArray_DIM(obj, channelIndex) == M && strides[channelIndex] ==
sizeof(T);
744 static bool isPropertyCompatible(PyArrayObject * obj)
746 return isShapeCompatible(obj) && ValuetypeTraits::isValuetypeCompatible(obj);
750 static TaggedShape taggedShape(TinyVector<U, N>
const & shape, PyAxisTags axistags)
752 return TaggedShape(shape, axistags).setChannelCount(M);
756 static TaggedShape taggedShape(TinyVector<U, N>
const & shape, std::string
const & order =
"")
758 return TaggedShape(shape,
759 PyAxisTags(detail::defaultAxistags(shape.size()+1, order))).setChannelCount(M);
762 static void finalizeTaggedShape(TaggedShape & tagged_shape)
764 tagged_shape.setChannelCount(M);
765 vigra_precondition(tagged_shape.size() == N+1,
766 "reshapeIfEmpty(): tagged_shape has wrong size.");
769 template <
class ARRAY>
770 static void permuteLikewise(python_ptr array, ARRAY
const & data, ARRAY & res)
772 vigra_precondition((
int)data.size() == N,
773 "NumpyArray::permuteLikewise(): size mismatch.");
775 ArrayVector<npy_intp> permute;
776 detail::getAxisPermutationImpl(permute, array,
"permutationToNormalOrder",
777 AxisInfo::NonChannel,
true);
779 if(permute.size() == 0)
785 applyPermutation(permute.begin(), permute.end(), data.begin(), res.begin());
789 static void permutationToSetupOrder(python_ptr array, ArrayVector<U> & permute)
791 detail::getAxisPermutationImpl(permute, array,
"permutationToNormalOrder",
792 AxisInfo::AllAxes,
true);
793 if(permute.size() == 0)
798 else if(permute.size() == N+1)
800 permute.erase(permute.begin());
805 static python_ptr unsafeConstructorFromData(TinyVector<U, N>
const & shape,
806 value_type *data, TinyVector<U, N>
const & stride)
808 TinyVector<npy_intp, N+1> npyShape;
809 std::copy(shape.begin(), shape.end(), npyShape.begin());
812 TinyVector<npy_intp, N+1> npyStride;
814 stride.begin(), stride.end(), npyStride.begin(),
815 std::bind2nd(std::multiplies<npy_intp>(),
sizeof(value_type)));
816 npyStride[N] =
sizeof(T);
818 return constructNumpyArrayFromData(npyShape, npyStride.begin(),
819 ValuetypeTraits::typeCode, data);
825 template<
unsigned int N,
int M,
class T>
826 struct NumpyArrayTraits<N, TinyVector<T, M>, UnstridedArrayTag>
827 :
public NumpyArrayTraits<N, TinyVector<T, M>, StridedArrayTag>
829 typedef NumpyArrayTraits<N, TinyVector<T, M>, StridedArrayTag> BaseType;
830 typedef typename BaseType::value_type value_type;
831 typedef typename BaseType::ValuetypeTraits ValuetypeTraits;
833 static bool isShapeCompatible(PyArrayObject * array)
835 PyObject * obj = (PyObject *)array;
836 int ndim = PyArray_NDIM(obj);
842 long channelIndex = pythonGetAttr(obj,
"channelIndex", ndim);
843 long majorIndex = pythonGetAttr(obj,
"innerNonchannelIndex", ndim);
844 npy_intp * strides = PyArray_STRIDES(obj);
846 if(majorIndex < ndim)
849 if(channelIndex == ndim)
853 return PyArray_DIM(obj, channelIndex) == M &&
854 strides[channelIndex] ==
sizeof(T) &&
855 strides[majorIndex] ==
sizeof(TinyVector<T, M>);
862 return PyArray_DIM(obj, N) == M &&
863 strides[N] ==
sizeof(T) &&
864 strides[0] ==
sizeof(TinyVector<T, M>);
868 static bool isPropertyCompatible(PyArrayObject * obj)
870 return isShapeCompatible(obj) && BaseType::isValuetypeCompatible(obj);
876 template<
unsigned int N,
class T>
877 struct NumpyArrayTraits<N, RGBValue<T>, StridedArrayTag>
878 :
public NumpyArrayTraits<N, TinyVector<T, 3>, StridedArrayTag>
881 typedef RGBValue<T> value_type;
882 typedef NumpyArrayValuetypeTraits<T> ValuetypeTraits;
887 template<
unsigned int N,
class T>
888 struct NumpyArrayTraits<N, RGBValue<T>, UnstridedArrayTag>
889 :
public NumpyArrayTraits<N, RGBValue<T>, StridedArrayTag>
891 typedef NumpyArrayTraits<N, TinyVector<T, 3>, UnstridedArrayTag> UnstridedTraits;
892 typedef NumpyArrayTraits<N, RGBValue<T>, StridedArrayTag> BaseType;
893 typedef typename BaseType::value_type value_type;
894 typedef typename BaseType::ValuetypeTraits ValuetypeTraits;
896 static bool isShapeCompatible(PyArrayObject * obj)
898 return UnstridedTraits::isShapeCompatible(obj);
901 static bool isPropertyCompatible(PyArrayObject * obj)
903 return UnstridedTraits::isPropertyCompatible(obj);
909 #endif // VIGRA_NUMPY_ARRAY_TRAITS_HXX
void applyPermutation(IndexIterator index_first, IndexIterator index_last, InIterator in, OutIterator out)
Definition: algorithm.hxx:388
void linearSequence(Iterator first, Iterator last, Value start, Value step)
Definition: algorithm.hxx:207