LCOV - code coverage report
Current view: top level - source/flat_buffer.c (source / functions) Coverage Total Hit
Test: CCC Test Suite Coverage Report Lines: 97.9 % 327 320
Test Date: 2026-08-22 15:52:04 Functions: 100.0 % 36 36

            Line data    Source code
       1              : /** Copyright 2025 Alexander G. Lopez
       2              : 
       3              : Licensed under the Apache License, Version 2.0 (the "License");
       4              : you may not use this file except in compliance with the License.
       5              : You may obtain a copy of the License at
       6              : 
       7              :    http://www.apache.org/licenses/LICENSE-2.0
       8              : 
       9              : Unless required by applicable law or agreed to in writing, software
      10              : distributed under the License is distributed on an "AS IS" BASIS,
      11              : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12              : See the License for the specific language governing permissions and
      13              : limitations under the License. */
      14              : /** C23 provided headers. */
      15              : #include <stdckdint.h>
      16              : #include <stddef.h>
      17              : 
      18              : /** CCC provided headers. */
      19              : #include "ccc/configuration.h" /* IWYU pragma: keep */
      20              : #include "ccc/flat_buffer.h"
      21              : #include "ccc/private/private_flat_buffer.h"
      22              : #include "ccc/types.h"
      23              : #include "source/compiler_utilities.h"
      24              : 
      25              : enum : size_t {
      26              :     START_CAPACITY = 8,
      27              : };
      28              : 
      29              : /*==========================   Prototypes    ================================*/
      30              : 
      31              : static void *at(CCC_Flat_buffer const *, size_t);
      32              : 
      33              : /*==========================    Interface    ================================*/
      34              : 
      35              : CCC_Result
      36           63 : CCC_flat_buffer_allocate(
      37              :     CCC_Flat_buffer *const buffer,
      38              :     size_t const capacity,
      39              :     CCC_Allocator const *const allocator
      40              : ) {
      41           63 :     if (!buffer || !allocator) {
      42            2 :         return CCC_RESULT_ARGUMENT_ERROR;
      43              :     }
      44           61 :     if (!allocator->allocate) {
      45            9 :         return CCC_RESULT_NO_ALLOCATION_FUNCTION;
      46              :     }
      47           52 :     size_t total_bytes = 0;
      48           52 :     if (ckd_mul(&total_bytes, capacity, buffer->sizeof_type)) {
      49            0 :         return CCC_RESULT_ALLOCATOR_ERROR;
      50              :     }
      51          260 :     void *const new_data = allocator->allocate((CCC_Allocator_arguments){
      52           52 :         .input = buffer->data,
      53           52 :         .bytes = total_bytes,
      54           52 :         .alignment = buffer->alignof_type,
      55           52 :         .context = allocator->context,
      56              :     });
      57           52 :     if (capacity && !new_data) {
      58            4 :         return CCC_RESULT_ALLOCATOR_ERROR;
      59              :     }
      60           48 :     buffer->data = new_data;
      61           48 :     buffer->capacity = capacity;
      62           48 :     return CCC_RESULT_OK;
      63           63 : }
      64              : 
      65              : CCC_Result
      66           51 : CCC_flat_buffer_reserve(
      67              :     CCC_Flat_buffer *const buffer,
      68              :     size_t const to_add,
      69              :     CCC_Allocator const *const allocator
      70              : ) {
      71           51 :     if (!buffer || !allocator || !allocator->allocate || !to_add) {
      72            9 :         return CCC_RESULT_ARGUMENT_ERROR;
      73              :     }
      74           42 :     size_t new_capacity = 0;
      75           42 :     if (ckd_add(&new_capacity, buffer->count, to_add)) {
      76            0 :         return CCC_RESULT_ALLOCATOR_ERROR;
      77              :     }
      78           42 :     if (new_capacity <= buffer->capacity) {
      79            1 :         return CCC_RESULT_OK;
      80              :     }
      81           41 :     if (new_capacity < START_CAPACITY) {
      82            3 :         new_capacity = START_CAPACITY;
      83            3 :     }
      84           41 :     size_t total_bytes = 0;
      85           41 :     if (ckd_mul(&total_bytes, new_capacity, buffer->sizeof_type)) {
      86            0 :         return CCC_RESULT_ALLOCATOR_ERROR;
      87              :     }
      88          205 :     void *const new_data = allocator->allocate((CCC_Allocator_arguments){
      89           41 :         .input = buffer->data,
      90           41 :         .bytes = total_bytes,
      91           41 :         .alignment = buffer->alignof_type,
      92           41 :         .context = allocator->context,
      93              :     });
      94           41 :     if (!new_data) {
      95            1 :         return CCC_RESULT_ALLOCATOR_ERROR;
      96              :     }
      97           40 :     buffer->data = new_data;
      98           40 :     buffer->capacity = new_capacity;
      99           40 :     return CCC_RESULT_OK;
     100           51 : }
     101              : 
     102              : CCC_Result
     103            4 : CCC_flat_buffer_clear(
     104              :     CCC_Flat_buffer *const buffer, CCC_Destructor const *const destructor
     105              : ) {
     106            4 :     if (!buffer || !destructor) {
     107            2 :         return CCC_RESULT_ARGUMENT_ERROR;
     108              :     }
     109            2 :     if (!destructor->destroy) {
     110            1 :         buffer->count = 0;
     111            1 :         return CCC_RESULT_OK;
     112              :     }
     113            9 :     for (void *i = CCC_flat_buffer_begin(buffer);
     114            9 :          i != CCC_flat_buffer_end(buffer);
     115            8 :          i = CCC_flat_buffer_next(buffer, i)) {
     116           24 :         destructor->destroy((CCC_Arguments){
     117            8 :             .type = i,
     118            8 :             .context = destructor->context,
     119              :         });
     120            8 :     }
     121            1 :     buffer->count = 0;
     122            1 :     return CCC_RESULT_OK;
     123            4 : }
     124              : 
     125              : CCC_Result
     126           20 : CCC_flat_buffer_clear_and_free(
     127              :     CCC_Flat_buffer *const buffer,
     128              :     CCC_Destructor const *const destructor,
     129              :     CCC_Allocator const *const allocator
     130              : ) {
     131           20 :     if (!buffer || !allocator || !destructor || !allocator->allocate) {
     132            1 :         return CCC_RESULT_ARGUMENT_ERROR;
     133              :     }
     134           19 :     if (destructor->destroy) {
     135            9 :         for (void *i = CCC_flat_buffer_begin(buffer);
     136            9 :              i != CCC_flat_buffer_end(buffer);
     137            8 :              i = CCC_flat_buffer_next(buffer, i)) {
     138           24 :             destructor->destroy((CCC_Arguments){
     139            8 :                 .type = i,
     140            8 :                 .context = destructor->context,
     141              :             });
     142            8 :         }
     143            1 :     }
     144           76 :     (void)allocator->allocate((CCC_Allocator_arguments){
     145           19 :         .input = buffer->data,
     146              :         .bytes = 0,
     147           19 :         .alignment = buffer->alignof_type,
     148           19 :         .context = allocator->context,
     149              :     });
     150           19 :     buffer->data = NULL;
     151           19 :     buffer->count = 0;
     152           19 :     buffer->capacity = 0;
     153           19 :     return CCC_RESULT_OK;
     154           20 : }
     155              : 
     156              : void *
     157         3696 : CCC_flat_buffer_at(CCC_Flat_buffer const *const buffer, size_t const i) {
     158         3696 :     if (!buffer || i >= buffer->capacity) {
     159            3 :         return NULL;
     160              :     }
     161         3693 :     return ((char *)buffer->data + (i * buffer->sizeof_type));
     162         3696 : }
     163              : 
     164              : void *
     165           90 : CCC_flat_buffer_back(CCC_Flat_buffer const *const buffer) {
     166           90 :     return CCC_flat_buffer_at(buffer, buffer->count - 1);
     167              : }
     168              : 
     169              : void *
     170            7 : CCC_flat_buffer_front(CCC_Flat_buffer const *const buffer) {
     171            7 :     return CCC_flat_buffer_at(buffer, 0);
     172              : }
     173              : 
     174              : void *
     175         4877 : CCC_flat_buffer_allocate_back(
     176              :     CCC_Flat_buffer *const buffer, CCC_Allocator const *const allocator
     177              : ) {
     178         4877 :     if (!buffer || !allocator) {
     179            4 :         return NULL;
     180              :     }
     181         4873 :     if (buffer->count == buffer->capacity) {
     182           20 :         size_t new_capacity = 0;
     183           20 :         if (ckd_mul(&new_capacity, buffer->capacity, 2)) {
     184            0 :             return NULL;
     185              :         }
     186           40 :         CCC_Result const resize_res = CCC_flat_buffer_allocate(
     187           20 :             buffer, CCC_max(new_capacity, START_CAPACITY), allocator
     188              :         );
     189           20 :         if (resize_res != CCC_RESULT_OK) {
     190            6 :             return NULL;
     191              :         }
     192           20 :     }
     193         9734 :     void *const ret
     194         4867 :         = ((char *)buffer->data + (buffer->sizeof_type * buffer->count));
     195         4867 :     ++buffer->count;
     196         4867 :     return ret;
     197         4877 : }
     198              : 
     199              : void *
     200          149 : CCC_flat_buffer_push_back(
     201              :     CCC_Flat_buffer *const buffer,
     202              :     void const *const data,
     203              :     CCC_Allocator const *const allocator
     204              : ) {
     205          149 :     if (!data) {
     206            1 :         return NULL;
     207              :     }
     208          148 :     void *const slot = CCC_flat_buffer_allocate_back(buffer, allocator);
     209          148 :     if (slot) {
     210          142 :         (void)memcpy(slot, data, buffer->sizeof_type);
     211          142 :     }
     212          148 :     return slot;
     213          149 : }
     214              : 
     215              : CCC_Result
     216            5 : CCC_flat_buffer_swap(
     217              :     CCC_Flat_buffer const *const buffer,
     218              :     void *const temp,
     219              :     size_t const index,
     220              :     size_t const swap_index
     221              : ) {
     222            5 :     if (!buffer || !temp || index >= buffer->capacity
     223            5 :         || swap_index >= buffer->capacity || swap_index == index) {
     224            1 :         return CCC_RESULT_ARGUMENT_ERROR;
     225              :     }
     226            4 :     (void)memcpy(temp, at(buffer, index), buffer->sizeof_type);
     227            4 :     (void)memcpy(
     228            4 :         at(buffer, index), at(buffer, swap_index), buffer->sizeof_type
     229              :     );
     230            4 :     (void)memcpy(at(buffer, swap_index), temp, buffer->sizeof_type);
     231            4 :     return CCC_RESULT_OK;
     232            5 : }
     233              : 
     234              : void *
     235            3 : CCC_flat_buffer_move(
     236              :     CCC_Flat_buffer const *const buffer,
     237              :     size_t const destination,
     238              :     size_t const source
     239              : ) {
     240            3 :     if (!buffer || destination >= buffer->capacity
     241            3 :         || source >= buffer->capacity) {
     242            1 :         return NULL;
     243              :     }
     244            2 :     if (destination == source) {
     245            1 :         return at(buffer, destination);
     246              :     }
     247            1 :     return memcpy(
     248            1 :         at(buffer, destination), at(buffer, source), buffer->sizeof_type
     249              :     );
     250            3 : }
     251              : 
     252              : CCC_Result
     253           10 : CCC_flat_buffer_write(
     254              :     CCC_Flat_buffer const *const buffer, size_t const i, void const *const data
     255              : ) {
     256           10 :     if (!buffer || !buffer->data || !data) {
     257            1 :         return CCC_RESULT_ARGUMENT_ERROR;
     258              :     }
     259            9 :     void *const pos = CCC_flat_buffer_at(buffer, i);
     260            9 :     if (!pos || data == pos) {
     261            2 :         return CCC_RESULT_ARGUMENT_ERROR;
     262              :     }
     263            7 :     (void)memcpy(pos, data, buffer->sizeof_type);
     264            7 :     return CCC_RESULT_OK;
     265           10 : }
     266              : 
     267              : CCC_Result
     268            6 : CCC_flat_buffer_erase(CCC_Flat_buffer *const buffer, size_t const i) {
     269            6 :     if (!buffer || !buffer->count || i >= buffer->count) {
     270            2 :         return CCC_RESULT_ARGUMENT_ERROR;
     271              :     }
     272            4 :     if (1 == buffer->count) {
     273            1 :         buffer->count = 0;
     274            1 :         return CCC_RESULT_OK;
     275              :     }
     276            3 :     if (i == buffer->count - 1) {
     277            1 :         --buffer->count;
     278            1 :         return CCC_RESULT_OK;
     279              :     }
     280            2 :     (void)memmove(
     281            2 :         at(buffer, i),
     282            2 :         at(buffer, i + 1),
     283            2 :         buffer->sizeof_type * (buffer->count - (i + 1))
     284              :     );
     285            2 :     --buffer->count;
     286            2 :     return CCC_RESULT_OK;
     287            6 : }
     288              : 
     289              : void *
     290           11 : CCC_flat_buffer_insert(
     291              :     CCC_Flat_buffer *const buffer,
     292              :     size_t const i,
     293              :     void const *const data,
     294              :     CCC_Allocator const *const allocator
     295              : ) {
     296           11 :     if (!buffer || !buffer->data || i > buffer->count || !allocator) {
     297            4 :         return NULL;
     298              :     }
     299            7 :     if (i == buffer->count) {
     300            1 :         return CCC_flat_buffer_push_back(buffer, data, allocator);
     301              :     }
     302            6 :     if (buffer->count == buffer->capacity) {
     303            1 :         size_t new_capacity = 0;
     304            1 :         if (ckd_mul(&new_capacity, buffer->count, 2)) {
     305            0 :             return NULL;
     306              :         }
     307            2 :         CCC_Result const r = CCC_flat_buffer_allocate(
     308            1 :             buffer, CCC_max(new_capacity, START_CAPACITY), allocator
     309              :         );
     310            1 :         if (r != CCC_RESULT_OK) {
     311            1 :             return NULL;
     312              :         }
     313            1 :     }
     314            5 :     (void)memmove(
     315            5 :         at(buffer, i + 1),
     316            5 :         at(buffer, i),
     317            5 :         buffer->sizeof_type * (buffer->count - i)
     318              :     );
     319            5 :     ++buffer->count;
     320            5 :     return memcpy(at(buffer, i), data, buffer->sizeof_type);
     321           11 : }
     322              : 
     323              : CCC_Result
     324           66 : CCC_flat_buffer_pop_back_n(CCC_Flat_buffer *const buffer, size_t count) {
     325           66 :     if (!buffer || count > buffer->count) {
     326            4 :         return CCC_RESULT_ARGUMENT_ERROR;
     327              :     }
     328           62 :     buffer->count -= count;
     329           62 :     return CCC_RESULT_OK;
     330           66 : }
     331              : 
     332              : CCC_Result
     333           64 : CCC_flat_buffer_pop_back(CCC_Flat_buffer *const buffer) {
     334           64 :     return CCC_flat_buffer_pop_back_n(buffer, 1);
     335              : }
     336              : 
     337              : CCC_Count
     338         1089 : CCC_flat_buffer_count(CCC_Flat_buffer const *const buffer) {
     339         1089 :     if (!buffer) {
     340            1 :         return (CCC_Count){.error = CCC_RESULT_ARGUMENT_ERROR};
     341              :     }
     342         1088 :     return (CCC_Count){.count = buffer->count};
     343         1089 : }
     344              : 
     345              : CCC_Count
     346           29 : CCC_flat_buffer_capacity(CCC_Flat_buffer const *const buffer) {
     347           29 :     if (!buffer) {
     348            1 :         return (CCC_Count){.error = CCC_RESULT_ARGUMENT_ERROR};
     349              :     }
     350           28 :     return (CCC_Count){.count = buffer->capacity};
     351           29 : }
     352              : 
     353              : CCC_Count
     354          140 : CCC_flat_buffer_sizeof_type(CCC_Flat_buffer const *const buffer) {
     355          140 :     if (!buffer) {
     356            1 :         return (CCC_Count){.error = CCC_RESULT_ARGUMENT_ERROR};
     357              :     }
     358          139 :     return (CCC_Count){.count = buffer->sizeof_type};
     359          140 : }
     360              : 
     361              : CCC_Tribool
     362         2043 : CCC_flat_buffer_is_empty(CCC_Flat_buffer const *const buffer) {
     363         2043 :     if (!buffer) {
     364            1 :         return CCC_TRIBOOL_ERROR;
     365              :     }
     366         2042 :     return !buffer->count;
     367         2043 : }
     368              : 
     369              : CCC_Tribool
     370           29 : CCC_flat_buffer_is_full(CCC_Flat_buffer const *const buffer) {
     371           29 :     if (!buffer) {
     372            1 :         return CCC_TRIBOOL_ERROR;
     373              :     }
     374           28 :     if (!buffer->capacity) {
     375            1 :         return CCC_FALSE;
     376              :     }
     377           27 :     return buffer->count == buffer->capacity ? CCC_TRUE : CCC_FALSE;
     378           29 : }
     379              : 
     380              : void *
     381         2164 : CCC_flat_buffer_begin(CCC_Flat_buffer const *const buffer) {
     382         2164 :     return buffer ? buffer->data : NULL;
     383              : }
     384              : 
     385              : void *
     386           64 : CCC_flat_buffer_reverse_begin(CCC_Flat_buffer const *const buffer) {
     387           64 :     if (!buffer || !buffer->data) {
     388            2 :         return NULL;
     389              :     }
     390              :     /* OK if count is 0. Negative offset puts at reverse_end anyway. */
     391          124 :     return (unsigned char *)buffer->data
     392           62 :          + ((buffer->count - 1) * buffer->sizeof_type);
     393           64 : }
     394              : 
     395              : void *
     396         1474 : CCC_flat_buffer_next(
     397              :     CCC_Flat_buffer const *const buffer, void const *const iterator
     398              : ) {
     399         1474 :     if (!buffer || !buffer->capacity || !iterator) {
     400            1 :         return NULL;
     401              :     }
     402         1473 :     if ((char *)iterator
     403         1473 :         >= (char *)buffer->data + ((buffer->count - 1) * buffer->sizeof_type)) {
     404           86 :         return CCC_flat_buffer_end(buffer);
     405              :     }
     406         1387 :     return (unsigned char *)iterator + buffer->sizeof_type;
     407         1474 : }
     408              : 
     409              : void *
     410          386 : CCC_flat_buffer_reverse_next(
     411              :     CCC_Flat_buffer const *const buffer, void const *const iterator
     412              : ) {
     413          386 :     if (!buffer || !buffer->data || !iterator) {
     414            1 :         return NULL;
     415              :     }
     416          385 :     if (iterator <= CCC_flat_buffer_reverse_end(buffer)) {
     417            1 :         return CCC_flat_buffer_reverse_end(buffer);
     418              :     }
     419          384 :     return (char *)iterator - buffer->sizeof_type;
     420          386 : }
     421              : 
     422              : void *
     423         1328 : CCC_flat_buffer_end(CCC_Flat_buffer const *const buffer) {
     424         1328 :     if (!buffer || !buffer->data) {
     425            2 :         return NULL;
     426              :     }
     427         2652 :     return (unsigned char *)buffer->data
     428         1326 :          + (buffer->count * buffer->sizeof_type);
     429         1328 : }
     430              : 
     431              : /** We accept that reverse_end is out of bounds and the address before start.
     432              : Even if the array base was somehow 0 and wrapping occurred upon subtraction the
     433              : iterator would eventually reach this same address through reverse_next and be
     434              : compared to it in the main user loop. */
     435              : void *
     436          740 : CCC_flat_buffer_reverse_end(CCC_Flat_buffer const *const buffer) {
     437          740 :     if (!buffer || !buffer->data) {
     438            1 :         return NULL;
     439              :     }
     440          739 :     return (unsigned char *)buffer->data - buffer->sizeof_type;
     441          740 : }
     442              : 
     443              : CCC_Count
     444           91 : CCC_flat_buffer_index(
     445              :     CCC_Flat_buffer const *const buffer, void const *const slot
     446              : ) {
     447           91 :     if (!buffer || !buffer->data || !slot || slot < buffer->data
     448           89 :         || (char *)slot
     449          176 :                >= ((char *)buffer->data
     450           88 :                    + (buffer->capacity * buffer->sizeof_type))) {
     451            3 :         return (CCC_Count){.error = CCC_RESULT_ARGUMENT_ERROR};
     452              :     }
     453            0 :     assert(
     454           88 :         slot >= buffer->data && "positive pointer difference is caught at entry"
     455              :     );
     456          176 :     return (CCC_Count){
     457              :         .count
     458           88 :         = ((size_t)((char *)slot - ((char *)buffer->data))
     459           88 :            / buffer->sizeof_type),
     460              :     };
     461           91 : }
     462              : 
     463              : CCC_Result
     464            3 : CCC_flat_buffer_count_plus(CCC_Flat_buffer *const buffer, size_t const count) {
     465            3 :     if (!buffer) {
     466            1 :         return CCC_RESULT_ARGUMENT_ERROR;
     467              :     }
     468            2 :     size_t new_count = 0;
     469            2 :     if (ckd_add(&new_count, buffer->count, count)) {
     470            0 :         return CCC_RESULT_ALLOCATOR_ERROR;
     471              :     }
     472            2 :     if (new_count > buffer->capacity) {
     473            1 :         buffer->count = buffer->capacity;
     474            1 :         return CCC_RESULT_ARGUMENT_ERROR;
     475              :     }
     476            1 :     buffer->count = new_count;
     477            1 :     return CCC_RESULT_OK;
     478            3 : }
     479              : 
     480              : CCC_Result
     481            3 : CCC_flat_buffer_count_minus(CCC_Flat_buffer *const buffer, size_t const count) {
     482            3 :     if (!buffer) {
     483            1 :         return CCC_RESULT_ARGUMENT_ERROR;
     484              :     }
     485            2 :     if (count > buffer->count) {
     486            1 :         buffer->count = 0;
     487            1 :         return CCC_RESULT_ARGUMENT_ERROR;
     488              :     }
     489            1 :     buffer->count -= count;
     490            1 :     return CCC_RESULT_OK;
     491            3 : }
     492              : 
     493              : CCC_Result
     494            3 : CCC_flat_buffer_count_set(CCC_Flat_buffer *const buffer, size_t const count) {
     495            3 :     if (!buffer) {
     496            1 :         return CCC_RESULT_ARGUMENT_ERROR;
     497              :     }
     498            2 :     if (count > buffer->capacity) {
     499            1 :         buffer->count = buffer->capacity;
     500            1 :         return CCC_RESULT_ARGUMENT_ERROR;
     501              :     }
     502            1 :     buffer->count = count;
     503            1 :     return CCC_RESULT_OK;
     504            3 : }
     505              : 
     506              : CCC_Count
     507            3 : CCC_flat_buffer_count_bytes(CCC_Flat_buffer const *buffer) {
     508            3 :     if (!buffer) {
     509            1 :         return (CCC_Count){.error = CCC_RESULT_ARGUMENT_ERROR};
     510              :     }
     511              :     /* No overflow check needed if buffer already exists. */
     512            2 :     return (CCC_Count){.count = buffer->count * buffer->sizeof_type};
     513            3 : }
     514              : 
     515              : CCC_Count
     516            2 : CCC_flat_buffer_capacity_bytes(CCC_Flat_buffer const *buffer) {
     517            2 :     if (!buffer) {
     518            1 :         return (CCC_Count){.error = CCC_RESULT_ARGUMENT_ERROR};
     519              :     }
     520              :     /* No overflow check needed if buffer already exists. */
     521            2 :     return (CCC_Count){
     522            1 :         .count = buffer->capacity * buffer->sizeof_type,
     523              :     };
     524            2 : }
     525              : 
     526              : CCC_Result
     527           18 : CCC_flat_buffer_copy(
     528              :     CCC_Flat_buffer *const destination,
     529              :     CCC_Flat_buffer const *const source,
     530              :     CCC_Allocator const *const allocator
     531              : ) {
     532           18 :     if (!destination || !source || source == destination || !allocator
     533           16 :         || (destination->capacity < source->capacity && !allocator->allocate)) {
     534            6 :         return CCC_RESULT_ARGUMENT_ERROR;
     535              :     }
     536           12 :     if (!source->capacity) {
     537            1 :         return CCC_RESULT_OK;
     538              :     }
     539           11 :     if (destination->capacity < source->capacity) {
     540           16 :         CCC_Result const r = CCC_flat_buffer_allocate(
     541            8 :             destination, source->capacity, allocator
     542              :         );
     543            8 :         if (r != CCC_RESULT_OK) {
     544            1 :             return r;
     545              :         }
     546            7 :         destination->capacity = source->capacity;
     547            8 :     }
     548           10 :     if (!source->data || !destination->data) {
     549            1 :         return CCC_RESULT_ARGUMENT_ERROR;
     550              :     }
     551            9 :     destination->count = source->count;
     552            9 :     (void)memcpy(
     553            9 :         destination->data, source->data, source->capacity * source->sizeof_type
     554              :     );
     555            9 :     return CCC_RESULT_OK;
     556           18 : }
     557              : 
     558              : void *
     559           11 : CCC_flat_buffer_data(CCC_Flat_buffer const *const buffer) {
     560           11 :     return buffer ? buffer->data : NULL;
     561              : }
     562              : 
     563              : /*======================  Static Helpers  ==================================*/
     564              : 
     565              : static inline void *
     566           38 : at(struct CCC_Flat_buffer const *const buffer, size_t const i) {
     567           38 :     return ((char *)buffer->data + (i * buffer->sizeof_type));
     568              : }
        

Generated by: LCOV version 2.4-beta