Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
J
json
Project
Overview
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
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
json
Commits
a32de3b5
Commit
a32de3b5
authored
Jan 08, 2017
by
Théo DELRIEU
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
replace constructor by from/to_json: number_unsigned_t
This commit forces a design change in custom JSONSerializer, which might be temporary
parent
d257149f
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
73 additions
and
128 deletions
+73
-128
json.hpp
src/json.hpp
+30
-61
json.hpp.re2c
src/json.hpp.re2c
+30
-61
unit-udt.cpp
test/src/unit-udt.cpp
+13
-6
No files found.
src/json.hpp
View file @
a32de3b5
...
@@ -248,6 +248,18 @@ struct external_constructor<value_t::number_float>
...
@@ -248,6 +248,18 @@ struct external_constructor<value_t::number_float>
}
}
};
};
template
<>
struct
external_constructor
<
value_t
::
number_unsigned
>
{
template
<
typename
Json
>
static
void
construct
(
Json
&
j
,
typename
Json
::
number_unsigned_t
val
)
noexcept
{
j
.
m_type
=
value_t
::
number_unsigned
;
j
.
m_value
=
val
;
j
.
assert_invariant
();
}
};
// very useful construct against boilerplate (more boilerplate needed than in
// very useful construct against boilerplate (more boilerplate needed than in
// C++17: http://en.cppreference.com/w/cpp/types/void_t)
// C++17: http://en.cppreference.com/w/cpp/types/void_t)
template
<
typename
...
>
struct
make_void
template
<
typename
...
>
struct
make_void
...
@@ -411,9 +423,7 @@ struct is_compatible_basic_json_type
...
@@ -411,9 +423,7 @@ struct is_compatible_basic_json_type
std
::
is_same
<
T
,
BasicJson
>::
value
or
std
::
is_same
<
T
,
BasicJson
>::
value
or
is_compatible_array_type
<
BasicJson
,
T
>::
value
or
is_compatible_array_type
<
BasicJson
,
T
>::
value
or
is_compatible_object_type
<
typename
BasicJson
::
object_t
,
T
>::
value
or
is_compatible_object_type
<
typename
BasicJson
::
object_t
,
T
>::
value
or
is_compatible_integer_type
<
typename
BasicJson
::
number_integer_t
,
T
>::
value
or
is_compatible_integer_type
<
typename
BasicJson
::
number_integer_t
,
T
>::
value
;
is_compatible_integer_type
<
typename
BasicJson
::
number_unsigned_t
,
T
>::
value
;
};
};
template
<
typename
T
,
typename
BasicJson
,
typename
PrimitiveIterator
>
template
<
typename
T
,
typename
BasicJson
,
typename
PrimitiveIterator
>
...
@@ -526,6 +536,17 @@ void to_json(Json &j, CompatibleNumberFloatType val) noexcept
...
@@ -526,6 +536,17 @@ void to_json(Json &j, CompatibleNumberFloatType val) noexcept
external_constructor
<
value_t
::
number_float
>::
construct
(
j
,
val
);
external_constructor
<
value_t
::
number_float
>::
construct
(
j
,
val
);
}
}
template
<
typename
Json
,
typename
CompatibleNumberUnsignedType
,
enable_if_t
<
is_compatible_integer_type
<
typename
Json
::
number_unsigned_t
,
CompatibleNumberUnsignedType
>::
value
,
int
>
=
0
>
void
to_json
(
Json
&
j
,
CompatibleNumberUnsignedType
val
)
noexcept
{
external_constructor
<
value_t
::
number_unsigned
>::
construct
(
j
,
val
);
}
template
<
typename
Json
>
template
<
typename
Json
>
void
from_json
(
Json
const
&
j
,
typename
Json
::
boolean_t
&
b
)
void
from_json
(
Json
const
&
j
,
typename
Json
::
boolean_t
&
b
)
{
{
...
@@ -548,6 +569,12 @@ void from_json(Json const& j, typename Json::number_float_t& val)
...
@@ -548,6 +569,12 @@ void from_json(Json const& j, typename Json::number_float_t& val)
get_arithmetic_value
(
j
,
val
);
get_arithmetic_value
(
j
,
val
);
}
}
template
<
typename
Json
>
void
from_json
(
Json
const
&
j
,
typename
Json
::
number_unsigned_t
&
val
)
{
get_arithmetic_value
(
j
,
val
);
}
// overload for arithmetic types, not chosen for basic_json template arguments (BooleanType, etc..)
// overload for arithmetic types, not chosen for basic_json template arguments (BooleanType, etc..)
//
//
// note: Is it really necessary to provide explicit overloads for boolean_t etc..
// note: Is it really necessary to provide explicit overloads for boolean_t etc..
...
@@ -1898,64 +1925,6 @@ class basic_json
...
@@ -1898,64 +1925,6 @@ class basic_json
}
}
/*!
/*!
@brief create an unsigned integer number (explicit)
Create an unsigned integer number JSON value with a given content.
@tparam T helper type to compare number_unsigned_t and unsigned int (not
visible in) the interface.
@param[in] val an integer to create a JSON number from
@complexity Constant.
@sa @ref basic_json(const CompatibleNumberUnsignedType) -- create a number
value (unsigned integer) from a compatible number type
@since version 2.0.0
*/
template
<
typename
T
,
typename
std
::
enable_if
<
not
(
std
::
is_same
<
T
,
int
>::
value
)
and
std
::
is_same
<
T
,
number_unsigned_t
>::
value
,
int
>::
type
=
0
>
basic_json
(
const
number_unsigned_t
val
)
noexcept
:
m_type
(
value_t
::
number_unsigned
),
m_value
(
val
)
{
assert_invariant
();
}
/*!
@brief create an unsigned number (implicit)
Create an unsigned number JSON value with a given content. This
constructor allows any type @a CompatibleNumberUnsignedType that can be
used to construct values of type @ref number_unsigned_t.
@tparam CompatibleNumberUnsignedType An integer type which is compatible
to @ref number_unsigned_t. Examples may include the types `unsigned int`,
`uint32_t`, or `unsigned short`.
@param[in] val an unsigned integer to create a JSON number from
@complexity Constant.
@sa @ref basic_json(const number_unsigned_t) -- create a number value
(unsigned)
@since version 2.0.0
*/
template
<
typename
CompatibleNumberUnsignedType
,
enable_if_t
<
detail
::
is_compatible_integer_type
<
number_unsigned_t
,
CompatibleNumberUnsignedType
>::
value
,
int
>
=
0
>
basic_json
(
const
CompatibleNumberUnsignedType
val
)
noexcept
:
m_type
(
value_t
::
number_unsigned
),
m_value
(
static_cast
<
number_unsigned_t
>
(
val
))
{
assert_invariant
();
}
/*!
@brief create a container (array or object) from an initializer list
@brief create a container (array or object) from an initializer list
Creates a JSON value of type array or object from the passed initializer
Creates a JSON value of type array or object from the passed initializer
...
...
src/json.hpp.re2c
View file @
a32de3b5
...
@@ -248,6 +248,18 @@ struct external_constructor<value_t::number_float>
...
@@ -248,6 +248,18 @@ struct external_constructor<value_t::number_float>
}
}
};
};
template <>
struct external_constructor<value_t::number_unsigned>
{
template <typename Json>
static void construct(Json &j, typename Json::number_unsigned_t val) noexcept
{
j.m_type = value_t::number_unsigned;
j.m_value = val;
j.assert_invariant();
}
};
// very useful construct against boilerplate (more boilerplate needed than in
// very useful construct against boilerplate (more boilerplate needed than in
// C++17: http://en.cppreference.com/w/cpp/types/void_t)
// C++17: http://en.cppreference.com/w/cpp/types/void_t)
template <typename...> struct make_void
template <typename...> struct make_void
...
@@ -411,9 +423,7 @@ struct is_compatible_basic_json_type
...
@@ -411,9 +423,7 @@ struct is_compatible_basic_json_type
std::is_same<T, BasicJson>::value or
std::is_same<T, BasicJson>::value or
is_compatible_array_type<BasicJson, T>::value or
is_compatible_array_type<BasicJson, T>::value or
is_compatible_object_type<typename BasicJson::object_t, T>::value or
is_compatible_object_type<typename BasicJson::object_t, T>::value or
is_compatible_integer_type<typename BasicJson::number_integer_t, T>::value or
is_compatible_integer_type<typename BasicJson::number_integer_t, T>::value;
is_compatible_integer_type<typename BasicJson::number_unsigned_t,
T>::value;
};
};
template <typename T, typename BasicJson, typename PrimitiveIterator>
template <typename T, typename BasicJson, typename PrimitiveIterator>
...
@@ -526,6 +536,17 @@ void to_json(Json &j, CompatibleNumberFloatType val) noexcept
...
@@ -526,6 +536,17 @@ void to_json(Json &j, CompatibleNumberFloatType val) noexcept
external_constructor<value_t::number_float>::construct(j, val);
external_constructor<value_t::number_float>::construct(j, val);
}
}
template <
typename Json, typename CompatibleNumberUnsignedType,
enable_if_t<is_compatible_integer_type<typename Json::number_unsigned_t,
CompatibleNumberUnsignedType>::value,
int> = 0>
void to_json(Json &j, CompatibleNumberUnsignedType val) noexcept
{
external_constructor<value_t::number_unsigned>::construct(j, val);
}
template <typename Json>
template <typename Json>
void from_json(Json const& j, typename Json::boolean_t& b)
void from_json(Json const& j, typename Json::boolean_t& b)
{
{
...
@@ -548,6 +569,12 @@ void from_json(Json const& j, typename Json::number_float_t& val)
...
@@ -548,6 +569,12 @@ void from_json(Json const& j, typename Json::number_float_t& val)
get_arithmetic_value(j, val);
get_arithmetic_value(j, val);
}
}
template <typename Json>
void from_json(Json const& j, typename Json::number_unsigned_t& val)
{
get_arithmetic_value(j, val);
}
// overload for arithmetic types, not chosen for basic_json template arguments (BooleanType, etc..)
// overload for arithmetic types, not chosen for basic_json template arguments (BooleanType, etc..)
//
//
// note: Is it really necessary to provide explicit overloads for boolean_t etc..
// note: Is it really necessary to provide explicit overloads for boolean_t etc..
...
@@ -1899,64 +1926,6 @@ class basic_json
...
@@ -1899,64 +1926,6 @@ class basic_json
}
}
/*!
/*!
@brief create an unsigned integer number (explicit)
Create an unsigned integer number JSON value with a given content.
@tparam T helper type to compare number_unsigned_t and unsigned int (not
visible in) the interface.
@param[in] val an integer to create a JSON number from
@complexity Constant.
@sa @ref basic_json(const CompatibleNumberUnsignedType) -- create a number
value (unsigned integer) from a compatible number type
@since version 2.0.0
*/
template<typename T, typename std::enable_if<
not (std::is_same<T, int>::value) and
std::is_same<T, number_unsigned_t>::value, int>::type = 0>
basic_json(const number_unsigned_t val) noexcept
: m_type(value_t::number_unsigned), m_value(val)
{
assert_invariant();
}
/*!
@brief create an unsigned number (implicit)
Create an unsigned number JSON value with a given content. This
constructor allows any type @a CompatibleNumberUnsignedType that can be
used to construct values of type @ref number_unsigned_t.
@tparam CompatibleNumberUnsignedType An integer type which is compatible
to @ref number_unsigned_t. Examples may include the types `unsigned int`,
`uint32_t`, or `unsigned short`.
@param[in] val an unsigned integer to create a JSON number from
@complexity Constant.
@sa @ref basic_json(const number_unsigned_t) -- create a number value
(unsigned)
@since version 2.0.0
*/
template <
typename CompatibleNumberUnsignedType,
enable_if_t<detail::is_compatible_integer_type<
number_unsigned_t, CompatibleNumberUnsignedType>::value,
int> = 0 >
basic_json(const CompatibleNumberUnsignedType val) noexcept
: m_type(value_t::number_unsigned),
m_value(static_cast<number_unsigned_t>(val))
{
assert_invariant();
}
/*!
@brief create a container (array or object) from an initializer list
@brief create a container (array or object) from an initializer list
Creates a JSON value of type array or object from the passed initializer
Creates a JSON value of type array or object from the passed initializer
...
...
test/src/unit-udt.cpp
View file @
a32de3b5
...
@@ -483,13 +483,20 @@ TEST_CASE("Non-copyable types", "[udt]")
...
@@ -483,13 +483,20 @@ TEST_CASE("Non-copyable types", "[udt]")
template
<
typename
T
,
typename
=
typename
std
::
enable_if
<
std
::
is_pod
<
T
>::
value
>::
type
>
template
<
typename
T
,
typename
=
typename
std
::
enable_if
<
std
::
is_pod
<
T
>::
value
>::
type
>
struct
pod_serializer
struct
pod_serializer
{
{
// I could forward-declare this struct, and add a basic_json alias
template
<
typename
Json
>
template
<
typename
Json
>
static
void
from_json
(
Json
const
&
j
,
T
&
t
)
static
void
from_json
(
Json
const
&
j
,
T
&
t
)
{
{
auto
value
=
j
.
template
get
<
std
::
uint64_t
>
();
std
::
uint64_t
value
;
auto
bytes
=
static_cast
<
char
*>
(
static_cast
<
void
*>
(
&
value
));
// Why cannot we simply use: j.get<std::uint64_t>() ?
std
::
memcpy
(
&
t
,
bytes
,
sizeof
(
value
));
// Well, with the current experiment, the get method looks for a from_json function, which we are currently defining!
// This would end up in a stack overflow. Calling nlohmann::from_json is a workaround.
// I shall find a good way to avoid this once all constructors are converted to free methods
//
// In short, constructing a json by constructor calls to_json
// calling get calls from_json, for now, we cannot do this in custom serializers
nlohmann
::
from_json
(
j
,
value
);
auto
bytes
=
static_cast
<
char
*>
(
static_cast
<
void
*>
(
&
value
));
std
::
memcpy
(
&
t
,
bytes
,
sizeof
(
value
));
}
}
template
<
typename
Json
>
template
<
typename
Json
>
...
@@ -501,8 +508,8 @@ struct pod_serializer
...
@@ -501,8 +508,8 @@ struct pod_serializer
{
{
value
|=
bytes
[
i
]
<<
8
*
i
;
value
|=
bytes
[
i
]
<<
8
*
i
;
}
}
// same thing here
j
=
value
;
nlohmann
::
to_json
(
j
,
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