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
e607fc95
Commit
e607fc95
authored
Jul 18, 2013
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow getting readers from const Orphans, and other tweaks.
parent
719eb094
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
165 additions
and
52 deletions
+165
-52
grammar.capnp
c++/src/capnp/compiler/grammar.capnp
+2
-6
parser.c++
c++/src/capnp/compiler/parser.c++
+12
-11
dynamic.c++
c++/src/capnp/dynamic.c++
+9
-0
dynamic.h
c++/src/capnp/dynamic.h
+4
-0
layout.c++
c++/src/capnp/layout.c++
+80
-15
layout.h
c++/src/capnp/layout.h
+7
-0
orphan-test.c++
c++/src/capnp/orphan-test.c++
+25
-18
orphan.h
c++/src/capnp/orphan.h
+21
-0
memory.h
c++/src/kj/memory.h
+3
-0
mutex.h
c++/src/kj/mutex.h
+2
-2
No files found.
c++/src/capnp/compiler/grammar.capnp
View file @
e607fc95
...
...
@@ -151,7 +151,7 @@ struct Declaration {
methodDecl @15 :Method;
annotationDecl @16 :Annotation;
nakedId @21 :
UInt64
;
nakedId @21 :
LocatedInteger
;
nakedAnnotation @22 :AnnotationApplication;
# A floating UID or annotation (allowed at the file top level).
}
...
...
@@ -221,9 +221,5 @@ struct Declaration {
}
struct ParsedFile {
id @0 :UInt64;
annotations @1 :List(Declaration.AnnotationApplication);
docComment @2 :Text;
topDecls @3 :List(Declaration);
root @0 :Declaration;
}
c++/src/capnp/compiler/parser.c++
View file @
e607fc95
...
...
@@ -44,7 +44,7 @@ uint64_t randomId() {
KJ_SYSCALL
(
n
=
read
(
fd
,
&
result
,
sizeof
(
result
)),
"/dev/urandom"
);
KJ_ASSERT
(
n
==
sizeof
(
result
),
"Incomplete read from /dev/urandom."
,
n
);
return
result
;
return
result
|
(
1ull
<<
63
)
;
}
}
// namespace
...
...
@@ -56,7 +56,7 @@ void parseFile(List<Statement>::Reader statements, ParsedFile::Builder result,
kj
::
Vector
<
Orphan
<
Declaration
>>
decls
(
statements
.
size
());
kj
::
Vector
<
Orphan
<
Declaration
::
AnnotationApplication
>>
annotations
;
bool
sawId
=
false
;
auto
fileDecl
=
result
.
getRoot
()
;
for
(
auto
statement
:
statements
)
{
KJ_IF_MAYBE
(
decl
,
parser
.
parseStatement
(
statement
,
parser
.
getParsers
().
fileLevelDecl
))
{
...
...
@@ -64,14 +64,13 @@ void parseFile(List<Statement>::Reader statements, ParsedFile::Builder result,
auto
body
=
builder
.
getBody
();
switch
(
body
.
which
())
{
case
Declaration
:
:
Body
::
NAKED_ID
:
if
(
sawId
)
{
if
(
fileDecl
.
getId
().
which
()
==
Declaration
::
Id
::
UID
)
{
errorReporter
.
addError
(
builder
.
getStartByte
(),
builder
.
getEndByte
(),
kj
::
str
(
"File can only have one ID."
));
}
else
{
sawId
=
true
;
result
.
setId
(
body
.
getNakedId
());
fileDecl
.
getId
().
adoptUid
(
body
.
disownNakedId
());
if
(
builder
.
hasDocComment
())
{
result
.
adoptDocComment
(
builder
.
disownDocComment
());
fileDecl
.
adoptDocComment
(
builder
.
disownDocComment
());
}
}
break
;
...
...
@@ -85,18 +84,20 @@ void parseFile(List<Statement>::Reader statements, ParsedFile::Builder result,
}
}
if
(
!
sawId
)
{
if
(
fileDecl
.
getId
().
which
()
!=
Declaration
::
Id
::
UID
)
{
uint64_t
id
=
randomId
();
fileDecl
.
getId
().
initUid
().
setValue
(
id
);
errorReporter
.
addError
(
0
,
0
,
kj
::
str
(
"File does not declare an ID. I've generated one for you. Add this line to your "
"file: @0x"
,
kj
::
hex
(
randomId
()
|
(
1ull
<<
63
)
),
";"
));
"file: @0x"
,
kj
::
hex
(
id
),
";"
));
}
auto
declsBuilder
=
result
.
initTop
Decls
(
decls
.
size
());
auto
declsBuilder
=
fileDecl
.
initNested
Decls
(
decls
.
size
());
for
(
size_t
i
=
0
;
i
<
decls
.
size
();
i
++
)
{
declsBuilder
.
adoptWithCaveats
(
i
,
kj
::
mv
(
decls
[
i
]));
}
auto
annotationsBuilder
=
result
.
initAnnotations
(
annotations
.
size
());
auto
annotationsBuilder
=
fileDecl
.
initAnnotations
(
annotations
.
size
());
for
(
size_t
i
=
0
;
i
<
annotations
.
size
();
i
++
)
{
annotationsBuilder
.
adoptWithCaveats
(
i
,
kj
::
mv
(
annotations
[
i
]));
}
...
...
@@ -817,7 +818,7 @@ CapnpParser::CapnpParser(Orphanage orphanageParam, ErrorReporter& errorReporterP
auto
&
nakedId
=
arena
.
copy
(
p
::
transform
(
parsers
.
uid
,
[
this
](
Orphan
<
LocatedInteger
>&&
value
)
->
DeclParserResult
{
auto
decl
=
orphanage
.
newOrphan
<
Declaration
>
();
decl
.
get
().
getBody
().
setNakedId
(
value
.
get
().
getValue
(
));
decl
.
get
().
getBody
().
adoptNakedId
(
kj
::
mv
(
value
));
return
DeclParserResult
(
kj
::
mv
(
decl
));
}));
...
...
c++/src/capnp/dynamic.c++
View file @
e607fc95
...
...
@@ -1578,6 +1578,10 @@ DynamicStruct::Builder Orphan<DynamicStruct>::get() {
return
DynamicStruct
::
Builder
(
schema
,
builder
.
asStruct
(
structSizeFromSchema
(
schema
)));
}
DynamicStruct
::
Reader
Orphan
<
DynamicStruct
>::
getReader
()
const
{
return
DynamicStruct
::
Reader
(
schema
,
builder
.
asStructReader
(
structSizeFromSchema
(
schema
)));
}
DynamicList
::
Builder
Orphan
<
DynamicList
>::
get
()
{
if
(
schema
.
whichElementType
()
==
schema
::
Type
::
Body
::
STRUCT_TYPE
)
{
return
DynamicList
::
Builder
(
...
...
@@ -1588,4 +1592,9 @@ DynamicList::Builder Orphan<DynamicList>::get() {
}
}
DynamicList
::
Reader
Orphan
<
DynamicList
>::
getReader
()
const
{
return
DynamicList
::
Reader
(
schema
,
builder
.
asListReader
(
elementSizeFor
(
schema
.
whichElementType
())));
}
}
// namespace capnp
c++/src/capnp/dynamic.h
View file @
e607fc95
...
...
@@ -306,6 +306,7 @@ private:
friend
kj
::
String
_
::
structString
(
_
::
StructReader
reader
,
const
_
::
RawSchema
&
schema
);
friend
class
Orphanage
;
friend
class
Orphan
<
DynamicStruct
>
;
};
class
DynamicStruct
::
Builder
{
...
...
@@ -456,6 +457,7 @@ private:
template
<
typename
T
,
::
capnp
::
Kind
k
>
friend
struct
::
capnp
::
ToDynamic_
;
friend
class
Orphanage
;
friend
class
Orphan
<
DynamicList
>
;
};
class
DynamicList
::
Builder
{
...
...
@@ -685,6 +687,7 @@ public:
Orphan
&
operator
=
(
Orphan
&&
)
=
default
;
DynamicStruct
::
Builder
get
();
DynamicStruct
::
Reader
getReader
()
const
;
inline
bool
operator
==
(
decltype
(
nullptr
))
{
return
builder
==
nullptr
;
}
inline
bool
operator
!=
(
decltype
(
nullptr
))
{
return
builder
==
nullptr
;
}
...
...
@@ -711,6 +714,7 @@ public:
Orphan
&
operator
=
(
Orphan
&&
)
=
default
;
DynamicList
::
Builder
get
();
DynamicList
::
Reader
getReader
()
const
;
inline
bool
operator
==
(
decltype
(
nullptr
))
{
return
builder
==
nullptr
;
}
inline
bool
operator
!=
(
decltype
(
nullptr
))
{
return
builder
==
nullptr
;
}
...
...
c++/src/capnp/layout.c++
View file @
e607fc95
...
...
@@ -192,6 +192,15 @@ static_assert(POINTERS * BYTES_PER_POINTER / BYTES == sizeof(WirePointer),
static_assert
(
POINTERS
*
BITS_PER_POINTER
/
BITS_PER_BYTE
/
BYTES
==
sizeof
(
WirePointer
),
"BITS_PER_POINTER is wrong."
);
namespace
{
static
const
union
{
AlignedData
<
POINTER_SIZE_IN_WORDS
/
WORDS
>
word
;
WirePointer
pointer
;
}
zero
=
{{{
0
}}};
}
// namespace
// =======================================================================================
struct
WireHelpers
{
...
...
@@ -285,10 +294,9 @@ struct WireHelpers {
}
}
static
KJ_ALWAYS_INLINE
(
const
word
*
followFars
(
const
WirePointer
*&
ref
,
SegmentReader
*&
segment
))
{
// Like the other followFars() but operates on readers. There is no `refTarget` parameter
// because `ref->target()` is valid for all use cases of this method.
static
KJ_ALWAYS_INLINE
(
const
word
*
followFars
(
const
WirePointer
*&
ref
,
const
word
*
refTarget
,
SegmentReader
*&
segment
))
{
// Like the other followFars() but operates on readers.
// If the segment is null, this is an unchecked message, so there are no FAR pointers.
if
(
segment
!=
nullptr
&&
ref
->
kind
()
==
WirePointer
::
FAR
)
{
...
...
@@ -325,7 +333,7 @@ struct WireHelpers {
return
segment
->
getStartPtr
()
+
pad
->
farPositionInSegment
();
}
else
{
return
ref
->
target
()
;
return
ref
Target
;
}
}
...
...
@@ -466,7 +474,7 @@ struct WireHelpers {
}
--
nestingLimit
;
const
word
*
ptr
=
followFars
(
ref
,
segment
);
const
word
*
ptr
=
followFars
(
ref
,
ref
->
target
(),
segment
);
WordCount64
result
=
0
*
WORDS
;
...
...
@@ -1559,6 +1567,12 @@ struct WireHelpers {
static
KJ_ALWAYS_INLINE
(
StructReader
readStructPointer
(
SegmentReader
*
segment
,
const
WirePointer
*
ref
,
const
word
*
defaultValue
,
int
nestingLimit
))
{
return
readStructPointer
(
segment
,
ref
,
ref
->
target
(),
defaultValue
,
nestingLimit
);
}
static
KJ_ALWAYS_INLINE
(
StructReader
readStructPointer
(
SegmentReader
*
segment
,
const
WirePointer
*
ref
,
const
word
*
refTarget
,
const
word
*
defaultValue
,
int
nestingLimit
))
{
if
(
ref
==
nullptr
||
ref
->
isNull
())
{
useDefault
:
if
(
defaultValue
==
nullptr
||
...
...
@@ -1567,6 +1581,7 @@ struct WireHelpers {
}
segment
=
nullptr
;
ref
=
reinterpret_cast
<
const
WirePointer
*>
(
defaultValue
);
refTarget
=
ref
->
target
();
defaultValue
=
nullptr
;
// If the default value is itself invalid, don't use it again.
}
...
...
@@ -1575,7 +1590,7 @@ struct WireHelpers {
goto
useDefault
;
}
const
word
*
ptr
=
followFars
(
ref
,
segment
);
const
word
*
ptr
=
followFars
(
ref
,
refTarget
,
segment
);
if
(
KJ_UNLIKELY
(
ptr
==
nullptr
))
{
// Already reported the error.
goto
useDefault
;
...
...
@@ -1601,6 +1616,13 @@ struct WireHelpers {
static
KJ_ALWAYS_INLINE
(
ListReader
readListPointer
(
SegmentReader
*
segment
,
const
WirePointer
*
ref
,
const
word
*
defaultValue
,
FieldSize
expectedElementSize
,
int
nestingLimit
))
{
return
readListPointer
(
segment
,
ref
,
ref
->
target
(),
defaultValue
,
expectedElementSize
,
nestingLimit
);
}
static
KJ_ALWAYS_INLINE
(
ListReader
readListPointer
(
SegmentReader
*
segment
,
const
WirePointer
*
ref
,
const
word
*
refTarget
,
const
word
*
defaultValue
,
FieldSize
expectedElementSize
,
int
nestingLimit
))
{
if
(
ref
==
nullptr
||
ref
->
isNull
())
{
useDefault
:
if
(
defaultValue
==
nullptr
||
...
...
@@ -1609,6 +1631,7 @@ struct WireHelpers {
}
segment
=
nullptr
;
ref
=
reinterpret_cast
<
const
WirePointer
*>
(
defaultValue
);
refTarget
=
ref
->
target
();
defaultValue
=
nullptr
;
// If the default value is itself invalid, don't use it again.
}
...
...
@@ -1617,7 +1640,7 @@ struct WireHelpers {
goto
useDefault
;
}
const
word
*
ptr
=
followFars
(
ref
,
segment
);
const
word
*
ptr
=
followFars
(
ref
,
refTarget
,
segment
);
if
(
KJ_UNLIKELY
(
ptr
==
nullptr
))
{
// Already reported error.
goto
useDefault
;
...
...
@@ -1743,12 +1766,18 @@ struct WireHelpers {
static
KJ_ALWAYS_INLINE
(
Text
::
Reader
readTextPointer
(
SegmentReader
*
segment
,
const
WirePointer
*
ref
,
const
void
*
defaultValue
,
ByteCount
defaultSize
))
{
return
readTextPointer
(
segment
,
ref
,
ref
->
target
(),
defaultValue
,
defaultSize
);
}
static
KJ_ALWAYS_INLINE
(
Text
::
Reader
readTextPointer
(
SegmentReader
*
segment
,
const
WirePointer
*
ref
,
const
word
*
refTarget
,
const
void
*
defaultValue
,
ByteCount
defaultSize
))
{
if
(
ref
==
nullptr
||
ref
->
isNull
())
{
useDefault
:
if
(
defaultValue
==
nullptr
)
defaultValue
=
""
;
return
Text
::
Reader
(
reinterpret_cast
<
const
char
*>
(
defaultValue
),
defaultSize
/
BYTES
);
}
else
{
const
word
*
ptr
=
followFars
(
ref
,
segment
);
const
word
*
ptr
=
followFars
(
ref
,
refTarget
,
segment
);
if
(
KJ_UNLIKELY
(
ptr
==
nullptr
))
{
// Already reported error.
...
...
@@ -1791,11 +1820,17 @@ struct WireHelpers {
static
KJ_ALWAYS_INLINE
(
Data
::
Reader
readDataPointer
(
SegmentReader
*
segment
,
const
WirePointer
*
ref
,
const
void
*
defaultValue
,
ByteCount
defaultSize
))
{
return
readDataPointer
(
segment
,
ref
,
ref
->
target
(),
defaultValue
,
defaultSize
);
}
static
KJ_ALWAYS_INLINE
(
Data
::
Reader
readDataPointer
(
SegmentReader
*
segment
,
const
WirePointer
*
ref
,
const
word
*
refTarget
,
const
void
*
defaultValue
,
ByteCount
defaultSize
))
{
if
(
ref
==
nullptr
||
ref
->
isNull
())
{
useDefault
:
return
Data
::
Reader
(
reinterpret_cast
<
const
byte
*>
(
defaultValue
),
defaultSize
/
BYTES
);
}
else
{
const
word
*
ptr
=
followFars
(
ref
,
segment
);
const
word
*
ptr
=
followFars
(
ref
,
refTarget
,
segment
);
if
(
KJ_UNLIKELY
(
ptr
==
nullptr
))
{
// Already reported error.
...
...
@@ -1827,6 +1862,12 @@ struct WireHelpers {
static
ObjectReader
readObjectPointer
(
SegmentReader
*
segment
,
const
WirePointer
*
ref
,
const
word
*
defaultValue
,
int
nestingLimit
)
{
return
readObjectPointer
(
segment
,
ref
,
ref
->
target
(),
defaultValue
,
nestingLimit
);
}
static
ObjectReader
readObjectPointer
(
SegmentReader
*
segment
,
const
WirePointer
*
ref
,
const
word
*
refTarget
,
const
word
*
defaultValue
,
int
nestingLimit
)
{
// We can't really reuse readStructPointer() and readListPointer() because they are designed
// for the case where we are expecting a specific type, and they do validation around that,
// whereas this method is for the case where we accept any pointer.
...
...
@@ -1842,10 +1883,11 @@ struct WireHelpers {
}
segment
=
nullptr
;
ref
=
reinterpret_cast
<
const
WirePointer
*>
(
defaultValue
);
refTarget
=
ref
->
target
();
defaultValue
=
nullptr
;
// If the default value is itself invalid, don't use it again.
}
const
word
*
ptr
=
WireHelpers
::
followFars
(
ref
,
segment
);
const
word
*
ptr
=
WireHelpers
::
followFars
(
ref
,
refTarget
,
segment
);
if
(
KJ_UNLIKELY
(
ptr
==
nullptr
))
{
// Already reported the error.
goto
useDefault
;
...
...
@@ -2111,13 +2153,13 @@ StructReader StructReader::readRoot(
StructReader
StructReader
::
getStructField
(
WirePointerCount
ptrIndex
,
const
word
*
defaultValue
)
const
{
const
WirePointer
*
ref
=
ptrIndex
>=
pointerCount
?
nullpt
r
:
pointers
+
ptrIndex
;
const
WirePointer
*
ref
=
ptrIndex
>=
pointerCount
?
&
zero
.
pointe
r
:
pointers
+
ptrIndex
;
return
WireHelpers
::
readStructPointer
(
segment
,
ref
,
defaultValue
,
nestingLimit
);
}
ListReader
StructReader
::
getListField
(
WirePointerCount
ptrIndex
,
FieldSize
expectedElementSize
,
const
word
*
defaultValue
)
const
{
const
WirePointer
*
ref
=
ptrIndex
>=
pointerCount
?
nullpt
r
:
pointers
+
ptrIndex
;
const
WirePointer
*
ref
=
ptrIndex
>=
pointerCount
?
&
zero
.
pointe
r
:
pointers
+
ptrIndex
;
return
WireHelpers
::
readListPointer
(
segment
,
ref
,
defaultValue
,
expectedElementSize
,
nestingLimit
);
}
...
...
@@ -2125,14 +2167,14 @@ ListReader StructReader::getListField(
template
<>
Text
::
Reader
StructReader
::
getBlobField
<
Text
>
(
WirePointerCount
ptrIndex
,
const
void
*
defaultValue
,
ByteCount
defaultSize
)
const
{
const
WirePointer
*
ref
=
ptrIndex
>=
pointerCount
?
nullpt
r
:
pointers
+
ptrIndex
;
const
WirePointer
*
ref
=
ptrIndex
>=
pointerCount
?
&
zero
.
pointe
r
:
pointers
+
ptrIndex
;
return
WireHelpers
::
readTextPointer
(
segment
,
ref
,
defaultValue
,
defaultSize
);
}
template
<>
Data
::
Reader
StructReader
::
getBlobField
<
Data
>
(
WirePointerCount
ptrIndex
,
const
void
*
defaultValue
,
ByteCount
defaultSize
)
const
{
const
WirePointer
*
ref
=
ptrIndex
>=
pointerCount
?
nullpt
r
:
pointers
+
ptrIndex
;
const
WirePointer
*
ref
=
ptrIndex
>=
pointerCount
?
&
zero
.
pointe
r
:
pointers
+
ptrIndex
;
return
WireHelpers
::
readDataPointer
(
segment
,
ref
,
defaultValue
,
defaultSize
);
}
...
...
@@ -2607,6 +2649,29 @@ ObjectBuilder OrphanBuilder::asObject() {
return
result
;
}
StructReader
OrphanBuilder
::
asStructReader
(
StructSize
size
)
const
{
return
WireHelpers
::
readStructPointer
(
segment
,
tagAsPtr
(),
location
,
nullptr
,
std
::
numeric_limits
<
int
>::
max
());
}
ListReader
OrphanBuilder
::
asListReader
(
FieldSize
elementSize
)
const
{
return
WireHelpers
::
readListPointer
(
segment
,
tagAsPtr
(),
location
,
nullptr
,
elementSize
,
std
::
numeric_limits
<
int
>::
max
());
}
Text
::
Reader
OrphanBuilder
::
asTextReader
()
const
{
return
WireHelpers
::
readTextPointer
(
segment
,
tagAsPtr
(),
location
,
nullptr
,
0
*
BYTES
);
}
Data
::
Reader
OrphanBuilder
::
asDataReader
()
const
{
return
WireHelpers
::
readDataPointer
(
segment
,
tagAsPtr
(),
location
,
nullptr
,
0
*
BYTES
);
}
ObjectReader
OrphanBuilder
::
asObjectReader
()
const
{
return
WireHelpers
::
readObjectPointer
(
segment
,
tagAsPtr
(),
location
,
nullptr
,
std
::
numeric_limits
<
int
>::
max
());
}
void
OrphanBuilder
::
euthanize
()
{
WireHelpers
::
zeroObject
(
segment
,
reinterpret_cast
<
WirePointer
*>
(
&
tag
),
location
);
memset
(
&
tag
,
0
,
sizeof
(
tag
));
// Use memset to comply with aliasing rules.
...
...
c++/src/capnp/layout.h
View file @
e607fc95
...
...
@@ -758,6 +758,12 @@ public:
ObjectBuilder
asObject
();
// Interpret as an arbitrary object.
StructReader
asStructReader
(
StructSize
size
)
const
;
ListReader
asListReader
(
FieldSize
elementSize
)
const
;
Text
::
Reader
asTextReader
()
const
;
Data
::
Reader
asDataReader
()
const
;
ObjectReader
asObjectReader
()
const
;
private
:
static_assert
(
1
*
POINTERS
*
WORDS_PER_POINTER
==
1
*
WORDS
,
"This struct assumes a pointer is one word."
);
...
...
@@ -783,6 +789,7 @@ private:
}
inline
WirePointer
*
tagAsPtr
()
{
return
reinterpret_cast
<
WirePointer
*>
(
&
tag
);
}
inline
const
WirePointer
*
tagAsPtr
()
const
{
return
reinterpret_cast
<
const
WirePointer
*>
(
&
tag
);
}
void
euthanize
();
// Erase the target object, zeroing it out and possibly reclaiming the memory. Called when
...
...
c++/src/capnp/orphan-test.c++
View file @
e607fc95
...
...
@@ -40,7 +40,8 @@ TEST(Orphans, Structs) {
Orphan
<
TestAllTypes
>
orphan
=
root
.
disownStructField
();
EXPECT_FALSE
(
orphan
==
nullptr
);
checkTestMessage
(
orphan
.
get
().
asReader
());
checkTestMessage
(
orphan
.
getReader
());
checkTestMessage
(
orphan
.
get
());
EXPECT_FALSE
(
root
.
hasStructField
());
root
.
adoptStructField
(
kj
::
mv
(
orphan
));
...
...
@@ -59,7 +60,8 @@ TEST(Orphans, Lists) {
Orphan
<
List
<
uint32_t
>>
orphan
=
root
.
disownUInt32List
();
EXPECT_FALSE
(
orphan
==
nullptr
);
checkList
(
orphan
.
get
().
asReader
(),
{
12u
,
34u
,
56u
});
checkList
(
orphan
.
getReader
(),
{
12u
,
34u
,
56u
});
checkList
(
orphan
.
get
(),
{
12u
,
34u
,
56u
});
EXPECT_FALSE
(
root
.
hasUInt32List
());
root
.
adoptUInt32List
(
kj
::
mv
(
orphan
));
...
...
@@ -80,6 +82,9 @@ TEST(Orphans, StructLists) {
Orphan
<
List
<
TestAllTypes
>>
orphan
=
root
.
disownStructList
();
EXPECT_FALSE
(
orphan
==
nullptr
);
ASSERT_EQ
(
2u
,
orphan
.
getReader
().
size
());
EXPECT_EQ
(
"foo"
,
orphan
.
getReader
()[
0
].
getTextField
());
EXPECT_EQ
(
"bar"
,
orphan
.
getReader
()[
1
].
getTextField
());
ASSERT_EQ
(
2u
,
orphan
.
get
().
size
());
EXPECT_EQ
(
"foo"
,
orphan
.
get
()[
0
].
getTextField
());
EXPECT_EQ
(
"bar"
,
orphan
.
get
()[
1
].
getTextField
());
...
...
@@ -103,6 +108,7 @@ TEST(Orphans, Text) {
Orphan
<
Text
>
orphan
=
root
.
disownTextField
();
EXPECT_FALSE
(
orphan
==
nullptr
);
EXPECT_EQ
(
"foo"
,
orphan
.
getReader
());
EXPECT_EQ
(
"foo"
,
orphan
.
get
());
EXPECT_FALSE
(
root
.
hasTextField
());
...
...
@@ -122,6 +128,7 @@ TEST(Orphans, Data) {
Orphan
<
Data
>
orphan
=
root
.
disownDataField
();
EXPECT_FALSE
(
orphan
==
nullptr
);
EXPECT_EQ
(
data
(
"foo"
),
orphan
.
getReader
());
EXPECT_EQ
(
data
(
"foo"
),
orphan
.
get
());
EXPECT_FALSE
(
root
.
hasDataField
());
...
...
@@ -155,7 +162,7 @@ TEST(Orphans, OrphanageStruct) {
Orphan
<
TestAllTypes
>
orphan
=
builder
.
getOrphanage
().
newOrphan
<
TestAllTypes
>
();
initTestMessage
(
orphan
.
get
());
checkTestMessage
(
orphan
.
get
().
as
Reader
());
checkTestMessage
(
orphan
.
getReader
());
auto
root
=
builder
.
initRoot
<
TestAllTypes
>
();
root
.
adoptStructField
(
kj
::
mv
(
orphan
));
...
...
@@ -168,7 +175,7 @@ TEST(Orphans, OrphanageList) {
orphan
.
get
().
set
(
0
,
123
);
orphan
.
get
().
set
(
1
,
456
);
List
<
uint32_t
>::
Reader
reader
=
orphan
.
get
().
as
Reader
();
List
<
uint32_t
>::
Reader
reader
=
orphan
.
getReader
();
ASSERT_EQ
(
2u
,
reader
.
size
());
EXPECT_EQ
(
123u
,
reader
[
0
]);
EXPECT_EQ
(
456u
,
reader
[
1
]);
...
...
@@ -212,7 +219,7 @@ TEST(Orphans, OrphanageStructCopy) {
initTestMessage
(
root1
);
Orphan
<
TestAllTypes
>
orphan
=
builder2
.
getOrphanage
().
newOrphanCopy
(
root1
.
asReader
());
checkTestMessage
(
orphan
.
get
().
as
Reader
());
checkTestMessage
(
orphan
.
getReader
());
auto
root2
=
builder2
.
initRoot
<
TestAllTypes
>
();
root2
.
adoptStructField
(
kj
::
mv
(
orphan
));
...
...
@@ -227,7 +234,7 @@ TEST(Orphans, OrphanageListCopy) {
Orphan
<
List
<
uint32_t
>>
orphan
=
builder2
.
getOrphanage
().
newOrphanCopy
(
root1
.
asReader
().
getUInt32List
());
checkList
(
orphan
.
get
().
as
Reader
(),
{
12u
,
34u
,
56u
});
checkList
(
orphan
.
getReader
(),
{
12u
,
34u
,
56u
});
auto
root2
=
builder2
.
initRoot
<
TestAllTypes
>
();
root2
.
adoptUInt32List
(
kj
::
mv
(
orphan
));
...
...
@@ -237,7 +244,7 @@ TEST(Orphans, OrphanageTextCopy) {
MallocMessageBuilder
builder
;
Orphan
<
Text
>
orphan
=
builder
.
getOrphanage
().
newOrphanCopy
(
Text
::
Reader
(
"foobarba"
));
EXPECT_EQ
(
"foobarba"
,
orphan
.
get
().
as
Reader
());
EXPECT_EQ
(
"foobarba"
,
orphan
.
getReader
());
auto
root
=
builder
.
initRoot
<
TestAllTypes
>
();
root
.
adoptTextField
(
kj
::
mv
(
orphan
));
...
...
@@ -247,7 +254,7 @@ TEST(Orphans, OrphanageDataCopy) {
MallocMessageBuilder
builder
;
Orphan
<
Data
>
orphan
=
builder
.
getOrphanage
().
newOrphanCopy
(
data
(
"foo"
));
EXPECT_EQ
(
data
(
"foo"
),
orphan
.
get
().
as
Reader
());
EXPECT_EQ
(
data
(
"foo"
),
orphan
.
getReader
());
auto
root
=
builder
.
initRoot
<
TestAllTypes
>
();
root
.
adoptDataField
(
kj
::
mv
(
orphan
));
...
...
@@ -259,9 +266,9 @@ TEST(Orphans, ZeroOut) {
{
Orphan
<
TestAllTypes
>
orphan
=
builder
.
getOrphanage
().
newOrphan
<
TestAllTypes
>
();
orphanReader
=
orphan
.
get
().
as
Reader
();
orphanReader
=
orphan
.
getReader
();
initTestMessage
(
orphan
.
get
());
checkTestMessage
(
orphan
.
get
().
as
Reader
());
checkTestMessage
(
orphan
.
getReader
());
}
// Once the Orphan destructor is called, the message should be zero'd out.
...
...
@@ -278,7 +285,7 @@ TEST(Orphans, StructObject) {
Orphan
<
TestAllTypes
>
orphan
=
root
.
disownObjectField
<
TestAllTypes
>
();
EXPECT_FALSE
(
orphan
==
nullptr
);
checkTestMessage
(
orphan
.
get
().
as
Reader
());
checkTestMessage
(
orphan
.
getReader
());
EXPECT_FALSE
(
root
.
hasObjectField
());
root
.
adoptObjectField
(
kj
::
mv
(
orphan
));
...
...
@@ -297,7 +304,7 @@ TEST(Orphans, ListObject) {
Orphan
<
List
<
uint32_t
>>
orphan
=
root
.
disownObjectField
<
List
<
uint32_t
>>
();
EXPECT_FALSE
(
orphan
==
nullptr
);
checkList
(
orphan
.
get
().
as
Reader
(),
{
12u
,
34u
,
56u
});
checkList
(
orphan
.
getReader
(),
{
12u
,
34u
,
56u
});
EXPECT_FALSE
(
root
.
hasObjectField
());
root
.
adoptObjectField
(
kj
::
mv
(
orphan
));
...
...
@@ -318,7 +325,7 @@ TEST(Orphans, DynamicStruct) {
EXPECT_FALSE
(
orphan
==
nullptr
);
EXPECT_TRUE
(
orphan
.
get
().
getSchema
()
==
Schema
::
from
<
TestAllTypes
>
());
checkDynamicTestMessage
(
orphan
.
get
().
as
Reader
());
checkDynamicTestMessage
(
orphan
.
getReader
());
EXPECT_FALSE
(
root
.
hasObjectField
());
root
.
adoptObjectField
(
kj
::
mv
(
orphan
));
...
...
@@ -337,7 +344,7 @@ TEST(Orphans, DynamicList) {
Orphan
<
DynamicList
>
orphan
=
root
.
disownObjectField
<
DynamicList
>
(
Schema
::
from
<
List
<
uint32_t
>>
());
EXPECT_FALSE
(
orphan
==
nullptr
);
checkList
<
uint32_t
>
(
orphan
.
get
().
as
Reader
(),
{
12
,
34
,
56
});
checkList
<
uint32_t
>
(
orphan
.
getReader
(),
{
12
,
34
,
56
});
EXPECT_FALSE
(
root
.
hasObjectField
());
root
.
adoptObjectField
(
kj
::
mv
(
orphan
));
...
...
@@ -377,7 +384,7 @@ TEST(Orphans, OrphanageDynamicStruct) {
Orphan
<
DynamicStruct
>
orphan
=
builder
.
getOrphanage
().
newOrphan
(
Schema
::
from
<
TestAllTypes
>
());
initDynamicTestMessage
(
orphan
.
get
());
checkDynamicTestMessage
(
orphan
.
get
().
as
Reader
());
checkDynamicTestMessage
(
orphan
.
getReader
());
auto
root
=
builder
.
initRoot
<
test
::
TestObject
>
();
root
.
adoptObjectField
(
kj
::
mv
(
orphan
));
...
...
@@ -391,7 +398,7 @@ TEST(Orphans, OrphanageDynamicList) {
orphan
.
get
().
set
(
0
,
123
);
orphan
.
get
().
set
(
1
,
456
);
checkList
<
uint32_t
>
(
orphan
.
get
().
as
Reader
(),
{
123
,
456
});
checkList
<
uint32_t
>
(
orphan
.
getReader
(),
{
123
,
456
});
auto
root
=
builder
.
initRoot
<
test
::
TestObject
>
();
root
.
adoptObjectField
(
kj
::
mv
(
orphan
));
...
...
@@ -407,7 +414,7 @@ TEST(Orphans, OrphanageDynamicStructCopy) {
Orphan
<
DynamicStruct
>
orphan
=
builder2
.
getOrphanage
().
newOrphanCopy
(
root1
.
asReader
().
getObjectField
<
DynamicStruct
>
(
Schema
::
from
<
TestAllTypes
>
()));
checkDynamicTestMessage
(
orphan
.
get
().
as
Reader
());
checkDynamicTestMessage
(
orphan
.
getReader
());
auto
root2
=
builder2
.
initRoot
<
test
::
TestObject
>
();
root2
.
adoptObjectField
(
kj
::
mv
(
orphan
));
...
...
@@ -423,7 +430,7 @@ TEST(Orphans, OrphanageDynamicListCopy) {
Orphan
<
DynamicList
>
orphan
=
builder2
.
getOrphanage
().
newOrphanCopy
(
root1
.
asReader
().
getObjectField
<
DynamicList
>
(
Schema
::
from
<
List
<
uint32_t
>>
()));
checkList
<
uint32_t
>
(
orphan
.
get
().
as
Reader
(),
{
12
,
34
,
56
});
checkList
<
uint32_t
>
(
orphan
.
getReader
(),
{
12
,
34
,
56
});
auto
root2
=
builder2
.
initRoot
<
test
::
TestObject
>
();
root2
.
adoptObjectField
(
kj
::
mv
(
orphan
));
...
...
c++/src/capnp/orphan.h
View file @
e607fc95
...
...
@@ -53,6 +53,7 @@ public:
Orphan
&
operator
=
(
Orphan
&&
)
=
default
;
inline
typename
T
::
Builder
get
();
inline
typename
T
::
Reader
getReader
()
const
;
inline
bool
operator
==
(
decltype
(
nullptr
))
{
return
builder
==
nullptr
;
}
inline
bool
operator
!=
(
decltype
(
nullptr
))
{
return
builder
==
nullptr
;
}
...
...
@@ -136,6 +137,9 @@ struct OrphanGetImpl<T, Kind::STRUCT> {
static
inline
typename
T
::
Builder
apply
(
_
::
OrphanBuilder
&
builder
)
{
return
typename
T
::
Builder
(
builder
.
asStruct
(
_
::
structSize
<
T
>
()));
}
static
inline
typename
T
::
Reader
applyReader
(
const
_
::
OrphanBuilder
&
builder
)
{
return
typename
T
::
Reader
(
builder
.
asStructReader
(
_
::
structSize
<
T
>
()));
}
};
template
<
typename
T
,
Kind
k
>
...
...
@@ -143,6 +147,9 @@ struct OrphanGetImpl<List<T, k>, Kind::LIST> {
static
inline
typename
List
<
T
>::
Builder
apply
(
_
::
OrphanBuilder
&
builder
)
{
return
typename
List
<
T
>::
Builder
(
builder
.
asList
(
_
::
ElementSizeForType
<
T
>::
value
));
}
static
inline
typename
List
<
T
>::
Reader
applyReader
(
const
_
::
OrphanBuilder
&
builder
)
{
return
typename
List
<
T
>::
Reader
(
builder
.
asListReader
(
_
::
ElementSizeForType
<
T
>::
value
));
}
};
template
<
typename
T
>
...
...
@@ -150,6 +157,9 @@ struct OrphanGetImpl<List<T, Kind::STRUCT>, Kind::LIST> {
static
inline
typename
List
<
T
>::
Builder
apply
(
_
::
OrphanBuilder
&
builder
)
{
return
typename
List
<
T
>::
Builder
(
builder
.
asStructList
(
_
::
structSize
<
T
>
()));
}
static
inline
typename
List
<
T
>::
Reader
applyReader
(
const
_
::
OrphanBuilder
&
builder
)
{
return
typename
List
<
T
>::
Reader
(
builder
.
asListReader
(
_
::
ElementSizeForType
<
T
>::
value
));
}
};
template
<>
...
...
@@ -157,6 +167,9 @@ struct OrphanGetImpl<Text, Kind::BLOB> {
static
inline
Text
::
Builder
apply
(
_
::
OrphanBuilder
&
builder
)
{
return
Text
::
Builder
(
builder
.
asText
());
}
static
inline
Text
::
Reader
applyReader
(
const
_
::
OrphanBuilder
&
builder
)
{
return
Text
::
Reader
(
builder
.
asTextReader
());
}
};
template
<>
...
...
@@ -164,6 +177,9 @@ struct OrphanGetImpl<Data, Kind::BLOB> {
static
inline
Data
::
Builder
apply
(
_
::
OrphanBuilder
&
builder
)
{
return
Data
::
Builder
(
builder
.
asData
());
}
static
inline
Data
::
Reader
applyReader
(
const
_
::
OrphanBuilder
&
builder
)
{
return
Data
::
Reader
(
builder
.
asDataReader
());
}
};
}
// namespace _ (private)
...
...
@@ -173,6 +189,11 @@ inline typename T::Builder Orphan<T>::get() {
return
_
::
OrphanGetImpl
<
T
>::
apply
(
builder
);
}
template
<
typename
T
>
inline
typename
T
::
Reader
Orphan
<
T
>::
getReader
()
const
{
return
_
::
OrphanGetImpl
<
T
>::
applyReader
(
builder
);
}
template
<
typename
T
>
struct
Orphanage
::
GetInnerBuilder
<
T
,
Kind
::
STRUCT
>
{
static
inline
_
::
StructBuilder
apply
(
typename
T
::
Builder
&
t
)
{
...
...
c++/src/kj/memory.h
View file @
e607fc95
...
...
@@ -271,6 +271,9 @@ class SpaceFor {
// returns an Own<T> which will take care of calling T's destructor later.
public
:
inline
SpaceFor
()
{}
inline
~
SpaceFor
()
{}
template
<
typename
...
Params
>
Own
<
T
>
construct
(
Params
&&
...
params
)
{
ctor
(
value
,
kj
::
fwd
<
Params
>
(
params
)...);
...
...
c++/src/kj/mutex.h
View file @
e607fc95
...
...
@@ -166,7 +166,7 @@ template <typename T>
class
Lazy
{
public
:
template
<
typename
Func
>
const
T
&
get
(
Func
&&
init
);
const
T
&
get
(
Func
&&
init
)
const
;
// The first thread to call get() will invoke the given init function to construct the value.
// Other threads will block until construction completes, then return the same value.
//
...
...
@@ -221,7 +221,7 @@ private:
template
<
typename
T
>
template
<
typename
Func
>
const
T
&
Lazy
<
T
>::
get
(
Func
&&
init
)
{
const
T
&
Lazy
<
T
>::
get
(
Func
&&
init
)
const
{
if
(
!
once
.
isInitialized
())
{
InitImpl
<
Func
>
initImpl
(
*
this
,
kj
::
fwd
<
Func
>
(
init
));
once
.
runOnce
(
initImpl
);
...
...
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