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