This is part of the Qpid Interop Test Suite, a test written for complex type interoperability.

AMQP allows arrays of arrays of differing types, I am wanting to test this using the different bindings against each other - this is what the QITS does.

In the case of the C++ binding, the default encoding for an AMQP array occurs when a container (std::vector, std::deque, etc.) is of a c++ type rather than using proton::value, which would cause the encoding to be an AMQP list.

Certainly I can see that the non-homogenous nature of the declaration is the issue, I just don't know how to get around it in a way that the Proton encoder will accept. I know there is a way to force a std::vector<proton::value> to be encoded as an array, but I don't know how to do that.

Kim


On 03/28/2018 11:49 AM, Chris Richardson wrote:
The short answer is "you can't", at least not along the lines you're
thinking. The std::vector type is a homogeneous container, see eg: this for
more info: https://isocpp.org/wiki/faq/containers#heterogeneous-containers

The upshot is that the elements of the vectors must have a common (base)
type, which clearly uint8_t and bool do not. The usual way to get around
this is exactly as you've outlined - to use some sort of variant-style
container such as the proton::value or boost::variant etc. The alternatives
(as mentioned in the above article) are almost too terrible to contemplate
and would involve lists of void pointers and risky reinterpret_casts
scattered through the code <shudder>.

In some situations it can be useful to use a tuple type, then you could
have some construct like
std::tuple<std::vector<uint8_t>, std::vector<bool>>
but if your list isn't of a fixed size known at compile-time (or
specifically needs to be a vector) this probably isn't what you're after
either.

Can you say more about what you're trying to do and why proton::value isn't
sufficient?

Chris



On 28 March 2018 at 15:45, Kim van der Riet <[email protected]> wrote:

By default, using std::vector<c++-type> is encoded as an AMQP array,
whereas std::vector<proton::value> is encoded as an AMQP list. So, to
create an array of lists of differing types, for example:

std::vector<proton::value> list1 = {uint8_t(0), uint8_t(1)};
std::vector<proton::value> list2 = {true, false};
std::vector<std::vector<proton::value> > array = {list1, list2};

works ok. However, how does one define an array of arrays of differing
types? For example:

std::vector<uint8_t> array1 = {uint8_t(0), uint8_t(1)};
std::vector<bool> array2 = {true, false};
std::vector<std::vector<##> > array3 = {array1, array2};

What is ##? Unless all the sub-arrays are of the same type, it is not
possible to define a single type here. If I use proton::value (which would
make it indistinguishable from the array of lists above), I get a compile
error:

could not convert '{array1, array2}' from '<brace-enclosed initializer
list' to 'std::vector<std::vector<proton::value> >'

What is the correct way to create an array of arrays of differing types?

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]





---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to