diff --git a/doc/qbk/01_overview.qbk b/doc/qbk/01_overview.qbk index 8ead13d8..66af1a5b 100644 --- a/doc/qbk/01_overview.qbk +++ b/doc/qbk/01_overview.qbk @@ -83,8 +83,6 @@ later. [heading Terminology] - - [heading Description] Avoid user-defined customizations for the value type such as template diff --git a/doc/qbk/02_2_strings.qbk b/doc/qbk/02_2_strings.qbk index 9dc11dbe..e2e2556e 100644 --- a/doc/qbk/02_2_strings.qbk +++ b/doc/qbk/02_2_strings.qbk @@ -14,7 +14,26 @@ Modifiable sequences of characters are represented using instances of type [link json.ref.boost__json__string `string`]. These strings have an interface almost identical to `std::string`, and -operate the same way, except that string is an ordinary class instead of -a class template, and uses __storage__ instead of __Allocator__. +operate the same way, with these variations: + +* __string__ is not a class template. + +* __storage__ is used instead of __Allocator__. + +* New characters are + +A string may be constructed initially empty without incurrent any +memory allocations using the default storage, or a specified storage: + +``` +string str1; // empty string, default storage + +string str2( make_storage() ); // empty string, block storage +``` + +As with `std` strings, space may be reserved upon construction. +Exceptions are possible here: + + [endsect] diff --git a/include/boost/json/array.hpp b/include/boost/json/array.hpp index da91e2eb..6b1a041f 100644 --- a/include/boost/json/array.hpp +++ b/include/boost/json/array.hpp @@ -1640,10 +1640,19 @@ private: @par Preconditions `&lhs != &rhs` + + @par Complexity - @param lhs The array to swap. + Constant or linear in `lhs.size() + rhs.size()`. - @param rhs The array to swap. + @par Exception Safety + + Strong guarantee. + Calls to @ref storage::allocate may throw. + + @param lhs The array to exchange. + + @param rhs The array to exchange. */ inline void diff --git a/include/boost/json/detail/string_impl.hpp b/include/boost/json/detail/string_impl.hpp index fe2d0e41..b9e5d35e 100644 --- a/include/boost/json/detail/string_impl.hpp +++ b/include/boost/json/detail/string_impl.hpp @@ -102,7 +102,11 @@ public: std::random_access_iterator_tag) : string_impl(last - first, sp) { + #ifdef _MSC_VER std::copy(first, last, data()); + #else + std::copy(first, last, data(), data() + size()); + #endif } template diff --git a/include/boost/json/impl/array.ipp b/include/boost/json/impl/array.ipp index a005fb53..c646a55e 100644 --- a/include/boost/json/impl/array.ipp +++ b/include/boost/json/impl/array.ipp @@ -438,12 +438,12 @@ void array:: swap(array& other) { + BOOST_JSON_ASSERT(this != &other); if(*sp_ == *other.sp_) { impl_.swap(other.impl_); return; } - array temp1( std::move(*this), other.storage()); diff --git a/include/boost/json/impl/object.ipp b/include/boost/json/impl/object.ipp index bdd96396..1a8c00f8 100644 --- a/include/boost/json/impl/object.ipp +++ b/include/boost/json/impl/object.ipp @@ -272,6 +272,7 @@ void object:: swap(object& other) { + BOOST_JSON_ASSERT(this != &other); if(*sp_ == *other.sp_) { impl_.swap(other.impl_); diff --git a/include/boost/json/impl/string.ipp b/include/boost/json/impl/string.ipp index d0f557dc..916bbcd2 100644 --- a/include/boost/json/impl/string.ipp +++ b/include/boost/json/impl/string.ipp @@ -284,12 +284,12 @@ void string:: swap(string& other) { + BOOST_JSON_ASSERT(this != &other); if(*sp_ == *other.sp_) { std::swap(impl_, other.impl_); return; } - string temp1( std::move(*this), other.sp_); string temp2( @@ -323,14 +323,6 @@ reserve_impl(size_type new_cap) } } -//---------------------------------------------------------- - -std::ostream& -operator<<(std::ostream& os, string const& s) -{ - return os << static_cast(s); -} - } // json } // boost diff --git a/include/boost/json/object.hpp b/include/boost/json/object.hpp index cb746058..fc9a8a58 100644 --- a/include/boost/json/object.hpp +++ b/include/boost/json/object.hpp @@ -1406,10 +1406,19 @@ private: @par Preconditions `&lhs != &rhs` + + @par Complexity - @param lhs The array to swap. + Constant or linear in `lhs.size() + rhs.size()`. - @param rhs The array to swap. + @par Exception Safety + + Strong guarantee. + Calls to @ref storage::allocate may throw. + + @param lhs The object to exchange. + + @param rhs The object to exchange. */ inline void diff --git a/include/boost/json/string.hpp b/include/boost/json/string.hpp index fa1e2194..46bc481d 100644 --- a/include/boost/json/string.hpp +++ b/include/boost/json/string.hpp @@ -2556,17 +2556,6 @@ public: return string_view(*this).find_last_not_of(t, pos); } - //------------------------------------------------------ - - /** Perform stream output. - - Behaves as a formatted output function. - */ - BOOST_JSON_DECL - friend - std::ostream& - operator<<(std::ostream& os, string const& s); - private: class undo; @@ -2620,10 +2609,19 @@ private: @par Preconditions `&lhs != &rhs` + + @par Complexity - @param lhs The string to swap. + Constant or linear in `lhs.size() + rhs.size()`. - @param rhs The string to swap. + @par Exception Safety + + Strong guarantee. + Calls to @ref storage::allocate may throw. + + @param lhs The string to exchange. + + @param rhs The string to exchange. */ inline void @@ -2634,6 +2632,17 @@ swap(string& lhs, string& rhs) //---------------------------------------------------------- +/** Perform stream output. + + Behaves as a formatted output function. +*/ +inline +std::ostream& +operator<<(std::ostream& os, string const& s) +{ + return os << static_cast(s); +} + /** Return true if lhs equals rhs. A lexicographical comparison is used. diff --git a/test/limits.cpp b/test/limits.cpp index b39dee2e..d495801d 100644 --- a/test/limits.cpp +++ b/test/limits.cpp @@ -170,8 +170,9 @@ public: string::max_size() + 1, '*'); auto const js = "\"" + big + "\":null"; + value jv; BEAST_THROWS( - parse(js), + jv = parse(js), std::length_error); } @@ -182,8 +183,9 @@ public: string::max_size() + 1, '*'); auto const js = "{\"" + big + "\":null}"; + value jv; BEAST_THROWS( - parse(js), + jv = parse(js), std::length_error); } } @@ -194,8 +196,9 @@ public: // max raw_stack { std::string big; + value jv; BEAST_THROWS( - parse( + jv = parse( "[1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0," "1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0," "1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0," @@ -227,8 +230,9 @@ public: string::max_size()*2, '*'); auto const js = "\"" + big + "\""; + value jv; BEAST_THROWS( - parse(js), + jv = parse(js), std::length_error); } @@ -240,8 +244,9 @@ public: (string::max_size()*3)/2, '*'); auto const js = "\"" + big + "\""; + value jv; BEAST_THROWS( - parse(js), + jv = parse(js), std::length_error); } }