@@ -7,6 +7,8 @@ use seq::Seq;
7
7
use self :: libc:: { c_double, c_int, c_uint} ;
8
8
use util:: { AfArray , AfIndex , DimT , MutAfArray , MutAfIndex } ;
9
9
10
+ use std:: marker:: PhantomData ;
11
+
10
12
#[ allow( dead_code) ]
11
13
extern {
12
14
fn af_create_indexers ( indexers : MutAfIndex ) -> c_int ;
@@ -22,8 +24,60 @@ extern {
22
24
}
23
25
24
26
/// Struct to manage an array of resources of type `af_indexer_t`(ArrayFire C struct)
25
- pub struct Indexer {
27
+ ///
28
+ /// # Examples
29
+ ///
30
+ /// Given below are examples illustrating correct and incorrect usage of Indexer struct.
31
+ ///
32
+ /// <h3> Correct Usage </h3>
33
+ ///
34
+ /// ```rust
35
+ /// use arrayfire::{Array, Dim4, randu, index_gen, Indexer};
36
+ ///
37
+ /// // Always be aware of the fact that, the `Seq` or `Array` objects
38
+ /// // that we intend to use for indexing via `Indexer` have to outlive
39
+ /// // the `Indexer` object created in this context.
40
+ ///
41
+ /// let dims = Dim4::new(&[1, 3, 1, 1]);
42
+ /// let bools = Array::new(&[1, 0, 1], dims);
43
+ /// let values = Array::new(&[2, 5, 6], dims);
44
+ ///
45
+ /// let mut idxr = Indexer::new();
46
+ ///
47
+ /// // `bools` is created much before idxr, thus will
48
+ /// // stay in scope at least as long as idxr
49
+ /// idxr.set_index(&bools, 0, None);
50
+ ///
51
+ /// index_gen(&values, idxr);
52
+ /// ```
53
+ ///
54
+ /// <h3> Incorrect Usage </h3>
55
+ ///
56
+ /// ```rust,ignore
57
+ /// // Say, you create an Array on the fly and try
58
+ /// // to call set_index, it will throw the given below
59
+ /// // error or something similar to that
60
+ /// idxr.set_index(&Array::new(&[1, 0, 1], dims), 0, None);
61
+ /// ```
62
+ ///
63
+ /// ```text
64
+ /// error: borrowed value does not live long enough
65
+ /// --> <anon>:16:55
66
+ /// |
67
+ ///16 | idxr.set_index(&Array::new(&[1, 0, 1], dims), 0, None);
68
+ /// | ---------------------------- ^ temporary value dropped here while still borrowed
69
+ /// | |
70
+ /// | temporary value created here
71
+ ///...
72
+ ///19 | }
73
+ /// | - temporary value needs to live until here
74
+ /// |
75
+ /// = note: consider using a `let` binding to increase its lifetime
76
+ /// ```
77
+ pub struct Indexer < ' object > {
26
78
handle : i64 ,
79
+ count : usize ,
80
+ marker : PhantomData < & ' object ( ) > ,
27
81
}
28
82
29
83
// Trait that indicates that object can be used for indexing
@@ -42,7 +96,7 @@ impl Indexable for Array {
42
96
#[ allow( unused_variables) ]
43
97
fn set ( & self , idxr : & mut Indexer , dim : u32 , is_batch : Option < bool > ) {
44
98
unsafe {
45
- let err_val = af_set_array_indexer ( idxr. get ( ) as AfIndex , self . clone ( ) . get ( ) as AfArray ,
99
+ let err_val = af_set_array_indexer ( idxr. get ( ) as AfIndex , self . get ( ) as AfArray ,
46
100
dim as DimT ) ;
47
101
HANDLE_ERROR ( AfError :: from ( err_val) ) ;
48
102
}
@@ -64,21 +118,28 @@ impl<T: Copy> Indexable for Seq<T> where c_double: From<T> {
64
118
}
65
119
}
66
120
67
- impl Indexer {
121
+ impl < ' object > Indexer < ' object > {
68
122
#[ allow( unused_mut) ]
69
123
/// Create a new Indexer object and set the dimension specific index objects later
70
- pub fn new ( ) -> Indexer {
124
+ pub fn new ( ) -> Indexer < ' object > {
71
125
unsafe {
72
126
let mut temp: i64 = 0 ;
73
127
let err_val = af_create_indexers ( & mut temp as MutAfIndex ) ;
74
128
HANDLE_ERROR ( AfError :: from ( err_val) ) ;
75
- Indexer { handle : temp}
129
+ Indexer { handle : temp, count : 0 , marker : PhantomData }
76
130
}
77
131
}
78
132
79
133
/// Set either [Array](./struct.Array.html) or [Seq](./struct.Seq.html) to index an Array along `idx` dimension
80
- pub fn set_index < T : Indexable > ( & mut self , idx : & T , dim : u32 , is_batch : Option < bool > ) {
81
- idx. set ( self , dim, is_batch)
134
+ pub fn set_index < ' s , T > ( & ' s mut self , idx : & ' object T , dim : u32 , is_batch : Option < bool > )
135
+ where T : Indexable + ' object {
136
+ idx. set ( self , dim, is_batch) ;
137
+ self . count = self . count +1 ;
138
+ }
139
+
140
+ /// Get number of indexing objects set
141
+ pub fn len ( & self ) -> usize {
142
+ self . count
82
143
}
83
144
84
145
/// Get native(ArrayFire) resource handle
@@ -87,7 +148,7 @@ impl Indexer {
87
148
}
88
149
}
89
150
90
- impl Drop for Indexer {
151
+ impl < ' object > Drop for Indexer < ' object > {
91
152
fn drop ( & mut self ) {
92
153
unsafe {
93
154
let ret_val = af_release_indexers ( self . handle as AfIndex ) ;
@@ -328,7 +389,7 @@ pub fn index_gen(input: &Array, indices: Indexer) -> Array {
328
389
unsafe {
329
390
let mut temp: i64 = 0 ;
330
391
let err_val = af_index_gen ( & mut temp as MutAfArray , input. get ( ) as AfArray ,
331
- 4 , indices. get ( ) as AfIndex ) ;
392
+ indices . len ( ) as DimT , indices. get ( ) as AfIndex ) ;
332
393
HANDLE_ERROR ( AfError :: from ( err_val) ) ;
333
394
Array :: from ( temp)
334
395
}
@@ -370,7 +431,7 @@ pub fn assign_gen(lhs: &Array, indices: &Indexer, rhs: &Array) -> Array {
370
431
unsafe {
371
432
let mut temp: i64 = 0 ;
372
433
let err_val = af_assign_gen ( & mut temp as MutAfArray , lhs. get ( ) as AfArray ,
373
- 4 , indices. get ( ) as AfIndex ,
434
+ indices . len ( ) as DimT , indices. get ( ) as AfIndex ,
374
435
rhs. get ( ) as AfArray ) ;
375
436
HANDLE_ERROR ( AfError :: from ( err_val) ) ;
376
437
Array :: from ( temp)
0 commit comments