Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 343fa13

Browse files
committed
Replace array_view.size with an external helper
This currently checks if any dimension is 0, and returns the first dimension or 0. However, `pybind11::array_t.size()` returns the product of the shapes, so we want to be explicit when we need the former. I also checked the remaining `size` calls, and those will be fine with either interpretation, so I did not change them.
1 parent 02fa8fc commit 343fa13

File tree

4 files changed

+53
-31
lines changed

4 files changed

+53
-31
lines changed

src/_backend_agg.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -918,15 +918,15 @@ inline void RendererAgg::_draw_path_collection_generic(GCAgg &gc,
918918
typedef agg::conv_curve<clipped_t> curve_t;
919919

920920
size_t Npaths = path_generator.num_paths();
921-
size_t Noffsets = offsets.size();
921+
size_t Noffsets = safe_first_shape(offsets);
922922
size_t N = std::max(Npaths, Noffsets);
923923

924-
size_t Ntransforms = transforms.size();
925-
size_t Nfacecolors = facecolors.size();
926-
size_t Nedgecolors = edgecolors.size();
927-
size_t Nlinewidths = linewidths.size();
924+
size_t Ntransforms = safe_first_shape(transforms);
925+
size_t Nfacecolors = safe_first_shape(facecolors);
926+
size_t Nedgecolors = safe_first_shape(edgecolors);
927+
size_t Nlinewidths = safe_first_shape(linewidths);
928928
size_t Nlinestyles = std::min(linestyles.size(), N);
929-
size_t Naa = antialiaseds.size();
929+
size_t Naa = safe_first_shape(antialiaseds);
930930

931931
if ((Nfacecolors == 0 && Nedgecolors == 0) || Npaths == 0) {
932932
return;

src/_path.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ void point_in_path_impl(PointArray &points, PathIterator &path, ResultArray &ins
113113
size_t i;
114114
bool all_done;
115115

116-
size_t n = points.size();
116+
size_t n = safe_first_shape(points);
117117

118118
std::vector<uint8_t> yflag0(n);
119119
std::vector<uint8_t> subpath_flag(n);
@@ -247,7 +247,7 @@ inline void points_in_path(PointArray &points,
247247
typedef agg::conv_contour<curve_t> contour_t;
248248

249249
size_t i;
250-
for (i = 0; i < points.size(); ++i) {
250+
for (i = 0; i < safe_first_shape(points); ++i) {
251251
result[i] = false;
252252
}
253253

@@ -384,9 +384,9 @@ void get_path_collection_extents(agg::trans_affine &master_transform,
384384
}
385385

386386
size_t Npaths = paths.size();
387-
size_t Noffsets = offsets.size();
387+
size_t Noffsets = safe_first_shape(offsets);
388388
size_t N = std::max(Npaths, Noffsets);
389-
size_t Ntransforms = std::min(transforms.size(), N);
389+
size_t Ntransforms = std::min(safe_first_shape(transforms), N);
390390
size_t i;
391391

392392
agg::trans_affine trans;
@@ -436,9 +436,9 @@ void point_in_path_collection(double x,
436436
return;
437437
}
438438

439-
size_t Noffsets = offsets.size();
439+
size_t Noffsets = safe_first_shape(offsets);
440440
size_t N = std::max(Npaths, Noffsets);
441-
size_t Ntransforms = std::min(transforms.size(), N);
441+
size_t Ntransforms = std::min(safe_first_shape(transforms), N);
442442
size_t i;
443443

444444
agg::trans_affine trans;
@@ -776,7 +776,7 @@ int count_bboxes_overlapping_bbox(agg::rect_d &a, BBoxArray &bboxes)
776776
std::swap(a.y1, a.y2);
777777
}
778778

779-
size_t num_bboxes = bboxes.size();
779+
size_t num_bboxes = safe_first_shape(bboxes);
780780
for (size_t i = 0; i < num_bboxes; ++i) {
781781
b = agg::rect_d(bboxes(i, 0, 0), bboxes(i, 0, 1), bboxes(i, 1, 0), bboxes(i, 1, 1));
782782

src/array.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ class scalar
4040
}
4141
};
4242

43+
template <typename T, int ND>
44+
size_t
45+
safe_first_shape(scalar<T, ND>)
46+
{
47+
return 1;
48+
}
49+
4350
template <typename T>
4451
class empty
4552
{
@@ -75,6 +82,12 @@ class empty
7582
return 0;
7683
}
7784
};
85+
86+
template <typename T>
87+
size_t safe_first_shape(empty<T>)
88+
{
89+
return 0;
90+
}
7891
}
7992

8093
#endif

src/numpy_cpp.h

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -500,24 +500,7 @@ class array_view : public detail::array_view_accessors<array_view, T, ND>
500500
return m_shape[i];
501501
}
502502

503-
/*
504-
In most cases, code should use size() instead of dim(0), since
505-
size() == 0 when any dimension is 0.
506-
*/
507-
size_t size() const
508-
{
509-
bool empty = (ND == 0);
510-
for (size_t i = 0; i < ND; i++) {
511-
if (m_shape[i] == 0) {
512-
empty = true;
513-
}
514-
}
515-
if (empty) {
516-
return 0;
517-
} else {
518-
return (size_t)shape(0);
519-
}
520-
}
503+
size_t size() const;
521504

522505
// Do not use this for array_view<bool, ND>. See comment near top of file.
523506
const T *data() const
@@ -567,6 +550,32 @@ class array_view : public detail::array_view_accessors<array_view, T, ND>
567550
}
568551
};
569552

553+
/* In most cases, code should use safe_first_shape(obj) instead of obj.shape(0), since
554+
safe_first_shape(obj) == 0 when any dimension is 0. */
555+
template <typename T, int ND>
556+
size_t
557+
safe_first_shape(const array_view<T, ND> &a)
558+
{
559+
bool empty = (ND == 0);
560+
for (size_t i = 0; i < ND; i++) {
561+
if (a.shape(i) == 0) {
562+
empty = true;
563+
}
564+
}
565+
if (empty) {
566+
return 0;
567+
} else {
568+
return (size_t)a.shape(0);
569+
}
570+
}
571+
572+
template <typename T, int ND>
573+
size_t
574+
array_view<T, ND>::size() const
575+
{
576+
return safe_first_shape<T, ND>(*this);
577+
}
578+
570579
} // namespace numpy
571580

572581

0 commit comments

Comments
 (0)