diff --git a/bench/bench.cpp b/bench/bench.cpp index 6ff89f92..2db3a5fc 100644 --- a/bench/bench.cpp +++ b/bench/bench.cpp @@ -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); diff --git a/include/boost/json/impl/storage.ipp b/include/boost/json/impl/storage.ipp index b497e5ac..08d75bdd 100644 --- a/include/boost/json/impl/storage.ipp +++ b/include/boost/json/impl/storage.ipp @@ -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(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(); - 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(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(); + return sp; +} + } // json } // boost diff --git a/include/boost/json/impl/string.hpp b/include/boost/json/impl/string.hpp index 93976db0..d99adacf 100644 --- a/include/boost/json/impl/string.hpp +++ b/include/boost/json/impl/string.hpp @@ -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{}); - 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); diff --git a/include/boost/json/storage.hpp b/include/boost/json/storage.hpp index 9f1e0380..efc3bad2 100644 --- a/include/boost/json/storage.hpp +++ b/include/boost/json/storage.hpp @@ -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; //---------------------------------------------------------- -/** 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`. @par Complexity @@ -498,38 +524,12 @@ using storage_ptr = basic_storage_ptr; @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 diff --git a/test/array.cpp b/test/array.cpp index 513be219..a9b12e66 100644 --- a/test/array.cpp +++ b/test/array.cpp @@ -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 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); diff --git a/test/object.cpp b/test/object.cpp index 9c209dc5..3bc6d105 100644 --- a/test/object.cpp +++ b/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> init = { @@ -164,9 +161,8 @@ public: {"c", "hello"}}; object o(init.begin(), init.end()); check(o, 3); - }); + } - fail_loop([&] { std::initializer_list> 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> 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> 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) { diff --git a/test/storage.cpp b/test/storage.cpp index 4066a379..99b4767f 100644 --- a/test/storage.cpp +++ b/test/storage.cpp @@ -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(); - default_storage(sp2); - BEAST_EXPECT(*default_storage() == *sp2); - default_storage(sp1); - } } void @@ -206,7 +197,7 @@ public: { testMembers(); testRelational(); - testFree(); + testDefaultStorage(); } }; diff --git a/test/string.cpp b/test/string.cpp index 74f14306..864fdd51 100644 --- a/test/string.cpp +++ b/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(); + 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); diff --git a/test/test.hpp b/test/test.hpp index 410ba323..f97ad525 100644 --- a/test/test.hpp +++ b/test/test.hpp @@ -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()); - } - - ~scoped_fail_storage() - { - default_storage(sp_); - } - - storage_ptr const& - get() const noexcept - { - return sp_; - } -}; - -//---------------------------------------------------------- - namespace detail { +#if 1 + +template +void +fail_loop(F&& f) +{ + auto sp = make_storage(); + while(sp->fail < 200) + { + try + { + f(sp); + } + catch(test_failure const&) + { + continue; + } + break; + } + BEAST_EXPECT(sp->fail < 200); +} + +#else + template typename std::enable_if< std::is_same