EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  <20232024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  <20232024 
<== Date ==> <== Thread ==>

Subject: Re: Is it possible to know if current field is the last node of parent struct in PVXS
From: Michael Davidsaver via Tech-talk <tech-talk at aps.anl.gov>
To: "Wang, Lin" <wanglin at ihep.ac.cn>
Cc: tech-talk at aps.anl.gov
Date: Mon, 12 Jun 2023 08:05:22 -0700
On 6/8/23 06:53, Wang, Lin via Tech-talk wrote:
Dear all,

In PVXS, when iterating over the tree structure of pvxs::Value with the approach similar to top() method in the following link,

_https://github.com/mdavidsaver/pvxs/blob/master/src/datafmt.cpp_


is it possible to know if the current field is the last node of the parent struct with pvxs::impl::FieldDesc or pvxs::impl::FieldStorage?


For example, I am wondering how to check "message" field is the last node of struct "alarm_t" when iterating.

struct "alarm_t" {
     int32_t severity = 2
     int32_t status = 1
     string message = "HIHI"
} alarm

The interface for iterating through the fields of a structure in brief is:

Value top(...); // some TypeCode::Structure

for(Value child : top.ichildren()) { ... }

Which is shorthand for something equivalent to:

{
    Value::IChildren range(top.ichildren());
    for(Value::IChildren::iterator cur(range.begin()), end(range.end()); cur!=end; ++cur) { Value child(*cur); ... }
}

cf. https://en.cppreference.com/w/cpp/language/range-for

One way to accomplish what you are asking with c++ iterators generally would be to track
both the "current" and "next" items.

{
    Value::IChildren range(top.ichildren());
    for(Value::IChildren::iterator end(range.end()), next(range.begin()), cur(next!=end ? next++ : end);
        cur!=end;
        cur=next, next!=end ? ++next : end
    ) { if(next==end) printf("last!\n"); }
}

Also, this is the same pattern could be used to eg. allow safe removal of 'cur' while iterating
an std::list.

You may come across other variations on this pattern, some using a while loop
instead.  This is ~equivalent functionally, and imo. ~equally ugly.

{
    Value::IChildren range(top.ichildren());
    Value::IChildren::iterator end(range.end()), next(range.begin());
    while(next!=end) {
        Value::IChildren::iterator cur=next++;
        if(next==end) printf("last!\n");
    }
}


References:
Is it possible to know if current field is the last node of parent struct in PVXS Wang, Lin via Tech-talk

Navigate by Date:
Prev: RE: AreaDetector ADFFmpeg with FFmpeg 5.1 Daykin, Evan via Tech-talk
Next: Re: Optional record alias Ralph Lange via Tech-talk
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  <20232024 
Navigate by Thread:
Prev: Is it possible to know if current field is the last node of parent struct in PVXS Wang, Lin via Tech-talk
Next: PVA Gateway SegFault when pvcall (or eget) is used as a client Murray, Doug via Tech-talk
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  <20232024 
ANJ, 12 Jun 2023 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·