c++sequencecorbaomniorb

Easy way to append CORBA sequences using C++


I'm using omniORB and C++.

In my application i get few small CORBA sequences form different modules and then I need to combine them to one big sequence for further processing. Is there easy way do this? Something like seq2.append(seq1) or seq2.push_back(seq1). Or some operators? (I am really newbie in STL-things).

The only way I found is to manually go through every element of small sequences and add it to large sequence.

//idl
struct Device;
typedef sequence<Device> DevicesList;

//c++
icore::DevicesList full_list;
foreach (const DStatusList &stlist, states_) {
    icore::DevicesList list = convertList(stlist);
    int newlength = full_list.length() + list.length();
    int last_index = full_list.length();
    full_list.length(newlength);
    int j=0;
    for(int i=last_index; i< last_index+list.length(); i++,j++) {
        full_list[i] = list[j];
    }
}

Thank you.


Solution

  • It isn't too hard to make little utility functions for doing stuff like this. For example, you can make your own push_back for CORBA sequences:

    template<class Seq, class T>
    void push_back(Seq& seq, const T& item)
    {
       const CORBA::ULong len = seq.length();
       seq.length(len + 1);
       seq[len] = item;
    }
    
    MySequence s;
    push_back(s, 42);
    

    Just be aware that some ORB's sequence types don't over-allocate memory on push_back (like std::vector does), so this may trigger a reallocation and copying on every single push_back() call. This may be a performance problem. You'll have to check to see if your ORB does this or not, probably by looking at the source to know if it is a problem. Unfortunately I think omniORB has this problem; at least it did a few years ago.

    One way to mitigate this is to construct your sequences with maximum values (if you know it in advance). This will make one big allocation up front and you can then call push_back() up to that maximum without triggering a reallocation:

    MySequence s(100);   // construct with maximum; allocation happens here
    push_back(s, 42);    // no reallocation
    push_back(s, 0);     // no reallocation
    

    I also agree with stefaanv's advice in the comments. Use CORBA sequences as little as possible. Basically only use it "around the edges" of your application where you need to make / receive CORBA calls. Get the data into standard containers where it is more easily manipulated as soon as possible. Don't let the CORBA types "seep" into your application. This also helps to make your application more portable if you ever decide to port to a non-CORBA environment.

    I've also heard of a new IDL to C++11 mapping that is being proposed. This will map IDL sequences right onto std::vector which will make things considerably easier.