mirror of
https://github.com/vdemydiuk/mtapi.git
synced 2026-08-09 08:57:52 +00:00
Added thirdparty: boost library
This commit is contained in:
+43
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.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/boostorg/json
|
||||
//
|
||||
|
||||
#ifndef BOOST_JSON_DETAIL_IMPL_ARRAY_HPP
|
||||
#define BOOST_JSON_DETAIL_IMPL_ARRAY_HPP
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
namespace detail {
|
||||
|
||||
unchecked_array::
|
||||
~unchecked_array()
|
||||
{
|
||||
if(! data_ ||
|
||||
sp_.is_not_shared_and_deallocate_is_trivial())
|
||||
return;
|
||||
for(unsigned long i = 0;
|
||||
i < size_; ++i)
|
||||
data_[i].~value();
|
||||
}
|
||||
|
||||
void
|
||||
unchecked_array::
|
||||
relocate(value* dest) noexcept
|
||||
{
|
||||
if(size_ > 0)
|
||||
std::memcpy(
|
||||
static_cast<void*>(dest),
|
||||
data_, size_ * sizeof(value));
|
||||
data_ = nullptr;
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // namespace json
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
//
|
||||
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.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/boostorg/json
|
||||
//
|
||||
|
||||
#ifndef BOOST_JSON_DETAIL_IMPL_DEFAULT_RESOURCE_IPP
|
||||
#define BOOST_JSON_DETAIL_IMPL_DEFAULT_RESOURCE_IPP
|
||||
|
||||
#include <boost/json/detail/default_resource.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
namespace detail {
|
||||
|
||||
#ifndef BOOST_JSON_WEAK_CONSTINIT
|
||||
# ifndef BOOST_JSON_NO_DESTROY
|
||||
BOOST_JSON_REQUIRE_CONST_INIT
|
||||
default_resource::holder
|
||||
default_resource::instance_;
|
||||
# else
|
||||
BOOST_JSON_REQUIRE_CONST_INIT
|
||||
default_resource
|
||||
default_resource::instance_;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// this is here so that ~memory_resource
|
||||
// is emitted in the library instead of
|
||||
// the user's TU.
|
||||
default_resource::
|
||||
~default_resource() = default;
|
||||
|
||||
void*
|
||||
default_resource::
|
||||
do_allocate(
|
||||
std::size_t n,
|
||||
std::size_t)
|
||||
{
|
||||
return ::operator new(n);
|
||||
}
|
||||
|
||||
void
|
||||
default_resource::
|
||||
do_deallocate(
|
||||
void* p,
|
||||
std::size_t,
|
||||
std::size_t)
|
||||
{
|
||||
::operator delete(p);
|
||||
}
|
||||
|
||||
bool
|
||||
default_resource::
|
||||
do_is_equal(
|
||||
memory_resource const& mr) const noexcept
|
||||
{
|
||||
return this == &mr;
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // namespace json
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.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/boostorg/json
|
||||
//
|
||||
|
||||
#ifndef BOOST_JSON_DETAIL_IMPL_EXCEPT_IPP
|
||||
#define BOOST_JSON_DETAIL_IMPL_EXCEPT_IPP
|
||||
|
||||
#include <boost/json/detail/except.hpp>
|
||||
#include <boost/version.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
|
||||
namespace detail {
|
||||
|
||||
void
|
||||
throw_system_error(
|
||||
error_code const& ec,
|
||||
source_location const& loc)
|
||||
{
|
||||
throw_exception(
|
||||
system_error(ec),
|
||||
loc);
|
||||
}
|
||||
|
||||
void
|
||||
throw_system_error(
|
||||
error e,
|
||||
source_location const* loc)
|
||||
{
|
||||
error_code ec;
|
||||
ec.assign(e, loc);
|
||||
|
||||
throw_exception(
|
||||
system_error(ec),
|
||||
*loc);
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // namespace json
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
//
|
||||
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
|
||||
// Copyright (c) 2020 Peter Dimov (pdimov 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/boostorg/json
|
||||
//
|
||||
|
||||
#ifndef BOOST_JSON_DETAIL_IMPL_FORMAT_IPP
|
||||
#define BOOST_JSON_DETAIL_IMPL_FORMAT_IPP
|
||||
|
||||
#include <boost/json/detail/ryu/ryu.hpp>
|
||||
#include <cstring>
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
namespace detail {
|
||||
|
||||
/* Reference work:
|
||||
|
||||
https://www.ampl.com/netlib/fp/dtoa.c
|
||||
https://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/
|
||||
https://kkimdev.github.io/posts/2018/06/15/IEEE-754-Floating-Point-Type-in-C++.html
|
||||
*/
|
||||
|
||||
inline char const* digits_lut() noexcept
|
||||
{
|
||||
return
|
||||
"00010203040506070809"
|
||||
"10111213141516171819"
|
||||
"20212223242526272829"
|
||||
"30313233343536373839"
|
||||
"40414243444546474849"
|
||||
"50515253545556575859"
|
||||
"60616263646566676869"
|
||||
"70717273747576777879"
|
||||
"80818283848586878889"
|
||||
"90919293949596979899";
|
||||
}
|
||||
|
||||
inline void format_four_digits( char * dest, unsigned v )
|
||||
{
|
||||
std::memcpy( dest + 2, digits_lut() + (v % 100) * 2, 2 );
|
||||
std::memcpy( dest , digits_lut() + (v / 100) * 2, 2 );
|
||||
}
|
||||
|
||||
inline void format_two_digits( char * dest, unsigned v )
|
||||
{
|
||||
std::memcpy( dest, digits_lut() + v * 2, 2 );
|
||||
}
|
||||
|
||||
inline void format_digit( char * dest, unsigned v )
|
||||
{
|
||||
*dest = static_cast<char>( v + '0' );
|
||||
}
|
||||
|
||||
unsigned
|
||||
format_uint64(
|
||||
char* dest,
|
||||
std::uint64_t v) noexcept
|
||||
{
|
||||
if(v < 10)
|
||||
{
|
||||
*dest = static_cast<char>( '0' + v );
|
||||
return 1;
|
||||
}
|
||||
|
||||
char buffer[ 24 ];
|
||||
|
||||
char * p = buffer + 24;
|
||||
|
||||
while( v >= 1000 )
|
||||
{
|
||||
p -= 4;
|
||||
format_four_digits( p, v % 10000 );
|
||||
v /= 10000;
|
||||
}
|
||||
|
||||
if( v >= 10 )
|
||||
{
|
||||
p -= 2;
|
||||
format_two_digits( p, v % 100 );
|
||||
v /= 100;
|
||||
}
|
||||
|
||||
if( v )
|
||||
{
|
||||
p -= 1;
|
||||
format_digit( p, static_cast<unsigned>(v) );
|
||||
}
|
||||
|
||||
unsigned const n = static_cast<unsigned>( buffer + 24 - p );
|
||||
std::memcpy( dest, p, n );
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
unsigned
|
||||
format_int64(
|
||||
char* dest, int64_t i) noexcept
|
||||
{
|
||||
std::uint64_t ui = static_cast<
|
||||
std::uint64_t>(i);
|
||||
if(i >= 0)
|
||||
return format_uint64(dest, ui);
|
||||
*dest++ = '-';
|
||||
ui = ~ui + 1;
|
||||
return 1 + format_uint64(dest, ui);
|
||||
}
|
||||
|
||||
unsigned
|
||||
format_double(
|
||||
char* dest, double d, bool allow_infinity_and_nan) noexcept
|
||||
{
|
||||
return static_cast<int>(
|
||||
ryu::d2s_buffered_n(d, dest, allow_infinity_and_nan));
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // namespace json
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
+204
@@ -0,0 +1,204 @@
|
||||
//
|
||||
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.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/boostorg/json
|
||||
//
|
||||
|
||||
#ifndef BOOST_JSON_DETAIL_IMPL_HANDLER_HPP
|
||||
#define BOOST_JSON_DETAIL_IMPL_HANDLER_HPP
|
||||
|
||||
#include <boost/json/detail/handler.hpp>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
namespace detail {
|
||||
|
||||
template<class... Args>
|
||||
handler::
|
||||
handler(Args&&... args)
|
||||
: st(std::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
handler::
|
||||
on_document_begin(
|
||||
error_code&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
handler::
|
||||
on_document_end(
|
||||
error_code&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
handler::
|
||||
on_object_begin(
|
||||
error_code&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
handler::
|
||||
on_object_end(
|
||||
std::size_t n,
|
||||
error_code&)
|
||||
{
|
||||
st.push_object(n);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
handler::
|
||||
on_array_begin(
|
||||
error_code&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
handler::
|
||||
on_array_end(
|
||||
std::size_t n,
|
||||
error_code&)
|
||||
{
|
||||
st.push_array(n);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
handler::
|
||||
on_key_part(
|
||||
string_view s,
|
||||
std::size_t,
|
||||
error_code&)
|
||||
{
|
||||
st.push_chars(s);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
handler::
|
||||
on_key(
|
||||
string_view s,
|
||||
std::size_t,
|
||||
error_code&)
|
||||
{
|
||||
st.push_key(s);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
handler::
|
||||
on_string_part(
|
||||
string_view s,
|
||||
std::size_t,
|
||||
error_code&)
|
||||
{
|
||||
st.push_chars(s);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
handler::
|
||||
on_string(
|
||||
string_view s,
|
||||
std::size_t,
|
||||
error_code&)
|
||||
{
|
||||
st.push_string(s);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
handler::
|
||||
on_number_part(
|
||||
string_view,
|
||||
error_code&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
handler::
|
||||
on_int64(
|
||||
std::int64_t i,
|
||||
string_view,
|
||||
error_code&)
|
||||
{
|
||||
st.push_int64(i);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
handler::
|
||||
on_uint64(
|
||||
std::uint64_t u,
|
||||
string_view,
|
||||
error_code&)
|
||||
{
|
||||
st.push_uint64(u);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
handler::
|
||||
on_double(
|
||||
double d,
|
||||
string_view,
|
||||
error_code&)
|
||||
{
|
||||
st.push_double(d);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
handler::
|
||||
on_bool(
|
||||
bool b,
|
||||
error_code&)
|
||||
{
|
||||
st.push_bool(b);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
handler::
|
||||
on_null(error_code&)
|
||||
{
|
||||
st.push_null();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
handler::
|
||||
on_comment_part(
|
||||
string_view,
|
||||
error_code&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
handler::
|
||||
on_comment(
|
||||
string_view, error_code&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // namespace json
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.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/boostorg/json
|
||||
//
|
||||
|
||||
#ifndef BOOST_JSON_DETAIL_IMPL_SHARED_RESOURCE_IPP
|
||||
#define BOOST_JSON_DETAIL_IMPL_SHARED_RESOURCE_IPP
|
||||
|
||||
#include <boost/json/detail/shared_resource.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
namespace detail {
|
||||
|
||||
// these are here so that ~memory_resource
|
||||
// is emitted in the library instead of
|
||||
// the user's TU.
|
||||
|
||||
shared_resource::
|
||||
shared_resource()
|
||||
{
|
||||
}
|
||||
|
||||
shared_resource::
|
||||
~shared_resource()
|
||||
{
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // namespace json
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.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/boostorg/json
|
||||
//
|
||||
|
||||
#ifndef BOOST_JSON_DETAIL_IMPL_STACK_IPP
|
||||
#define BOOST_JSON_DETAIL_IMPL_STACK_IPP
|
||||
|
||||
#include <boost/json/detail/stack.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
namespace detail {
|
||||
|
||||
stack::
|
||||
~stack()
|
||||
{
|
||||
if(base_ != buf_)
|
||||
sp_->deallocate(
|
||||
base_, cap_);
|
||||
}
|
||||
|
||||
stack::
|
||||
stack(
|
||||
storage_ptr sp,
|
||||
unsigned char* buf,
|
||||
std::size_t buf_size) noexcept
|
||||
: sp_(std::move(sp))
|
||||
, cap_(buf_size)
|
||||
, base_(buf)
|
||||
, buf_(buf)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
stack::
|
||||
reserve(std::size_t n)
|
||||
{
|
||||
if(cap_ >= n)
|
||||
return;
|
||||
auto const base = static_cast<
|
||||
unsigned char*>(sp_->allocate(n));
|
||||
if(base_)
|
||||
{
|
||||
if(size_ > 0)
|
||||
std::memcpy(base, base_, size_);
|
||||
if(base_ != buf_)
|
||||
sp_->deallocate(base_, cap_);
|
||||
}
|
||||
base_ = base;
|
||||
cap_ = n;
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // namespace json
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
+487
@@ -0,0 +1,487 @@
|
||||
//
|
||||
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
|
||||
// Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.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/boostorg/json
|
||||
//
|
||||
|
||||
#ifndef BOOST_JSON_DETAIL_IMPL_STRING_IMPL_IPP
|
||||
#define BOOST_JSON_DETAIL_IMPL_STRING_IMPL_IPP
|
||||
|
||||
#include <boost/json/detail/string_impl.hpp>
|
||||
#include <boost/json/detail/except.hpp>
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
namespace detail {
|
||||
|
||||
inline
|
||||
bool
|
||||
ptr_in_range(
|
||||
const char* first,
|
||||
const char* last,
|
||||
const char* ptr) noexcept
|
||||
{
|
||||
return std::less<const char*>()(ptr, last) &&
|
||||
std::greater_equal<const char*>()(ptr, first);
|
||||
}
|
||||
|
||||
string_impl::
|
||||
string_impl() noexcept
|
||||
{
|
||||
s_.k = short_string_;
|
||||
s_.buf[sbo_chars_] =
|
||||
static_cast<char>(
|
||||
sbo_chars_);
|
||||
s_.buf[0] = 0;
|
||||
}
|
||||
|
||||
string_impl::
|
||||
string_impl(
|
||||
std::size_t size,
|
||||
storage_ptr const& sp)
|
||||
{
|
||||
if(size <= sbo_chars_)
|
||||
{
|
||||
s_.k = short_string_;
|
||||
s_.buf[sbo_chars_] =
|
||||
static_cast<char>(
|
||||
sbo_chars_ - size);
|
||||
s_.buf[size] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_.k = kind::string;
|
||||
auto const n = growth(
|
||||
size, sbo_chars_ + 1);
|
||||
p_.t = ::new(sp->allocate(
|
||||
sizeof(table) +
|
||||
n + 1,
|
||||
alignof(table))) table{
|
||||
static_cast<
|
||||
std::uint32_t>(size),
|
||||
static_cast<
|
||||
std::uint32_t>(n)};
|
||||
data()[n] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// construct a key, unchecked
|
||||
string_impl::
|
||||
string_impl(
|
||||
key_t,
|
||||
string_view s,
|
||||
storage_ptr const& sp)
|
||||
{
|
||||
BOOST_ASSERT(
|
||||
s.size() <= max_size());
|
||||
k_.k = key_string_;
|
||||
k_.n = static_cast<
|
||||
std::uint32_t>(s.size());
|
||||
k_.s = reinterpret_cast<char*>(
|
||||
sp->allocate(s.size() + 1,
|
||||
alignof(char)));
|
||||
k_.s[s.size()] = 0; // null term
|
||||
std::memcpy(&k_.s[0],
|
||||
s.data(), s.size());
|
||||
}
|
||||
|
||||
// construct a key, unchecked
|
||||
string_impl::
|
||||
string_impl(
|
||||
key_t,
|
||||
string_view s1,
|
||||
string_view s2,
|
||||
storage_ptr const& sp)
|
||||
{
|
||||
auto len = s1.size() + s2.size();
|
||||
BOOST_ASSERT(len <= max_size());
|
||||
k_.k = key_string_;
|
||||
k_.n = static_cast<
|
||||
std::uint32_t>(len);
|
||||
k_.s = reinterpret_cast<char*>(
|
||||
sp->allocate(len + 1,
|
||||
alignof(char)));
|
||||
k_.s[len] = 0; // null term
|
||||
std::memcpy(&k_.s[0],
|
||||
s1.data(), s1.size());
|
||||
std::memcpy(&k_.s[s1.size()],
|
||||
s2.data(), s2.size());
|
||||
}
|
||||
|
||||
std::uint32_t
|
||||
string_impl::
|
||||
growth(
|
||||
std::size_t new_size,
|
||||
std::size_t capacity)
|
||||
{
|
||||
if(new_size > max_size())
|
||||
{
|
||||
BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
|
||||
detail::throw_system_error( error::string_too_large, &loc );
|
||||
}
|
||||
// growth factor 2
|
||||
if( capacity >
|
||||
max_size() - capacity)
|
||||
return static_cast<
|
||||
std::uint32_t>(max_size()); // overflow
|
||||
return static_cast<std::uint32_t>(
|
||||
(std::max)(capacity * 2, new_size));
|
||||
}
|
||||
|
||||
char*
|
||||
string_impl::
|
||||
assign(
|
||||
std::size_t new_size,
|
||||
storage_ptr const& sp)
|
||||
{
|
||||
if(new_size > capacity())
|
||||
{
|
||||
string_impl tmp(growth(
|
||||
new_size,
|
||||
capacity()), sp);
|
||||
destroy(sp);
|
||||
*this = tmp;
|
||||
}
|
||||
term(new_size);
|
||||
return data();
|
||||
}
|
||||
|
||||
char*
|
||||
string_impl::
|
||||
append(
|
||||
std::size_t n,
|
||||
storage_ptr const& sp)
|
||||
{
|
||||
if(n > max_size() - size())
|
||||
{
|
||||
BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
|
||||
detail::throw_system_error( error::string_too_large, &loc );
|
||||
}
|
||||
if(n <= capacity() - size())
|
||||
{
|
||||
term(size() + n);
|
||||
return end() - n;
|
||||
}
|
||||
string_impl tmp(growth(
|
||||
size() + n, capacity()), sp);
|
||||
std::memcpy(
|
||||
tmp.data(), data(), size());
|
||||
tmp.term(size() + n);
|
||||
destroy(sp);
|
||||
*this = tmp;
|
||||
return end() - n;
|
||||
}
|
||||
|
||||
void
|
||||
string_impl::
|
||||
insert(
|
||||
std::size_t pos,
|
||||
const char* s,
|
||||
std::size_t n,
|
||||
storage_ptr const& sp)
|
||||
{
|
||||
const auto curr_size = size();
|
||||
if(pos > curr_size)
|
||||
{
|
||||
BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
|
||||
detail::throw_system_error( error::out_of_range, &loc );
|
||||
}
|
||||
const auto curr_data = data();
|
||||
if(n <= capacity() - curr_size)
|
||||
{
|
||||
const bool inside = detail::ptr_in_range(curr_data, curr_data + curr_size, s);
|
||||
if (!inside || (inside && ((s - curr_data) + n <= pos)))
|
||||
{
|
||||
std::memmove(&curr_data[pos + n], &curr_data[pos], curr_size - pos + 1);
|
||||
std::memcpy(&curr_data[pos], s, n);
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::size_t offset = s - curr_data;
|
||||
std::memmove(&curr_data[pos + n], &curr_data[pos], curr_size - pos + 1);
|
||||
if (offset < pos)
|
||||
{
|
||||
const std::size_t diff = pos - offset;
|
||||
std::memcpy(&curr_data[pos], &curr_data[offset], diff);
|
||||
std::memcpy(&curr_data[pos + diff], &curr_data[pos + n], n - diff);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::memcpy(&curr_data[pos], &curr_data[offset + n], n);
|
||||
}
|
||||
}
|
||||
size(curr_size + n);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(n > max_size() - curr_size)
|
||||
{
|
||||
BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
|
||||
detail::throw_system_error( error::string_too_large, &loc );
|
||||
}
|
||||
string_impl tmp(growth(
|
||||
curr_size + n, capacity()), sp);
|
||||
tmp.size(curr_size + n);
|
||||
std::memcpy(
|
||||
tmp.data(),
|
||||
curr_data,
|
||||
pos);
|
||||
std::memcpy(
|
||||
tmp.data() + pos + n,
|
||||
curr_data + pos,
|
||||
curr_size + 1 - pos);
|
||||
std::memcpy(
|
||||
tmp.data() + pos,
|
||||
s,
|
||||
n);
|
||||
destroy(sp);
|
||||
*this = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
char*
|
||||
string_impl::
|
||||
insert_unchecked(
|
||||
std::size_t pos,
|
||||
std::size_t n,
|
||||
storage_ptr const& sp)
|
||||
{
|
||||
const auto curr_size = size();
|
||||
if(pos > curr_size)
|
||||
{
|
||||
BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
|
||||
detail::throw_system_error( error::out_of_range, &loc );
|
||||
}
|
||||
const auto curr_data = data();
|
||||
if(n <= capacity() - size())
|
||||
{
|
||||
auto const dest =
|
||||
curr_data + pos;
|
||||
std::memmove(
|
||||
dest + n,
|
||||
dest,
|
||||
curr_size + 1 - pos);
|
||||
size(curr_size + n);
|
||||
return dest;
|
||||
}
|
||||
if(n > max_size() - curr_size)
|
||||
{
|
||||
BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
|
||||
detail::throw_system_error( error::string_too_large, &loc );
|
||||
}
|
||||
string_impl tmp(growth(
|
||||
curr_size + n, capacity()), sp);
|
||||
tmp.size(curr_size + n);
|
||||
std::memcpy(
|
||||
tmp.data(),
|
||||
curr_data,
|
||||
pos);
|
||||
std::memcpy(
|
||||
tmp.data() + pos + n,
|
||||
curr_data + pos,
|
||||
curr_size + 1 - pos);
|
||||
destroy(sp);
|
||||
*this = tmp;
|
||||
return data() + pos;
|
||||
}
|
||||
|
||||
void
|
||||
string_impl::
|
||||
replace(
|
||||
std::size_t pos,
|
||||
std::size_t n1,
|
||||
const char* s,
|
||||
std::size_t n2,
|
||||
storage_ptr const& sp)
|
||||
{
|
||||
const auto curr_size = size();
|
||||
if (pos > curr_size)
|
||||
{
|
||||
BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
|
||||
detail::throw_system_error( error::out_of_range, &loc );
|
||||
}
|
||||
const auto curr_data = data();
|
||||
n1 = (std::min)(n1, curr_size - pos);
|
||||
const auto delta = (std::max)(n1, n2) -
|
||||
(std::min)(n1, n2);
|
||||
// if we are shrinking in size or we have enough
|
||||
// capacity, dont reallocate
|
||||
if (n1 > n2 || delta <= capacity() - curr_size)
|
||||
{
|
||||
const bool inside = detail::ptr_in_range(curr_data, curr_data + curr_size, s);
|
||||
// there is nothing to replace; return
|
||||
if (inside && s == curr_data + pos && n1 == n2)
|
||||
return;
|
||||
if (!inside || (inside && ((s - curr_data) + n2 <= pos)))
|
||||
{
|
||||
// source outside
|
||||
std::memmove(&curr_data[pos + n2], &curr_data[pos + n1], curr_size - pos - n1 + 1);
|
||||
std::memcpy(&curr_data[pos], s, n2);
|
||||
}
|
||||
else
|
||||
{
|
||||
// source inside
|
||||
const std::size_t offset = s - curr_data;
|
||||
if (n2 >= n1)
|
||||
{
|
||||
// grow/unchanged
|
||||
const std::size_t diff = offset <= pos + n1 ? (std::min)((pos + n1) - offset, n2) : 0;
|
||||
// shift all right of splice point by n2 - n1 to the right
|
||||
std::memmove(&curr_data[pos + n2], &curr_data[pos + n1], curr_size - pos - n1 + 1);
|
||||
// copy all before splice point
|
||||
std::memmove(&curr_data[pos], &curr_data[offset], diff);
|
||||
// copy all after splice point
|
||||
std::memmove(&curr_data[pos + diff], &curr_data[(offset - n1) + n2 + diff], n2 - diff);
|
||||
}
|
||||
else
|
||||
{
|
||||
// shrink
|
||||
// copy all elements into place
|
||||
std::memmove(&curr_data[pos], &curr_data[offset], n2);
|
||||
// shift all elements after splice point left
|
||||
std::memmove(&curr_data[pos + n2], &curr_data[pos + n1], curr_size - pos - n1 + 1);
|
||||
}
|
||||
}
|
||||
size((curr_size - n1) + n2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (delta > max_size() - curr_size)
|
||||
{
|
||||
BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
|
||||
detail::throw_system_error( error::string_too_large, &loc );
|
||||
}
|
||||
// would exceed capacity, reallocate
|
||||
string_impl tmp(growth(
|
||||
curr_size + delta, capacity()), sp);
|
||||
tmp.size(curr_size + delta);
|
||||
std::memcpy(
|
||||
tmp.data(),
|
||||
curr_data,
|
||||
pos);
|
||||
std::memcpy(
|
||||
tmp.data() + pos + n2,
|
||||
curr_data + pos + n1,
|
||||
curr_size - pos - n1 + 1);
|
||||
std::memcpy(
|
||||
tmp.data() + pos,
|
||||
s,
|
||||
n2);
|
||||
destroy(sp);
|
||||
*this = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
// unlike the replace overload, this function does
|
||||
// not move any characters
|
||||
char*
|
||||
string_impl::
|
||||
replace_unchecked(
|
||||
std::size_t pos,
|
||||
std::size_t n1,
|
||||
std::size_t n2,
|
||||
storage_ptr const& sp)
|
||||
{
|
||||
const auto curr_size = size();
|
||||
if(pos > curr_size)
|
||||
{
|
||||
BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
|
||||
detail::throw_system_error( error::out_of_range, &loc );
|
||||
}
|
||||
const auto curr_data = data();
|
||||
const auto delta = (std::max)(n1, n2) -
|
||||
(std::min)(n1, n2);
|
||||
// if the size doesn't change, we don't need to
|
||||
// do anything
|
||||
if (!delta)
|
||||
return curr_data + pos;
|
||||
// if we are shrinking in size or we have enough
|
||||
// capacity, dont reallocate
|
||||
if(n1 > n2 || delta <= capacity() - curr_size)
|
||||
{
|
||||
auto const replace_pos = curr_data + pos;
|
||||
std::memmove(
|
||||
replace_pos + n2,
|
||||
replace_pos + n1,
|
||||
curr_size - pos - n1 + 1);
|
||||
size((curr_size - n1) + n2);
|
||||
return replace_pos;
|
||||
}
|
||||
if(delta > max_size() - curr_size)
|
||||
{
|
||||
BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
|
||||
detail::throw_system_error( error::string_too_large, &loc );
|
||||
}
|
||||
// would exceed capacity, reallocate
|
||||
string_impl tmp(growth(
|
||||
curr_size + delta, capacity()), sp);
|
||||
tmp.size(curr_size + delta);
|
||||
std::memcpy(
|
||||
tmp.data(),
|
||||
curr_data,
|
||||
pos);
|
||||
std::memcpy(
|
||||
tmp.data() + pos + n2,
|
||||
curr_data + pos + n1,
|
||||
curr_size - pos - n1 + 1);
|
||||
destroy(sp);
|
||||
*this = tmp;
|
||||
return data() + pos;
|
||||
}
|
||||
|
||||
void
|
||||
string_impl::
|
||||
shrink_to_fit(
|
||||
storage_ptr const& sp) noexcept
|
||||
{
|
||||
if(s_.k == short_string_)
|
||||
return;
|
||||
auto const t = p_.t;
|
||||
if(t->size <= sbo_chars_)
|
||||
{
|
||||
s_.k = short_string_;
|
||||
std::memcpy(
|
||||
s_.buf, data(), t->size);
|
||||
s_.buf[sbo_chars_] =
|
||||
static_cast<char>(
|
||||
sbo_chars_ - t->size);
|
||||
s_.buf[t->size] = 0;
|
||||
sp->deallocate(t,
|
||||
sizeof(table) +
|
||||
t->capacity + 1,
|
||||
alignof(table));
|
||||
return;
|
||||
}
|
||||
if(t->size >= t->capacity)
|
||||
return;
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
#endif
|
||||
string_impl tmp(t->size, sp);
|
||||
std::memcpy(
|
||||
tmp.data(),
|
||||
data(),
|
||||
size());
|
||||
destroy(sp);
|
||||
*this = tmp;
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
}
|
||||
catch(std::exception const&)
|
||||
{
|
||||
// eat the exception
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // namespace json
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user