Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
C
capnproto
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
capnproto
Commits
5986724f
Commit
5986724f
authored
Apr 17, 2013
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update docs for unions. Also allow setters for void values to omit the parameter.
parent
0df5fb63
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
90 additions
and
14 deletions
+90
-14
test-util.c++
c++/src/capnproto/test-util.c++
+1
-0
CxxGenerator.hs
compiler/src/CxxGenerator.hs
+3
-0
c++-header.mustache
compiler/src/c++-header.mustache
+1
-1
page.html
doc/_layouts/page.html
+1
-1
cxx.md
doc/cxx.md
+71
-0
language.md
doc/language.md
+13
-12
No files found.
c++/src/capnproto/test-util.c++
View file @
5986724f
...
...
@@ -31,6 +31,7 @@ namespace {
template
<
typename
Builder
>
void
genericInitTestMessage
(
Builder
builder
)
{
builder
.
setVoidField
(
Void
::
VOID
);
builder
.
setVoidField
();
// Means the same as above.
builder
.
setBoolField
(
true
);
builder
.
setInt8Field
(
-
123
);
builder
.
setInt16Field
(
-
12345
);
...
...
compiler/src/CxxGenerator.hs
View file @
5986724f
...
...
@@ -236,6 +236,9 @@ fieldContext parent desc = mkStrContext context where
context
"fieldUnionDiscriminant"
=
case
fieldUnion
desc
of
Just
(
_
,
n
)
->
MuVariable
n
Nothing
->
muNull
context
"fieldSetterDefault"
=
case
fieldType
desc
of
BuiltinType
BuiltinVoid
->
MuVariable
" = ::capnproto::Void::VOID"
_
->
MuVariable
""
context
s
=
parent
s
unionContext
parent
desc
=
mkStrContext
context
where
...
...
compiler/src/c++-header.mustache
View file @
5986724f
...
...
@@ -233,7 +233,7 @@ inline {{fieldType}} {{typeFullName}}::Builder::get{{fieldTitleCase}}() {
return _builder.getDataField
<
{{
fieldType
}}
>
(
{{
fieldOffset
}}
* ::capnproto::ELEMENTS
{{
fieldDefaultMask
}}
);
}
inline void
{{
typeFullName
}}
::Builder::set
{{
fieldTitleCase
}}
(
{{
fieldType
}}
value) {
inline void
{{
typeFullName
}}
::Builder::set
{{
fieldTitleCase
}}
(
{{
fieldType
}}
value
{{
fieldSetterDefault
}}
) {
{{#
fieldUnion
}}
_builder.setDataField
<
{{
unionTitleCase
}}
::Which>
(
{{
unionTagOffset
}}
* ::capnproto::ELEMENTS,
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
);
...
...
doc/_layouts/page.html
View file @
5986724f
...
...
@@ -33,7 +33,7 @@
<ul>
<li><a
href=
"index.html"
>
Introduction
</a></li>
<li><a
href=
"install.html"
>
Installation
</a></li>
<li><a
href=
"language.html"
>
Defining Types
</a></li>
<li><a
href=
"language.html"
>
Schema Language
</a></li>
<li><a
href=
"encoding.html"
>
Encoding
</a></li>
<li><a
href=
"rpc.html"
>
RPC Protocol
</a></li>
<li><a
href=
"cxx.html"
>
C++ Runtime
</a></li>
...
...
doc/cxx.md
View file @
5986724f
...
...
@@ -16,6 +16,26 @@ struct Person {
id @0 :UInt32;
name @1 :Text;
email @2 :Text;
phones @3 :List(PhoneNumber);
struct PhoneNumber {
number @0 :Text;
type @1 :Type;
enum Type {
mobile @0;
home @1;
work @2;
}
}
employment @4 union {
unemployed @5 :Void;
employer @6 :Text;
school @7 :Text;
selfEmployed @8 :Void;
# We assume that a person is only one of these.
}
}
struct AddressBook {
...
...
@@ -29,6 +49,7 @@ You might write code like:
#include "addressbook.capnp.h"
#include <capnproto/message.h>
#include <capnproto/serialize-packed.h>
#include <iostream>
void writeAddressBook(int fd) {
::capnproto::MallocMessageBuilder message;
...
...
@@ -40,11 +61,23 @@ void writeAddressBook(int fd) {
alice.setId(123);
alice.setName("Alice");
alice.setEmail("alice@example.com");
// Type shown for explanation purposes; normally you'd use auto.
capnproto::List
<Person::PhoneNumber>
::Builder alicePhones =
alice.initPhones(1);
alicePhones
[
0
]
.setNumber("555-1212");
alicePhones
[
0
]
.setType(Person::PhoneNumber::Type::MOBILE);
alice.getEmployment().setSchool("MIT");
Person::Builder bob = people
[
1
]
;
bob.setId(456);
bob.setName("Bob");
bob.setEmail("bob@example.com");
auto bobPhones = bob.initPhones(2);
bobPhones
[
0
]
.setNumber("555-4567");
bobPhones
[
0
]
.setType(Person::PhoneNumber::Type::HOME);
bobPhones
[
1
]
.setNumber("555-7654");
bobPhones
[
1
]
.setType(Person::PhoneNumber::Type::WORK);
bob.getEmployment().setUnemployed();
writePackedMessageToFd(fd, message);
}
...
...
@@ -56,6 +89,33 @@ void printAddressBook(int fd) {
for (Person::Reader person : addressBook.getPeople()) {
std::cout << person.getName() << ": " << person.getEmail() << std::endl;
for (Person::PhoneNumber::Reader phone: person.getPhones()) {
const char
*
typeName = "UNKNOWN";
switch (phone.getType()) {
case Person::PhoneNumber::Type::MOBILE: typeName = "mobile"; break;
case Person::PhoneNumber::Type::HOME: typeName = "home"; break;
case Person::PhoneNumber::Type::WORK: typeName = "work"; break;
}
std::cout << " " << typeName << " phone: "
<< phone.getNumber() << std::endl;
}
Person::Employment::Reader employment = person.getEmployment();
switch (employment.which()) {
case Person::Employment::UNEMPLOYED:
std::cout << " unemployed" << std::endl;
break;
case Person::Employment::EMPLOYER:
std::cout << " employer: "
<< employment.getEmployer() << std::endl;
break;
case Person::Employment::SCHOOL:
std::cout << " student at: "
<< employment.getSchool() << std::endl;
break;
case Person::Employment::SELF_EMPLOYED:
std::cout << " self-employed" << std::endl;
break;
}
}
}
{% endhighlight %}
...
...
@@ -183,6 +243,17 @@ void setMyListField(::capnproto::List<double>::Reader value);
::capnproto::List
<double>
::Builder initMyListField(size_t size);
{% endhighlight %}
## Unions
For each union
`foo`
declared in the struct, the struct's reader and builder have a method
`getFoo()`
which returns a reader/builder for the union. The union reader/builder has accessors
for each field exactly like a struct's accessors. It also has an accessor
`which()`
which returns
an enum indicating which member of the union is currently set. Setting any member of the union
updates the value returned by
`which()`
. Getting a member other than the currently-set member
crashes in debug mode or returns garbage when
`NDEBUG`
is defined.
See the
[
example
](
#example_usage
)
at the top of the page for an example of unions.
## Lists
Lists are represented by the type
`capnproto::List<T>`
, where
`T`
is any of the primitive types,
...
...
doc/language.md
View file @
5986724f
...
...
@@ -135,23 +135,24 @@ union declarations do not look like types.
struct Person {
# ...
union employment @4;
unemployed @5 in employment :Void
;
employer @6 in employment :Company
;
school @7 in employment :School
;
selfEmployed @8 in employment :Void;
# We assume that a person is only one of these.
employment @4 union {
unemployed @5 :Void;
employer @6 :Company
;
school @7 :School
;
selfEmployed @8 :Void
;
# We assume that a person is only one of these.
}
}
{% endhighlight %}
Notes:
*
Unions are numbered in the same number space as other fields. Remember that the purpose of the
numbers is to indicate the evolution order of the struct. The system needs to know when the union
was declared relative to the fields in it. Also note that no more than one element of the union is
allowed to have a number less than the union's number, as unionizing two or more pre-existing
fields would change their layout.
*
Unions and their members are numbered in the same number space as fields of the containing
struct. Remember that the purpose of the numbers is to indicate the evolution order of the
struct. The system needs to know when the union and each of its members was declared relative to
the non-union fields. Also note that no more than one element of the union is allowed to have a
number less than the union's number, as unionizing two or more pre-existing fields would change
their layout.
*
Notice that we used the "useless"
`Void`
type here. We don't have any extra information to store
for the
`unemployed`
or
`selfEmployed`
cases, but we still want the union to distinguish these
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment