LCOV - code coverage report
Current view: top level - source/lib - lib.h (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 5 15 33.3 %
Date: 2023-01-19 00:18:29 Functions: 2 6 33.3 %

          Line data    Source code
       1             : /* Copyright (C) 2019 Wildfire Games.
       2             :  *
       3             :  * Permission is hereby granted, free of charge, to any person obtaining
       4             :  * a copy of this software and associated documentation files (the
       5             :  * "Software"), to deal in the Software without restriction, including
       6             :  * without limitation the rights to use, copy, modify, merge, publish,
       7             :  * distribute, sublicense, and/or sell copies of the Software, and to
       8             :  * permit persons to whom the Software is furnished to do so, subject to
       9             :  * the following conditions:
      10             :  *
      11             :  * The above copyright notice and this permission notice shall be included
      12             :  * in all copies or substantial portions of the Software.
      13             :  *
      14             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
      15             :  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      16             :  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
      17             :  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
      18             :  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
      19             :  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
      20             :  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
      21             :  */
      22             : 
      23             : /*
      24             :  * various utility functions.
      25             :  */
      26             : 
      27             : /**
      28             : 
      29             : low-level aka "lib"
      30             : -------------------
      31             : 
      32             : this codebase was grown from modules shared between several projects,
      33             : i.e. my personal library; hence the name "lib". it has been expanded to
      34             : fit the needs of 0ad - in particular, resource loading.
      35             : 
      36             : owing to the dual-use situation, the 0ad coding conventions are not met;
      37             : also, major changes are ill-advised because they may break other projects.
      38             : 
      39             : 
      40             : design goals
      41             : ------------
      42             : 
      43             : - fast and low-overhead, including startup time
      44             : - portable: must run on Win32, Mac OS X and Linux
      45             : - reusable across projects, i.e. no dependency on a
      46             :   central 'manager' that ties modules together.
      47             : 
      48             : 
      49             : scope
      50             : -----
      51             : 
      52             : - POSIX definitions
      53             : - resource management
      54             : - debugging tools (including memory tracker)
      55             : - low-level helper functions, e.g. ADTs, endian conversion and timing
      56             : - platform-dependent system/feature detection
      57             : 
      58             : **/
      59             : 
      60             : #ifndef INCLUDED_LIB
      61             : #define INCLUDED_LIB
      62             : 
      63             : #include <cmath>  // fabsf
      64             : #include <limits> // numeric_limits
      65             : #include <stdexcept>  // out_of_range
      66             : 
      67             : template<typename T>
      68          20 : T DivideRoundUp(T dividend, T divisor)
      69             : {
      70          20 :     ASSERT(divisor != 0);
      71          20 :     return (dividend + divisor-1) / divisor;
      72             : }
      73             : 
      74             : /**
      75             :  * are the given floats nearly "equal"?
      76             :  *
      77             :  * @return whether the numbers are within "epsilon" of each other.
      78             :  *
      79             :  * notes:
      80             :  * - the epsilon magic number varies with the magnitude of the inputs.
      81             :  *   we use a sane default, but don't use this routine for very
      82             :  *   large/small comparands.
      83             :  * - floating-point numbers don't magically lose precision. addition,
      84             :  *   subtraction and multiplication results are precise up to the mantissa's
      85             :  *   least-significant bit. only division, sqrt, sin/cos and other
      86             :  *   transcendental operations introduce error.
      87             :  **/
      88          20 : inline bool feq(double d1, double d2, double epsilon = 0.00001)
      89             : {
      90          20 :     return fabs(d1 - d2) < epsilon;
      91             : }
      92             : 
      93             : inline bool feqf(float f1, float f2, float epsilon = 0.001f)
      94             : {
      95             :     return fabsf(f1 - f2) < epsilon;
      96             : }
      97             : 
      98             : inline bool IsSimilarMagnitude(double d1, double d2, const double relativeErrorTolerance = 0.05)
      99             : {
     100             :     const double relativeError = fabs(d1/d2 - 1.0);
     101             :     if(relativeError > relativeErrorTolerance)
     102             :         return false;
     103             :     return true;
     104             : }
     105             : 
     106             : 
     107             : //-----------------------------------------------------------------------------
     108             : // type conversion
     109             : 
     110             : // note: these avoid a common mistake in using >> (ANSI requires
     111             : // shift count be less than the bit width of the type).
     112             : 
     113             : extern u32 u64_hi(u64 x);   /// return upper 32-bits
     114             : extern u32 u64_lo(u64 x);   /// return lower 32-bits
     115             : extern u16 u32_hi(u32 x);   /// return upper 16-bits
     116             : extern u16 u32_lo(u32 x);   /// return lower 16-bits
     117             : 
     118             : extern u64 u64_from_u32(u32 hi, u32 lo);    /// assemble u64 from u32
     119             : extern u32 u32_from_u16(u16 hi, u16 lo);    /// assemble u32 from u16
     120             : 
     121             : // safe downcasters: cast from any integral type to u32 or u16;
     122             : // issues warning if larger than would fit in the target type.
     123             : //
     124             : // these are generally useful but included here (instead of e.g. lib.h) for
     125             : // several reasons:
     126             : // - including implementation in lib.h doesn't work because the definition
     127             : //   of ENSURE in turn requires lib.h's STMT.
     128             : // - separate compilation of templates via export isn't supported by
     129             : //   most compilers.
     130             : 
     131             : template<typename T> u8 u8_from_larger(T x)
     132             : {
     133             :     const u8 max = std::numeric_limits<u8>::max();
     134             :     if((u64)x > (u64)max)
     135             :         throw std::out_of_range("u8_from_larger");
     136             :     return (u8)(x & max);
     137             : }
     138             : 
     139           0 : template<typename T> u16 u16_from_larger(T x)
     140             : {
     141           0 :     const u16 max = std::numeric_limits<u16>::max();
     142           0 :     if((u64)x > (u64)max)
     143           0 :         throw std::out_of_range("u16_from_larger");
     144           0 :     return (u16)(x & max);
     145             : }
     146             : 
     147           0 : template<typename T> u32 u32_from_larger(T x)
     148             : {
     149           0 :     const u32 max = std::numeric_limits<u32>::max();
     150           0 :     if((u64)x > (u64)max)
     151           0 :         throw std::out_of_range("u32_from_larger");
     152           0 :     return (u32)(x & max);
     153             : }
     154             : 
     155             : /// convert double to u8; verifies number is in range.
     156             : extern u8 u8_from_double(double in);
     157             : /// convert double to u16; verifies number is in range.
     158             : extern u16 u16_from_double(double in);
     159             : 
     160             : #endif  // #ifndef INCLUDED_LIB

Generated by: LCOV version 1.13