… | |
… | |
114 | |
114 | |
115 | // sign0 returns -1, 0 or +1 |
115 | // sign0 returns -1, 0 or +1 |
116 | template<typename T> |
116 | template<typename T> |
117 | static inline T sign0 (T v) { return v ? sign (v) : 0; } |
117 | static inline T sign0 (T v) { return v ? sign (v) : 0; } |
118 | |
118 | |
|
|
119 | //clashes with C++0x |
119 | template<typename T, typename U> |
120 | template<typename T, typename U> |
120 | static inline T copysign (T a, U b) { return a > 0 ? b : -b; } |
121 | static inline T copysign (T a, U b) { return a > 0 ? b : -b; } |
121 | |
122 | |
122 | // div* only work correctly for div > 0 |
123 | // div* only work correctly for div > 0 |
123 | // div, with correct rounding (< 0.5 downwards, >=0.5 upwards) |
124 | // div, with correct rounding (< 0.5 downwards, >=0.5 upwards) |
… | |
… | |
511 | // use FNV-1a hash (http://isthe.com/chongo/tech/comp/fnv/) |
512 | // use FNV-1a hash (http://isthe.com/chongo/tech/comp/fnv/) |
512 | // it is about twice as fast as the one-at-a-time one, |
513 | // it is about twice as fast as the one-at-a-time one, |
513 | // with good distribution. |
514 | // with good distribution. |
514 | // FNV-1a is faster on many cpus because the multiplication |
515 | // FNV-1a is faster on many cpus because the multiplication |
515 | // runs concurrently with the looping logic. |
516 | // runs concurrently with the looping logic. |
|
|
517 | // we modify the hash a bit to improve its distribution |
516 | uint32_t hash = STRHSH_NULL; |
518 | uint32_t hash = STRHSH_NULL; |
517 | |
519 | |
518 | while (*s) |
520 | while (*s) |
519 | hash = (hash ^ *s++) * 16777619U; |
521 | hash = (hash ^ *s++) * 16777619U; |
520 | |
522 | |
521 | return hash; |
523 | return hash ^ (hash >> 16); |
522 | } |
524 | } |
523 | |
525 | |
524 | static inline uint32_t |
526 | static inline uint32_t |
525 | memhsh (const char *s, size_t len) |
527 | memhsh (const char *s, size_t len) |
526 | { |
528 | { |
… | |
… | |
641 | { |
643 | { |
642 | erase (&obj); |
644 | erase (&obj); |
643 | } |
645 | } |
644 | }; |
646 | }; |
645 | |
647 | |
|
|
648 | ///////////////////////////////////////////////////////////////////////////// |
|
|
649 | |
|
|
650 | // something like a vector or stack, but without |
|
|
651 | // out of bounds checking |
|
|
652 | template<typename T> |
|
|
653 | struct fixed_stack |
|
|
654 | { |
|
|
655 | T *data; |
|
|
656 | int size; |
|
|
657 | int max; |
|
|
658 | |
|
|
659 | fixed_stack () |
|
|
660 | : size (0), data (0) |
|
|
661 | { |
|
|
662 | } |
|
|
663 | |
|
|
664 | fixed_stack (int max) |
|
|
665 | : size (0), max (max) |
|
|
666 | { |
|
|
667 | data = salloc<T> (max); |
|
|
668 | } |
|
|
669 | |
|
|
670 | void reset (int new_max) |
|
|
671 | { |
|
|
672 | sfree (data, max); |
|
|
673 | size = 0; |
|
|
674 | max = new_max; |
|
|
675 | data = salloc<T> (max); |
|
|
676 | } |
|
|
677 | |
|
|
678 | void free () |
|
|
679 | { |
|
|
680 | sfree (data, max); |
|
|
681 | data = 0; |
|
|
682 | } |
|
|
683 | |
|
|
684 | ~fixed_stack () |
|
|
685 | { |
|
|
686 | sfree (data, max); |
|
|
687 | } |
|
|
688 | |
|
|
689 | T &operator[](int idx) |
|
|
690 | { |
|
|
691 | return data [idx]; |
|
|
692 | } |
|
|
693 | |
|
|
694 | void push (T v) |
|
|
695 | { |
|
|
696 | data [size++] = v; |
|
|
697 | } |
|
|
698 | |
|
|
699 | T &pop () |
|
|
700 | { |
|
|
701 | return data [--size]; |
|
|
702 | } |
|
|
703 | |
|
|
704 | T remove (int idx) |
|
|
705 | { |
|
|
706 | T v = data [idx]; |
|
|
707 | |
|
|
708 | data [idx] = data [--size]; |
|
|
709 | |
|
|
710 | return v; |
|
|
711 | } |
|
|
712 | }; |
|
|
713 | |
|
|
714 | ///////////////////////////////////////////////////////////////////////////// |
|
|
715 | |
646 | // basically does what strncpy should do, but appends "..." to strings exceeding length |
716 | // basically does what strncpy should do, but appends "..." to strings exceeding length |
647 | // returns the number of bytes actually used (including \0) |
717 | // returns the number of bytes actually used (including \0) |
648 | int assign (char *dst, const char *src, int maxsize); |
718 | int assign (char *dst, const char *src, int maxsize); |
649 | |
719 | |
650 | // type-safe version of assign |
720 | // type-safe version of assign |