<commit_before>#include "../gtest.h"
#include "common.hpp"

#include <iostream>
#include <ostream>
// (Pending abstraction of threading interface)
#include <arbor/version.hpp>

#include "threading/threading.hpp"
#include "threading/enumerable_thread_specific.hpp"

using namespace arb::threading::impl;
using namespace arb::threading;
using namespace arb;
namespace {

std::atomic<int> nmove{0};
std::atomic<int> ncopy{0};

void reset() {
    nmove = 0;
    ncopy = 0;
}

struct ftor {

    ftor() {}

    ftor(ftor&& other) {
        ++nmove;
    }

    ftor(const ftor& other) {
        ++ncopy;
    }

    void operator()() const {}
};

struct ftor_wait {
    int duration_us = 100;

    ftor_wait() {}
    ftor_wait(int us): duration_us(us) {}

    void operator()() const {
        auto duration = std::chrono::microseconds(duration_us);
        std::this_thread::sleep_for(duration);
    }
};

struct ftor_parallel_wait {

    ftor_parallel_wait(task_system* ts): ts{ts} {}

    void operator()() const {
        auto nthreads = ts->get_num_threads();
        auto duration = std::chrono::microseconds(100);
        parallel_for::apply(0, nthreads, ts, [=](int i){ std::this_thread::sleep_for(duration);});
    }

    task_system* ts;
};

}

TEST(task_system, test_copy) {
    for (int nthreads = 1; nthreads < 20; nthreads*=2) {
        task_system ts(nthreads);

        ftor f;
        ts.async(f, 0);

        // Copy into new ftor and move ftor into a task (std::function<void()>)
        EXPECT_EQ(1, nmove);
        EXPECT_EQ(1, ncopy);
        reset();
    }
}

TEST(task_system, test_move) {
    for (int nthreads = 1; nthreads < 20; nthreads*=2) {
        task_system ts(nthreads);

        ftor f;
        ts.async(std::move(f), 0);

        // Move into new ftor and move ftor into a task (std::function<void()>)
        EXPECT_LE(nmove, 2);
        EXPECT_LE(ncopy, 1);
        reset();
    }
}

TEST(notification_queue, test_copy) {
    notification_queue q;

    ftor f;
    q.push({task(f), 0});

    // Copy into new ftor and move ftor into a task (std::function<void()>)
    EXPECT_EQ(1, nmove);
    EXPECT_EQ(1, ncopy);
    reset();
}

TEST(notification_queue, test_move) {
    notification_queue q;

    ftor f;

    // Move into new ftor and move ftor into a task (std::function<void()>)
    q.push({task(std::move(f)), 1});
    EXPECT_LE(nmove, 2);
    EXPECT_LE(ncopy, 1);
    reset();
}

TEST(task_group, test_copy) {
    for (int nthreads = 1; nthreads < 20; nthreads*=2) {
        task_system ts(nthreads);
        task_group g(&ts);

        ftor f;
        g.run(f);
        g.wait();

        // Copy into "wrap" and move wrap into a task (std::function<void()>)<commit_msg>remove checks for move ctor when it could be elided (#1899)<commit_after>#include "../gtest.h"
#include "common.hpp"

#include <iostream>
#include <ostream>
// (Pending abstraction of threading interface)
#include <arbor/version.hpp>

#include "threading/threading.hpp"
#include "threading/enumerable_thread_specific.hpp"

using namespace arb::threading::impl;
using namespace arb::threading;
using namespace arb;
namespace {

std::atomic<int> nmove{0};
std::atomic<int> ncopy{0};

void reset() {
    nmove = 0;
    ncopy = 0;
}

struct ftor {

    ftor() {}

    ftor(ftor&& other) {
        ++nmove;
    }

    ftor(const ftor& other) {
        ++ncopy;
    }

    void operator()() const {}
};

struct ftor_wait {
    int duration_us = 100;

    ftor_wait() {}
    ftor_wait(int us): duration_us(us) {}

    void operator()() const {
        auto duration = std::chrono::microseconds(duration_us);
        std::this_thread::sleep_for(duration);
    }
};

struct ftor_parallel_wait {

    ftor_parallel_wait(task_system* ts): ts{ts} {}

    void operator()() const {
        auto nthreads = ts->get_num_threads();
        auto duration = std::chrono::microseconds(100);
        parallel_for::apply(0, nthreads, ts, [=](int i){ std::this_thread::sleep_for(duration);});
    }

    task_system* ts;
};

}

TEST(task_system, test_copy) {
    for (int nthreads = 1; nthreads < 20; nthreads*=2) {
        task_system ts(nthreads);

        ftor f;
        ts.async(f, 0);

        // Copy into new ftor and move ftor into a task (std::function<void()>)
        // move ctor is elided with some compilers
        //EXPECT_EQ(1, nmove);
        EXPECT_EQ(1, ncopy);
        reset();
    }
}

TEST(task_system, test_move) {
    for (int nthreads = 1; nthreads < 20; nthreads*=2) {
        task_system ts(nthreads);

        ftor f;
        ts.async(std::move(f), 0);

        // Move into new ftor and move ftor into a task (std::function<void()>)
        EXPECT_LE(nmove, 2);
        EXPECT_LE(ncopy, 1);
        reset();
    }
}

TEST(notification_queue, test_copy) {
    notification_queue q;

    ftor f;
    q.push({task(f), 0});

    // Copy into new ftor and move ftor into a task (std::function<void()>)
    // move ctor is elided with some compilers
    //EXPECT_EQ(1, nmove);
    EXPECT_EQ(1, ncopy);
    reset();
}

TEST(notification_queue, test_move) {
    notification_queue q;

    ftor f;

    // Move into new ftor and move ftor into a task (std::function<void()>)
    q.push({task(std::move(f)), 1});
    EXPECT_LE(nmove, 2);
    EXPECT_LE(ncopy, 1);
    reset();
}

TEST(task_group, test_copy) {
    for (int nthreads = 1; nthreads < 20; nthreads*=2) {
        task_system ts(nthreads);
        task_group g(&ts);

        ftor f;
        g.run(f);
        g.wait();

        // Copy into "wrap" and move wrap into a task (std::function<void()>)
{'fraction_non_alphanumeric': 0.1482213438735178, 'fraction_numerical': 0.01329500538986705, 'mean_word_length': 2.8261168384879727, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 25, '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': '3188697', 'n_tokens_mistral': 2029, 'n_tokens_neox': 1934, 'n_words': 477}