mirror of
https://github.com/boostorg/json.git
synced 2025-05-11 13:44:06 +00:00
Refactor storage
This commit is contained in:
parent
e73d4886ea
commit
b82419c1a4
@ -52,7 +52,7 @@ public:
|
||||
}
|
||||
|
||||
void*
|
||||
allocate(
|
||||
do_allocate(
|
||||
std::size_t n,
|
||||
std::size_t align) override
|
||||
{
|
||||
@ -60,7 +60,7 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
deallocate(
|
||||
do_deallocate(
|
||||
void* p,
|
||||
std::size_t n,
|
||||
std::size_t align) noexcept override
|
||||
@ -69,7 +69,7 @@ public:
|
||||
}
|
||||
|
||||
bool
|
||||
is_equal(storage const& other) const noexcept override
|
||||
do_is_equal(storage const& other) const noexcept override
|
||||
{
|
||||
return this == dynamic_cast<
|
||||
pool_storage const*>(&other);
|
||||
|
@ -19,73 +19,6 @@ namespace json {
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
namespace detail {
|
||||
|
||||
storage_ptr const&
|
||||
global_storage() noexcept
|
||||
{
|
||||
struct builtin : storage
|
||||
{
|
||||
void*
|
||||
allocate(
|
||||
std::size_t n,
|
||||
std::size_t) override
|
||||
{
|
||||
return std::allocator<
|
||||
char>().allocate(n);
|
||||
}
|
||||
|
||||
void
|
||||
deallocate(
|
||||
void* p,
|
||||
std::size_t n,
|
||||
std::size_t) noexcept override
|
||||
{
|
||||
std::allocator<
|
||||
char>().deallocate(
|
||||
static_cast<char*>(p), n);
|
||||
}
|
||||
|
||||
bool
|
||||
is_equal(storage const& other)
|
||||
const noexcept override
|
||||
{
|
||||
(void)other;
|
||||
BOOST_JSON_ASSERT(dynamic_cast<
|
||||
builtin const*>(&other) == nullptr);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
static storage_ptr const sp =
|
||||
make_storage<builtin>();
|
||||
return sp;
|
||||
}
|
||||
|
||||
inline
|
||||
storage_ptr&
|
||||
raw_default_storage() noexcept
|
||||
{
|
||||
static storage_ptr sp =
|
||||
global_storage();
|
||||
return sp;
|
||||
}
|
||||
|
||||
} // detail
|
||||
|
||||
storage_ptr
|
||||
default_storage() noexcept
|
||||
{
|
||||
return detail::raw_default_storage();
|
||||
}
|
||||
|
||||
void
|
||||
default_storage(storage_ptr sp) noexcept
|
||||
{
|
||||
detail::raw_default_storage() = std::move(sp);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
void
|
||||
storage::
|
||||
addref() noexcept
|
||||
@ -108,6 +41,48 @@ storage() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
storage_ptr const&
|
||||
default_storage() noexcept
|
||||
{
|
||||
struct builtin : storage
|
||||
{
|
||||
void*
|
||||
do_allocate(
|
||||
std::size_t n,
|
||||
std::size_t) override
|
||||
{
|
||||
return std::allocator<
|
||||
char>().allocate(n);
|
||||
}
|
||||
|
||||
void
|
||||
do_deallocate(
|
||||
void* p,
|
||||
std::size_t n,
|
||||
std::size_t) noexcept override
|
||||
{
|
||||
std::allocator<
|
||||
char>().deallocate(
|
||||
static_cast<char*>(p), n);
|
||||
}
|
||||
|
||||
bool
|
||||
do_is_equal(storage const& other)
|
||||
const noexcept override
|
||||
{
|
||||
(void)other;
|
||||
BOOST_JSON_ASSERT(dynamic_cast<
|
||||
builtin const*>(&other) == nullptr);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
static storage_ptr const sp =
|
||||
make_storage<builtin>();
|
||||
return sp;
|
||||
}
|
||||
|
||||
} // json
|
||||
} // boost
|
||||
|
||||
|
@ -136,11 +136,12 @@ insert(
|
||||
};
|
||||
|
||||
impl tmp;
|
||||
// We use the global storage since
|
||||
// it is a temporary deallocated here.
|
||||
tmp.construct(first, last,
|
||||
detail::global_storage(),
|
||||
default_storage(),
|
||||
iter_cat<InputIt>{});
|
||||
cleanup c{tmp,
|
||||
detail::global_storage()};
|
||||
cleanup c{tmp, default_storage()};
|
||||
auto const off = pos - s_.data();
|
||||
traits_type::copy(
|
||||
s_.insert(off, tmp.size, sp_),
|
||||
@ -219,11 +220,12 @@ append(
|
||||
};
|
||||
|
||||
impl tmp;
|
||||
// We use the global storage since
|
||||
// it is a temporary deallocated here.
|
||||
tmp.construct(first, last,
|
||||
detail::global_storage(),
|
||||
default_storage(),
|
||||
std::input_iterator_tag{});
|
||||
cleanup c{tmp,
|
||||
detail::global_storage()};
|
||||
cleanup c{tmp, default_storage()};
|
||||
traits_type::copy(
|
||||
s_.append(tmp.size, sp_),
|
||||
tmp.data(), tmp.size);
|
||||
|
@ -47,25 +47,31 @@ public:
|
||||
virtual
|
||||
~storage() = default;
|
||||
|
||||
virtual
|
||||
void*
|
||||
allocate(
|
||||
std::size_t n,
|
||||
std::size_t align =
|
||||
max_align) = 0;
|
||||
max_align)
|
||||
{
|
||||
return do_allocate(n, align);
|
||||
}
|
||||
|
||||
virtual
|
||||
void
|
||||
deallocate(
|
||||
void* p,
|
||||
std::size_t n,
|
||||
std::size_t align =
|
||||
max_align) noexcept = 0;
|
||||
max_align)
|
||||
{
|
||||
return do_deallocate(p, n, align);
|
||||
}
|
||||
|
||||
virtual
|
||||
bool
|
||||
is_equal(
|
||||
storage const& other) const noexcept = 0;
|
||||
storage const& other) const noexcept
|
||||
{
|
||||
return do_is_equal(other);
|
||||
}
|
||||
|
||||
friend
|
||||
bool
|
||||
@ -84,6 +90,26 @@ public:
|
||||
{
|
||||
return &lhs != &rhs && ! lhs.is_equal(rhs);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual
|
||||
void*
|
||||
do_allocate(
|
||||
std::size_t n,
|
||||
std::size_t align) = 0;
|
||||
|
||||
virtual
|
||||
void
|
||||
do_deallocate(
|
||||
void* p,
|
||||
std::size_t n,
|
||||
std::size_t align) noexcept = 0;
|
||||
|
||||
virtual
|
||||
bool
|
||||
do_is_equal(
|
||||
storage const& other) const noexcept = 0;
|
||||
|
||||
};
|
||||
|
||||
//----------------------------------------------------------
|
||||
@ -481,12 +507,12 @@ using storage_ptr = basic_storage_ptr<storage>;
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
/** Return a pointer to the current default storage
|
||||
/** Return a pointer to the default storage
|
||||
|
||||
This function returns a pointer to the current default storage.
|
||||
This default storage is used when constructing
|
||||
any @ref value, @ref object, @ref array, or @ref string
|
||||
and the storage is not explicitly specified.
|
||||
This function returns the default storage, which is
|
||||
used when constructing a container without explicitly
|
||||
specifying the storage. The default storage uses the
|
||||
global allocator, equivalent to `std::allocator<char>`.
|
||||
|
||||
@par Complexity
|
||||
|
||||
@ -498,38 +524,12 @@ using storage_ptr = basic_storage_ptr<storage>;
|
||||
|
||||
@par Thread Safety
|
||||
|
||||
May not be called concurrently with
|
||||
`void default_storage(storage_ptr)`.
|
||||
May be called concurrently.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
storage_ptr
|
||||
storage_ptr const&
|
||||
default_storage() noexcept;
|
||||
|
||||
/** Set the current default storage
|
||||
|
||||
This function changes the current default storage pointer.
|
||||
This default storage is used when constructing
|
||||
any @ref value, @ref object, @ref array, or @ref string
|
||||
and the storage is not explicitly specified.
|
||||
|
||||
@par Complexity
|
||||
|
||||
Constant.
|
||||
|
||||
@par Exception Safety
|
||||
|
||||
No-throw guarantee.
|
||||
|
||||
@par Thread Safety
|
||||
|
||||
May not be called concurrently with
|
||||
`void default_storage()` or
|
||||
`void default_storage(storage_ptr)`.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
void
|
||||
default_storage(storage_ptr sp) noexcept;
|
||||
|
||||
} // json
|
||||
} // boost
|
||||
|
||||
|
@ -62,7 +62,6 @@ public:
|
||||
|
||||
// array()
|
||||
{
|
||||
scoped_fail_storage fs;
|
||||
array a;
|
||||
BEAST_EXPECT(a.empty());
|
||||
BEAST_EXPECT(a.size() == 0);
|
||||
@ -70,7 +69,6 @@ public:
|
||||
|
||||
// array(storage_ptr)
|
||||
{
|
||||
scoped_fail_storage fs;
|
||||
array a(default_storage());
|
||||
check_storage(a, default_storage());
|
||||
}
|
||||
@ -103,19 +101,20 @@ public:
|
||||
// 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);
|
||||
for(auto const& v : a)
|
||||
BEAST_EXPECT(v.is_null());
|
||||
check_storage(a, sp);
|
||||
});
|
||||
}
|
||||
@ -123,7 +122,6 @@ public:
|
||||
// array(InputIt, InputIt, storage)
|
||||
{
|
||||
// default storage
|
||||
fail_loop([&]
|
||||
{
|
||||
init_list init{ 0, 1, str_, 3, 4 };
|
||||
array a(init.begin(), init.end());
|
||||
@ -133,7 +131,7 @@ public:
|
||||
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)
|
||||
@ -169,14 +167,13 @@ public:
|
||||
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)
|
||||
@ -185,7 +182,7 @@ public:
|
||||
init_list init{ 1, true, str_ };
|
||||
array a1(init.begin(), init.end());
|
||||
array a2(a1, sp);
|
||||
BEAST_EXPECT(a2.size() == 3);
|
||||
check(a2);
|
||||
check_storage(a2, sp);
|
||||
});
|
||||
|
||||
@ -357,7 +354,6 @@ public:
|
||||
// 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());
|
||||
@ -375,7 +371,6 @@ public:
|
||||
// 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());
|
||||
@ -393,7 +388,6 @@ public:
|
||||
// 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());
|
||||
@ -402,7 +396,6 @@ public:
|
||||
// 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());
|
||||
@ -411,28 +404,24 @@ public:
|
||||
// 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());
|
||||
}
|
||||
|
||||
@ -440,7 +429,6 @@ public:
|
||||
{
|
||||
{
|
||||
array a({1, true, str_});
|
||||
scoped_fail_storage fs;
|
||||
BEAST_EXPECT(a.data() == &a[0]);
|
||||
}
|
||||
{
|
||||
@ -452,7 +440,6 @@ public:
|
||||
{
|
||||
{
|
||||
array const a({1, true, str_});
|
||||
scoped_fail_storage fs;
|
||||
BEAST_EXPECT(a.data() == &a[0]);
|
||||
}
|
||||
{
|
||||
@ -763,7 +750,6 @@ public:
|
||||
|
||||
// input iterator (empty range)
|
||||
{
|
||||
scoped_fail_storage fs;
|
||||
std::initializer_list<value> init;
|
||||
array a;
|
||||
a.insert(a.begin(),
|
||||
@ -948,7 +934,6 @@ public:
|
||||
{
|
||||
array a1({1, true, str_});
|
||||
array a2 = {1.};
|
||||
scoped_fail_storage fs;
|
||||
a1.swap(a2);
|
||||
check(a2);
|
||||
BEAST_EXPECT(a1.size() == 1);
|
||||
|
124
test/object.cpp
124
test/object.cpp
@ -120,7 +120,6 @@ public:
|
||||
|
||||
// object()
|
||||
{
|
||||
scoped_fail_storage fs;
|
||||
object o;
|
||||
BEAST_EXPECT(o.empty());
|
||||
BEAST_EXPECT(o.size() == 0);
|
||||
@ -135,13 +134,12 @@ public:
|
||||
});
|
||||
|
||||
// object(size_type)
|
||||
fail_loop([&]
|
||||
{
|
||||
object o(50);
|
||||
BEAST_EXPECT(o.empty());
|
||||
BEAST_EXPECT(o.size() == 0);
|
||||
BEAST_EXPECT(o.capacity() == 53);
|
||||
});
|
||||
}
|
||||
|
||||
// object(size_type, storage_ptr)
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
@ -155,7 +153,6 @@ public:
|
||||
|
||||
// object(InputIt, InputIt, size_type, storage_ptr)
|
||||
{
|
||||
fail_loop([&]
|
||||
{
|
||||
std::initializer_list<std::pair<
|
||||
string_view, value>> init = {
|
||||
@ -164,9 +161,8 @@ public:
|
||||
{"c", "hello"}};
|
||||
object o(init.begin(), init.end());
|
||||
check(o, 3);
|
||||
});
|
||||
}
|
||||
|
||||
fail_loop([&]
|
||||
{
|
||||
std::initializer_list<std::pair<
|
||||
string_view, value>> init = {
|
||||
@ -175,7 +171,7 @@ public:
|
||||
{"c", "hello"}};
|
||||
object o(init.begin(), init.end(), 5);
|
||||
check(o, 7);
|
||||
});
|
||||
}
|
||||
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
@ -203,7 +199,6 @@ public:
|
||||
check(obj1, 3);
|
||||
auto const sp =
|
||||
default_storage();
|
||||
scoped_fail_storage fs;
|
||||
object obj2(std::move(obj1));
|
||||
BEAST_EXPECT(obj1.empty());
|
||||
BEAST_EXPECT(obj1.size() == 0);
|
||||
@ -219,7 +214,6 @@ public:
|
||||
{"b", true},
|
||||
{"c", "hello"}
|
||||
});
|
||||
scoped_fail_storage fs;
|
||||
object obj2(pilfer(obj1));
|
||||
BEAST_EXPECT(
|
||||
obj1.get_storage() == nullptr);
|
||||
@ -247,7 +241,6 @@ public:
|
||||
});
|
||||
|
||||
// object(object const&)
|
||||
fail_loop([&]
|
||||
{
|
||||
object obj1({
|
||||
{"a", 1},
|
||||
@ -257,7 +250,7 @@ public:
|
||||
object obj2(obj1);
|
||||
BEAST_EXPECT(! obj1.empty());
|
||||
check(obj2, 3);
|
||||
});
|
||||
}
|
||||
|
||||
// object(object const&, storage_ptr)
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
@ -274,7 +267,6 @@ public:
|
||||
});
|
||||
|
||||
// object(initializer_list)
|
||||
fail_loop([&]
|
||||
{
|
||||
object o({
|
||||
{"a", 1},
|
||||
@ -282,10 +274,9 @@ public:
|
||||
{"c", "hello"}
|
||||
});
|
||||
check(o, 3);
|
||||
});
|
||||
}
|
||||
|
||||
// object(initializer_list, size_type)
|
||||
fail_loop([&]
|
||||
{
|
||||
object o({
|
||||
{"a", 1},
|
||||
@ -294,7 +285,7 @@ public:
|
||||
},
|
||||
5);
|
||||
check(o, 7);
|
||||
});
|
||||
}
|
||||
|
||||
// object(initializer_list, storage_ptr)
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
@ -310,6 +301,7 @@ public:
|
||||
});
|
||||
|
||||
// object(initializer_list, size_type, storage_ptr)
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
object o({
|
||||
{"a", 1},
|
||||
@ -320,7 +312,7 @@ public:
|
||||
BEAST_EXPECT(
|
||||
*o.get_storage() == *sp);
|
||||
check(o, 7);
|
||||
}
|
||||
});
|
||||
|
||||
// operator=(object&&)
|
||||
{
|
||||
@ -357,7 +349,6 @@ public:
|
||||
|
||||
// operator=(object const&)
|
||||
{
|
||||
fail_loop([&]
|
||||
{
|
||||
object obj1({
|
||||
{"a", 1},
|
||||
@ -371,7 +362,7 @@ public:
|
||||
default_storage());
|
||||
check_storage(obj2,
|
||||
default_storage());
|
||||
});
|
||||
}
|
||||
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
@ -391,7 +382,6 @@ public:
|
||||
|
||||
// operator=(initializer_list)
|
||||
{
|
||||
fail_loop([&]
|
||||
{
|
||||
object o;
|
||||
o = {
|
||||
@ -401,7 +391,7 @@ public:
|
||||
check(o, 3);
|
||||
check_storage(o,
|
||||
default_storage());
|
||||
});
|
||||
}
|
||||
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
@ -515,9 +505,9 @@ public:
|
||||
}
|
||||
|
||||
// insert(value_type&&)
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
object o;
|
||||
object o(sp);
|
||||
auto v = object::value_type("a", 1);
|
||||
auto result = o.insert(std::move(v));
|
||||
BEAST_EXPECT(result.second);
|
||||
@ -530,9 +520,9 @@ public:
|
||||
});
|
||||
|
||||
// insert(value_type const&)
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
object o;
|
||||
object o(sp);
|
||||
auto v = object::value_type("a", 1);
|
||||
auto result = o.insert(v);
|
||||
BEAST_EXPECT(! v.second.is_null());
|
||||
@ -546,9 +536,9 @@ public:
|
||||
|
||||
// insert(P&&)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
object o;
|
||||
object o(sp);
|
||||
auto result = o.insert(
|
||||
std::make_pair("x", 1));
|
||||
BEAST_EXPECT(result.second);
|
||||
@ -556,9 +546,9 @@ public:
|
||||
BEAST_EXPECT(result.first->second.as_number() == 1);
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
object o;
|
||||
object o(sp);
|
||||
auto const p = std::make_pair("x", 1);
|
||||
auto result = o.insert(p);
|
||||
BEAST_EXPECT(result.second);
|
||||
@ -568,9 +558,9 @@ public:
|
||||
}
|
||||
|
||||
// insert(before, value_type const&)
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
object o;
|
||||
object o(sp);
|
||||
o.emplace("a", 1);
|
||||
o.emplace("c", "hello");
|
||||
object::value_type const p("b", true);
|
||||
@ -579,9 +569,9 @@ public:
|
||||
});
|
||||
|
||||
// insert(before, value_type&&)
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
object o;
|
||||
object o(sp);
|
||||
o.emplace("a", 1);
|
||||
o.emplace("c", "hello");
|
||||
o.insert(o.find("c"), { "b", true });
|
||||
@ -590,9 +580,9 @@ public:
|
||||
|
||||
// insert(before, P&&)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
object o;
|
||||
object o(sp);
|
||||
o.emplace("a", 1);
|
||||
o.emplace("c", "hello");
|
||||
o.insert(o.find("c"),
|
||||
@ -600,9 +590,9 @@ public:
|
||||
check(o, 3);
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
object o;
|
||||
object o(sp);
|
||||
o.emplace("a", 1);
|
||||
o.emplace("c", "hello");
|
||||
auto const p =
|
||||
@ -613,34 +603,34 @@ public:
|
||||
}
|
||||
|
||||
// insert(InputIt, InputIt)
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
std::initializer_list<std::pair<
|
||||
string_view, value>> init = {
|
||||
{"a", 1},
|
||||
{"b", true},
|
||||
{"c", "hello"}};
|
||||
object o;
|
||||
object o(sp);
|
||||
o.insert(init.begin(), init.end());
|
||||
check(o, 3);
|
||||
});
|
||||
|
||||
// insert(InputIt, InputIt)
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
std::initializer_list<std::pair<
|
||||
string_view, value>> init = {
|
||||
{"b", true}};
|
||||
object o({{"a", 1}, {"c", "hello"}});
|
||||
object o({{"a", 1}, {"c", "hello"}}, sp);
|
||||
o.insert(++o.begin(),
|
||||
init.begin(), init.end());
|
||||
check(o, 3);
|
||||
});
|
||||
|
||||
// insert(initializer_list)
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
object o;
|
||||
object o(sp);
|
||||
o.emplace("a", 1);
|
||||
o.insert({
|
||||
{ "b", true },
|
||||
@ -649,9 +639,9 @@ public:
|
||||
});
|
||||
|
||||
// insert(before, initializer_list)
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
object o;
|
||||
object o(sp);
|
||||
o.emplace("c", "hello");
|
||||
o.insert(
|
||||
o.find("c"),
|
||||
@ -664,35 +654,35 @@ public:
|
||||
|
||||
// insert_or_assign(key, o);
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
object o({{"a", 1}});
|
||||
object o({{"a", 1}}, sp);
|
||||
o.insert_or_assign("a", str_);
|
||||
BEAST_EXPECT(o["a"].is_string());
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
object o({
|
||||
{"a", 1},
|
||||
{"b", 2},
|
||||
{"c", 3}});
|
||||
{"c", 3}}, sp);
|
||||
o.insert_or_assign("d", str_);
|
||||
BEAST_EXPECT(o["d"].is_string());
|
||||
BEAST_EXPECT(o.size() == 4);
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
object o({{"a", 1}});
|
||||
object o({{"a", 1}}, sp);
|
||||
o.insert_or_assign("b", true);
|
||||
o.insert_or_assign("c", "hello");
|
||||
check(o, 3);
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
object o({{"a", 1}});
|
||||
object o({{"a", 1}}, sp);
|
||||
BEAST_EXPECT(
|
||||
! o.insert_or_assign("a", 2).second);
|
||||
BEAST_EXPECT(o["a"].as_number() == 2);
|
||||
@ -701,17 +691,17 @@ public:
|
||||
|
||||
// insert_or_assign(before, key, o);
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
object o({{"a", 1}});
|
||||
object o({{"a", 1}}, sp);
|
||||
o.insert_or_assign("c", "hello");
|
||||
o.insert_or_assign(o.find("c"), "b", true);
|
||||
check(o, 3);
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
object o({{"a", 1}});
|
||||
object o({{"a", 1}}, sp);
|
||||
o.insert_or_assign("b", true);
|
||||
o.insert_or_assign("c", "hello");
|
||||
BEAST_EXPECT(! o.insert_or_assign(
|
||||
@ -721,9 +711,9 @@ public:
|
||||
}
|
||||
|
||||
// emplace(key, arg)
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
object o;
|
||||
object o(sp);
|
||||
o.emplace("a", 1);
|
||||
o.emplace("b", true);
|
||||
o.emplace("c", "hello");
|
||||
@ -731,9 +721,9 @@ public:
|
||||
});
|
||||
|
||||
// emplace(before, key, arg)
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
object o;
|
||||
object o(sp);
|
||||
o.emplace("a", 1);
|
||||
o.emplace("c", "hello");
|
||||
o.emplace(o.find("c"), "b", true);
|
||||
@ -742,13 +732,13 @@ public:
|
||||
|
||||
// erase(pos)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
object o({
|
||||
{"d", nullptr },
|
||||
{"a", 1},
|
||||
{"b", true},
|
||||
{"c", "hello"}});
|
||||
{"c", "hello"}}, sp);
|
||||
auto it = o.erase(o.begin());
|
||||
BEAST_EXPECT(it->first == "a");
|
||||
BEAST_EXPECT(it->second.as_number() == 1);
|
||||
@ -757,7 +747,7 @@ public:
|
||||
}
|
||||
|
||||
// erase(first, last)
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
object o({
|
||||
{"a", 1},
|
||||
@ -765,7 +755,7 @@ public:
|
||||
{"b2", 2},
|
||||
{"b3", 3},
|
||||
{"b4", 4},
|
||||
{"c", "hello"}});
|
||||
{"c", "hello"}}, sp);
|
||||
auto first = o.find("b2");
|
||||
auto last = std::next(first, 3);
|
||||
auto it = o.erase(first, last);
|
||||
@ -782,7 +772,6 @@ public:
|
||||
{"a", 1},
|
||||
{"b", true},
|
||||
{"c", "hello"}});
|
||||
scoped_fail_storage fs;
|
||||
BEAST_EXPECT(o.erase("b2") == 0);
|
||||
check(o, 3);
|
||||
}
|
||||
@ -793,7 +782,6 @@ public:
|
||||
{"b", true},
|
||||
{"b2", 2},
|
||||
{"c", "hello"}});
|
||||
scoped_fail_storage fs;
|
||||
BEAST_EXPECT(o.erase("b2") == 1);
|
||||
check(o, 7);
|
||||
}
|
||||
@ -804,7 +792,6 @@ public:
|
||||
{
|
||||
object o1 = {{"a",1}, {"b",true}, {"c", "hello"}};
|
||||
object o2 = {{"d",{1,2,3}}};
|
||||
scoped_fail_storage fs;
|
||||
swap(o1, o2);
|
||||
BEAST_EXPECT(o1.size() == 1);
|
||||
BEAST_EXPECT(o2.size() == 3);
|
||||
@ -861,7 +848,6 @@ public:
|
||||
}
|
||||
|
||||
// operator[&](key)
|
||||
fail_loop([&]
|
||||
{
|
||||
object o({
|
||||
{"a", 1},
|
||||
@ -871,7 +857,7 @@ public:
|
||||
BEAST_EXPECT(o["a"].is_number());
|
||||
BEAST_EXPECT(o["d"].is_null());
|
||||
BEAST_EXPECT(o.count("d") == 1);
|
||||
});
|
||||
}
|
||||
|
||||
// count(key)
|
||||
{
|
||||
|
@ -28,7 +28,7 @@ public:
|
||||
}
|
||||
|
||||
void*
|
||||
allocate(
|
||||
do_allocate(
|
||||
std::size_t,
|
||||
std::size_t) override
|
||||
{
|
||||
@ -36,7 +36,7 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
deallocate(
|
||||
do_deallocate(
|
||||
void*,
|
||||
std::size_t,
|
||||
std::size_t) noexcept override
|
||||
@ -44,7 +44,7 @@ public:
|
||||
}
|
||||
|
||||
bool
|
||||
is_equal(
|
||||
do_is_equal(
|
||||
storage const&)
|
||||
const noexcept override
|
||||
{
|
||||
@ -182,7 +182,7 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
testFree()
|
||||
testDefaultStorage()
|
||||
{
|
||||
// default_storage()
|
||||
{
|
||||
@ -190,15 +190,6 @@ public:
|
||||
auto sp2 = default_storage();
|
||||
BEAST_EXPECT(*sp1 == *sp2);
|
||||
}
|
||||
|
||||
// default_storage(storage_ptr)
|
||||
{
|
||||
auto sp1 = default_storage();
|
||||
auto sp2 = make_storage<unique_storage>();
|
||||
default_storage(sp2);
|
||||
BEAST_EXPECT(*default_storage() == *sp2);
|
||||
default_storage(sp1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -206,7 +197,7 @@ public:
|
||||
{
|
||||
testMembers();
|
||||
testRelational();
|
||||
testFree();
|
||||
testDefaultStorage();
|
||||
}
|
||||
};
|
||||
|
||||
|
361
test/string.cpp
361
test/string.cpp
@ -63,16 +63,16 @@ public:
|
||||
|
||||
// string()
|
||||
{
|
||||
scoped_fail_storage fs;
|
||||
string s;
|
||||
}
|
||||
|
||||
// string(storage_ptr)
|
||||
{
|
||||
scoped_fail_storage fs;
|
||||
string s(fs.get());
|
||||
{
|
||||
auto const sp =
|
||||
make_storage<unique_storage>();
|
||||
string s(sp);
|
||||
BEAST_EXPECT(s.empty());
|
||||
BEAST_EXPECT(*s.get_storage() == *fs.get());
|
||||
BEAST_EXPECT(*s.get_storage() == *sp.get());
|
||||
}
|
||||
|
||||
// string(size_type, char, storage_ptr)
|
||||
@ -83,11 +83,10 @@ public:
|
||||
BEAST_EXPECT(s == std::string(t.v1.size(), '*'));
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
{
|
||||
string s(t.v2.size(), '*');
|
||||
BEAST_EXPECT(s == std::string(t.v2.size(), '*'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// string(string const&, size_type, size_type, storage_ptr)
|
||||
@ -98,17 +97,15 @@ public:
|
||||
BEAST_EXPECT(s == "bcd");
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
{
|
||||
string s(string(t.v1), 1, 3);
|
||||
BEAST_EXPECT(s == "bcd");
|
||||
});
|
||||
}
|
||||
|
||||
fail_loop([&]
|
||||
{
|
||||
string s(string(t.v1), 1);
|
||||
BEAST_EXPECT(s == t.v1.substr(1));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// string(char const*, storage_ptr)
|
||||
@ -125,17 +122,15 @@ public:
|
||||
BEAST_EXPECT(s == t.v2);
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
{
|
||||
string s(t.s1.c_str());
|
||||
BEAST_EXPECT(s == t.v1);
|
||||
});
|
||||
}
|
||||
|
||||
fail_loop([&]
|
||||
{
|
||||
string s(t.s2.c_str());
|
||||
BEAST_EXPECT(s == t.v2);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// string(char const*, size_type, storage_ptr)
|
||||
@ -152,17 +147,15 @@ public:
|
||||
BEAST_EXPECT(s == "ABC");
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
{
|
||||
string s(t.s1.c_str(), 3);
|
||||
BEAST_EXPECT(s == "abc");
|
||||
});
|
||||
}
|
||||
|
||||
fail_loop([&]
|
||||
{
|
||||
string s(t.s2.c_str(), 3);
|
||||
BEAST_EXPECT(s == "ABC");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// string(InputIt, InputIt, storage_ptr)
|
||||
@ -195,48 +188,42 @@ public:
|
||||
BEAST_EXPECT(s == t.v2);
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
{
|
||||
string s(t.v1.begin(), t.v1.end());
|
||||
BEAST_EXPECT(s == t.v1);
|
||||
});
|
||||
}
|
||||
|
||||
fail_loop([&]
|
||||
{
|
||||
string s(t.v2.begin(), t.v2.end());
|
||||
BEAST_EXPECT(s == t.v2);
|
||||
});
|
||||
}
|
||||
|
||||
fail_loop([&]
|
||||
{
|
||||
string s(
|
||||
make_input_iterator(t.v1.begin()),
|
||||
make_input_iterator(t.v1.end()));
|
||||
BEAST_EXPECT(s == t.v1);
|
||||
});
|
||||
}
|
||||
|
||||
fail_loop([&]
|
||||
{
|
||||
string s(
|
||||
make_input_iterator(t.v2.begin()),
|
||||
make_input_iterator(t.v2.end()));
|
||||
BEAST_EXPECT(s == t.v2);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// string(string)
|
||||
{
|
||||
fail_loop([&]
|
||||
{
|
||||
string s(string(t.v1));
|
||||
BEAST_EXPECT(s == t.v1);
|
||||
});
|
||||
}
|
||||
|
||||
fail_loop([&]
|
||||
{
|
||||
string s(string(t.v2));
|
||||
BEAST_EXPECT(s == t.v2);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// string(string, storage_ptr)
|
||||
@ -279,7 +266,6 @@ public:
|
||||
{
|
||||
{
|
||||
string s1(t.v1);
|
||||
scoped_fail_storage fs;
|
||||
string s2(std::move(s1));
|
||||
BEAST_EXPECT(s2 == t.v1);
|
||||
BEAST_EXPECT(s1.empty());
|
||||
@ -290,7 +276,6 @@ public:
|
||||
|
||||
{
|
||||
string s1(t.v2);
|
||||
scoped_fail_storage fs;
|
||||
string s2(std::move(s1));
|
||||
BEAST_EXPECT(s2 == t.v2);
|
||||
BEAST_EXPECT(s1.empty());
|
||||
@ -377,17 +362,15 @@ public:
|
||||
BEAST_EXPECT(s == t.v2);
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
{
|
||||
string s(init1);
|
||||
BEAST_EXPECT(s == t.v1);
|
||||
});
|
||||
}
|
||||
|
||||
fail_loop([&]
|
||||
{
|
||||
string s(init2);
|
||||
BEAST_EXPECT(s == t.v2);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// string(string_view, storage_ptr)
|
||||
@ -404,17 +387,15 @@ public:
|
||||
BEAST_EXPECT(s == t.v2);
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
{
|
||||
string s(t.v1);
|
||||
BEAST_EXPECT(s == t.v1);
|
||||
});
|
||||
}
|
||||
|
||||
fail_loop([&]
|
||||
{
|
||||
string s(t.v2);
|
||||
BEAST_EXPECT(s == t.v2);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// string(string_view, size_type, size_type, storage_ptr)
|
||||
@ -431,17 +412,15 @@ public:
|
||||
BEAST_EXPECT(s == "BCD");
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
{
|
||||
string s(t.v1, 1, 3);
|
||||
BEAST_EXPECT(s == "bcd");
|
||||
});
|
||||
}
|
||||
|
||||
fail_loop([&]
|
||||
{
|
||||
string s(t.v2, 1, 3);
|
||||
BEAST_EXPECT(s == "BCD");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1443,9 +1422,9 @@ public:
|
||||
|
||||
// reserve(size_type)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s;
|
||||
string s(sp);
|
||||
s.append(t.v1);
|
||||
s.append(t.v2);
|
||||
|
||||
@ -1473,9 +1452,9 @@ public:
|
||||
}
|
||||
|
||||
// shrink_to_fit()
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s;
|
||||
string s(sp);
|
||||
string::size_type cap;
|
||||
|
||||
cap = s.capacity();
|
||||
@ -1532,17 +1511,17 @@ public:
|
||||
|
||||
// insert(size_type, size_type, char)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s.insert(1, 3, '*');
|
||||
BEAST_EXPECT(s == std::string(
|
||||
t.v1).insert(1, 3, '*'));
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s.insert(1, 3, '*');
|
||||
BEAST_EXPECT(s == std::string(
|
||||
t.v2).insert(1, 3, '*'));
|
||||
@ -1567,17 +1546,17 @@ public:
|
||||
|
||||
// insert(size_type, char const*)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s.insert(1, "***");
|
||||
BEAST_EXPECT(s == std::string(
|
||||
t.v1).insert(1, "***"));
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s.insert(1, "***");
|
||||
BEAST_EXPECT(s == std::string(
|
||||
t.v2).insert(1, "***"));
|
||||
@ -1594,17 +1573,17 @@ public:
|
||||
|
||||
// insert(size_type, char const*, size_type)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s.insert(1, "*****", 3);
|
||||
BEAST_EXPECT(s == std::string(
|
||||
t.v1).insert(1, "*****", 3));
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s.insert(1, "*****", 3);
|
||||
BEAST_EXPECT(s == std::string(
|
||||
t.v2).insert(1, "*****", 3));
|
||||
@ -1613,17 +1592,17 @@ public:
|
||||
|
||||
// insert(size_type, string const&)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s.insert(1, string(t.v2));
|
||||
BEAST_EXPECT(s == std::string(
|
||||
t.v1).insert(1, t.s2));
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s.insert(1, string(t.v1));
|
||||
BEAST_EXPECT(s == std::string(
|
||||
t.v2).insert(1, t.s1));
|
||||
@ -1632,33 +1611,33 @@ public:
|
||||
|
||||
// insert(size_type, string const&, size_type, size_type)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s.insert(1, string(t.v2), 1, 3);
|
||||
BEAST_EXPECT(s == std::string(
|
||||
t.v1).insert(1, t.s2, 1, 3));
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s.insert(1, string(t.v1), 1, 3);
|
||||
BEAST_EXPECT(s == std::string(
|
||||
t.v2).insert(1, t.s1, 1, 3));
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s.insert(1, string(t.v2), 1);
|
||||
BEAST_EXPECT(s == std::string(
|
||||
t.v1).insert(1, t.s2, 1, std::string::npos));
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s.insert(1, string(t.v1), 1);
|
||||
BEAST_EXPECT(s == std::string(
|
||||
t.v2).insert(1, t.s1, 1, std::string::npos));
|
||||
@ -1667,16 +1646,16 @@ public:
|
||||
|
||||
// insert(const_iterator, char)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
BEAST_EXPECT(
|
||||
*s.insert(s.begin()+2, '*') == '*');
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
BEAST_EXPECT(
|
||||
*s.insert(s.begin()+2, '*') == '*');
|
||||
});
|
||||
@ -1684,17 +1663,17 @@ public:
|
||||
|
||||
// insert(const_iterator, size_type, char)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
BEAST_EXPECT(string_view(
|
||||
s.insert(s.begin()+2, 3, '*'), 5) ==
|
||||
"***cd");
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
BEAST_EXPECT(string_view(
|
||||
s.insert(s.begin()+2, 3, '*'), 5) ==
|
||||
"***CD");
|
||||
@ -1715,25 +1694,25 @@ public:
|
||||
};
|
||||
BEAST_EXPECT(std::string(init2) == t.s2);
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s.insert(s.begin()+2, init2.begin(), init2.end());
|
||||
BEAST_EXPECT(s == std::string(
|
||||
t.s1).insert(2, init2.begin(), init2.size()));
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s.insert(s.begin()+2, init1.begin(), init1.end());
|
||||
BEAST_EXPECT(s == std::string(
|
||||
t.s2).insert(2, init1.begin(), init1.size()));
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s.insert(s.begin()+2,
|
||||
make_input_iterator(init2.begin()),
|
||||
make_input_iterator(init2.end()));
|
||||
@ -1741,9 +1720,9 @@ public:
|
||||
t.s1).insert(2, init2.begin(), init2.size()));
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s.insert(s.begin()+2,
|
||||
make_input_iterator(init1.begin()),
|
||||
make_input_iterator(init1.end()));
|
||||
@ -1766,17 +1745,17 @@ public:
|
||||
};
|
||||
BEAST_EXPECT(std::string(init2) == t.s2);
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s.insert(s.begin()+2, init2);
|
||||
BEAST_EXPECT(s == std::string(
|
||||
t.s1).insert(2, init2.begin(), init2.size()));
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s.insert(s.begin()+2, init1);
|
||||
BEAST_EXPECT(s == std::string(
|
||||
t.s2).insert(2, init1.begin(), init1.size()));
|
||||
@ -1785,17 +1764,17 @@ public:
|
||||
|
||||
// insert(const_iterator, string_view)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s.insert(2, string_view(t.v2));
|
||||
BEAST_EXPECT(s == std::string(
|
||||
t.v1).insert(2, t.s2));
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s.insert(2, string_view(t.v1));
|
||||
BEAST_EXPECT(s == std::string(
|
||||
t.v2).insert(2, t.s1));
|
||||
@ -1804,17 +1783,17 @@ public:
|
||||
|
||||
// insert(const_iterator, string_view)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s.insert(2, string_view(t.v2), 2, 3);
|
||||
BEAST_EXPECT(s == std::string(
|
||||
t.v1).insert(2, t.s2, 2, 3));
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s.insert(2, string_view(t.v1), 2, 3);
|
||||
BEAST_EXPECT(s == std::string(
|
||||
t.v2).insert(2, t.s1, 2, 3));
|
||||
@ -1915,17 +1894,17 @@ public:
|
||||
|
||||
// push_back(char)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s;
|
||||
string s(sp);
|
||||
for(auto ch : t.v1)
|
||||
s.push_back(ch);
|
||||
BEAST_EXPECT(s == t.v1);
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s;
|
||||
string s(sp);
|
||||
for(auto ch : t.v2)
|
||||
s.push_back(ch);
|
||||
BEAST_EXPECT(s == t.v2);
|
||||
@ -1959,17 +1938,17 @@ public:
|
||||
|
||||
// append(size_type, char)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s.append(t.v2.size(), '*');
|
||||
BEAST_EXPECT(s == t.s1 +
|
||||
std::string(t.v2.size(), '*'));
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s.append(t.v1.size(), '*');
|
||||
BEAST_EXPECT(s == t.s2 +
|
||||
std::string(t.v1.size(), '*'));
|
||||
@ -1978,16 +1957,16 @@ public:
|
||||
|
||||
// append(string)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s.append(string(t.v2));
|
||||
BEAST_EXPECT(s == t.s1 + t.s2);
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s.append(string(t.v1));
|
||||
BEAST_EXPECT(s == t.s2 + t.s1);
|
||||
});
|
||||
@ -1995,30 +1974,30 @@ public:
|
||||
|
||||
// append(string, size_type, size_type)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s.append(string(t.v2), 3);
|
||||
BEAST_EXPECT(s == t.s1 + t.s2.substr(3));
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s.append(string(t.v1), 3);
|
||||
BEAST_EXPECT(s == t.s2 + t.s1.substr(3));
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s.append(string(t.v2), 2, 3);
|
||||
BEAST_EXPECT(s == t.s1 + t.s2.substr(2, 3));
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s.append(string(t.v1), 2, 3);
|
||||
BEAST_EXPECT(s == t.s2 + t.s1.substr(2, 3));
|
||||
});
|
||||
@ -2026,16 +2005,16 @@ public:
|
||||
|
||||
// append(char const*)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s.append(t.s2.c_str());
|
||||
BEAST_EXPECT(s == t.s1 + t.s2);
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s.append(t.s1.c_str());
|
||||
BEAST_EXPECT(s == t.s2 + t.s1);
|
||||
});
|
||||
@ -2043,16 +2022,16 @@ public:
|
||||
|
||||
// append(char const*, size_type)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s.append(t.s2.c_str(), 5);
|
||||
BEAST_EXPECT(s == t.s1 + t.s2.substr(0, 5));
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s.append(t.s1.c_str(), 5);
|
||||
BEAST_EXPECT(s == t.s2 + t.s1.substr(0, 5));
|
||||
});
|
||||
@ -2072,16 +2051,16 @@ public:
|
||||
};
|
||||
BEAST_EXPECT(std::string(init2) == t.s2);
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s.append(init2);
|
||||
BEAST_EXPECT(s == t.s1 + t.s2);
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s.append(init1);
|
||||
BEAST_EXPECT(s == t.s2 + t.s1);
|
||||
});
|
||||
@ -2101,32 +2080,32 @@ public:
|
||||
};
|
||||
BEAST_EXPECT(std::string(init2) == t.s2);
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s.append(init2.begin(), init2.end());
|
||||
BEAST_EXPECT(s == t.s1 + t.s2);
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s.append(init1.begin(), init1.end());
|
||||
BEAST_EXPECT(s == t.s2 + t.s1);
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s.append(
|
||||
make_input_iterator(init2.begin()),
|
||||
make_input_iterator(init2.end()));
|
||||
BEAST_EXPECT(s == t.s1 + t.s2);
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s.append(
|
||||
make_input_iterator(init1.begin()),
|
||||
make_input_iterator(init1.end()));
|
||||
@ -2136,16 +2115,16 @@ public:
|
||||
|
||||
// append(string_view)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s.append(t.v2);
|
||||
BEAST_EXPECT(s == t.s1 + t.s2);
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s.append(t.v1);
|
||||
BEAST_EXPECT(s == t.s2 + t.s1);
|
||||
});
|
||||
@ -2153,30 +2132,30 @@ public:
|
||||
|
||||
// append(string_view)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s.append(t.v2, 2);
|
||||
BEAST_EXPECT(s == t.s1 + t.s2.substr(2));
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s.append(t.v1, 2);
|
||||
BEAST_EXPECT(s == t.s2 + t.s1.substr(2));
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s.append(t.v2, 2, 3);
|
||||
BEAST_EXPECT(s == t.s1 + t.s2.substr(2, 3));
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s.append(t.v1, 2, 3);
|
||||
BEAST_EXPECT(s == t.s2 + t.s1.substr(2, 3));
|
||||
});
|
||||
@ -2190,16 +2169,16 @@ public:
|
||||
|
||||
// operator+=(string)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s += string(t.v2);
|
||||
BEAST_EXPECT(s == t.s1 + t.s2);
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s += string(t.v1);
|
||||
BEAST_EXPECT(s == t.s2 + t.s1);
|
||||
});
|
||||
@ -2207,17 +2186,17 @@ public:
|
||||
|
||||
// operator+=(char)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s;
|
||||
string s(sp);
|
||||
for(auto ch : t.v1)
|
||||
s += ch;
|
||||
BEAST_EXPECT(s == t.v1);
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s;
|
||||
string s(sp);
|
||||
for(auto ch : t.v2)
|
||||
s += ch;
|
||||
BEAST_EXPECT(s == t.v2);
|
||||
@ -2226,16 +2205,16 @@ public:
|
||||
|
||||
// operator+=(char const*)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s += t.s2.c_str();
|
||||
BEAST_EXPECT(s == t.s1 + t.s2);
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s += t.s1.c_str();
|
||||
BEAST_EXPECT(s == t.s2 + t.s1);
|
||||
});
|
||||
@ -2255,16 +2234,16 @@ public:
|
||||
};
|
||||
BEAST_EXPECT(std::string(init2) == t.s2);
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s += init2;
|
||||
BEAST_EXPECT(s == t.s1 + t.s2);
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s += init1;
|
||||
BEAST_EXPECT(s == t.s2 + t.s1);
|
||||
});
|
||||
@ -2272,16 +2251,16 @@ public:
|
||||
|
||||
// operator+=(string_view)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v1);
|
||||
string s(t.v1, sp);
|
||||
s += t.v2;
|
||||
BEAST_EXPECT(s == t.s1 + t.s2);
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s(t.v2);
|
||||
string s(t.v2, sp);
|
||||
s += t.v1;
|
||||
BEAST_EXPECT(s == t.s2 + t.s1);
|
||||
});
|
||||
@ -2449,25 +2428,25 @@ public:
|
||||
|
||||
// resize(size_type)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s;
|
||||
string s(sp);
|
||||
s.resize(t.v1.size());
|
||||
BEAST_EXPECT(s.size() == t.v1.size());
|
||||
BEAST_EXPECT(s == string(t.v1.size(), '\0'));
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s;
|
||||
string s(sp);
|
||||
s.resize(t.v2.size());
|
||||
BEAST_EXPECT(s.size() == t.v2.size());
|
||||
BEAST_EXPECT(s == string(t.v2.size(), '\0'));
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s;
|
||||
string s(sp);
|
||||
s.resize(t.v1.size());
|
||||
s.resize(t.v2.size());
|
||||
BEAST_EXPECT(s == string(t.v2.size(), '\0'));
|
||||
@ -2478,25 +2457,25 @@ public:
|
||||
|
||||
// resize(size_type, char)
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s;
|
||||
string s(sp);
|
||||
s.resize(t.v1.size(), '*');
|
||||
BEAST_EXPECT(s.size() == t.v1.size());
|
||||
BEAST_EXPECT(s == string(t.v1.size(), '*'));
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s;
|
||||
string s(sp);
|
||||
s.resize(t.v2.size(), '*');
|
||||
BEAST_EXPECT(s.size() == t.v2.size());
|
||||
BEAST_EXPECT(s == string(t.v2.size(), '*'));
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s;
|
||||
string s(sp);
|
||||
s.resize(t.v1.size(), '*');
|
||||
s.resize(t.v2.size(), '*');
|
||||
BEAST_EXPECT(s == string(t.v2.size(), '*'));
|
||||
@ -2513,19 +2492,19 @@ public:
|
||||
|
||||
// swap
|
||||
{
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s1(t.v1);
|
||||
string s2(t.v2);
|
||||
string s1(t.v1, sp);
|
||||
string s2(t.v2, sp);
|
||||
s1.swap(s2);
|
||||
BEAST_EXPECT(s1 == t.v2);
|
||||
BEAST_EXPECT(s2 == t.v1);
|
||||
});
|
||||
|
||||
fail_loop([&]
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
string s1(t.v1);
|
||||
string s2(t.v2);
|
||||
string s1(t.v1, sp);
|
||||
string s2(t.v2, sp);
|
||||
swap(s1, s2);
|
||||
BEAST_EXPECT(s1 == t.v2);
|
||||
BEAST_EXPECT(s2 == t.v1);
|
||||
|
@ -28,7 +28,7 @@ namespace json {
|
||||
struct unique_storage : storage
|
||||
{
|
||||
void*
|
||||
allocate(
|
||||
do_allocate(
|
||||
std::size_t n,
|
||||
std::size_t) override
|
||||
{
|
||||
@ -37,7 +37,7 @@ struct unique_storage : storage
|
||||
}
|
||||
|
||||
void
|
||||
deallocate(
|
||||
do_deallocate(
|
||||
void* p,
|
||||
std::size_t n,
|
||||
std::size_t) noexcept override
|
||||
@ -48,7 +48,7 @@ struct unique_storage : storage
|
||||
char>{}.deallocate(cp, n);
|
||||
}
|
||||
bool
|
||||
is_equal(
|
||||
do_is_equal(
|
||||
storage const&) const noexcept override
|
||||
{
|
||||
return false;
|
||||
@ -77,7 +77,7 @@ struct fail_storage : storage
|
||||
}
|
||||
|
||||
void*
|
||||
allocate(
|
||||
do_allocate(
|
||||
std::size_t n,
|
||||
std::size_t) override
|
||||
{
|
||||
@ -92,7 +92,7 @@ struct fail_storage : storage
|
||||
}
|
||||
|
||||
void
|
||||
deallocate(
|
||||
do_deallocate(
|
||||
void* p,
|
||||
std::size_t n,
|
||||
std::size_t) noexcept override
|
||||
@ -103,7 +103,7 @@ struct fail_storage : storage
|
||||
char>{}.deallocate(cp, n);
|
||||
}
|
||||
bool
|
||||
is_equal(
|
||||
do_is_equal(
|
||||
storage const&) const noexcept override
|
||||
{
|
||||
return false;
|
||||
@ -112,34 +112,32 @@ struct fail_storage : storage
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
class scoped_fail_storage
|
||||
{
|
||||
storage_ptr sp_;
|
||||
|
||||
public:
|
||||
scoped_fail_storage()
|
||||
: sp_(default_storage())
|
||||
{
|
||||
default_storage(
|
||||
make_storage<fail_storage>());
|
||||
}
|
||||
|
||||
~scoped_fail_storage()
|
||||
{
|
||||
default_storage(sp_);
|
||||
}
|
||||
|
||||
storage_ptr const&
|
||||
get() const noexcept
|
||||
{
|
||||
return sp_;
|
||||
}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
namespace detail {
|
||||
|
||||
#if 1
|
||||
|
||||
template<class F>
|
||||
void
|
||||
fail_loop(F&& f)
|
||||
{
|
||||
auto sp = make_storage<fail_storage>();
|
||||
while(sp->fail < 200)
|
||||
{
|
||||
try
|
||||
{
|
||||
f(sp);
|
||||
}
|
||||
catch(test_failure const&)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
BEAST_EXPECT(sp->fail < 200);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template<class F>
|
||||
typename std::enable_if<
|
||||
std::is_same<void,
|
||||
@ -191,6 +189,8 @@ fail_loop(F&& f)
|
||||
default_storage(saved);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // detail
|
||||
|
||||
template<class F>
|
||||
|
Loading…
x
Reference in New Issue
Block a user