<commit_before>// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once

#include "array.h"
#include <cstdlib>
#include <cstring>
#include <type_traits>

namespace vespalib {

template <typename T>
void construct(T * dest, const T * source, size_t sz, std::false_type)
{
    for (size_t i(0); i < sz; i++) {
        ::new (static_cast<void *>(dest + i)) T(*(source + i));
    }
}

template <typename T>
void construct(T * dest, const T * source, size_t sz, std::true_type)
{
    memcpy(dest, source, sz*sizeof(T));
}

template <typename T>
void construct(T * dest, size_t sz, std::false_type)
{
    for (size_t i(0); i < sz; i++) {
        void *ptr = &dest[i];
        new(ptr) T();
    }
}

template <typename T>
void construct(T * dest, size_t sz, std::true_type)
{
    (void) dest;
    (void) sz;
}

template <typename T>
void construct(T * dest, size_t sz, T val, std::false_type)
{
    for (size_t i(0); i < sz; i++) {
        void *ptr = &dest[i];
        new(ptr) T(val);
    }
}

template <typename T>
void construct(T * dest, size_t sz, T val, std::true_type)
{
    for (size_t i(0); i < sz; i++) {
        dest[i] = val;
    }
}

template <typename T>
Array<T>::Array(const Array & rhs)
    : _array(rhs._array.create(rhs.size() * sizeof(T))),
      _sz(rhs.size())
{
    construct(array(0), rhs.array(0), _sz, std::is_trivially_copyable<T>());
}

template <typename T>
Array<T> & Array<T>::operator =(const Array & rhs)
{
    if (&rhs != this) {
        Array t(rhs);
        swap(t);
    }
    return *this;
}

template <typename T>
Array<T> & Array<T>::operator =(Array && rhs) noexcept {
    if (&rhs != this) {<commit_msg>Don't try to memcpy from nullptr Array source even with zero size<commit_after>// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once

#include "array.h"
#include <cstdlib>
#include <cstring>
#include <type_traits>

namespace vespalib {

template <typename T>
void construct(T * dest, const T * source, size_t sz, std::false_type)
{
    for (size_t i(0); i < sz; i++) {
        ::new (static_cast<void *>(dest + i)) T(*(source + i));
    }
}

template <typename T>
void construct(T * dest, const T * source, size_t sz, std::true_type)
{
    memcpy(dest, source, sz*sizeof(T));
}

template <typename T>
void construct(T * dest, size_t sz, std::false_type)
{
    for (size_t i(0); i < sz; i++) {
        void *ptr = &dest[i];
        new(ptr) T();
    }
}

template <typename T>
void construct(T * dest, size_t sz, std::true_type)
{
    (void) dest;
    (void) sz;
}

template <typename T>
void construct(T * dest, size_t sz, T val, std::false_type)
{
    for (size_t i(0); i < sz; i++) {
        void *ptr = &dest[i];
        new(ptr) T(val);
    }
}

template <typename T>
void construct(T * dest, size_t sz, T val, std::true_type)
{
    for (size_t i(0); i < sz; i++) {
        dest[i] = val;
    }
}

template <typename T>
Array<T>::Array(const Array & rhs)
    : _array(rhs._array.create(rhs.size() * sizeof(T))),
      _sz(rhs.size())
{
    if (_sz > 0) [[likely]] {
        construct(array(0), rhs.array(0), _sz, std::is_trivially_copyable<T>());
    }
}

template <typename T>
Array<T> & Array<T>::operator =(const Array & rhs)
{
    if (&rhs != this) {
        Array t(rhs);
        swap(t);
    }
    return *this;
}

template <typename T>
Array<T> & Array<T>::operator =(Array && rhs) noexcept {
    if (&rhs != this) {
{'fraction_non_alphanumeric': 0.17191977077363896, 'fraction_numerical': 0.004871060171919771, 'mean_word_length': 3.2212817412333736, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 42, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4218318', 'n_tokens_mistral': 1308, 'n_tokens_neox': 1308, 'n_words': 381}