Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
MODMED
modmedLog
Commits
599d3cd5
Commit
599d3cd5
authored
Jul 30, 2018
by
EXT Arnaud Clère
Browse files
Added support for .any() "wildcard" to allow partial QBind and data
schema evolution
parent
1cd6dcfe
Changes
4
Hide whitespace changes
Inline
Side-by-side
tests/QBind/QBind_impl.h
View file @
599d3cd5
...
...
@@ -124,6 +124,8 @@ struct BindNative {};
struct
BindGeneric
{};
template
<
class
TImpl
,
typename
T
,
typename
TEnabledIf
=
void
>
struct
BindSupport
:
BindGeneric
{};
template
<
class
TImpl
>
struct
BindSupport
<
TImpl
,
void
,
void
>
:
BindGeneric
{};
template
<
class
T_
>
class
Rec
;
//!< a Record data structure (not defined in this Proof-Of-Concept for the sake of simplicity)
template
<
class
T_
>
class
Seq
;
//!< a Sequence data structure defined below
...
...
@@ -140,12 +142,15 @@ public:
operator
bool
()
{
return
m_out
.
operator
bool
();
}
//!< to drive QBind<TResult,T>() traversal
TImpl
*
operator
->
()
{
return
m_out
.
operator
->
();
}
template
<
typename
T
>
T_
bind
(
T
&&
t
)
{
if
(
_bind
(
std
::
forward
<
T
>
(
t
),
BindSupport
<
TImpl
,
T
>
()))
return
std
::
move
(
m_out
)
;
else
return
T_
();
}
/**/
T_
null
()
{
if
(
Q_LIKELY
(
m_out
)
&&
m_out
->
_null
())
return
std
::
move
(
m_out
)
;
else
return
T_
();
}
/**/
Seq
<
T_
>
sequence
()
{
if
(
Q_LIKELY
(
m_out
)
&&
m_out
->
_sequence
())
return
Seq
<
T_
>
(
std
::
move
(
m_out
));
else
return
Seq
<
T_
>
();
}
/**/
T_
null
()
{
if
(
Q_LIKELY
(
m_out
)
&&
m_out
->
_null
())
return
std
::
move
(
m_out
)
;
else
return
T_
();
}
/**/
Seq
<
T_
>
sequence
()
{
if
(
Q_LIKELY
(
m_out
)
&&
m_out
->
_sequence
())
return
Seq
<
T_
>
(
std
::
move
(
m_out
));
else
return
Seq
<
T_
>
();
}
template
<
typename
T
>
T_
bind
(
T
&&
t
)
{
if
(
_bind
(
BindSupport
<
TImpl
,
T
>
(),
std
::
forward
<
T
>
(
t
)))
return
std
::
move
(
m_out
)
;
else
return
T_
();
}
/**/
T_
any
()
{
if
(
_bind
(
BindSupport
<
TImpl
,
void
>
()
))
return
std
::
move
(
m_out
)
;
else
return
T_
();
}
private:
template
<
typename
T
>
bool
_bind
(
T
&&
t
,
BindNative
)
{
return
Q_LIKELY
(
m_out
)
&&
m_out
->
_bind
(
std
::
forward
<
T
>
(
t
));
}
template
<
typename
T
>
bool
_bind
(
T
&&
t
,
BindGeneric
)
{
return
QBind
<
TResult
,
T
&&>::
bind
(
Val
<
TResult
>
(
m_out
.
_unsafeCopy
()),
std
::
forward
<
T
>
(
t
));
}
template
<
typename
T
>
bool
_bind
(
BindNative
,
T
&&
t
)
{
return
Q_LIKELY
(
m_out
)
&&
m_out
->
_bind
(
std
::
forward
<
T
>
(
t
));
}
template
<
typename
T
>
bool
_bind
(
BindGeneric
,
T
&&
t
)
{
return
QBind
<
TResult
,
T
&&>::
bind
(
Val
<
TResult
>
(
m_out
.
_unsafeCopy
()),
std
::
forward
<
T
>
(
t
));
}
/**/
bool
_bind
(
BindNative
)
{
return
Q_LIKELY
(
m_out
)
&&
m_out
->
_bind
(
);
}
/**/
bool
_bind
(
BindGeneric
)
{
return
QBind
<
TResult
,
void
>::
bind
(
Val
<
TResult
>
(
m_out
.
_unsafeCopy
())
);
}
T_
m_out
=
T_
();
//!< moved context of current traversal up to TResult that will reference the val itself (be it a QIODevice or QCborValue)
};
...
...
@@ -171,7 +176,10 @@ public:
TResult
result
()
{
return
operator
TResult
();
}
// Shortcuts
template
<
typename
T
>
Seq
<
T_
>
bind
(
T
&&
t
)
{
return
item
().
bind
(
std
::
forward
<
T
>
(
t
));
}
/**/
Seq
<
T_
>
any
()
{
return
item
().
any
();
}
/**/
Seq
<
T_
>
null
()
{
return
item
().
null
();
}
/**/
Seq
<
Seq
<
T_
>>
sequence
()
{
return
item
().
sequence
();
}
template
<
typename
T
>
Seq
<
T_
>
bind
(
T
&&
t
)
{
return
item
().
bind
(
std
::
forward
<
T
>
(
t
));
}
private:
template
<
class
TSrcResult
,
typename
TDst
,
typename
TEnabledIf
>
friend
struct
QBind
;
// restricting to <TSrcResult, Val<TDst>&&, IsReader<TSrcResult>>; is not possible in C++11
Val
<
TResult
>
_unsafeItem
(
int
min
=
1
)
{
if
(
Q_LIKELY
(
m_out
)
&&
m_out
->
_item
(
min
))
return
Val
<
TResult
>
(
m_out
.
_unsafeCopy
());
else
return
Val
<
TResult
>
();
}
...
...
@@ -277,6 +285,26 @@ private:
// //////////////////////////////////////////////////////////////////////////
// QBind partial specializations (generic on TResult, usually not on TResult::Mode for dynamically-sized or builtin types)
template
<
class
TResult
>
struct
QBind
<
TResult
,
void
,
IsWriter
<
TResult
>>
{
static
TResult
bind
(
Val
<
TResult
>
dst
)
{
return
dst
.
null
();
}};
template
<
class
TResult
>
struct
QBind
<
TResult
,
void
,
IsReader
<
TResult
>>
{
static
TResult
bind
(
Val
<
TResult
>
src
)
{
TResult
srcRes
;
{
ScopedChoice
<
Val
<
TResult
>>
choice
(
src
);
Seq
<
TResult
>
srcSeq
;
if
(
srcSeq
=
src
.
sequence
())
{
return
srcSeq
.
out
();
}
QString
t
;
if
(
srcRes
=
src
.
bind
(
t
))
{
return
srcRes
;
}
}
return
src
.
null
();
}};
#include <cstddef>
template
<
class
TResult
>
...
...
tests/QBind/QCbor_impl.h
View file @
599d3cd5
...
...
@@ -115,8 +115,8 @@ protected:
friend
class
QMovedWriter
<
CborWriter
>
;
template
<
class
T_
>
friend
class
Val
;
// calls methods below
bool
_sequence
()
{
levels
++
;
return
io
->
putChar
(
cbor
::
IndefiniteLengthArrayByte
)
;
}
bool
_null
()
{
return
io
->
putChar
(
cbor
::
NullByte
)
;
}
bool
_sequence
()
{
levels
++
;
return
io
->
putChar
(
cbor
::
IndefiniteLengthArrayByte
)
;
}
bool
_bind
(
const
char
*
s
)
{
return
(
putInteger
(
cbor
::
TextStringType
,
strlen
(
s
))
&&
io
->
write
(
s
));
}
// Natively supported overloads
...
...
tests/QBind/QJson_impl.h
View file @
599d3cd5
...
...
@@ -375,12 +375,13 @@ protected:
double
d
;
qlonglong
i
;
bool
isNegative
;
auto
r
=
getNumber
(
d
,
i
,
isNegative
);
if
(
r
)
t
=
(
isNegative
?-
i
:
i
);
return
r
;
}
bool
_any
()
{
QByteArray
t
;
double
d
;
bool
b
;
bool
_bind
()
{
QByteArray
t
;
double
d
;
bool
b
;
return
(
_sequence
()
&&
_out
())
||
_bind
(
t
)
||
_bind
(
d
)
||
_null
()
||
_bind
(
b
)
||
_null
();
}
||
_bind
(
d
)
||
_bind
(
t
)
// including any other?
;}
template
<
class
T_
>
friend
class
Seq
;
// calls methods below
...
...
@@ -394,7 +395,7 @@ protected:
return
true
;
}
bool
_out
(
int
max
=-
1
)
{
auto
level
=
levels
.
pop
();
while
((
max
<
0
||
0
<
max
--
)
&&
get
(
','
,
level
.
end
))
{
_
any
();
_
bind
();
}
return
get
(
*
level
.
end
,
"}"
);
}
...
...
@@ -503,6 +504,7 @@ private:
}
};
QJsonReader
::
QJsonReader
(
QIODevice
*
io
)
:
QScopedResult
(
new
QJsonReaderImpl
(
io
),
true
)
{}
template
<
>
struct
BindSupport
<
QJsonReaderImpl
,
void
>
:
BindNative
{};
template
<
>
struct
BindSupport
<
QJsonReaderImpl
,
QByteArray
&>
:
BindNative
{};
template
<
>
struct
BindSupport
<
QJsonReaderImpl
,
bool
&>
:
BindNative
{};
template
<
>
struct
BindSupport
<
QJsonReaderImpl
,
float
&>
:
BindNative
{};
...
...
tests/QBind/main.cpp
View file @
599d3cd5
...
...
@@ -63,7 +63,7 @@ struct Person
.
bind
(
firstName
)
.
bind
(
lastName
)
.
bind
(
height
)
.
bind
(
age
)
//
TODO
.any()
//
ignored
.
bind
(
age
)
// .any() ignored
.
bind
(
phones
)
// recursive calls to QBind will take care of that part
;
// automagically closes all opened structures
}
...
...
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