mirror of
https://github.com/boostorg/json.git
synced 2025-05-12 14:11:40 +00:00
1080 lines
29 KiB
C++
1080 lines
29 KiB
C++
//
|
|
// 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/BeastLounge
|
|
//
|
|
|
|
// Test that header file is self-contained.
|
|
#include <boost/json/array.hpp>
|
|
|
|
#include <boost/beast/_experimental/unit_test/suite.hpp>
|
|
|
|
#include "test.hpp"
|
|
|
|
namespace boost {
|
|
namespace json {
|
|
|
|
class array_test : public beast::unit_test::suite
|
|
{
|
|
public:
|
|
using init_list = std::initializer_list<value>;
|
|
|
|
string_view const str_;
|
|
|
|
array_test()
|
|
: str_(
|
|
"abcdefghijklmnopqrstuvwxyz")
|
|
{
|
|
// ensure this string does
|
|
// not fit in the SBO area.
|
|
BOOST_ASSERT(str_.size() >
|
|
string().capacity());
|
|
}
|
|
|
|
void
|
|
check(array const& a)
|
|
{
|
|
BEAST_EXPECT(a.size() == 3);
|
|
BEAST_EXPECT(a[0].is_number());
|
|
BEAST_EXPECT(a[1].is_bool());
|
|
BEAST_EXPECT(a[2].is_string());
|
|
}
|
|
|
|
void
|
|
check(
|
|
array const& a,
|
|
storage_ptr const& sp)
|
|
{
|
|
check(a);
|
|
check_storage(a, sp);
|
|
}
|
|
|
|
void
|
|
testCtors()
|
|
{
|
|
// ~array()
|
|
{
|
|
// implied
|
|
}
|
|
|
|
// array()
|
|
{
|
|
scoped_fail_storage fs;
|
|
array a;
|
|
BEAST_EXPECT(a.empty());
|
|
BEAST_EXPECT(a.size() == 0);
|
|
}
|
|
|
|
// array(storage_ptr)
|
|
{
|
|
scoped_fail_storage fs;
|
|
array a(default_storage());
|
|
check_storage(a, default_storage());
|
|
}
|
|
|
|
// array(size_type, value, storage)
|
|
{
|
|
// default storage
|
|
{
|
|
array a(3, true);
|
|
BEAST_EXPECT(a.size() == 3);
|
|
for(auto const& v : a)
|
|
BEAST_EXPECT(v.is_bool());
|
|
check_storage(a, default_storage());
|
|
}
|
|
|
|
// construct with zero `true` values
|
|
{
|
|
array(0, true);
|
|
}
|
|
|
|
// construct with three `true` values
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
array a(3, true, sp);
|
|
BEAST_EXPECT(a.size() == 3);
|
|
check_storage(a, sp);
|
|
});
|
|
}
|
|
|
|
// array(size_type, storage)
|
|
{
|
|
// default storage
|
|
fail_loop([&]
|
|
{
|
|
array a(3);
|
|
BEAST_EXPECT(a.size() == 3);
|
|
for(auto const& v : a)
|
|
BEAST_EXPECT(v.is_null());
|
|
check_storage(a, default_storage());
|
|
});
|
|
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
array a(3, sp);
|
|
BEAST_EXPECT(a.size() == 3);
|
|
check_storage(a, sp);
|
|
});
|
|
}
|
|
|
|
// array(InputIt, InputIt, storage)
|
|
{
|
|
// default storage
|
|
fail_loop([&]
|
|
{
|
|
init_list init{ 0, 1, str_, 3, 4 };
|
|
array a(init.begin(), init.end());
|
|
check_storage(a, default_storage());
|
|
BEAST_EXPECT(a[0].as_number() == 0);
|
|
BEAST_EXPECT(a[1].as_number() == 1);
|
|
BEAST_EXPECT(a[2].as_string() == str_);
|
|
BEAST_EXPECT(a[3].as_number() == 3);
|
|
BEAST_EXPECT(a[4].as_number() == 4);
|
|
});
|
|
|
|
// forward iterator
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
init_list init{ 1, true, str_ };
|
|
array a(init.begin(), init.end(), sp);
|
|
check(a);
|
|
check_storage(a, sp);
|
|
});
|
|
|
|
// input iterator
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
init_list init{ 1, true, str_ };
|
|
array a(
|
|
make_input_iterator(init.begin()),
|
|
make_input_iterator(init.end()), sp);
|
|
check(a);
|
|
check_storage(a, sp);
|
|
});
|
|
}
|
|
|
|
// array(array const&)
|
|
{
|
|
{
|
|
array a1;
|
|
array a2(a1);
|
|
}
|
|
|
|
{
|
|
array a1;
|
|
array a2({ 1, true, str_ });
|
|
a2 = a1;
|
|
}
|
|
|
|
fail_loop([&]
|
|
{
|
|
init_list init{ 1, true, str_ };
|
|
array a1(init.begin(), init.end());
|
|
array a2(a1);
|
|
check(a2);
|
|
check_storage(a2, default_storage());
|
|
});
|
|
}
|
|
|
|
// array(array const&, storage)
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
init_list init{ 1, true, str_ };
|
|
array a1(init.begin(), init.end());
|
|
array a2(a1, sp);
|
|
BEAST_EXPECT(a2.size() == 3);
|
|
check_storage(a2, sp);
|
|
});
|
|
|
|
// array(pilfered<array>)
|
|
{
|
|
init_list init{ 1, true, str_ };
|
|
array a1(init.begin(), init.end());
|
|
array a2(pilfer(a1));
|
|
BEAST_EXPECT(a1.empty());
|
|
BEAST_EXPECT(! a1.get_storage());
|
|
check(a2);
|
|
check_storage(a2, default_storage());
|
|
}
|
|
|
|
// array(array&&)
|
|
{
|
|
init_list init{ 1, true, str_ };
|
|
array a1(init.begin(), init.end());
|
|
array a2 = std::move(a1);
|
|
BEAST_EXPECT(a1.empty());
|
|
check(a2);
|
|
check_storage(a2, default_storage());
|
|
}
|
|
|
|
// array(array&&, storage)
|
|
{
|
|
{
|
|
init_list init{ 1, true, str_ };
|
|
array a1(init.begin(), init.end());
|
|
array a2(
|
|
std::move(a1), default_storage());
|
|
BEAST_EXPECT(a1.empty());
|
|
check(a2);
|
|
check_storage(a1, default_storage());
|
|
check_storage(a2, default_storage());
|
|
}
|
|
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
init_list init{ 1, true, str_ };
|
|
array a1(init.begin(), init.end());
|
|
array a2(std::move(a1), sp);
|
|
BEAST_EXPECT(! a1.empty());
|
|
check(a2);
|
|
check_storage(a1, default_storage());
|
|
check_storage(a2, sp);
|
|
});
|
|
}
|
|
|
|
// array(init_list, storage)
|
|
{
|
|
// default storage
|
|
{
|
|
array a({1, true, str_});
|
|
check(a);
|
|
check_storage(a, default_storage());
|
|
}
|
|
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
array a({1, true, str_}, sp);
|
|
check(a, sp);
|
|
check_storage(a, sp);
|
|
});
|
|
}
|
|
}
|
|
|
|
void
|
|
testAssignment()
|
|
{
|
|
// operator=(array const&)
|
|
{
|
|
{
|
|
array a1({1, true, str_});
|
|
array a2({nullptr, value(kind::object), 1.f});
|
|
a2 = a1;
|
|
check(a1);
|
|
check(a2);
|
|
check_storage(a1, default_storage());
|
|
check_storage(a2, default_storage());
|
|
}
|
|
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
array a1({1, true, str_});
|
|
array a2({nullptr, value(kind::object), 1.f}, sp);
|
|
a2 = a1;
|
|
check(a1);
|
|
check(a2);
|
|
check_storage(a1, default_storage());
|
|
check_storage(a2, sp);
|
|
});
|
|
}
|
|
|
|
// operator=(array&&)
|
|
{
|
|
{
|
|
array a1({1, true, str_});
|
|
array a2({nullptr, object{}, 1.f});
|
|
a2 = std::move(a1);
|
|
BEAST_EXPECT(a1.empty());
|
|
check(a2);
|
|
}
|
|
|
|
// empty
|
|
{
|
|
array a1;
|
|
array a2;
|
|
a2 = std::move(a1);
|
|
BEAST_EXPECT(a1.empty());
|
|
BEAST_EXPECT(a2.empty());
|
|
}
|
|
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
array a1({1, true, str_});
|
|
array a2({nullptr, value(kind::object), 1.f}, sp);
|
|
a2 = std::move(a1);
|
|
check(a1);
|
|
check(a2);
|
|
check_storage(a1, default_storage());
|
|
check_storage(a2, sp);
|
|
});
|
|
}
|
|
|
|
// operator=(init_list)
|
|
{
|
|
{
|
|
array a;
|
|
a = {};
|
|
}
|
|
|
|
{
|
|
array a({ 1, true, str_ });
|
|
a = {};
|
|
}
|
|
|
|
{
|
|
init_list init{ 1, true, str_ };
|
|
array a({nullptr, value(kind::object), 1.f});
|
|
a = init;
|
|
check(a);
|
|
check_storage(a, default_storage());
|
|
}
|
|
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
init_list init{ 1, true, str_ };
|
|
array a({nullptr, value(kind::object), 1.f}, sp);
|
|
a = init;
|
|
check(a);
|
|
check_storage(a, sp);
|
|
});
|
|
}
|
|
}
|
|
|
|
void
|
|
testGetStorage()
|
|
{
|
|
// get_storage()
|
|
{
|
|
// implied
|
|
}
|
|
}
|
|
|
|
void
|
|
testAccess()
|
|
{
|
|
// at(pos)
|
|
{
|
|
array a({1, true, str_});
|
|
scoped_fail_storage fs;
|
|
BEAST_EXPECT(a.at(0).is_number());
|
|
BEAST_EXPECT(a.at(1).is_bool());
|
|
BEAST_EXPECT(a.at(2).is_string());
|
|
try
|
|
{
|
|
a.at(3);
|
|
BEAST_FAIL();
|
|
}
|
|
catch(std::out_of_range const&)
|
|
{
|
|
BEAST_PASS();
|
|
}
|
|
}
|
|
|
|
// at(pos) const
|
|
{
|
|
array const a({1, true, str_});
|
|
scoped_fail_storage fs;
|
|
BEAST_EXPECT(a.at(0).is_number());
|
|
BEAST_EXPECT(a.at(1).is_bool());
|
|
BEAST_EXPECT(a.at(2).is_string());
|
|
try
|
|
{
|
|
a.at(3);
|
|
BEAST_FAIL();
|
|
}
|
|
catch(std::out_of_range const&)
|
|
{
|
|
BEAST_PASS();
|
|
}
|
|
}
|
|
|
|
// operator[&](size_type)
|
|
{
|
|
array a({1, true, str_});
|
|
scoped_fail_storage fs;
|
|
BEAST_EXPECT(a[0].is_number());
|
|
BEAST_EXPECT(a[1].is_bool());
|
|
BEAST_EXPECT(a[2].is_string());
|
|
}
|
|
|
|
// operator[&](size_type) const
|
|
{
|
|
array const a({1, true, str_});
|
|
scoped_fail_storage fs;
|
|
BEAST_EXPECT(a[0].is_number());
|
|
BEAST_EXPECT(a[1].is_bool());
|
|
BEAST_EXPECT(a[2].is_string());
|
|
}
|
|
|
|
// front()
|
|
{
|
|
array a({1, true, str_});
|
|
scoped_fail_storage fs;
|
|
BEAST_EXPECT(a.front().is_number());
|
|
}
|
|
|
|
// front() const
|
|
{
|
|
array const a({1, true, str_});
|
|
scoped_fail_storage fs;
|
|
BEAST_EXPECT(a.front().is_number());
|
|
}
|
|
|
|
// back()
|
|
{
|
|
array a({1, true, str_});
|
|
scoped_fail_storage fs;
|
|
BEAST_EXPECT(a.back().is_string());
|
|
}
|
|
|
|
// back() const
|
|
{
|
|
array const a({1, true, str_});
|
|
scoped_fail_storage fs;
|
|
BEAST_EXPECT(a.back().is_string());
|
|
}
|
|
|
|
// data()
|
|
{
|
|
{
|
|
array a({1, true, str_});
|
|
scoped_fail_storage fs;
|
|
BEAST_EXPECT(a.data() == &a[0]);
|
|
}
|
|
{
|
|
BEAST_EXPECT(array{}.data() == nullptr);
|
|
}
|
|
}
|
|
|
|
// data() const
|
|
{
|
|
{
|
|
array const a({1, true, str_});
|
|
scoped_fail_storage fs;
|
|
BEAST_EXPECT(a.data() == &a[0]);
|
|
}
|
|
{
|
|
array const a;
|
|
BEAST_EXPECT(a.data() == nullptr);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
testIterators()
|
|
{
|
|
array a({1, true, str_});
|
|
auto const& ac(a);
|
|
|
|
{
|
|
auto it = a.begin();
|
|
BEAST_EXPECT(it->is_number()); ++it;
|
|
BEAST_EXPECT(it->is_bool()); it++;
|
|
BEAST_EXPECT(it->is_string()); ++it;
|
|
BEAST_EXPECT(it == a.end());
|
|
}
|
|
{
|
|
auto it = a.cbegin();
|
|
BEAST_EXPECT(it->is_number()); ++it;
|
|
BEAST_EXPECT(it->is_bool()); it++;
|
|
BEAST_EXPECT(it->is_string()); ++it;
|
|
BEAST_EXPECT(it == a.cend());
|
|
}
|
|
{
|
|
auto it = ac.begin();
|
|
BEAST_EXPECT(it->is_number()); ++it;
|
|
BEAST_EXPECT(it->is_bool()); it++;
|
|
BEAST_EXPECT(it->is_string()); ++it;
|
|
BEAST_EXPECT(it == ac.end());
|
|
}
|
|
{
|
|
auto it = a.end();
|
|
--it; BEAST_EXPECT(it->is_string());
|
|
it--; BEAST_EXPECT(it->is_bool());
|
|
--it; BEAST_EXPECT(it->is_number());
|
|
BEAST_EXPECT(it == a.begin());
|
|
}
|
|
{
|
|
auto it = a.cend();
|
|
--it; BEAST_EXPECT(it->is_string());
|
|
it--; BEAST_EXPECT(it->is_bool());
|
|
--it; BEAST_EXPECT(it->is_number());
|
|
BEAST_EXPECT(it == a.cbegin());
|
|
}
|
|
{
|
|
auto it = ac.end();
|
|
--it; BEAST_EXPECT(it->is_string());
|
|
it--; BEAST_EXPECT(it->is_bool());
|
|
--it; BEAST_EXPECT(it->is_number());
|
|
BEAST_EXPECT(it == ac.begin());
|
|
}
|
|
|
|
{
|
|
auto it = a.rbegin();
|
|
BEAST_EXPECT(it->is_string()); ++it;
|
|
BEAST_EXPECT(it->is_bool()); it++;
|
|
BEAST_EXPECT(it->is_number()); ++it;
|
|
BEAST_EXPECT(it == a.rend());
|
|
}
|
|
{
|
|
auto it = a.crbegin();
|
|
BEAST_EXPECT(it->is_string()); ++it;
|
|
BEAST_EXPECT(it->is_bool()); it++;
|
|
BEAST_EXPECT(it->is_number()); ++it;
|
|
BEAST_EXPECT(it == a.crend());
|
|
}
|
|
{
|
|
auto it = ac.rbegin();
|
|
BEAST_EXPECT(it->is_string()); ++it;
|
|
BEAST_EXPECT(it->is_bool()); it++;
|
|
BEAST_EXPECT(it->is_number()); ++it;
|
|
BEAST_EXPECT(it == ac.rend());
|
|
}
|
|
{
|
|
auto it = a.rend();
|
|
--it; BEAST_EXPECT(it->is_number());
|
|
it--; BEAST_EXPECT(it->is_bool());
|
|
--it; BEAST_EXPECT(it->is_string());
|
|
BEAST_EXPECT(it == a.rbegin());
|
|
}
|
|
{
|
|
auto it = a.crend();
|
|
--it; BEAST_EXPECT(it->is_number());
|
|
it--; BEAST_EXPECT(it->is_bool());
|
|
--it; BEAST_EXPECT(it->is_string());
|
|
BEAST_EXPECT(it == a.crbegin());
|
|
}
|
|
{
|
|
auto it = ac.rend();
|
|
--it; BEAST_EXPECT(it->is_number());
|
|
it--; BEAST_EXPECT(it->is_bool());
|
|
--it; BEAST_EXPECT(it->is_string());
|
|
BEAST_EXPECT(it == ac.rbegin());
|
|
}
|
|
|
|
{
|
|
array a2;
|
|
array const& ca2(a2);
|
|
BEAST_EXPECT(std::distance(
|
|
a2.begin(), a2.end()) == 0);
|
|
BEAST_EXPECT(std::distance(
|
|
ca2.begin(), ca2.end()) == 0);
|
|
BEAST_EXPECT(std::distance(
|
|
ca2.cbegin(), ca2.cend()) == 0);
|
|
BEAST_EXPECT(std::distance(
|
|
a2.rbegin(), a2.rend()) == 0);
|
|
BEAST_EXPECT(std::distance(
|
|
ca2.rbegin(), ca2.rend()) == 0);
|
|
BEAST_EXPECT(std::distance(
|
|
ca2.crbegin(), ca2.crend()) == 0);
|
|
}
|
|
}
|
|
|
|
void
|
|
testCapacity()
|
|
{
|
|
// empty()
|
|
{
|
|
{
|
|
array a;
|
|
BEAST_EXPECT(a.empty());
|
|
a.emplace_back(1);
|
|
BEAST_EXPECT(! a.empty());
|
|
}
|
|
|
|
{
|
|
array a({1, 2});
|
|
BEAST_EXPECT(! a.empty());
|
|
a.clear();
|
|
BEAST_EXPECT(a.empty());
|
|
BEAST_EXPECT(a.capacity() > 0);
|
|
}
|
|
}
|
|
|
|
// size()
|
|
{
|
|
array a;
|
|
BEAST_EXPECT(a.size() == 0);
|
|
a.emplace_back(1);
|
|
BEAST_EXPECT(a.size() == 1);
|
|
}
|
|
|
|
// max_size()
|
|
{
|
|
array a;
|
|
BEAST_EXPECT(a.max_size() > 0);
|
|
}
|
|
|
|
// reserve()
|
|
{
|
|
{
|
|
array a;
|
|
a.reserve(0);
|
|
}
|
|
|
|
{
|
|
array a(3);
|
|
a.reserve(1);
|
|
}
|
|
|
|
{
|
|
array a(3);
|
|
a.reserve(0);
|
|
}
|
|
|
|
{
|
|
array a;
|
|
a.reserve(50);
|
|
BEAST_EXPECT(a.capacity() >= 50);
|
|
}
|
|
}
|
|
|
|
// capacity()
|
|
{
|
|
array a;
|
|
BEAST_EXPECT(a.capacity() == 0);
|
|
}
|
|
|
|
// shrink_to_fit()
|
|
{
|
|
{
|
|
array a(1);
|
|
a.shrink_to_fit();
|
|
BEAST_EXPECT(a.size() == 1);
|
|
BEAST_EXPECT(a.capacity() >= 1);
|
|
}
|
|
|
|
{
|
|
array a({0, 1, 2, 3});
|
|
BEAST_EXPECT(a.capacity() > 3);
|
|
a.erase(a.begin(), a.begin() + 2);
|
|
a.shrink_to_fit();
|
|
BEAST_EXPECT(a.capacity() == 3);
|
|
}
|
|
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
array a(1, sp);
|
|
a.resize(a.capacity());
|
|
a.shrink_to_fit();
|
|
BEAST_EXPECT(a.size() == a.capacity());
|
|
});
|
|
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
array a(sp);
|
|
a.reserve(10);
|
|
BEAST_EXPECT(a.capacity() >= 10);
|
|
a.shrink_to_fit();
|
|
BEAST_EXPECT(a.capacity() == 0);
|
|
});
|
|
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
array a(3, sp);
|
|
a.reserve(10);
|
|
BEAST_EXPECT(a.capacity() >= 10);
|
|
a.shrink_to_fit();
|
|
if(a.capacity() > 3)
|
|
throw test_failure{};
|
|
});
|
|
}
|
|
}
|
|
|
|
void
|
|
testModifiers()
|
|
{
|
|
// clear
|
|
{
|
|
{
|
|
array a;
|
|
BEAST_EXPECT(a.size() == 0);
|
|
BEAST_EXPECT(a.capacity() == 0);
|
|
a.clear();
|
|
BEAST_EXPECT(a.size() == 0);
|
|
BEAST_EXPECT(a.capacity() == 0);
|
|
}
|
|
{
|
|
array a({1, true, str_});
|
|
a.clear();
|
|
BEAST_EXPECT(a.size() == 0);
|
|
BEAST_EXPECT(a.capacity() > 0);
|
|
}
|
|
}
|
|
|
|
// insert(const_iterator, value_type const&)
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
array a({1, str_}, sp);
|
|
value v(true);
|
|
a.insert(a.begin() + 1, v);
|
|
check(a);
|
|
check_storage(a, sp);
|
|
});
|
|
|
|
// insert(const_iterator, value_type&&)
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
array a({1, str_}, sp);
|
|
value v(true);
|
|
a.insert(
|
|
a.begin() + 1, std::move(v));
|
|
check(a);
|
|
check_storage(a, sp);
|
|
});
|
|
|
|
// insert(const_iterator, size_type, value_type const&)
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
value v({1,2,3});
|
|
array a({1, str_}, sp);
|
|
a.insert(a.begin() + 1, 3, v);
|
|
BEAST_EXPECT(a[0].is_number());
|
|
BEAST_EXPECT(a[1].as_array().size() == 3);
|
|
BEAST_EXPECT(a[2].as_array().size() == 3);
|
|
BEAST_EXPECT(a[3].as_array().size() == 3);
|
|
BEAST_EXPECT(a[4].is_string());
|
|
});
|
|
|
|
// insert(const_iterator, InputIt, InputIt)
|
|
{
|
|
// forward iterator
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
std::initializer_list<
|
|
value> init = {1, true};
|
|
array a({str_}, sp);
|
|
a.insert(a.begin(),
|
|
init.begin(), init.end());
|
|
check(a);
|
|
});
|
|
|
|
// forward iterator (multiple growth)
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
std::initializer_list<
|
|
value> init = {1, str_, true, 1, 2, 3, 4, 5, 6, 7};
|
|
array a(sp);
|
|
a.insert(a.begin(),
|
|
init.begin(), init.end());
|
|
});
|
|
|
|
// input iterator (empty range)
|
|
{
|
|
scoped_fail_storage fs;
|
|
std::initializer_list<value> init;
|
|
array a;
|
|
a.insert(a.begin(),
|
|
make_input_iterator(init.begin()),
|
|
make_input_iterator(init.end()));
|
|
BEAST_EXPECT(a.empty());
|
|
}
|
|
|
|
// input iterator
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
std::initializer_list<
|
|
value> init = {1, true};
|
|
array a({str_}, sp);
|
|
a.insert(a.begin(),
|
|
make_input_iterator(init.begin()),
|
|
make_input_iterator(init.end()));
|
|
check(a);
|
|
});
|
|
|
|
// input iterator (multiple growth)
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
std::initializer_list<
|
|
value> init = {1, true, 1, 2, 3, 4, 5, 6, 7};
|
|
array a({str_}, sp);
|
|
a.insert(a.begin(),
|
|
make_input_iterator(init.begin()),
|
|
make_input_iterator(init.end()));
|
|
BEAST_EXPECT(a.size() == init.size() + 1);
|
|
});
|
|
|
|
// backward relocate
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
std::initializer_list<
|
|
value> init = {1, 2};
|
|
array a({"a", "b", "c", "d", "e"}, sp);
|
|
a.insert(
|
|
a.begin() + 1,
|
|
init.begin(), init.end());
|
|
});
|
|
}
|
|
|
|
// insert(const_iterator, init_list)
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
array a({0, 3, 4}, sp);
|
|
auto it = a.insert(
|
|
a.begin() + 1, {1, str_});
|
|
BEAST_EXPECT(it == a.begin() + 1);
|
|
BEAST_EXPECT(a[0].as_number() == 0);
|
|
BEAST_EXPECT(a[1].as_number() == 1);
|
|
BEAST_EXPECT(a[2].as_string() == str_);
|
|
BEAST_EXPECT(a[3].as_number() == 3);
|
|
BEAST_EXPECT(a[4].as_number() == 4);
|
|
});
|
|
|
|
// emplace(const_iterator, arg)
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
array a({0, 2, 3, 4}, sp);
|
|
auto it = a.emplace(
|
|
a.begin() + 1, str_);
|
|
BEAST_EXPECT(it == a.begin() + 1);
|
|
BEAST_EXPECT(a[0].as_number() == 0);
|
|
BEAST_EXPECT(a[1].as_string() == str_);
|
|
BEAST_EXPECT(a[2].as_number() == 2);
|
|
BEAST_EXPECT(a[3].as_number() == 3);
|
|
BEAST_EXPECT(a[4].as_number() == 4);
|
|
});
|
|
|
|
// erase(pos)
|
|
{
|
|
array a({1, true, nullptr, str_});
|
|
a.erase(a.begin() + 2);
|
|
check(a);
|
|
}
|
|
|
|
// erase(first, last)
|
|
{
|
|
array a({1, true, nullptr, 1.f, str_});
|
|
a.erase(
|
|
a.begin() + 2,
|
|
a.begin() + 4);
|
|
check(a);
|
|
}
|
|
|
|
// push_back(value const&)
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
array a({1, true}, sp);
|
|
value v(str_);
|
|
a.push_back(v);
|
|
BEAST_EXPECT(
|
|
v.as_string() == str_);
|
|
check(a);
|
|
check_storage(a, sp);
|
|
});
|
|
|
|
// push_back(value&&)
|
|
{
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
array a({1, true}, sp);
|
|
value v(str_);
|
|
a.push_back(std::move(v));
|
|
check(a);
|
|
check_storage(a, sp);
|
|
});
|
|
}
|
|
|
|
// emplace_back(arg)
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
array a({1, true}, sp);
|
|
a.emplace_back(str_);
|
|
check(a);
|
|
check_storage(a, sp);
|
|
});
|
|
|
|
// pop_back()
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
array a({1, true, str_, nullptr}, sp);
|
|
a.pop_back();
|
|
check(a);
|
|
check_storage(a, sp);
|
|
});
|
|
|
|
// resize(size_type)
|
|
{
|
|
value v(array{});
|
|
v.as_array().emplace_back(1);
|
|
v.as_array().emplace_back(true);
|
|
v.as_array().emplace_back(str_);
|
|
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
array a(5, sp);
|
|
a.resize(3);
|
|
BEAST_EXPECT(a.size() == 3);
|
|
check_storage(a, sp);
|
|
});
|
|
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
array a(sp);
|
|
a.resize(3);
|
|
BEAST_EXPECT(a.size() == 3);
|
|
check_storage(a, sp);
|
|
});
|
|
}
|
|
|
|
// resize(size_type, value_type const&)
|
|
{
|
|
value v(array{});
|
|
v.as_array().emplace_back(1);
|
|
v.as_array().emplace_back(true);
|
|
v.as_array().emplace_back(str_);
|
|
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
array a(5, v, sp);
|
|
a.resize(3, v);
|
|
BEAST_EXPECT(a.size() == 3);
|
|
check_storage(a, sp);
|
|
});
|
|
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
array a(3, v, sp);
|
|
a.resize(5, v);
|
|
BEAST_EXPECT(a.size() == 5);
|
|
check_storage(a, sp);
|
|
});
|
|
}
|
|
|
|
// swap
|
|
{
|
|
// same storage
|
|
{
|
|
array a1({1, true, str_});
|
|
array a2 = {1.};
|
|
scoped_fail_storage fs;
|
|
a1.swap(a2);
|
|
check(a2);
|
|
BEAST_EXPECT(a1.size() == 1);
|
|
BEAST_EXPECT(a1.front().is_number());
|
|
BEAST_EXPECT(a1.front().as_number().get_double() == 1.);
|
|
}
|
|
|
|
// different storage
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
array a1({1, true, str_}, sp);
|
|
array a2 = {1.};
|
|
a1.swap(a2);
|
|
check(a2);
|
|
BEAST_EXPECT(a1.size() == 1);
|
|
});
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
array a1 = {1.};
|
|
array a2({1, true, str_}, sp);
|
|
a1.swap(a2);
|
|
check(a1);
|
|
BEAST_EXPECT(a2.size() == 1);
|
|
});
|
|
}
|
|
}
|
|
|
|
void
|
|
testExceptions()
|
|
{
|
|
// operator=(array const&)
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
array a0({1, true, str_});
|
|
array a1;
|
|
array a(sp);
|
|
a.emplace_back(nullptr);
|
|
a = a0;
|
|
a1 = a;
|
|
check(a1);
|
|
});
|
|
|
|
// operator=(init_list)
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
init_list init{ 1, true, str_ };
|
|
array a1;
|
|
array a(sp);
|
|
a.emplace_back(nullptr);
|
|
a = init;
|
|
a1 = a;
|
|
check(a1);
|
|
});
|
|
|
|
// insert(const_iterator, count, value_type const&)
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
array a1;
|
|
array a({1, true}, sp);
|
|
a.insert(a.begin() + 1,
|
|
3, value(kind::null));
|
|
a1 = a;
|
|
BEAST_EXPECT(a1.size() == 5);
|
|
BEAST_EXPECT(a1[0].is_number());
|
|
BEAST_EXPECT(a1[1].is_null());
|
|
BEAST_EXPECT(a1[2].is_null());
|
|
BEAST_EXPECT(a1[3].is_null());
|
|
BEAST_EXPECT(a1[4].is_bool());
|
|
});
|
|
|
|
// insert(const_iterator, InputIt, InputIt)
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
init_list init{ 1, true, str_ };
|
|
array a1;
|
|
array a(sp);
|
|
a.insert(a.end(),
|
|
init.begin(), init.end());
|
|
a1 = a;
|
|
check(a1);
|
|
});
|
|
|
|
// emplace(const_iterator, arg)
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
array a1;
|
|
array a({1, nullptr}, sp);
|
|
a.emplace(a.begin() + 1, true);
|
|
a1 = a;
|
|
BEAST_EXPECT(a1.size() == 3);
|
|
BEAST_EXPECT(a1[0].is_number());
|
|
BEAST_EXPECT(a1[1].is_bool());
|
|
BEAST_EXPECT(a1[2].is_null());
|
|
});
|
|
|
|
// emplace(const_iterator, arg)
|
|
fail_loop([&](storage_ptr const& sp)
|
|
{
|
|
array a1;
|
|
array a({1, str_}, sp);
|
|
a.emplace(a.begin() + 1, true);
|
|
a1 = a;
|
|
check(a1);
|
|
BEAST_EXPECT(a1.size() == 3);
|
|
BEAST_EXPECT(a1[0].is_number());
|
|
BEAST_EXPECT(a1[1].is_bool());
|
|
BEAST_EXPECT(a1[2].is_string());
|
|
});
|
|
}
|
|
|
|
void
|
|
run() override
|
|
{
|
|
testCtors();
|
|
testAssignment();
|
|
testGetStorage();
|
|
testAccess();
|
|
testIterators();
|
|
testCapacity();
|
|
testModifiers();
|
|
testExceptions();
|
|
}
|
|
};
|
|
|
|
BEAST_DEFINE_TESTSUITE(boost,json,array);
|
|
|
|
} // json
|
|
} // boost
|