LCOV - code coverage report
Current view: top level - gcc - vec.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 85.4 % 452 386
Test Date: 2026-02-28 14:20:25 Functions: 78.9 % 38 30
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Vector API for GNU compiler.
       2              :    Copyright (C) 2004-2026 Free Software Foundation, Inc.
       3              :    Contributed by Nathan Sidwell <nathan@codesourcery.com>
       4              :    Re-implemented in C++ by Diego Novillo <dnovillo@google.com>
       5              : 
       6              : This file is part of GCC.
       7              : 
       8              : GCC is free software; you can redistribute it and/or modify it under
       9              : the terms of the GNU General Public License as published by the Free
      10              : Software Foundation; either version 3, or (at your option) any later
      11              : version.
      12              : 
      13              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      14              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      15              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      16              : for more details.
      17              : 
      18              : You should have received a copy of the GNU General Public License
      19              : along with GCC; see the file COPYING3.  If not see
      20              : <http://www.gnu.org/licenses/>.  */
      21              : 
      22              : /* This file is compiled twice: once for the generator programs
      23              :    once for the compiler.  */
      24              : #ifdef GENERATOR_FILE
      25              : #include "bconfig.h"
      26              : #else
      27              : #include "config.h"
      28              : #endif
      29              : 
      30              : #include "system.h"
      31              : #include "coretypes.h"
      32              : #include "hash-table.h"
      33              : #include "selftest.h"
      34              : #ifdef GENERATOR_FILE
      35              : #include "errors.h"
      36              : #else
      37              : #include "input.h"
      38              : #include "diagnostic-core.h"
      39              : #endif
      40              : 
      41              : /* Vector memory usage.  */
      42              : class vec_usage: public mem_usage
      43              : {
      44              : public:
      45              :   /* Default constructor.  */
      46            0 :   vec_usage (): m_items (0), m_items_peak (0), m_element_size (0) {}
      47              : 
      48              :   /* Constructor.  */
      49            0 :   vec_usage (size_t allocated, size_t times, size_t peak,
      50              :              size_t items, size_t items_peak, size_t element_size)
      51            0 :     : mem_usage (allocated, times, peak),
      52            0 :     m_items (items), m_items_peak (items_peak),
      53            0 :     m_element_size (element_size) {}
      54              : 
      55              :   /* Sum the usage with SECOND usage.  */
      56              :   vec_usage
      57            0 :   operator+ (const vec_usage &second)
      58              :   {
      59            0 :     return vec_usage (m_allocated + second.m_allocated,
      60            0 :                       m_times + second.m_times,
      61            0 :                       m_peak + second.m_peak,
      62            0 :                       m_items + second.m_items,
      63            0 :                       m_items_peak + second.m_items_peak, 0);
      64              :   }
      65              : 
      66              :   /* Dump usage coupled to LOC location, where TOTAL is sum of all rows.  */
      67              :   inline void
      68            0 :   dump (mem_location *loc, mem_usage &total) const
      69              :   {
      70            0 :     char s[4096];
      71            0 :     sprintf (s, "%s:%i (%s)", loc->get_trimmed_filename (),
      72              :              loc->m_line, loc->m_function);
      73              : 
      74            0 :     s[48] = '\0';
      75              : 
      76            0 :     fprintf (stderr,
      77              :              "%-48s %10" PRIu64 PRsa (10) ":%4.1f%%" PRsa (9) "%10" PRIu64
      78              :              ":%4.1f%%" PRsa (10) PRsa (10) "\n",
      79              :              s,
      80            0 :              (uint64_t)m_element_size,
      81            0 :              SIZE_AMOUNT (m_allocated),
      82            0 :              m_allocated * 100.0 / total.m_allocated,
      83            0 :              SIZE_AMOUNT (m_peak), (uint64_t)m_times,
      84            0 :              m_times * 100.0 / total.m_times,
      85            0 :              SIZE_AMOUNT (m_items), SIZE_AMOUNT (m_items_peak));
      86            0 :   }
      87              : 
      88              :   /* Dump footer.  */
      89              :   inline void
      90            0 :   dump_footer ()
      91              :   {
      92            0 :     fprintf (stderr, "%s" PRsa (64) PRsa (25) PRsa (16) "\n",
      93            0 :              "Total", SIZE_AMOUNT (m_allocated),
      94            0 :              SIZE_AMOUNT (m_times), SIZE_AMOUNT (m_items));
      95            0 :   }
      96              : 
      97              :   /* Dump header with NAME.  */
      98              :   static inline void
      99            0 :   dump_header (const char *name)
     100              :   {
     101            0 :     fprintf (stderr, "%-48s %10s%11s%16s%10s%17s%11s\n", name, "sizeof(T)",
     102              :              "Leak", "Peak", "Times", "Leak items", "Peak items");
     103            0 :   }
     104              : 
     105              :   /* Current number of items allocated.  */
     106              :   size_t m_items;
     107              :   /* Peak value of number of allocated items.  */
     108              :   size_t m_items_peak;
     109              :   /* Size of element of the vector.  */
     110              :   size_t m_element_size;
     111              : };
     112              : 
     113              : /* Vector memory description.  */
     114              : static mem_alloc_description <vec_usage> vec_mem_desc;
     115              : 
     116              : /* Account the overhead.  */
     117              : 
     118              : void
     119            0 : vec_prefix::register_overhead (void *ptr, size_t elements,
     120              :                                size_t element_size MEM_STAT_DECL)
     121              : {
     122            0 :   vec_mem_desc.register_descriptor (ptr, VEC_ORIGIN, false
     123              :                                     FINAL_PASS_MEM_STAT);
     124            0 :   vec_usage *usage
     125            0 :     = vec_mem_desc.register_instance_overhead (elements * element_size, ptr);
     126            0 :   usage->m_element_size = element_size;
     127            0 :   usage->m_items += elements;
     128            0 :   if (usage->m_items_peak < usage->m_items)
     129            0 :     usage->m_items_peak = usage->m_items;
     130            0 : }
     131              : 
     132              : /* Notice that the memory allocated for the vector has been freed.  */
     133              : 
     134              : void
     135            0 : vec_prefix::release_overhead (void *ptr, size_t size, size_t elements,
     136              :                               bool in_dtor MEM_STAT_DECL)
     137              : {
     138            0 :   if (!vec_mem_desc.contains_descriptor_for_instance (ptr))
     139            0 :     vec_mem_desc.register_descriptor (ptr, VEC_ORIGIN,
     140              :                                       false FINAL_PASS_MEM_STAT);
     141            0 :   vec_usage *usage = vec_mem_desc.release_instance_overhead (ptr, size,
     142              :                                                              in_dtor);
     143            0 :   usage->m_items -= elements;
     144            0 : }
     145              : 
     146              : /* Calculate the number of slots to reserve a vector, making sure that
     147              :    it is of at least DESIRED size by growing ALLOC exponentially.  */
     148              : 
     149              : unsigned
     150    995675770 : vec_prefix::calculate_allocation_1 (unsigned alloc, unsigned desired)
     151              : {
     152              :   /* We must have run out of room.  */
     153    995675770 :   gcc_assert (alloc < desired);
     154              : 
     155              :   /* Exponential growth. */
     156    995675770 :   if (!alloc)
     157              :     alloc = 4;
     158    995675770 :   else if (alloc < 16)
     159              :     /* Double when small.  */
     160    852343758 :     alloc = alloc * 2;
     161              :   else
     162              :     /* Grow slower when large.  */
     163    143332012 :     alloc = (alloc * 3 / 2);
     164              : 
     165              :   /* If this is still too small, set it to the right size. */
     166    995675770 :   if (alloc < desired)
     167              :     alloc = desired;
     168    995675770 :   return alloc;
     169              : }
     170              : 
     171              : /* Dump per-site memory statistics.  */
     172              : 
     173              : void
     174            0 : dump_vec_loc_statistics (void)
     175              : {
     176            0 :   vec_mem_desc.dump (VEC_ORIGIN);
     177            0 : }
     178              : 
     179              : /* Gets the next token from STR delimited by DELIMS (deliminator not included
     180              :    in returned string).
     181              : 
     182              :    Updates STR to be the remaining string after the given token.
     183              : 
     184              :    STR and DELIMS must both be valid string_slices.
     185              : 
     186              :    If there aren't any of the chars in DELIM in STR (ie no more tokens in STR)
     187              :    then returns the string, and updates STR to be invalid.  */
     188              : string_slice
     189          630 : string_slice::tokenize (string_slice *str, string_slice delims)
     190              : {
     191          630 :   const char *ptr = str->begin ();
     192              : 
     193          630 :   gcc_assert (str->is_valid () && delims.is_valid ());
     194              : 
     195         4976 :   for (; ptr < str->end (); ptr++)
     196         9036 :     for (char c : delims)
     197         4690 :       if (*ptr == c)
     198              :         {
     199              :           /* Update the input string to be the remaining string.  */
     200           76 :           const char *str_begin = str->begin ();
     201           76 :           *str = string_slice (ptr  + 1, str->end ());
     202           76 :           return string_slice (str_begin, ptr);
     203              :         }
     204              : 
     205              :   /* If no deliminators between the start and end, return the whole string.  */
     206          554 :   string_slice res = *str;
     207          554 :   *str = string_slice::invalid ();
     208          554 :   return res;
     209              : }
     210              : 
     211              : /* Compares the string_slices STR1 and STR2 giving a lexograpical ordering.
     212              :    Returns -1 if STR1 comes before STR2, 1 if STR1 comes after, and 0 if the
     213              :    string_slices have the same contents.  */
     214              : 
     215              : int
     216           32 : string_slice::strcmp (string_slice str1, string_slice str2)
     217              : {
     218           56 :   for (unsigned int i = 0; i < str1.size () && i < str2.size (); i++)
     219              :     {
     220           32 :       if (str1[i] < str2[i])
     221              :         return -1;
     222           28 :       if (str1[i] > str2[i])
     223              :         return 1;
     224              :     }
     225              : 
     226           24 :   if (str1.size () < str2.size ())
     227              :     return -1;
     228           20 :   if (str1.size () > str2.size ())
     229            8 :     return 1;
     230              :   return 0;
     231              : }
     232              : 
     233              : string_slice
     234          586 : string_slice::strip ()
     235              : {
     236          586 :   const char *start = this->begin ();
     237          586 :   const char *end = this->end ();
     238              : 
     239         1236 :   while (start < end && ISSPACE (*start))
     240           64 :     start++;
     241          622 :   while (end > start && ISSPACE (*(end-1)))
     242           36 :     end--;
     243              : 
     244          586 :   return string_slice (start, end);
     245              : }
     246              : 
     247              : #if CHECKING_P
     248              : /* Report qsort comparator CMP consistency check failure with P1, P2, P3 as
     249              :    witness elements.  */
     250              : ATTRIBUTE_NORETURN ATTRIBUTE_COLD
     251              : static void
     252            0 : qsort_chk_error (const void *p1, const void *p2, const void *p3,
     253              :                  sort_r_cmp_fn *cmp, void *data)
     254              : {
     255            0 :   if (!p3)
     256              :     {
     257            0 :       int r1 = cmp (p1, p2, data), r2 = cmp (p2, p1, data);
     258            0 :       error ("qsort comparator not anti-symmetric: %d, %d", r1, r2);
     259              :     }
     260            0 :   else if (p1 == p2)
     261              :     {
     262            0 :       int r = cmp (p1, p3, data);
     263            0 :       error ("qsort comparator non-negative on sorted output: %d", r);
     264              :     }
     265              :   else
     266              :     {
     267            0 :       int r1 = cmp (p1, p2, data);
     268            0 :       int r2 = cmp (p2, p3, data);
     269            0 :       int r3 = cmp (p1, p3, data);
     270            0 :       error ("qsort comparator not transitive: %d, %d, %d", r1, r2, r3);
     271              :     }
     272            0 :   internal_error ("qsort checking failed");
     273              : }
     274              : 
     275              : /* Verify anti-symmetry and transitivity for comparator CMP on sorted array
     276              :    of N SIZE-sized elements pointed to by BASE.  */
     277              : void
     278    172774936 : qsort_chk (void *base, size_t n, size_t size, sort_r_cmp_fn *cmp, void *data)
     279              : {
     280              : #if 0
     281              : #define LIM(n) (n)
     282              : #else
     283              :   /* Limit overall time complexity to O(n log n).  */
     284              : #define LIM(n) ((n) <= 16 ? (n) : 12 + floor_log2 (n))
     285              : #endif
     286              : #define ELT(i) ((const char *) base + (i) * size)
     287              : #define CMP(i, j) cmp (ELT (i), ELT (j), data)
     288              : #define ERR2(i, j) qsort_chk_error (ELT (i), ELT (j), NULL, cmp, data)
     289              : #define ERR3(i, j, k) qsort_chk_error (ELT (i), ELT (j), ELT (k), cmp, data)
     290    172774936 :   size_t i1, i2, i, j;
     291              :   /* This outer loop iterates over maximum spans [i1, i2) such that
     292              :      elements within each span compare equal to each other.  */
     293   1380632523 :   for (i1 = 0; i1 < n; i1 = i2)
     294              :     {
     295              :       /* Position i2 one past last element that compares equal to i1'th.  */
     296   1300027781 :       for (i2 = i1 + 1; i2 < n; i2++)
     297   1127252845 :         if (CMP (i1, i2))
     298              :           break;
     299     92170194 :         else if (CMP (i2, i1))
     300            0 :           ERR2 (i1, i2);
     301   1207857587 :       size_t lim1 = LIM (i2 - i1), lim2 = LIM (n - i2);
     302              :       /* Verify that other pairs within current span compare equal.  */
     303   1289822339 :       for (i = i1 + 1; i + 1 < i2; i++)
     304    180175293 :         for (j = i + 1; j < i1 + lim1; j++)
     305     98210541 :           if (CMP (i, j))
     306            0 :             ERR3 (i, i1, j);
     307     98210541 :           else if (CMP (j, i))
     308            0 :             ERR2 (i, j);
     309              :       /* Verify that elements within this span compare less than
     310              :          elements beyond the span.  */
     311   2507885368 :       for (i = i1; i < i2; i++)
     312  13868861997 :         for (j = i2; j < i2 + lim2; j++)
     313  12568834216 :           if (CMP (i, j) >= 0)
     314            0 :             ERR3 (i, i1, j);
     315  12568834216 :           else if (CMP (j, i) <= 0)
     316            0 :             ERR2 (i, j);
     317              :     }
     318              : #undef ERR3
     319              : #undef ERR2
     320              : #undef CMP
     321              : #undef ELT
     322              : #undef LIM
     323    172774936 : }
     324              : #endif /* #if CHECKING_P */
     325              : 
     326              : #ifndef GENERATOR_FILE
     327              : #if CHECKING_P
     328              : 
     329              : namespace selftest {
     330              : 
     331              : /* Selftests.  */
     332              : 
     333              : /* Call V.safe_push for all ints from START up to, but not including LIMIT.
     334              :    Helper function for selftests.  */
     335              : 
     336              : static void
     337           52 : safe_push_range (vec <int>&v, int start, int limit)
     338              : {
     339          540 :   for (int i = start; i < limit; i++)
     340          488 :     v.safe_push (i);
     341           52 : }
     342              : 
     343              : /* Verify forms of initialization.  */
     344              : 
     345              : static void
     346            4 : test_init ()
     347              : {
     348            4 :   {
     349            4 :     vec<int> v1{ };
     350            4 :     ASSERT_EQ (0, v1.length ());
     351              : 
     352            4 :     vec<int> v2 (v1);
     353            4 :     ASSERT_EQ (0, v2.length ());
     354              :   }
     355              : 
     356            4 :   {
     357            4 :     vec<int> v1 = vec<int>();
     358            4 :     ASSERT_EQ (0, v1.length ());
     359              : 
     360            4 :     vec<int> v2 = v1;
     361            4 :     ASSERT_EQ (0, v2.length ());
     362              :   }
     363              : 
     364            4 :   {
     365            4 :     vec<int> v1 (vNULL);
     366            4 :     ASSERT_EQ (0, v1.length ());
     367            4 :     v1.safe_push (1);
     368              : 
     369            4 :     vec<int> v2 (v1);
     370            4 :     ASSERT_EQ (1, v1.length ());
     371            4 :     v2.safe_push (1);
     372              : 
     373            4 :     ASSERT_EQ (2, v1.length ());
     374            4 :     ASSERT_EQ (2, v2.length ());
     375            4 :     v1.release ();
     376              :   }
     377            4 : }
     378              : 
     379              : /* Verify that vec::quick_push works correctly.  */
     380              : 
     381              : static void
     382            4 : test_quick_push ()
     383              : {
     384            4 :   auto_vec <int> v;
     385            4 :   ASSERT_EQ (0, v.length ());
     386            4 :   v.reserve (3);
     387            4 :   ASSERT_EQ (0, v.length ());
     388            4 :   ASSERT_TRUE (v.space (3));
     389            4 :   v.quick_push (5);
     390            4 :   v.quick_push (6);
     391            4 :   v.quick_push (7);
     392            4 :   ASSERT_EQ (3, v.length ());
     393            4 :   ASSERT_EQ (5, v[0]);
     394            4 :   ASSERT_EQ (6, v[1]);
     395            4 :   ASSERT_EQ (7, v[2]);
     396            4 : }
     397              : 
     398              : /* Verify that vec::safe_push works correctly.  */
     399              : 
     400              : static void
     401            4 : test_safe_push ()
     402              : {
     403            4 :   auto_vec <int> v;
     404            4 :   ASSERT_EQ (0, v.length ());
     405            4 :   v.safe_push (5);
     406            4 :   v.safe_push (6);
     407            4 :   v.safe_push (7);
     408            4 :   ASSERT_EQ (3, v.length ());
     409            4 :   ASSERT_EQ (5, v[0]);
     410            4 :   ASSERT_EQ (6, v[1]);
     411            4 :   ASSERT_EQ (7, v[2]);
     412            4 : }
     413              : 
     414              : /* Verify that vec::truncate works correctly.  */
     415              : 
     416              : static void
     417            4 : test_truncate ()
     418              : {
     419            4 :   auto_vec <int> v;
     420            4 :   ASSERT_EQ (0, v.length ());
     421            4 :   safe_push_range (v, 0, 10);
     422            4 :   ASSERT_EQ (10, v.length ());
     423              : 
     424            4 :   v.truncate (5);
     425            4 :   ASSERT_EQ (5, v.length ());
     426            4 : }
     427              : 
     428              : /* Verify that vec::safe_grow_cleared works correctly.  */
     429              : 
     430              : static void
     431            4 : test_safe_grow_cleared ()
     432              : {
     433            4 :   auto_vec <int> v;
     434            4 :   ASSERT_EQ (0, v.length ());
     435            4 :   v.safe_grow_cleared (50, true);
     436            4 :   ASSERT_EQ (50, v.length ());
     437            4 :   ASSERT_EQ (0, v[0]);
     438            4 :   ASSERT_EQ (0, v[49]);
     439            4 : }
     440              : 
     441              : /* Verify that vec::pop works correctly.  */
     442              : 
     443              : static void
     444            4 : test_pop ()
     445              : {
     446            4 :   auto_vec <int> v;
     447            4 :   safe_push_range (v, 5, 20);
     448            4 :   ASSERT_EQ (15, v.length ());
     449              : 
     450            4 :   int last = v.pop ();
     451            4 :   ASSERT_EQ (19, last);
     452            4 :   ASSERT_EQ (14, v.length ());
     453            4 : }
     454              : 
     455              : /* Verify that vec::safe_insert works correctly.  */
     456              : 
     457              : static void
     458            4 : test_safe_insert ()
     459              : {
     460            4 :   auto_vec <int> v;
     461            4 :   safe_push_range (v, 0, 10);
     462            4 :   v.safe_insert (5, 42);
     463            4 :   ASSERT_EQ (4, v[4]);
     464            4 :   ASSERT_EQ (42, v[5]);
     465            4 :   ASSERT_EQ (5, v[6]);
     466            4 :   ASSERT_EQ (11, v.length ());
     467            4 : }
     468              : 
     469              : /* Verify that vec::ordered_remove works correctly.  */
     470              : 
     471              : static void
     472            4 : test_ordered_remove ()
     473              : {
     474            4 :   auto_vec <int> v;
     475            4 :   safe_push_range (v, 0, 10);
     476            4 :   v.ordered_remove (5);
     477            4 :   ASSERT_EQ (4, v[4]);
     478            4 :   ASSERT_EQ (6, v[5]);
     479            4 :   ASSERT_EQ (9, v.length ());
     480            4 : }
     481              : 
     482              : /* Verify that vec::ordered_remove_if works correctly.  */
     483              : 
     484              : static void
     485            4 : test_ordered_remove_if (void)
     486              : {
     487            4 :   auto_vec <int> v;
     488            4 :   safe_push_range (v, 0, 10);
     489            4 :   unsigned ix, ix2;
     490            4 :   int *elem_ptr;
     491           44 :   VEC_ORDERED_REMOVE_IF (v, ix, ix2, elem_ptr,
     492            4 :                          *elem_ptr == 5 || *elem_ptr == 7);
     493            4 :   ASSERT_EQ (4, v[4]);
     494            4 :   ASSERT_EQ (6, v[5]);
     495            4 :   ASSERT_EQ (8, v[6]);
     496            4 :   ASSERT_EQ (8, v.length ());
     497              : 
     498            4 :   v.truncate (0);
     499            4 :   safe_push_range (v, 0, 10);
     500           28 :   VEC_ORDERED_REMOVE_IF_FROM_TO (v, ix, ix2, elem_ptr, 0, 6,
     501            4 :                                  *elem_ptr == 5 || *elem_ptr == 7);
     502            4 :   ASSERT_EQ (4, v[4]);
     503            4 :   ASSERT_EQ (6, v[5]);
     504            4 :   ASSERT_EQ (7, v[6]);
     505            4 :   ASSERT_EQ (9, v.length ());
     506              : 
     507            4 :   v.truncate (0);
     508            4 :   safe_push_range (v, 0, 10);
     509           24 :   VEC_ORDERED_REMOVE_IF_FROM_TO (v, ix, ix2, elem_ptr, 0, 5,
     510            4 :                                  *elem_ptr == 5 || *elem_ptr == 7);
     511           12 :   VEC_ORDERED_REMOVE_IF_FROM_TO (v, ix, ix2, elem_ptr, 8, 10,
     512            4 :                                  *elem_ptr == 5 || *elem_ptr == 7);
     513            4 :   ASSERT_EQ (4, v[4]);
     514            4 :   ASSERT_EQ (5, v[5]);
     515            4 :   ASSERT_EQ (6, v[6]);
     516            4 :   ASSERT_EQ (10, v.length ());
     517              : 
     518            4 :   v.truncate (0);
     519            4 :   safe_push_range (v, 0, 10);
     520           44 :   VEC_ORDERED_REMOVE_IF (v, ix, ix2, elem_ptr, *elem_ptr == 5);
     521            4 :   ASSERT_EQ (4, v[4]);
     522            4 :   ASSERT_EQ (6, v[5]);
     523            4 :   ASSERT_EQ (7, v[6]);
     524            4 :   ASSERT_EQ (9, v.length ());
     525            4 : }
     526              : 
     527              : /* Verify that vec::unordered_remove works correctly.  */
     528              : 
     529              : static void
     530            4 : test_unordered_remove ()
     531              : {
     532            4 :   auto_vec <int> v;
     533            4 :   safe_push_range (v, 0, 10);
     534            4 :   v.unordered_remove (5);
     535            4 :   ASSERT_EQ (9, v.length ());
     536            4 : }
     537              : 
     538              : /* Verify that vec::block_remove works correctly.  */
     539              : 
     540              : static void
     541            4 : test_block_remove ()
     542              : {
     543            4 :   auto_vec <int> v;
     544            4 :   safe_push_range (v, 0, 10);
     545            4 :   v.block_remove (5, 3);
     546            4 :   ASSERT_EQ (3, v[3]);
     547            4 :   ASSERT_EQ (4, v[4]);
     548            4 :   ASSERT_EQ (8, v[5]);
     549            4 :   ASSERT_EQ (9, v[6]);
     550            4 :   ASSERT_EQ (7, v.length ());
     551            4 : }
     552              : 
     553              : /* Comparator for use by test_qsort.  */
     554              : 
     555              : static int
     556          492 : reverse_cmp (const void *p_i, const void *p_j)
     557              : {
     558          492 :   return *(const int *)p_j - *(const int *)p_i;
     559              : }
     560              : 
     561              : /* Verify that vec::qsort works correctly.  */
     562              : 
     563              : static void
     564            4 : test_qsort ()
     565              : {
     566            4 :   auto_vec <int> v;
     567            4 :   safe_push_range (v, 0, 10);
     568            4 :   v.qsort (reverse_cmp);
     569            4 :   ASSERT_EQ (9, v[0]);
     570            4 :   ASSERT_EQ (8, v[1]);
     571            4 :   ASSERT_EQ (1, v[8]);
     572            4 :   ASSERT_EQ (0, v[9]);
     573            4 :   ASSERT_EQ (10, v.length ());
     574            4 : }
     575              : 
     576              : /* Verify that vec::reverse works correctly.  */
     577              : 
     578              : static void
     579            4 : test_reverse ()
     580              : {
     581              :   /* Reversing an empty vec ought to be a no-op.  */
     582            4 :   {
     583            4 :     auto_vec <int> v;
     584            4 :     ASSERT_EQ (0, v.length ());
     585            4 :     v.reverse ();
     586            4 :     ASSERT_EQ (0, v.length ());
     587            4 :   }
     588              : 
     589              :   /* Verify reversing a vec with even length.  */
     590            4 :   {
     591            4 :     auto_vec <int> v;
     592            4 :     safe_push_range (v, 0, 4);
     593            4 :     v.reverse ();
     594            4 :     ASSERT_EQ (3, v[0]);
     595            4 :     ASSERT_EQ (2, v[1]);
     596            4 :     ASSERT_EQ (1, v[2]);
     597            4 :     ASSERT_EQ (0, v[3]);
     598            4 :     ASSERT_EQ (4, v.length ());
     599            4 :   }
     600              : 
     601              :   /* Verify reversing a vec with odd length.  */
     602            4 :   {
     603            4 :     auto_vec <int> v;
     604            4 :     safe_push_range (v, 0, 3);
     605            4 :     v.reverse ();
     606            4 :     ASSERT_EQ (2, v[0]);
     607            4 :     ASSERT_EQ (1, v[1]);
     608            4 :     ASSERT_EQ (0, v[2]);
     609            4 :     ASSERT_EQ (3, v.length ());
     610            4 :   }
     611            4 : }
     612              : 
     613              : /* A test class that increments a counter every time its dtor is called.  */
     614              : 
     615              : class count_dtor
     616              : {
     617              :  public:
     618            8 :   count_dtor (int *counter) : m_counter (counter) {}
     619            8 :   ~count_dtor () { (*m_counter)++; }
     620              : 
     621              :  private:
     622              :   int *m_counter;
     623              : };
     624              : 
     625              : /* Verify that auto_delete_vec deletes the elements within it.  */
     626              : 
     627              : static void
     628            4 : test_auto_delete_vec ()
     629              : {
     630            4 :   int dtor_count = 0;
     631            4 :   {
     632            4 :     auto_delete_vec <count_dtor> v;
     633            4 :     v.safe_push (new count_dtor (&dtor_count));
     634            4 :     v.safe_push (new count_dtor (&dtor_count));
     635            4 :   }
     636            4 :   ASSERT_EQ (dtor_count, 2);
     637            4 : }
     638              : 
     639              : /* Verify accesses to vector elements are done indirectly.  */
     640              : 
     641              : static void
     642            4 : test_auto_alias ()
     643              : {
     644            4 :   volatile int i = 1;
     645            4 :   auto_vec<int, 8> v;
     646            4 :   v.quick_grow (2);
     647            4 :   v[0] = 1;
     648            4 :   v[1] = 2;
     649            4 :   int val;
     650            8 :   for (int ix = i; v.iterate (ix, &val); ix++)
     651            4 :     ASSERT_EQ (val, 2);
     652            4 :   ASSERT_EQ (val, 0);
     653            4 : }
     654              : 
     655              : static void
     656            4 : test_string_slice_initializers ()
     657              : {
     658            4 :   string_slice str1 = string_slice ();
     659            4 :   ASSERT_TRUE (str1.is_valid ());
     660            4 :   ASSERT_EQ (str1.size (), 0);
     661              : 
     662            4 :   string_slice str2 = string_slice ("Test string");
     663            4 :   ASSERT_TRUE (str2.is_valid ());
     664            4 :   ASSERT_EQ (str2.size (), 11);
     665              : 
     666            4 :   string_slice str3 = "Test string the second";
     667            4 :   ASSERT_TRUE (str3.is_valid ());
     668            4 :   ASSERT_EQ (str3.size (), 22);
     669              : 
     670            4 :   string_slice str4 = string_slice ("Test string", 4);
     671            4 :   ASSERT_TRUE (str4.is_valid ());
     672            4 :   ASSERT_EQ (str4.size (), 4);
     673            4 : }
     674              : 
     675              : static void
     676            4 : test_string_slice_tokenize ()
     677              : {
     678            4 :   string_slice test_string_slice = "";
     679            4 :   string_slice test_delims = ",";
     680              : 
     681            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), "");
     682            8 :   ASSERT_FALSE (test_string_slice.is_valid ());
     683              : 
     684            4 :   test_string_slice = ",";
     685            4 :   test_delims = ",";
     686            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims),
     687              :              string_slice (""));
     688            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims),
     689              :              string_slice (""));
     690            8 :   ASSERT_FALSE (test_string_slice.is_valid ());
     691              : 
     692            4 :   test_string_slice = ",test.,.test, ,  test  ";
     693            4 :   test_delims = ",.";
     694            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), "");
     695            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), "test");
     696            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), "");
     697            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), "");
     698            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), "test");
     699            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), " ");
     700            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims),
     701              :              "  test  ");
     702            8 :   ASSERT_FALSE (test_string_slice.is_valid ());
     703              : 
     704            4 :   const char *test_string
     705              :     = "This is the test string, it \0 is for testing, 123 ,,";
     706            4 :   test_string_slice = string_slice (test_string, 52);
     707            4 :   test_delims = string_slice (",\0", 2);
     708              : 
     709            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims),
     710              :              "This is the test string");
     711            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims),
     712              :              " it ");
     713            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims),
     714              :              " is for testing");
     715            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims),
     716              :              " 123 ");
     717            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims),
     718              :              "");
     719            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims),
     720              :              "");
     721            8 :   ASSERT_FALSE (test_string_slice.is_valid ());
     722            4 : }
     723              : 
     724              : static void
     725            4 : test_string_slice_strcmp ()
     726              : {
     727            4 :   ASSERT_EQ (string_slice::strcmp (string_slice (),
     728              :                                    string_slice ()), 0);
     729            4 :   ASSERT_EQ (string_slice::strcmp (string_slice ("test"),
     730              :                                    string_slice ()), 1);
     731            4 :   ASSERT_EQ (string_slice::strcmp (string_slice (),
     732              :                                    string_slice ("test")), -1);
     733            4 :   ASSERT_EQ (string_slice::strcmp (string_slice ("test"),
     734              :                                    string_slice ("test")), 0);
     735            4 :   ASSERT_EQ (string_slice::strcmp (string_slice ("a"),
     736              :                                    string_slice ("b")), -1);
     737            4 :   ASSERT_EQ (string_slice::strcmp (string_slice ("b"),
     738              :                                    string_slice ("a")), 1);
     739            4 :   ASSERT_EQ (string_slice::strcmp (string_slice ("ab", 1),
     740              :                                    string_slice ("a")), 0);
     741            4 :   ASSERT_EQ (string_slice::strcmp (string_slice ("ab", 2),
     742              :                                    string_slice ("a")), 1);
     743            4 : }
     744              : 
     745              : static void
     746            4 : test_string_slice_equality ()
     747              : {
     748            4 :   ASSERT_TRUE (string_slice () == string_slice ());
     749            4 :   ASSERT_FALSE (string_slice ("test") == string_slice ());
     750            4 :   ASSERT_FALSE ("test" == string_slice ());
     751            4 :   ASSERT_FALSE (string_slice () == string_slice ("test"));
     752            4 :   ASSERT_FALSE (string_slice () == "test");
     753            4 :   ASSERT_TRUE (string_slice ("test") == string_slice ("test"));
     754            4 :   ASSERT_TRUE ("test" == string_slice ("test"));
     755            4 :   ASSERT_TRUE (string_slice ("test") == "test");
     756            4 :   ASSERT_FALSE (string_slice ("a") == string_slice ("b"));
     757            4 :   ASSERT_FALSE ("a" == string_slice ("b"));
     758            4 :   ASSERT_FALSE (string_slice ("a") == "b");
     759            4 :   ASSERT_FALSE (string_slice ("b") == string_slice ("a"));
     760            4 :   ASSERT_TRUE (string_slice ("ab", 1) == string_slice ("a"));
     761            4 :   ASSERT_TRUE (string_slice ("ab", 1) == "a");
     762            4 :   ASSERT_FALSE (string_slice ("ab", 2) == string_slice ("a"));
     763            4 :   ASSERT_FALSE (string_slice ("ab", 2) == "a");
     764            4 : }
     765              : 
     766              : static void
     767            4 : test_string_slice_inequality ()
     768              : {
     769            4 :   ASSERT_FALSE (string_slice () != string_slice ());
     770            4 :   ASSERT_TRUE (string_slice ("test") != string_slice ());
     771            4 :   ASSERT_TRUE ("test" != string_slice ());
     772            4 :   ASSERT_TRUE (string_slice () != string_slice ("test"));
     773            4 :   ASSERT_TRUE (string_slice () != "test");
     774            4 :   ASSERT_FALSE (string_slice ("test") != string_slice ("test"));
     775            4 :   ASSERT_FALSE ("test" != string_slice ("test"));
     776            4 :   ASSERT_FALSE (string_slice ("test") != "test");
     777            4 :   ASSERT_TRUE (string_slice ("a") != string_slice ("b"));
     778            4 :   ASSERT_TRUE ("a" != string_slice ("b"));
     779            4 :   ASSERT_TRUE (string_slice ("a") != "b");
     780            4 :   ASSERT_TRUE (string_slice ("b") != string_slice ("a"));
     781            4 :   ASSERT_FALSE (string_slice ("ab", 1) != string_slice ("a"));
     782            4 :   ASSERT_FALSE (string_slice ("ab", 1) != "a");
     783            4 :   ASSERT_TRUE (string_slice ("ab", 2) != string_slice ("a"));
     784            4 :   ASSERT_TRUE (string_slice ("ab", 2) != "a");
     785            4 : }
     786              : 
     787              : static void
     788            4 : test_string_slice_invalid ()
     789              : {
     790            4 :   ASSERT_FALSE (string_slice::invalid ().is_valid ());
     791            4 :   ASSERT_FALSE (string_slice (NULL, 1).is_valid ());
     792            4 :   ASSERT_TRUE (string_slice (NULL, (size_t) 0).is_valid ());
     793            4 :   ASSERT_TRUE (string_slice ("Test", (size_t) 0).is_valid ());
     794            4 :   ASSERT_TRUE (string_slice ().is_valid ());
     795            4 : }
     796              : 
     797              : static void
     798            4 : test_string_slice_strip ()
     799              : {
     800            4 :   ASSERT_EQ (string_slice ("   test   ").strip (), string_slice ("test"));
     801            4 :   ASSERT_EQ (string_slice ("\t   test string\t   \n ").strip (),
     802              :              string_slice ("test string"));
     803            4 :   ASSERT_EQ (string_slice ("test").strip (), string_slice ("test"));
     804            4 :   ASSERT_EQ (string_slice ().strip (), string_slice ());
     805            4 :   ASSERT_EQ (string_slice ("\t  \n \t   ").strip (), string_slice ());
     806            4 : }
     807              : 
     808              : /* Run all of the selftests within this file.  */
     809              : 
     810              : void
     811            4 : vec_cc_tests ()
     812              : {
     813            4 :   test_init ();
     814            4 :   test_quick_push ();
     815            4 :   test_safe_push ();
     816            4 :   test_truncate ();
     817            4 :   test_safe_grow_cleared ();
     818            4 :   test_pop ();
     819            4 :   test_safe_insert ();
     820            4 :   test_ordered_remove ();
     821            4 :   test_ordered_remove_if ();
     822            4 :   test_unordered_remove ();
     823            4 :   test_block_remove ();
     824            4 :   test_qsort ();
     825            4 :   test_reverse ();
     826            4 :   test_auto_delete_vec ();
     827            4 :   test_auto_alias ();
     828            4 :   test_string_slice_initializers ();
     829            4 :   test_string_slice_tokenize ();
     830            4 :   test_string_slice_strcmp ();
     831            4 :   test_string_slice_equality ();
     832            4 :   test_string_slice_inequality ();
     833            4 :   test_string_slice_invalid ();
     834            4 :   test_string_slice_strip ();
     835            4 : }
     836              : 
     837              : } // namespace selftest
     838              : 
     839              : #endif /* #if CHECKING_P */
     840              : #endif /* #ifndef GENERATOR_FILE */
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.