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

Co-authored-by: S. B. Tam <cpplearner@outlook.com>
Co-authored-by: Casey Carter <cartec69@gmail.com>
Co-authored-by: Stephan T. Lavavej <stl@microsoft.com>
This commit is contained in:
Alex Guteniev 2020-07-30 06:30:29 +03:00 коммит произвёл GitHub
Родитель 35ce1cf44a
Коммит 0e7b5d2509
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 154 добавлений и 24 удалений

Просмотреть файл

@ -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>;
@ -992,7 +999,7 @@ public:
return _Ans;
}
size_t _Totlen() const {
_NODISCARD size_t _Totlen() const {
if (_Len.size() == 0) {
return 0;
}
@ -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>;
@ -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]) {
@ -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>;
@ -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>;

Просмотреть файл

@ -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.
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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -0,0 +1,4 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
RUNALL_INCLUDE ..\usual_matrix.lst

Просмотреть файл

@ -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());
}
void test_slice() {
std::valarray<int> v{0, 1, 2, 3, 4};
std::slice_array<int> slice_array = v[std::slice(2, 2, 2)];
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;
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});
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;
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;
}