--- deliantra/server/include/util.h 2010/03/26 01:04:44 1.97 +++ deliantra/server/include/util.h 2010/05/02 11:23:51 1.106 @@ -57,6 +57,17 @@ // use C0X decltype for auto declarations until ISO C++ sanctifies them (if ever) #define auto(var,expr) decltype(expr) var = (expr) +#if cplusplus_does_not_suck +// does not work for local types (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm) +template +static inline int array_length (const T (&arr)[N]) +{ + return N; +} +#else +#define array_length(name) (sizeof (name) / sizeof (name [0])) +#endif + // very ugly macro that basically declares and initialises a variable // that is in scope for the next statement only // works only for stuff that can be assigned 0 and converts to false @@ -95,18 +106,29 @@ static inline T sign (T v) { return v < 0 ? -1 : +1; } // relies on 2c representation template<> -inline sint8 sign (sint8 v) { return 1 - (sint8 (uint8 (v) >> 7) * 2); } +inline sint8 sign (sint8 v) { return 1 - (sint8 (uint8 (v) >> 7) * 2); } +template<> +inline sint16 sign (sint16 v) { return 1 - (sint16 (uint16 (v) >> 15) * 2); } +template<> +inline sint32 sign (sint32 v) { return 1 - (sint32 (uint32 (v) >> 31) * 2); } // sign0 returns -1, 0 or +1 template static inline T sign0 (T v) { return v ? sign (v) : 0; } +template +static inline T copysign (T a, U b) { return a > 0 ? b : -b; } + // div* only work correctly for div > 0 // div, with correct rounding (< 0.5 downwards, >=0.5 upwards) template static inline T div (T val, T div) { return expect_false (val < 0) ? - ((-val + (div - 1) / 2) / div) : (val + div / 2) / div; } + +template<> inline float div (float val, float div) { return val / div; } +template<> inline double div (double val, double div) { return val / div; } + // div, round-up template static inline T div_ru (T val, T div) { @@ -461,7 +483,7 @@ template struct random_number_generator : generator { - // uniform distribution, 0 .. max (0, num - 1) + // uniform distribution, [0 .. num - 1] uint32_t operator ()(uint32_t num) { return !is_constant (num) ? get_range (num) // non-constant @@ -469,17 +491,18 @@ : this->next () & (num - 1); // constant, power-of-two } - // return a number within (min .. max) + // return a number within the closed interval [min .. max] int operator () (int r_min, int r_max) { - return is_constant (r_min) && is_constant (r_max) && r_min <= r_max + return is_constant (r_min <= r_max) && r_min <= r_max ? r_min + operator ()(r_max - r_min + 1) : get_range (r_min, r_max); } + // return a number within the half-open interval [0..1[ double operator ()() { - return this->next () / (double)0xFFFFFFFFU; + return this->next () / 0x100000000; } protected: @@ -561,6 +584,7 @@ typedef refptr arch_ptr; typedef refptr client_ptr; typedef refptr player_ptr; +typedef refptr region_ptr; #define STRHSH_NULL 2166136261 @@ -575,7 +599,7 @@ uint32_t hash = STRHSH_NULL; while (*s) - hash = (hash ^ *s++) * 16777619; + hash = (hash ^ *s++) * 16777619U; return hash; } @@ -586,7 +610,7 @@ uint32_t hash = STRHSH_NULL; while (len--) - hash = (hash ^ *s++) * 16777619; + hash = (hash ^ *s++) * 16777619U; return hash; }