logo
Tags down

shadow

Iterator with multiple lifetimes


By : Farid Hattab
Date : July 29 2020, 07:08 AM
it fixes the issue Closures capture variables by reference unless the variable is consumed (moved) from within the closure.
Here, your closure captures query by reference, which means it stores a reference to a reference. &'c &'b str explicitly implements Pattern<'a>, so the closure doesn't need ownership of query.
code :
fn search<'a>(query: &'a str, text: &'a str) -> impl Iterator<Item=&'a str> {
   text.lines().filter(move |&line| line.contains(query))
}


Share : facebook icon twitter icon

Boost python container, iterator and item lifetimes


By : A Kumar
Date : March 29 2020, 07:55 AM
hop of those help? Ok, so after long digging I think I came up with solution that is transparent to exposed type.
Short description
code :
// This policy is used for methods returning items that require object to be
// kept as long as return thing is alive.
// It stores reference in attribute named Property_::name
template <typename Property_, class BasePolicy_ = boost::python::default_call_policies>
struct store_parent_reference: public BasePolicy_
{
    template <class ArgumentPackage>
    static PyObject* postcall(ArgumentPackage const& args_, PyObject* result)
    {
        result = BasePolicy_::postcall(args_, result);

        PyObject* parent = detail::get_prev< std::size_t(1) >::execute(args_, result);
        PyObject* child = result;

        if( PyObject_SetAttrString( child, Property_::name, parent ) == -1 )
        {
            std::ostringstream err;
            err << "store_parent_reference::postcall could not set attribute `"                    << Property_::name
                << "` on newly allocated object `"
                << extract<std::string>( object( handle<>(borrowed(child))).attr("__str__")() )()
                << "`";
            throw std::runtime_error(err.str());
        }



        return result;
    }
};


// This policy is used for methods returning "sibling" in the meaning both the returned object
// and one that has this method called on require "parent" object to be alive.
//
// It copies reference to "parent" to attribute named ChildProperty_::name
// from "original" object's attribute named SiblingProperty_::name
template <typename ChildProperty_, typename SiblingProperty_ = ChildProperty_, class BasePolicy_ = boost::python::default_call_policies>
struct copy_parent_from_sibling: public BasePolicy_
{
    template <class ArgumentPackage>
    static PyObject* postcall(ArgumentPackage const& args_, PyObject* result)
    {
        result = BasePolicy_::postcall(args_, result);

        PyObject* sibling = detail::get_prev< std::size_t(1) >::execute(args_, result);
        PyObject* new_child = result;

        PyObject* parent = PyObject_GetAttrString( sibling, SiblingProperty_::name );

        if( parent == NULL )
        {
            std::ostringstream err;
            err << "copy_parent_from_sibling::postcall could not get attribute `"
                << SiblingProperty_::name
                << "` from sibling `"
                << extract<std::string>( object( handle<>(borrowed(sibling))).attr("__str__")() )()
                << "` to set up attribute `"
                << ChildProperty_::name
                << "` of returned object which is `"
                << extract<std::string>( object( handle<>(borrowed(new_child))).attr("__str__")() )()
                << "`";
            throw std::runtime_error(err.str());
        }

        if( PyObject_SetAttrString( new_child, ChildProperty_::name, parent ) == -1 )
        {
            std::ostringstream err;
            err << "copy_parent_from_sibling::postcall could not set attribute `"
                << ChildProperty_::name
                << "` on returned object which is `"
                << extract<std::string>( object( handle<>(borrowed(new_child))).attr("__str__")() )()
                << "`";
            throw std::runtime_error(err.str());
        }

        Py_DECREF(parent);

        return result;
    }
};
struct ContainerProperty {
    static const char * const name;
};
const char * const ContainerProperty::name = "__container"

class_<Container>("Container", ...)
    .def("__iter__", &Container::__iter__, store_parent_reference< ContainerProperty >() )
;

class_<Iterator>("Iterator", ...)
    .def("next", &Iterator::__next__, copy_parent_from_sibling< ContainerProperty >() )
;

class_<Item>("Item", ...)
;

Need help understanding Iterator lifetimes


By : Henri Moreno Fernand
Date : March 29 2020, 07:55 AM
may help you . The definition of Index is:
code :
pub trait Index<Index: ?Sized> {
    type Output: ?Sized;
    /// The method for the indexing (`Foo[Bar]`) operation
    fn index<'a>(&'a self, index: &Index) -> &'a Self::Output;
}
<anon>:23:29: 23:40 error: cannot infer an appropriate lifetime for autoref due to conflicting requirements
<anon>:23             Some(self.items.index(&idx))
                                      ^~~~~~~~~~~
<anon>:17:5: 25:6 help: consider using an explicit lifetime parameter as shown: fn next(&'a mut self) -> Option<&'a <I as Index<uint>>::Output>
<anon>:17     fn next(&mut self) -> Option<&'a <I as Index<uint>>::Output> {
<anon>:18         if (self.current_idx >= self.len) {
<anon>:19             None
<anon>:20         } else {
<anon>:21             let idx = self.current_idx;
<anon>:22             self.current_idx += self.stride;
          ...
struct IndexablePair<T>  {
    x: T, y: T
}

impl Index<uint> for IndexablePair<T> {
    type Output = T;
    fn index(&self, index: &uint) -> &T {
        match *index {
            0 => &self.x,
            1 => &self.y,
            _ => panic!("out of bounds")
        }
    }
}
let pair = IndexablePair { x: "foo".to_string(), y: "bar".to_string() };

let mut stride = Stride::new(pair, 2, 1);

let value = stride.next();

// allocate some memory and move stride into, changing its address
let mut moved = box stride;

println!("value is {}", value);
pub struct Stride<'a, I: Index<uint> + 'a> {
    items: &'a I,
    len: uint,
    current_idx: uint,
    stride: uint,
}
use std::ops::Index;

#[derive(Clone)]
pub struct Stride<'a, I: Index<uint> + 'a> {
    items: &'a I,
    len: uint,
    current_idx: uint,
    stride: uint,
}

impl<'a, I> Iterator for Stride<'a, I> where I: Index<uint> {
    type Item = &'a <I as Index<uint>>::Output;

    #[inline]
    fn next(&mut self) -> Option<&'a <I as Index<uint>>::Output> {
        if (self.current_idx >= self.len) {
            None
        } else {
            let idx = self.current_idx;
            self.current_idx += self.stride;
            Some(self.items.index(&idx))
        }
    }
}

How to implement an iterator giving struct with lifetimes?


By : Matt
Date : March 29 2020, 07:55 AM
Any of those help You won't be able to get this to work with simple mutable references, unless you're OK with not implementing the standard Iterator trait. That's because it's not legal in Rust to have more than one usable mutable alias to a particular value at the same time (because it can lead to memory unsafety). Let's see why your code violates this restriction.
First, I can instantiate a FitnessIterMut object. From this object, I can call next to obtain a FitnessModifier. At this point, both the FitnessIterMut and the FitnessModifier contain a mutable reference to a RouletteWheel object, and both the FitnessIterMut and the FitnessModifier are still usable – that's not legal! I could call next again on the FitnessIterMut to obtain another FitnessModifier, and now I'd have 3 mutable aliases to the RouletteWheel.
code :
impl<'a, T> FitnessIterMut<'a, T> {
    fn next<'b>(&'b mut self) -> Option<FitnessModifier<'b, T>> {
        if let Some(value) = self.iterator.next() {
            Some(FitnessModifier { wheel: self.wheel, value: value })
        }
        else {
            None
        }
    }
}

Lifetimes for method returning iterator of structs with same lifetime


By : Alex
Date : March 29 2020, 07:55 AM
fixed the issue. Will look into that further When you have this kind of issue in a method, a good thing to do is to add an explicit lifetime to &self:
code :
pub fn neighbors(&'a self) -> impl Iterator<Item = Point<'a>> {
    [(0, -1), (-1, 0), (1, 0), (1, 0)]
        .iter().map(|(dx, dy)| Point {
            board: self.board,
            x: self.x + dx,
            y: self.y + dy,
        })
}
error[E0373]: closure may outlive the current function, but it borrows `self`, which is owned by the current function
  --> src/main.rs:14:30
   |
14 |             .iter().map(|(dx, dy)| Point {
   |                         ^^^^^^^^^^ may outlive borrowed value `self`
15 |                 board: self.board,
   |                        ---- `self` is borrowed here
help: to force the closure to take ownership of `self` (and any other referenced variables), use the `move` keyword
   |
14 |             .iter().map(move |(dx, dy)| Point {
   |                         ^^^^^^^^^^^^^^^
fn neighbors<'b>(&'b self) -> impl 'b + Iterator<Item = Point<'a>>

How can I return an impl Iterator that has multiple lifetimes?


By : user3310989
Date : March 29 2020, 07:55 AM
Hope this helps Lifetime parameters don't always represent the exact lifetime of an object (or of a borrow). Let's consider this example:
code :
fn main() {
    let a = 3;
    let b = 5;
    let c = min(&a, &b);
    println!("{:?}", c);
}

fn min<'a>(a: &'a i32, b: &'a i32) -> &'a i32 {
    if a < b {
        a
    } else {
        b
    }
}
struct Foo<'op, Input> {
    op: Box<dyn Fn(Input) -> i32 + 'op>,
}

impl<'op, Input> Foo<'op, Input> {
    fn new<Op>(op: Op) -> Foo<'op, Input>
    where
        Op: Fn(Input) -> i32 + 'op,
    {
        Foo { op: Box::new(op) }
    }

    fn apply<InputIter>(
        self,
        input_iter: InputIter,
    ) -> impl Iterator<Item = i32> + 'op
    where
        Input: 'op,
        InputIter: IntoIterator<Item = Input> + 'op,
    {
        input_iter.into_iter().map(move |input| (self.op)(input))
    }
}

fn main() {
    let y = 1;
    let foo = Foo::new(|x| x as i32 + y);

    let s = "abc".to_string();
    let sr: &str = &*s;
    let bar = sr.chars();

    let baz: Vec<_> = foo.apply(bar).collect();
    println!("{:?}", baz);
}
shadow
Privacy Policy - Terms - Contact Us © voile276.org