2
0
mirror of https://github.com/boostorg/json.git synced 2026-01-25 06:12:26 +00:00

Make string impl data private

This commit is contained in:
Vinnie Falco
2019-11-12 12:14:32 -08:00
parent 7e7236609b
commit 548d48ef22
3 changed files with 113 additions and 105 deletions

View File

@@ -26,12 +26,11 @@ impl(
InputIt last,
storage_ptr const& sp,
std::random_access_iterator_tag)
: impl(static_cast<size_type>(
last - first), sp)
: impl(last - first, sp)
{
std::copy(
first, last, data());
data()[size] = 0;
data()[size()] = 0;
}
template<class InputIt>
@@ -59,12 +58,12 @@ impl(
undo u{*this, sp, false};
auto dest = data();
size = 1;
size(1);
*dest++ = *first++;
while(first != last)
{
if(size < capacity)
++size;
if(size() < capacity())
size(size() + 1);
else
dest = append(1, sp);
*dest++ = *first++;
@@ -138,9 +137,9 @@ insert(
cleanup c{tmp, storage_ptr{}};
auto const off = pos - impl_.data();
traits_type::copy(
impl_.insert(off, tmp.size, sp_),
impl_.insert(off, tmp.size(), sp_),
tmp.data(),
tmp.size);
tmp.size());
return impl_.data() + off;
}
@@ -221,8 +220,8 @@ append(
std::input_iterator_tag{});
cleanup c{tmp, storage_ptr{}};
traits_type::copy(
impl_.append(tmp.size, sp_),
tmp.data(), tmp.size);
impl_.append(tmp.size(), sp_),
tmp.data(), tmp.size());
}
} // json

View File

@@ -26,32 +26,32 @@ namespace json {
string::
impl::
impl(
size_type size_,
std::size_t size,
storage_ptr const& sp)
{
if(size_ < sizeof(buf))
{
// SBO
capacity = sizeof(buf) - 1;
capacity_ = sizeof(buf) - 1;
}
else
{
capacity = growth(size_,
capacity_ = growth(size,
sizeof(buf) - 1);
p = static_cast<char*>(
sp->allocate(capacity + 1, 1));
sp->allocate(capacity_ + 1, 1));
}
size = static_cast<
impl_size_type>(size_);
size_ = static_cast<
std::uint32_t>(size);
}
auto
string::
impl::
growth(
size_type new_size,
impl_size_type capacity) ->
impl_size_type
std::size_t new_size,
std::size_t capacity) ->
std::uint32_t
{
if(new_size > max_size())
BOOST_JSON_THROW(
@@ -59,15 +59,14 @@ growth(
new_size |= mask_;
if( new_size > max_size())
return static_cast<
impl_size_type>(max_size());
std::uint32_t>(max_size());
// growth factor 2
if( capacity >
max_size() - capacity)
return static_cast<
impl_size_type>(max_size()); // overflow
return (std::max<impl_size_type>)(
capacity * 2, static_cast<
impl_size_type>(new_size));
std::uint32_t>(max_size()); // overflow
return static_cast<std::uint32_t>(
(std::max)(capacity * 2, new_size));
}
void
@@ -78,7 +77,7 @@ destroy(
{
if(! in_sbo())
sp->deallocate(
p, capacity + 1, 1);
p, capacity() + 1, 1);
}
char*
@@ -88,11 +87,11 @@ assign(
size_type new_size,
storage_ptr const& sp)
{
if(new_size > capacity)
if(new_size > capacity())
{
impl tmp(growth(
new_size,
capacity), sp);
capacity()), sp);
destroy(sp);
*this = tmp;
}
@@ -107,19 +106,19 @@ append(
size_type n,
storage_ptr const& sp)
{
if(n > max_size() - size)
if(n > max_size() - size())
BOOST_JSON_THROW(
detail::string_too_large_exception());
if(n <= capacity - size)
if(n <= capacity() - size())
{
term(size + n);
term(size() + n);
return end() - n;
}
impl tmp(growth(
size + n, capacity), sp);
size() + n, capacity()), sp);
traits_type::copy(
tmp.data(), data(), size);
tmp.term(size + n);
tmp.data(), data(), size());
tmp.term(size() + n);
destroy(sp);
*this = tmp;
return end() - n;
@@ -133,28 +132,26 @@ insert(
size_type n,
storage_ptr const& sp)
{
if(pos > size)
if(pos > size())
BOOST_JSON_THROW(
detail::string_pos_too_large());
if(n <= capacity - size)
if(n <= capacity() - size())
{
auto const dest =
data() + pos;
traits_type::move(
dest + n,
dest,
size + 1 - pos);
size += static_cast<
impl_size_type>(n);
size() + 1 - pos);
size(size() + n);
return dest;
}
if(n > max_size() - size)
if(n > max_size() - size())
BOOST_JSON_THROW(
detail::string_too_large_exception());
impl tmp(growth(
size + n, capacity), sp);
tmp.size = size + static_cast<
impl_size_type>(n);
size() + n, capacity()), sp);
tmp.size(size() + n);
traits_type::copy(
tmp.data(),
data(),
@@ -162,7 +159,7 @@ insert(
traits_type::copy(
tmp.data() + pos + n,
data() + pos,
size + 1 - pos);
size() + 1 - pos);
destroy(sp);
*this = tmp;
return data() + pos;
@@ -173,14 +170,14 @@ string::
impl::
unalloc(storage_ptr const& sp) noexcept
{
BOOST_JSON_ASSERT(size < sizeof(buf));
BOOST_JSON_ASSERT(size() < sizeof(buf));
BOOST_JSON_ASSERT(! in_sbo());
auto const p_ = p;
traits_type::copy(
buf, data(), size + 1);
buf, data(), size() + 1);
sp->deallocate(
p_, capacity + 1, 1);
capacity = sizeof(buf) - 1;
p_, capacity() + 1, 1);
capacity_ = sizeof(buf) - 1;
}
//----------------------------------------------------------
@@ -254,22 +251,22 @@ shrink_to_fit()
{
if(impl_.in_sbo())
return;
if(impl_.size < sizeof(impl_.buf))
if(impl_.size() < sizeof(impl_.buf))
{
impl_.unalloc(sp_);
return;
}
auto const new_cap =
(std::min<size_type>)(
impl_.size | mask_,
impl_.size() | mask_,
max_size());
if(new_cap >= impl_.capacity)
if(new_cap >= impl_.capacity())
return;
impl tmp(new_cap, sp_);
traits_type::copy(tmp.data(),
impl_.data(), impl_.size + 1);
tmp.size = impl_.size;
impl_.data(), impl_.size() + 1);
tmp.size(impl_.size());
impl_.destroy(sp_);
impl_ = tmp;
}
@@ -300,7 +297,8 @@ void
string::
pop_back()
{
impl_.data()[--impl_.size] = 0;
back() = 0;
impl_.size(impl_.size() - 1);
}
//----------------------------------------------------------
@@ -349,10 +347,10 @@ insert(
char const* s,
size_type count)
{
if(pos > impl_.size)
if(pos > impl_.size())
BOOST_JSON_THROW(
detail::string_pos_too_large());
if(count > impl_.capacity - impl_.size)
if(count > impl_.capacity() - impl_.size())
{
traits_type::copy(
impl_.insert(pos, count, sp_),
@@ -363,12 +361,11 @@ insert(
traits_type::move(
impl_.data() + pos + count,
impl_.data() + pos,
impl_.size - pos + 1);
impl_.size() - pos + 1);
traits_type::copy(
impl_.data() + pos,
s, count);
impl_.size += static_cast<
impl_size_type>(count);
impl_.size(impl_.size() + count);
return *this;
}
@@ -406,18 +403,16 @@ erase(
size_type pos,
size_type count)
{
if(pos > impl_.size)
if(pos > impl_.size())
BOOST_JSON_THROW(
detail::string_pos_too_large());
if( count > impl_.size - pos)
count = impl_.size - pos;
if( count > impl_.size() - pos)
count = impl_.size() - pos;
traits_type::move(
impl_.data() + pos,
impl_.data() + pos + count,
impl_.size - pos - count + 1);
impl_.size -= static_cast<
impl_size_type>(count);
impl_.data()[impl_.size] = 0;
impl_.size() - pos - count + 1);
impl_.term(impl_.size() - count);
return *this;
}
@@ -448,22 +443,18 @@ void
string::
resize(size_type count, char ch)
{
if(count <= impl_.size)
if(count <= impl_.size())
{
auto const n = static_cast<
impl_size_type>(count);
impl_.data()[n] = 0;
impl_.size = n;
impl_.term(count);
return;
}
reserve(count);
traits_type::assign(
impl_.end(),
count + 1 - impl_.size,
count - impl_.size(),
ch);
impl_.size = static_cast<
impl_size_type>(count);
grow(count - size());
}
//----------------------------------------------------------
@@ -495,16 +486,16 @@ string::
reserve_impl(size_type new_cap)
{
BOOST_JSON_ASSERT(
new_cap >= impl_.capacity);
if(new_cap > impl_.capacity)
new_cap >= impl_.capacity());
if(new_cap > impl_.capacity())
{
// grow
new_cap = impl::growth(
new_cap, impl_.capacity);
new_cap, impl_.capacity());
impl tmp(new_cap, sp_);
traits_type::copy(tmp.data(),
impl_.data(), impl_.size + 1);
tmp.size = impl_.size;
impl_.data(), impl_.size() + 1);
tmp.size(impl_.size());
impl_.destroy(sp_);
impl_ = tmp;
return;

View File

@@ -97,15 +97,12 @@ private:
std::iterator_traits<T>::value_type,
char>::value>::type;
using impl_size_type = unsigned long;
static constexpr
impl_size_type mask_ = 0x0f;
static constexpr std::size_t mask_ = 0x0f;
struct impl
{
impl_size_type size;
impl_size_type capacity;
std::uint32_t size_;
std::uint32_t capacity_;
#ifndef GENERATING_DOCUMENTATION
// XSL has problems with anonymous unions
@@ -117,8 +114,8 @@ private:
#endif
impl() noexcept
: size(0)
, capacity(sizeof(buf) - 1)
: size_(0)
, capacity_(sizeof(buf) - 1)
{
buf[0] = 0;
}
@@ -137,6 +134,28 @@ private:
storage_ptr const& sp,
std::input_iterator_tag);
inline
std::size_t
size() const noexcept
{
return size_;
}
inline
std::size_t
capacity() const noexcept
{
return capacity_;
}
inline
void
size(std::size_t n)
{
size_ = static_cast<
std::uint32_t>(n);
}
BOOST_JSON_DECL
impl(
size_type new_size,
@@ -144,10 +163,10 @@ private:
BOOST_JSON_DECL
static
impl_size_type
std::uint32_t
growth(
size_type new_size,
impl_size_type capacity);
std::size_t new_size,
std::size_t capacity);
BOOST_JSON_DECL
void
@@ -180,15 +199,14 @@ private:
bool
in_sbo() const noexcept
{
return capacity < sizeof(buf);
return capacity_ < sizeof(buf);
}
void
term(size_type n) noexcept
term(std::size_t n) noexcept
{
size = static_cast<
impl_size_type>(n);
data()[size] = 0;
size(n);
data()[size_] = 0;
}
char*
@@ -210,13 +228,13 @@ private:
char*
end() noexcept
{
return data() + size;
return data() + size_;
}
char const*
end() const noexcept
{
return data() + size;
return data() + size_;
}
bool
@@ -244,7 +262,7 @@ public:
{
if(! impl_.in_sbo())
sp_->deallocate(impl_.p,
impl_.capacity + 1, 1);
impl_.capacity() + 1, 1);
}
//
@@ -1346,7 +1364,7 @@ public:
char&
back()
{
return impl_.data()[impl_.size - 1];
return impl_.data()[impl_.size() - 1];
}
/** Access the last character
@@ -1364,7 +1382,7 @@ public:
char const&
back() const
{
return impl_.data()[impl_.size - 1];
return impl_.data()[impl_.size() - 1];
}
/** Access the underlying character array directly
@@ -1659,7 +1677,7 @@ public:
bool
empty() const noexcept
{
return impl_.size == 0;
return impl_.size() == 0;
}
/** Return the number of characters in the string.
@@ -1674,7 +1692,7 @@ public:
size_type
size() const noexcept
{
return impl_.size;
return impl_.size();
}
/** Return the maximum number of characters the string can hold
@@ -1711,7 +1729,7 @@ public:
size_type
capacity() const noexcept
{
return impl_.capacity;
return impl_.capacity();
}
/** Increase the capacity to at least a certain amount
@@ -1746,7 +1764,7 @@ public:
void
reserve(size_type new_capacity)
{
if(new_capacity <= impl_.capacity)
if(new_capacity <= capacity())
return;
reserve_impl(new_capacity);
}
@@ -2344,8 +2362,8 @@ public:
grow(size_type n) noexcept
{
BOOST_JSON_ASSERT(
n <= impl_.capacity - impl_.size);
impl_.term(impl_.size + n);
n <= impl_.capacity() - impl_.size());
impl_.term(impl_.size() + n);
}
//------------------------------------------------------