bfops
bfops

Reputation: 5688

Rust: Create an Iterator out of Default and Succ?

I have the following code in a repo:

impl<Id> IdAllocator<Id> where
  Id : Clone + Default + Add<u32, Id>,
{
  pub fn new() -> IdAllocator<Id> {
    IdAllocator {
      next: Default::default()
    }
  }

  // Produce an Id that hasn't been produced yet by this object.
  pub fn allocate(&mut self) -> Id {
    let ret = self.next.clone();
    self.next = self.next + 1;
    ret
  }
}

But it seems a little clumsy, especially since the Add instance is only used as a succ function (generating the next value in sequence). Is there some Succ class I can use? And if so, is there already some Iterator construction somewhere in the standard library that already does this Default+Succ pattern?

Thanks!

Upvotes: 1

Views: 165

Answers (1)

Vladimir Matveev
Vladimir Matveev

Reputation: 128131

No, unfortunately, there is no Succ-like thing in the standard library. The closest thing you can find is range() family of iterators, however, it uses Add and One numeric traits to generate items. You can do it this way (the idea is basically the same as yours, but this version is slightly more generic due to One trait usage):

use std::num::One;
use std::default::Default;

struct IdAllocator<T> {
    current: T
}

impl<T: Default> IdAllocator<T> {
    #[inline]
    pub fn new() -> IdAllocator<T> {
        IdAllocator {
            current: Default::default()
        }
    }
}

impl<T: Add<T, T>+One+Clone> Iterator<T> for IdAllocator<T> {
    fn next(&mut self) -> Option<T> {
        let next = self.current + One::one();
        self.current = next.clone();
        Some(next)
    }
}

fn main() {
    let a = IdAllocator::<uint>::new();
    for i in a.take(10) {
        println!("{}", i);
    }
}

(try it here)

Upvotes: 3

Related Questions