-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathutil_for_c.h
95 lines (73 loc) · 2.29 KB
/
util_for_c.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*
* Miscellaneous utilities for C programming language
*/
#ifndef _UTIL_FOR_C_H_
#define _UTIL_FOR_C_H_
#include <stdint.h>
// unions
union union64 {
uint64_t ui;
int64_t i;
double f;
};
union union32 {
uint32_t ui;
int32_t i;
float f;
};
union union16 {
uint16_t ui;
int16_t i;
};
union union8 {
uint8_t ui;
int8_t i;
};
// A compile time assertion check
#define __paste(foo,bar) (foo##bar)
#define __ct_assert_with_info(predication, info) \
typedef char __paste(ct_assertion_failed_at_,info)[(predication)?1:-1];
#define __ct_assert(predication) \
__ct_assert_with_info((predication), __LINE__)
// Obtain the number of elements in the given C array
#define __get_array_len(array) ( sizeof(array) / sizeof((array)[0]) )
// Align the given length to the specified power_of_two
#define __align_to_power_of_two(n_to_align, power_of_two) \
( ((n_to_align)+(power_of_two)-1) & ~((power_of_two)-1) )
// Check whether the given length is aligned to the specified power_of_two
#define __is_aligned_to_power_of_two(n_to_test, power_of_two) \
( ((n_to_test) & ((power_of_two)-1)) == 0 )
// Obtain the offset of a field in a structure
#define __get_field_offset(struct_name, field_name) \
( (uint_fast32_t)(0+&(((struct struct_name*)NULL)->field_name)) )
// Obtain the struct element at the specified offset given the struct ptr
/* #define __get_field_ptr(struct_ptr, offset) \
( (void*)(((int8_t*)struct_ptr)+(offset)) ) */
// I've seen this be compiled into one xchg instruction in gcc 4.6.3 Athlon X2
#define __xorswap(p1,p2) *(p1) ^= *(p2); *(p2) ^= *(p1); *(p1) ^= *(p2);
// A quote: "Most modern compilers can optimize the temporary variable in the naive swap,
// in which case the naive swap uses the same amount of memory and the same number of registers
// as the __xorswap does and is at least as fast, and often faster."
#define __swap(p1,p2)\
{\
__ct_assert( sizeof(*(p2)) == sizeof(*(p1)) )\
typeof(*(p1)) __tmpvar = *(p1);\
*(p1) = *(p2);\
*(p2) = __tmpvar;\
}
// Obtain the absolute value of the given floating point value
inline double _fabsd(double d)
{
union union64 ret;
ret.f = d;
ret.ui &= 0x7fffffffffffffff;
return ret.f;
}
inline float _fabsf(float f)
{
union union32 ret;
ret.f = f;
ret.ui &= 0x7fffffffu;
return ret.f;
}
#endif //_UTIL_FOR_C_H_