void basic_flat_buffer<Allocator>:: move_assign(basic_flat_buffer& other, std::false_type) { if(this->get() != other.get()) { copy_from(other); other.clear(); other.shrink_to_fit(); } else { move_assign(other, std::true_type{}); } }
void swap( basic_flat_buffer<Allocator>& lhs, basic_flat_buffer<Allocator>& rhs) { lhs.swap(rhs); }
void basic_flat_buffer<Allocator>:: copy_assign(basic_flat_buffer const& other, std::true_type) { max_ = other.max_; this->get() = other.get(); copy_from(other); }
void basic_flat_buffer<Allocator>:: swap(basic_flat_buffer& other, std::false_type) { BOOST_ASSERT(this->get() == other.get()); using std::swap; swap(max_, other.max_); swap(begin_, other.begin_); swap(in_, other.in_); swap(out_, other.out_); last_ = this->out_; other.last_ = other.out_; swap(end_, other.end_); }
basic_flat_buffer<Allocator>:: basic_flat_buffer(basic_flat_buffer const& other) : boost::empty_value<base_alloc_type>(boost::empty_init_t{}, alloc_traits::select_on_container_copy_construction( other.get())) , begin_(nullptr) , in_(nullptr) , out_(nullptr) , last_(nullptr) , end_(nullptr) , max_(other.max_) { copy_from(other); }
void basic_flat_buffer<Allocator>:: move_assign(basic_flat_buffer& other, std::true_type) { clear(); shrink_to_fit(); this->get() = std::move(other.get()); begin_ = other.begin_; in_ = other.in_; out_ = other.out_; last_ = out_; end_ = other.end_; max_ = other.max_; other.begin_ = nullptr; other.in_ = nullptr; other.out_ = nullptr; other.last_ = nullptr; other.end_ = nullptr; }
void basic_flat_buffer<Allocator>:: copy_from( basic_flat_buffer<OtherAlloc> const& other) { std::size_t const n = other.size(); if(n == 0 || n > capacity()) { if(begin_ != nullptr) { alloc_traits::deallocate( this->get(), begin_, this->capacity()); begin_ = nullptr; in_ = nullptr; out_ = nullptr; last_ = nullptr; end_ = nullptr; } if(n == 0) return; begin_ = alloc(n); in_ = begin_; out_ = begin_ + n; last_ = begin_ + n; end_ = begin_ + n; } in_ = begin_; out_ = begin_ + n; last_ = begin_ + n; if(begin_) { BOOST_ASSERT(other.begin_); std::memcpy(begin_, other.begin_, n); } }
void read_istream( std::istream& is, basic_flat_buffer<Allocator>& buffer, message<isRequest, Body, fields>& msg, error_code& ec) { // Create the message parser // // Arguments passed to the parser's constructor are // forwarded to the message constructor. Here, we use // a move construction in case the caller has constructed // their message in a non-default way. // parser<isRequest, Body> p{std::move(msg)}; do { // Extract whatever characters are presently available in the istream if(is.rdbuf()->in_avail() > 0) { // Get a mutable buffer sequence for writing auto const mb = buffer.prepare( static_cast<std::size_t>(is.rdbuf()->in_avail())); // Now get everything we can from the istream buffer.commit(static_cast<std::size_t>(is.readsome( boost::asio::buffer_cast<char*>(mb), boost::asio::buffer_size(mb)))); } else if(buffer.size() == 0) { // Our buffer is empty and we need more characters, // see if we've reached the end of file on the istream if(! is.eof()) { // Get a mutable buffer sequence for writing auto const mb = buffer.prepare(1024); // Try to get more from the istream. This might block. is.read( boost::asio::buffer_cast<char*>(mb), boost::asio::buffer_size(mb)); // If an error occurs on the istream then return it to the caller. if(is.fail() && ! is.eof()) { // We'll just re-use io_error since std::istream has no error_code interface. ec = make_error_code(errc::io_error); return; } // Commit the characters we got to the buffer. buffer.commit(static_cast<std::size_t>(is.gcount())); } else { // Inform the parser that we've reached the end of the istream. p.put_eof(ec); if(ec) return; break; } } // Write the data to the parser auto const bytes_used = p.put(buffer.data(), ec); // This error means that the parser needs additional octets. if(ec == error::need_more) ec = {}; if(ec) return; // Consume the buffer octets that were actually parsed. buffer.consume(bytes_used); } while(! p.is_done()); // Transfer ownership of the message container in the parser to the caller. msg = p.release(); }