Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
lib.h
Go to the documentation of this file.
1 /* Copyright (c) 2010 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 T Clamp(T val, T min, T max)
69 {
70  ASSERT(min <= max);
71  return std::max(min, std::min(val, max));
72 }
73 
74 template<typename T>
75 T DivideRoundUp(T dividend, T divisor)
76 {
77  ASSERT(divisor != 0);
78  return (dividend + divisor-1) / divisor;
79 }
80 
81 /**
82  * are the given floats nearly "equal"?
83  *
84  * @return whether the numbers are within "epsilon" of each other.
85  *
86  * notes:
87  * - the epsilon magic number varies with the magnitude of the inputs.
88  * we use a sane default, but don't use this routine for very
89  * large/small comparands.
90  * - floating-point numbers don't magically lose precision. addition,
91  * subtraction and multiplication results are precise up to the mantissa's
92  * least-significant bit. only division, sqrt, sin/cos and other
93  * transcendental operations introduce error.
94  **/
95 inline bool feq(double d1, double d2, double epsilon = 0.00001)
96 {
97  return fabs(d1 - d2) < epsilon;
98 }
99 
100 inline bool feqf(float f1, float f2, float epsilon = 0.001f)
101 {
102  return fabsf(f1 - f2) < epsilon;
103 }
104 
105 inline bool IsSimilarMagnitude(double d1, double d2, const double relativeErrorTolerance = 0.05)
106 {
107  const double relativeError = fabs(d1/d2 - 1.0);
108  if(relativeError > relativeErrorTolerance)
109  return false;
110  return true;
111 }
112 
113 
114 //-----------------------------------------------------------------------------
115 // type conversion
116 
117 // note: these avoid a common mistake in using >> (ANSI requires
118 // shift count be less than the bit width of the type).
119 
120 extern u32 u64_hi(u64 x); /// return upper 32-bits
121 extern u32 u64_lo(u64 x); /// return lower 32-bits
122 extern u16 u32_hi(u32 x); /// return upper 16-bits
123 extern u16 u32_lo(u32 x); /// return lower 16-bits
124 
125 extern u64 u64_from_u32(u32 hi, u32 lo); /// assemble u64 from u32
126 extern u32 u32_from_u16(u16 hi, u16 lo); /// assemble u32 from u16
127 
128 // safe downcasters: cast from any integral type to u32 or u16;
129 // issues warning if larger than would fit in the target type.
130 //
131 // these are generally useful but included here (instead of e.g. lib.h) for
132 // several reasons:
133 // - including implementation in lib.h doesn't work because the definition
134 // of ENSURE in turn requires lib.h's STMT.
135 // - separate compilation of templates via export isn't supported by
136 // most compilers.
137 
138 template<typename T> u8 u8_from_larger(T x)
139 {
140  const u8 max = std::numeric_limits<u8>::max();
141  if((u64)x > (u64)max)
142  throw std::out_of_range("u8_from_larger");
143  return (u8)(x & max);
144 }
145 
146 template<typename T> u16 u16_from_larger(T x)
147 {
148  const u16 max = std::numeric_limits<u16>::max();
149  if((u64)x > (u64)max)
150  throw std::out_of_range("u16_from_larger");
151  return (u16)(x & max);
152 }
153 
154 template<typename T> u32 u32_from_larger(T x)
155 {
156  const u32 max = std::numeric_limits<u32>::max();
157  if((u64)x > (u64)max)
158  throw std::out_of_range("u32_from_larger");
159  return (u32)(x & max);
160 }
161 
162 /// convert double to u8; verifies number is in range.
163 extern u8 u8_from_double(double in);
164 /// convert double to u16; verifies number is in range.
165 extern u16 u16_from_double(double in);
166 
167 #endif // #ifndef INCLUDED_LIB
#define u8
Definition: types.h:39
u8 u8_from_double(double in)
convert double to u8; verifies number is in range.
Definition: lib.cpp:83
T DivideRoundUp(T dividend, T divisor)
Definition: lib.h:75
u8 u8_from_larger(T x)
assemble u32 from u16
Definition: lib.h:138
u16 u32_lo(u32 x)
return upper 16-bits
Definition: lib.cpp:59
u16 u16_from_double(double in)
convert double to u16; verifies number is in range.
Definition: lib.cpp:97
#define ASSERT(expr)
same as ENSURE in debug mode, does nothing in release mode.
Definition: debug.h:310
T Clamp(T val, T min, T max)
low-level aka &quot;lib&quot;
Definition: lib.h:68
u32 u64_lo(u64 x)
return upper 32-bits
Definition: lib.cpp:49
u32 u32_from_u16(u16 hi, u16 lo)
assemble u64 from u32
Definition: lib.cpp:73
u16 u32_hi(u32 x)
return lower 32-bits
Definition: lib.cpp:54
bool IsSimilarMagnitude(double d1, double d2, const double relativeErrorTolerance=0.05)
Definition: lib.h:105
#define T(string_literal)
Definition: secure_crt.cpp:70
u32 u32_from_larger(T x)
Definition: lib.h:154
#define u16
Definition: types.h:40
#define u64
Definition: types.h:42
#define u32
Definition: types.h:41
u64 u64_from_u32(u32 hi, u32 lo)
return lower 16-bits
Definition: lib.cpp:65
u32 u64_hi(u64 x)
Definition: lib.cpp:44
bool feq(double d1, double d2, double epsilon=0.00001)
are the given floats nearly &quot;equal&quot;?
Definition: lib.h:95
bool feqf(float f1, float f2, float epsilon=0.001f)
Definition: lib.h:100
u16 u16_from_larger(T x)
Definition: lib.h:146