/** * When the object has no memory allocated straight heap assignment overwriting existing data. * NOTE: If it throws (memory allocation failure), it hasn't written into `this`. */ void heap_assign(const char *data, size_t size) { char *buffer = new char[size + sizeof(size_t) + NulPadding]; *reinterpret_cast<size_t *>(buffer) = size; DYND_MEMCPY(buffer + sizeof(size_t), data, size); if (NulPadding) { buffer[sizeof(size_t) + size] = 0; } m_pointer = reinterpret_cast<intptr_t>(buffer); m_size = ~static_cast<int64_t>(size); }
/** Move constructor */ shortvector(shortvector&& rhs) { if (rhs.m_data == rhs.m_shortdata) { // In the short case, copy the full shortdata vector DYND_MEMCPY(m_shortdata, rhs.m_shortdata, staticN * sizeof(T)); m_data = m_shortdata; } else { // In the long case, move the long allocated pointer m_data = rhs.m_data; rhs.m_data = rhs.m_shortdata; } }
void swap(shortvector& rhs) { // Start by swapping the pointers std::swap(m_data, rhs.m_data); // Copy the shortdata if necessary if (m_data == rhs.m_shortdata) { // The rhs data was pointing to shortdata m_data = m_shortdata; if (rhs.m_data == m_shortdata) { // Both data's were pointing to their shortdata T tmp[staticN]; rhs.m_data = rhs.m_shortdata; DYND_MEMCPY(tmp, m_shortdata, staticN * sizeof(T)); DYND_MEMCPY(m_shortdata, rhs.m_shortdata, staticN * sizeof(T)); DYND_MEMCPY(rhs.m_shortdata, tmp, staticN * sizeof(T)); } else { // Just the rhs data was pointing to shortdata DYND_MEMCPY(m_shortdata, rhs.m_shortdata, staticN * sizeof(T)); } } else if (rhs.m_data == m_shortdata) { // Just this data was pointing to shortdata rhs.m_data = rhs.m_shortdata; DYND_MEMCPY(rhs.m_shortdata, m_shortdata, staticN * sizeof(T)); } }
/** Move assignment operator */ shortvector& operator=(shortvector&& rhs) { if (this != &rhs) { if (m_data != m_shortdata) { delete[] m_data; } if (rhs.m_data == rhs.m_shortdata) { // In the short case, copy the full shortdata vector DYND_MEMCPY(m_shortdata, rhs.m_shortdata, staticN * sizeof(T)); m_data = m_shortdata; } else { // In the long case, move the long allocated pointer m_data = rhs.m_data; rhs.m_data = rhs.m_shortdata; } } return *this; }
void string_concat(size_t nop, StringType &d, const StringType *const *s) { // Get the size of the concatenated string size_t size = 0; for (size_t i = 0; i != nop; ++i) { size += (s[i]->size()); } // Allocate the output d.resize(size); // Copy the string data char *dst = d.begin(); for (size_t i = 0; i != nop; ++i) { size_t op_size = (s[i]->size()); DYND_MEMCPY(dst, s[i]->begin(), op_size); dst += op_size; } }
/** When the object has no memory allocated and `size` is <= capacity(), do straight SSO assignment */ void sso_assign(const char *data, size_t size) { m_size = static_cast<int64_t>(static_cast<uint64_t>(size) << 56); DYND_MEMCPY(sso_data(), data, size); // Zero out the rest of the bytes for a unique representation memset(sso_data() + size, 0, 15u - size); }
/** Construct the shortvector with a specified size and initial data */ shortvector(size_t size, const T* data) : m_data((size <= staticN) ? m_shortdata : new T[size]) { DYND_MEMCPY(m_data, data, size * sizeof(T)); }