4

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.

uni
  • 539
  • 1
  • 9
  • 21
  • In my case i can just combine basic lists (not CORBA) and then convert result to CORBA list. But question asked to know other ways. Although sorry for bad English. – uni Jun 04 '13 at 09:57
  • 2
    I would advise using it that way: try to keep the CORBA-types for communication as much as possible and use std (or your own) containers for processing. – stefaanv Jun 04 '13 at 10:56
  • 1
    The new IDL to C++11l language mapping does use std containers instead of special CORBA types, see http://swsupport.remedy.nl for TAOX11, a CORBA implementation that supports this new mapping. – Johnny Willemsen Nov 01 '13 at 15:07

1 Answers1

6

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.

Brian Neal
  • 31,821
  • 7
  • 55
  • 59
  • 2
    It is correct that IDL to C++11 maps an IDL sequence to std::vector, something that makes it much easier to use. This IDL to C++11 mapping has been adopted and is formally published as OMG standard, see http://www.omg.org/spec/CPP11/. At the upcoming OMG Berling meeting we will present a V1.1 revision, you can find that online at http://www.omg.org/techprocess/meetings/schedule/IDL_to_C++11_1.1_RTF.html or see http://osportal.remedy.nl. The specification has been fully implemented already as part of our TAOX11 product, see http://www.theaceorb.nl – Johnny Willemsen Jun 04 '13 at 17:36