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