Skip to content

Commit 34ed69a

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents 1d158a9 + 961722d commit 34ed69a

11 files changed

Lines changed: 149 additions & 16 deletions

File tree

.github/workflows/linux.yml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@ defaults:
1212
shell: bash -e -l {0}
1313
jobs:
1414
build:
15-
runs-on: ubuntu-24.04
16-
name: ${{ matrix.sys.compiler }} ${{ matrix.sys.version }} - ${{ matrix.sys.name }}
15+
runs-on: ${{ matrix.os }}
16+
name: ${{ matrix.os }} ${{ matrix.sys.compiler }} ${{ matrix.sys.version }} - ${{ matrix.sys.name }}
1717
strategy:
1818
fail-fast: false
1919
matrix:
20+
os: [ubuntu-24.04, ubuntu-24.04-arm]
2021
sys:
2122
- {compiler: clang, version: '17', name: assert, flags: -DXTENSOR_ENABLE_ASSERT=ON}
2223
- {compiler: clang, version: '18', name: column-major, flags: -DDEFAULT_COLUMN_MAJOR=ON}
@@ -38,6 +39,16 @@ jobs:
3839
# - {compiler: gcc, version: '15', name: tbb, flags: -DXTENSOR_USE_TBB=ON -DTBB_INCLUDE_DIR=$CONDA_PREFIX/include -DTBB_LIBRARY=$CONDA_PREFIX/lib}
3940
# - {compiler: gcc, version: '16', name: xsimd-tbb, flags: -DXTENSOR_USE_XSIMD=ON -DXTENSOR_USE_TBB=ON}
4041
# - {compiler: gcc, version: '16', name: tbb, flags: -DXTENSOR_USE_TBB=ON -DTBB_INCLUDE_DIR=$CONDA_PREFIX/include -DTBB_LIBRARY=$CONDA_PREFIX/lib}
42+
exclude:
43+
- os: ubuntu-24.04-arm
44+
sys:
45+
compiler: gcc
46+
version: '12'
47+
- os: ubuntu-24.04-arm
48+
sys:
49+
compiler: gcc
50+
version: '11'
51+
4152
steps:
4253
- name: Install GCC
4354
if: matrix.sys.compiler == 'gcc'

include/xtensor/containers/xcontainer.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -997,10 +997,10 @@ namespace xt
997997
template <class S>
998998
inline void xstrided_container<D>::resize(S&& shape, bool force)
999999
{
1000-
XTENSOR_ASSERT_MSG(
1000+
XTENSOR_PRECONDITION(
10011001
detail::check_resize_dimension(m_shape, shape),
10021002
"cannot change the number of dimensions of xtensor"
1003-
)
1003+
);
10041004
std::size_t dim = shape.size();
10051005
if (m_shape.size() != dim || !std::equal(std::begin(shape), std::end(shape), std::begin(m_shape))
10061006
|| force)

include/xtensor/core/xfunction.hpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,7 @@ namespace xt
608608
// leading to warning about signed/unsigned conversions in the deeper layers of the access methods
609609

610610
return std::apply(
611-
[&](auto&... e)
611+
[&](auto&... e) -> const_reference
612612
{
613613
XTENSOR_TRY(check_index(shape(), args...));
614614
XTENSOR_CHECK_DIMENSION(shape(), args...);
@@ -631,7 +631,7 @@ namespace xt
631631
inline auto xfunction<F, CT...>::flat(size_type index) const -> const_reference
632632
{
633633
return std::apply(
634-
[&](auto&... e)
634+
[&](auto&... e) -> const_reference
635635
{
636636
return m_f(e.data_element(index)...);
637637
},
@@ -665,7 +665,7 @@ namespace xt
665665
// The static cast prevents the compiler from instantiating the template methods with signed integers,
666666
// leading to warning about signed/unsigned conversions in the deeper layers of the access methods
667667
return std::apply(
668-
[&](const auto&... e)
668+
[&](const auto&... e) -> const_reference
669669
{
670670
return m_f(e.unchecked(static_cast<size_type>(args)...)...);
671671
},
@@ -685,7 +685,7 @@ namespace xt
685685
inline auto xfunction<F, CT...>::element(It first, It last) const -> const_reference
686686
{
687687
return std::apply(
688-
[&](auto&... e)
688+
[&](auto&... e) -> const_reference
689689
{
690690
XTENSOR_TRY(check_element_index(shape(), first, last));
691691
return m_f(e.element(first, last)...);
@@ -826,7 +826,7 @@ namespace xt
826826
inline auto xfunction<F, CT...>::data_element(size_type i) const -> const_reference
827827
{
828828
return std::apply(
829-
[&](auto&... e)
829+
[&](auto&... e) -> const_reference
830830
{
831831
return m_f(e.data_element(i)...);
832832
},
@@ -957,7 +957,7 @@ namespace xt
957957
inline auto xfunction_iterator<F, CT...>::operator*() const -> reference
958958
{
959959
return std::apply(
960-
[&](auto&... it)
960+
[&](auto&... it) -> reference
961961
{
962962
return (p_f->m_f)(*it...);
963963
},
@@ -1109,7 +1109,7 @@ namespace xt
11091109
inline auto xfunction_stepper<F, CT...>::operator*() const -> reference
11101110
{
11111111
return std::apply(
1112-
[&](auto&... e)
1112+
[&](auto&... e) -> reference
11131113
{
11141114
return (p_f->m_f)(*e...);
11151115
},

include/xtensor/core/xmath.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -606,13 +606,13 @@ namespace xt
606606
template <class A1, class A2, class A3>
607607
constexpr auto operator()(const A1& v, const A2& lo, const A3& hi) const
608608
{
609-
return xtl::select(v < lo, lo, xtl::select(hi < v, hi, v));
609+
return xtl::select(lo < hi, xtl::select(v < lo, lo, xtl::select(hi < v, hi, v)), hi);
610610
}
611611

612612
template <class A1, class A2, class A3>
613613
constexpr auto simd_apply(const A1& v, const A2& lo, const A3& hi) const
614614
{
615-
return xt_simd::select(v < lo, lo, xt_simd::select(hi < v, hi, v));
615+
return xt_simd::select(lo < hi, xt_simd::select(v < lo, lo, xt_simd::select(hi < v, hi, v)), hi);
616616
}
617617
};
618618

include/xtensor/io/xcsv.hpp

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,47 @@ namespace xt
274274
}
275275
};
276276

277+
template <class E>
278+
void dump_csv(std::ostream& stream, const xexpression<E>& e, const xcsv_config& config)
279+
{
280+
using size_type = typename E::size_type;
281+
const E& ex = e.derived_cast();
282+
if (ex.dimension() == 1)
283+
{
284+
const size_type n = ex.shape()[0];
285+
for (size_type i = 0; i != n; ++i)
286+
{
287+
stream << ex(i);
288+
if (i != n - 1)
289+
{
290+
stream << config.delimiter;
291+
}
292+
}
293+
stream << std::endl;
294+
}
295+
else if (ex.dimension() == 2)
296+
{
297+
const size_type nbrows = ex.shape()[0];
298+
const size_type nbcols = ex.shape()[1];
299+
for (size_type r = 0; r != nbrows; ++r)
300+
{
301+
for (size_type c = 0; c != nbcols; ++c)
302+
{
303+
stream << ex(r, c);
304+
if (c != nbcols - 1)
305+
{
306+
stream << config.delimiter;
307+
}
308+
}
309+
stream << std::endl;
310+
}
311+
}
312+
else
313+
{
314+
XTENSOR_THROW(std::runtime_error, "Only 1-D and 2-D expressions can be serialized to CSV");
315+
}
316+
}
317+
277318
template <class E>
278319
void load_file(std::istream& stream, xexpression<E>& e, const xcsv_config& config)
279320
{
@@ -287,9 +328,9 @@ namespace xt
287328
}
288329

289330
template <class E>
290-
void dump_file(std::ostream& stream, const xexpression<E>& e, const xcsv_config&)
331+
void dump_file(std::ostream& stream, const xexpression<E>& e, const xcsv_config& config)
291332
{
292-
dump_csv(stream, e);
333+
dump_csv(stream, e, config);
293334
}
294335
}
295336

include/xtensor/io/xio.hpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "../core/xexpression.hpp"
2121
#include "../core/xmath.hpp"
2222
#include "../views/xstrided_view.hpp"
23+
#include "xtl/xmasked_value_meta.hpp"
2324

2425
namespace xt
2526
{
@@ -646,7 +647,14 @@ namespace xt
646647
void update(const_reference val)
647648
{
648649
std::stringstream buf;
649-
buf << val;
650+
if constexpr (xtl::is_xmasked_value<value_type>::value)
651+
{
652+
buf << +val;
653+
}
654+
else
655+
{
656+
buf << val;
657+
}
650658
std::string s = buf.str();
651659
if (int(s.size()) > m_width)
652660
{

test/test_xassign.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "xtensor/containers/xtensor.hpp"
1616
#include "xtensor/core/xassign.hpp"
1717
#include "xtensor/core/xnoalias.hpp"
18+
#include "xtensor/misc/xmanipulation.hpp"
1819

1920
#include "test_common.hpp"
2021
#include "test_common_macros.hpp"
@@ -167,4 +168,10 @@ namespace xt
167168
EXPECT_EQ(a.shape(1), 3);
168169
}
169170
}
171+
172+
TEST(xassign, fixed_dimension_mismatch)
173+
{
174+
auto a = xt::xtensor<float, 1>::from_shape({2});
175+
XT_ASSERT_THROW(a = xt::expand_dims(a, 0), std::runtime_error);
176+
}
170177
}

test/test_xcsv.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,4 +162,28 @@ namespace xt
162162

163163
XT_EXPECT_THROW(dump_csv(res, data), std::runtime_error);
164164
}
165+
166+
TEST(xcsv, dump_with_config)
167+
{
168+
xtensor<double, 2> data{{1.0, 2.0, 3.0, 4.0}, {10.0, 12.0, 15.0, 18.0}};
169+
170+
std::stringstream res;
171+
172+
xcsv_config config;
173+
config.delimiter = ' ';
174+
dump_csv(res, data, config);
175+
ASSERT_EQ("1 2 3 4\n10 12 15 18\n", res.str());
176+
}
177+
178+
TEST(xcsv, dump_file_with_config)
179+
{
180+
xtensor<double, 2> data{{1.0, 2.0, 3.0, 4.0}, {10.0, 12.0, 15.0, 18.0}};
181+
182+
std::stringstream res;
183+
184+
xcsv_config config;
185+
config.delimiter = ';';
186+
dump_file(res, data, config);
187+
ASSERT_EQ("1;2;3;4\n10;12;15;18\n", res.str());
188+
}
165189
}

test/test_xfunction.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "xtensor/containers/xarray.hpp"
1111
#include "xtensor/containers/xfixed.hpp"
1212
#include "xtensor/containers/xtensor.hpp"
13+
#include "xtensor/core/xvectorize.hpp"
1314
#include "xtensor/generators/xrandom.hpp"
1415
#include "xtensor/views/xview.hpp"
1516

@@ -193,6 +194,21 @@ namespace xt
193194
}
194195
}
195196

197+
TEST(xfunction, access_dangling_reference)
198+
{
199+
auto values_original = xt::xtensor<double, 1>{1., 2., 3.};
200+
auto indexes = xt::arange<size_t>(values_original.size());
201+
auto map = [&](const size_t& index) -> auto&
202+
{
203+
return values_original[index];
204+
};
205+
auto values_mapped = xt::vectorize(map)(indexes);
206+
for (size_t i = 0; i < values_original.size(); ++i)
207+
{
208+
EXPECT_TRUE(&(values_mapped[i]) == &(values_original[i]));
209+
}
210+
}
211+
196212
TEST(xfunction, unchecked)
197213
{
198214
xfunction_features f;

test/test_xmasked_view.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
* The full license is in the file LICENSE, distributed with this software. *
88
****************************************************************************/
99

10+
#include <sstream>
11+
1012
#include "xtensor/io/xio.hpp"
1113
#include "xtensor/optional/xoptional_assembly.hpp"
1214
#include "xtensor/views/xmasked_view.hpp"
@@ -210,6 +212,21 @@ namespace xt
210212
EXPECT_EQ(data, expected2);
211213
}
212214

215+
TEST(xmasked_view, non_optional_data_stream)
216+
{
217+
const xarray<double> data = {{1., 5., 3.}, {4., 5., 6.}};
218+
const xarray<bool> mask = {{true, false, false}, {false, true, false}};
219+
220+
const auto masked_data = masked_view(data, mask);
221+
222+
std::stringstream out;
223+
out << masked_data;
224+
225+
const std::string expected = "{{ 1, masked, masked},\n"
226+
" {masked, 5, masked}}";
227+
EXPECT_EQ(out.str(), expected);
228+
}
229+
213230
TEST(xmasked_view, assign)
214231
{
215232
xarray<double> data = {{1., -2., 3.}, {4., 5., -6.}, {7., 8., -9.}};

0 commit comments

Comments
 (0)