Is it possible to extend a tagged union with more variants in Cap'n proto while being binary-compatible with any old data? - capnproto

I'm looking into protocol schema languages, and it seems like Cap'n'proto will suit my needs, but there's one critical feature I need which I cannot find in the docs:
Let's say I have this tagged union with two struct members in C-like syntax:
struct taggedUnion {
int tag;
union {
struct a {
int x;
}
struct b {
float x;
}
}
}
Can I then in the future add another struct to the tagged union, while still being able to read the old data?
struct taggedUnion {
int tag;
union {
struct a {
int x;
}
struct b {
float y;
}
struct c {
int z;
bool b;
}
}
}
It feels like it should be doable, but I can't find anything in the docs saying that it is. There's a note on groups being extensible without breaking wire-compatibility (new fields are zeroed out for old data).
If it's possible, how would I declare this change in cap'n proto schema syntax? A before/after example would be great!

Found it. ... new fields may be added to existing groups and unions seems like it could be an answer to this question.

Related

Pointers to member as variadic template parameters

Is it possible to pass pointers-to-member as variadic template arguments. I can't seem to figure out the syntax.
for a function call it works like this:
struct A
{
int a;
float b;
}
template <typename ... TArgs> void f(A *obj, TArgs ... params)
{
void *members[] { (&(obj->*params))... };
// ... do something ...
}
That can be used like this:
f(obj, &A::a, &A::b);
I would like to pass params in a similar fashion to a class template
template <[something] ... params> class Foo
{
void Bar(A *obj)
{
void *members[] { (&(obj->*params))... };
// ... do something ...
}
};
That should be used like this:
Foo<&A::a, &A::b> foo;
foo.bar(obj);
I'm having trouble figuring out what [something] should be.
If member type is known and there is only one parameter, it can be done like this:
template <int A::*ptr> //...
Is there a way to generalize this for variadic parameter list of member pointers where members are of different unknown beforehand types?
Update: Variadic argument pack for member pointers of fixed known types is declared like so:
template<int A::*...ptr> struct Foo {};
Now I just need to replace int with typename that can be deduced.
And with C++17, following works perfectly:
template<auto A::*...ptr> struct Foo {};
Unfortunately I need a solution that will work with C++14
In C++14, you can use another level of indirection to do that:
struct A {
int a;
float b;
};
template<typename... T>
struct Bar {
template <T A::*... params>
struct Foo {
void Bar(A *obj) {
void *members[] { (&(obj->*params))... };
// ... do something ...
(void)members;
}
};
};
int main() {
A a;
Bar<int, float>::Foo<&A::a, &A::b> foo;
foo.Bar(&a);
}
auto keyword (introduced with the C++17 for non-type template parameters, as you mentioned) solves more or less this kind of issues. Think of std::integral_constant and how would it be more user-friendly if you hadn't to specify each time the type as the first argument...

how to access array of structure within a structure

struct students
{
char name[256];
int Roll_number;
};
struct colleges
{
char name[256];
Student students[100];
};
How to access student[0].name, I have tried to access using -> and . operator is is not accessable
Structure within Structure : Nested Structure
Structure written inside another structure is called as nesting of two structures.
Nested Structures are allowed in C Programming Language.
We can write one Structure inside another structure as member of another structure.
as member of another structure
#include <stdio.h>
struct students {
char name[256];
int Roll_number;
};
struct colleges {
char name[256];
struct students students[100];
};
int main(void)
{
struct colleges c = { };
printf("%s\n", c.students[0].name);
return 0;
}

Groups inside structs

Can I have groups inside a struct?
pseudo-code:
typedef struct {
input_group {
logic a;
}
output_group {
logic b;
}
} my_signals_list
Short answer: no.
If you want to have signals grouped like this, why not create a struct for the input group and a struct for your output group?
typedef struct {
logic a;
} input_group_s;
typedef struct {
logic b;
} output_group_s;
typedef struct {
input_group_s input_group;
output_group_s output_group;
} my_signals_list;
As Greg points out in the comments, you can also have nested struct definitions inside the main struct:
typedef struct {
struct { logic a; } input_group;
struct { logic b; } output_group;
} my_signals_list;
If you want to specify signals for a module in a nice encapsulated fashion, I would suggest using an interface, though.

Xcode struct help

So I am new to programming and even newer to Xcode. I am having trouble using a struct in Xcode. I have gotten to the point where I copied and pasted the code,
struct product {
int weight;
float price;
} ;
product apple;
from the c++ site, but when I try to declare the apple's weight via apple.weight = 5;
I get errors saying unknown type name 'apple' and expected unqualified Id at .
Simple: You have a structure, not a typedef structure.
You can use it as follows:
struct product {
int weight;
float price;
};
struct product apple;
void func() {
apple.weight = 12;
}
However, if you use a typedef, you can give your datatype an actual name:
typedef struct { .. } product;
product apple;
product apple;
apple.weight = 5;
This is valid code inside a function, but not at file scope.
Although at file scope you can initialize it like this:
product apple = { 5 };

Why does GCC not find my non-template function? ("no matching function for call to...")

In MSVC 2008, I have the following code:
class Foo {
// Be a little smarter about deriving the vertex type, to save the user some typing.
template<typename Vertex> inline void drawVertices(
Elements vCount, RenPrim primitiveType, PixMaterial *mtl, Vertex const *vertices)
{
this->drawVertices(vCount, primitiveType, mtl, vertices, Vertex::VertexType);
}
virtual void drawVertices(
Elements vCount,
RenPrim primitiveType,
PixMaterial *mtl,
void const *vertices,
uint vertexType) = 0;
};
I use it something like:
struct RenFlexibleVertexPc
{
enum { VertexType = RenVbufVertexComponentsPc };
float x;
float y;
float z;
GraVideoRgba8 c; // Video format, not external!
};
PixMaterial *material;
struct Pc : RenFlexibleVertexPc
{
void set(Triple t, uint cl) { x = (float)t.x_; y = (float)t.y_; z = (float)t.z_; c = cl; }
} vpc[4];
...
Foo *renderer;
renderer->drawVertices(4, RenPrimTriangleFan, material, vpc);
This works fine in MSVC 2008 SP1. However, GCC (3.4 and 4.1,2) throws a "no matching function for call to function" error, apparently not seeing the template when there is a non-template function with more arguments.
Is GCC broken, or is my code broken, and if so, why?
There is no problem with overloading or inheritance:
#include <iostream>
#include <memory>
namespace {
struct A {
virtual void f()
{
std::cout<<"inside A's f()\n";
}
template <typename T> void f(T t)
{
std::cout<<T::i<<'\t';
this->f();
}
};
struct B : A {
void f()
{
std::cout<<"hello\t";
A::f();
}
};
struct C {
static const unsigned int i = 5;
};
struct D {
enum { i = 6 };
};
}
int main()
{
std::auto_ptr<A> b(new B());
b->f(C());
b->f(D());
}
Works correctly. On the other hand, the smallest example I can find that exhibits your problem does not have inheritance or overloading:
#include <iostream>
namespace {
struct A {
template<class C> void print(C c)
{
c.print();
}
};
}
int main()
{
struct B {
void print()
{
std::cout << "whee!\n";
}
};
A a;
B b;
a.print(b);
}
Note that if struct B is defined in a namespace (whether it's an unnamed namespace, or a completely different namespace, or the global namespace) instead of inside main() that this compiles without error.
I don't know enough of the standard to say if this is a bug, but it appears to be one. I've gone ahead and reported it to the GCC bug database.
And here's your answer from the GCC developers (from the link above): "Local classes cannot be template arguments."
So the code is broken. Not that it's a bad idea. In fact, C++0x removes this restriction.
I noticed the line
Note that the code works in GCC if I explicitly cast vpc to (RenFlexibleVertexPc *)
And since RenFlexibleVertexPc is not a local class this makes sense. However Pc is a local class/struct, so it is not allowed.
#OP: Specifying the template parameter is a valid approach.
renderer->drawVertices<RenFlexibleVertexPc>(4, RenPrimTriangleFan, material, vpc);
With Pete's additions, you code also compiles on Apple's GCC 4.0.1, so I suspect there's something your posted code is missing that's causing the problem.
#Max: GCC's treatment of your source is standard. Struct B is local to main(), so B (and thus main()::B::print()) is not visible outside main(). As you're probably aware, moving the definition of B outside of main() and it will compile.
The definition of VertexType is already in the code (an enum). Elements is an unsigned long. Note that the code works in GCC if I explicitly cast vpc to (RenFlexibleVertexPc *)
If it's an enum why pass an object of type array 4 of struct? What is RenFlexibleVertexPc? The last argument to drawVertices should either be a constant pointer to a Vertex object or a const* to an object of a class derived from Vertex.
Foo *renderer;
renderer->drawVertices(4, RenPrimTriangleFan, material, vpc);
You are calling a function on an uninitialized pointer. I hope this is not the real code. \

Resources