Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
J
json
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
json
Commits
f364f5ac
Unverified
Commit
f364f5ac
authored
Aug 14, 2017
by
Théo DELRIEU
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add detail/meta.hpp
parent
d686713f
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
230 additions
and
212 deletions
+230
-212
Makefile
Makefile
+3
-1
src/detail/meta.hpp
src/detail/meta.hpp
+226
-0
src/json.hpp
src/json.hpp
+1
-211
No files found.
Makefile
View file @
f364f5ac
...
...
@@ -4,7 +4,9 @@ SRCDIR = src
SRCS
=
${SRCDIR}
/json.hpp
\
${SRCDIR}
/json_fwd.hpp
\
${SRCDIR}
/detail/macro_scope.hpp
\
${SRCDIR}
/detail/macro_unscope.hpp
${SRCDIR}
/detail/macro_unscope.hpp
\
${SRCDIR}
/detail/meta.hpp
# main target
all
:
...
...
src/detail/meta.hpp
0 → 100644
View file @
f364f5ac
#ifndef NLOHMANN_JSON_DETAIL_META_HPP
#define NLOHMANN_JSON_DETAIL_META_HPP
#include <cstdint>
#include <limits>
#include <type_traits> // add_pointer, conditional, decay, enable_if, false_type, integral_constant, is_arithmetic, is_base_of, is_const, is_constructible, is_convertible, is_default_constructible, is_enum, is_floating_point, is_integral, is_nothrow_move_assignable, is_nothrow_move_constructible, is_pointer, is_reference, is_same, is_scalar, is_signed, remove_const, remove_cv, remove_pointer, remove_reference, true_type, underlying_type
#include <utility>
#include "json_fwd.hpp"
#include "detail/macro_scope.hpp"
namespace
nlohmann
{
/*!
@brief detail namespace with internal helper functions
This namespace collects functions that should not be exposed,
implementations of some @ref basic_json methods, and meta-programming helpers.
@since version 2.1.0
*/
namespace
detail
{
/////////////
// helpers //
/////////////
template
<
typename
>
struct
is_basic_json
:
std
::
false_type
{};
NLOHMANN_BASIC_JSON_TPL_DECLARATION
struct
is_basic_json
<
NLOHMANN_BASIC_JSON_TPL
>
:
std
::
true_type
{};
// alias templates to reduce boilerplate
template
<
bool
B
,
typename
T
=
void
>
using
enable_if_t
=
typename
std
::
enable_if
<
B
,
T
>::
type
;
template
<
typename
T
>
using
uncvref_t
=
typename
std
::
remove_cv
<
typename
std
::
remove_reference
<
T
>::
type
>::
type
;
// implementation of C++14 index_sequence and affiliates
// source: https://stackoverflow.com/a/32223343
template
<
std
::
size_t
...
Ints
>
struct
index_sequence
{
using
type
=
index_sequence
;
using
value_type
=
std
::
size_t
;
static
constexpr
std
::
size_t
size
()
noexcept
{
return
sizeof
...(
Ints
);
}
};
template
<
class
Sequence1
,
class
Sequence2
>
struct
merge_and_renumber
;
template
<
std
::
size_t
...
I1
,
std
::
size_t
...
I2
>
struct
merge_and_renumber
<
index_sequence
<
I1
...
>
,
index_sequence
<
I2
...
>>
:
index_sequence
<
I1
...,
(
sizeof
...(
I1
)
+
I2
)...
>
{};
template
<
std
::
size_t
N
>
struct
make_index_sequence
:
merge_and_renumber
<
typename
make_index_sequence
<
N
/
2
>::
type
,
typename
make_index_sequence
<
N
-
N
/
2
>::
type
>
{};
template
<
>
struct
make_index_sequence
<
0
>
:
index_sequence
<>
{};
template
<
>
struct
make_index_sequence
<
1
>
:
index_sequence
<
0
>
{};
template
<
typename
...
Ts
>
using
index_sequence_for
=
make_index_sequence
<
sizeof
...(
Ts
)
>
;
/*
Implementation of two C++17 constructs: conjunction, negation. This is needed
to avoid evaluating all the traits in a condition
For example: not std::is_same<void, T>::value and has_value_type<T>::value
will not compile when T = void (on MSVC at least). Whereas
conjunction<negation<std::is_same<void, T>>, has_value_type<T>>::value will
stop evaluating if negation<...>::value == false
Please note that those constructs must be used with caution, since symbols can
become very long quickly (which can slow down compilation and cause MSVC
internal compiler errors). Only use it when you have to (see example ahead).
*/
template
<
class
...
>
struct
conjunction
:
std
::
true_type
{};
template
<
class
B1
>
struct
conjunction
<
B1
>
:
B1
{};
template
<
class
B1
,
class
...
Bn
>
struct
conjunction
<
B1
,
Bn
...
>
:
std
::
conditional
<
bool
(
B1
::
value
),
conjunction
<
Bn
...
>
,
B1
>::
type
{};
template
<
class
B
>
struct
negation
:
std
::
integral_constant
<
bool
,
not
B
::
value
>
{};
// dispatch utility (taken from ranges-v3)
template
<
unsigned
N
>
struct
priority_tag
:
priority_tag
<
N
-
1
>
{};
template
<
>
struct
priority_tag
<
0
>
{};
////////////////////////
// has_/is_ functions //
////////////////////////
NLOHMANN_JSON_HAS_HELPER
(
mapped_type
);
NLOHMANN_JSON_HAS_HELPER
(
key_type
);
NLOHMANN_JSON_HAS_HELPER
(
value_type
);
NLOHMANN_JSON_HAS_HELPER
(
iterator
);
template
<
bool
B
,
class
RealType
,
class
CompatibleObjectType
>
struct
is_compatible_object_type_impl
:
std
::
false_type
{};
template
<
class
RealType
,
class
CompatibleObjectType
>
struct
is_compatible_object_type_impl
<
true
,
RealType
,
CompatibleObjectType
>
{
static
constexpr
auto
value
=
std
::
is_constructible
<
typename
RealType
::
key_type
,
typename
CompatibleObjectType
::
key_type
>::
value
and
std
::
is_constructible
<
typename
RealType
::
mapped_type
,
typename
CompatibleObjectType
::
mapped_type
>::
value
;
};
template
<
class
BasicJsonType
,
class
CompatibleObjectType
>
struct
is_compatible_object_type
{
static
auto
constexpr
value
=
is_compatible_object_type_impl
<
conjunction
<
negation
<
std
::
is_same
<
void
,
CompatibleObjectType
>>
,
has_mapped_type
<
CompatibleObjectType
>
,
has_key_type
<
CompatibleObjectType
>>::
value
,
typename
BasicJsonType
::
object_t
,
CompatibleObjectType
>::
value
;
};
template
<
typename
BasicJsonType
,
typename
T
>
struct
is_basic_json_nested_type
{
static
auto
constexpr
value
=
std
::
is_same
<
T
,
typename
BasicJsonType
::
iterator
>::
value
or
std
::
is_same
<
T
,
typename
BasicJsonType
::
const_iterator
>::
value
or
std
::
is_same
<
T
,
typename
BasicJsonType
::
reverse_iterator
>::
value
or
std
::
is_same
<
T
,
typename
BasicJsonType
::
const_reverse_iterator
>::
value
;
};
template
<
class
BasicJsonType
,
class
CompatibleArrayType
>
struct
is_compatible_array_type
{
static
auto
constexpr
value
=
conjunction
<
negation
<
std
::
is_same
<
void
,
CompatibleArrayType
>>
,
negation
<
is_compatible_object_type
<
BasicJsonType
,
CompatibleArrayType
>>
,
negation
<
std
::
is_constructible
<
typename
BasicJsonType
::
string_t
,
CompatibleArrayType
>>
,
negation
<
is_basic_json_nested_type
<
BasicJsonType
,
CompatibleArrayType
>>
,
has_value_type
<
CompatibleArrayType
>
,
has_iterator
<
CompatibleArrayType
>>::
value
;
};
template
<
bool
,
typename
,
typename
>
struct
is_compatible_integer_type_impl
:
std
::
false_type
{};
template
<
typename
RealIntegerType
,
typename
CompatibleNumberIntegerType
>
struct
is_compatible_integer_type_impl
<
true
,
RealIntegerType
,
CompatibleNumberIntegerType
>
{
// is there an assert somewhere on overflows?
using
RealLimits
=
std
::
numeric_limits
<
RealIntegerType
>
;
using
CompatibleLimits
=
std
::
numeric_limits
<
CompatibleNumberIntegerType
>
;
static
constexpr
auto
value
=
std
::
is_constructible
<
RealIntegerType
,
CompatibleNumberIntegerType
>::
value
and
CompatibleLimits
::
is_integer
and
RealLimits
::
is_signed
==
CompatibleLimits
::
is_signed
;
};
template
<
typename
RealIntegerType
,
typename
CompatibleNumberIntegerType
>
struct
is_compatible_integer_type
{
static
constexpr
auto
value
=
is_compatible_integer_type_impl
<
std
::
is_integral
<
CompatibleNumberIntegerType
>::
value
and
not
std
::
is_same
<
bool
,
CompatibleNumberIntegerType
>::
value
,
RealIntegerType
,
CompatibleNumberIntegerType
>
::
value
;
};
// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
template
<
typename
BasicJsonType
,
typename
T
>
struct
has_from_json
{
private:
// also check the return type of from_json
template
<
typename
U
,
typename
=
enable_if_t
<
std
::
is_same
<
void
,
decltype
(
uncvref_t
<
U
>
::
from_json
(
std
::
declval
<
BasicJsonType
>
(),
std
::
declval
<
T
&>
()))
>::
value
>>
static
int
detect
(
U
&&
);
static
void
detect
(...);
public:
static
constexpr
bool
value
=
std
::
is_integral
<
decltype
(
detect
(
std
::
declval
<
typename
BasicJsonType
::
template
json_serializer
<
T
,
void
>
>
()))
>::
value
;
};
// This trait checks if JSONSerializer<T>::from_json(json const&) exists
// this overload is used for non-default-constructible user-defined-types
template
<
typename
BasicJsonType
,
typename
T
>
struct
has_non_default_from_json
{
private:
template
<
typename
U
,
typename
=
enable_if_t
<
std
::
is_same
<
T
,
decltype
(
uncvref_t
<
U
>
::
from_json
(
std
::
declval
<
BasicJsonType
>
()))
>::
value
>>
static
int
detect
(
U
&&
);
static
void
detect
(...);
public:
static
constexpr
bool
value
=
std
::
is_integral
<
decltype
(
detect
(
std
::
declval
<
typename
BasicJsonType
::
template
json_serializer
<
T
,
void
>
>
()))
>::
value
;
};
// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
template
<
typename
BasicJsonType
,
typename
T
>
struct
has_to_json
{
private:
template
<
typename
U
,
typename
=
decltype
(
uncvref_t
<
U
>
::
to_json
(
std
::
declval
<
BasicJsonType
&>
(),
std
::
declval
<
T
>
()))
>
static
int
detect
(
U
&&
);
static
void
detect
(...);
public:
static
constexpr
bool
value
=
std
::
is_integral
<
decltype
(
detect
(
std
::
declval
<
typename
BasicJsonType
::
template
json_serializer
<
T
,
void
>
>
()))
>::
value
;
};
}
}
#endif
src/json.hpp
View file @
f364f5ac
...
...
@@ -48,12 +48,12 @@ SOFTWARE.
#include <locale> // locale
#include <numeric> // accumulate
#include <sstream> // stringstream
#include <type_traits> // add_pointer, conditional, decay, enable_if, false_type, integral_constant, is_arithmetic, is_base_of, is_const, is_constructible, is_convertible, is_default_constructible, is_enum, is_floating_point, is_integral, is_nothrow_move_assignable, is_nothrow_move_constructible, is_pointer, is_reference, is_same, is_scalar, is_signed, remove_const, remove_cv, remove_pointer, remove_reference, true_type, underlying_type
#include <utility> // declval, forward, make_pair, move, pair, swap
#include <valarray> // valarray
#include "json_fwd.hpp"
#include "detail/macro_scope.hpp"
#include "detail/meta.hpp"
/*!
@brief namespace for Niels Lohmann
...
...
@@ -62,14 +62,6 @@ SOFTWARE.
*/
namespace
nlohmann
{
/*!
@brief unnamed namespace with internal helper functions
This namespace collects some functions that could not be defined inside the
@ref basic_json class.
@since version 2.1.0
*/
namespace
detail
{
////////////////
...
...
@@ -455,79 +447,6 @@ inline bool operator<(const value_t lhs, const value_t rhs) noexcept
return
l_index
<
order
.
size
()
and
r_index
<
order
.
size
()
and
order
[
l_index
]
<
order
[
r_index
];
}
/////////////
// helpers //
/////////////
template
<
typename
>
struct
is_basic_json
:
std
::
false_type
{};
NLOHMANN_BASIC_JSON_TPL_DECLARATION
struct
is_basic_json
<
NLOHMANN_BASIC_JSON_TPL
>
:
std
::
true_type
{};
// alias templates to reduce boilerplate
template
<
bool
B
,
typename
T
=
void
>
using
enable_if_t
=
typename
std
::
enable_if
<
B
,
T
>::
type
;
template
<
typename
T
>
using
uncvref_t
=
typename
std
::
remove_cv
<
typename
std
::
remove_reference
<
T
>::
type
>::
type
;
// implementation of C++14 index_sequence and affiliates
// source: https://stackoverflow.com/a/32223343
template
<
std
::
size_t
...
Ints
>
struct
index_sequence
{
using
type
=
index_sequence
;
using
value_type
=
std
::
size_t
;
static
constexpr
std
::
size_t
size
()
noexcept
{
return
sizeof
...(
Ints
);
}
};
template
<
class
Sequence1
,
class
Sequence2
>
struct
merge_and_renumber
;
template
<
std
::
size_t
...
I1
,
std
::
size_t
...
I2
>
struct
merge_and_renumber
<
index_sequence
<
I1
...
>
,
index_sequence
<
I2
...
>>
:
index_sequence
<
I1
...,
(
sizeof
...(
I1
)
+
I2
)...
>
{};
template
<
std
::
size_t
N
>
struct
make_index_sequence
:
merge_and_renumber
<
typename
make_index_sequence
<
N
/
2
>::
type
,
typename
make_index_sequence
<
N
-
N
/
2
>::
type
>
{};
template
<
>
struct
make_index_sequence
<
0
>
:
index_sequence
<>
{};
template
<
>
struct
make_index_sequence
<
1
>
:
index_sequence
<
0
>
{};
template
<
typename
...
Ts
>
using
index_sequence_for
=
make_index_sequence
<
sizeof
...(
Ts
)
>
;
/*
Implementation of two C++17 constructs: conjunction, negation. This is needed
to avoid evaluating all the traits in a condition
For example: not std::is_same<void, T>::value and has_value_type<T>::value
will not compile when T = void (on MSVC at least). Whereas
conjunction<negation<std::is_same<void, T>>, has_value_type<T>>::value will
stop evaluating if negation<...>::value == false
Please note that those constructs must be used with caution, since symbols can
become very long quickly (which can slow down compilation and cause MSVC
internal compiler errors). Only use it when you have to (see example ahead).
*/
template
<
class
...
>
struct
conjunction
:
std
::
true_type
{};
template
<
class
B1
>
struct
conjunction
<
B1
>
:
B1
{};
template
<
class
B1
,
class
...
Bn
>
struct
conjunction
<
B1
,
Bn
...
>
:
std
::
conditional
<
bool
(
B1
::
value
),
conjunction
<
Bn
...
>
,
B1
>::
type
{};
template
<
class
B
>
struct
negation
:
std
::
integral_constant
<
bool
,
not
B
::
value
>
{};
// dispatch utility (taken from ranges-v3)
template
<
unsigned
N
>
struct
priority_tag
:
priority_tag
<
N
-
1
>
{};
template
<
>
struct
priority_tag
<
0
>
{};
//////////////////
// constructors //
//////////////////
...
...
@@ -690,135 +609,6 @@ struct external_constructor<value_t::object>
}
};
////////////////////////
// has_/is_ functions //
////////////////////////
NLOHMANN_JSON_HAS_HELPER
(
mapped_type
);
NLOHMANN_JSON_HAS_HELPER
(
key_type
);
NLOHMANN_JSON_HAS_HELPER
(
value_type
);
NLOHMANN_JSON_HAS_HELPER
(
iterator
);
template
<
bool
B
,
class
RealType
,
class
CompatibleObjectType
>
struct
is_compatible_object_type_impl
:
std
::
false_type
{};
template
<
class
RealType
,
class
CompatibleObjectType
>
struct
is_compatible_object_type_impl
<
true
,
RealType
,
CompatibleObjectType
>
{
static
constexpr
auto
value
=
std
::
is_constructible
<
typename
RealType
::
key_type
,
typename
CompatibleObjectType
::
key_type
>::
value
and
std
::
is_constructible
<
typename
RealType
::
mapped_type
,
typename
CompatibleObjectType
::
mapped_type
>::
value
;
};
template
<
class
BasicJsonType
,
class
CompatibleObjectType
>
struct
is_compatible_object_type
{
static
auto
constexpr
value
=
is_compatible_object_type_impl
<
conjunction
<
negation
<
std
::
is_same
<
void
,
CompatibleObjectType
>>
,
has_mapped_type
<
CompatibleObjectType
>
,
has_key_type
<
CompatibleObjectType
>>::
value
,
typename
BasicJsonType
::
object_t
,
CompatibleObjectType
>::
value
;
};
template
<
typename
BasicJsonType
,
typename
T
>
struct
is_basic_json_nested_type
{
static
auto
constexpr
value
=
std
::
is_same
<
T
,
typename
BasicJsonType
::
iterator
>::
value
or
std
::
is_same
<
T
,
typename
BasicJsonType
::
const_iterator
>::
value
or
std
::
is_same
<
T
,
typename
BasicJsonType
::
reverse_iterator
>::
value
or
std
::
is_same
<
T
,
typename
BasicJsonType
::
const_reverse_iterator
>::
value
;
};
template
<
class
BasicJsonType
,
class
CompatibleArrayType
>
struct
is_compatible_array_type
{
static
auto
constexpr
value
=
conjunction
<
negation
<
std
::
is_same
<
void
,
CompatibleArrayType
>>
,
negation
<
is_compatible_object_type
<
BasicJsonType
,
CompatibleArrayType
>>
,
negation
<
std
::
is_constructible
<
typename
BasicJsonType
::
string_t
,
CompatibleArrayType
>>
,
negation
<
is_basic_json_nested_type
<
BasicJsonType
,
CompatibleArrayType
>>
,
has_value_type
<
CompatibleArrayType
>
,
has_iterator
<
CompatibleArrayType
>>::
value
;
};
template
<
bool
,
typename
,
typename
>
struct
is_compatible_integer_type_impl
:
std
::
false_type
{};
template
<
typename
RealIntegerType
,
typename
CompatibleNumberIntegerType
>
struct
is_compatible_integer_type_impl
<
true
,
RealIntegerType
,
CompatibleNumberIntegerType
>
{
// is there an assert somewhere on overflows?
using
RealLimits
=
std
::
numeric_limits
<
RealIntegerType
>
;
using
CompatibleLimits
=
std
::
numeric_limits
<
CompatibleNumberIntegerType
>
;
static
constexpr
auto
value
=
std
::
is_constructible
<
RealIntegerType
,
CompatibleNumberIntegerType
>::
value
and
CompatibleLimits
::
is_integer
and
RealLimits
::
is_signed
==
CompatibleLimits
::
is_signed
;
};
template
<
typename
RealIntegerType
,
typename
CompatibleNumberIntegerType
>
struct
is_compatible_integer_type
{
static
constexpr
auto
value
=
is_compatible_integer_type_impl
<
std
::
is_integral
<
CompatibleNumberIntegerType
>::
value
and
not
std
::
is_same
<
bool
,
CompatibleNumberIntegerType
>::
value
,
RealIntegerType
,
CompatibleNumberIntegerType
>::
value
;
};
// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
template
<
typename
BasicJsonType
,
typename
T
>
struct
has_from_json
{
private:
// also check the return type of from_json
template
<
typename
U
,
typename
=
enable_if_t
<
std
::
is_same
<
void
,
decltype
(
uncvref_t
<
U
>
::
from_json
(
std
::
declval
<
BasicJsonType
>
(),
std
::
declval
<
T
&>
()))
>::
value
>>
static
int
detect
(
U
&&
);
static
void
detect
(...);
public:
static
constexpr
bool
value
=
std
::
is_integral
<
decltype
(
detect
(
std
::
declval
<
typename
BasicJsonType
::
template
json_serializer
<
T
,
void
>
>
()))
>::
value
;
};
// This trait checks if JSONSerializer<T>::from_json(json const&) exists
// this overload is used for non-default-constructible user-defined-types
template
<
typename
BasicJsonType
,
typename
T
>
struct
has_non_default_from_json
{
private:
template
<
typename
U
,
typename
=
enable_if_t
<
std
::
is_same
<
T
,
decltype
(
uncvref_t
<
U
>
::
from_json
(
std
::
declval
<
BasicJsonType
>
()))
>::
value
>>
static
int
detect
(
U
&&
);
static
void
detect
(...);
public:
static
constexpr
bool
value
=
std
::
is_integral
<
decltype
(
detect
(
std
::
declval
<
typename
BasicJsonType
::
template
json_serializer
<
T
,
void
>
>
()))
>::
value
;
};
// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
template
<
typename
BasicJsonType
,
typename
T
>
struct
has_to_json
{
private:
template
<
typename
U
,
typename
=
decltype
(
uncvref_t
<
U
>
::
to_json
(
std
::
declval
<
BasicJsonType
&>
(),
std
::
declval
<
T
>
()))
>
static
int
detect
(
U
&&
);
static
void
detect
(...);
public:
static
constexpr
bool
value
=
std
::
is_integral
<
decltype
(
detect
(
std
::
declval
<
typename
BasicJsonType
::
template
json_serializer
<
T
,
void
>
>
()))
>::
value
;
};
/////////////
// to_json //
/////////////
...
...
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