Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<valarray>: Implement copies for slice_array, gslice_array, mask_array, and indirect_array #988

Merged
merged 24 commits into from
Jul 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
e00b11a
#940 <valarray>: slice_array's copy ctor
AlexGuteniev Jul 4, 2020
563960d
license
AlexGuteniev Jul 4, 2020
a445153
one missed case
AlexGuteniev Jul 4, 2020
e10ba6a
Seems correct implementation of assignments
AlexGuteniev Jul 4, 2020
7c1ef11
missing ref
AlexGuteniev Jul 4, 2020
8c97417
Complete test
AlexGuteniev Jul 4, 2020
974ccb2
test warnings fix
AlexGuteniev Jul 4, 2020
b776945
optimize
AlexGuteniev Jul 4, 2020
7d4b040
whitespace
AlexGuteniev Jul 4, 2020
e4afd4b
Optimize `mask_array::operator=`
AlexGuteniev Jul 5, 2020
ae46fb4
clang format
AlexGuteniev Jul 5, 2020
662fbe9
_Right
AlexGuteniev Jul 5, 2020
dd3d547
Update stl/inc/valarray
AlexGuteniev Jul 6, 2020
243bb3a
Update stl/inc/valarray
AlexGuteniev Jul 6, 2020
5e7a331
Update stl/inc/valarray
AlexGuteniev Jul 6, 2020
8b84713
Update stl/inc/valarray
AlexGuteniev Jul 6, 2020
c5a2ba7
Merge remote-tracking branch 'upstream/master' into valarray
AlexGuteniev Jul 19, 2020
8c251df
Merge remote-tracking branch 'upstream/master' into valarray
AlexGuteniev Jul 25, 2020
471720c
Update tests/std/tests/GH_000940_missing_valarray_copy/test.cpp
AlexGuteniev Jul 28, 2020
caf1fc0
review comments
AlexGuteniev Jul 28, 2020
1a12d38
Merge branch 'valarray' of https://github.com/AlexGuteniev/STL into v…
AlexGuteniev Jul 28, 2020
454246e
move slices to avoid overlap
AlexGuteniev Jul 28, 2020
11e1412
Include algorithm and cstddef.
StephanTLavavej Jul 29, 2020
2a6a122
Merge branch 'master' into valarray
StephanTLavavej Jul 29, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 62 additions & 16 deletions stl/inc/valarray
Original file line number Diff line number Diff line change
Expand Up @@ -938,9 +938,16 @@ public:

slice_array() = delete;

slice_array(const slice_array&); // not defined
slice_array(const slice_array&) = default;

slice_array& operator=(const slice_array&); // not defined
const slice_array& operator=(const slice_array& _Right) const {
size_t _Dst_off = _Start;
size_t _Src_off = _Right._Start;
for (size_t _Idx = 0; _Idx < _Len; ++_Idx, _Dst_off += _Stride, _Src_off += _Right._Stride) {
_Myptr[_Dst_off] = _Right._Myptr[_Src_off];
}
return *this;
}

private:
friend valarray<_Ty>;
Expand Down Expand Up @@ -992,7 +999,7 @@ public:
return _Ans;
}

size_t _Totlen() const {
_NODISCARD size_t _Totlen() const {
if (_Len.size() == 0) {
return 0;
}
Expand Down Expand Up @@ -1073,15 +1080,23 @@ public:
_GSLOP(>>= _Right[_Idx]);
}

_Ty& _Data(size_t _Idx) const {
_NODISCARD _Ty& _Data(size_t _Idx) const {
return _Myptr[_Idx];
}

gslice_array() = delete;

gslice_array(const gslice_array&); // not defined
gslice_array(const gslice_array&) = default;

gslice_array& operator=(const gslice_array&); // not defined
const gslice_array& operator=(const gslice_array& _Right) const {
_Sizarray _Dst_indexarray(size_t{0}, _Nslice());
_Sizarray _Src_indexarray(size_t{0}, _Right._Nslice());
const size_t _Size = _Totlen();
for (size_t _Idx = 0; _Idx < _Size; ++_Idx) {
_Myptr[_Off(_Dst_indexarray)] = _Right._Myptr[_Right._Off(_Src_indexarray)];
}
return *this;
}

private:
friend valarray<_Ty>;
Expand Down Expand Up @@ -1155,15 +1170,32 @@ public:
_MOP(>>= _Right[_Idx]);
}

_Ty& _Data(size_t _Idx) const {
_NODISCARD _Ty& _Data(size_t _Idx) const {
return _Myptr[_Idx];
}

bool _Mask(size_t _Idx) const {
_NODISCARD bool _Mask(size_t _Idx) const {
return _Mybool[_Idx];
}

size_t _Totlen() const {
_NODISCARD size_t _Start_off() const {
size_t _Off = 0;
const size_t _Size = _Mybool.size();
while (_Off < _Size && !_Mybool[_Off]) {
++_Off;
}
return _Off;
}

_NODISCARD size_t _Next_off(size_t _Off) const {
const size_t _Size = _Mybool.size();
do {
++_Off;
} while (_Off < _Size && !_Mybool[_Off]);
return _Off;
}

_NODISCARD size_t _Totlen() const {
size_t _Count = 0;
for (size_t _Idx = 0; _Idx < _Mybool.size(); ++_Idx) {
if (_Mybool[_Idx]) {
Expand All @@ -1176,9 +1208,17 @@ public:

mask_array() = delete;

mask_array(const mask_array&); // not defined
mask_array(const mask_array&) = default;

mask_array& operator=(const mask_array&); // not defined
const mask_array& operator=(const mask_array& _Right) const {
const size_t _Size = _Mybool.size();
size_t _Dst_off = _Start_off();
size_t _Src_off = _Right._Start_off();
for (; _Dst_off < _Size; _Src_off = _Right._Next_off(_Src_off), _Dst_off = _Next_off(_Dst_off)) {
_Myptr[_Dst_off] = _Right._Myptr[_Src_off];
}
return *this;
}

private:
friend valarray<_Ty>;
Expand Down Expand Up @@ -1250,23 +1290,29 @@ public:
_IOP(>>= _Right[_Idx]);
}

_Ty& _Data(size_t _Idx) const {
_NODISCARD _Ty& _Data(size_t _Idx) const {
return _Myptr[_Idx];
}

size_t _Indir(size_t _Idx) const {
_NODISCARD size_t _Indir(size_t _Idx) const {
return _Myindarr[_Idx];
}

size_t _Totlen() const {
_NODISCARD size_t _Totlen() const {
return _Myindarr.size();
}

indirect_array() = delete;

indirect_array(const indirect_array&); // not defined
indirect_array(const indirect_array&) = default;

indirect_array& operator=(const indirect_array&); // not defined
const indirect_array& operator=(const indirect_array& _Right) const {
const size_t _Size = _Totlen();
for (size_t _Idx = 0; _Idx < _Size; ++_Idx) {
_Myptr[_Indir(_Idx)] = _Right._Myptr[_Right._Indir(_Idx)];
}
return *this;
}

private:
friend valarray<_Ty>;
Expand Down
4 changes: 0 additions & 4 deletions tests/libcxx/expected_results.txt
Original file line number Diff line number Diff line change
Expand Up @@ -565,10 +565,6 @@ std/re/re.traits/transform.pass.cpp FAIL
# STL bug: Incorrect return types.
std/numerics/complex.number/cmplx.over/pow.pass.cpp FAIL

# STL bug: Missing <valarray> assignment operators.
AlexGuteniev marked this conversation as resolved.
Show resolved Hide resolved
std/numerics/numarray/template.mask.array/mask.array.assign/mask_array.pass.cpp FAIL
std/numerics/numarray/template.slice.array/slice.arr.assign/slice_array.pass.cpp FAIL

# STL bug: We allow fill() and swap() for array<const T, 0>.
std/containers/sequences/array/array.fill/fill.fail.cpp FAIL
std/containers/sequences/array/array.swap/swap.fail.cpp FAIL
Expand Down
4 changes: 0 additions & 4 deletions tests/libcxx/skipped_tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -565,10 +565,6 @@ re\re.traits\transform.pass.cpp
# STL bug: Incorrect return types.
numerics\complex.number\cmplx.over\pow.pass.cpp

# STL bug: Missing <valarray> assignment operators.
numerics\numarray\template.mask.array\mask.array.assign\mask_array.pass.cpp
numerics\numarray\template.slice.array\slice.arr.assign\slice_array.pass.cpp

# STL bug: We allow fill() and swap() for array<const T, 0>.
containers\sequences\array\array.fill\fill.fail.cpp
containers\sequences\array\array.swap\swap.fail.cpp
Expand Down
1 change: 1 addition & 0 deletions tests/std/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ tests\GH_000545_include_compare
tests\GH_000685_condition_variable_any
tests\GH_000690_overaligned_function
tests\GH_000890_pow_template
tests\GH_000940_missing_valarray_copy
tests\GH_001010_filesystem_error_encoding
tests\GH_001017_discrete_distribution_out_of_range
tests\LWG2597_complex_branch_cut
Expand Down
4 changes: 4 additions & 0 deletions tests/std/tests/GH_000940_missing_valarray_copy/env.lst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

RUNALL_INCLUDE ..\usual_matrix.lst
87 changes: 87 additions & 0 deletions tests/std/tests/GH_000940_missing_valarray_copy/test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <algorithm>
#include <cassert>
#include <cstddef>
#include <iostream>
#include <valarray>

template <class T>
bool eq(const std::valarray<T>& v, std::initializer_list<T> il) {
return std::equal(begin(v), end(v), il.begin(), il.end());
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved
}

void test_slice() {
std::valarray<int> v{0, 1, 2, 3, 4};

std::slice_array<int> slice_array = v[std::slice(2, 2, 2)];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No change requested, just a stylistic comment - while we have tests that vary in their usage of using namespace std; and it's fine to std:: qualify everything, even when the namespace prevents ambiguity I think that naming things identically to Standard identifiers makes things unnecessarily hard to read/search. (Being able to search for all occurrences of slice_array in product and test code, and having few spurious results show up, is useful.) Any other names would be fine; e.g. slice_array_copy won't show up in a whole-word search.

Since it looks like this PR will be ready to merge with a couple of include fixups (yay!), I don't think it's worth renaming now, but I wanted to mention it.

std::slice_array<int> slice_array_copy = slice_array;
(void) slice_array_copy;

assert(eq(v, {0, 1, 2, 3, 4}));

std::slice_array<int> other_slice_array = v[std::slice(0, 2, 1)];
other_slice_array = slice_array;
AlexGuteniev marked this conversation as resolved.
Show resolved Hide resolved

assert(eq(v, {2, 4, 2, 3, 4}));
}

void test_gslice() {
std::valarray<int> v{0, 1, 2, 3, 4};

std::gslice gslice(2, std::valarray<std::size_t>{2}, std::valarray<std::size_t>{2});
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved
std::gslice_array<int> gslice_array = v[gslice];
std::gslice_array<int> gslice_array_copy = gslice_array;
(void) gslice_array_copy;

assert(eq(v, {0, 1, 2, 3, 4}));

std::gslice other_gslice(0, std::valarray<std::size_t>{2}, std::valarray<std::size_t>{1});
std::gslice_array<int> other_gslice_array = v[other_gslice];
other_gslice_array = gslice_array;
AlexGuteniev marked this conversation as resolved.
Show resolved Hide resolved

assert(eq(v, {2, 4, 2, 3, 4}));
}

void test_mask() {
std::valarray<int> v{0, 1, 2, 3, 4};

std::valarray<bool> mask{true, false, false, false, true};
std::mask_array<int> mask_array = v[mask];
std::mask_array<int> mask_array_copy = mask_array;
(void) mask_array_copy;

assert(eq(v, {0, 1, 2, 3, 4}));

std::valarray<bool> other_mask{false, true, true, false, false};
std::mask_array<int> other_mask_array = v[other_mask];
other_mask_array = mask_array;

assert(eq(v, {0, 0, 4, 3, 4}));
}

void test_indirect() {
std::valarray<int> v{0, 1, 2, 3, 4};

std::valarray<std::size_t> indices{2, 3};
std::indirect_array<int> indirect_array = v[indices];
std::indirect_array<int> indirect_array_copy = indirect_array;
(void) indirect_array_copy;

assert(eq(v, {0, 1, 2, 3, 4}));

std::valarray<std::size_t> other_indices{4, 0};
std::indirect_array<int> other_indirect_array = v[other_indices];
other_indirect_array = indirect_array;

assert(eq(v, {3, 1, 2, 3, 2}));
}

int main() {
test_slice();
test_gslice();
test_mask();
test_indirect();
return 0;
}