Re: [rust-dev] Some help needed in Vector of enum conversion

2014-04-10 Thread Philippe Delrieu
I trying to do some polymorphism with trait and object and I have some 
problems.


At the beginning I want to store different types of object that 
implement the same trait (Base) in a Vec. To do this I use the enum 
pattern. If the enum contains only struct, I manage to iter the Vec for 
the different types.

code:
enum BaseImpl{
FirstThinkImpl(FirstThink),
SecondThinkImpl(SecondThink),
}

What I would like to do is to have a generic method to add like 
addMyBaseTrait( ~Base) to add all the struct that implement Base to the 
vector and to have a specific method that add a specific struct 
addSecondStruct(~SecondStruct). The enum is changed to:

enum BaseImpl{
FirstThinkImpl(~Base),
SecondThinkImpl(~SecondThink),
}

With this enum has have problem to iter the vector. I didn't find a way 
to iter all the vector and return Base or ~Base:

this code
impl'a Iterator'a ~Base for BaseItems'a {
fn next(mut self) - Option'a ~Base{
match self.iter.next() {
Some(ref baseimpl) = {
Some(match ***baseimpl{
FirstThinkImpl(ref first) = first,
SecondThinkImpl(ref second)= 'a (*second as ~Base),
})
},
None = None,
}
}
}
generate an error  borrowed value does not live long enough 
SecondThinkImpl(ref second)= 'a (*second as ~Base), which is logic so 
I try not to borrow with this code:


SecondThinkImpl(ref second)= second as 'a ~Base,

and I have the error non-scalar cast: `~SecondThink` as `'a 
~Baseno-bounds`

Perhaps there is no way. I didn't find any.
What I see with all my test is that a trait must be use as a reference 
to be stored but object reference can't be cast to a reference trait and 
trait can't be cast to an object. So it seems that tray is useful to 
pass or return parameters to method but not to store data.


Philippe


Le 09/04/2014 21:53, Philippe Delrieu a écrit :

I find a solution by removing the ~ to Base trait.
The code

//(First and Second think as defined earlier)


enum BaseImpl{
FirstThinkImpl(FirstThink),
SecondThinkImpl(SecondThink),
}


struct Container{
nodeList: Vec~BaseImpl,
}

impl'a Container{

fn iter_base('a self) - BaseItems'a {
   let iter = self.nodeList.iter();
   BaseItems{ iter : iter }
}

}


struct BaseItems'a {
iter : Items'a, ~BaseImpl
}

impl'a Iterator'a Base for BaseItems'a {
fn next(mut self) - Option'a Base{
match self.iter.next() {
Some(ref baseimpl) = {
Some(match ***baseimpl{
FirstThinkImpl(ref first) = first as 'a Base,
SecondThinkImpl(ref second)= second as 'a Base,
})
},
None = None,
}
}
}

Now it compile.

So I try to define a mutable iterator like the immuable and with 
similar code I have again the lifetime compile error :



struct BaseMutItems'a {
iter : MutItems'a, ~BaseImpl
}

impl'a Iterator'a mut Base for BaseMutItems'a {
fn next(mut self) - Option'a mut Base {
match self.iter.next() {
Some(ref mut baseimpl) = {
Some(match ***baseimpl{
FirstThinkImpl(ref mut first) = first as 'a mut 
Base,
SecondThinkImpl(ref mut second)= second as 'a 
mut Base,

})
},
None = None,
}
}
}

error :
test_enum.rs:125:36: 125:49 error: lifetime of `baseimpl` is too short 
to guarantee its contents can be safely reborrowed
test_enum.rs:125 FirstThinkImpl(ref mut first) = 
first as 'a mut Base,


I can't see what's going wrong.


I put all the code if someone want to test :

use std::iter::Iterator;
use std::slice::{Items, MutItems};

trait Base{
  fn set_something(mut self);
  fn isSecondThink(self) - bool;
}

struct FirstThink{
count1: int,
}

impl Base for FirstThink{
fn set_something(mut self){println!(ici First count:{:?}, 
self.count1); self.count1+=1;}

fn isSecondThink(self) - bool  {false}
}

struct SecondThink{
count2: int,
}

impl Base for SecondThink{
fn set_something(mut self){println!(ici Second count:{:?}, 
self.count2); self.count2+=1;}

fn isSecondThink(self) - bool  {true}
}

enum BaseImpl{
FirstThinkImpl(FirstThink),
SecondThinkImpl(SecondThink),
}

fn some_second_process(think: mut SecondThink){
think.set_something();
}

struct Container{
nodeList: Vec~BaseImpl,
}

impl'a Container{
fn add_FirstThink(mut self, think: FirstThink){
self.nodeList.push(~FirstThinkImpl(think));
}
fn add_SecondThink(mut self, think: SecondThink){
self.nodeList.push(~SecondThinkImpl(think));
}


fn iter_base('a self) - BaseItems'a {
   let iter = self.nodeList.iter();
   BaseItems{ iter : iter }
}

fn iter_second('a self) - SecondItems'a {
  

Re: [rust-dev] Some help needed in Vector of enum conversion

2014-04-09 Thread Philippe Delrieu

I find a solution by removing the ~ to Base trait.
The code

//(First and Second think as defined earlier)


enum BaseImpl{
FirstThinkImpl(FirstThink),
SecondThinkImpl(SecondThink),
}


struct Container{
nodeList: Vec~BaseImpl,
}

impl'a Container{

fn iter_base('a self) - BaseItems'a {
   let iter = self.nodeList.iter();
   BaseItems{ iter : iter }
}

}


struct BaseItems'a {
iter : Items'a, ~BaseImpl
}

impl'a Iterator'a Base for BaseItems'a {
fn next(mut self) - Option'a Base{
match self.iter.next() {
Some(ref baseimpl) = {
Some(match ***baseimpl{
FirstThinkImpl(ref first) = first as 'a Base,
SecondThinkImpl(ref second)= second as 'a Base,
})
},
None = None,
}
}
}

Now it compile.

So I try to define a mutable iterator like the immuable and with similar 
code I have again the lifetime compile error :



struct BaseMutItems'a {
iter : MutItems'a, ~BaseImpl
}

impl'a Iterator'a mut Base for BaseMutItems'a {
fn next(mut self) - Option'a mut Base {
match self.iter.next() {
Some(ref mut baseimpl) = {
Some(match ***baseimpl{
FirstThinkImpl(ref mut first) = first as 'a mut Base,
SecondThinkImpl(ref mut second)= second as 'a mut 
Base,

})
},
None = None,
}
}
}

error :
test_enum.rs:125:36: 125:49 error: lifetime of `baseimpl` is too short 
to guarantee its contents can be safely reborrowed
test_enum.rs:125 FirstThinkImpl(ref mut first) = 
first as 'a mut Base,


I can't see what's going wrong.


I put all the code if someone want to test :

use std::iter::Iterator;
use std::slice::{Items, MutItems};

trait Base{
  fn set_something(mut self);
  fn isSecondThink(self) - bool;
}

struct FirstThink{
count1: int,
}

impl Base for FirstThink{
fn set_something(mut self){println!(ici First count:{:?}, 
self.count1); self.count1+=1;}

fn isSecondThink(self) - bool  {false}
}

struct SecondThink{
count2: int,
}

impl Base for SecondThink{
fn set_something(mut self){println!(ici Second count:{:?}, 
self.count2); self.count2+=1;}

fn isSecondThink(self) - bool  {true}
}

enum BaseImpl{
FirstThinkImpl(FirstThink),
SecondThinkImpl(SecondThink),
}

fn some_second_process(think: mut SecondThink){
think.set_something();
}

struct Container{
nodeList: Vec~BaseImpl,
}

impl'a Container{
fn add_FirstThink(mut self, think: FirstThink){
self.nodeList.push(~FirstThinkImpl(think));
}
fn add_SecondThink(mut self, think: SecondThink){
self.nodeList.push(~SecondThinkImpl(think));
}


fn iter_base('a self) - BaseItems'a {
   let iter = self.nodeList.iter();
   BaseItems{ iter : iter }
}

fn iter_second('a self) - SecondItems'a {
   let iter = self.nodeList.iter();
   SecondItems{ iter : iter }
}

fn mut_iter_base('a mut self) - BaseMutItems'a {
   let iter = self.nodeList.mut_iter();
   BaseMutItems{ iter : iter }
}

fn appli_secondthink_someprocess(mut self, fct : fn (mut 
SecondThink))  {

for think in self.nodeList.mut_iter() {
match **think {
FirstThinkImpl(first) = println!(),
SecondThinkImpl(ref mut second)= fct(second),
}
}

}

}

struct BaseItems'a {
iter : Items'a, ~BaseImpl
}

impl'a Iterator'a Base for BaseItems'a {
fn next(mut self) - Option'a Base{
match self.iter.next() {
Some(ref baseimpl) = {
Some(match ***baseimpl{
FirstThinkImpl(ref first) = first as 'a Base,
SecondThinkImpl(ref second)= second as 'a Base,
})
},
None = None,
}
}
}


struct SecondItems'a {
iter : Items'a, ~BaseImpl
}

impl'a Iterator'a SecondThink for SecondItems'a {
fn next(mut self) - Option'a SecondThink{
match self.iter.next() {
Some(ref baseimpl) = {
match ***baseimpl{
FirstThinkImpl(ref first) = self.next(),
SecondThinkImpl(ref second)= Some(second),
}
},
None = None,
}
}
}


struct BaseMutItems'a {
iter : MutItems'a, ~BaseImpl
}

impl'a Iterator'a mut Base for BaseMutItems'a {
fn next(mut self) - Option'a mut Base {
match self.iter.next() {
Some(ref mut baseimpl) = {
Some(match ***baseimpl{
FirstThinkImpl(ref mut first) = first as 'a mut Base,
SecondThinkImpl(ref mut second)= second as 'a mut 
Base,

})
},
None = None,
}
}
}



#[main]

Re: [rust-dev] Some help needed in Vector of enum conversion

2014-04-07 Thread Rodrigo Rivas
On Sun, Apr 6, 2014 at 7:50 PM, Philippe Delrieu
philippe.delr...@free.fr wrote:
 I need some more help.

 The impl Iteratormut  ~Base for Container declaration generate the error:
 error: missing lifetime specifier
 So I had it but I can't manage to return the next value with the specified
 life time.
 The code :
 impl'a Iterator'a mut  ~Base for Container {
 /// Advance the iterator and return the next value. Return `None` when
 the end is reached.
 fn next(mut self) - Option'a mut ~Base{
 if self.iter_counter == self.nodeList.len()   {
 None
 } else  {
 self.iter_counter += 1;
 Some('a mut match **self.nodeList.get(self.iter_counter){
 FirstThinkImpl(first) = first as ~Base,
 SecondThinkImpl(second)= second as ~Base,
 })
 }
 }
 }

 Generate these errors :
 test_enum.rs:58:18: 61:14 error: borrowed value does not live long enough
 test/test_enum.rs:58 Some('a mut match

Oh, I think I may have misleaded you... You cannot implement the
iterator directly in Container, because the iterator must handle the
current position, while the Container just holds the values. You need
a intermediate struct that implements the Iterator traits. That's what
the `iter()` and ' move_iter()` functions do for vectors and other
standard containers. So you'll need something along the lines of this
(disclaimer: totally untested!!):

struct Container {
//
fn iter('a self) - BaseItems'a {
   let iter = nodeList.iter();
   BaseItems{ iter : iter }
}
}

struct BaseItems'a {
iter : Items'a, ~Base
}

impl'a Iterator'a mut  ~Base for BaseItems'a {
//
}

BTW, why all the double pointer in all the mut ~Base instead of
just mut Base?

-- 
Rodrigo
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Some help needed in Vector of enum conversion

2014-04-07 Thread Philippe Delrieu

Thanks for your help. I'll test ASAP.
I use the counter mutable var to have a simple implantation of the 
iterator to make the code works. Thank for you're example to show a 
better way. I was thinking of a similar way but I would like to avoid 
the specific struct with perhaps use a recursive call. I'll think about 
it later.


Le 07/04/2014 10:27, Rodrigo Rivas a écrit :

BTW, why all the double pointer in all the mut ~Base instead of
just mut Base?
For your question, I have mut ~Base because i didn't find a way to 
convert the mut ~Base to mut Base (or ~Base to Base) without copy.
I have the error error: mismatched types: expected 
`std::option::Option'a mut ~Baseno-bounds` but found 
`std::option::Optionmut ~Baseno-bounds`
I try  (error above), * error type `~Baseno-bounds` cannot be 
dereferenced. So I stop searching and try to make it works with ~Base.
The callback function is modifying the Vec instance. It's a method that 
update all the of the Vec element after an event occurs. I have to keep 
the reference to the Vec instance during the call. Perhaps there's a 
conception problem that I'll look later to remove most of the mut call 
but I try this type of call to learn who Rust works.


Perhaps you can help me for this part.

Philippe

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Some help needed in Vector of enum conversion

2014-04-07 Thread Philippe Delrieu

I try to implement the iterator like that:


struct BaseItems'a {
iter : Items'a, ~BaseImpl
}

impl'a Iterator'a ~Base for BaseItems'a {
fn next(mut self) - Option'a ~Base{
match self.iter.next() {
Some(ref baseimpl) = {
Some('a match ***baseimpl{
FirstThinkImpl(ref first) = *first as ~Base,
SecondThinkImpl(ref second)= *second as ~Base,
})
},
None = None,
}
}
}

But I have a lifetime problem. The error is : borrowed value does not 
live long enough and reference must be valid for the lifetime 'a  as 
defined on the block

and :
cannot move out of dereference of ``-pointer SecondThinkImpl(ref 
second)= *second as ~Base,


Another possibility:
fn next(mut self) - Option'a ~Base{
match self.iter.next() {
Some(ref baseimpl) = {
Some(match ***baseimpl{
FirstThinkImpl(ref first) = first as 'a ~Base,
SecondThinkImpl(ref second)= second as 'a ~Base,
})
},
None = None,
}
}
generate the error: non-scalar cast: `~FirstThink` as `'a 
~Baseno-bounds`


I try different possibility but I didn't find how to return a 'a 
lifetime ~Base or Base


I remove the mut to simplify the test of the different lifetime 
possibilities.


Philippe

Le 07/04/2014 10:27, Rodrigo Rivas a écrit :

On Sun, Apr 6, 2014 at 7:50 PM, Philippe Delrieu
philippe.delr...@free.fr wrote:

I need some more help.

The impl Iteratormut  ~Base for Container declaration generate the error:
error: missing lifetime specifier
So I had it but I can't manage to return the next value with the specified
life time.
The code :
impl'a Iterator'a mut  ~Base for Container {
 /// Advance the iterator and return the next value. Return `None` when
the end is reached.
 fn next(mut self) - Option'a mut ~Base{
 if self.iter_counter == self.nodeList.len()   {
 None
 } else  {
 self.iter_counter += 1;
 Some('a mut match **self.nodeList.get(self.iter_counter){
 FirstThinkImpl(first) = first as ~Base,
 SecondThinkImpl(second)= second as ~Base,
 })
 }
 }
}

Generate these errors :
test_enum.rs:58:18: 61:14 error: borrowed value does not live long enough
test/test_enum.rs:58 Some('a mut match

Oh, I think I may have misleaded you... You cannot implement the
iterator directly in Container, because the iterator must handle the
current position, while the Container just holds the values. You need
a intermediate struct that implements the Iterator traits. That's what
the `iter()` and ' move_iter()` functions do for vectors and other
standard containers. So you'll need something along the lines of this
(disclaimer: totally untested!!):

struct Container {
 //
 fn iter('a self) - BaseItems'a {
let iter = nodeList.iter();
BaseItems{ iter : iter }
 }
}

struct BaseItems'a {
 iter : Items'a, ~Base
}

impl'a Iterator'a mut  ~Base for BaseItems'a {
 //
}

BTW, why all the double pointer in all the mut ~Base instead of
just mut Base?



___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Some help needed in Vector of enum conversion

2014-04-06 Thread Philippe Delrieu

I need some more help.

The impl Iteratormut  ~Base for Container declaration generate the 
error:  error: missing lifetime specifier
So I had it but I can't manage to return the next value with the 
specified life time.

The code :
impl'a Iterator'a mut  ~Base for Container {
/// Advance the iterator and return the next value. Return `None` 
when the end is reached.

fn next(mut self) - Option'a mut ~Base{
if self.iter_counter == self.nodeList.len()   {
None
} else  {
self.iter_counter += 1;
Some('a mut match **self.nodeList.get(self.iter_counter){
FirstThinkImpl(first) = first as ~Base,
SecondThinkImpl(second)= second as ~Base,
})
}
}
}

Generate these errors :
test_enum.rs:58:18: 61:14 error: borrowed value does not live long enough
test/test_enum.rs:58 Some('a mut match 
**self.nodeList.get(self.iter_counter){
test/test_enum.rs:59 FirstThinkImpl(first) = first as 
~Base,

test_enum.rs:60 SecondThinkImpl(second)= second as ~Base,
test_enum.rs:61 })
test_enum.rs:53:52: 63:6 note: reference must be valid for the lifetime 
'a  as defined on the block at 53:51...

test_enum.rs:53 fn next(mut self) - Option'a mut ~Base{
test_enum.rs:54 if self.iter_counter == self.nodeList.len()   {
test/test_enum.rs:55 None
test_enum.rs:56 } else  {
test_enum.rs:57 self.iter_counter += 1;
test_enum.rs:58 Some('a mut match 
**self.nodeList.get(self.iter_counter){

...
test_enum.rs:56:17: 62:10 note: ...but borrowed value is only valid for 
the expression at 56:16

test_enum.rs:56 } else  {
test_enum.rs:57 self.iter_counter += 1;
test_enum.rs:58 Some('a mut match 
**self.nodeList.get(self.iter_counter){

test_enum.rs:59 FirstThinkImpl(first) = first as ~Base,
test_enum.rs:60 SecondThinkImpl(second)= second as ~Base,
test/test_enum.rs:61 })
...
test_enum.rs:59:17: 59:38 error: cannot move out of dereference of 
``-pointer

test_enum.rs:59 FirstThinkImpl(first) = first as ~Base,
^
test_enum.rs:60:17: 60:40 error: cannot move out of dereference of 
``-pointer

test_enum.rs:60 SecondThinkImpl(second)= second as ~Base,



Le 05/04/2014 21:59, Rodrigo Rivas a écrit :

On Fri, Apr 4, 2014 at 10:41 PM, Philippe Delrieu
philippe.delr...@free.fr wrote:

Hello,

I've some problem to find a solution for something I want to do with a
vector of enum. This is an example of what I want to do:

trait Base{
   fn set_something(mut self);
}

struct FirstThink;

impl Base for FirstThink{
   fn set_something(mut self){}
}

struct SecondThink;
impl Base for SecondThink{
   fn set_something(mut self){}
}

enum BaseImpl{
 FirstThinkImpl(~FirstThink),
 SecondThinkImpl(~SecondThink),
}

fn some_process(list: mut Vecmut ~Base){
 for think in list.mut_iter()   {
 think.set_something();
 }
}

struct Container{
 nodeList: Vec~BaseImpl,
}

impl Container{
 fn add_FirstThink(mut self, think: ~FirstThink){
 self.nodeList.push(~FirstThinkImpl(think));
 }
 fn add_SecondThink(mut self, think: ~SecondThink){
 self.nodeList.push(~SecondThinkImpl(think));
 }

 fn do_some_process(mut self, fct: fn(mut Vecmut ~Base)){
  I didn't find a simple  way to convert the Vec~BaseImpl to a mut
Vecmut ~Base
  to do the call
fct(self.nodeList);

 }
}

I use the enum pattern to have only one collection of object that impl Base
but sometime I have to do specific processing depending if the Base is a
FirstThink or SecondThink (not in the example). I use the match as follow

match think {
 FirstThinkImpl(first) = do specific first,
 SecondThinkImpl(second)= do specific second,
});

Perhaps there is a better way to do. Any suggestions would  be appreciated.

I think that would be better if the `fct` function take an
`std::iter::Iteratormut ~Base` instead of a `Vec`. Naturally, you
will not be able to modify the vector, only to iterate through it. But
if `fct` is allowed to modify the vector your requirements are
impossible in the first place!

Then you can write a simple adaptor:

impl std::iter::Iteratormut ~Base for Container {
 // left as an exercise to the reader ;-)
}



___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Some help needed in Vector of enum conversion

2014-04-05 Thread Rodrigo Rivas
On Fri, Apr 4, 2014 at 10:41 PM, Philippe Delrieu
philippe.delr...@free.fr wrote:
 Hello,

 I've some problem to find a solution for something I want to do with a
 vector of enum. This is an example of what I want to do:

 trait Base{
   fn set_something(mut self);
 }

 struct FirstThink;

 impl Base for FirstThink{
   fn set_something(mut self){}
 }

 struct SecondThink;
 impl Base for SecondThink{
   fn set_something(mut self){}
 }

 enum BaseImpl{
 FirstThinkImpl(~FirstThink),
 SecondThinkImpl(~SecondThink),
 }

 fn some_process(list: mut Vecmut ~Base){
 for think in list.mut_iter()   {
 think.set_something();
 }
 }

 struct Container{
 nodeList: Vec~BaseImpl,
 }

 impl Container{
 fn add_FirstThink(mut self, think: ~FirstThink){
 self.nodeList.push(~FirstThinkImpl(think));
 }
 fn add_SecondThink(mut self, think: ~SecondThink){
 self.nodeList.push(~SecondThinkImpl(think));
 }

 fn do_some_process(mut self, fct: fn(mut Vecmut ~Base)){
  I didn't find a simple  way to convert the Vec~BaseImpl to a mut
 Vecmut ~Base
  to do the call
fct(self.nodeList);

 }
 }

 I use the enum pattern to have only one collection of object that impl Base
 but sometime I have to do specific processing depending if the Base is a
 FirstThink or SecondThink (not in the example). I use the match as follow

 match think {
 FirstThinkImpl(first) = do specific first,
 SecondThinkImpl(second)= do specific second,
 });

 Perhaps there is a better way to do. Any suggestions would  be appreciated.

I think that would be better if the `fct` function take an
`std::iter::Iteratormut ~Base` instead of a `Vec`. Naturally, you
will not be able to modify the vector, only to iterate through it. But
if `fct` is allowed to modify the vector your requirements are
impossible in the first place!

Then you can write a simple adaptor:

impl std::iter::Iteratormut ~Base for Container {
// left as an exercise to the reader ;-)
}

-- 
Rodrigo
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Some help needed in Vector of enum conversion

2014-04-05 Thread Philippe Delrieu

Very good idea. The vector don't have to be modified so it'll work.

Thank you for the advice. I make a try an I'll post the result.

Philippe

Le 05/04/2014 21:59, Rodrigo Rivas a écrit :

On Fri, Apr 4, 2014 at 10:41 PM, Philippe Delrieu
philippe.delr...@free.fr wrote:

Hello,

I've some problem to find a solution for something I want to do with a
vector of enum. This is an example of what I want to do:

trait Base{
   fn set_something(mut self);
}

struct FirstThink;

impl Base for FirstThink{
   fn set_something(mut self){}
}

struct SecondThink;
impl Base for SecondThink{
   fn set_something(mut self){}
}

enum BaseImpl{
 FirstThinkImpl(~FirstThink),
 SecondThinkImpl(~SecondThink),
}

fn some_process(list: mut Vecmut ~Base){
 for think in list.mut_iter()   {
 think.set_something();
 }
}

struct Container{
 nodeList: Vec~BaseImpl,
}

impl Container{
 fn add_FirstThink(mut self, think: ~FirstThink){
 self.nodeList.push(~FirstThinkImpl(think));
 }
 fn add_SecondThink(mut self, think: ~SecondThink){
 self.nodeList.push(~SecondThinkImpl(think));
 }

 fn do_some_process(mut self, fct: fn(mut Vecmut ~Base)){
  I didn't find a simple  way to convert the Vec~BaseImpl to a mut
Vecmut ~Base
  to do the call
fct(self.nodeList);

 }
}

I use the enum pattern to have only one collection of object that impl Base
but sometime I have to do specific processing depending if the Base is a
FirstThink or SecondThink (not in the example). I use the match as follow

match think {
 FirstThinkImpl(first) = do specific first,
 SecondThinkImpl(second)= do specific second,
});

Perhaps there is a better way to do. Any suggestions would  be appreciated.

I think that would be better if the `fct` function take an
`std::iter::Iteratormut ~Base` instead of a `Vec`. Naturally, you
will not be able to modify the vector, only to iterate through it. But
if `fct` is allowed to modify the vector your requirements are
impossible in the first place!

Then you can write a simple adaptor:

impl std::iter::Iteratormut ~Base for Container {
 // left as an exercise to the reader ;-)
}



___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Some help needed in Vector of enum conversion

2014-04-04 Thread Philippe Delrieu

Hello,

I've some problem to find a solution for something I want to do with a 
vector of enum. This is an example of what I want to do:


trait Base{
  fn set_something(mut self);
}

struct FirstThink;

impl Base for FirstThink{
  fn set_something(mut self){}
}

struct SecondThink;
impl Base for SecondThink{
  fn set_something(mut self){}
}

enum BaseImpl{
FirstThinkImpl(~FirstThink),
SecondThinkImpl(~SecondThink),
}

fn some_process(list: mut Vecmut ~Base){
for think in list.mut_iter()   {
think.set_something();
}
}

struct Container{
nodeList: Vec~BaseImpl,
}

impl Container{
fn add_FirstThink(mut self, think: ~FirstThink){
self.nodeList.push(~FirstThinkImpl(think));
}
fn add_SecondThink(mut self, think: ~SecondThink){
self.nodeList.push(~SecondThinkImpl(think));
}

fn do_some_process(mut self, fct: fn(mut Vecmut ~Base)){
 I didn't find a simple  way to convert the Vec~BaseImpl to a 
mut Vecmut ~Base

 to do the call
   fct(self.nodeList);

}
}

I use the enum pattern to have only one collection of object that impl 
Base but sometime I have to do specific processing depending if the Base 
is a FirstThink or SecondThink (not in the example). I use the match as 
follow


match think {
FirstThinkImpl(first) = do specific first,
SecondThinkImpl(second)= do specific second,
});

Perhaps there is a better way to do. Any suggestions would  be appreciated.

Philippe


___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev