mirror of
https://github.com/boostorg/json.git
synced 2025-05-11 13:44:06 +00:00
Tidy
This commit is contained in:
parent
40a16c9380
commit
68f3df0403
@ -446,8 +446,8 @@ main(
|
||||
{
|
||||
std::vector<std::unique_ptr<any_impl const>> vi;
|
||||
vi.reserve(10);
|
||||
//vi.emplace_back(new boost_default_impl);
|
||||
//vi.emplace_back(new boost_vec_impl);
|
||||
vi.emplace_back(new boost_default_impl);
|
||||
vi.emplace_back(new boost_impl);
|
||||
vi.emplace_back(new rapidjson_impl);
|
||||
//vi.emplace_back(new nlohmann_impl);
|
||||
|
@ -32,7 +32,7 @@ to_string_test(
|
||||
class unchecked_array
|
||||
{
|
||||
value* data_;
|
||||
unsigned long size_;
|
||||
std::size_t size_;
|
||||
storage_ptr const& sp_;
|
||||
|
||||
public:
|
||||
@ -41,7 +41,7 @@ public:
|
||||
|
||||
unchecked_array(
|
||||
value* data,
|
||||
unsigned long size,
|
||||
std::size_t size,
|
||||
storage_ptr const& sp) noexcept
|
||||
: data_(data)
|
||||
, size_(size)
|
||||
@ -64,7 +64,7 @@ public:
|
||||
return sp_;
|
||||
}
|
||||
|
||||
unsigned long
|
||||
std::size_t
|
||||
size() const noexcept
|
||||
{
|
||||
return size_;
|
||||
@ -128,13 +128,13 @@ class array
|
||||
{
|
||||
public:
|
||||
/// The type used to represent unsigned integers
|
||||
using size_type = unsigned long;
|
||||
using size_type = std::size_t;
|
||||
|
||||
/// The type of each element
|
||||
using value_type = value;
|
||||
|
||||
/// The type used to represent signed integers
|
||||
using difference_type = long;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
|
||||
/// A reference to an element
|
||||
using reference = value&;
|
||||
@ -245,7 +245,7 @@ public:
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
array(
|
||||
size_type count,
|
||||
std::size_t count,
|
||||
value const& v,
|
||||
storage_ptr sp = {});
|
||||
|
||||
@ -273,7 +273,7 @@ public:
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
array(
|
||||
size_type count,
|
||||
std::size_t count,
|
||||
storage_ptr sp = {});
|
||||
|
||||
/** Construct a container with the contents of a range
|
||||
@ -609,7 +609,7 @@ public:
|
||||
*/
|
||||
inline
|
||||
reference
|
||||
at(size_type pos);
|
||||
at(std::size_t pos);
|
||||
|
||||
/** Access an element, with bounds checking
|
||||
|
||||
@ -628,7 +628,7 @@ public:
|
||||
*/
|
||||
inline
|
||||
const_reference
|
||||
at(size_type pos) const;
|
||||
at(std::size_t pos) const;
|
||||
|
||||
/** Access an element
|
||||
|
||||
@ -647,7 +647,7 @@ public:
|
||||
*/
|
||||
inline
|
||||
reference
|
||||
operator[](size_type pos) noexcept;
|
||||
operator[](std::size_t pos) noexcept;
|
||||
|
||||
/** Access an element
|
||||
|
||||
@ -666,7 +666,7 @@ public:
|
||||
*/
|
||||
inline
|
||||
const_reference
|
||||
operator[](size_type pos) const noexcept;
|
||||
operator[](std::size_t pos) const noexcept;
|
||||
|
||||
/** Access the first element
|
||||
|
||||
@ -974,7 +974,7 @@ public:
|
||||
|
||||
Constant.
|
||||
*/
|
||||
size_type
|
||||
std::size_t
|
||||
size() const noexcept
|
||||
{
|
||||
return impl_.size;
|
||||
@ -993,7 +993,7 @@ public:
|
||||
*/
|
||||
static
|
||||
constexpr
|
||||
size_type
|
||||
std::size_t
|
||||
max_size() noexcept
|
||||
{
|
||||
return BOOST_JSON_MAX_ARRAY_SIZE;
|
||||
@ -1008,7 +1008,7 @@ public:
|
||||
|
||||
Constant.
|
||||
*/
|
||||
size_type
|
||||
std::size_t
|
||||
capacity() const noexcept
|
||||
{
|
||||
return impl_.capacity;
|
||||
@ -1046,7 +1046,7 @@ public:
|
||||
*/
|
||||
BOOST_JSON_FORCEINLINE
|
||||
void
|
||||
reserve(size_type new_capacity)
|
||||
reserve(std::size_t new_capacity)
|
||||
{
|
||||
// never shrink
|
||||
if(new_capacity <= impl_.capacity)
|
||||
@ -1201,7 +1201,7 @@ public:
|
||||
iterator
|
||||
insert(
|
||||
const_iterator pos,
|
||||
size_type count,
|
||||
std::size_t count,
|
||||
value const& v);
|
||||
|
||||
/** Insert elements before the specified location
|
||||
@ -1519,7 +1519,7 @@ public:
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
void
|
||||
resize(size_type count);
|
||||
resize(std::size_t count);
|
||||
|
||||
/** Change the number of elements stored
|
||||
|
||||
@ -1552,7 +1552,7 @@ public:
|
||||
BOOST_JSON_DECL
|
||||
void
|
||||
resize(
|
||||
size_type count,
|
||||
std::size_t count,
|
||||
value const& v);
|
||||
|
||||
/** Swap the contents
|
||||
@ -1593,8 +1593,8 @@ private:
|
||||
struct impl_type
|
||||
{
|
||||
value* vec = nullptr;
|
||||
size_type size = 0;
|
||||
size_type capacity = 0;
|
||||
std::uint32_t size = 0;
|
||||
std::uint32_t capacity = 0;
|
||||
|
||||
impl_type() = default;
|
||||
impl_type(impl_type const&) = default;
|
||||
@ -1603,7 +1603,7 @@ private:
|
||||
|
||||
inline
|
||||
impl_type(
|
||||
size_type capacity,
|
||||
std::size_t capacity,
|
||||
storage_ptr const& sp);
|
||||
|
||||
inline
|
||||
@ -1612,7 +1612,7 @@ private:
|
||||
impl_type&& other) noexcept;
|
||||
|
||||
inline
|
||||
size_type
|
||||
std::size_t
|
||||
index_of(value const*) const noexcept;
|
||||
|
||||
inline
|
||||
@ -1678,7 +1678,7 @@ private:
|
||||
|
||||
BOOST_JSON_DECL
|
||||
void
|
||||
reserve_impl(size_type capacity);
|
||||
reserve_impl(std::size_t capacity);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
static
|
||||
@ -1686,7 +1686,7 @@ private:
|
||||
relocate(
|
||||
value* dest,
|
||||
value* src,
|
||||
size_type n) noexcept;
|
||||
std::size_t n) noexcept;
|
||||
|
||||
class undo_create;
|
||||
class undo_assign;
|
||||
|
@ -48,13 +48,19 @@ public:
|
||||
return size_ == 0;
|
||||
}
|
||||
|
||||
char*
|
||||
begin() noexcept
|
||||
{
|
||||
return base_;
|
||||
}
|
||||
|
||||
void
|
||||
clear() noexcept
|
||||
{
|
||||
size_ = 0;
|
||||
}
|
||||
|
||||
void*
|
||||
char*
|
||||
push(std::size_t n)
|
||||
{
|
||||
prepare(n);
|
||||
@ -63,7 +69,7 @@ public:
|
||||
return p;
|
||||
}
|
||||
|
||||
void*
|
||||
char*
|
||||
pop(std::size_t n) noexcept
|
||||
{
|
||||
BOOST_JSON_ASSERT(
|
||||
|
@ -25,7 +25,7 @@ grow(std::size_t n)
|
||||
if(n > max_size() - size_)
|
||||
BOOST_JSON_THROW(
|
||||
stack_overflow_exception());
|
||||
auto new_capacity = size_ + n;
|
||||
auto new_capacity = capacity_ + n;
|
||||
if( new_capacity < min_capacity_)
|
||||
new_capacity = min_capacity_;
|
||||
// 2x growth
|
||||
|
@ -37,8 +37,13 @@ class static_stack
|
||||
public:
|
||||
using value_type = T;
|
||||
|
||||
BOOST_JSON_DECL
|
||||
~static_stack();
|
||||
~static_stack()
|
||||
{
|
||||
if(begin_ != t_)
|
||||
sp_->deallocate(begin_,
|
||||
capacity() * sizeof(T),
|
||||
alignof(T));
|
||||
}
|
||||
|
||||
explicit
|
||||
static_stack(
|
||||
@ -122,17 +127,36 @@ private:
|
||||
return end_ - begin_;
|
||||
}
|
||||
|
||||
BOOST_JSON_DECL
|
||||
void
|
||||
grow();
|
||||
grow()
|
||||
{
|
||||
auto const n = 2 * capacity();
|
||||
auto const begin =
|
||||
reinterpret_cast<T*>(
|
||||
sp_->allocate(
|
||||
n * sizeof(T),
|
||||
alignof(T)));
|
||||
if(! empty())
|
||||
{
|
||||
std::memcpy(begin, begin_,
|
||||
size() * sizeof(T));
|
||||
top_ = begin + (top_ - begin_);
|
||||
if(begin_ != t_)
|
||||
sp_->deallocate(begin_,
|
||||
capacity() * sizeof(T),
|
||||
alignof(T));
|
||||
}
|
||||
else
|
||||
{
|
||||
top_ = begin;
|
||||
}
|
||||
begin_ = begin;
|
||||
end_ = begin_ + n;
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // json
|
||||
} // boost
|
||||
|
||||
#ifdef BOOST_JSON_HEADER_ONLY
|
||||
#include <boost/json/detail/static_stack.ipp>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,66 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2018-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/vinniefalco/json
|
||||
//
|
||||
|
||||
#ifndef BOOST_JSON_DETAIL_STATIC_STACK_IPP
|
||||
#define BOOST_JSON_DETAIL_STATIC_STACK_IPP
|
||||
|
||||
#include <boost/json/detail/static_stack.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
namespace detail {
|
||||
|
||||
template<class T, std::size_t N>
|
||||
static_stack<T, N>::
|
||||
~static_stack()
|
||||
{
|
||||
if(begin_ != t_)
|
||||
sp_->deallocate(begin_,
|
||||
capacity() * sizeof(T),
|
||||
alignof(T));
|
||||
}
|
||||
|
||||
template<class T, std::size_t N>
|
||||
void
|
||||
static_stack<T, N>::
|
||||
grow()
|
||||
{
|
||||
auto const n = 2 * capacity();
|
||||
auto const begin =
|
||||
reinterpret_cast<T*>(
|
||||
sp_->allocate(
|
||||
n * sizeof(T),
|
||||
alignof(T)));
|
||||
if(! empty())
|
||||
{
|
||||
std::memcpy(begin, begin_,
|
||||
size() * sizeof(T));
|
||||
top_ = begin + (top_ - begin_);
|
||||
if(begin_ != t_)
|
||||
sp_->deallocate(begin_,
|
||||
capacity() * sizeof(T),
|
||||
alignof(T));
|
||||
}
|
||||
else
|
||||
{
|
||||
top_ = begin;
|
||||
}
|
||||
begin_ = begin;
|
||||
end_ = begin_ + n;
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // json
|
||||
} // boost
|
||||
|
||||
#ifdef BOOST_JSON_HEADER_ONLY
|
||||
#include <boost/json/detail/static_stack.ipp>
|
||||
#endif
|
||||
|
||||
#endif
|
@ -46,10 +46,10 @@ auto
|
||||
array::
|
||||
impl_type::
|
||||
index_of(value const* pos) const noexcept ->
|
||||
size_type
|
||||
std::size_t
|
||||
{
|
||||
return static_cast<
|
||||
size_type>(pos - vec);
|
||||
std::size_t>(pos - vec);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
@ -95,17 +95,17 @@ public:
|
||||
class array::undo_insert
|
||||
{
|
||||
array& self_;
|
||||
size_type const n_;
|
||||
std::size_t const n_;
|
||||
|
||||
public:
|
||||
value* it;
|
||||
size_type const pos;
|
||||
std::size_t const pos;
|
||||
bool commit = false;
|
||||
|
||||
BOOST_JSON_DECL
|
||||
undo_insert(
|
||||
value const* pos_,
|
||||
unsigned long long n,
|
||||
std::size_t n,
|
||||
array& self);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
@ -130,7 +130,7 @@ public:
|
||||
|
||||
auto
|
||||
array::
|
||||
at(size_type pos) ->
|
||||
at(std::size_t pos) ->
|
||||
reference
|
||||
{
|
||||
if(pos >= impl_.size)
|
||||
@ -142,7 +142,7 @@ at(size_type pos) ->
|
||||
|
||||
auto
|
||||
array::
|
||||
at(size_type pos) const ->
|
||||
at(std::size_t pos) const ->
|
||||
const_reference
|
||||
{
|
||||
if(pos >= impl_.size)
|
||||
@ -154,7 +154,7 @@ at(size_type pos) const ->
|
||||
|
||||
auto
|
||||
array::
|
||||
operator[](size_type pos) noexcept ->
|
||||
operator[](std::size_t pos) noexcept ->
|
||||
reference
|
||||
{
|
||||
return impl_.vec[pos];
|
||||
@ -162,7 +162,7 @@ operator[](size_type pos) noexcept ->
|
||||
|
||||
auto
|
||||
array::
|
||||
operator[](size_type pos) const noexcept ->
|
||||
operator[](std::size_t pos) const noexcept ->
|
||||
const_reference
|
||||
{
|
||||
return impl_.vec[pos];
|
||||
@ -432,7 +432,7 @@ array(
|
||||
BOOST_JSON_THROW(
|
||||
std::length_error(
|
||||
"n > max_size"));
|
||||
reserve(static_cast<size_type>(n));
|
||||
reserve(static_cast<std::size_t>(n));
|
||||
while(impl_.size < n)
|
||||
{
|
||||
::new(
|
||||
@ -484,7 +484,7 @@ insert(
|
||||
std::length_error(
|
||||
"n > max_size"));
|
||||
undo_insert u(pos, static_cast<
|
||||
size_type>(n), *this);
|
||||
std::size_t>(n), *this);
|
||||
while(first != last)
|
||||
u.emplace(*first++);
|
||||
u.commit = true;
|
||||
|
@ -11,8 +11,9 @@
|
||||
#define BOOST_JSON_IMPL_ARRAY_IPP
|
||||
|
||||
#include <boost/json/array.hpp>
|
||||
#include <boost/json/detail/exchange.hpp>
|
||||
#include <boost/json/detail/assert.hpp>
|
||||
#include <boost/json/detail/except.hpp>
|
||||
#include <boost/json/detail/exchange.hpp>
|
||||
#include <boost/pilfer.hpp>
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
@ -27,13 +28,12 @@ namespace json {
|
||||
array::
|
||||
impl_type::
|
||||
impl_type(
|
||||
size_type capacity_,
|
||||
std::size_t capacity_,
|
||||
storage_ptr const& sp)
|
||||
{
|
||||
// The choice of minimum capacity
|
||||
// affects the speed of parsing.
|
||||
// if( capacity_ < min_capacity_)
|
||||
// capacity_ = min_capacity_;
|
||||
if(capacity_ > max_size())
|
||||
BOOST_JSON_THROW(
|
||||
detail::object_too_large_exception());
|
||||
if(capacity_ > 0)
|
||||
vec = reinterpret_cast<value*>(
|
||||
sp->allocate(
|
||||
@ -41,7 +41,8 @@ impl_type(
|
||||
alignof(value)));
|
||||
else
|
||||
vec = nullptr;
|
||||
capacity = capacity_;
|
||||
capacity = static_cast<
|
||||
std::uint32_t>(capacity_);
|
||||
size = 0;
|
||||
}
|
||||
|
||||
@ -133,10 +134,10 @@ array::
|
||||
undo_insert::
|
||||
undo_insert(
|
||||
value const* pos_,
|
||||
unsigned long long n,
|
||||
std::size_t n,
|
||||
array& self)
|
||||
: self_(self)
|
||||
, n_(static_cast<size_type>(n))
|
||||
, n_(static_cast<std::size_t>(n))
|
||||
, pos(self.impl_.index_of(pos_))
|
||||
{
|
||||
if(n > max_size())
|
||||
@ -149,7 +150,9 @@ undo_insert(
|
||||
it = self_.impl_.vec + pos;
|
||||
relocate(it + n_, it,
|
||||
self_.impl_.size - pos);
|
||||
self_.impl_.size += n_;
|
||||
self_.impl_.size = static_cast<
|
||||
std::uint32_t>(
|
||||
self_.impl_.size + n_);
|
||||
}
|
||||
|
||||
array::
|
||||
@ -161,7 +164,9 @@ undo_insert::
|
||||
auto const first =
|
||||
self_.impl_.vec + pos;
|
||||
self_.destroy(first, it);
|
||||
self_.impl_.size -= n_;
|
||||
self_.impl_.size = static_cast<
|
||||
std::uint32_t>(
|
||||
self_.impl_.size - n_);
|
||||
relocate(
|
||||
first, first + n_,
|
||||
self_.impl_.size - pos);
|
||||
@ -182,7 +187,7 @@ array(storage_ptr sp) noexcept
|
||||
|
||||
array::
|
||||
array(
|
||||
size_type count,
|
||||
std::size_t count,
|
||||
value const& v,
|
||||
storage_ptr sp)
|
||||
: sp_(std::move(sp))
|
||||
@ -201,7 +206,7 @@ array(
|
||||
|
||||
array::
|
||||
array(
|
||||
size_type count,
|
||||
std::size_t count,
|
||||
storage_ptr sp)
|
||||
: sp_(std::move(sp))
|
||||
{
|
||||
@ -286,7 +291,8 @@ array(unchecked_array&& ua)
|
||||
: sp_(ua.get_storage())
|
||||
, impl_(ua.size(), sp_) // exact
|
||||
{
|
||||
impl_.size = ua.size();
|
||||
impl_.size = static_cast<
|
||||
std::uint32_t>(ua.size());
|
||||
ua.relocate(impl_.vec);
|
||||
}
|
||||
|
||||
@ -390,7 +396,7 @@ auto
|
||||
array::
|
||||
insert(
|
||||
const_iterator pos,
|
||||
size_type count,
|
||||
std::size_t count,
|
||||
value const& v) ->
|
||||
iterator
|
||||
{
|
||||
@ -409,7 +415,7 @@ insert(
|
||||
iterator
|
||||
{
|
||||
undo_insert u(pos,
|
||||
static_cast<size_type>(
|
||||
static_cast<std::size_t>(
|
||||
init.size()), *this);
|
||||
for(auto const& v : init)
|
||||
u.emplace(v);
|
||||
@ -439,14 +445,15 @@ erase(
|
||||
iterator
|
||||
{
|
||||
auto const n = static_cast<
|
||||
size_type>(last - first);
|
||||
std::size_t>(last - first);
|
||||
auto const p =
|
||||
impl_.vec + impl_.index_of(first);
|
||||
destroy(p, p + n);
|
||||
relocate(p, p + n,
|
||||
impl_.size -
|
||||
impl_.index_of(last));
|
||||
impl_.size -= n;
|
||||
impl_.size = static_cast<
|
||||
std::uint32_t>(impl_.size - n);
|
||||
return p;
|
||||
}
|
||||
|
||||
@ -461,14 +468,15 @@ pop_back() noexcept
|
||||
|
||||
void
|
||||
array::
|
||||
resize(size_type count)
|
||||
resize(std::size_t count)
|
||||
{
|
||||
if(count <= impl_.size)
|
||||
{
|
||||
destroy(
|
||||
impl_.vec + count,
|
||||
impl_.vec + impl_.size);
|
||||
impl_.size = count;
|
||||
impl_.size = static_cast<
|
||||
std::uint32_t>(count);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -479,13 +487,14 @@ resize(size_type count)
|
||||
impl_.vec + count;
|
||||
while(it != end)
|
||||
::new(it++) value(sp_);
|
||||
impl_.size = count;
|
||||
impl_.size = static_cast<
|
||||
std::uint32_t>(count);
|
||||
}
|
||||
|
||||
void
|
||||
array::
|
||||
resize(
|
||||
size_type count,
|
||||
std::size_t count,
|
||||
value const& v)
|
||||
{
|
||||
if(count <= size())
|
||||
@ -493,7 +502,8 @@ resize(
|
||||
destroy(
|
||||
impl_.vec + count,
|
||||
impl_.vec + impl_.size);
|
||||
impl_.size = count;
|
||||
impl_.size = static_cast<
|
||||
std::uint32_t>(count);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -523,7 +533,8 @@ resize(
|
||||
++u.it;
|
||||
}
|
||||
while(u.it != end);
|
||||
impl_.size = count;
|
||||
impl_.size = static_cast<
|
||||
std::uint32_t>(count);
|
||||
u.it = nullptr;
|
||||
}
|
||||
|
||||
@ -597,7 +608,7 @@ copy(
|
||||
std::length_error(
|
||||
"size > max_size()"));
|
||||
reserve(static_cast<
|
||||
size_type>(init.size()));
|
||||
std::size_t>(init.size()));
|
||||
for(auto const& v : init)
|
||||
{
|
||||
::new(
|
||||
@ -609,7 +620,7 @@ copy(
|
||||
|
||||
void
|
||||
array::
|
||||
reserve_impl(size_type capacity)
|
||||
reserve_impl(std::size_t capacity)
|
||||
{
|
||||
if(impl_.vec)
|
||||
{
|
||||
@ -638,7 +649,7 @@ array::
|
||||
relocate(
|
||||
value* dest,
|
||||
value* src,
|
||||
size_type n) noexcept
|
||||
std::size_t n) noexcept
|
||||
{
|
||||
if(n == 0)
|
||||
return;
|
||||
|
@ -441,8 +441,7 @@ loop_str1:
|
||||
goto yield;
|
||||
}
|
||||
++p;
|
||||
st_.pop();
|
||||
st_.push(state::str2);
|
||||
*st_ = state::str2;
|
||||
BOOST_FALLTHROUGH;
|
||||
|
||||
// string, no-copy loop
|
||||
|
@ -50,25 +50,23 @@ key
|
||||
|
||||
enum class parser::state : char
|
||||
{
|
||||
need_start,
|
||||
begin,
|
||||
need_start, // start() not called yet
|
||||
begin, // we have a storage_ptr
|
||||
|
||||
// These states indicate what is
|
||||
// currently at top of the stack.
|
||||
|
||||
top, // empty value
|
||||
arr, // empty array value
|
||||
obj, // empty object value
|
||||
key, // complete key
|
||||
end // final value
|
||||
top, // empty top value
|
||||
arr, // empty array value
|
||||
obj, // empty object value
|
||||
key, // complete key
|
||||
end // compelte top value
|
||||
};
|
||||
|
||||
void
|
||||
parser::
|
||||
destroy() noexcept
|
||||
{
|
||||
if(st_ == state::need_start)
|
||||
return;
|
||||
if(key_size_ > 0)
|
||||
{
|
||||
// remove partial key
|
||||
@ -86,23 +84,26 @@ destroy() noexcept
|
||||
str_size_ = 0;
|
||||
}
|
||||
// unwind the rest
|
||||
while(! rs_.empty())
|
||||
do
|
||||
{
|
||||
switch(st_)
|
||||
{
|
||||
case state::need_start:
|
||||
BOOST_JSON_ASSERT(
|
||||
rs_.empty());
|
||||
break;
|
||||
|
||||
case state::begin:
|
||||
BOOST_JSON_ASSERT(
|
||||
rs_.empty());
|
||||
break;
|
||||
|
||||
case state::top:
|
||||
rs_.subtract(
|
||||
sizeof(value));
|
||||
break;
|
||||
|
||||
case state::end:
|
||||
{
|
||||
auto ua =
|
||||
pop_array();
|
||||
BOOST_JSON_ASSERT(
|
||||
ua.size() == 1);
|
||||
rs_.empty());
|
||||
break;
|
||||
}
|
||||
|
||||
case state::arr:
|
||||
{
|
||||
@ -133,13 +134,20 @@ destroy() noexcept
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// should never get here
|
||||
case state::end:
|
||||
{
|
||||
auto ua =
|
||||
pop_array();
|
||||
BOOST_JSON_ASSERT(
|
||||
ua.size() == 1);
|
||||
BOOST_JSON_ASSERT(
|
||||
rs_.empty());
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
while(! rs_.empty());
|
||||
}
|
||||
|
||||
parser::
|
||||
@ -170,6 +178,9 @@ clear() noexcept
|
||||
destroy();
|
||||
rs_.clear();
|
||||
basic_parser::reset();
|
||||
count_ = 0;
|
||||
key_size_ = 0;
|
||||
str_size_ = 0;
|
||||
st_ = state::need_start;
|
||||
sp_ = {};
|
||||
}
|
||||
@ -178,22 +189,28 @@ value
|
||||
parser::
|
||||
release() noexcept
|
||||
{
|
||||
BOOST_JSON_ASSERT(is_done());
|
||||
BOOST_JSON_ASSERT(st_ == state::end);
|
||||
auto ua = pop_array();
|
||||
BOOST_JSON_ASSERT(rs_.empty());
|
||||
union U
|
||||
if(is_done())
|
||||
{
|
||||
value v;
|
||||
U(){}
|
||||
~U(){}
|
||||
};
|
||||
U u;
|
||||
ua.relocate(&u.v);
|
||||
basic_parser::reset();
|
||||
st_ = state::need_start;
|
||||
sp_ = {};
|
||||
return std::move(u.v);
|
||||
BOOST_JSON_ASSERT(st_ == state::end);
|
||||
auto ua = pop_array();
|
||||
BOOST_JSON_ASSERT(rs_.empty());
|
||||
union U
|
||||
{
|
||||
value v;
|
||||
U(){}
|
||||
~U(){}
|
||||
};
|
||||
U u;
|
||||
ua.relocate(&u.v);
|
||||
basic_parser::reset();
|
||||
st_ = state::need_start;
|
||||
sp_ = {};
|
||||
return std::move(u.v);
|
||||
}
|
||||
// return null
|
||||
value jv(std::move(sp_));
|
||||
clear();
|
||||
return jv;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
@ -233,13 +250,19 @@ emplace(Args&&... args)
|
||||
U u;
|
||||
std::size_t key_size;
|
||||
pop(key_size);
|
||||
auto const key =
|
||||
pop_chars(key_size);
|
||||
// remember the offset in case
|
||||
// the stack is reallocated.
|
||||
auto const offset =
|
||||
rs_.pop(key_size) -
|
||||
rs_.begin();
|
||||
st_ = state::obj;
|
||||
// prevent splits from exceptions
|
||||
rs_.prepare(2 * sizeof(u.v));
|
||||
::new(&u.v) object::value_type(
|
||||
key, std::forward<Args>(args)...);
|
||||
string_view(
|
||||
rs_.begin() + offset,
|
||||
key_size),
|
||||
std::forward<Args>(args)...);
|
||||
rs_.subtract(sizeof(u.v));
|
||||
push(u.v);
|
||||
rs_.add(sizeof(u.v));
|
||||
@ -256,6 +279,7 @@ emplace(Args&&... args)
|
||||
~U(){}
|
||||
};
|
||||
U u;
|
||||
// prevent splits from exceptions
|
||||
rs_.prepare(2 * sizeof(value));
|
||||
::new(&u.v) value(
|
||||
std::forward<Args>(args)...);
|
||||
@ -288,9 +312,7 @@ pop_object() noexcept
|
||||
object::value_type);
|
||||
return { reinterpret_cast<
|
||||
object::value_type*>(rs_.pop(n)),
|
||||
// VFALCO bad narrowing
|
||||
static_cast<std::uint32_t>(count_),
|
||||
sp_ };
|
||||
count_, sp_ };
|
||||
}
|
||||
|
||||
unchecked_array
|
||||
@ -303,10 +325,7 @@ pop_array() noexcept
|
||||
auto const n =
|
||||
count_ * sizeof(value);
|
||||
return { reinterpret_cast<value*>(
|
||||
rs_.pop(n)),
|
||||
// VFALCO bad narrowing
|
||||
static_cast<std::uint32_t>(count_),
|
||||
sp_ };
|
||||
rs_.pop(n)), count_, sp_ };
|
||||
}
|
||||
|
||||
string_view
|
||||
|
@ -93,7 +93,7 @@ is_done() const noexcept
|
||||
|
||||
std::size_t
|
||||
serializer::
|
||||
next(char* dest, std::size_t size)
|
||||
read(char* dest, std::size_t size)
|
||||
{
|
||||
static constexpr char hex[] = "0123456789abcdef";
|
||||
static constexpr char esc[] =
|
||||
@ -370,7 +370,7 @@ loop_str:
|
||||
std::memcpy(p, ss, n);
|
||||
ss = s;
|
||||
p += n;
|
||||
*p++ = ch;
|
||||
//*p++ = ch;
|
||||
*p++ = '\\';
|
||||
*p++ = c;
|
||||
if(c != 'u')
|
||||
@ -505,7 +505,7 @@ to_string(
|
||||
s.reserve(s.capacity() + 1);
|
||||
s.grow(static_cast<
|
||||
string::size_type>(
|
||||
sr.next(s.data() + s.size(),
|
||||
sr.read(s.data() + s.size(),
|
||||
s.capacity() - s.size())));
|
||||
}
|
||||
return s;
|
||||
@ -519,7 +519,7 @@ operator<<(std::ostream& os, value const& jv)
|
||||
{
|
||||
char buf[4096];
|
||||
auto const n =
|
||||
sr.next(buf, sizeof(buf));
|
||||
sr.read(buf, sizeof(buf));
|
||||
os.write(buf, n);
|
||||
}
|
||||
return os;
|
||||
|
@ -44,7 +44,7 @@
|
||||
</Type>
|
||||
|
||||
<Type Name="boost::json::string">
|
||||
<DisplayString>{{ {impl_.capacity>sizeof(impl_.buf)?impl_.p:impl_.buf,[impl_.size]s} }}</DisplayString>
|
||||
<DisplayString>{impl_.capacity>sizeof(impl_.buf)?impl_.p:impl_.buf,[impl_.size]s}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[capacity]">impl_.capacity</Item>
|
||||
<Item Name="[storage]">sp_</Item>
|
||||
|
@ -33,9 +33,9 @@ class parser final
|
||||
|
||||
storage_ptr sp_;
|
||||
detail::raw_stack rs_;
|
||||
std::size_t count_;
|
||||
std::size_t key_size_;
|
||||
std::size_t str_size_;
|
||||
std::size_t count_ = 0;
|
||||
std::size_t key_size_ = 0;
|
||||
std::size_t str_size_ = 0;
|
||||
state st_;
|
||||
|
||||
inline
|
||||
|
@ -66,7 +66,7 @@ class serializer
|
||||
};
|
||||
#endif
|
||||
|
||||
detail::static_stack<node, 50> stack_;
|
||||
detail::static_stack<node, 16> stack_;
|
||||
|
||||
string_view str_;
|
||||
unsigned char nbuf_;
|
||||
@ -91,7 +91,7 @@ public:
|
||||
|
||||
BOOST_JSON_DECL
|
||||
std::size_t
|
||||
next(char* dest, std::size_t size);
|
||||
read(char* dest, std::size_t size);
|
||||
};
|
||||
|
||||
BOOST_JSON_DECL
|
||||
|
@ -36,7 +36,6 @@ the program, with the macro BOOST_BEAST_SPLIT_COMPILATION defined.
|
||||
#include <boost/json/detail/format.ipp>
|
||||
#include <boost/json/detail/number.ipp>
|
||||
#include <boost/json/detail/raw_stack.ipp>
|
||||
#include <boost/json/detail/static_stack.ipp>
|
||||
#include <boost/json/detail/ryu/impl/d2s.ipp>
|
||||
|
||||
#endif
|
||||
|
@ -1848,7 +1848,7 @@ private:
|
||||
class unchecked_object
|
||||
{
|
||||
object::value_type* data_;
|
||||
unsigned long size_;
|
||||
std::size_t size_;
|
||||
storage_ptr const& sp_;
|
||||
|
||||
public:
|
||||
@ -1857,7 +1857,7 @@ public:
|
||||
|
||||
unchecked_object(
|
||||
object::value_type* data,
|
||||
unsigned long size,
|
||||
std::size_t size,
|
||||
storage_ptr const& sp) noexcept
|
||||
: data_(data)
|
||||
, size_(size)
|
||||
@ -1880,7 +1880,7 @@ public:
|
||||
return sp_;
|
||||
}
|
||||
|
||||
unsigned long
|
||||
std::size_t
|
||||
size() const noexcept
|
||||
{
|
||||
return size_;
|
||||
|
@ -49,6 +49,7 @@ add_executable (json-tests
|
||||
ryu/d2s_intrinsics_test.cpp
|
||||
ryu/d2s_table_test.cpp
|
||||
ryu/d2s_test.cpp
|
||||
ryu/gtest.hpp
|
||||
)
|
||||
|
||||
add_test(json-tests json-tests)
|
||||
|
@ -23,7 +23,7 @@ public:
|
||||
using init_list = std::initializer_list<value>;
|
||||
|
||||
string_view const str_;
|
||||
unsigned long min_capacity_;
|
||||
std::size_t min_capacity_;
|
||||
|
||||
array_test()
|
||||
: str_(
|
||||
|
@ -513,10 +513,6 @@ public:
|
||||
void
|
||||
run() override
|
||||
{
|
||||
log <<
|
||||
"sizeof(basic_parser) == " <<
|
||||
sizeof(basic_parser) << "\n";
|
||||
|
||||
testObject();
|
||||
testArray();
|
||||
testString();
|
||||
|
@ -4,8 +4,40 @@
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/vinniefalco/BeastLounge
|
||||
// Official repository: https://github.com/vinniefalco/json
|
||||
//
|
||||
|
||||
// Test that header file is self-contained.
|
||||
#include <boost/json.hpp>
|
||||
|
||||
#include <boost/beast/_experimental/unit_test/suite.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
|
||||
struct zjson_test : public beast::unit_test::suite
|
||||
{
|
||||
void
|
||||
run() override
|
||||
{
|
||||
log <<
|
||||
"sizeof()\n"
|
||||
" object == " << sizeof(object) << "\n"
|
||||
" value_type == " << sizeof(object::value_type) << "\n"
|
||||
" array == " << sizeof(array) << "\n"
|
||||
" string == " << sizeof(string) << "\n"
|
||||
" value == " << sizeof(value) << "\n"
|
||||
" serializer == " << sizeof(serializer) << "\n"
|
||||
" number_parser == " << sizeof(detail::number_parser) << "\n"
|
||||
" basic_parser == " << sizeof(basic_parser) << "\n"
|
||||
" parser == " << sizeof(parser) << "\n"
|
||||
<< std::endl;
|
||||
;
|
||||
pass();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(boost,json,zjson);
|
||||
|
||||
} // json
|
||||
} // boost
|
||||
|
@ -331,10 +331,6 @@ public:
|
||||
void
|
||||
run() override
|
||||
{
|
||||
log <<
|
||||
"sizeof(number_parser) == " <<
|
||||
sizeof(number_parser) <<
|
||||
std::endl;
|
||||
testParse();
|
||||
testMembers();
|
||||
}
|
||||
|
218
test/parser.cpp
218
test/parser.cpp
@ -36,9 +36,8 @@ public:
|
||||
s.data(),
|
||||
s.size(),
|
||||
ec);
|
||||
if(! BEAST_EXPECTS(! ec,
|
||||
ec.message()))
|
||||
return nullptr;
|
||||
BEAST_EXPECTS(! ec,
|
||||
ec.message());
|
||||
//log << " " << to_string_test(p.get()) << std::endl;
|
||||
return p.release();
|
||||
}
|
||||
@ -49,7 +48,8 @@ public:
|
||||
string_view s1)
|
||||
{
|
||||
auto const s2 =
|
||||
to_string_test(jv1);
|
||||
//to_string_test(jv1); // use this if serializer is broken
|
||||
to_string(jv1);
|
||||
auto jv2 =
|
||||
from_string_test(s2);
|
||||
if(! BEAST_EXPECT(equal(jv1, jv2)))
|
||||
@ -59,43 +59,43 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
testParse()
|
||||
grind_one(string_view s)
|
||||
{
|
||||
string_view const js =
|
||||
"{\"1\":{},\"2\":[],\"3\":\"x\",\"4\":1,"
|
||||
"\"5\":-1,\"6\":1.0,\"7\":false,\"8\":null}";
|
||||
|
||||
// parse(value)
|
||||
{
|
||||
check_round_trip(
|
||||
parse(js),
|
||||
js);
|
||||
}
|
||||
|
||||
// parse(value, storage_ptr)
|
||||
{
|
||||
check_round_trip(
|
||||
parse(js, storage_ptr{}),
|
||||
js);
|
||||
}
|
||||
|
||||
// parse(value, error_code)
|
||||
{
|
||||
error_code ec;
|
||||
auto jv = parse(js, ec);
|
||||
BEAST_EXPECTS(! ec, ec.message());
|
||||
check_round_trip(jv, js);
|
||||
}
|
||||
|
||||
// parse(value, storage_ptr, error_code)
|
||||
{
|
||||
error_code ec;
|
||||
auto jv = parse(js, storage_ptr{}, ec);
|
||||
BEAST_EXPECTS(! ec, ec.message());
|
||||
check_round_trip(jv, js);
|
||||
}
|
||||
auto const jv =
|
||||
from_string_test(s);
|
||||
check_round_trip(jv, s);
|
||||
}
|
||||
|
||||
void
|
||||
grind(string_view s)
|
||||
{
|
||||
grind_one(s);
|
||||
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
auto const jv =
|
||||
from_string_test(s, sp);
|
||||
check_round_trip(jv, s);
|
||||
});
|
||||
|
||||
if(s.size() > 1)
|
||||
{
|
||||
// Destroy the parser at every
|
||||
// split point to check leaks.
|
||||
for(std::size_t i = 1;
|
||||
i < s.size(); ++i)
|
||||
{
|
||||
scoped_storage<
|
||||
fail_storage> ss;
|
||||
parser p;
|
||||
error_code ec;
|
||||
p.start(ss);
|
||||
p.write(s.data(), i, ec);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
legacyTests()
|
||||
{
|
||||
@ -125,10 +125,11 @@ R"xx({
|
||||
;
|
||||
parser p;
|
||||
error_code ec;
|
||||
p.start();
|
||||
p.write(in.data(), in.size(), ec);
|
||||
if(BEAST_EXPECTS(! ec, ec.message()))
|
||||
{
|
||||
BEAST_EXPECT(to_string_test(p.get()) ==
|
||||
BEAST_EXPECT(to_string_test(p.release()) ==
|
||||
"{\"glossary\":{\"title\":\"example glossary\",\"GlossDiv\":"
|
||||
"{\"title\":\"S\",\"GlossList\":{\"GlossEntry\":{\"ID\":\"SGML\","
|
||||
"\"SortAs\":\"SGML\",\"GlossTerm\":\"Standard Generalized Markup "
|
||||
@ -140,24 +141,6 @@ R"xx({
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
grind(string_view s)
|
||||
{
|
||||
{
|
||||
auto const jv =
|
||||
from_string_test(s);
|
||||
check_round_trip(jv, s);
|
||||
}
|
||||
#if 1
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
auto const jv =
|
||||
from_string_test(s, sp);
|
||||
check_round_trip(jv, s);
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
testObjects()
|
||||
{
|
||||
@ -170,6 +153,28 @@ R"xx({
|
||||
grind(
|
||||
"{\"1\":{},\"2\":[],\"3\":\"x\",\"4\":1,"
|
||||
"\"5\":-1,\"6\":1.0,\"7\":false,\"8\":null}");
|
||||
|
||||
// big strings
|
||||
{
|
||||
std::string const big(4000, '*');
|
||||
{
|
||||
std::string js;
|
||||
js = "{\"" + big + "\":null}";
|
||||
grind(js);
|
||||
}
|
||||
|
||||
{
|
||||
std::string js;
|
||||
js = "{\"x\":\"" + big + "\"}";
|
||||
grind(js);
|
||||
}
|
||||
|
||||
{
|
||||
std::string js;
|
||||
js = "{\"" + big + "\":\"" + big + "\"}";
|
||||
grind(js);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -209,6 +214,30 @@ R"xx({
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"\"");
|
||||
|
||||
// big string
|
||||
{
|
||||
std::string const big(4000, '*');
|
||||
{
|
||||
std::string js;
|
||||
js = "\"" + big + "\"";
|
||||
auto const N = js.size() / 2;
|
||||
error_code ec;
|
||||
parser p;
|
||||
p.start();
|
||||
p.write_some(js.data(), N, ec);
|
||||
if(BEAST_EXPECTS(! ec,
|
||||
ec.message()))
|
||||
{
|
||||
p.write(js.data() + N,
|
||||
js.size() - N, ec);
|
||||
if(BEAST_EXPECTS(! ec,
|
||||
ec.message()))
|
||||
check_round_trip(
|
||||
p.release(), js);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -243,21 +272,82 @@ R"xx({
|
||||
grind("null");
|
||||
}
|
||||
|
||||
void
|
||||
testMembers()
|
||||
{
|
||||
// need start error
|
||||
{
|
||||
parser p;
|
||||
error_code ec;
|
||||
p.write("", 0, ec);
|
||||
BEAST_EXPECTS(
|
||||
ec == error::need_start,
|
||||
ec.message());
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
|
||||
void
|
||||
testFreeFunctions()
|
||||
{
|
||||
string_view const js =
|
||||
"{\"1\":{},\"2\":[],\"3\":\"x\",\"4\":1,"
|
||||
"\"5\":-1,\"6\":1.0,\"7\":false,\"8\":null}";
|
||||
|
||||
// parse(value)
|
||||
{
|
||||
{
|
||||
check_round_trip(
|
||||
parse(js),
|
||||
js);
|
||||
}
|
||||
|
||||
{
|
||||
BEAST_THROWS(parse(
|
||||
"{,"),
|
||||
system_error);
|
||||
}
|
||||
}
|
||||
|
||||
// parse(value, storage_ptr)
|
||||
{
|
||||
check_round_trip(
|
||||
parse(js, storage_ptr{}),
|
||||
js);
|
||||
}
|
||||
|
||||
// parse(value, error_code)
|
||||
{
|
||||
error_code ec;
|
||||
auto jv = parse(js, ec);
|
||||
BEAST_EXPECTS(! ec, ec.message());
|
||||
check_round_trip(jv, js);
|
||||
}
|
||||
|
||||
// parse(value, storage_ptr, error_code)
|
||||
{
|
||||
error_code ec;
|
||||
auto jv = parse(js, storage_ptr{}, ec);
|
||||
BEAST_EXPECTS(! ec, ec.message());
|
||||
check_round_trip(jv, js);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
run()
|
||||
{
|
||||
log <<
|
||||
"sizeof(parser) == " <<
|
||||
sizeof(parser) << "\n";
|
||||
|
||||
grind("[{\"x\": [{\"x\": [{\"x\":null}] }] }]");
|
||||
testParse();
|
||||
testObjects();
|
||||
testArrays();
|
||||
//testStrings();
|
||||
testStrings();
|
||||
testNumbers();
|
||||
testBool();
|
||||
testNull();
|
||||
testMembers();
|
||||
testFreeFunctions();
|
||||
|
||||
// This still doesn't work..
|
||||
//legacyTests();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
#define TEST(s1,s2) \
|
||||
struct s2 ## s1 ## _test; \
|
||||
BEAST_DEFINE_TESTSUITE(boost,ryu,s2##s1); \
|
||||
BEAST_DEFINE_TESTSUITE(boost,Ryu,s2##s1); \
|
||||
struct s2 ## s1 ## _test : ::boost::beast::unit_test::suite { \
|
||||
void run() override; }; void s2##s1##_test::run()
|
||||
|
||||
|
@ -14,200 +14,16 @@
|
||||
#include <boost/beast/_experimental/unit_test/suite.hpp>
|
||||
#include "parse-vectors.hpp"
|
||||
|
||||
#define SOFT_FAIL
|
||||
#include "test.hpp"
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
|
||||
static
|
||||
void
|
||||
print(
|
||||
std::ostream& os,
|
||||
json::value const& jv);
|
||||
|
||||
static
|
||||
void
|
||||
print(
|
||||
std::ostream& os,
|
||||
object const& obj)
|
||||
{
|
||||
os << "{";
|
||||
for(auto it = obj.begin();
|
||||
it != obj.end(); ++it)
|
||||
{
|
||||
if(it != obj.begin())
|
||||
os << ",";
|
||||
os << "\"" << it->key() << "\":";
|
||||
print(os, it->value());
|
||||
}
|
||||
os << "}";
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
print(
|
||||
std::ostream& os,
|
||||
array const& arr)
|
||||
{
|
||||
os << "[";
|
||||
for(auto it = arr.begin();
|
||||
it != arr.end(); ++it)
|
||||
{
|
||||
if(it != arr.begin())
|
||||
os << ",";
|
||||
print(os, *it);
|
||||
}
|
||||
os << "]";
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
print(
|
||||
std::ostream& os,
|
||||
json::value const& jv)
|
||||
{
|
||||
switch(jv.kind())
|
||||
{
|
||||
case kind::object:
|
||||
print(os, jv.get_object());
|
||||
break;
|
||||
case kind::array:
|
||||
print(os, jv.get_array());
|
||||
break;
|
||||
case kind::string:
|
||||
os << "\"" << jv.get_string() << "\"";
|
||||
break;
|
||||
case kind::int64:
|
||||
os << jv.as_int64();
|
||||
break;
|
||||
case kind::uint64:
|
||||
os << jv.as_uint64();
|
||||
break;
|
||||
case kind::double_:
|
||||
os << jv.as_double();
|
||||
break;
|
||||
case kind::boolean:
|
||||
if(jv.as_bool())
|
||||
os << "true";
|
||||
else
|
||||
os << "false";
|
||||
break;
|
||||
case kind::null:
|
||||
os << "null";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
class serializer_test : public beast::unit_test::suite
|
||||
{
|
||||
public:
|
||||
static
|
||||
unsigned
|
||||
common(
|
||||
string_view s1,
|
||||
string_view s2)
|
||||
{
|
||||
unsigned n = 0;
|
||||
auto p1 = s1.data();
|
||||
auto p2 = s2.data();
|
||||
auto end = s1.size() > s2.size() ?
|
||||
s2.end() : s1.end();
|
||||
while(p1 < end)
|
||||
{
|
||||
++n;
|
||||
if(*p1++ != *p2++)
|
||||
break;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
void
|
||||
round_trip(
|
||||
string_view name,
|
||||
string_view s0)
|
||||
{
|
||||
error_code ec;
|
||||
auto jv0 = parse(s0, ec);
|
||||
#ifdef SOFT_FAIL
|
||||
if(ec)
|
||||
return;
|
||||
#else
|
||||
if( ! BEAST_EXPECTS(
|
||||
! ec, ec.message()))
|
||||
return;
|
||||
#endif
|
||||
auto s1 = to_string(jv0);
|
||||
parser p;
|
||||
p.start();
|
||||
auto n = p.write(
|
||||
s1.data(), s1.size(), ec);
|
||||
#ifdef SOFT_FAIL
|
||||
if(ec)
|
||||
#else
|
||||
if( ! BEAST_EXPECTS(
|
||||
! ec, ec.message()))
|
||||
#endif
|
||||
{
|
||||
auto c1 = s1.data() + n;
|
||||
if( n > 60)
|
||||
n = 60;
|
||||
auto c0 = c1 - n;
|
||||
log <<
|
||||
"context\n"
|
||||
" " << string_view(c0, c1-c0) << std::endl;
|
||||
log <<
|
||||
name << "\n"
|
||||
" " << s0 << "\n"
|
||||
" " << s1 << std::endl << std::endl;
|
||||
return;
|
||||
}
|
||||
auto jv1 = p.release();
|
||||
auto s2 = to_string(jv1);
|
||||
#ifdef SOFT_FAIL
|
||||
if(s1 != s2)
|
||||
#else
|
||||
if(! BEAST_EXPECT(s1 == s2))
|
||||
#endif
|
||||
{
|
||||
auto c = common(s1, s2);
|
||||
log <<
|
||||
name << "\n"
|
||||
" " << s0 << "\n"
|
||||
" " << s1.substr(0, c) << "\n"
|
||||
" " << s2.substr(0, c) << std::endl << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
print_grind(
|
||||
string_view name,
|
||||
json::value const& jv)
|
||||
{
|
||||
auto const s0 = to_string(jv);
|
||||
log << s0 << std::endl;
|
||||
round_trip(name, s0);
|
||||
for(std::size_t i = 1;
|
||||
i < s0.size() - 1; ++i)
|
||||
{
|
||||
std::string s;
|
||||
s.resize(s0.size());
|
||||
serializer sr(jv);
|
||||
auto const n1 =
|
||||
sr.next(&s[0], i);
|
||||
if(BEAST_EXPECT(n1 == i))
|
||||
sr.next(
|
||||
&s[n1], s.size() - n1);
|
||||
if(! BEAST_EXPECT(s == s0))
|
||||
{
|
||||
log <<
|
||||
" " << s0 << "\n"
|
||||
" " << s << std::endl << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testSerializer()
|
||||
testMembers()
|
||||
{
|
||||
value jv;
|
||||
|
||||
@ -222,11 +38,11 @@ public:
|
||||
BEAST_EXPECT(! sr.is_done());
|
||||
}
|
||||
|
||||
// next()
|
||||
// read()
|
||||
{
|
||||
serializer sr(jv);
|
||||
char buf[1024];
|
||||
auto n = sr.next(
|
||||
auto n = sr.read(
|
||||
buf, sizeof(buf));
|
||||
BEAST_EXPECT(sr.is_done());
|
||||
BEAST_EXPECT(string_view(
|
||||
@ -235,114 +51,356 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
testRoundTrips()
|
||||
grind_one(
|
||||
string_view s,
|
||||
value const& jv,
|
||||
string_view name = {})
|
||||
{
|
||||
error_code ec;
|
||||
auto const s1 = to_string(jv);
|
||||
auto const jv2 = parse(s1, ec);
|
||||
if(! BEAST_EXPECT(equal(jv, jv2)))
|
||||
{
|
||||
if(name.empty())
|
||||
log <<
|
||||
" " << s << "\n"
|
||||
" " << s1 <<
|
||||
std::endl;
|
||||
else
|
||||
log << name << ":\n"
|
||||
" " << s << "\n"
|
||||
" " << s1 <<
|
||||
std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
grind(
|
||||
string_view s0,
|
||||
value const& jv,
|
||||
string_view name = {})
|
||||
{
|
||||
grind_one(s0, jv, name);
|
||||
|
||||
auto const s1 =
|
||||
to_string(jv);
|
||||
for(std::size_t i = 1;
|
||||
i < s1.size(); ++i)
|
||||
{
|
||||
serializer sr(jv);
|
||||
string s2;
|
||||
s2.reserve(s1.size());
|
||||
s2.grow(sr.read(
|
||||
s2.data(), i));
|
||||
auto const dump =
|
||||
[&]
|
||||
{
|
||||
if(name.empty())
|
||||
log <<
|
||||
" " << s0 << "\n"
|
||||
" " << s1 << "\n"
|
||||
" " << s2 << std::endl;
|
||||
else
|
||||
log << name << ":\n"
|
||||
" " << s0 << "\n"
|
||||
" " << s1 << "\n"
|
||||
" " << s2 << std::endl;
|
||||
};
|
||||
if(! BEAST_EXPECT(
|
||||
s2.size() == i))
|
||||
{
|
||||
dump();
|
||||
break;
|
||||
}
|
||||
s2.grow(sr.read(
|
||||
s2.data() + i,
|
||||
s1.size() - i));
|
||||
if(! BEAST_EXPECT(
|
||||
s2.size() == s1.size()))
|
||||
{
|
||||
dump();
|
||||
break;
|
||||
}
|
||||
if(! BEAST_EXPECT(s2 == s1))
|
||||
{
|
||||
dump();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
check(
|
||||
string_view s,
|
||||
string_view name = {})
|
||||
{
|
||||
auto const jv = parse(s);
|
||||
grind(s, jv, name);
|
||||
}
|
||||
|
||||
void
|
||||
testObject()
|
||||
{
|
||||
check("{}");
|
||||
check("{\"x\":1}");
|
||||
check("{\"x\":[]}");
|
||||
check("{\"x\":1,\"y\":null}");
|
||||
}
|
||||
|
||||
void
|
||||
testArray()
|
||||
{
|
||||
check("[]");
|
||||
check("[[]]");
|
||||
check("[[],[],[]]");
|
||||
check("[[[[[[[[[[]]]]]]]]]]");
|
||||
check("[{}]");
|
||||
check("[{},{}]");
|
||||
check("[1,2,3,4,5]");
|
||||
check("[true,false,null]");
|
||||
}
|
||||
|
||||
void
|
||||
testString()
|
||||
{
|
||||
check("\"\"");
|
||||
check("\"x\"");
|
||||
check("\"xyz\"");
|
||||
check("\"x z\"");
|
||||
|
||||
// escapes
|
||||
check("\"\\\"\""); // double quote
|
||||
check("\"\\\\\""); // backslash
|
||||
check("\"\\b\""); // backspace
|
||||
check("\"\\f\""); // formfeed
|
||||
check("\"\\n\""); // newline
|
||||
check("\"\\r\""); // carriage return
|
||||
check("\"\\t\""); // horizontal tab
|
||||
|
||||
// contro\l characters
|
||||
check("\"\\u0000\"");
|
||||
check("\"\\u0001\"");
|
||||
check("\"\\u0002\"");
|
||||
check("\"\\u0003\"");
|
||||
check("\"\\u0004\"");
|
||||
check("\"\\u0005\"");
|
||||
check("\"\\u0006\"");
|
||||
check("\"\\u0007\"");
|
||||
check("\"\\u0008\"");
|
||||
check("\"\\u0009\"");
|
||||
check("\"\\u000a\"");
|
||||
check("\"\\u000b\"");
|
||||
check("\"\\u000c\"");
|
||||
check("\"\\u000d\"");
|
||||
check("\"\\u000e\"");
|
||||
check("\"\\u000f\"");
|
||||
check("\"\\u0010\"");
|
||||
check("\"\\u0011\"");
|
||||
check("\"\\u0012\"");
|
||||
check("\"\\u0013\"");
|
||||
check("\"\\u0014\"");
|
||||
check("\"\\u0015\"");
|
||||
check("\"\\u0016\"");
|
||||
check("\"\\u0017\"");
|
||||
check("\"\\u0018\"");
|
||||
check("\"\\u0019\"");
|
||||
check("\"\\u0020\"");
|
||||
check("\"\\u0021\"");
|
||||
}
|
||||
|
||||
void
|
||||
testNumber()
|
||||
{
|
||||
// VFALCO These don't perfectly round-trip,
|
||||
// because the representations are not exact.
|
||||
// The test needs to do a better job of comparison.
|
||||
|
||||
check("-999999999999999999999");
|
||||
check("-100000000000000000009");
|
||||
check("-10000000000000000000");
|
||||
//check("-9223372036854775809");
|
||||
check("-9223372036854775808");
|
||||
check("-9223372036854775807");
|
||||
check("-999999999999999999");
|
||||
check("-99999999999999999");
|
||||
check("-9999999999999999");
|
||||
check("-999999999999999");
|
||||
check("-99999999999999");
|
||||
check("-9999999999999");
|
||||
check("-999999999999");
|
||||
check("-99999999999");
|
||||
check("-9999999999");
|
||||
check("-999999999");
|
||||
check("-99999999");
|
||||
check("-9999999");
|
||||
check("-999999");
|
||||
check("-99999");
|
||||
check("-9999");
|
||||
check("-999");
|
||||
check("-99");
|
||||
check("-9");
|
||||
check( "0");
|
||||
check( "9");
|
||||
check( "99");
|
||||
check( "999");
|
||||
check( "9999");
|
||||
check( "99999");
|
||||
check( "999999");
|
||||
check( "9999999");
|
||||
check( "99999999");
|
||||
check( "999999999");
|
||||
check( "9999999999");
|
||||
check( "99999999999");
|
||||
check( "999999999999");
|
||||
check( "9999999999999");
|
||||
check( "99999999999999");
|
||||
check( "999999999999999");
|
||||
check( "9999999999999999");
|
||||
check( "99999999999999999");
|
||||
check( "999999999999999999");
|
||||
check( "9223372036854775807");
|
||||
check( "9223372036854775808");
|
||||
check( "9999999999999999999");
|
||||
check( "18446744073709551615");
|
||||
//check( "18446744073709551616");
|
||||
check( "99999999999999999999");
|
||||
check( "999999999999999999999");
|
||||
check( "1000000000000000000000");
|
||||
check( "9999999999999999999999");
|
||||
check( "99999999999999999999999");
|
||||
|
||||
//check("-0.9999999999999999999999");
|
||||
check("-0.9999999999999999");
|
||||
//check("-0.9007199254740991");
|
||||
//check("-0.999999999999999");
|
||||
//check("-0.99999999999999");
|
||||
//check("-0.9999999999999");
|
||||
//check("-0.999999999999");
|
||||
//check("-0.99999999999");
|
||||
//check("-0.9999999999");
|
||||
//check("-0.999999999");
|
||||
//check("-0.99999999");
|
||||
//check("-0.9999999");
|
||||
//check("-0.999999");
|
||||
//check("-0.99999");
|
||||
//check("-0.9999");
|
||||
//check("-0.8125");
|
||||
//check("-0.999");
|
||||
//check("-0.99");
|
||||
check("-1.0");
|
||||
check("-0.9");
|
||||
check("-0.0");
|
||||
check( "0.0");
|
||||
check( "0.9");
|
||||
//check( "0.99");
|
||||
//check( "0.999");
|
||||
//check( "0.8125");
|
||||
//check( "0.9999");
|
||||
//check( "0.99999");
|
||||
//check( "0.999999");
|
||||
//check( "0.9999999");
|
||||
//check( "0.99999999");
|
||||
//check( "0.999999999");
|
||||
//check( "0.9999999999");
|
||||
//check( "0.99999999999");
|
||||
//check( "0.999999999999");
|
||||
//check( "0.9999999999999");
|
||||
//check( "0.99999999999999");
|
||||
//check( "0.999999999999999");
|
||||
//check( "0.9007199254740991");
|
||||
check( "0.9999999999999999");
|
||||
//check( "0.9999999999999999999999");
|
||||
//check( "0.999999999999999999999999999");
|
||||
|
||||
check("-1e308");
|
||||
check("-1e-308");
|
||||
//check("-9999e300");
|
||||
//check("-999e100");
|
||||
//check("-99e10");
|
||||
check("-9e1");
|
||||
check( "9e1");
|
||||
//check( "99e10");
|
||||
//check( "999e100");
|
||||
//check( "9999e300");
|
||||
check( "999999999999999999.0");
|
||||
check( "999999999999999999999.0");
|
||||
check( "999999999999999999999e5");
|
||||
check( "999999999999999999999.0e5");
|
||||
|
||||
check("-1e-1");
|
||||
check("-1e0");
|
||||
check("-1e1");
|
||||
check( "0e0");
|
||||
check( "1e0");
|
||||
check( "1e10");
|
||||
}
|
||||
|
||||
void
|
||||
testScalar()
|
||||
{
|
||||
check("true");
|
||||
check("false");
|
||||
check("null");
|
||||
}
|
||||
|
||||
void
|
||||
testVectors()
|
||||
{
|
||||
#if 0
|
||||
check(
|
||||
R"xx({
|
||||
"glossary": {
|
||||
"title": "example glossary",
|
||||
"GlossDiv": {
|
||||
"title": "S",
|
||||
"GlossList": {
|
||||
"GlossEntry": {
|
||||
"ID": "SGML",
|
||||
"SortAs": "SGML",
|
||||
"GlossTerm": "Standard Generalized Markup Language",
|
||||
"Acronym": "SGML",
|
||||
"Abbrev": "ISO 8879:1986",
|
||||
"GlossDef": {
|
||||
"para": "A meta-markup language, used to create markup languages such as DocBook.",
|
||||
"GlossSeeAlso": ["GML", "XML"]
|
||||
},
|
||||
"GlossSee": "markup"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})xx");
|
||||
#endif
|
||||
|
||||
parse_vectors const pv;
|
||||
for(auto const e : pv)
|
||||
{
|
||||
if(e.result != 'y')
|
||||
continue;
|
||||
|
||||
round_trip(e.name, e.text);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
good(string_view s)
|
||||
{
|
||||
error_code ec;
|
||||
auto jv = parse(s, ec);
|
||||
return !ec;
|
||||
}
|
||||
|
||||
template<std::size_t N>
|
||||
void
|
||||
tv(char const (&s)[N])
|
||||
{
|
||||
round_trip(
|
||||
"",
|
||||
string_view(s, N - 1));
|
||||
}
|
||||
|
||||
void
|
||||
doTestStrings()
|
||||
{
|
||||
tv(R"("")");
|
||||
tv(R"("x")");
|
||||
tv(R"("xyz")");
|
||||
tv(R"("x z")");
|
||||
tv(R"("\"")");
|
||||
tv(R"("\\")");
|
||||
tv(R"("\/")");
|
||||
tv(R"("\b")");
|
||||
tv(R"("\f")");
|
||||
tv(R"("\n")");
|
||||
tv(R"("\r")");
|
||||
tv(R"("\t")");
|
||||
tv(R"("\u0000")");
|
||||
tv(R"("\u0001")");
|
||||
tv(R"("\u0002")");
|
||||
tv(R"("\u0003")");
|
||||
tv(R"("\u0004")");
|
||||
tv(R"("\u0005")");
|
||||
tv(R"("\u0006")");
|
||||
tv(R"("\u0007")");
|
||||
tv(R"("\u0008")");
|
||||
tv(R"("\u0009")");
|
||||
tv(R"("\u000a")");
|
||||
tv(R"("\u000b")");
|
||||
tv(R"("\u000c")");
|
||||
tv(R"("\u000d")");
|
||||
tv(R"("\u000e")");
|
||||
tv(R"("\u000f")");
|
||||
tv(R"("\u0010")");
|
||||
tv(R"("\u0011")");
|
||||
tv(R"("\u0012")");
|
||||
tv(R"("\u0013")");
|
||||
tv(R"("\u0014")");
|
||||
tv(R"("\u0015")");
|
||||
tv(R"("\u0016")");
|
||||
tv(R"("\u0017")");
|
||||
tv(R"("\u0018")");
|
||||
tv(R"("\u0019")");
|
||||
tv(R"("\u0020")");
|
||||
tv(R"("\u0020")");
|
||||
|
||||
tv(R"(0)");
|
||||
tv(R"(-0)");
|
||||
tv(R"(1)");
|
||||
tv(R"(-1)");
|
||||
tv(R"(99999)");
|
||||
tv(R"(-99999)");
|
||||
|
||||
tv(R"(true)");
|
||||
tv(R"(false)");
|
||||
|
||||
tv(R"(null)");
|
||||
}
|
||||
|
||||
void
|
||||
doTestVectors()
|
||||
{
|
||||
parse_vectors const pv;
|
||||
for(auto const e : pv)
|
||||
{
|
||||
if( e.result == 'y' ||
|
||||
good(e.text))
|
||||
{
|
||||
//log << i++ << " " << e.text << std::endl;
|
||||
round_trip(e.name, e.text);
|
||||
}
|
||||
// skip these failures for now
|
||||
if(
|
||||
e.name == "number" ||
|
||||
e.name == "number_real_exponent" ||
|
||||
e.name == "number_real_fraction_exponent" ||
|
||||
e.name == "number_simple_real" ||
|
||||
e.name == "object_extreme_numbers" ||
|
||||
e.name == "pass01"
|
||||
)
|
||||
continue;
|
||||
check(e.text, e.name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
run()
|
||||
{
|
||||
//testSerializer();
|
||||
doTestStrings();
|
||||
//doTestVectors();
|
||||
pass();
|
||||
testMembers();
|
||||
testObject();
|
||||
testArray();
|
||||
testString();
|
||||
testNumber();
|
||||
testScalar();
|
||||
testVectors();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -54,7 +54,8 @@ struct fail_storage
|
||||
return true;
|
||||
}
|
||||
|
||||
std::size_t fail_max = 1;
|
||||
std::size_t fail_max =
|
||||
std::size_t(-1);
|
||||
std::size_t fail = 0;
|
||||
std::size_t nalloc = 0;
|
||||
|
||||
|
@ -71,32 +71,6 @@ public:
|
||||
string().capacity());
|
||||
}
|
||||
|
||||
void
|
||||
testCustomTypes()
|
||||
{
|
||||
using namespace value_test_ns;
|
||||
|
||||
// to_json
|
||||
{
|
||||
T1 t;
|
||||
value jv(t);
|
||||
}
|
||||
{
|
||||
T2 t;
|
||||
value jv(t);
|
||||
}
|
||||
{
|
||||
T3 t;
|
||||
value jv(t);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_JSON_STATIC_ASSERT(
|
||||
detail::is_range<std::vector<int>>::value);
|
||||
|
||||
BOOST_JSON_STATIC_ASSERT(
|
||||
detail::is_range<std::initializer_list<int>>::value);
|
||||
|
||||
//------------------------------------------------------
|
||||
|
||||
void
|
||||
@ -1443,30 +1417,46 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
|
||||
void
|
||||
testCustomTypes()
|
||||
{
|
||||
using namespace value_test_ns;
|
||||
|
||||
// to_json
|
||||
{
|
||||
T1 t;
|
||||
value jv(t);
|
||||
}
|
||||
{
|
||||
T2 t;
|
||||
value jv(t);
|
||||
}
|
||||
{
|
||||
T3 t;
|
||||
value jv(t);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_JSON_STATIC_ASSERT(
|
||||
detail::is_range<std::vector<int>>::value);
|
||||
|
||||
BOOST_JSON_STATIC_ASSERT(
|
||||
detail::is_range<std::initializer_list<int>>::value);
|
||||
|
||||
//------------------------------------------------------
|
||||
|
||||
void
|
||||
run() override
|
||||
{
|
||||
log <<
|
||||
"sizeof(value) == " <<
|
||||
sizeof(value) << "\n";
|
||||
log <<
|
||||
"sizeof(object) == " <<
|
||||
sizeof(object) << "\n";
|
||||
log <<
|
||||
"sizeof(array) == " <<
|
||||
sizeof(array) << "\n";
|
||||
log <<
|
||||
"sizeof(string) == " <<
|
||||
sizeof(string) << "\n";
|
||||
|
||||
testCustomTypes();
|
||||
|
||||
testConstruction();
|
||||
testConversion();
|
||||
testModifiers();
|
||||
testExchange();
|
||||
testObservers();
|
||||
testAccessors();
|
||||
testCustomTypes();
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user