mirror of
https://github.com/boostorg/json.git
synced 2026-02-12 00:02:14 +00:00
string work
This commit is contained in:
@@ -80,7 +80,7 @@ class array
|
||||
table* tab_ = nullptr;
|
||||
storage_ptr sp_;
|
||||
|
||||
struct undo;
|
||||
struct undo_create;
|
||||
struct undo_insert;
|
||||
|
||||
public:
|
||||
|
||||
@@ -87,6 +87,26 @@ struct array::table
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
struct array::undo_create
|
||||
{
|
||||
table* tab;
|
||||
storage_ptr const& sp;
|
||||
|
||||
undo_create(
|
||||
size_type n,
|
||||
storage_ptr const& sp_)
|
||||
: tab(table::create(n, sp_))
|
||||
, sp(sp_)
|
||||
{
|
||||
}
|
||||
|
||||
~undo_create()
|
||||
{
|
||||
if(tab)
|
||||
table::destroy(tab, sp);
|
||||
}
|
||||
};
|
||||
|
||||
struct array::undo_insert
|
||||
{
|
||||
value* it;
|
||||
@@ -117,7 +137,8 @@ array(
|
||||
InputIt first, InputIt last)
|
||||
: array(
|
||||
first, last,
|
||||
default_storage())
|
||||
default_storage(),
|
||||
iter_cat<InputIt>{})
|
||||
{
|
||||
static_assert(
|
||||
std::is_constructible<value,
|
||||
@@ -129,10 +150,10 @@ template<class InputIt, class>
|
||||
array::
|
||||
array(
|
||||
InputIt first, InputIt last,
|
||||
storage_ptr store)
|
||||
storage_ptr sp)
|
||||
: array(
|
||||
first, last,
|
||||
std::move(store),
|
||||
std::move(sp),
|
||||
iter_cat<InputIt>{})
|
||||
{
|
||||
static_assert(
|
||||
@@ -185,26 +206,31 @@ template<class InputIt>
|
||||
array::
|
||||
array(
|
||||
InputIt first, InputIt last,
|
||||
storage_ptr store,
|
||||
storage_ptr sp,
|
||||
std::input_iterator_tag)
|
||||
: sp_(std::move(store))
|
||||
: sp_(std::move(sp))
|
||||
{
|
||||
while(first != last)
|
||||
emplace_impl(end(), *first++);
|
||||
}
|
||||
|
||||
template<class InputIt>
|
||||
array::
|
||||
array(
|
||||
InputIt first, InputIt last,
|
||||
storage_ptr store,
|
||||
storage_ptr sp,
|
||||
std::forward_iterator_tag)
|
||||
: sp_(std::move(store))
|
||||
: sp_(std::move(sp))
|
||||
{
|
||||
reserve(std::distance(first, last));
|
||||
undo_create u(
|
||||
std::distance(first, last), sp_);
|
||||
while(first != last)
|
||||
emplace_impl(end(), *first++);
|
||||
{
|
||||
::new(u.tab->end()) value(
|
||||
*first++, sp_);
|
||||
++u.tab->d.size;
|
||||
}
|
||||
std::swap(tab_, u.tab);
|
||||
}
|
||||
|
||||
template<class InputIt>
|
||||
auto
|
||||
array::
|
||||
|
||||
@@ -89,20 +89,6 @@ relocate(
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
struct array::undo
|
||||
{
|
||||
table* tab;
|
||||
storage_ptr const& sp;
|
||||
|
||||
~undo()
|
||||
{
|
||||
if(tab)
|
||||
table::destroy(tab, sp);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
array::
|
||||
undo_insert::
|
||||
undo_insert(
|
||||
@@ -197,8 +183,7 @@ array(
|
||||
if(count == 0)
|
||||
return;
|
||||
|
||||
undo u{table::create(
|
||||
count, sp_), sp_};
|
||||
undo_create u(count, sp_);
|
||||
while(count--)
|
||||
{
|
||||
::new(u.tab->end()) value(v, sp_);
|
||||
@@ -825,8 +810,7 @@ copy(array const& other)
|
||||
return;
|
||||
}
|
||||
|
||||
undo u{table::create(
|
||||
other.size(), sp_), sp_};
|
||||
undo_create u(other.size(), sp_);
|
||||
for(auto const& v : other)
|
||||
{
|
||||
::new(u.tab->end()) value(v, sp_);
|
||||
@@ -873,8 +857,7 @@ assign(
|
||||
return;
|
||||
}
|
||||
|
||||
undo u{table::create(
|
||||
init.size(), sp_), sp_};
|
||||
undo_create u(init.size(), sp_);
|
||||
for(auto const& v : init)
|
||||
{
|
||||
::new(u.tab->end()) value(v, sp_);
|
||||
|
||||
126
include/boost/json/impl/string.hpp
Normal file
126
include/boost/json/impl/string.hpp
Normal file
@@ -0,0 +1,126 @@
|
||||
//
|
||||
// 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_IMPL_STRING_HPP
|
||||
#define BOOST_JSON_IMPL_STRING_HPP
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
struct string::impl
|
||||
{
|
||||
size_type size;
|
||||
size_type capacity;
|
||||
|
||||
static
|
||||
impl*
|
||||
construct(
|
||||
size_type capacity,
|
||||
storage_ptr const& sp)
|
||||
{
|
||||
auto s = ::new(sp->allocate(
|
||||
sizeof(impl) + capacity + 1,
|
||||
sizeof(impl))) impl;
|
||||
s->capacity = capacity;
|
||||
return s;
|
||||
}
|
||||
|
||||
static
|
||||
impl*
|
||||
construct(
|
||||
size_type size,
|
||||
size_type capacity,
|
||||
storage_ptr const& sp)
|
||||
{
|
||||
auto s = construct(capacity, sp);
|
||||
s->term(size);
|
||||
return s;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
destroy(
|
||||
impl* s,
|
||||
storage_ptr const& sp) noexcept
|
||||
{
|
||||
sp->deallocate(s,
|
||||
sizeof(impl) + s->capacity + 1,
|
||||
sizeof(impl));
|
||||
}
|
||||
|
||||
char*
|
||||
data() noexcept
|
||||
{
|
||||
return reinterpret_cast<
|
||||
char*>(this+1);
|
||||
}
|
||||
|
||||
char*
|
||||
end() noexcept
|
||||
{
|
||||
return data() + size;
|
||||
}
|
||||
|
||||
void
|
||||
term() noexcept
|
||||
{
|
||||
data()[size] = 0;
|
||||
}
|
||||
|
||||
void
|
||||
term(size_type n) noexcept
|
||||
{
|
||||
size = n;
|
||||
data()[size] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class InputIt, class>
|
||||
string::
|
||||
string(
|
||||
InputIt first,
|
||||
InputIt last,
|
||||
storage_ptr sp)
|
||||
: sp_(std::move(sp))
|
||||
{
|
||||
assign(first, last);
|
||||
}
|
||||
|
||||
template<class InputIt, class>
|
||||
string&
|
||||
string::
|
||||
assign(
|
||||
InputIt first,
|
||||
InputIt last)
|
||||
{
|
||||
maybe_raw_resize(
|
||||
first, last, iter_cat<InputIt>{});
|
||||
char* p = s_->data();
|
||||
while(first != last)
|
||||
*p++ = *first++;
|
||||
*p = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class InputIt, class>
|
||||
string&
|
||||
string::
|
||||
append(InputIt, InputIt)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // json
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
749
include/boost/json/impl/string.ipp
Normal file
749
include/boost/json/impl/string.ipp
Normal file
@@ -0,0 +1,749 @@
|
||||
//
|
||||
// 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_IMPL_STRING_IPP
|
||||
#define BOOST_JSON_IMPL_STRING_IPP
|
||||
|
||||
#include <boost/core/exchange.hpp>
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <algorithm>
|
||||
#include <new>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
|
||||
string::
|
||||
~string()
|
||||
{
|
||||
if(s_)
|
||||
impl::destroy(s_, sp_);
|
||||
}
|
||||
|
||||
string::
|
||||
string() noexcept
|
||||
: sp_(default_storage())
|
||||
{
|
||||
}
|
||||
|
||||
string::
|
||||
string(storage_ptr sp) noexcept
|
||||
: sp_(std::move(sp))
|
||||
{
|
||||
}
|
||||
|
||||
string::
|
||||
string(
|
||||
size_type count,
|
||||
char ch,
|
||||
storage_ptr sp)
|
||||
: sp_(std::move(sp))
|
||||
{
|
||||
assign(count, ch);
|
||||
}
|
||||
|
||||
string::
|
||||
string(
|
||||
string const& other,
|
||||
size_type pos,
|
||||
size_type count,
|
||||
storage_ptr sp)
|
||||
: sp_(std::move(sp))
|
||||
{
|
||||
assign(other, pos, count);
|
||||
}
|
||||
|
||||
string::
|
||||
string(
|
||||
char const* s,
|
||||
storage_ptr sp)
|
||||
: sp_(std::move(sp))
|
||||
{
|
||||
assign(s);
|
||||
}
|
||||
|
||||
string::
|
||||
string(
|
||||
char const* s,
|
||||
size_type count,
|
||||
storage_ptr sp)
|
||||
: sp_(std::move(sp))
|
||||
{
|
||||
assign(s, count);
|
||||
}
|
||||
|
||||
string::
|
||||
string(string const& other)
|
||||
: sp_(default_storage())
|
||||
{
|
||||
assign(other);
|
||||
}
|
||||
|
||||
string::
|
||||
string(
|
||||
string const& other,
|
||||
storage_ptr sp)
|
||||
: sp_(std::move(sp))
|
||||
{
|
||||
assign(other);
|
||||
}
|
||||
|
||||
string::
|
||||
string(pilfered<string> p) noexcept
|
||||
: s_(boost::exchange(
|
||||
p.get().s_, nullptr))
|
||||
, sp_(std::move(p.get().sp_))
|
||||
{
|
||||
}
|
||||
|
||||
string::
|
||||
string(string&& other) noexcept
|
||||
: s_(boost::exchange(
|
||||
other.s_, nullptr))
|
||||
, sp_(other.sp_)
|
||||
{
|
||||
}
|
||||
|
||||
string::
|
||||
string(
|
||||
string&& other,
|
||||
storage_ptr sp)
|
||||
: sp_(std::move(sp))
|
||||
{
|
||||
assign(std::move(other));
|
||||
}
|
||||
|
||||
string::
|
||||
string(
|
||||
std::initializer_list<char> init,
|
||||
storage_ptr sp)
|
||||
: sp_(std::move(sp))
|
||||
{
|
||||
assign(init);
|
||||
}
|
||||
|
||||
string::
|
||||
string(
|
||||
string_view sv,
|
||||
storage_ptr sp)
|
||||
: sp_(std::move(sp))
|
||||
{
|
||||
assign(sv);
|
||||
}
|
||||
|
||||
string::
|
||||
string(
|
||||
string_view sv,
|
||||
size_type pos,
|
||||
size_type n,
|
||||
storage_ptr sp)
|
||||
: sp_(std::move(sp))
|
||||
{
|
||||
assign(sv.substr(pos, n));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
string&
|
||||
string::
|
||||
operator=(string const& other)
|
||||
{
|
||||
assign(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
string&
|
||||
string::
|
||||
operator=(string&& other)
|
||||
{
|
||||
assign(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
|
||||
string&
|
||||
string::
|
||||
operator=(char const* s)
|
||||
{
|
||||
assign(s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
string&
|
||||
string::
|
||||
operator=(char ch)
|
||||
{
|
||||
raw_resize(1);
|
||||
traits_type::assign(
|
||||
s_->data(), 1, ch);
|
||||
return *this;
|
||||
}
|
||||
|
||||
string&
|
||||
string::
|
||||
operator=(
|
||||
std::initializer_list<char> init)
|
||||
{
|
||||
assign(init);
|
||||
return *this;
|
||||
}
|
||||
|
||||
string&
|
||||
string::
|
||||
operator=(string_view sv)
|
||||
{
|
||||
assign(sv);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
string&
|
||||
string::
|
||||
assign(
|
||||
size_type count,
|
||||
char ch)
|
||||
{
|
||||
raw_resize(count);
|
||||
traits_type::assign(
|
||||
s_->data(), count, ch);
|
||||
return *this;
|
||||
}
|
||||
|
||||
string&
|
||||
string::
|
||||
assign(
|
||||
string const& other)
|
||||
{
|
||||
raw_resize(other.size());
|
||||
traits_type::copy(data(),
|
||||
other.data(), other.size());
|
||||
return *this;
|
||||
}
|
||||
|
||||
string&
|
||||
string::
|
||||
assign(
|
||||
string const& other,
|
||||
size_type pos,
|
||||
size_type count)
|
||||
{
|
||||
return assign(
|
||||
other.substr(pos, count));
|
||||
}
|
||||
|
||||
string&
|
||||
string::
|
||||
assign(string&& other)
|
||||
{
|
||||
if(*sp_ != *other.sp_)
|
||||
return assign(other);
|
||||
|
||||
auto s = s_;
|
||||
s_ = other.s_;
|
||||
other.s_ = nullptr;
|
||||
if(s)
|
||||
impl::destroy(s, sp_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
string&
|
||||
string::
|
||||
assign(
|
||||
char const* s,
|
||||
size_type count)
|
||||
{
|
||||
raw_resize(count);
|
||||
traits_type::copy(
|
||||
data(), s, count);
|
||||
return *this;
|
||||
}
|
||||
|
||||
string&
|
||||
string::
|
||||
assign(
|
||||
char const* s)
|
||||
{
|
||||
return assign(s,
|
||||
traits_type::length(s));
|
||||
}
|
||||
|
||||
string&
|
||||
string::
|
||||
assign(std::initializer_list<char> init)
|
||||
{
|
||||
raw_resize(init.size());
|
||||
std::copy(
|
||||
init.begin(),
|
||||
init.end(),
|
||||
s_->data());
|
||||
return *this;
|
||||
}
|
||||
|
||||
string&
|
||||
string::
|
||||
assign(string_view sv)
|
||||
{
|
||||
return assign(
|
||||
sv.data(), sv.size());
|
||||
}
|
||||
|
||||
string&
|
||||
string::
|
||||
assign(
|
||||
string_view sv,
|
||||
size_type pos,
|
||||
size_type count)
|
||||
{
|
||||
return assign(
|
||||
sv.substr(pos, count));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Element Access
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
char&
|
||||
string::
|
||||
at(size_type pos)
|
||||
{
|
||||
if(pos >= size())
|
||||
BOOST_THROW_EXCEPTION(
|
||||
std::out_of_range(
|
||||
"pos >= size()"));
|
||||
return s_->data()[pos];
|
||||
}
|
||||
|
||||
char const&
|
||||
string::
|
||||
at(size_type pos) const
|
||||
{
|
||||
if(pos >= size())
|
||||
BOOST_THROW_EXCEPTION(
|
||||
std::out_of_range(
|
||||
"pos >= size()"));
|
||||
return s_->data()[pos];
|
||||
}
|
||||
|
||||
char&
|
||||
string::
|
||||
operator[](size_type pos)
|
||||
{
|
||||
return s_->data()[pos];
|
||||
}
|
||||
|
||||
const char&
|
||||
string::
|
||||
operator[](size_type pos) const
|
||||
{
|
||||
return s_->data()[pos];
|
||||
}
|
||||
|
||||
char&
|
||||
string::
|
||||
front()
|
||||
{
|
||||
return s_->data()[0];
|
||||
}
|
||||
|
||||
char const&
|
||||
string::
|
||||
front() const
|
||||
{
|
||||
return s_->data()[0];
|
||||
}
|
||||
|
||||
char&
|
||||
string::
|
||||
back()
|
||||
{
|
||||
return s_->data()[s_->size - 1];
|
||||
}
|
||||
|
||||
char const&
|
||||
string::
|
||||
back() const
|
||||
{
|
||||
return s_->data()[s_->size - 1];
|
||||
}
|
||||
|
||||
char*
|
||||
string::
|
||||
data() noexcept
|
||||
{
|
||||
if(! s_)
|
||||
return const_cast<
|
||||
char*>("");
|
||||
return s_->data();
|
||||
}
|
||||
|
||||
char const*
|
||||
string::
|
||||
data() const noexcept
|
||||
{
|
||||
if(! s_)
|
||||
return "";
|
||||
return s_->data();
|
||||
}
|
||||
|
||||
char const*
|
||||
string::
|
||||
c_str() const noexcept
|
||||
{
|
||||
return data();
|
||||
}
|
||||
|
||||
string::
|
||||
operator string_view() const noexcept
|
||||
{
|
||||
return {data(), size()};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Iterators
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
auto
|
||||
string::
|
||||
begin() noexcept ->
|
||||
iterator
|
||||
{
|
||||
if(! s_)
|
||||
return nullptr;
|
||||
return s_->data();
|
||||
}
|
||||
|
||||
auto
|
||||
string::
|
||||
begin() const noexcept ->
|
||||
const_iterator
|
||||
{
|
||||
if(! s_)
|
||||
return nullptr;
|
||||
return s_->data();
|
||||
}
|
||||
|
||||
auto
|
||||
string::
|
||||
end() noexcept ->
|
||||
iterator
|
||||
{
|
||||
if(! s_)
|
||||
return nullptr;
|
||||
return s_->end();
|
||||
}
|
||||
|
||||
auto
|
||||
string::
|
||||
end() const noexcept ->
|
||||
const_iterator
|
||||
{
|
||||
if(! s_)
|
||||
return nullptr;
|
||||
return s_->end();
|
||||
}
|
||||
|
||||
auto
|
||||
string::
|
||||
rbegin() noexcept ->
|
||||
reverse_iterator
|
||||
{
|
||||
if(! s_)
|
||||
return reverse_iterator(nullptr);
|
||||
return reverse_iterator(s_->end());
|
||||
}
|
||||
|
||||
auto
|
||||
string::
|
||||
rbegin() const noexcept ->
|
||||
const_reverse_iterator
|
||||
{
|
||||
if(! s_)
|
||||
return reverse_iterator(nullptr);
|
||||
return const_reverse_iterator(s_->end());
|
||||
}
|
||||
|
||||
auto
|
||||
string::
|
||||
rend() noexcept ->
|
||||
reverse_iterator
|
||||
{
|
||||
if(! s_)
|
||||
return reverse_iterator(nullptr);
|
||||
return reverse_iterator(s_->data());
|
||||
}
|
||||
|
||||
auto
|
||||
string::
|
||||
rend() const noexcept ->
|
||||
const_reverse_iterator
|
||||
{
|
||||
if(! s_)
|
||||
return reverse_iterator(nullptr);
|
||||
return const_reverse_iterator(s_->data());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Capacity
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool
|
||||
string::
|
||||
empty() const noexcept
|
||||
{
|
||||
if(! s_)
|
||||
return true;
|
||||
return s_->size == 0;
|
||||
}
|
||||
|
||||
auto
|
||||
string::
|
||||
size() const noexcept ->
|
||||
size_type
|
||||
{
|
||||
if(! s_)
|
||||
return 0;
|
||||
return s_->size;
|
||||
}
|
||||
|
||||
void
|
||||
string::
|
||||
reserve(size_type new_capacity)
|
||||
{
|
||||
if(new_capacity <= capacity())
|
||||
return;
|
||||
auto s = impl::construct(
|
||||
size(), new_capacity, sp_);
|
||||
traits_type::copy(
|
||||
s->data(), data(), size());
|
||||
impl::destroy(
|
||||
boost::exchange(s_, s), sp_);
|
||||
}
|
||||
|
||||
auto
|
||||
string::
|
||||
capacity() const noexcept ->
|
||||
size_type
|
||||
{
|
||||
if(! s_)
|
||||
return 0;
|
||||
return s_->capacity;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Operations
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
string::
|
||||
clear() noexcept
|
||||
{
|
||||
if(s_)
|
||||
s_->term(0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
string::
|
||||
push_back(char ch)
|
||||
{
|
||||
s_->data()[s_->size++] = ch;
|
||||
s_->data()[s_->size] = 0;
|
||||
}
|
||||
|
||||
void
|
||||
string::
|
||||
pop_back()
|
||||
{
|
||||
s_->data()[--s_->size] = 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
string&
|
||||
string::
|
||||
append(size_type count, char ch)
|
||||
{
|
||||
traits_type::assign(
|
||||
raw_insert(size(), count),
|
||||
count, ch);
|
||||
return *this;
|
||||
}
|
||||
|
||||
string&
|
||||
string::
|
||||
append(string const& str)
|
||||
{
|
||||
return append(
|
||||
str.data(), str.size());
|
||||
}
|
||||
|
||||
string&
|
||||
string::
|
||||
append(
|
||||
string const& str,
|
||||
size_type pos,
|
||||
size_type count)
|
||||
{
|
||||
return append(str.substr(pos, count));
|
||||
}
|
||||
|
||||
string&
|
||||
string::
|
||||
append(
|
||||
char const* s,
|
||||
size_type count)
|
||||
{
|
||||
traits_type::copy(
|
||||
raw_insert(size(), count),
|
||||
s, count);
|
||||
return *this;
|
||||
}
|
||||
|
||||
string&
|
||||
string::
|
||||
append(char const* s)
|
||||
{
|
||||
return append(s,
|
||||
traits_type::length(s));
|
||||
}
|
||||
|
||||
string&
|
||||
string::
|
||||
append(std::initializer_list<char> init)
|
||||
{
|
||||
// TODO
|
||||
boost::ignore_unused(init);
|
||||
return *this;
|
||||
}
|
||||
|
||||
string&
|
||||
string::
|
||||
append(string_view sv)
|
||||
{
|
||||
return append(
|
||||
sv.data(), sv.size());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
string_view
|
||||
string::
|
||||
substr(
|
||||
size_type pos ,
|
||||
size_type count) const
|
||||
{
|
||||
if(pos > size())
|
||||
BOOST_THROW_EXCEPTION(
|
||||
std::out_of_range("pos > size()"));
|
||||
if(! s_)
|
||||
return {};
|
||||
return {
|
||||
s_->data() + pos,
|
||||
std::min<size_type>(
|
||||
s_->size - pos,
|
||||
count)};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
string::
|
||||
raw_resize(size_type n)
|
||||
{
|
||||
if(n <= capacity())
|
||||
{
|
||||
if(s_)
|
||||
s_->term(n);
|
||||
return;
|
||||
}
|
||||
auto s = boost::exchange(s_,
|
||||
impl::construct(n, n, sp_));
|
||||
if(s)
|
||||
impl::destroy(s, sp_);
|
||||
}
|
||||
|
||||
// insert `n` uninitialized chars at `pos`,
|
||||
// reallocating as needed. does nothing if n==0.
|
||||
// returns the insertion point
|
||||
char*
|
||||
string::
|
||||
raw_insert(
|
||||
size_type pos,
|
||||
size_type n)
|
||||
{
|
||||
if( n > max_size() ||
|
||||
size() > max_size() - n)
|
||||
BOOST_THROW_EXCEPTION(
|
||||
std::out_of_range(
|
||||
"size() + n > max_size()"));
|
||||
if(pos > size())
|
||||
BOOST_THROW_EXCEPTION(
|
||||
std::out_of_range(
|
||||
"pos > size()"));
|
||||
auto const new_size = size() + n;
|
||||
|
||||
if(new_size <= capacity())
|
||||
{
|
||||
if(s_)
|
||||
{
|
||||
traits_type::move(
|
||||
s_->data() + pos + n,
|
||||
s_->data() + pos,
|
||||
s_->size + 1 - pos);
|
||||
s_->size = new_size;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto s = impl::construct(
|
||||
new_size, sp_);
|
||||
if(s_)
|
||||
{
|
||||
traits_type::copy(
|
||||
s->data(),
|
||||
s_->data(),
|
||||
pos);
|
||||
traits_type::copy(
|
||||
s->data() + pos + n,
|
||||
s_->data() + pos,
|
||||
s_->size + 1 - pos);
|
||||
s->size = new_size;
|
||||
impl::destroy(s_, sp_);
|
||||
}
|
||||
else
|
||||
{
|
||||
s->term(n);
|
||||
}
|
||||
s_ = s;
|
||||
}
|
||||
return s_->data() + pos;
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, string const& s)
|
||||
{
|
||||
os.write(s.data(), s.size());
|
||||
return os;
|
||||
}
|
||||
|
||||
} // json
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
@@ -143,8 +143,7 @@ value(
|
||||
|
||||
case json::kind::string:
|
||||
::new(&str_) string(
|
||||
string::allocator_type(
|
||||
std::move(sp)));
|
||||
std::move(sp));
|
||||
break;
|
||||
|
||||
case json::kind::number:
|
||||
@@ -188,10 +187,8 @@ value(
|
||||
break;
|
||||
|
||||
case json::kind::string:
|
||||
// workaround for some stdlibs
|
||||
construct_string(
|
||||
other.str_,
|
||||
std::move(sp));
|
||||
::new(&str_) string(
|
||||
other.str_, std::move(sp));
|
||||
break;
|
||||
|
||||
case json::kind::number:
|
||||
@@ -318,8 +315,7 @@ value(
|
||||
break;
|
||||
|
||||
case json::kind::string:
|
||||
// workaround for some stdlibs
|
||||
construct_string(
|
||||
::new(&str_) string(
|
||||
std::move(other.str_),
|
||||
std::move(sp));
|
||||
break;
|
||||
@@ -424,11 +420,11 @@ value::
|
||||
value(
|
||||
string str,
|
||||
storage_ptr sp)
|
||||
{
|
||||
// workaround for some stdlibs
|
||||
construct_string(
|
||||
: str_(
|
||||
std::move(str),
|
||||
std::move(sp));
|
||||
std::move(sp))
|
||||
, kind_(json::kind::string)
|
||||
{
|
||||
}
|
||||
|
||||
value::
|
||||
@@ -591,7 +587,7 @@ maybe_object(
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
storage_ptr
|
||||
storage_ptr const&
|
||||
value::
|
||||
get_storage() const noexcept
|
||||
{
|
||||
@@ -604,7 +600,7 @@ get_storage() const noexcept
|
||||
return arr_.get_storage();
|
||||
|
||||
case json::kind::string:
|
||||
return str_.get_allocator().get_storage();
|
||||
return str_.get_storage();
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -1004,48 +1000,6 @@ pop_back()
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// private
|
||||
|
||||
template<class S>
|
||||
auto
|
||||
value::
|
||||
construct_string(
|
||||
S&& str, storage_ptr sp) ->
|
||||
typename std::enable_if<
|
||||
! std::is_constructible<S, string,
|
||||
typename string::allocator_type
|
||||
>::value>::type
|
||||
|
||||
{
|
||||
// workaround for missing std::string
|
||||
// ctors in some stdlib versions
|
||||
auto s = string(typename
|
||||
string::allocator_type(
|
||||
std::move(sp)));
|
||||
s = std::move(str);
|
||||
::new(&str_) string(
|
||||
std::move(s));
|
||||
kind_ = json::kind::string;
|
||||
}
|
||||
|
||||
template<class S>
|
||||
auto
|
||||
value::
|
||||
construct_string(
|
||||
S&& str, storage_ptr sp) ->
|
||||
typename std::enable_if<
|
||||
std::is_constructible<S, string,
|
||||
typename string::allocator_type
|
||||
>::value>::type
|
||||
{
|
||||
::new(&str_) string(std::move(str),
|
||||
typename string::allocator_type(
|
||||
std::move(sp)));
|
||||
kind_ = json::kind::string;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// friends
|
||||
|
||||
std::ostream&
|
||||
|
||||
@@ -11,23 +11,685 @@
|
||||
#define BOOST_JSON_STRING_HPP
|
||||
|
||||
#include <boost/json/detail/config.hpp>
|
||||
#include <boost/json/allocator.hpp>
|
||||
#include <boost/json/storage.hpp>
|
||||
#include <boost/pilfer.hpp>
|
||||
#include <boost/utility/string_view.hpp>
|
||||
#include <algorithm>
|
||||
#include <initializer_list>
|
||||
#include <iosfwd>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
|
||||
class value;
|
||||
|
||||
/** The native type of string values
|
||||
*/
|
||||
using string =
|
||||
std::basic_string<
|
||||
char,
|
||||
std::char_traits<char>,
|
||||
allocator<char>>;
|
||||
class string
|
||||
{
|
||||
struct impl;
|
||||
|
||||
impl* s_ = nullptr;
|
||||
storage_ptr sp_;
|
||||
|
||||
public:
|
||||
using traits_type = std::char_traits<char>;
|
||||
using value_type = char;
|
||||
using size_type = unsigned long;
|
||||
using difference_type = long;
|
||||
using pointer = char*;
|
||||
using reference = char&;
|
||||
using iterator = char*;
|
||||
using const_pointer = char const*;
|
||||
using const_reference = const char&;
|
||||
using const_iterator = char const*;
|
||||
using reverse_iterator =
|
||||
std::reverse_iterator<iterator>;
|
||||
using const_reverse_iterator =
|
||||
std::reverse_iterator<const_iterator>;
|
||||
|
||||
/// A special index
|
||||
static constexpr size_type npos =
|
||||
(std::numeric_limits<size_type>::max)();
|
||||
|
||||
BOOST_JSON_DECL
|
||||
~string();
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string() noexcept;
|
||||
|
||||
BOOST_JSON_DECL
|
||||
explicit
|
||||
string(storage_ptr sp) noexcept;
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string(
|
||||
size_type count,
|
||||
char ch,
|
||||
storage_ptr sp =
|
||||
default_storage());
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string(
|
||||
string const& other,
|
||||
size_type pos,
|
||||
size_type count = npos,
|
||||
storage_ptr sp =
|
||||
default_storage());
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string(
|
||||
char const* s,
|
||||
storage_ptr sp =
|
||||
default_storage());
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string(
|
||||
char const* s,
|
||||
size_type count,
|
||||
storage_ptr sp =
|
||||
default_storage());
|
||||
|
||||
template<class InputIt
|
||||
#ifndef GENERATING_DOCUMENTATION
|
||||
,class = typename std::enable_if<
|
||||
std::is_convertible<
|
||||
typename std::iterator_traits<
|
||||
InputIt>::value_type,
|
||||
char>::value>::type
|
||||
#endif
|
||||
>
|
||||
string(
|
||||
InputIt first,
|
||||
InputIt last,
|
||||
storage_ptr sp =
|
||||
default_storage());
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string(string const& other);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string(
|
||||
string const& other,
|
||||
storage_ptr sp);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string(pilfered<string> other) noexcept;
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string(string&& other) noexcept;
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string(
|
||||
string&& other,
|
||||
storage_ptr sp);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string(
|
||||
std::initializer_list<char> init,
|
||||
storage_ptr sp = default_storage());
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string(
|
||||
string_view sv,
|
||||
storage_ptr sp =
|
||||
default_storage());
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string(
|
||||
string_view sv,
|
||||
size_type pos,
|
||||
size_type n,
|
||||
storage_ptr sp =
|
||||
default_storage());
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string&
|
||||
operator=(string const& other);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string&
|
||||
operator=(string&& other);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string&
|
||||
operator=(char const* s);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string&
|
||||
operator=(char ch);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string&
|
||||
operator=(std::initializer_list<char> init);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string&
|
||||
operator=(string_view sv);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string&
|
||||
assign(
|
||||
size_type count,
|
||||
char ch);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string&
|
||||
assign(
|
||||
string const& other);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string&
|
||||
assign(
|
||||
string const& other,
|
||||
size_type pos,
|
||||
size_type count);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string&
|
||||
assign(string&& other);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string&
|
||||
assign(
|
||||
char const* s,
|
||||
size_type count);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string&
|
||||
assign(
|
||||
char const* s);
|
||||
|
||||
template<class InputIt
|
||||
#ifndef GENERATING_DOCUMENTATION
|
||||
,class = typename std::enable_if<
|
||||
std::is_convertible<
|
||||
typename std::iterator_traits<
|
||||
InputIt>::value_type,
|
||||
char>::value>::type
|
||||
#endif
|
||||
>
|
||||
string&
|
||||
assign(
|
||||
InputIt first,
|
||||
InputIt last);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string&
|
||||
assign(std::initializer_list<char> init);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string&
|
||||
assign(string_view sv);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string&
|
||||
assign(
|
||||
string_view sv,
|
||||
size_type pos,
|
||||
size_type count = npos);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
storage_ptr const&
|
||||
get_storage() const noexcept
|
||||
{
|
||||
return sp_;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Element Access
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
BOOST_JSON_DECL
|
||||
char&
|
||||
at(size_type pos);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
char const&
|
||||
at(size_type pos) const;
|
||||
|
||||
BOOST_JSON_DECL
|
||||
char&
|
||||
operator[](size_type pos);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
const char&
|
||||
operator[](size_type pos) const;
|
||||
|
||||
BOOST_JSON_DECL
|
||||
char&
|
||||
front();
|
||||
|
||||
BOOST_JSON_DECL
|
||||
char const&
|
||||
front() const;
|
||||
|
||||
BOOST_JSON_DECL
|
||||
char&
|
||||
back();
|
||||
|
||||
BOOST_JSON_DECL
|
||||
char const&
|
||||
back() const;
|
||||
|
||||
BOOST_JSON_DECL
|
||||
char*
|
||||
data() noexcept;
|
||||
|
||||
BOOST_JSON_DECL
|
||||
char const*
|
||||
data() const noexcept;
|
||||
|
||||
BOOST_JSON_DECL
|
||||
char const*
|
||||
c_str() const noexcept;
|
||||
|
||||
BOOST_JSON_DECL
|
||||
operator string_view() const noexcept;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Iterators
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Return an iterator to the first character
|
||||
|
||||
If the container is empty, the returned iterator
|
||||
will be equal to @ref end().
|
||||
|
||||
@par Complexity
|
||||
|
||||
Constant.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
iterator
|
||||
begin() noexcept;
|
||||
|
||||
/** Return an iterator to the first character
|
||||
|
||||
If the container is empty, the returned iterator
|
||||
will be equal to @ref end().
|
||||
|
||||
@par Complexity
|
||||
|
||||
Constant.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
const_iterator
|
||||
begin() const noexcept;
|
||||
|
||||
/** Return an iterator to the first character
|
||||
|
||||
If the container is empty, the returned iterator
|
||||
will be equal to @ref end().
|
||||
|
||||
@par Complexity
|
||||
|
||||
Constant.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
const_iterator
|
||||
cbegin() const noexcept
|
||||
{
|
||||
return begin();
|
||||
}
|
||||
|
||||
/** Return an iterator to the character following the last character
|
||||
|
||||
The character acts as a placeholder; attempting to
|
||||
access it results in undefined behavior.
|
||||
|
||||
@par Complexity
|
||||
|
||||
Constant.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
iterator
|
||||
end() noexcept;
|
||||
|
||||
/** Return an iterator to the character following the last character
|
||||
|
||||
The character acts as a placeholder; attempting to
|
||||
access it results in undefined behavior.
|
||||
|
||||
@par Complexity
|
||||
|
||||
Constant.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
const_iterator
|
||||
end() const noexcept;
|
||||
|
||||
/** Return an iterator to the character following the last character
|
||||
|
||||
The character acts as a placeholder; attempting to
|
||||
access it results in undefined behavior.
|
||||
|
||||
@par Complexity
|
||||
|
||||
Constant.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
const_iterator
|
||||
cend() const noexcept
|
||||
{
|
||||
return end();
|
||||
}
|
||||
|
||||
/** Return a reverse iterator to the first character of the reversed container
|
||||
|
||||
The pointed-to character corresponds to the last character
|
||||
of the non-reversed container. If the container is empty,
|
||||
the returned iterator is equal to @ref rend()
|
||||
|
||||
@par Complexity
|
||||
|
||||
Constant.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
reverse_iterator
|
||||
rbegin() noexcept;
|
||||
|
||||
/** Return a reverse iterator to the first character of the reversed container
|
||||
|
||||
The pointed-to character corresponds to the last character
|
||||
of the non-reversed container. If the container is empty,
|
||||
the returned iterator is equal to @ref rend()
|
||||
|
||||
@par Complexity
|
||||
|
||||
Constant.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
const_reverse_iterator
|
||||
rbegin() const noexcept;
|
||||
|
||||
/** Return a reverse iterator to the first character of the reversed container
|
||||
|
||||
The pointed-to character corresponds to the last character
|
||||
of the non-reversed container. If the container is empty,
|
||||
the returned iterator is equal to @ref rend()
|
||||
|
||||
@par Complexity
|
||||
|
||||
Constant.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
const_reverse_iterator
|
||||
crbegin() const noexcept
|
||||
{
|
||||
return rbegin();
|
||||
}
|
||||
|
||||
/** Return a reverse iterator to the character following the last character of the reversed container
|
||||
|
||||
The pointed-to character corresponds to the character
|
||||
preceding the first character of the non-reversed container.
|
||||
This character acts as a placeholder, attempting to access
|
||||
it results in undefined behavior.
|
||||
|
||||
@par Complexity
|
||||
|
||||
Constant.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
reverse_iterator
|
||||
rend() noexcept;
|
||||
|
||||
/** Return a reverse iterator to the character following the last character of the reversed container
|
||||
|
||||
The pointed-to character corresponds to the character
|
||||
preceding the first character of the non-reversed container.
|
||||
This character acts as a placeholder, attempting to access
|
||||
it results in undefined behavior.
|
||||
|
||||
@par Complexity
|
||||
|
||||
Constant.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
const_reverse_iterator
|
||||
rend() const noexcept;
|
||||
|
||||
/** Return a reverse iterator to the character following the last character of the reversed container
|
||||
|
||||
The pointed-to character corresponds to the character
|
||||
preceding the first character of the non-reversed container.
|
||||
This character acts as a placeholder, attempting to access
|
||||
it results in undefined behavior.
|
||||
|
||||
@par Complexity
|
||||
|
||||
Constant.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
const_reverse_iterator
|
||||
crend() const noexcept
|
||||
{
|
||||
return rend();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Capacity
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
BOOST_JSON_DECL
|
||||
bool
|
||||
empty() const noexcept;
|
||||
|
||||
BOOST_JSON_DECL
|
||||
size_type
|
||||
size() const noexcept;
|
||||
|
||||
size_type
|
||||
length() const noexcept
|
||||
{
|
||||
return size();
|
||||
}
|
||||
|
||||
size_type
|
||||
max_size() const noexcept
|
||||
{
|
||||
return npos - 1;
|
||||
}
|
||||
|
||||
BOOST_JSON_DECL
|
||||
void
|
||||
reserve(size_type new_capacity);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
size_type
|
||||
capacity() const noexcept;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Operations
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
BOOST_JSON_DECL
|
||||
void
|
||||
clear() noexcept;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// insert
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string&
|
||||
erase(
|
||||
size_type index = 0,
|
||||
size_type count = npos);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
iterator
|
||||
erase(const_iterator pos);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
iterator
|
||||
erase(
|
||||
const_iterator first,
|
||||
const_iterator last);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
BOOST_JSON_DECL
|
||||
void
|
||||
push_back(char ch);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
void
|
||||
pop_back();
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string&
|
||||
append(size_type count, char ch);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string&
|
||||
append(string const& str );
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string&
|
||||
append(
|
||||
string const& str,
|
||||
size_type pos,
|
||||
size_type count = npos);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string&
|
||||
append(
|
||||
char const* s,
|
||||
size_type count);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string&
|
||||
append(char const* s);
|
||||
|
||||
template<class InputIt
|
||||
#ifndef GENERATING_DOCUMENTATION
|
||||
,class = typename std::enable_if<
|
||||
std::is_convertible<
|
||||
typename std::iterator_traits<
|
||||
InputIt>::value_type,
|
||||
char>::value>::type
|
||||
#endif
|
||||
>
|
||||
string&
|
||||
append(InputIt first, InputIt last);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string&
|
||||
append(std::initializer_list<char> init);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string&
|
||||
append(string_view sv);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Observers
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
BOOST_JSON_DECL
|
||||
string_view
|
||||
substr(
|
||||
size_type pos = 0,
|
||||
size_type count = npos) const;
|
||||
|
||||
private:
|
||||
template<class It>
|
||||
using iter_cat = typename
|
||||
std::iterator_traits<It>::iterator_category;
|
||||
|
||||
BOOST_JSON_DECL
|
||||
void
|
||||
raw_resize(
|
||||
size_type size);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
char*
|
||||
raw_insert(
|
||||
size_type pos,
|
||||
size_type n);
|
||||
|
||||
template<class InputIt>
|
||||
void
|
||||
maybe_raw_resize(
|
||||
InputIt, InputIt,
|
||||
std::input_iterator_tag)
|
||||
{
|
||||
}
|
||||
|
||||
template<class InputIt>
|
||||
void
|
||||
maybe_raw_resize(
|
||||
InputIt first,
|
||||
InputIt last,
|
||||
std::forward_iterator_tag)
|
||||
{
|
||||
raw_resize(std::distance(
|
||||
first, last));
|
||||
}
|
||||
};
|
||||
|
||||
inline
|
||||
bool
|
||||
operator==(string const& lhs, string const& rhs)
|
||||
{
|
||||
return std::lexicographical_compare(
|
||||
lhs.begin(), lhs.end(),
|
||||
rhs.begin(), rhs.end())
|
||||
== 0;
|
||||
}
|
||||
|
||||
inline
|
||||
bool
|
||||
operator==(char const* lhs, string const& rhs)
|
||||
{
|
||||
return std::lexicographical_compare(
|
||||
lhs, lhs + std::char_traits<char>::length(lhs),
|
||||
rhs.begin(), rhs.end())
|
||||
== 0;
|
||||
}
|
||||
|
||||
inline
|
||||
bool
|
||||
operator==(string const& lhs, char const* rhs)
|
||||
{
|
||||
return std::lexicographical_compare(
|
||||
lhs.begin(), lhs.end(),
|
||||
rhs, rhs + std::char_traits<char>::length(rhs))
|
||||
== 0;
|
||||
}
|
||||
|
||||
BOOST_JSON_DECL
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, string const& s);
|
||||
|
||||
} // json
|
||||
} // boost
|
||||
|
||||
#include <boost/json/impl/string.hpp>
|
||||
#if BOOST_JSON_HEADER_ONLY
|
||||
#include <boost/json/impl/string.ipp>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -767,7 +767,7 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
BOOST_JSON_DECL
|
||||
storage_ptr
|
||||
storage_ptr const&
|
||||
get_storage() const noexcept;
|
||||
|
||||
object&
|
||||
@@ -1079,24 +1079,6 @@ private:
|
||||
construct(
|
||||
json::kind, storage_ptr) noexcept;
|
||||
|
||||
template<class S>
|
||||
auto
|
||||
construct_string(
|
||||
S&& str, storage_ptr store) ->
|
||||
typename std::enable_if<
|
||||
! std::is_constructible<S, string,
|
||||
typename string::allocator_type
|
||||
>::value>::type;
|
||||
|
||||
template<class S>
|
||||
auto
|
||||
construct_string(
|
||||
S&& str, storage_ptr store) ->
|
||||
typename std::enable_if<
|
||||
std::is_constructible<S, string,
|
||||
typename string::allocator_type
|
||||
>::value>::type;
|
||||
|
||||
BOOST_JSON_DECL
|
||||
friend
|
||||
std::ostream&
|
||||
|
||||
Reference in New Issue
Block a user