2
0
mirror of https://github.com/boostorg/json.git synced 2026-02-11 11:52:17 +00:00
This commit is contained in:
Vinnie Falco
2019-11-05 13:34:19 -08:00
parent 0347d1d09d
commit 9cfa2ed5c6
12 changed files with 388 additions and 160 deletions

View File

@@ -62,8 +62,6 @@
// optimizations
#define BOOST_JSON_VALUE_IS_TRIVIAL
#ifndef BOOST_JSON_NO_SSE2
# if (defined(_M_IX86) && _M_IX86_FP == 2) || \
defined(_M_X64) || defined(__SSE2__)

View File

@@ -37,7 +37,7 @@ class number_parser
{
init, init0, init1,
mant, mantn, mantd,
frac1, frac2, frac3, fracd,
frac1, frac2, fracd,
exp1, exp2, exp3,
done
};

View File

@@ -393,7 +393,7 @@ loop:
{
++p;
n_.d = static_cast<double>(m);
st_ = state::frac3;
st_ = state::fracd;
goto loop;
}
++p;
@@ -420,7 +420,7 @@ loop:
}
// zero or more [0..9] (double)
case state::frac3:
case state::fracd:
{
BOOST_JSON_ASSERT(
n_.kind == kind::double_);
@@ -505,7 +505,7 @@ loop:
{
if(p < p1)
{
auto const lim = 308 - off_;
//auto const lim = 308 - off_;
auto e = exp_;
while(p < p1)
{
@@ -620,7 +620,7 @@ write_eof(
st_ = state::done;
break;
case state::frac3:
case state::fracd:
BOOST_JSON_ASSERT(
n_.kind == kind::double_);
ec = {};

View File

@@ -635,7 +635,6 @@ relocate(
value* src,
size_type n) noexcept
{
#ifdef BOOST_JSON_VALUE_IS_TRIVIAL
if(n == 0)
return;
std::memmove(
@@ -644,25 +643,6 @@ relocate(
reinterpret_cast<
void const*>(src),
n * sizeof(value));
#else
if( dest >= src &&
dest < src + n)
{
// backwards
dest += n;
auto it = src + n;
while(it != src)
boost::relocate(
--dest, *--it);
}
else
{
auto last = src + n;
while(src != last)
boost::relocate(
dest++, *src++);
}
#endif
}
} // json

View File

@@ -861,6 +861,7 @@ loop_num:
auto const num = iep_.get();
switch(num.kind)
{
default:
case kind::int64:
this->on_int64(num.i, ec);
break;
@@ -1107,6 +1108,7 @@ write_eof(error_code& ec)
auto const num = iep_.get();
switch(num.kind)
{
default:
case kind::int64:
this->on_int64(num.i, ec);
break;

View File

@@ -130,9 +130,9 @@ on_object_begin(error_code& ec)
}
else if(jv.is_array())
{
jv.if_array()->emplace_back(object{});
jv.get_array().emplace_back(object_kind);
stack_.push(
&jv.if_array()->back());
&jv.get_array().back());
}
else
{
@@ -177,9 +177,9 @@ on_array_begin(error_code& ec)
else if(jv.is_array())
{
BOOST_JSON_ASSERT(s_.empty());
jv.if_array()->emplace_back(array{});
jv.get_array().emplace_back(array_kind);
stack_.push(
&jv.if_array()->back());
&jv.get_array().back());
}
else
{
@@ -227,7 +227,7 @@ on_key_end(
s = {s_.data(), s_.size()};
}
auto const result =
jv.if_object()->emplace(s, nullptr);
jv.get_object().emplace(s, nullptr);
// overwrite duplicate keys
if(! result.second)
result.first->second.emplace_null();
@@ -253,9 +253,9 @@ on_string_data(
else if(stack_.front()->is_array())
{
BOOST_JSON_ASSERT(s_.empty());
jv.if_array()->emplace_back(string{});
jv.get_array().emplace_back(string{});
stack_.push(
&jv.if_array()->back());
&jv.get_array().back());
stack_.front()->if_string()->append(
s.data(), s.size());
}
@@ -308,7 +308,7 @@ on_int64(
else if(stack_.front()->is_array())
{
BOOST_JSON_ASSERT(s_.empty());
jv.if_array()->emplace_back(i);
jv.get_array().emplace_back(i);
}
else
{
@@ -334,7 +334,7 @@ on_uint64(
else if(stack_.front()->is_array())
{
BOOST_JSON_ASSERT(s_.empty());
jv.if_array()->emplace_back(u);
jv.get_array().emplace_back(u);
}
else
{
@@ -360,7 +360,7 @@ on_double(
else if(stack_.front()->is_array())
{
BOOST_JSON_ASSERT(s_.empty());
jv.if_array()->emplace_back(d);
jv.get_array().emplace_back(d);
}
else
{
@@ -384,7 +384,7 @@ on_bool(bool b, error_code&)
else if(stack_.front()->is_array())
{
BOOST_JSON_ASSERT(s_.empty());
jv.if_array()->emplace_back(b);
jv.get_array().emplace_back(b);
}
else
{
@@ -407,7 +407,7 @@ on_null(error_code&)
else if(stack_.front()->is_array())
{
BOOST_JSON_ASSERT(s_.empty());
jv.if_array()->emplace_back(nullptr);
jv.get_array().emplace_back(nullptr);
}
else
{

View File

@@ -104,64 +104,9 @@ value::
value::
value(pilfered<value> p) noexcept
{
#ifdef BOOST_JSON_VALUE_IS_TRIVIAL
std::memcpy(this, &p.get(), sizeof(*this));
::new(&p.get().sca_.sp) storage_ptr{};
p.get().kind_ = json::kind::null;
#else
auto& other = p.get();
switch(other.kind_)
{
case json::kind::object:
relocate(&obj_, other.obj_);
::new(&other.sca_.sp) storage_ptr;
break;
case json::kind::array:
relocate(&arr_, other.arr_);
::new(&other.sca_.sp) storage_ptr;
break;
case json::kind::string:
relocate(&str_, other.str_);
::new(&other.sca_.sp) storage_ptr;
break;
case json::kind::int64:
::new(&sca_.i) std::int64_t(
other.sca_.i);
::new(&sca_.sp) storage_ptr(
std::move(other.sca_.sp));
break;
case json::kind::uint64:
::new(&sca_.u) std::uint64_t(
other.sca_.u);
::new(&sca_.sp) storage_ptr(
std::move(other.sca_.sp));
break;
case json::kind::double_:
::new(&sca_.d) double(
other.sca_.d);
::new(&sca_.sp) storage_ptr(
std::move(other.sca_.sp));
break;
case json::kind::boolean:
::new(&sca_.b) bool(other.sca_.b);
::new(&sca_.sp) storage_ptr(
std::move(other.sca_.sp));
break;
case json::kind::null:
::new(&sca_.sp) storage_ptr(
std::move(other.sca_.sp));
break;
}
kind_ = other.kind_;
other.kind_ = json::kind::null;
#endif
}
value::
@@ -225,63 +170,9 @@ value(
value::
value(value&& other) noexcept
{
#ifdef BOOST_JSON_VALUE_IS_TRIVIAL
std::memcpy(this, &other, sizeof(*this));
::new(&other.sca_.sp) storage_ptr{};
other.kind_ = json::kind::null;
#else
switch(other.kind_)
{
case json::kind::object:
::new(&obj_) object(
std::move(other.obj_));
break;
case json::kind::array:
::new(&arr_) array(
std::move(other.arr_));
break;
case json::kind::string:
::new(&str_) string(
std::move(other.str_));
break;
case json::kind::int64:
::new(&sca_.i) std::int64_t(
other.sca_.i);
::new(&sca_.sp) storage_ptr(
other.sca_.sp);
break;
case json::kind::uint64:
::new(&sca_.u) std::uint64_t(
other.sca_.u);
::new(&sca_.sp) storage_ptr(
other.sca_.sp);
break;
case json::kind::double_:
::new(&sca_.d) double(
other.sca_.d);
::new(&sca_.sp) storage_ptr(
other.sca_.sp);
break;
case json::kind::boolean:
::new(&sca_.b) bool(
other.sca_.b);
::new(&sca_.sp) storage_ptr(
other.sca_.sp);
break;
case json::kind::null:
::new(&sca_.sp) storage_ptr(
other.sca_.sp);
break;
}
kind_ = other.kind_;
#endif
}
value::

View File

@@ -44,6 +44,17 @@ enum class kind
null
};
struct object_kind_t
{
};
struct array_kind_t
{
};
BOOST_JSON_INLINE_VARIABLE(object_kind, object_kind_t);
BOOST_JSON_INLINE_VARIABLE(array_kind, array_kind_t);
} // json
} // boost

View File

@@ -352,7 +352,7 @@ public:
//
//------------------------------------------------------
/** Construct an object
/** Construct an object.
*/
value(object obj) noexcept
: obj_(std::move(obj))
@@ -360,7 +360,7 @@ public:
{
}
/** Construct an object
/** Construct an object.
*/
value(object obj, storage_ptr sp)
: obj_(std::move(obj), std::move(sp))
@@ -368,7 +368,16 @@ public:
{
}
/** Construct an array
/** Construct an object.
*/
value(object_kind_t,
storage_ptr sp = {}) noexcept
: obj_(std::move(sp))
, kind_(json::kind::object)
{
}
/** Construct an array.
*/
value(array arr) noexcept
: arr_(std::move(arr))
@@ -376,7 +385,7 @@ public:
{
}
/** Construct an array
/** Construct an array.
*/
value(array arr, storage_ptr sp)
: arr_(std::move(arr), std::move(sp))
@@ -384,7 +393,16 @@ public:
{
}
/** Construct a string
/** Construct an array.
*/
value(array_kind_t,
storage_ptr sp = {}) noexcept
: arr_(std::move(sp))
, kind_(json::kind::array)
{
}
/** Construct a string.
*/
value(
string str) noexcept
@@ -393,7 +411,7 @@ public:
{
}
/** Construct a string
/** Construct a string.
*/
value(string str, storage_ptr sp)
: str_(std::move(str), std::move(sp))
@@ -401,7 +419,7 @@ public:
{
}
/** Construct a string
/** Construct a string.
*/
value(
string_view s,
@@ -411,7 +429,7 @@ public:
{
}
/** Construct a string
/** Construct a string.
*/
value(
char const* s,
@@ -1531,6 +1549,112 @@ public:
//------------------------------------------------------
/** Return a value as an object, without checking.
This is a fast way to gain access to an object
value when the kind is known.
@par Preconditions
@code
this->is_object()
@endcode
@par Complexity
Constant.
@par Exception Safety
No-throw guarantee.
*/
object&
get_object() noexcept
{
BOOST_JSON_ASSERT(is_object());
return obj_;
}
/** Return a value as an object, without checking.
This is a fast way to gain access to an object
value when the kind is known.
@par Preconditions
@code
this->is_object()
@endcode
@par Complexity
Constant.
@par Exception Safety
No-throw guarantee.
*/
object const&
get_object() const noexcept
{
BOOST_JSON_ASSERT(is_object());
return obj_;
}
/** Return a value as an array, without checking.
This is a fast way to gain access to an array
value when the kind is known.
@par Preconditions
@code
this->is_array()
@endcode
@par Complexity
Constant.
@par Exception Safety
No-throw guarantee.
*/
array&
get_array() noexcept
{
BOOST_JSON_ASSERT(is_array());
return arr_;
}
/** Return a value as an array, without checking.
This is a fast way to gain access to an array
value when the kind is known.
@par Preconditions
@code
this->is_array()
@endcode
@par Complexity
Constant.
@par Exception Safety
No-throw guarantee.
*/
array const&
get_array() const noexcept
{
BOOST_JSON_ASSERT(is_array());
return arr_;
}
//------------------------------------------------------
private:
BOOST_JSON_DECL
storage_ptr