[xsde-users] find() in sequences

Boris Kolpackov boris at codesynthesis.com
Wed Oct 7 03:24:14 EDT 2009


Hi Duncan,

Duncan.Perrett at elekta.com <Duncan.Perrett at elekta.com> writes:

> class myClassA
> {
>         -- --
>   typedef ::xsde::cxx::hybrid::var_sequence< ::TxMessageType > 
> TxMessage_sequence;
>   typedef TxMessage_sequence::iterator TxMessage_iterator;
>   typedef TxMessage_sequence::const_iterator TxMessage_const_iterator;
> }
> 
> class TxMessageType
> {
>         - -
>   const ::std::string&
>   Name () const;
> 
>   ::std::string&
>   Name ();
> 
>   void
>   Name (const ::std::string&);
> }
> 
> 
> And I want to search the TxMessage sequence container for a particular 
> string returned by Name().
> 
> NodeType::TxMessage_iterator msgPosn = 
> find_if(nodeForMsg->TxMessage().begin(), nodeForMsg->TxMessage().end(),
>  not1(bind2nd(ptr_fun(strcmp),"ADC1_data_dia")));
> 
> This doesn't compile and I'm not sure why.

Two reasons. The first one has to to with XSD/e's lack of support for
fully-conforming STL iterators (that missing iterator_category member
that is reported in the error message). We didn't add it because it
requires working <iterator> headers and some of the targets that we
support don't have it or have a broken one. But there is no reason
why we can't support it conditionally which is what I implemented for 
the next release of XSD/e. The change is quite simple and I've
backported it to 3.1.0. To apply it, you can download this archive:

http://www.codesynthesis.com/~boris/tmp/xsde-3.1.0-stl-iterator.tar.gz

Then replace the files in xsde-3.1.0 with the ones in the archive
(maybe save your config first, if you've made any changes to it).
The new configuration parameter is XSDE_STL_ITERATOR. Finally, clean
('make clean') and rebuild ('make') the XSD/e runtime (libxsde). And
that's it.

If you try to compile the above code again with XSDE_STL_ITERATOR 
enabled, you will still get an error, though a different one. This
has to do with the predicate that you are passing to find_if. Right
now that predicate will result in a call like this:

strcmp (*i, "ADC1_data_dia");

Here 'i' is NodeType::TxMessage_iterator and '*i' is TxMessageType.
See the problem? What you actually need for the above call to work
is this:

strcmp (i->Name ().c_str (), "ADC1_data_dia");

I don't think there is a way to get this with the bind functionality
(you might be able to achieve this with Boost though). Instead, you 
will need to write your own predicate, something along these lines:


struct pred
{
  pred (const char* v): v_ (v) {}
  bool operator() (const TxMessageType& x) const {return x.Name () == v_;}
  const char* v_;
};

And then:

find_if(nodeForMsg->TxMessage().begin(), 
        nodeForMsg->TxMessage().end(),
        pred("ADC1_data_dia"));

Boris



More information about the xsde-users mailing list