@@ -7,6 +7,8 @@ use seq::Seq;
77use self :: libc:: { c_double, c_int, c_uint} ;
88use util:: { AfArray , AfIndex , DimT , MutAfArray , MutAfIndex } ;
99
10+ use std:: marker:: PhantomData ;
11+
1012#[ allow( dead_code) ]
1113extern {
1214 fn af_create_indexers ( indexers : MutAfIndex ) -> c_int ;
@@ -22,8 +24,60 @@ extern {
2224}
2325
2426/// 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 > {
2678 handle : i64 ,
79+ count : usize ,
80+ marker : PhantomData < & ' object ( ) > ,
2781}
2882
2983// Trait that indicates that object can be used for indexing
@@ -42,7 +96,7 @@ impl Indexable for Array {
4296 #[ allow( unused_variables) ]
4397 fn set ( & self , idxr : & mut Indexer , dim : u32 , is_batch : Option < bool > ) {
4498 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 ,
46100 dim as DimT ) ;
47101 HANDLE_ERROR ( AfError :: from ( err_val) ) ;
48102 }
@@ -64,21 +118,28 @@ impl<T: Copy> Indexable for Seq<T> where c_double: From<T> {
64118 }
65119}
66120
67- impl Indexer {
121+ impl < ' object > Indexer < ' object > {
68122 #[ allow( unused_mut) ]
69123 /// Create a new Indexer object and set the dimension specific index objects later
70- pub fn new ( ) -> Indexer {
124+ pub fn new ( ) -> Indexer < ' object > {
71125 unsafe {
72126 let mut temp: i64 = 0 ;
73127 let err_val = af_create_indexers ( & mut temp as MutAfIndex ) ;
74128 HANDLE_ERROR ( AfError :: from ( err_val) ) ;
75- Indexer { handle : temp}
129+ Indexer { handle : temp, count : 0 , marker : PhantomData }
76130 }
77131 }
78132
79133 /// 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
82143 }
83144
84145 /// Get native(ArrayFire) resource handle
@@ -87,7 +148,7 @@ impl Indexer {
87148 }
88149}
89150
90- impl Drop for Indexer {
151+ impl < ' object > Drop for Indexer < ' object > {
91152 fn drop ( & mut self ) {
92153 unsafe {
93154 let ret_val = af_release_indexers ( self . handle as AfIndex ) ;
@@ -328,7 +389,7 @@ pub fn index_gen(input: &Array, indices: Indexer) -> Array {
328389 unsafe {
329390 let mut temp: i64 = 0 ;
330391 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 ) ;
332393 HANDLE_ERROR ( AfError :: from ( err_val) ) ;
333394 Array :: from ( temp)
334395 }
@@ -370,7 +431,7 @@ pub fn assign_gen(lhs: &Array, indices: &Indexer, rhs: &Array) -> Array {
370431 unsafe {
371432 let mut temp: i64 = 0 ;
372433 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 ,
374435 rhs. get ( ) as AfArray ) ;
375436 HANDLE_ERROR ( AfError :: from ( err_val) ) ;
376437 Array :: from ( temp)
0 commit comments