LCOV - code coverage report
Current view: top level - aws-c-common/include/aws/common - math.h (source / functions) Hit Total Coverage
Test: all_fuzz.info Lines: 2 2 100.0 %
Date: 2021-04-23 16:28:21 Functions: 0 0 -

          Line data    Source code
       1             : #ifndef AWS_COMMON_MATH_H
       2             : #define AWS_COMMON_MATH_H
       3             : 
       4             : /**
       5             :  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
       6             :  * SPDX-License-Identifier: Apache-2.0.
       7             :  */
       8             : 
       9             : #include <aws/common/common.h>
      10             : #include <aws/common/config.h>
      11             : 
      12             : #include <limits.h>
      13             : #include <stdlib.h>
      14             : 
      15             : /* The number of bits in a size_t variable */
      16             : #if SIZE_MAX == UINT32_MAX
      17             : #    define SIZE_BITS 32
      18             : #elif SIZE_MAX == UINT64_MAX
      19     1439225 : #    define SIZE_BITS 64
      20             : #else
      21             : #    error "Target not supported"
      22             : #endif
      23             : 
      24             : /* The largest power of two that can be stored in a size_t */
      25     1439225 : #define SIZE_MAX_POWER_OF_TWO (((size_t)1) << (SIZE_BITS - 1))
      26             : 
      27             : AWS_EXTERN_C_BEGIN
      28             : 
      29             : #if defined(AWS_HAVE_GCC_OVERFLOW_MATH_EXTENSIONS) && (defined(__clang__) || !defined(__cplusplus)) ||                 \
      30             :     (defined(__x86_64__) || defined(__aarch64__)) && defined(AWS_HAVE_GCC_INLINE_ASM) ||                               \
      31             :     defined(AWS_HAVE_MSVC_MULX) || defined(CBMC) || !defined(AWS_HAVE_GCC_OVERFLOW_MATH_EXTENSIONS)
      32             : /* In all these cases, we can use fast static inline versions of this code */
      33             : #    define AWS_COMMON_MATH_API AWS_STATIC_IMPL
      34             : #else
      35             : /*
      36             :  * We got here because we are building in C++ mode but we only support overflow extensions
      37             :  * in C mode. Because the fallback is _slow_ (involving a division), we'd prefer to make a
      38             :  * non-inline call to the fast C intrinsics.
      39             :  */
      40             : #    define AWS_COMMON_MATH_API AWS_COMMON_API
      41             : #endif
      42             : 
      43             : /**
      44             :  * Multiplies a * b. If the result overflows, returns 2^64 - 1.
      45             :  */
      46             : AWS_COMMON_MATH_API uint64_t aws_mul_u64_saturating(uint64_t a, uint64_t b);
      47             : 
      48             : /**
      49             :  * If a * b overflows, returns AWS_OP_ERR; otherwise multiplies
      50             :  * a * b, returns the result in *r, and returns AWS_OP_SUCCESS.
      51             :  */
      52             : AWS_COMMON_MATH_API int aws_mul_u64_checked(uint64_t a, uint64_t b, uint64_t *r);
      53             : 
      54             : /**
      55             :  * Multiplies a * b. If the result overflows, returns 2^32 - 1.
      56             :  */
      57             : AWS_COMMON_MATH_API uint32_t aws_mul_u32_saturating(uint32_t a, uint32_t b);
      58             : 
      59             : /**
      60             :  * If a * b overflows, returns AWS_OP_ERR; otherwise multiplies
      61             :  * a * b, returns the result in *r, and returns AWS_OP_SUCCESS.
      62             :  */
      63             : AWS_COMMON_MATH_API int aws_mul_u32_checked(uint32_t a, uint32_t b, uint32_t *r);
      64             : 
      65             : /**
      66             :  * Adds a + b.  If the result overflows returns 2^64 - 1.
      67             :  */
      68             : AWS_COMMON_MATH_API uint64_t aws_add_u64_saturating(uint64_t a, uint64_t b);
      69             : 
      70             : /**
      71             :  * If a + b overflows, returns AWS_OP_ERR; otherwise adds
      72             :  * a + b, returns the result in *r, and returns AWS_OP_SUCCESS.
      73             :  */
      74             : AWS_COMMON_MATH_API int aws_add_u64_checked(uint64_t a, uint64_t b, uint64_t *r);
      75             : 
      76             : /**
      77             :  * Adds a + b. If the result overflows returns 2^32 - 1.
      78             :  */
      79             : AWS_COMMON_MATH_API uint32_t aws_add_u32_saturating(uint32_t a, uint32_t b);
      80             : 
      81             : /**
      82             :  * If a + b overflows, returns AWS_OP_ERR; otherwise adds
      83             :  * a + b, returns the result in *r, and returns AWS_OP_SUCCESS.
      84             :  */
      85             : AWS_COMMON_MATH_API int aws_add_u32_checked(uint32_t a, uint32_t b, uint32_t *r);
      86             : 
      87             : /**
      88             :  * Subtracts a - b. If the result overflows returns 0.
      89             :  */
      90             : AWS_STATIC_IMPL uint64_t aws_sub_u64_saturating(uint64_t a, uint64_t b);
      91             : 
      92             : /**
      93             :  * If a - b overflows, returns AWS_OP_ERR; otherwise subtracts
      94             :  * a - b, returns the result in *r, and returns AWS_OP_SUCCESS.
      95             :  */
      96             : AWS_STATIC_IMPL int aws_sub_u64_checked(uint64_t a, uint64_t b, uint64_t *r);
      97             : 
      98             : /**
      99             :  * Subtracts a - b. If the result overflows returns 0.
     100             :  */
     101             : AWS_STATIC_IMPL uint32_t aws_sub_u32_saturating(uint32_t a, uint32_t b);
     102             : 
     103             : /**
     104             :  * If a - b overflows, returns AWS_OP_ERR; otherwise subtracts
     105             :  * a - b, returns the result in *r, and returns AWS_OP_SUCCESS.
     106             :  */
     107             : AWS_STATIC_IMPL int aws_sub_u32_checked(uint32_t a, uint32_t b, uint32_t *r);
     108             : 
     109             : /**
     110             :  * Multiplies a * b. If the result overflows, returns SIZE_MAX.
     111             :  */
     112             : AWS_STATIC_IMPL size_t aws_mul_size_saturating(size_t a, size_t b);
     113             : 
     114             : /**
     115             :  * Multiplies a * b and returns the result in *r. If the result
     116             :  * overflows, returns AWS_OP_ERR; otherwise returns AWS_OP_SUCCESS.
     117             :  */
     118             : AWS_STATIC_IMPL int aws_mul_size_checked(size_t a, size_t b, size_t *r);
     119             : 
     120             : /**
     121             :  * Adds a + b.  If the result overflows returns SIZE_MAX.
     122             :  */
     123             : AWS_STATIC_IMPL size_t aws_add_size_saturating(size_t a, size_t b);
     124             : 
     125             : /**
     126             :  * Adds a + b and returns the result in *r. If the result
     127             :  * overflows, returns AWS_OP_ERR; otherwise returns AWS_OP_SUCCESS.
     128             :  */
     129             : AWS_STATIC_IMPL int aws_add_size_checked(size_t a, size_t b, size_t *r);
     130             : 
     131             : /**
     132             :  * Adds [num] arguments (expected to be of size_t), and returns the result in *r.
     133             :  * If the result overflows, returns AWS_OP_ERR; otherwise returns AWS_OP_SUCCESS.
     134             :  */
     135             : AWS_COMMON_API int aws_add_size_checked_varargs(size_t num, size_t *r, ...);
     136             : 
     137             : /**
     138             :  * Subtracts a - b. If the result overflows returns 0.
     139             :  */
     140             : AWS_STATIC_IMPL size_t aws_sub_size_saturating(size_t a, size_t b);
     141             : 
     142             : /**
     143             :  * If a - b overflows, returns AWS_OP_ERR; otherwise subtracts
     144             :  * a - b, returns the result in *r, and returns AWS_OP_SUCCESS.
     145             :  */
     146             : AWS_STATIC_IMPL int aws_sub_size_checked(size_t a, size_t b, size_t *r);
     147             : 
     148             : /**
     149             :  * Function to check if x is power of 2
     150             :  */
     151             : AWS_STATIC_IMPL bool aws_is_power_of_two(const size_t x);
     152             : /**
     153             :  * Function to find the smallest result that is power of 2 >= n. Returns AWS_OP_ERR if this cannot
     154             :  * be done without overflow
     155             :  */
     156             : AWS_STATIC_IMPL int aws_round_up_to_power_of_two(size_t n, size_t *result);
     157             : 
     158             : /**
     159             :  * Counts the number of leading 0 bits in an integer
     160             :  */
     161             : AWS_STATIC_IMPL size_t aws_clz_u32(uint32_t n);
     162             : AWS_STATIC_IMPL size_t aws_clz_i32(int32_t n);
     163             : AWS_STATIC_IMPL size_t aws_clz_u64(uint64_t n);
     164             : AWS_STATIC_IMPL size_t aws_clz_i64(int64_t n);
     165             : AWS_STATIC_IMPL size_t aws_clz_size(size_t n);
     166             : 
     167             : /**
     168             :  * Counts the number of trailing 0 bits in an integer
     169             :  */
     170             : AWS_STATIC_IMPL size_t aws_ctz_u32(uint32_t n);
     171             : AWS_STATIC_IMPL size_t aws_ctz_i32(int32_t n);
     172             : AWS_STATIC_IMPL size_t aws_ctz_u64(uint64_t n);
     173             : AWS_STATIC_IMPL size_t aws_ctz_i64(int64_t n);
     174             : AWS_STATIC_IMPL size_t aws_ctz_size(size_t n);
     175             : 
     176             : AWS_STATIC_IMPL uint8_t aws_min_u8(uint8_t a, uint8_t b);
     177             : AWS_STATIC_IMPL uint8_t aws_max_u8(uint8_t a, uint8_t b);
     178             : AWS_STATIC_IMPL int8_t aws_min_i8(int8_t a, int8_t b);
     179             : AWS_STATIC_IMPL int8_t aws_max_i8(int8_t a, int8_t b);
     180             : AWS_STATIC_IMPL uint16_t aws_min_u16(uint16_t a, uint16_t b);
     181             : AWS_STATIC_IMPL uint16_t aws_max_u16(uint16_t a, uint16_t b);
     182             : AWS_STATIC_IMPL int16_t aws_min_i16(int16_t a, int16_t b);
     183             : AWS_STATIC_IMPL int16_t aws_max_i16(int16_t a, int16_t b);
     184             : AWS_STATIC_IMPL uint32_t aws_min_u32(uint32_t a, uint32_t b);
     185             : AWS_STATIC_IMPL uint32_t aws_max_u32(uint32_t a, uint32_t b);
     186             : AWS_STATIC_IMPL int32_t aws_min_i32(int32_t a, int32_t b);
     187             : AWS_STATIC_IMPL int32_t aws_max_i32(int32_t a, int32_t b);
     188             : AWS_STATIC_IMPL uint64_t aws_min_u64(uint64_t a, uint64_t b);
     189             : AWS_STATIC_IMPL uint64_t aws_max_u64(uint64_t a, uint64_t b);
     190             : AWS_STATIC_IMPL int64_t aws_min_i64(int64_t a, int64_t b);
     191             : AWS_STATIC_IMPL int64_t aws_max_i64(int64_t a, int64_t b);
     192             : AWS_STATIC_IMPL size_t aws_min_size(size_t a, size_t b);
     193             : AWS_STATIC_IMPL size_t aws_max_size(size_t a, size_t b);
     194             : AWS_STATIC_IMPL int aws_min_int(int a, int b);
     195             : AWS_STATIC_IMPL int aws_max_int(int a, int b);
     196             : AWS_STATIC_IMPL float aws_min_float(float a, float b);
     197             : AWS_STATIC_IMPL float aws_max_float(float a, float b);
     198             : AWS_STATIC_IMPL double aws_min_double(double a, double b);
     199             : AWS_STATIC_IMPL double aws_max_double(double a, double b);
     200             : 
     201             : #ifndef AWS_NO_STATIC_IMPL
     202             : #    include <aws/common/math.inl>
     203             : #endif /* AWS_NO_STATIC_IMPL */
     204             : 
     205             : AWS_EXTERN_C_END
     206             : 
     207             : #endif /* AWS_COMMON_MATH_H */

Generated by: LCOV version 1.13