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
513eb3ab
Unverified
Commit
513eb3ab
authored
Feb 18, 2017
by
Niels Lohmann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
🚧
clean up
parent
6408402a
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
62 additions
and
86 deletions
+62
-86
json.hpp
src/json.hpp
+29
-42
json.hpp.re2c
src/json.hpp.re2c
+32
-43
unit-class_parser.cpp
test/src/unit-class_parser.cpp
+1
-1
No files found.
src/json.hpp
View file @
513eb3ab
...
@@ -8226,15 +8226,10 @@ class basic_json
...
@@ -8226,15 +8226,10 @@ class basic_json
struct
numtostr
struct
numtostr
{
{
public
:
public
:
template
<
typename
T
>
template
<
typename
NumberType
>
numtostr
(
T
value
)
numtostr
(
NumberType
value
)
{
{
x_write
(
value
,
std
::
is_integral
<
T
>
());
x_write
(
value
,
std
::
is_integral
<
NumberType
>
());
}
operator
const
char
*
()
const
{
return
m_buf
.
data
();
}
}
const
char
*
c_str
()
const
const
char
*
c_str
()
const
...
@@ -8244,17 +8239,24 @@ class basic_json
...
@@ -8244,17 +8239,24 @@ class basic_json
private
:
private
:
static
constexpr
size_t
s_capacity
=
30
;
static
constexpr
size_t
s_capacity
=
30
;
std
::
array
<
char
,
s_capacity
+
2
>
m_buf
{{}};
// +2 for leading '-'
/// added capacity for leading '-' and trailing '\0'
// and trailing '\0'
std
::
array
<
char
,
s_capacity
+
2
>
m_buf
{{}};
template
<
typename
T
>
void
x_write
(
T
x
,
std
::
true_type
)
template
<
typename
NumberType
>
void
x_write
(
NumberType
x
,
/*is_integral=*/
std
::
true_type
)
{
{
static_assert
(
std
::
numeric_limits
<
T
>::
digits10
<=
s_capacity
,
""
);
if
(
x
==
0
)
{
m_buf
[
0
]
=
'0'
;
return
;
}
static_assert
(
std
::
numeric_limits
<
NumberType
>::
digits10
<=
s_capacity
,
""
);
const
bool
is_neg
=
x
<
0
;
const
bool
is_neg
=
x
<
0
;
size_t
i
=
0
;
size_t
i
=
0
;
while
(
x
and
i
<
s_capacity
)
while
(
x
!=
0
and
i
<
s_capacity
)
{
{
const
auto
digit
=
std
::
labs
(
static_cast
<
long
>
(
x
%
10
));
const
auto
digit
=
std
::
labs
(
static_cast
<
long
>
(
x
%
10
));
m_buf
[
i
++
]
=
static_cast
<
char
>
(
'0'
+
digit
);
m_buf
[
i
++
]
=
static_cast
<
char
>
(
'0'
+
digit
);
...
@@ -8263,11 +8265,6 @@ class basic_json
...
@@ -8263,11 +8265,6 @@ class basic_json
assert
(
i
<
s_capacity
);
assert
(
i
<
s_capacity
);
if
(
i
==
0
)
{
m_buf
[
i
++
]
=
'0'
;
}
if
(
is_neg
)
if
(
is_neg
)
{
{
m_buf
[
i
++
]
=
'-'
;
m_buf
[
i
++
]
=
'-'
;
...
@@ -8276,18 +8273,16 @@ class basic_json
...
@@ -8276,18 +8273,16 @@ class basic_json
std
::
reverse
(
m_buf
.
begin
(),
m_buf
.
begin
()
+
i
);
std
::
reverse
(
m_buf
.
begin
(),
m_buf
.
begin
()
+
i
);
}
}
template
<
typename
T
>
template
<
typename
NumberType
>
void
x_write
(
T
x
,
std
::
false_type
)
void
x_write
(
NumberType
x
,
/*is_integral=*/
std
::
false_type
)
{
{
if
(
x
==
0
)
if
(
x
==
0
)
{
{
std
::
strcpy
(
m_buf
.
data
(),
std
::
strcpy
(
m_buf
.
data
(),
std
::
signbit
(
x
)
?
"-0.0"
:
"0.0"
);
std
::
signbit
(
x
)
?
"-0.0"
:
"0.0"
);
return
;
return
;
}
}
static
constexpr
auto
d
=
static
constexpr
auto
d
=
std
::
numeric_limits
<
NumberType
>::
digits10
;
std
::
numeric_limits
<
number_float_t
>::
digits10
;
static_assert
(
d
==
6
or
d
==
15
or
d
==
16
or
d
==
17
,
""
);
static_assert
(
d
==
6
or
d
==
15
or
d
==
16
or
d
==
17
,
""
);
static
constexpr
auto
fmt
=
d
==
6
?
"%.7g"
static
constexpr
auto
fmt
=
d
==
6
?
"%.7g"
...
@@ -8330,17 +8325,14 @@ class basic_json
...
@@ -8330,17 +8325,14 @@ class basic_json
#endif
#endif
// erase thousands separator
// erase thousands separator
if
(
thousands_sep
)
if
(
thousands_sep
!=
'\0'
)
{
{
auto
end
=
std
::
remove
(
m_buf
.
begin
(),
const
auto
end
=
std
::
remove
(
m_buf
.
begin
(),
m_buf
.
end
(),
thousands_sep
);
m_buf
.
end
(),
thousands_sep
);
std
::
fill
(
end
,
m_buf
.
end
(),
'\0'
);
std
::
fill
(
end
,
m_buf
.
end
(),
'\0'
);
}
}
// convert decimal point to '.'
// convert decimal point to '.'
if
(
decimal_point
and
decimal_point
!=
'.'
)
if
(
decimal_point
!=
'\0'
and
decimal_point
!=
'.'
)
{
{
for
(
auto
&
c
:
m_buf
)
for
(
auto
&
c
:
m_buf
)
{
{
...
@@ -8352,20 +8344,16 @@ class basic_json
...
@@ -8352,20 +8344,16 @@ class basic_json
}
}
}
}
// determine if need to appe
r
d ".0"
// determine if need to appe
n
d ".0"
auto
data_end
=
m_buf
.
begin
()
+
strlen
(
m_buf
.
data
());
const
auto
data_end
=
m_buf
.
begin
()
+
strlen
(
m_buf
.
data
());
const
bool
value_is_int_like
=
const
bool
value_is_int_like
=
std
::
find_if
(
m_buf
.
begin
(),
data_end
,
std
::
none_of
(
m_buf
.
begin
(),
data_end
,
[](
const
char
c
)
[](
const
char
c
)
{
{
return
c
==
'.'
return
(
c
==
'.'
or
c
==
'e'
or
c
==
'E'
);
or
c
==
'e'
});
or
c
==
'E'
;
})
==
data_end
;
assert
(
data_end
+
2
<
m_buf
.
end
());
assert
(
data_end
+
2
<
m_buf
.
end
());
if
(
value_is_int_like
)
if
(
value_is_int_like
)
{
{
strcat
(
m_buf
.
data
(),
".0"
);
strcat
(
m_buf
.
data
(),
".0"
);
...
@@ -8374,7 +8362,6 @@ class basic_json
...
@@ -8374,7 +8362,6 @@ class basic_json
};
};
/*!
/*!
@brief internal implementation of the serialization function
@brief internal implementation of the serialization function
...
...
src/json.hpp.re2c
View file @
513eb3ab
...
@@ -8226,15 +8226,10 @@ class basic_json
...
@@ -8226,15 +8226,10 @@ class basic_json
struct numtostr
struct numtostr
{
{
public:
public:
template<typename
T
>
template<typename
NumberType
>
numtostr(
T
value)
numtostr(
NumberType
value)
{
{
x_write(value, std::is_integral<T>());
x_write(value, std::is_integral<NumberType>());
}
operator const char* () const
{
return m_buf.data();
}
}
const char* c_str() const
const char* c_str() const
...
@@ -8244,17 +8239,25 @@ class basic_json
...
@@ -8244,17 +8239,25 @@ class basic_json
private:
private:
static constexpr size_t s_capacity = 30;
static constexpr size_t s_capacity = 30;
std::array < char, s_capacity + 2 > m_buf{{}}; // +2 for leading '-'
/// added capacity for leading '-' and trailing '\0'
// and trailing '\0'
std::array < char, s_capacity + 2 > m_buf{{}};
template<typename T>
void x_write(T x, std::true_type)
template<typename NumberType>
void x_write(NumberType x, /*is_integral=*/std::true_type)
{
{
static_assert(std::numeric_limits<T>::digits10 <= s_capacity, "");
if (x == 0)
{
m_buf[0] = '0';
return;
}
static_assert(std::numeric_limits<NumberType>::digits10 <= s_capacity,
"unexpected NumberType");
const bool is_neg = x < 0;
const bool is_neg = x < 0;
size_t i = 0;
size_t i = 0;
while (x and i < s_capacity)
while (x
!= 0
and i < s_capacity)
{
{
const auto digit = std::labs(static_cast<long>(x % 10));
const auto digit = std::labs(static_cast<long>(x % 10));
m_buf[i++] = static_cast<char>('0' + digit);
m_buf[i++] = static_cast<char>('0' + digit);
...
@@ -8263,11 +8266,6 @@ class basic_json
...
@@ -8263,11 +8266,6 @@ class basic_json
assert(i < s_capacity);
assert(i < s_capacity);
if (i == 0)
{
m_buf[i++] = '0';
}
if (is_neg)
if (is_neg)
{
{
m_buf[i++] = '-';
m_buf[i++] = '-';
...
@@ -8276,19 +8274,18 @@ class basic_json
...
@@ -8276,19 +8274,18 @@ class basic_json
std::reverse(m_buf.begin(), m_buf.begin() + i);
std::reverse(m_buf.begin(), m_buf.begin() + i);
}
}
template<typename
T
>
template<typename
NumberType
>
void x_write(
T x,
std::false_type)
void x_write(
NumberType x, /*is_integral=*/
std::false_type)
{
{
if (x == 0)
if (x == 0)
{
{
std::strcpy(m_buf.data(),
std::strcpy(m_buf.data(), std::signbit(x) ? "-0.0" : "0.0");
std::signbit(x) ? "-0.0" : "0.0");
return;
return;
}
}
static constexpr auto d =
static constexpr auto d =
std::numeric_limits<NumberType>::digits10;
std::numeric_limits<number_float_t>::digits10;
static_assert(d == 6 or d == 15 or d == 16 or d == 17,
static_assert(d == 6 or d == 15 or d == 16 or d == 17, "
");
"unexpected NumberType
");
static constexpr auto fmt = d == 6 ? "%.7g"
static constexpr auto fmt = d == 6 ? "%.7g"
: d == 15 ? "%.16g"
: d == 15 ? "%.16g"
...
@@ -8330,17 +8327,14 @@ class basic_json
...
@@ -8330,17 +8327,14 @@ class basic_json
#endif
#endif
// erase thousands separator
// erase thousands separator
if (thousands_sep)
if (thousands_sep
!= '\0'
)
{
{
auto end = std::remove(m_buf.begin(),
const auto end = std::remove(m_buf.begin(), m_buf.end(), thousands_sep);
m_buf.end(),
thousands_sep);
std::fill(end, m_buf.end(), '\0');
std::fill(end, m_buf.end(), '\0');
}
}
// convert decimal point to '.'
// convert decimal point to '.'
if (decimal_point and decimal_point != '.')
if (decimal_point
!= '\0'
and decimal_point != '.')
{
{
for (auto& c : m_buf)
for (auto& c : m_buf)
{
{
...
@@ -8352,20 +8346,16 @@ class basic_json
...
@@ -8352,20 +8346,16 @@ class basic_json
}
}
}
}
// determine if need to appe
r
d ".0"
// determine if need to appe
n
d ".0"
auto data_end = m_buf.begin() + strlen(m_buf.data());
const
auto data_end = m_buf.begin() + strlen(m_buf.data());
const bool value_is_int_like =
const bool value_is_int_like =
std::find_if(m_buf.begin(), data_end,
std::none_of(m_buf.begin(), data_end, [](const char c)
[](const char c)
{
{
return c == '.'
return (c == '.' or c == 'e' or c == 'E');
or c == 'e'
});
or c == 'E';
})
== data_end;
assert(data_end + 2 < m_buf.end());
assert(data_end + 2 < m_buf.end());
if (value_is_int_like)
if (value_is_int_like)
{
{
strcat(m_buf.data(), ".0");
strcat(m_buf.data(), ".0");
...
@@ -8374,7 +8364,6 @@ class basic_json
...
@@ -8374,7 +8364,6 @@ class basic_json
};
};
/*!
/*!
@brief internal implementation of the serialization function
@brief internal implementation of the serialization function
...
...
test/src/unit-class_parser.cpp
View file @
513eb3ab
...
@@ -613,7 +613,7 @@ TEST_CASE("parser class")
...
@@ -613,7 +613,7 @@ TEST_CASE("parser class")
// test case to make sure the callback is properly evaluated after reading a key
// test case to make sure the callback is properly evaluated after reading a key
{
{
json
::
parser_callback_t
cb
=
[](
int
depth
,
json
::
parse_event_t
event
,
json
&
parsed
)
json
::
parser_callback_t
cb
=
[](
int
,
json
::
parse_event_t
event
,
json
&
)
{
{
if
(
event
==
json
::
parse_event_t
::
key
)
if
(
event
==
json
::
parse_event_t
::
key
)
{
{
...
...
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