This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Add av_count()
authorKarl Williamson <khw@cpan.org>
Wed, 19 Aug 2020 17:57:17 +0000 (11:57 -0600)
committerKarl Williamson <khw@cpan.org>
Wed, 19 Aug 2020 22:12:19 +0000 (16:12 -0600)
This returns the number of elements in an array in a clearly named
function.

av_top_index(), av_tindex() are clearly named, but are less than ideal,
and came about because no one back then thought of this one, until now
Paul Evans did.

av.c
av.h
embed.fnc
embed.h
inline.h
pod/perldelta.pod
proto.h

diff --git a/av.c b/av.c
index 27b2f12..b5ddaca 100644 (file)
--- a/av.c
+++ b/av.c
@@ -814,9 +814,10 @@ The Perl equivalent for this is C<$#myarray>.
 =for apidoc av_len
 
 Same as L</av_top_index>.  Note that, unlike what the name implies, it returns
-the highest index in the array, so to get the size of the array you need to use
-S<C<av_len(av) + 1>>.  This is unlike L</sv_len>, which returns what you would
-expect.
+the highest index in the array.  This is unlike L</sv_len>, which returns what
+you would expect.
+
+B<To get the true number of elements in the array, instead use C<L</av_count>>>.
 
 =cut
 */
@@ -1089,6 +1090,16 @@ Perl_av_nonelem(pTHX_ AV *av, SSize_t ix) {
     return sv;
 }
 
+SSize_t
+Perl_av_top_index(pTHX_ AV *av)
+{
+    PERL_ARGS_ASSERT_AV_TOP_INDEX;
+    assert(SvTYPE(av) == SVt_PVAV);
+
+    return AvFILL(av);
+}
+
+
 /*
  * ex: set ts=8 sts=4 sw=4 et:
  */
diff --git a/av.h b/av.h
index 5e39c42..90ebfff 100644 (file)
--- a/av.h
+++ b/av.h
@@ -81,7 +81,8 @@ Same as C<av_top_index()>.
                                           
 #define AvFILL(av)     ((SvRMAGICAL((const SV *) (av))) \
                         ? mg_size(MUTABLE_SV(av)) : AvFILLp(av))
-#define av_tindex(av)   av_top_index(av)
+#define av_top_index(av) AvFILL(av)
+#define av_tindex(av)    av_top_index(av)
 
 /* Note that it doesn't make sense to do this:
  *      SvGETMAGIC(av); IV x = av_tindex_nomg(av);
index 454e59d..efcaabf 100644 (file)
--- a/embed.fnc
+++ b/embed.fnc
@@ -542,7 +542,8 @@ Apd |void   |av_push        |NN AV *av|NN SV *val
 EXp    |void   |av_reify       |NN AV *av
 ApdR   |SV*    |av_shift       |NN AV *av
 Apd    |SV**   |av_store       |NN AV *av|SSize_t key|NULLOK SV *val
-AidRp  |SSize_t|av_top_index   |NN AV *av
+AMdRp  |SSize_t|av_top_index   |NN AV *av
+AidRp  |Size_t |av_count       |NN AV *av
 AmdR   |SSize_t|av_tindex      |NN AV *av
 Apd    |void   |av_undef       |NN AV *av
 Apdoex |SV**   |av_create_and_unshift_one|NN AV **const avp|NN SV *const val
diff --git a/embed.h b/embed.h
index fb7fef5..50706a7 100644 (file)
--- a/embed.h
+++ b/embed.h
@@ -48,6 +48,7 @@
 #define atfork_lock            Perl_atfork_lock
 #define atfork_unlock          Perl_atfork_unlock
 #define av_clear(a)            Perl_av_clear(aTHX_ a)
+#define av_count(a)            Perl_av_count(aTHX_ a)
 #define av_delete(a,b,c)       Perl_av_delete(aTHX_ a,b,c)
 #define av_exists(a,b)         Perl_av_exists(aTHX_ a,b)
 #define av_extend(a,b)         Perl_av_extend(aTHX_ a,b)
@@ -59,7 +60,6 @@
 #define av_push(a,b)           Perl_av_push(aTHX_ a,b)
 #define av_shift(a)            Perl_av_shift(aTHX_ a)
 #define av_store(a,b,c)                Perl_av_store(aTHX_ a,b,c)
-#define av_top_index(a)                Perl_av_top_index(aTHX_ a)
 #define av_undef(a)            Perl_av_undef(aTHX_ a)
 #define av_unshift(a,b)                Perl_av_unshift(aTHX_ a,b)
 #define block_end(a,b)         Perl_block_end(aTHX_ a,b)
index 8e9bef5..a8240ef 100644 (file)
--- a/inline.h
+++ b/inline.h
@@ -39,13 +39,21 @@ SOFTWARE.
 
 /* ------------------------------- av.h ------------------------------- */
 
-PERL_STATIC_INLINE SSize_t
-Perl_av_top_index(pTHX_ AV *av)
+/*
+=for apidoc av_count
+Returns the number of elements in the array C<av>.  This is the true length of
+the array, including any undefined elements.  It is always the same as
+S<C<av_top_index(av) + 1>>.
+
+=cut
+*/
+PERL_STATIC_INLINE Size_t
+Perl_av_count(pTHX_ AV *av)
 {
-    PERL_ARGS_ASSERT_AV_TOP_INDEX;
+    PERL_ARGS_ASSERT_AV_COUNT;
     assert(SvTYPE(av) == SVt_PVAV);
 
-    return AvFILL(av);
+    return AvFILL(av) + 1;
 }
 
 /* ------------------------------- cv.h ------------------------------- */
index 02bc20b..20662b5 100644 (file)
@@ -372,6 +372,11 @@ C<HINT_LOCALIZE_HH> bit, which complicates external code that inspects the
 save stack. The new version uses a different savestack type to indicate the
 difference.
 
+=item *
+
+A new API function L<perlapi/av_count> has been added which gives a
+clearly named way to find how many elements are in an array.
+
 =back
 
 =head1 Selected Bug Fixes
diff --git a/proto.h b/proto.h
index 3e5c654..1b030a9 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -219,6 +219,13 @@ PERL_CALLCONV SV** Perl_av_arylen_p(pTHX_ AV *av);
 PERL_CALLCONV void     Perl_av_clear(pTHX_ AV *av);
 #define PERL_ARGS_ASSERT_AV_CLEAR      \
        assert(av)
+#ifndef PERL_NO_INLINE_FUNCTIONS
+PERL_STATIC_INLINE Size_t      Perl_av_count(pTHX_ AV *av)
+                       __attribute__warn_unused_result__;
+#define PERL_ARGS_ASSERT_AV_COUNT      \
+       assert(av)
+#endif
+
 PERL_CALLCONV void     Perl_av_create_and_push(pTHX_ AV **const avp, SV *const val);
 #define PERL_ARGS_ASSERT_AV_CREATE_AND_PUSH    \
        assert(avp); assert(val)
@@ -284,12 +291,10 @@ PERL_CALLCONV SV**        Perl_av_store(pTHX_ AV *av, SSize_t key, SV *val);
                        __attribute__warn_unused_result__; */
 #define PERL_ARGS_ASSERT_AV_TINDEX
 
-#ifndef PERL_NO_INLINE_FUNCTIONS
-PERL_STATIC_INLINE SSize_t     Perl_av_top_index(pTHX_ AV *av)
+PERL_CALLCONV SSize_t  Perl_av_top_index(pTHX_ AV *av)
                        __attribute__warn_unused_result__;
 #define PERL_ARGS_ASSERT_AV_TOP_INDEX  \
        assert(av)
-#endif
 
 PERL_CALLCONV void     Perl_av_undef(pTHX_ AV *av);
 #define PERL_ARGS_ASSERT_AV_UNDEF      \