This is an archive of the discontinued LLVM Phabricator instance.

[libcxx] Fix transform_reduce mishandling move-only types, and nonstandard macro use in tests.
ClosedPublic

Authored by BillyONeal on Dec 18 2017, 5:32 PM.

Details

Summary
  • Remove _VSTD use and remove C++03-isms in C++17 tests for transform_reduce.
  • Add tests for all the transform_reduce overloads that pass in a move-only type.
  • Repair missing move in libc++ product code.

Diff Detail

Event Timeline

BillyONeal created this revision.Dec 18 2017, 5:32 PM
BillyONeal added inline comments.Dec 18 2017, 5:35 PM
test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp
61

Should these go in MoveOnly.h ?

BillyONeal added inline comments.Dec 18 2017, 5:55 PM
include/numeric
245

It's arguable that this should be _VSTD::move(__init); I asked SG1 / LEWG about that. (After all, if they're going to make inner_product do that this should too)

mclow.lists accepted this revision.Dec 18 2017, 7:50 PM

The rest of this LGTM.

test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp
61

I think so. While you're at it, you can remove the friend declaration in MoveOnly - that's a remnant.

This revision is now accepted and ready to land.Dec 18 2017, 7:50 PM

Do you folks want me to port this test case for move-only T into libcxx? (I added this to our test harness) Note that discussion on validity is ongoing on lists.

#define _SILENCE_PARALLEL_ALGORITHMS_EXPERIMENTAL_WARNING
#include <stdlib.h>
#include <algorithm>
#include <execution>
#include <memory>
#include <iterator>
#include <numeric>
#include <utility>
#include <vector>
#include <parallel_algorithms_utilities.hpp>
#include <pmretvals.h>

using namespace std;
using namespace std::execution;

void verify(const bool b) {
    if (!b) {
        exit(PM_TEST_FAIL);
    }
}

vector<unique_ptr<vector<unsigned int>>> get_move_only_test_data(const size_t testSize) {
    vector<unique_ptr<vector<unsigned int>>> testData;
    testData.reserve(testSize);
    for (size_t idx = 0; idx < testSize; ++idx) {
        testData.emplace_back(make_unique<vector<unsigned int>>(1, static_cast<unsigned int>(idx)));
    }

    return testData;
}

template<class ExPo>
void test_case_move_only(const size_t testSize, ExPo&& exec) {
    auto testData = get_move_only_test_data(testSize);
    unique_ptr<vector<unsigned int>> result = transform_reduce(std::forward<ExPo>(exec),
        make_move_iterator(testData.begin()), make_move_iterator(testData.end()),
        make_unique<vector<unsigned int>>(),
        [](unique_ptr<vector<unsigned int>> lhs, unique_ptr<vector<unsigned int>> rhs) {
            lhs->insert(lhs->end(), rhs->begin(), rhs->end());
            return lhs;
        },
        [](unique_ptr<vector<unsigned int>> target) {
            verify(target->size() == 1); // should only be called directly on the input sequence
            target->back() *= 10;
            return target;
        });

    sort(result->begin(), result->end());
    for (size_t idx = 0; idx < testSize; ++idx) {
        verify((*result)[idx] == idx * 10);
    }
}

int main() {
    parallel_test_case(test_case_move_only<const sequenced_policy&>, seq);
    parallel_test_case(test_case_move_only<const parallel_policy&>, par);
    return PM_TEST_PASS;
}
include/numeric
245

Any comment on whether these should have extra moves added @mclow.lists ?

test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp
61

Should I also add op== and op< while I'm in there for testing things like sort?

BillyONeal updated this revision to Diff 128695.Jan 4 2018, 5:30 PM
BillyONeal marked 5 inline comments as done.

Moved things to MoveOnly.h.

BillyONeal closed this revision.Jan 4 2018, 5:34 PM