Skip to content
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
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.
Comment thread
AlexGuteniev marked this conversation as 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());
Comment thread
StephanTLavavej marked this conversation as 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
Copy Markdown
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;
Comment thread
AlexGuteniev marked this conversation as 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});
Comment thread
StephanTLavavej marked this conversation as 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;
Comment thread
AlexGuteniev marked this conversation as 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;
}