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
d99c0b4c
Commit
d99c0b4c
authored
Sep 24, 2013
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove DynamicObject. DynamicValue can now contain an ObjectPointer to represent object fields.
parent
2b643930
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
234 additions
and
316 deletions
+234
-316
node-translator.c++
c++/src/capnp/compiler/node-translator.c++
+3
-3
dynamic-test.c++
c++/src/capnp/dynamic-test.c++
+12
-6
dynamic.c++
c++/src/capnp/dynamic.c++
+52
-115
dynamic.h
c++/src/capnp/dynamic.h
+35
-177
layout.c++
c++/src/capnp/layout.c++
+29
-8
layout.h
c++/src/capnp/layout.h
+4
-0
object.h
c++/src/capnp/object.h
+96
-0
orphan-test.c++
c++/src/capnp/orphan-test.c++
+3
-5
stringify.c++
c++/src/capnp/stringify.c++
+0
-2
No files found.
c++/src/capnp/compiler/node-translator.c++
View file @
d99c0b4c
...
...
@@ -1811,13 +1811,13 @@ kj::Maybe<DynamicValue::Reader> NodeTranslator::readConstant(
if
(
constValue
.
getType
()
==
DynamicValue
::
OBJECT
)
{
// We need to assign an appropriate schema to this object.
DynamicObject
::
Reader
objValue
=
constValue
.
as
<
DynamicObject
>
();
ObjectPointer
::
Reader
objValue
=
constValue
.
as
<
ObjectPointer
>
();
auto
constType
=
constReader
.
getType
();
switch
(
constType
.
which
())
{
case
schema
:
:
Type
::
STRUCT
:
KJ_IF_MAYBE
(
structSchema
,
resolver
.
resolveBootstrapSchema
(
constType
.
getStruct
().
getTypeId
()))
{
constValue
=
objValue
.
as
(
structSchema
->
asStruct
());
constValue
=
objValue
.
getAs
<
DynamicStruct
>
(
structSchema
->
asStruct
());
}
else
{
// The struct's schema is broken for reasons already reported.
return
nullptr
;
...
...
@@ -1825,7 +1825,7 @@ kj::Maybe<DynamicValue::Reader> NodeTranslator::readConstant(
break
;
case
schema
:
:
Type
::
LIST
:
KJ_IF_MAYBE
(
listSchema
,
makeListSchemaOf
(
constType
.
getList
().
getElementType
()))
{
constValue
=
objValue
.
as
(
*
listSchema
);
constValue
=
objValue
.
getAs
<
DynamicList
>
(
*
listSchema
);
}
else
{
// The list's schema is broken for reasons already reported.
return
nullptr
;
...
...
c++/src/capnp/dynamic-test.c++
View file @
d99c0b4c
...
...
@@ -191,11 +191,14 @@ TEST(DynamicApi, DynamicGenericObjects) {
checkTestMessage
(
root
.
asReader
().
as
<
test
::
TestObject
>
().
getObjectField
().
getAs
<
TestAllTypes
>
());
checkDynamicTestMessage
(
root
.
asReader
().
get
(
"objectField"
).
as
<
DynamicObject
>
().
as
(
Schema
::
from
<
TestAllTypes
>
()));
root
.
asReader
().
get
(
"objectField"
).
as
<
ObjectPointer
>
()
.
getAs
<
DynamicStruct
>
(
Schema
::
from
<
TestAllTypes
>
()));
checkDynamicTestMessage
(
root
.
asReader
().
get
(
"objectField"
).
as
<
DynamicObject
>
().
as
(
Schema
::
from
<
TestAllTypes
>
()));
root
.
asReader
().
get
(
"objectField"
).
as
<
ObjectPointer
>
()
.
getAs
<
DynamicStruct
>
(
Schema
::
from
<
TestAllTypes
>
()));
checkDynamicTestMessage
(
root
.
get
(
"objectField"
).
as
<
DynamicObject
>
().
asReader
().
as
(
Schema
::
from
<
TestAllTypes
>
()));
root
.
get
(
"objectField"
).
as
<
ObjectPointer
>
().
asReader
()
.
getAs
<
DynamicStruct
>
(
Schema
::
from
<
TestAllTypes
>
()));
checkDynamicTestMessage
(
root
.
getObject
(
"objectField"
,
Schema
::
from
<
TestAllTypes
>
()));
...
...
@@ -218,13 +221,16 @@ TEST(DynamicApi, DynamicGenericObjects) {
}
checkList
<
uint32_t
>
(
root
.
asReader
().
get
(
"objectField"
).
as
<
DynamicObject
>
().
as
(
Schema
::
from
<
List
<
uint32_t
>>
()),
root
.
asReader
().
get
(
"objectField"
).
as
<
ObjectPointer
>
()
.
getAs
<
DynamicList
>
(
Schema
::
from
<
List
<
uint32_t
>>
()),
{
123u
,
456u
,
789u
,
123456789u
});
checkList
<
uint32_t
>
(
root
.
asReader
().
get
(
"objectField"
).
as
<
DynamicObject
>
().
as
(
Schema
::
from
<
List
<
uint32_t
>>
()),
root
.
asReader
().
get
(
"objectField"
).
as
<
ObjectPointer
>
()
.
getAs
<
DynamicList
>
(
Schema
::
from
<
List
<
uint32_t
>>
()),
{
123u
,
456u
,
789u
,
123456789u
});
checkList
<
uint32_t
>
(
root
.
get
(
"objectField"
).
as
<
DynamicObject
>
().
asReader
().
as
(
Schema
::
from
<
List
<
uint32_t
>>
()),
root
.
get
(
"objectField"
).
as
<
ObjectPointer
>
().
asReader
()
.
getAs
<
DynamicList
>
(
Schema
::
from
<
List
<
uint32_t
>>
()),
{
123u
,
456u
,
789u
,
123456789u
});
checkList
<
uint32_t
>
(
root
.
getObject
(
"objectField"
,
Schema
::
from
<
List
<
uint32_t
>>
()),
...
...
c++/src/capnp/dynamic.c++
View file @
d99c0b4c
...
...
@@ -125,30 +125,6 @@ uint16_t DynamicEnum::asImpl(uint64_t requestedTypeId) const {
// =======================================================================================
DynamicStruct
::
Reader
DynamicObject
::
Reader
::
as
(
StructSchema
schema
)
const
{
if
(
reader
.
kind
==
_
::
ObjectKind
::
NULL_POINTER
)
{
return
DynamicStruct
::
Reader
(
schema
,
_
::
StructReader
());
}
KJ_REQUIRE
(
reader
.
kind
==
_
::
ObjectKind
::
STRUCT
,
"Object is not a struct."
)
{
// Return default struct.
return
DynamicStruct
::
Reader
(
schema
,
_
::
StructReader
());
}
return
DynamicStruct
::
Reader
(
schema
,
reader
.
structReader
);
}
DynamicList
::
Reader
DynamicObject
::
Reader
::
as
(
ListSchema
schema
)
const
{
if
(
reader
.
kind
==
_
::
ObjectKind
::
NULL_POINTER
)
{
return
DynamicList
::
Reader
(
schema
,
_
::
ListReader
());
}
KJ_REQUIRE
(
reader
.
kind
==
_
::
ObjectKind
::
LIST
,
"Object is not a list."
)
{
// Return empty list.
return
DynamicList
::
Reader
(
schema
,
_
::
ListReader
());
}
return
DynamicList
::
Reader
(
schema
,
reader
.
listReader
);
}
// =======================================================================================
bool
DynamicStruct
::
Reader
::
isSetInUnion
(
StructSchema
::
Field
field
)
const
{
auto
proto
=
field
.
getProto
();
if
(
proto
.
hasDiscriminantValue
())
{
...
...
@@ -257,18 +233,14 @@ DynamicValue::Reader DynamicStruct::Reader::get(StructSchema::Field field) const
dval
.
getList
().
getAs
<
_
::
UncheckedMessage
>
()));
}
case
schema
:
:
Type
::
STRUCT
:
{
case
schema
:
:
Type
::
STRUCT
:
return
DynamicStruct
::
Reader
(
field
.
getContainingStruct
().
getDependency
(
type
.
getStruct
().
getTypeId
()).
asStruct
(),
reader
.
getPointerField
(
slot
.
getOffset
()
*
POINTERS
)
.
getStruct
(
dval
.
getStruct
().
getAs
<
_
::
UncheckedMessage
>
()));
}
case
schema
:
:
Type
::
OBJECT
:
{
return
DynamicObject
::
Reader
(
reader
.
getPointerField
(
slot
.
getOffset
()
*
POINTERS
)
.
getObject
(
dval
.
getObject
().
getAs
<
_
::
UncheckedMessage
>
()));
}
case
schema
:
:
Type
::
OBJECT
:
return
ObjectPointer
::
Reader
(
reader
.
getPointerField
(
slot
.
getOffset
()
*
POINTERS
));
case
schema
:
:
Type
::
INTERFACE
:
KJ_FAIL_ASSERT
(
"Interfaces not yet implemented."
);
...
...
@@ -366,11 +338,8 @@ DynamicValue::Builder DynamicStruct::Builder::get(StructSchema::Field field) {
dval
.
getStruct
().
getAs
<
_
::
UncheckedMessage
>
()));
}
case
schema
:
:
Type
::
OBJECT
:
{
return
DynamicObject
::
Builder
(
builder
.
getPointerField
(
slot
.
getOffset
()
*
POINTERS
)
.
getObject
(
dval
.
getObject
().
getAs
<
_
::
UncheckedMessage
>
()));
}
case
schema
:
:
Type
::
OBJECT
:
return
ObjectPointer
::
Builder
(
builder
.
getPointerField
(
slot
.
getOffset
()
*
POINTERS
));
case
schema
:
:
Type
::
INTERFACE
:
KJ_FAIL_ASSERT
(
"Interfaces not yet implemented."
);
...
...
@@ -579,8 +548,8 @@ void DynamicStruct::Builder::set(StructSchema::Field field, const DynamicValue::
}
case
schema
:
:
Type
::
OBJECT
:
builder
.
getPointerField
(
slot
.
getOffset
()
*
POINTERS
)
.
set
Object
(
value
.
as
<
DynamicObject
>
().
reader
);
ObjectPointer
::
Builder
(
builder
.
getPointerField
(
slot
.
getOffset
()
*
POINTERS
)
)
.
set
(
value
.
as
<
ObjectPointer
>
()
);
return
;
case
schema
:
:
Type
::
INTERFACE
:
...
...
@@ -1115,7 +1084,7 @@ DynamicValue::Reader DynamicList::Reader::operator[](uint index) const {
reader
.
getDataElement
<
uint16_t
>
(
index
*
ELEMENTS
));
case
schema
:
:
Type
::
OBJECT
:
return
DynamicObject
::
Reader
(
reader
.
getPointerElement
(
index
*
ELEMENTS
).
getObject
(
nullptr
));
return
ObjectPointer
::
Reader
(
reader
.
getPointerElement
(
index
*
ELEMENTS
));
case
schema
:
:
Type
::
INTERFACE
:
KJ_FAIL_ASSERT
(
"Interfaces not implemented."
)
{
...
...
@@ -1480,7 +1449,7 @@ DynamicValue::Reader::Reader(ConstSchema constant) {
break
;
case
schema
:
:
Type
::
OBJECT
:
*
this
=
value
.
getObject
()
.
getAs
<
DynamicObject
>
()
;
*
this
=
value
.
getObject
();
break
;
case
schema
:
:
Type
::
INTERFACE
:
...
...
@@ -1620,7 +1589,7 @@ HANDLE_TYPE(text, TEXT, Text)
HANDLE_TYPE
(
list
,
LIST
,
DynamicList
)
HANDLE_TYPE
(
struct
,
STRUCT
,
DynamicStruct
)
HANDLE_TYPE
(
enum
,
ENUM
,
DynamicEnum
)
HANDLE_TYPE
(
object
,
OBJECT
,
DynamicObject
)
HANDLE_TYPE
(
object
,
OBJECT
,
ObjectPointer
)
#undef HANDLE_TYPE
...
...
@@ -1759,17 +1728,6 @@ DynamicList::Builder PointerHelpers<DynamicList, Kind::UNKNOWN>::init(
}
}
DynamicObject
::
Reader
PointerHelpers
<
DynamicObject
,
Kind
::
UNKNOWN
>::
get
(
PointerReader
reader
)
{
return
DynamicObject
::
Reader
(
reader
.
getObject
(
nullptr
));
}
DynamicObject
::
Builder
PointerHelpers
<
DynamicObject
,
Kind
::
UNKNOWN
>::
get
(
PointerBuilder
builder
)
{
return
DynamicObject
::
Builder
(
builder
.
getObject
(
nullptr
));
}
void
PointerHelpers
<
DynamicObject
,
Kind
::
UNKNOWN
>::
set
(
PointerBuilder
builder
,
const
DynamicObject
::
Reader
&
value
)
{
builder
.
setObject
(
value
.
reader
);
}
}
// namespace _ (private)
template
<>
...
...
@@ -1795,6 +1753,38 @@ void ObjectPointer::Builder::adopt<DynamicValue>(Orphan<DynamicValue>&& orphan)
}
}
template
<>
DynamicStruct
::
Builder
Orphan
<
ObjectPointer
>::
getAs
<
DynamicStruct
>
(
StructSchema
schema
)
{
return
DynamicStruct
::
Builder
(
schema
,
builder
.
asStruct
(
structSizeFromSchema
(
schema
)));
}
template
<>
DynamicStruct
::
Reader
Orphan
<
ObjectPointer
>::
getAsReader
<
DynamicStruct
>
(
StructSchema
schema
)
const
{
return
DynamicStruct
::
Reader
(
schema
,
builder
.
asStructReader
(
structSizeFromSchema
(
schema
)));
}
template
<>
Orphan
<
DynamicStruct
>
Orphan
<
ObjectPointer
>::
releaseAs
<
DynamicStruct
>
(
StructSchema
schema
)
{
return
Orphan
<
DynamicStruct
>
(
schema
,
kj
::
mv
(
builder
));
}
template
<>
DynamicList
::
Builder
Orphan
<
ObjectPointer
>::
getAs
<
DynamicList
>
(
ListSchema
schema
)
{
if
(
schema
.
whichElementType
()
==
schema
::
Type
::
STRUCT
)
{
return
DynamicList
::
Builder
(
schema
,
builder
.
asStructList
(
structSizeFromSchema
(
schema
.
getStructElementType
())));
}
else
{
return
DynamicList
::
Builder
(
schema
,
builder
.
asList
(
elementSizeFor
(
schema
.
whichElementType
())));
}
}
template
<>
DynamicList
::
Reader
Orphan
<
ObjectPointer
>::
getAsReader
<
DynamicList
>
(
ListSchema
schema
)
const
{
return
DynamicList
::
Reader
(
schema
,
builder
.
asListReader
(
elementSizeFor
(
schema
.
whichElementType
())));
}
template
<>
Orphan
<
DynamicList
>
Orphan
<
ObjectPointer
>::
releaseAs
<
DynamicList
>
(
ListSchema
schema
)
{
return
Orphan
<
DynamicList
>
(
schema
,
kj
::
mv
(
builder
));
}
// -------------------------------------------------------------------
Orphan
<
DynamicStruct
>
Orphanage
::
newOrphan
(
StructSchema
schema
)
const
{
...
...
@@ -1835,53 +1825,6 @@ DynamicList::Reader Orphan<DynamicList>::getReader() const {
schema
,
builder
.
asListReader
(
elementSizeFor
(
schema
.
whichElementType
())));
}
DynamicObject
::
Builder
Orphan
<
DynamicObject
>::
get
()
{
return
DynamicObject
::
Builder
(
builder
.
asObject
());
}
DynamicObject
::
Reader
Orphan
<
DynamicObject
>::
getReader
()
const
{
return
DynamicObject
::
Reader
(
builder
.
asObjectReader
());
}
DynamicStruct
::
Builder
Orphan
<
DynamicObject
>::
getAs
(
StructSchema
schema
)
{
return
DynamicStruct
::
Builder
(
schema
,
builder
.
asStruct
(
structSizeFromSchema
(
schema
)));
}
DynamicList
::
Builder
Orphan
<
DynamicObject
>::
getAs
(
ListSchema
schema
)
{
if
(
schema
.
whichElementType
()
==
schema
::
Type
::
STRUCT
)
{
return
DynamicList
::
Builder
(
schema
,
builder
.
asStructList
(
structSizeFromSchema
(
schema
.
getStructElementType
())));
}
else
{
return
DynamicList
::
Builder
(
schema
,
builder
.
asList
(
elementSizeFor
(
schema
.
whichElementType
())));
}
}
template
<>
Text
::
Builder
Orphan
<
DynamicObject
>::
getAs
<
Text
>
()
{
return
builder
.
asText
();
}
template
<>
Data
::
Builder
Orphan
<
DynamicObject
>::
getAs
<
Data
>
()
{
return
builder
.
asData
();
}
Orphan
<
DynamicStruct
>
Orphan
<
DynamicObject
>::
releaseAs
(
StructSchema
schema
)
{
getAs
(
schema
);
// type check
return
Orphan
<
DynamicStruct
>
(
schema
,
kj
::
mv
(
builder
));
}
Orphan
<
DynamicList
>
Orphan
<
DynamicObject
>::
releaseAs
(
ListSchema
schema
)
{
getAs
(
schema
);
// type check
return
Orphan
<
DynamicList
>
(
schema
,
kj
::
mv
(
builder
));
}
template
<>
Orphan
<
Text
>
Orphan
<
DynamicObject
>::
releaseAs
<
Text
>
()
{
getAs
<
Text
>
();
// type check
return
Orphan
<
Text
>
(
kj
::
mv
(
builder
));
}
template
<>
Orphan
<
Data
>
Orphan
<
DynamicObject
>::
releaseAs
<
Data
>
()
{
getAs
<
Data
>
();
// type check
return
Orphan
<
Data
>
(
kj
::
mv
(
builder
));
}
Orphan
<
DynamicValue
>::
Orphan
(
DynamicValue
::
Builder
value
,
_
::
OrphanBuilder
&&
builder
)
:
type
(
value
.
getType
()),
builder
(
kj
::
mv
(
builder
))
{
switch
(
type
)
{
...
...
@@ -1928,7 +1871,8 @@ DynamicValue::Builder Orphan<DynamicValue>::get() {
case
DynamicValue
:
:
INTERFACE
:
KJ_FAIL_ASSERT
(
"Interfaces not implemented."
);
case
DynamicValue
:
:
OBJECT
:
return
DynamicObject
::
Builder
(
builder
.
asObject
());
KJ_FAIL_REQUIRE
(
"Can't get() an untyped Object orphan; there is no underlying pointer to "
"wrap in an ObjectPointer::Builder."
);
}
KJ_UNREACHABLE
;
}
...
...
@@ -1953,11 +1897,18 @@ DynamicValue::Reader Orphan<DynamicValue>::getReader() const {
case
DynamicValue
:
:
INTERFACE
:
KJ_FAIL_ASSERT
(
"Interfaces not implemented."
);
case
DynamicValue
:
:
OBJECT
:
return
DynamicObject
::
Reader
(
builder
.
asObjectReader
());
KJ_FAIL_ASSERT
(
"Can't get() an untyped Object orphan; there is no underlying pointer to "
"wrap in an ObjectPointer::Builder."
);
}
KJ_UNREACHABLE
;
}
template
<>
Orphan
<
ObjectPointer
>
Orphan
<
DynamicValue
>::
releaseAs
<
ObjectPointer
>
()
{
KJ_REQUIRE
(
type
==
DynamicValue
::
OBJECT
,
"Value type mismatch."
);
type
=
DynamicValue
::
UNKNOWN
;
return
Orphan
<
ObjectPointer
>
(
kj
::
mv
(
builder
));
}
template
<>
Orphan
<
DynamicStruct
>
Orphan
<
DynamicValue
>::
releaseAs
<
DynamicStruct
>
()
{
KJ_REQUIRE
(
type
==
DynamicValue
::
STRUCT
,
"Value type mismatch."
);
...
...
@@ -1971,20 +1922,6 @@ Orphan<DynamicList> Orphan<DynamicValue>::releaseAs<DynamicList>() {
return
Orphan
<
DynamicList
>
(
listSchema
,
kj
::
mv
(
builder
));
}
template
<>
Orphan
<
DynamicObject
>
Orphanage
::
newOrphanCopy
<
DynamicObject
::
Reader
>
(
const
DynamicObject
::
Reader
&
copyFrom
)
const
{
switch
(
copyFrom
.
reader
.
kind
)
{
case
_
:
:
ObjectKind
::
NULL_POINTER
:
return
Orphan
<
DynamicObject
>
();
case
_
:
:
ObjectKind
::
STRUCT
:
return
Orphan
<
DynamicObject
>
(
_
::
OrphanBuilder
::
copy
(
arena
,
copyFrom
.
reader
.
structReader
));
case
_
:
:
ObjectKind
::
LIST
:
return
Orphan
<
DynamicObject
>
(
_
::
OrphanBuilder
::
copy
(
arena
,
copyFrom
.
reader
.
listReader
));
}
KJ_UNREACHABLE
;
}
template
<>
Orphan
<
DynamicValue
>
Orphanage
::
newOrphanCopy
<
DynamicValue
::
Reader
>
(
const
DynamicValue
::
Reader
&
copyFrom
)
const
{
...
...
c++/src/capnp/dynamic.h
View file @
d99c0b4c
...
...
@@ -72,11 +72,6 @@ struct DynamicValue {
class
Builder
;
};
class
DynamicEnum
;
struct
DynamicObject
{
DynamicObject
()
=
delete
;
class
Reader
;
class
Builder
;
};
struct
DynamicStruct
{
DynamicStruct
()
=
delete
;
class
Reader
;
...
...
@@ -147,68 +142,6 @@ private:
// -------------------------------------------------------------------
class
DynamicObject
::
Reader
{
// Represents an "Object" field of unknown type.
public
:
typedef
DynamicObject
Reads
;
Reader
()
=
default
;
template
<
typename
T
>
typename
T
::
Reader
as
()
const
;
// Convert the object to the given struct, list, or blob type.
DynamicStruct
::
Reader
as
(
StructSchema
schema
)
const
;
DynamicList
::
Reader
as
(
ListSchema
schema
)
const
;
private
:
_
::
ObjectReader
reader
;
inline
Reader
(
_
::
ObjectReader
reader
)
:
reader
(
reader
)
{}
friend
struct
DynamicStruct
;
friend
struct
DynamicList
;
template
<
typename
T
,
Kind
K
>
friend
struct
_
::
PointerHelpers
;
friend
class
DynamicObject
::
Builder
;
friend
class
Orphan
<
DynamicObject
>
;
friend
class
Orphan
<
DynamicValue
>
;
friend
class
Orphanage
;
};
class
DynamicObject
::
Builder
:
public
kj
::
DisallowConstCopy
{
// Represents an "Object" field of unknown type.
//
// You can't actually do anything with a DynamicObject::Builder except read it. It can't be
// converted to a Builder for any specific type because that could require initializing or
// updating the pointer that points *to* this object. Therefore, you must call
// DynamicStruct::Builder::{get,set,init}Object() and pass a type schema to build object fields.
public
:
typedef
DynamicObject
Builds
;
Builder
()
=
default
;
inline
Builder
(
decltype
(
nullptr
))
{}
Builder
(
Builder
&
)
=
default
;
Builder
(
Builder
&&
)
=
default
;
Reader
asReader
()
const
{
return
Reader
(
builder
.
asReader
());
}
private
:
_
::
ObjectBuilder
builder
;
inline
Builder
(
_
::
ObjectBuilder
builder
)
:
builder
(
builder
)
{}
friend
struct
DynamicStruct
;
friend
struct
DynamicList
;
template
<
typename
T
,
Kind
K
>
friend
struct
_
::
PointerHelpers
;
friend
class
Orphan
<
DynamicObject
>
;
friend
class
Orphan
<
DynamicValue
>
;
};
// -------------------------------------------------------------------
class
DynamicStruct
::
Reader
{
public
:
typedef
DynamicStruct
Reads
;
...
...
@@ -260,7 +193,6 @@ private:
template
<
typename
T
,
Kind
K
>
friend
struct
_
::
PointerHelpers
;
friend
struct
DynamicObject
;
friend
class
DynamicStruct
::
Builder
;
friend
struct
DynamicList
;
friend
class
MessageReader
;
...
...
@@ -272,6 +204,7 @@ private:
friend
class
Orphanage
;
friend
class
Orphan
<
DynamicStruct
>
;
friend
class
Orphan
<
DynamicValue
>
;
friend
class
Orphan
<
ObjectPointer
>
;
};
class
DynamicStruct
::
Builder
{
...
...
@@ -380,8 +313,8 @@ private:
friend
struct
::
capnp
::
ToDynamic_
;
friend
class
Orphanage
;
friend
class
Orphan
<
DynamicStruct
>
;
friend
class
Orphan
<
DynamicObject
>
;
friend
class
Orphan
<
DynamicValue
>
;
friend
class
Orphan
<
ObjectPointer
>
;
};
// -------------------------------------------------------------------
...
...
@@ -418,13 +351,13 @@ private:
template
<
typename
T
,
Kind
k
>
friend
struct
_
::
PointerHelpers
;
friend
struct
DynamicStruct
;
friend
struct
DynamicObject
;
friend
class
DynamicList
::
Builder
;
template
<
typename
T
,
::
capnp
::
Kind
k
>
friend
struct
::
capnp
::
ToDynamic_
;
friend
class
Orphanage
;
friend
class
Orphan
<
DynamicList
>
;
friend
class
Orphan
<
DynamicValue
>
;
friend
class
Orphan
<
ObjectPointer
>
;
};
class
DynamicList
::
Builder
{
...
...
@@ -474,19 +407,17 @@ private:
template
<
typename
T
,
Kind
k
>
friend
struct
_
::
OrphanGetImpl
;
friend
class
Orphan
<
DynamicList
>
;
friend
class
Orphan
<
DynamicObject
>
;
friend
class
Orphan
<
DynamicValue
>
;
friend
class
Orphan
<
ObjectPointer
>
;
};
// -------------------------------------------------------------------
// Make sure ReaderFor<T> and BuilderFor<T> work for DynamicEnum, Dynamic
Object, Dynamic
Struct, and
// Make sure ReaderFor<T> and BuilderFor<T> work for DynamicEnum, DynamicStruct, and
// DynamicList, so that we can define DynamicValue::as().
template
<>
struct
ReaderFor_
<
DynamicEnum
,
Kind
::
UNKNOWN
>
{
typedef
DynamicEnum
Type
;
};
template
<>
struct
BuilderFor_
<
DynamicEnum
,
Kind
::
UNKNOWN
>
{
typedef
DynamicEnum
Type
;
};
template
<>
struct
ReaderFor_
<
DynamicObject
,
Kind
::
UNKNOWN
>
{
typedef
DynamicObject
::
Reader
Type
;
};
template
<>
struct
BuilderFor_
<
DynamicObject
,
Kind
::
UNKNOWN
>
{
typedef
DynamicObject
::
Builder
Type
;
};
template
<>
struct
ReaderFor_
<
DynamicStruct
,
Kind
::
UNKNOWN
>
{
typedef
DynamicStruct
::
Reader
Type
;
};
template
<>
struct
BuilderFor_
<
DynamicStruct
,
Kind
::
UNKNOWN
>
{
typedef
DynamicStruct
::
Builder
Type
;
};
template
<>
struct
ReaderFor_
<
DynamicList
,
Kind
::
UNKNOWN
>
{
typedef
DynamicList
::
Reader
Type
;
};
...
...
@@ -518,7 +449,7 @@ public:
inline
Reader
(
const
DynamicList
::
Reader
&
value
);
inline
Reader
(
DynamicEnum
value
);
inline
Reader
(
const
DynamicStruct
::
Reader
&
value
);
inline
Reader
(
const
DynamicObject
::
Reader
&
value
);
inline
Reader
(
const
ObjectPointer
::
Reader
&
value
);
Reader
(
ConstSchema
constant
);
template
<
typename
T
,
typename
=
decltype
(
toDynamic
(
kj
::
instance
<
T
>
()))
>
...
...
@@ -528,9 +459,9 @@ public:
inline
ReaderFor
<
T
>
as
()
const
{
return
AsImpl
<
T
>::
apply
(
*
this
);
}
// Use to interpret the value as some Cap'n Proto type. Allowed types are:
// - Void, bool, [u]int{8,16,32,64}_t, float, double, any enum: Returns the raw value.
// - Text, Data, any struct type: Returns the corresponding Reader.
// - Text, Data,
ObjectPointer,
any struct type: Returns the corresponding Reader.
// - List<T> for any T listed above: Returns List<T>::Reader.
// - DynamicEnum
, DynamicObject
: Returns the corresponding type.
// - DynamicEnum: Returns the corresponding type.
// - DynamicStruct, DynamicList: Returns the corresponding Reader.
//
// DynamicValue allows various implicit conversions, mostly just to make the interface friendlier.
...
...
@@ -563,7 +494,7 @@ private:
DynamicList
::
Reader
listValue
;
DynamicEnum
enumValue
;
DynamicStruct
::
Reader
structValue
;
DynamicObject
::
Reader
objectValue
;
ObjectPointer
::
Reader
objectValue
;
};
template
<
typename
T
,
Kind
kind
=
kind
<
T
>
()
>
struct
AsImpl
;
...
...
@@ -598,7 +529,7 @@ public:
inline
Builder
(
DynamicList
::
Builder
value
);
inline
Builder
(
DynamicEnum
value
);
inline
Builder
(
DynamicStruct
::
Builder
value
);
inline
Builder
(
DynamicObject
::
Builder
value
);
inline
Builder
(
ObjectPointer
::
Builder
value
);
template
<
typename
T
,
typename
=
decltype
(
toDynamic
(
kj
::
instance
<
T
>
()))
>
inline
Builder
(
T
value
)
:
Builder
(
toDynamic
(
value
))
{}
...
...
@@ -635,7 +566,7 @@ private:
DynamicList
::
Builder
listValue
;
DynamicEnum
enumValue
;
DynamicStruct
::
Builder
structValue
;
DynamicObject
::
Builder
objectValue
;
ObjectPointer
::
Builder
objectValue
;
};
template
<
typename
T
,
Kind
kind
=
kind
<
T
>
()
>
struct
AsImpl
;
...
...
@@ -648,8 +579,6 @@ private:
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicValue
::
Reader
&
value
);
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicValue
::
Builder
&
value
);
kj
::
StringTree
KJ_STRINGIFY
(
DynamicEnum
value
);
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicObject
::
Reader
&
value
);
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicObject
::
Builder
&
value
);
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicStruct
::
Reader
&
value
);
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicStruct
::
Builder
&
value
);
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicList
::
Reader
&
value
);
...
...
@@ -689,8 +618,8 @@ private:
friend
struct
_
::
PointerHelpers
;
friend
struct
DynamicList
;
friend
class
Orphanage
;
friend
class
Orphan
<
DynamicObject
>
;
friend
class
Orphan
<
DynamicValue
>
;
friend
class
Orphan
<
ObjectPointer
>
;
friend
class
MessageBuilder
;
};
...
...
@@ -725,56 +654,8 @@ private:
friend
struct
_
::
PointerHelpers
;
friend
struct
DynamicList
;
friend
class
Orphanage
;
friend
class
Orphan
<
DynamicObject
>
;
friend
class
Orphan
<
DynamicValue
>
;
};
template
<>
class
Orphan
<
DynamicObject
>
{
public
:
Orphan
()
=
default
;
KJ_DISALLOW_COPY
(
Orphan
);
Orphan
(
Orphan
&&
)
=
default
;
Orphan
&
operator
=
(
Orphan
&&
)
=
default
;
DynamicObject
::
Builder
get
();
DynamicObject
::
Reader
getReader
()
const
;
template
<
typename
T
>
BuilderFor
<
T
>
getAs
();
// Coerce the object to the given type and return a builder for that type. This may relocate
// the object if it was originally created with a previous version of the schema and the sizes
// don't match.
//
// Notice that DynamicObject::Builder does not have an "as<T>()" method, which is why this is
// needed.
template
<
typename
T
>
Orphan
<
T
>
releaseAs
();
// Like DynamicValue::Builder::as(), but coerces the Orphan type. Since Orphans are move-only,
// the original Orphan<DynamicStruct> is no longer valid after this call; ownership is
// transferred to the returned Orphan<T>.
DynamicStruct
::
Builder
getAs
(
StructSchema
schema
);
DynamicList
::
Builder
getAs
(
ListSchema
schema
);
// Dynamic versions of 'getAs()'.
Orphan
<
DynamicStruct
>
releaseAs
(
StructSchema
schema
);
Orphan
<
DynamicList
>
releaseAs
(
ListSchema
schema
);
// Dynamic versions of 'releaseAs()'.
inline
bool
operator
==
(
decltype
(
nullptr
))
const
{
return
builder
==
nullptr
;
}
inline
bool
operator
!=
(
decltype
(
nullptr
))
const
{
return
builder
!=
nullptr
;
}
private
:
_
::
OrphanBuilder
builder
;
explicit
Orphan
(
_
::
OrphanBuilder
&&
builder
)
:
builder
(
kj
::
mv
(
builder
))
{}
template
<
typename
,
Kind
>
friend
struct
_
::
PointerHelpers
;
friend
class
Orphan
<
DynamicValue
>
;
friend
class
Orphan
age
;
friend
class
Orphan
<
ObjectPointer
>
;
};
template
<>
...
...
@@ -800,6 +681,7 @@ public:
Orphan
(
Orphan
&&
)
=
default
;
template
<
typename
T
>
Orphan
(
Orphan
<
T
>&&
);
Orphan
(
Orphan
<
ObjectPointer
>&&
);
KJ_DISALLOW_COPY
(
Orphan
);
Orphan
&
operator
=
(
Orphan
&&
)
=
default
;
...
...
@@ -848,27 +730,12 @@ private:
};
template
<
typename
T
>
BuilderFor
<
T
>
Orphan
<
DynamicObject
>::
getAs
()
{
return
getAs
(
Schema
::
from
<
T
>
()).
template
as
<
T
>
();
}
template
<>
Text
::
Builder
Orphan
<
DynamicObject
>::
getAs
<
Text
>
();
template
<>
Data
::
Builder
Orphan
<
DynamicObject
>::
getAs
<
Data
>
();
template
<
typename
T
>
Orphan
<
T
>
Orphan
<
DynamicObject
>::
releaseAs
()
{
return
releaseAs
(
Schema
::
from
<
T
>
()).
template
releaseAs
<
T
>
();
}
template
<>
Orphan
<
Text
>
Orphan
<
DynamicObject
>::
releaseAs
<
Text
>
();
template
<>
Orphan
<
Data
>
Orphan
<
DynamicObject
>::
releaseAs
<
Data
>
();
template
<
typename
T
>
Orphan
<
DynamicValue
>::
Orphan
(
Orphan
<
T
>&&
other
)
inline
Orphan
<
DynamicValue
>::
Orphan
(
Orphan
<
T
>&&
other
)
:
Orphan
(
other
.
get
(),
kj
::
mv
(
other
.
builder
))
{}
inline
Orphan
<
DynamicValue
>::
Orphan
(
Orphan
<
ObjectPointer
>&&
other
)
:
type
(
DynamicValue
::
OBJECT
),
builder
(
kj
::
mv
(
other
.
builder
))
{}
template
<
typename
T
>
Orphan
<
T
>
Orphan
<
DynamicStruct
>::
releaseAs
()
{
get
().
as
<
T
>
();
// type check
...
...
@@ -888,6 +755,8 @@ Orphan<T> Orphan<DynamicValue>::releaseAs() {
return
Orphan
<
T
>
(
kj
::
mv
(
builder
));
}
template
<>
Orphan
<
ObjectPointer
>
Orphan
<
DynamicValue
>::
releaseAs
<
ObjectPointer
>
();
template
<>
Orphan
<
DynamicStruct
>
Orphan
<
DynamicValue
>::
releaseAs
<
DynamicStruct
>
();
template
<>
...
...
@@ -920,10 +789,6 @@ inline Orphan<DynamicList> Orphanage::newOrphanCopy<DynamicList::Reader>(
return
Orphan
<
DynamicList
>
(
copyFrom
.
getSchema
(),
_
::
OrphanBuilder
::
copy
(
arena
,
copyFrom
.
reader
));
}
template
<>
Orphan
<
DynamicObject
>
Orphanage
::
newOrphanCopy
<
DynamicObject
::
Reader
>
(
const
DynamicObject
::
Reader
&
copyFrom
)
const
;
template
<>
Orphan
<
DynamicValue
>
Orphanage
::
newOrphanCopy
<
DynamicValue
::
Reader
>
(
const
DynamicValue
::
Reader
&
copyFrom
)
const
;
...
...
@@ -985,19 +850,6 @@ struct PointerHelpers<DynamicList, Kind::UNKNOWN> {
}
};
template
<>
struct
PointerHelpers
<
DynamicObject
,
Kind
::
UNKNOWN
>
{
static
DynamicObject
::
Reader
get
(
PointerReader
reader
);
static
DynamicObject
::
Builder
get
(
PointerBuilder
builder
);
static
void
set
(
PointerBuilder
builder
,
const
DynamicObject
::
Reader
&
value
);
static
inline
void
adopt
(
PointerBuilder
builder
,
Orphan
<
DynamicObject
>&&
value
)
{
builder
.
adopt
(
kj
::
mv
(
value
.
builder
));
}
static
inline
Orphan
<
DynamicObject
>
disown
(
PointerBuilder
builder
)
{
return
Orphan
<
DynamicObject
>
(
builder
.
disown
());
}
};
}
// namespace _ (private)
template
<
typename
T
>
...
...
@@ -1043,6 +895,19 @@ inline Orphan<T> ObjectPointer::Builder::disownAs(ListSchema schema) {
return
_
::
PointerHelpers
<
T
>::
disown
(
builder
,
schema
);
}
template
<>
DynamicStruct
::
Builder
Orphan
<
ObjectPointer
>::
getAs
<
DynamicStruct
>
(
StructSchema
schema
);
template
<>
DynamicList
::
Builder
Orphan
<
ObjectPointer
>::
getAs
<
DynamicList
>
(
ListSchema
schema
);
template
<>
DynamicStruct
::
Reader
Orphan
<
ObjectPointer
>::
getAsReader
<
DynamicStruct
>
(
StructSchema
schema
)
const
;
template
<>
DynamicList
::
Reader
Orphan
<
ObjectPointer
>::
getAsReader
<
DynamicList
>
(
ListSchema
schema
)
const
;
template
<>
Orphan
<
DynamicStruct
>
Orphan
<
ObjectPointer
>::
releaseAs
<
DynamicStruct
>
(
StructSchema
schema
);
template
<>
Orphan
<
DynamicList
>
Orphan
<
ObjectPointer
>::
releaseAs
<
DynamicList
>
(
ListSchema
schema
);
// =======================================================================================
// Inline implementation details.
...
...
@@ -1118,7 +983,7 @@ CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(Text, TEXT, text);
CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR
(
Data
,
DATA
,
data
);
CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR
(
DynamicList
,
LIST
,
list
);
CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR
(
DynamicStruct
,
STRUCT
,
struct
);
CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR
(
DynamicObject
,
OBJECT
,
object
);
CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR
(
ObjectPointer
,
OBJECT
,
object
);
#undef CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR
...
...
@@ -1152,7 +1017,7 @@ CAPNP_DECLARE_TYPE(data, DATA, Data)
CAPNP_DECLARE_TYPE
(
list
,
LIST
,
DynamicList
)
CAPNP_DECLARE_TYPE
(
struct
,
STRUCT
,
DynamicStruct
)
CAPNP_DECLARE_TYPE
(
enum
,
ENUM
,
DynamicEnum
)
CAPNP_DECLARE_TYPE
(
object
,
OBJECT
,
DynamicObject
)
CAPNP_DECLARE_TYPE
(
object
,
OBJECT
,
ObjectPointer
)
#undef CAPNP_DECLARE_TYPE
// CAPNP_DECLARE_TYPE(Void) causes gcc 4.7 to segfault. If I do it manually and remove the
...
...
@@ -1207,13 +1072,6 @@ struct DynamicValue::Builder::AsImpl<T, Kind::LIST> {
// -------------------------------------------------------------------
template
<
typename
T
>
inline
typename
T
::
Reader
DynamicObject
::
Reader
::
as
()
const
{
return
as
(
Schema
::
from
<
T
>
()).
template
as
<
T
>
();
}
// -------------------------------------------------------------------
template
<
typename
T
>
typename
T
::
Reader
DynamicStruct
::
Reader
::
as
()
const
{
static_assert
(
kind
<
T
>
()
==
Kind
::
STRUCT
,
...
...
c++/src/capnp/layout.c++
View file @
d99c0b4c
...
...
@@ -1617,19 +1617,19 @@ struct WireHelpers {
}
}
static
KJ_ALWAYS_INLINE
(
void
setObjectPointer
(
SegmentBuilder
*
segment
,
WirePointer
*
ref
,
ObjectReader
value
))
{
static
KJ_ALWAYS_INLINE
(
SegmentAnd
<
word
*>
setObjectPointer
(
SegmentBuilder
*
segment
,
WirePointer
*
ref
,
ObjectReader
value
,
BuilderArena
*
orphanArena
=
nullptr
))
{
switch
(
value
.
kind
)
{
case
ObjectKind
:
:
NULL_POINTER
:
memset
(
ref
,
0
,
sizeof
(
*
ref
));
break
;
return
{
segment
,
nullptr
}
;
case
ObjectKind
:
:
STRUCT
:
setStructPointer
(
segment
,
ref
,
value
.
structReader
);
break
;
return
setStructPointer
(
segment
,
ref
,
value
.
structReader
,
orphanArena
);
case
ObjectKind
:
:
LIST
:
setListPointer
(
segment
,
ref
,
value
.
listReader
);
break
;
return
setListPointer
(
segment
,
ref
,
value
.
listReader
,
orphanArena
);
}
KJ_UNREACHABLE
;
}
static
void
adopt
(
SegmentBuilder
*
segment
,
WirePointer
*
ref
,
OrphanBuilder
&&
value
)
{
...
...
@@ -2139,7 +2139,7 @@ void PointerBuilder::setList(const ListReader& value) {
}
void
PointerBuilder
::
setObject
(
const
ObjectReader
&
value
)
{
return
WireHelpers
::
setObjectPointer
(
segment
,
pointer
,
value
);
WireHelpers
::
setObjectPointer
(
segment
,
pointer
,
value
);
}
void
PointerBuilder
::
adopt
(
OrphanBuilder
&&
value
)
{
...
...
@@ -2159,6 +2159,18 @@ bool PointerBuilder::isNull() {
return
pointer
->
isNull
();
}
void
PointerBuilder
::
transferFrom
(
PointerBuilder
other
)
{
WireHelpers
::
transferPointer
(
segment
,
pointer
,
other
.
segment
,
other
.
pointer
);
}
void
PointerBuilder
::
copyFrom
(
PointerReader
other
)
{
WireHelpers
::
setObjectPointer
(
segment
,
pointer
,
other
.
getObject
(
nullptr
));
}
PointerReader
PointerBuilder
::
asReader
()
const
{
return
PointerReader
(
segment
,
pointer
,
std
::
numeric_limits
<
int
>::
max
());
}
// =======================================================================================
// PointerReader
...
...
@@ -2541,6 +2553,15 @@ OrphanBuilder OrphanBuilder::copy(BuilderArena* arena, ListReader copyFrom) {
return
result
;
}
OrphanBuilder
OrphanBuilder
::
copy
(
BuilderArena
*
arena
,
PointerReader
copyFrom
)
{
OrphanBuilder
result
;
auto
allocation
=
WireHelpers
::
setObjectPointer
(
nullptr
,
result
.
tagAsPtr
(),
copyFrom
.
getObject
(
nullptr
),
arena
);
result
.
segment
=
allocation
.
segment
;
result
.
location
=
reinterpret_cast
<
word
*>
(
allocation
.
value
);
return
result
;
}
OrphanBuilder
OrphanBuilder
::
copy
(
BuilderArena
*
arena
,
Text
::
Reader
copyFrom
)
{
OrphanBuilder
result
;
auto
allocation
=
WireHelpers
::
setTextPointer
(
...
...
c++/src/capnp/layout.h
View file @
d99c0b4c
...
...
@@ -316,6 +316,8 @@ public:
void
copyFrom
(
PointerReader
other
);
// Equivalent to `set(other.get())`.
PointerReader
asReader
()
const
;
private
:
SegmentBuilder
*
segment
;
// Memory segment in which the pointer resides.
WirePointer
*
pointer
;
// Pointer to the pointer.
...
...
@@ -360,6 +362,7 @@ private:
friend
class
StructReader
;
friend
class
ListReader
;
friend
class
PointerBuilder
;
};
// -------------------------------------------------------------------
...
...
@@ -739,6 +742,7 @@ public:
static
OrphanBuilder
copy
(
BuilderArena
*
arena
,
StructReader
copyFrom
);
static
OrphanBuilder
copy
(
BuilderArena
*
arena
,
ListReader
copyFrom
);
static
OrphanBuilder
copy
(
BuilderArena
*
arena
,
PointerReader
copyFrom
);
static
OrphanBuilder
copy
(
BuilderArena
*
arena
,
Text
::
Reader
copyFrom
);
static
OrphanBuilder
copy
(
BuilderArena
*
arena
,
Data
::
Reader
copyFrom
);
...
...
c++/src/capnp/object.h
View file @
d99c0b4c
...
...
@@ -26,11 +26,13 @@
#include "layout.h"
#include "pointer-helpers.h"
#include "orphan.h"
namespace
capnp
{
class
StructSchema
;
class
ListSchema
;
class
Orphanage
;
struct
ObjectPointer
{
// Reader/Builder for the `Object` field type, i.e. a pointer that can point to an arbitrary
...
...
@@ -38,6 +40,8 @@ struct ObjectPointer {
class
Reader
{
public
:
typedef
ObjectPointer
Reads
;
Reader
()
=
default
;
inline
Reader
(
_
::
PointerReader
reader
)
:
reader
(
reader
)
{}
...
...
@@ -57,10 +61,14 @@ struct ObjectPointer {
private
:
_
::
PointerReader
reader
;
friend
struct
ObjectPointer
;
friend
class
Orphanage
;
};
class
Builder
{
public
:
typedef
ObjectPointer
Builds
;
Builder
()
=
delete
;
inline
Builder
(
decltype
(
nullptr
))
{}
inline
Builder
(
_
::
PointerBuilder
builder
)
:
builder
(
builder
)
{}
...
...
@@ -107,6 +115,9 @@ struct ObjectPointer {
inline
void
setAs
(
std
::
initializer_list
<
ReaderFor
<
ListElementType
<
T
>>>
list
);
// Valid for T = List<?>.
inline
void
set
(
Reader
value
)
{
builder
.
copyFrom
(
value
.
reader
);
}
// Set to a copy of another ObjectPointer.
template
<
typename
T
>
inline
void
adopt
(
Orphan
<
T
>&&
orphan
);
// Valid for T = any generated struct type, List<U>, Text, Data, DynamicList, DynamicStruct,
...
...
@@ -124,11 +135,69 @@ struct ObjectPointer {
inline
Orphan
<
T
>
disownAs
(
ListSchema
schema
);
// Only valid for T = DynamicList. Requires `#include <capnp/dynamic.h>`.
inline
Orphan
<
ObjectPointer
>
disown
();
// Disown without a type.
inline
Reader
asReader
()
const
{
return
Reader
(
builder
.
asReader
());
}
inline
operator
Reader
()
const
{
return
Reader
(
builder
.
asReader
());
}
private
:
_
::
PointerBuilder
builder
;
};
};
template
<>
class
Orphan
<
ObjectPointer
>
{
// An orphaned object of unknown type.
public
:
Orphan
()
=
default
;
KJ_DISALLOW_COPY
(
Orphan
);
Orphan
(
Orphan
&&
)
=
default
;
Orphan
&
operator
=
(
Orphan
&&
)
=
default
;
// It's not possible to get an ObjectPointer::{Reader,Builder} directly since there is no
// underlying pointer (the pointer would normally live in the parent, but this object is
// orphaned). It is possible, however, to request readers/builders.
template
<
typename
T
>
inline
typename
T
::
Builder
getAs
();
template
<
typename
T
>
inline
typename
T
::
Builder
getAs
(
StructSchema
schema
);
template
<
typename
T
>
inline
typename
T
::
Builder
getAs
(
ListSchema
schema
);
template
<
typename
T
>
inline
typename
T
::
Reader
getAsReader
()
const
;
template
<
typename
T
>
inline
typename
T
::
Reader
getAsReader
(
StructSchema
schema
)
const
;
template
<
typename
T
>
inline
typename
T
::
Reader
getAsReader
(
ListSchema
schema
)
const
;
template
<
typename
T
>
inline
Orphan
<
T
>
releaseAs
();
template
<
typename
T
>
inline
Orphan
<
T
>
releaseAs
(
StructSchema
schema
);
template
<
typename
T
>
inline
Orphan
<
T
>
releaseAs
(
ListSchema
schema
);
// Down-cast the orphan to a specific type.
inline
bool
operator
==
(
decltype
(
nullptr
))
const
{
return
builder
==
nullptr
;
}
inline
bool
operator
!=
(
decltype
(
nullptr
))
const
{
return
builder
!=
nullptr
;
}
private
:
_
::
OrphanBuilder
builder
;
inline
Orphan
(
_
::
OrphanBuilder
&&
builder
)
:
builder
(
kj
::
mv
(
builder
))
{}
template
<
typename
,
Kind
>
friend
struct
_
::
PointerHelpers
;
friend
class
Orphanage
;
template
<
typename
U
>
friend
class
Orphan
;
friend
class
ObjectPointer
::
Builder
;
};
// =======================================================================================
// Inline implementation details
...
...
@@ -185,6 +254,33 @@ inline Orphan<T> ObjectPointer::Builder::disownAs() {
return
_
::
PointerHelpers
<
T
>::
disown
(
builder
);
}
inline
Orphan
<
ObjectPointer
>
ObjectPointer
::
Builder
::
disown
()
{
return
Orphan
<
ObjectPointer
>
(
builder
.
disown
());
}
template
<>
struct
ReaderFor_
<
ObjectPointer
,
Kind
::
UNKNOWN
>
{
typedef
ObjectPointer
::
Reader
Type
;
};
template
<>
struct
BuilderFor_
<
ObjectPointer
,
Kind
::
UNKNOWN
>
{
typedef
ObjectPointer
::
Builder
Type
;
};
template
<>
struct
Orphanage
::
GetInnerReader
<
ObjectPointer
,
Kind
::
UNKNOWN
>
{
static
inline
_
::
PointerReader
apply
(
const
ObjectPointer
::
Reader
&
t
)
{
return
t
.
reader
;
}
};
template
<
typename
T
>
inline
typename
T
::
Builder
Orphan
<
ObjectPointer
>::
getAs
()
{
return
_
::
OrphanGetImpl
<
T
>::
apply
(
builder
);
}
template
<
typename
T
>
inline
typename
T
::
Reader
Orphan
<
ObjectPointer
>::
getAsReader
()
const
{
return
_
::
OrphanGetImpl
<
T
>::
applyReader
(
builder
);
}
template
<
typename
T
>
inline
Orphan
<
T
>
Orphan
<
ObjectPointer
>::
releaseAs
()
{
return
Orphan
<
T
>
(
kj
::
mv
(
builder
));
}
}
// namespace capnp
#endif // CAPNP_OBJECT_H_
c++/src/capnp/orphan-test.c++
View file @
d99c0b4c
...
...
@@ -529,14 +529,12 @@ TEST(Orphans, DynamicObject) {
initTestMessage
(
root
.
getObjectField
().
initAs
<
TestAllTypes
>
());
EXPECT_TRUE
(
root
.
hasObjectField
());
Orphan
<
DynamicValue
>
orphan
=
root
.
getObjectField
().
disown
As
<
DynamicObject
>
();
Orphan
<
DynamicValue
>
orphan
=
root
.
getObjectField
().
disown
();
EXPECT_EQ
(
DynamicValue
::
OBJECT
,
orphan
.
getType
());
checkTestMessage
(
orphan
.
getReader
().
as
<
DynamicObject
>
().
as
<
TestAllTypes
>
());
Orphan
<
DynamicObject
>
objectOrphan
=
orphan
.
releaseAs
<
DynamicObject
>
();
Orphan
<
ObjectPointer
>
objectOrphan
=
orphan
.
releaseAs
<
ObjectPointer
>
();
checkTestMessage
(
objectOrphan
.
getAs
<
TestAllTypes
>
());
checkDynamicTestMessage
(
objectOrphan
.
getAs
(
Schema
::
from
<
TestAllTypes
>
()));
checkDynamicTestMessage
(
objectOrphan
.
getAs
<
DynamicStruct
>
(
Schema
::
from
<
TestAllTypes
>
()));
}
TEST
(
Orphans
,
DynamicDisown
)
{
...
...
c++/src/capnp/stringify.c++
View file @
d99c0b4c
...
...
@@ -267,8 +267,6 @@ kj::StringTree prettyPrint(DynamicList::Builder value) { return prettyPrint(valu
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicValue
::
Reader
&
value
)
{
return
stringify
(
value
);
}
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicValue
::
Builder
&
value
)
{
return
stringify
(
value
.
asReader
());
}
kj
::
StringTree
KJ_STRINGIFY
(
DynamicEnum
value
)
{
return
stringify
(
value
);
}
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicObject
::
Reader
&
value
)
{
return
stringify
(
value
);
}
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicObject
::
Builder
&
value
)
{
return
stringify
(
value
.
asReader
());
}
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicStruct
::
Reader
&
value
)
{
return
stringify
(
value
);
}
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicStruct
::
Builder
&
value
)
{
return
stringify
(
value
.
asReader
());
}
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicList
::
Reader
&
value
)
{
return
stringify
(
value
);
}
...
...
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