// // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // Official repository: https://github.com/boostorg/json // #ifndef BOOST_JSON_IMPL_STRING_HPP #define BOOST_JSON_IMPL_STRING_HPP #include BOOST_JSON_NS_BEGIN string:: string( detail::key_t const&, string_view s, storage_ptr sp) : sp_(std::move(sp)) , impl_(detail::key_t{}, s, sp_) { } string:: string( detail::key_t const&, string_view s1, string_view s2, storage_ptr sp) : sp_(std::move(sp)) , impl_(detail::key_t{}, s1, s2, sp_) { } template string:: string( InputIt first, InputIt last, storage_ptr sp) : sp_(std::move(sp)) , impl_(first, last, sp_, iter_cat{}) { } template string& string:: assign( InputIt first, InputIt last) { assign(first, last, iter_cat{}); return *this; } template string& string:: append(InputIt first, InputIt last) { append(first, last, iter_cat{}); return *this; } // KRYSTIAN TODO: this can be done without copies when // reallocation is not needed, when the iterator is a // FowardIterator or better, as we can use std::distance template auto string:: insert( size_type pos, InputIt first, InputIt last) -> string& { struct cleanup { detail::string_impl& s; storage_ptr const& sp; ~cleanup() { s.destroy(sp); } }; // We use the default storage because // the allocation is immediately freed. storage_ptr dsp; detail::string_impl tmp( first, last, dsp, iter_cat{}); cleanup c{tmp, dsp}; std::memcpy( impl_.insert_unchecked(pos, tmp.size(), sp_), tmp.data(), tmp.size()); return *this; } // KRYSTIAN TODO: this can be done without copies when // reallocation is not needed, when the iterator is a // FowardIterator or better, as we can use std::distance template auto string:: replace( const_iterator first, const_iterator last, InputIt first2, InputIt last2) -> string& { struct cleanup { detail::string_impl& s; storage_ptr const& sp; ~cleanup() { s.destroy(sp); } }; // We use the default storage because // the allocation is immediately freed. storage_ptr dsp; detail::string_impl tmp( first2, last2, dsp, iter_cat{}); cleanup c{tmp, dsp}; std::memcpy( impl_.replace_unchecked( first - begin(), last - first, tmp.size(), sp_), tmp.data(), tmp.size()); return *this; } //---------------------------------------------------------- template void string:: assign( InputIt first, InputIt last, std::random_access_iterator_tag) { auto dest = impl_.assign(static_cast< size_type>(last - first), sp_); while(first != last) *dest++ = *first++; } template void string:: assign( InputIt first, InputIt last, std::input_iterator_tag) { if(first == last) { impl_.term(0); return; } detail::string_impl tmp( first, last, sp_, std::input_iterator_tag{}); impl_.destroy(sp_); impl_ = tmp; } template void string:: append( InputIt first, InputIt last, std::random_access_iterator_tag) { auto const n = static_cast< size_type>(last - first); std::copy(first, last, impl_.append(n, sp_)); } template void string:: append( InputIt first, InputIt last, std::input_iterator_tag) { struct cleanup { detail::string_impl& s; storage_ptr const& sp; ~cleanup() { s.destroy(sp); } }; // We use the default storage because // the allocation is immediately freed. storage_ptr dsp; detail::string_impl tmp( first, last, dsp, std::input_iterator_tag{}); cleanup c{tmp, dsp}; std::memcpy( impl_.append(tmp.size(), sp_), tmp.data(), tmp.size()); } BOOST_JSON_NS_END #endif