8446b7
From bafffe7f2ca587960177ed03216e2d5692fe6143 Mon Sep 17 00:00:00 2001
8446b7
From: Karl Williamson <khw@cpan.org>
8446b7
Date: Wed, 19 Aug 2020 11:57:17 -0600
8446b7
Subject: [PATCH] Add av_count()
8446b7
MIME-Version: 1.0
8446b7
Content-Type: text/plain; charset=UTF-8
8446b7
Content-Transfer-Encoding: 8bit
8446b7
8446b7
This returns the number of elements in an array in a clearly named
8446b7
function.
8446b7
8446b7
av_top_index(), av_tindex() are clearly named, but are less than ideal,
8446b7
and came about because no one back then thought of this one, until now
8446b7
Paul Evans did.
8446b7
8446b7
Petr Písař: Port 87306e0674dfe3af29804b4641347cd5ac9b0521 to 5.32.0.
8446b7
8446b7
Signed-off-by: Petr Písař <ppisar@redhat.com>
8446b7
---
8446b7
 av.c      | 17 ++++++++++++++---
8446b7
 av.h      |  3 ++-
8446b7
 embed.fnc |  3 ++-
8446b7
 embed.h   |  2 +-
8446b7
 inline.h  | 16 ++++++++++++----
8446b7
 proto.h   | 11 ++++++++---
8446b7
 6 files changed, 39 insertions(+), 13 deletions(-)
8446b7
8446b7
diff --git a/av.c b/av.c
8446b7
index 27b2f12..b5ddaca 100644
8446b7
--- a/av.c
8446b7
+++ b/av.c
8446b7
@@ -814,9 +814,10 @@ The Perl equivalent for this is C<$#myarray>.
8446b7
 =for apidoc av_len
8446b7
 
8446b7
 Same as L</av_top_index>.  Note that, unlike what the name implies, it returns
8446b7
-the highest index in the array, so to get the size of the array you need to use
8446b7
-S<C<av_len(av) + 1>>.  This is unlike L</sv_len>, which returns what you would
8446b7
-expect.
8446b7
+the highest index in the array.  This is unlike L</sv_len>, which returns what
8446b7
+you would expect.
8446b7
+
8446b7
+B<To get the true number of elements in the array, instead use C<L</av_count>>>.
8446b7
 
8446b7
 =cut
8446b7
 */
8446b7
@@ -1089,6 +1090,16 @@ Perl_av_nonelem(pTHX_ AV *av, SSize_t ix) {
8446b7
     return sv;
8446b7
 }
8446b7
 
8446b7
+SSize_t
8446b7
+Perl_av_top_index(pTHX_ AV *av)
8446b7
+{
8446b7
+    PERL_ARGS_ASSERT_AV_TOP_INDEX;
8446b7
+    assert(SvTYPE(av) == SVt_PVAV);
8446b7
+
8446b7
+    return AvFILL(av);
8446b7
+}
8446b7
+
8446b7
+
8446b7
 /*
8446b7
  * ex: set ts=8 sts=4 sw=4 et:
8446b7
  */
8446b7
diff --git a/av.h b/av.h
8446b7
index 5e39c42..90ebfff 100644
8446b7
--- a/av.h
8446b7
+++ b/av.h
8446b7
@@ -81,7 +81,8 @@ Same as C<av_top_index()>.
8446b7
                                           
8446b7
 #define AvFILL(av)	((SvRMAGICAL((const SV *) (av))) \
8446b7
 			 ? mg_size(MUTABLE_SV(av)) : AvFILLp(av))
8446b7
-#define av_tindex(av)   av_top_index(av)
8446b7
+#define av_top_index(av) AvFILL(av)
8446b7
+#define av_tindex(av)    av_top_index(av)
8446b7
 
8446b7
 /* Note that it doesn't make sense to do this:
8446b7
  *      SvGETMAGIC(av); IV x = av_tindex_nomg(av);
8446b7
diff --git a/embed.fnc b/embed.fnc
8446b7
index 589ab1a..789cd3c 100644
8446b7
--- a/embed.fnc
8446b7
+++ b/embed.fnc
8446b7
@@ -541,7 +541,8 @@ Apd	|void	|av_push	|NN AV *av|NN SV *val
8446b7
 EXp	|void	|av_reify	|NN AV *av
8446b7
 ApdR	|SV*	|av_shift	|NN AV *av
8446b7
 Apd	|SV**	|av_store	|NN AV *av|SSize_t key|NULLOK SV *val
8446b7
-AidRp	|SSize_t|av_top_index	|NN AV *av
8446b7
+AMdRp	|SSize_t|av_top_index	|NN AV *av
8446b7
+AidRp	|Size_t	|av_count	|NN AV *av
8446b7
 AmdR	|SSize_t|av_tindex	|NN AV *av
8446b7
 Apd	|void	|av_undef	|NN AV *av
8446b7
 Apdoex	|SV**	|av_create_and_unshift_one|NN AV **const avp|NN SV *const val
8446b7
diff --git a/embed.h b/embed.h
8446b7
index 182b12a..329ac40 100644
8446b7
--- a/embed.h
8446b7
+++ b/embed.h
8446b7
@@ -48,6 +48,7 @@
8446b7
 #define atfork_lock		Perl_atfork_lock
8446b7
 #define atfork_unlock		Perl_atfork_unlock
8446b7
 #define av_clear(a)		Perl_av_clear(aTHX_ a)
8446b7
+#define av_count(a)		Perl_av_count(aTHX_ a)
8446b7
 #define av_delete(a,b,c)	Perl_av_delete(aTHX_ a,b,c)
8446b7
 #define av_exists(a,b)		Perl_av_exists(aTHX_ a,b)
8446b7
 #define av_extend(a,b)		Perl_av_extend(aTHX_ a,b)
8446b7
@@ -59,7 +60,6 @@
8446b7
 #define av_push(a,b)		Perl_av_push(aTHX_ a,b)
8446b7
 #define av_shift(a)		Perl_av_shift(aTHX_ a)
8446b7
 #define av_store(a,b,c)		Perl_av_store(aTHX_ a,b,c)
8446b7
-#define av_top_index(a)		Perl_av_top_index(aTHX_ a)
8446b7
 #define av_undef(a)		Perl_av_undef(aTHX_ a)
8446b7
 #define av_unshift(a,b)		Perl_av_unshift(aTHX_ a,b)
8446b7
 #define block_end(a,b)		Perl_block_end(aTHX_ a,b)
8446b7
diff --git a/inline.h b/inline.h
8446b7
index 27005d2..35af18a 100644
8446b7
--- a/inline.h
8446b7
+++ b/inline.h
8446b7
@@ -39,13 +39,21 @@ SOFTWARE.
8446b7
 
8446b7
 /* ------------------------------- av.h ------------------------------- */
8446b7
 
8446b7
-PERL_STATIC_INLINE SSize_t
8446b7
-Perl_av_top_index(pTHX_ AV *av)
8446b7
+/*
8446b7
+=for apidoc av_count
8446b7
+Returns the number of elements in the array C<av>.  This is the true length of
8446b7
+the array, including any undefined elements.  It is always the same as
8446b7
+S<C<av_top_index(av) + 1>>.
8446b7
+
8446b7
+=cut
8446b7
+*/
8446b7
+PERL_STATIC_INLINE Size_t
8446b7
+Perl_av_count(pTHX_ AV *av)
8446b7
 {
8446b7
-    PERL_ARGS_ASSERT_AV_TOP_INDEX;
8446b7
+    PERL_ARGS_ASSERT_AV_COUNT;
8446b7
     assert(SvTYPE(av) == SVt_PVAV);
8446b7
 
8446b7
-    return AvFILL(av);
8446b7
+    return AvFILL(av) + 1;
8446b7
 }
8446b7
 
8446b7
 /* ------------------------------- cv.h ------------------------------- */
8446b7
diff --git a/proto.h b/proto.h
8446b7
index 02ef4ed..83ba098 100644
8446b7
--- a/proto.h
8446b7
+++ b/proto.h
8446b7
@@ -219,6 +219,13 @@ PERL_CALLCONV SV**	Perl_av_arylen_p(pTHX_ AV *av);
8446b7
 PERL_CALLCONV void	Perl_av_clear(pTHX_ AV *av);
8446b7
 #define PERL_ARGS_ASSERT_AV_CLEAR	\
8446b7
 	assert(av)
8446b7
+#ifndef PERL_NO_INLINE_FUNCTIONS
8446b7
+PERL_STATIC_INLINE Size_t	Perl_av_count(pTHX_ AV *av)
8446b7
+			__attribute__warn_unused_result__;
8446b7
+#define PERL_ARGS_ASSERT_AV_COUNT	\
8446b7
+	assert(av)
8446b7
+#endif
8446b7
+
8446b7
 PERL_CALLCONV void	Perl_av_create_and_push(pTHX_ AV **const avp, SV *const val);
8446b7
 #define PERL_ARGS_ASSERT_AV_CREATE_AND_PUSH	\
8446b7
 	assert(avp); assert(val)
8446b7
@@ -284,12 +291,10 @@ PERL_CALLCONV SV**	Perl_av_store(pTHX_ AV *av, SSize_t key, SV *val);
8446b7
 			__attribute__warn_unused_result__; */
8446b7
 #define PERL_ARGS_ASSERT_AV_TINDEX
8446b7
 
8446b7
-#ifndef PERL_NO_INLINE_FUNCTIONS
8446b7
-PERL_STATIC_INLINE SSize_t	Perl_av_top_index(pTHX_ AV *av)
8446b7
+PERL_CALLCONV SSize_t	Perl_av_top_index(pTHX_ AV *av)
8446b7
 			__attribute__warn_unused_result__;
8446b7
 #define PERL_ARGS_ASSERT_AV_TOP_INDEX	\
8446b7
 	assert(av)
8446b7
-#endif
8446b7
 
8446b7
 PERL_CALLCONV void	Perl_av_undef(pTHX_ AV *av);
8446b7
 #define PERL_ARGS_ASSERT_AV_UNDEF	\
8446b7
-- 
8446b7
2.25.4
8446b7