arrayfire/core/
util.rs

1use super::defines::{
2    AfError, BinaryOp, ColorMap, ConvDomain, ConvMode, DType, InterpType, MatProp, MatchType,
3    RandomEngineType, SparseFormat,
4};
5use super::error::HANDLE_ERROR;
6
7use half::f16;
8use libc::{c_int, c_uint, c_void, size_t};
9use num::Complex;
10use std::convert::From;
11use std::mem;
12use std::ops::BitOr;
13
14/// Short type alias for Complex single precision type
15pub type c32 = Complex<f32>;
16/// Short type alias for Complex double precision type
17pub type c64 = Complex<f64>;
18/// ArrayFire FFI Type alias for libc's signed long long
19pub type dim_t = libc::c_longlong;
20/// ArrayFire FFI Type alias for libc's unsigned long long
21pub type u64_t = libc::c_ulonglong;
22/// ArrayFire FFI Type alias for libc's void*
23pub type void_ptr = *mut libc::c_void;
24
25/// ArrayFire FFI Type alias for af_array
26pub type af_array = *mut libc::c_void;
27/// ArrayFire FFI Type alias for af_event
28pub type af_event = *mut libc::c_void;
29/// ArrayFire FFI Type alias for af_indexers_t
30pub type af_index_t = *mut libc::c_void;
31/// ArrayFire FFI Type alias for af_features
32pub type af_features = *const libc::c_void;
33/// ArrayFire FFI Type alias for af_random_engine
34pub type af_random_engine = *mut libc::c_void;
35/// ArrayFire FFI Type alias for af_window
36pub type af_window = *mut libc::c_void;
37
38extern "C" {
39    fn af_get_size_of(size: *mut size_t, aftype: c_uint) -> c_int;
40    fn af_alloc_host(ptr: *mut *const c_void, bytes: dim_t) -> c_int;
41    fn af_free_host(ptr: *mut c_void) -> c_int;
42}
43
44/// Get size, in bytes, of the arrayfire native type
45pub fn get_size(value: DType) -> usize {
46    unsafe {
47        let mut ret_val: usize = 0;
48        let err_val = af_get_size_of(&mut ret_val as *mut size_t, value as c_uint);
49        HANDLE_ERROR(AfError::from(err_val));
50        ret_val
51    }
52}
53
54/// Allocates space using Arrayfire allocator in host memory
55pub fn alloc_host<T>(elements: usize, _type: DType) -> *const T {
56    let ptr: *const T = ::std::ptr::null();
57    let bytes = (elements * get_size(_type)) as dim_t;
58    unsafe {
59        let err_val = af_alloc_host(&mut (ptr as *const c_void), bytes);
60        HANDLE_ERROR(AfError::from(err_val));
61    }
62    ptr
63}
64
65/// Frees memory allocated by Arrayfire allocator in host memory
66pub fn free_host<T>(ptr: *mut T) {
67    unsafe {
68        let err_val = af_free_host(ptr as *mut c_void);
69        HANDLE_ERROR(AfError::from(err_val));
70    }
71}
72
73impl From<i32> for AfError {
74    fn from(t: i32) -> Self {
75        assert!(AfError::SUCCESS as i32 <= t && t <= AfError::ERR_UNKNOWN as i32);
76        unsafe { mem::transmute(t) }
77    }
78}
79
80impl From<u32> for DType {
81    fn from(t: u32) -> Self {
82        assert!(DType::F32 as u32 <= t && t <= DType::U64 as u32);
83        unsafe { mem::transmute(t) }
84    }
85}
86
87impl From<u32> for InterpType {
88    fn from(t: u32) -> Self {
89        assert!(InterpType::NEAREST as u32 <= t && t <= InterpType::BICUBIC_SPLINE as u32);
90        unsafe { mem::transmute(t) }
91    }
92}
93
94impl From<u32> for ConvMode {
95    fn from(t: u32) -> Self {
96        assert!(ConvMode::DEFAULT as u32 <= t && t <= ConvMode::EXPAND as u32);
97        unsafe { mem::transmute(t) }
98    }
99}
100
101impl From<u32> for ConvDomain {
102    fn from(t: u32) -> Self {
103        assert!(ConvDomain::AUTO as u32 <= t && t <= ConvDomain::FREQUENCY as u32);
104        unsafe { mem::transmute(t) }
105    }
106}
107
108impl From<u32> for MatchType {
109    fn from(t: u32) -> Self {
110        assert!(MatchType::SAD as u32 <= t && t <= MatchType::SHD as u32);
111        unsafe { mem::transmute(t) }
112    }
113}
114
115impl From<u32> for ColorMap {
116    fn from(t: u32) -> Self {
117        assert!(ColorMap::DEFAULT as u32 <= t && t <= ColorMap::BLUE as u32);
118        unsafe { mem::transmute(t) }
119    }
120}
121
122/// Types of the data that can be generated using ArrayFire data generation functions.
123///
124/// The trait HasAfEnum has been defined internally for the following types. We strongly suggest
125/// not to implement this trait in your program for user defined types because ArrayFire functions
126/// will only work for the following data types currently. Any such trait implementation for types
127/// other than the ones listed below will result in undefined behavior.
128///
129/// - f32
130/// - f64
131/// - num::Complex\<f32\>
132/// - num::Complex\<f64\>
133/// - bool
134/// - i32
135/// - u32
136/// - u8
137/// - i64
138/// - u64
139/// - i16
140/// - u16
141///
142pub trait HasAfEnum {
143    /// This type alias points to `Self` always.
144    type InType: HasAfEnum;
145    /// This type alias points to the data type used to hold real part of a
146    /// complex number. For real valued numbers, this points to `Self`.
147    type BaseType: HasAfEnum;
148    /// This type alias points to `f32` for all 32 bit size types and `f64` for
149    /// larger 64-bit size types.
150    type AbsOutType: HasAfEnum;
151    /// This type alias points to `f64`/`f32` for floating point types and
152    /// `Self` otherwise.
153    type ArgOutType: HasAfEnum;
154    /// This type alias is used to define the output Array type for unary
155    /// operations. It points to `Self` for floating point types, either
156    /// real or complex. It points to `f32` for rest of the input types.
157    type UnaryOutType: HasAfEnum;
158    /// This type alias points to complex type created from a given input type.
159    /// This alias always points to either `std::Complex<f32>` or `std::Complex<f64>`
160    type ComplexOutType;
161    /// This type alias points to a data type that can store the mean value for
162    /// a given input type. This alias points to `f32`/`Complex<f32>` for all 32
163    /// bit size types and `f64`/`Complex<f64>` for larger 64-bit size types.
164    type MeanOutType: HasAfEnum;
165    /// This type alias points to a data type that can store the result of
166    /// aggregation of set of values for a given input type. Aggregate type
167    /// alias points to below types for given input types:
168    /// - `Self` for input types: `Complex<64>`, `Complex<f32>`, `f64`, `f32`, `i64`, `u64`
169    /// - `u32` for input types: `bool`
170    /// - `u32` for input types: `u8`
171    /// - `i32` for input types: `i16`
172    /// - `u32` for input types: `u16`
173    /// - `i32` for input types: `i32`
174    /// - `u32` for input types: `u32`
175    type AggregateOutType: HasAfEnum;
176    /// This type is different for b8 input type
177    type ProductOutType: HasAfEnum;
178    /// This type alias points to the output type for given input type of
179    /// sobel filter operation. Sobel filter output alias points to below
180    /// types for given input types:
181    /// - `f32` for input types: `Complex<f32>`, `f32`
182    /// - `f64` for input types: `Complex<f64>`, `f64`
183    /// - `i32` for input types: `bool`, `u8`, `i16`, `u16`, `i32`, `u32`
184    /// - `i64` for input types: `i64`, `u64`
185    type SobelOutType: HasAfEnum;
186
187    /// Return trait implmentors corresponding [DType](./enum.DType.html)
188    fn get_af_dtype() -> DType;
189}
190
191impl HasAfEnum for Complex<f32> {
192    type InType = Self;
193    type BaseType = f32;
194    type AbsOutType = f32;
195    type ArgOutType = f32;
196    type UnaryOutType = Self;
197    type ComplexOutType = Self;
198    type MeanOutType = Self;
199    type AggregateOutType = Self;
200    type ProductOutType = Self;
201    type SobelOutType = Self;
202
203    fn get_af_dtype() -> DType {
204        DType::C32
205    }
206}
207impl HasAfEnum for Complex<f64> {
208    type InType = Self;
209    type BaseType = f64;
210    type AbsOutType = f64;
211    type ArgOutType = f64;
212    type UnaryOutType = Self;
213    type ComplexOutType = Self;
214    type MeanOutType = Self;
215    type AggregateOutType = Self;
216    type ProductOutType = Self;
217    type SobelOutType = Self;
218
219    fn get_af_dtype() -> DType {
220        DType::C64
221    }
222}
223impl HasAfEnum for f32 {
224    type InType = Self;
225    type BaseType = Self;
226    type AbsOutType = f32;
227    type ArgOutType = f32;
228    type UnaryOutType = Self;
229    type ComplexOutType = Complex<f32>;
230    type MeanOutType = Self;
231    type AggregateOutType = Self;
232    type ProductOutType = Self;
233    type SobelOutType = Self;
234
235    fn get_af_dtype() -> DType {
236        DType::F32
237    }
238}
239impl HasAfEnum for f64 {
240    type InType = Self;
241    type BaseType = Self;
242    type AbsOutType = f64;
243    type ArgOutType = f64;
244    type UnaryOutType = Self;
245    type ComplexOutType = Complex<f64>;
246    type MeanOutType = Self;
247    type AggregateOutType = Self;
248    type ProductOutType = Self;
249    type SobelOutType = Self;
250
251    fn get_af_dtype() -> DType {
252        DType::F64
253    }
254}
255impl HasAfEnum for bool {
256    type InType = Self;
257    type BaseType = Self;
258    type AbsOutType = f32;
259    type ArgOutType = bool;
260    type UnaryOutType = f32;
261    type ComplexOutType = Complex<f32>;
262    type MeanOutType = f32;
263    type AggregateOutType = u32;
264    type ProductOutType = bool;
265    type SobelOutType = i32;
266
267    fn get_af_dtype() -> DType {
268        DType::B8
269    }
270}
271impl HasAfEnum for u8 {
272    type InType = Self;
273    type BaseType = Self;
274    type AbsOutType = f32;
275    type ArgOutType = u8;
276    type UnaryOutType = f32;
277    type ComplexOutType = Complex<f32>;
278    type MeanOutType = f32;
279    type AggregateOutType = u32;
280    type ProductOutType = u32;
281    type SobelOutType = i32;
282
283    fn get_af_dtype() -> DType {
284        DType::U8
285    }
286}
287impl HasAfEnum for i16 {
288    type InType = Self;
289    type BaseType = Self;
290    type AbsOutType = f32;
291    type ArgOutType = i16;
292    type UnaryOutType = f32;
293    type ComplexOutType = Complex<f32>;
294    type MeanOutType = f32;
295    type AggregateOutType = i32;
296    type ProductOutType = i32;
297    type SobelOutType = i32;
298
299    fn get_af_dtype() -> DType {
300        DType::S16
301    }
302}
303impl HasAfEnum for u16 {
304    type InType = Self;
305    type BaseType = Self;
306    type AbsOutType = f32;
307    type ArgOutType = u16;
308    type UnaryOutType = f32;
309    type ComplexOutType = Complex<f32>;
310    type MeanOutType = f32;
311    type AggregateOutType = u32;
312    type ProductOutType = u32;
313    type SobelOutType = i32;
314
315    fn get_af_dtype() -> DType {
316        DType::U16
317    }
318}
319impl HasAfEnum for f16 {
320    type InType = Self;
321    type BaseType = Self;
322    type AbsOutType = Self;
323    type ArgOutType = Self;
324    type UnaryOutType = Self;
325    type ComplexOutType = Complex<f16>;
326    type MeanOutType = Self;
327    type AggregateOutType = f32;
328    type ProductOutType = f32;
329    type SobelOutType = Self;
330
331    fn get_af_dtype() -> DType {
332        DType::F16
333    }
334}
335impl HasAfEnum for i32 {
336    type InType = Self;
337    type BaseType = Self;
338    type AbsOutType = f32;
339    type ArgOutType = i32;
340    type UnaryOutType = f32;
341    type ComplexOutType = Complex<f32>;
342    type MeanOutType = f32;
343    type AggregateOutType = i32;
344    type ProductOutType = i32;
345    type SobelOutType = i32;
346
347    fn get_af_dtype() -> DType {
348        DType::S32
349    }
350}
351impl HasAfEnum for u32 {
352    type InType = Self;
353    type BaseType = Self;
354    type AbsOutType = f32;
355    type ArgOutType = u32;
356    type UnaryOutType = f32;
357    type ComplexOutType = Complex<f32>;
358    type MeanOutType = f32;
359    type AggregateOutType = u32;
360    type ProductOutType = u32;
361    type SobelOutType = i32;
362
363    fn get_af_dtype() -> DType {
364        DType::U32
365    }
366}
367impl HasAfEnum for i64 {
368    type InType = Self;
369    type BaseType = Self;
370    type AbsOutType = f64;
371    type ArgOutType = i64;
372    type UnaryOutType = f64;
373    type ComplexOutType = Complex<f64>;
374    type MeanOutType = f64;
375    type AggregateOutType = Self;
376    type ProductOutType = Self;
377    type SobelOutType = i64;
378
379    fn get_af_dtype() -> DType {
380        DType::S64
381    }
382}
383impl HasAfEnum for u64 {
384    type InType = Self;
385    type BaseType = Self;
386    type AbsOutType = f64;
387    type ArgOutType = u64;
388    type UnaryOutType = f64;
389    type ComplexOutType = Complex<f64>;
390    type MeanOutType = f64;
391    type AggregateOutType = Self;
392    type ProductOutType = Self;
393    type SobelOutType = i64;
394
395    fn get_af_dtype() -> DType {
396        DType::U64
397    }
398}
399
400impl From<u32> for SparseFormat {
401    fn from(t: u32) -> Self {
402        assert!(SparseFormat::DENSE as u32 <= t && t <= SparseFormat::COO as u32);
403        unsafe { mem::transmute(t) }
404    }
405}
406
407impl From<u32> for BinaryOp {
408    fn from(t: u32) -> Self {
409        assert!(BinaryOp::ADD as u32 <= t && t <= BinaryOp::MAX as u32);
410        unsafe { mem::transmute(t) }
411    }
412}
413
414impl From<u32> for RandomEngineType {
415    fn from(t: u32) -> Self {
416        assert!(
417            RandomEngineType::PHILOX_4X32_10 as u32 <= t
418                && t <= RandomEngineType::MERSENNE_GP11213 as u32
419        );
420        unsafe { mem::transmute(t) }
421    }
422}
423
424/// This is an internal trait defined and implemented by ArrayFire
425/// create for rust's built-in types to figure out the data type
426/// binary operation's results.
427pub trait ImplicitPromote<RHS>: HasAfEnum {
428    /// This type alias points to the type of the result obtained
429    /// by performing a given binary option on given type and `RHS`.
430    type Output: HasAfEnum;
431}
432
433impl<T> ImplicitPromote<T> for T
434where
435    T: HasAfEnum,
436{
437    type Output = T;
438}
439
440macro_rules! implicit {
441    [$implType: ident, $rhsType: ident => $outType: ident] => (
442        impl ImplicitPromote< $rhsType > for $implType {
443            type Output = $outType;
444        }
445    )
446}
447
448//
449//implicit(implementation type, RHS type, output type)
450//
451
452//LHS is Complex double
453implicit!(c64, c32 => c64);
454implicit!(c64, f64       => c64);
455implicit!(c64, f32       => c64);
456implicit!(c64, i64       => c64);
457implicit!(c64, u64       => c64);
458implicit!(c64, i32       => c64);
459implicit!(c64, u32       => c64);
460implicit!(c64, i16       => c64);
461implicit!(c64, u16       => c64);
462implicit!(c64, bool      => c64);
463implicit!(c64, u8        => c64);
464
465//LHS is Complex float
466implicit!(c32, c64 => c64);
467implicit!(c32, f64       => c64);
468implicit!(c32, f32       => c32);
469implicit!(c32, i64       => c32);
470implicit!(c32, u64       => c32);
471implicit!(c32, i32       => c32);
472implicit!(c32, u32       => c32);
473implicit!(c32, i16       => c32);
474implicit!(c32, u16       => c32);
475implicit!(c32, bool      => c32);
476implicit!(c32, u8        => c32);
477
478//LHS is 64-bit floating point
479implicit!(f64, c64 => c64);
480implicit!(f64, c32 => c64);
481implicit!(f64, f32       =>       f64);
482implicit!(f64, i64       =>       f64);
483implicit!(f64, u64       =>       f64);
484implicit!(f64, i32       =>       f64);
485implicit!(f64, u32       =>       f64);
486implicit!(f64, i16       =>       f64);
487implicit!(f64, u16       =>       f64);
488implicit!(f64, bool      =>       f64);
489implicit!(f64, u8        =>       f64);
490
491//LHS is 32-bit floating point
492implicit!(f32, c64 => c64);
493implicit!(f32, c32 => c32);
494implicit!(f32, f64       =>       f64);
495implicit!(f32, i64       =>       f32);
496implicit!(f32, u64       =>       f32);
497implicit!(f32, i32       =>       f32);
498implicit!(f32, u32       =>       f32);
499implicit!(f32, i16       =>       f32);
500implicit!(f32, u16       =>       f32);
501implicit!(f32, bool      =>       f32);
502implicit!(f32, u8        =>       f32);
503
504//LHS is 64-bit signed integer
505implicit!(i64, c64 => c64);
506implicit!(i64, c32 => c32);
507implicit!(i64, f64       =>       f64);
508implicit!(i64, f32       =>       f32);
509implicit!(i64, u64       =>       u64);
510implicit!(i64, i32       =>       i64);
511implicit!(i64, u32       =>       i64);
512implicit!(i64, i16       =>       i64);
513implicit!(i64, u16       =>       i64);
514implicit!(i64, bool      =>       i64);
515implicit!(i64, u8        =>       i64);
516
517//LHS is 64-bit unsigned integer
518implicit!(u64, c64 => c64);
519implicit!(u64, c32 => c32);
520implicit!(u64, f64       =>       f64);
521implicit!(u64, f32       =>       f32);
522implicit!(u64, i64       =>       u64);
523implicit!(u64, i32       =>       u64);
524implicit!(u64, u32       =>       u64);
525implicit!(u64, i16       =>       u64);
526implicit!(u64, u16       =>       u64);
527implicit!(u64, bool      =>       u64);
528implicit!(u64, u8        =>       u64);
529
530//LHS is 32-bit signed integer
531implicit!(i32, c64 => c64);
532implicit!(i32, c32 => c32);
533implicit!(i32, f64       =>       f64);
534implicit!(i32, f32       =>       f32);
535implicit!(i32, i64       =>       i64);
536implicit!(i32, u64       =>       u64);
537implicit!(i32, u32       =>       u32);
538implicit!(i32, i16       =>       i32);
539implicit!(i32, u16       =>       i32);
540implicit!(i32, bool      =>       i32);
541implicit!(i32, u8        =>       i32);
542
543//LHS is 32-bit unsigned integer
544implicit!(u32, c64 => c64);
545implicit!(u32, c32 => c32);
546implicit!(u32, f64       =>       f64);
547implicit!(u32, f32       =>       f32);
548implicit!(u32, i64       =>       i64);
549implicit!(u32, u64       =>       u64);
550implicit!(u32, i32       =>       u32);
551implicit!(u32, i16       =>       u32);
552implicit!(u32, u16       =>       u32);
553implicit!(u32, bool      =>       u32);
554implicit!(u32, u8        =>       u32);
555
556//LHS is 16-bit signed integer
557implicit!(i16, c64 => c64);
558implicit!(i16, c32 => c32);
559implicit!(i16, f64       =>       f64);
560implicit!(i16, f32       =>       f32);
561implicit!(i16, i64       =>       i64);
562implicit!(i16, u64       =>       u64);
563implicit!(i16, i32       =>       i32);
564implicit!(i16, u32       =>       u32);
565implicit!(i16, u16       =>       u16);
566implicit!(i16, bool      =>       u16);
567implicit!(i16, u8        =>       u16);
568
569//LHS is 16-bit unsigned integer
570implicit!(u16, c64 => c64);
571implicit!(u16, c32 => c32);
572implicit!(u16, f64       =>       f64);
573implicit!(u16, f32       =>       f32);
574implicit!(u16, i64       =>       i64);
575implicit!(u16, u64       =>       u64);
576implicit!(u16, i32       =>       i32);
577implicit!(u16, u32       =>       u32);
578implicit!(u16, i16       =>       u16);
579implicit!(u16, bool      =>       u16);
580implicit!(u16, u8        =>       u16);
581
582//LHS is 8-bit unsigned integer
583implicit!(u8, c64 => c64);
584implicit!(u8, c32 => c32);
585implicit!(u8, f64       =>       f64);
586implicit!(u8, f32       =>       f32);
587implicit!(u8, i64       =>       i64);
588implicit!(u8, u64       =>       u64);
589implicit!(u8, i32       =>       i32);
590implicit!(u8, u32       =>       u32);
591implicit!(u8, i16       =>       i16);
592implicit!(u8, u16       =>       u16);
593implicit!(u8, bool      =>        u8);
594
595//LHS is bool(af::s8)
596implicit!(bool, c64 => c64);
597implicit!(bool, c32 => c32);
598implicit!(bool, f64       =>       f64);
599implicit!(bool, f32       =>       f32);
600implicit!(bool, i64       =>       i64);
601implicit!(bool, u64       =>       u64);
602implicit!(bool, i32       =>       i32);
603implicit!(bool, u32       =>       u32);
604implicit!(bool, i16       =>       i16);
605implicit!(bool, u16       =>       u16);
606implicit!(bool, u8        =>        u8);
607
608///Trait qualifier to accept either real or complex typed data
609pub trait FloatingPoint: HasAfEnum {
610    /// Use to check if trait implementor is real number
611    fn is_real() -> bool {
612        false
613    }
614    /// Use to check if trait implementor is complex number
615    fn is_complex() -> bool {
616        false
617    }
618}
619
620impl FloatingPoint for Complex<f64> {
621    fn is_complex() -> bool {
622        true
623    }
624}
625impl FloatingPoint for Complex<f32> {
626    fn is_complex() -> bool {
627        true
628    }
629}
630impl FloatingPoint for f64 {
631    fn is_real() -> bool {
632        true
633    }
634}
635impl FloatingPoint for f32 {
636    fn is_real() -> bool {
637        true
638    }
639}
640
641///Trait qualifier to accept real data(numbers)
642pub trait RealFloating: HasAfEnum {}
643
644impl RealFloating for f64 {}
645impl RealFloating for f32 {}
646
647///Trait qualifier to accept complex data(numbers)
648pub trait ComplexFloating: HasAfEnum {}
649
650impl ComplexFloating for c64 {}
651impl ComplexFloating for c32 {}
652
653///Trait qualifier indicating it can hold real numbers only
654pub trait RealNumber: HasAfEnum {}
655
656impl RealNumber for f64 {}
657impl RealNumber for f32 {}
658impl RealNumber for i32 {}
659impl RealNumber for u32 {}
660impl RealNumber for i16 {}
661impl RealNumber for u16 {}
662impl RealNumber for u8 {}
663impl RealNumber for bool {}
664impl RealNumber for u64 {}
665impl RealNumber for i64 {}
666
667///Trait qualifier for the type of Arrays accepted by scan operations
668pub trait Scanable: HasAfEnum {}
669
670impl Scanable for i32 {}
671impl Scanable for u32 {}
672impl Scanable for u64 {}
673impl Scanable for i64 {}
674
675/// Trait qualifier for type of Array's that are accepted
676/// by native image load/save functions.
677pub trait ImageNativeType: HasAfEnum {}
678
679impl ImageNativeType for f32 {}
680impl ImageNativeType for u16 {}
681impl ImageNativeType for u8 {}
682
683/// Trait qualifier for type of Array's that are accepted
684/// by image processing functions especially filtering algorithms
685pub trait ImageFilterType: HasAfEnum {}
686
687impl ImageFilterType for f64 {}
688impl ImageFilterType for f32 {}
689impl ImageFilterType for i32 {}
690impl ImageFilterType for u32 {}
691impl ImageFilterType for i16 {}
692impl ImageFilterType for u16 {}
693impl ImageFilterType for u8 {}
694impl ImageFilterType for bool {}
695
696// TODO Rust haven't stabilized trait aliases yet
697/// Trait qualifier for given type indicating conversion capability between
698/// grayscale and RGB triplets of data
699pub trait GrayRGBConvertible: HasAfEnum {}
700
701impl GrayRGBConvertible for f64 {}
702impl GrayRGBConvertible for f32 {}
703impl GrayRGBConvertible for i32 {}
704impl GrayRGBConvertible for u32 {}
705impl GrayRGBConvertible for i16 {}
706impl GrayRGBConvertible for u16 {}
707impl GrayRGBConvertible for u8 {}
708
709// TODO Rust haven't stabilized trait aliases yet
710/// Trait qualifier for given type indicating computability of Moments
711pub trait MomentsComputable: HasAfEnum {}
712
713impl MomentsComputable for f64 {}
714impl MomentsComputable for f32 {}
715impl MomentsComputable for i32 {}
716impl MomentsComputable for u32 {}
717impl MomentsComputable for i16 {}
718impl MomentsComputable for u16 {}
719impl MomentsComputable for u8 {}
720
721// TODO Rust haven't stabilized trait aliases yet
722/// Trait qualifier for given type indicating computability of Median
723pub trait MedianComputable: HasAfEnum {}
724
725impl MedianComputable for f64 {}
726impl MedianComputable for f32 {}
727impl MedianComputable for i32 {}
728impl MedianComputable for u32 {}
729impl MedianComputable for i16 {}
730impl MedianComputable for u16 {}
731impl MedianComputable for u8 {}
732
733// TODO Rust haven't stabilized trait aliases yet
734/// Trait qualifier for given type indicating if edge calculations such as
735/// derivates etc. can be performed
736pub trait EdgeComputable: HasAfEnum {}
737
738impl EdgeComputable for f64 {}
739impl EdgeComputable for f32 {}
740impl EdgeComputable for i32 {}
741impl EdgeComputable for u32 {}
742impl EdgeComputable for i16 {}
743impl EdgeComputable for u16 {}
744impl EdgeComputable for u8 {}
745
746/// Trait qualifier for given type indicating computability of covariance
747pub trait CovarianceComputable: HasAfEnum {}
748
749impl CovarianceComputable for f64 {}
750impl CovarianceComputable for f32 {}
751impl CovarianceComputable for i32 {}
752impl CovarianceComputable for u32 {}
753impl CovarianceComputable for i16 {}
754impl CovarianceComputable for u16 {}
755impl CovarianceComputable for u8 {}
756impl CovarianceComputable for u64 {}
757impl CovarianceComputable for i64 {}
758
759/// Trait qualifier for confidence connected components input
760pub trait ConfidenceCCInput: HasAfEnum {}
761
762impl ConfidenceCCInput for f32 {}
763impl ConfidenceCCInput for u32 {}
764impl ConfidenceCCInput for u16 {}
765impl ConfidenceCCInput for u8 {}
766
767/// Trait qualifier for confidence connected components input
768pub trait DeconvInput: HasAfEnum {}
769
770impl DeconvInput for f32 {}
771impl DeconvInput for i16 {}
772impl DeconvInput for u16 {}
773impl DeconvInput for u8 {}
774
775/// Trait qualifier for Reduction Key type
776pub trait ReduceByKeyInput: HasAfEnum {}
777
778impl ReduceByKeyInput for i32 {}
779impl ReduceByKeyInput for u32 {}
780
781impl From<u32> for MatProp {
782    fn from(t: u32) -> Self {
783        unsafe { mem::transmute(t) }
784    }
785}
786
787impl BitOr for MatProp {
788    type Output = Self;
789
790    fn bitor(self, rhs: Self) -> Self {
791        Self::from(self as u32 | rhs as u32)
792    }
793}
794
795/// Trait to convert reduction's scalar output to appropriate output type
796///
797/// This is an internal trait and ideally of no use to user usecases.
798pub trait Fromf64 {
799    /// Convert to target type from a double precision value
800    fn fromf64(value: f64) -> Self;
801}
802
803#[rustfmt::skip]
804impl Fromf64 for usize{ fn fromf64(value: f64) -> Self { value as Self }}
805#[rustfmt::skip]
806impl Fromf64 for f64  { fn fromf64(value: f64) -> Self { value as Self }}
807#[rustfmt::skip]
808impl Fromf64 for u64  { fn fromf64(value: f64) -> Self { value as Self }}
809#[rustfmt::skip]
810impl Fromf64 for i64  { fn fromf64(value: f64) -> Self { value as Self }}
811#[rustfmt::skip]
812impl Fromf64 for f32  { fn fromf64(value: f64) -> Self { value as Self }}
813#[rustfmt::skip]
814impl Fromf64 for u32  { fn fromf64(value: f64) -> Self { value as Self }}
815#[rustfmt::skip]
816impl Fromf64 for i32  { fn fromf64(value: f64) -> Self { value as Self }}
817#[rustfmt::skip]
818impl Fromf64 for u16  { fn fromf64(value: f64) -> Self { value as Self }}
819#[rustfmt::skip]
820impl Fromf64 for i16  { fn fromf64(value: f64) -> Self { value as Self }}
821#[rustfmt::skip]
822impl Fromf64 for u8   { fn fromf64(value: f64) -> Self { value as Self }}
823#[rustfmt::skip]
824impl Fromf64 for bool { fn fromf64(value: f64) -> Self { value > 0.0   }}
825
826///Trait qualifier for the type of Arrays accepted by scan operations
827pub trait IndexableType: HasAfEnum {}
828
829impl IndexableType for f64 {}
830impl IndexableType for i64 {}
831impl IndexableType for u64 {}
832impl IndexableType for f32 {}
833impl IndexableType for i32 {}
834impl IndexableType for u32 {}
835impl IndexableType for i16 {}
836impl IndexableType for u16 {}
837impl IndexableType for u8 {}
838
839/// Trait qualifier for given type indicating computability of covariance
840pub trait IntegralType {}
841
842impl IntegralType for i64 {}
843impl IntegralType for u64 {}
844impl IntegralType for i32 {}
845impl IntegralType for u32 {}
846impl IntegralType for i16 {}
847impl IntegralType for u16 {}
848impl IntegralType for u8 {}
849impl IntegralType for bool {}