[xsd-users] sorting of a sequence of elements when IDs are contained, duplicate_id exception

Boris Kolpackov boris at codesynthesis.com
Mon Feb 16 08:03:03 EST 2009


Hi Jan,

Boris Kolpackov <boris at codesynthesis.com> writes:

> Hm, that's an interesting problem. I think you are right about what
> happens: std::sort() first inserts a new copy and then removes the
> old one. So you end up with two objects with the same ID in the tree.

Actually, there is another, bigger problem with this in that the
sequence contains polymorphic objects and _clone() should be used
instead of the copy constructor to copy them.

> (1) Implement your own sort where you first remove the old element
>     from the sequence and then insert the new one.

With this approach you should be able to use _clone() without any
problems.


> (2) Copy the contents of the sequence into another, "free-standing"
>     sequence which is not part of any object model. You can then sort
>     that sequence and copy the result back. There is quite a bit of
>     copying with this approach:
> 
>     TourSectionContainer tmp = tour->getTourSection();
>     std::sort(tmp.begin(), tmp.end(), compareTourSectionBySectionNumber);
>     tour->getTourSection() = tmp;

This approach will need to be modified slightly to work with 
polymorphic objects. Something along these lines:

bool compareTourSectionBySectionNumber (gml::FeaturePropertyType* sec1,
                                        gml::FeaturePropertyType* sec2)
{
  return
  (static_cast<TourSectionType*>(sec1->getFeature())->getSectionNo() <
  static_cast<TourSectionType*>(sec2->getFeature())->getSectionNo());
}

TourSectionContainer& tsc = tour->getTourSection();

// Copy polymorphically into a temporary sort vector.
//
typedef std::vector<gml::FeaturePropertyType*> SortVector;
SortVector tmp;
tmp.reserve (tsc.size ());

for (TourSectionIterator i (tsc.begin ()); i != tsc.end (); ++i)
{
  tmp.push_back (i._clone ());
}

// Sort.
//
std::sort(tmp.begin(), tmp.end(), compareTourSectionBySectionNumber);

// Copy back.
//
tsc.clear ();

for (SortVector::iterator i (tmp.begin ()); i != tmp.end (); ++i)
{
  tsc.push_back (std::auto_ptr<gml::FeaturePropertyType> (*i));
}

Boris




More information about the xsd-users mailing list