// // Copyright (C) 2000, 2001, 2002 Andrey Slepuhin // // libp++ is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // libp++ is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with libp++; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // $Source$ // $Revision$ // $Date$ // Author: Andrey Slepuhin #ifndef __pxx_common_ih__ #define __pxx_common_ih__ #include "pxx_common.hh" namespace pxx { // // This function returns a ceiling of a binary logarythm of its argument. // Here are two implementations of this function. Choose the one that you like. inline size_t get_order (size_t _size) { if (_size > 0) _size--; #if 1 size_t b; int n = -8; do { b = _size & size_t(0xFF); _size >>= 8; n += 8; } while (_size != 0); return orders[b] + n + 1; #else size_t n = 0; if (_size & 0xFFFF0000) { _size &= 0xFFFF0000; n += 16; } if (_size & 0xFF00FF00) { _size &= 0xFF00FF00; n += 8; } if (_size & 0xF0F0F0F0) { _size &= 0xF0F0F0F0; n += 4; } if (_size & 0xCCCCCCCC) { _size &= 0xCCCCCCCC; n += 2; } if (_size & 0xAAAAAAAA) n += 1; return n + 1; #endif } // // This functions checks whether a pointer is properly aligned. The second // argument should be an exponent of 2. inline bool ptr_is_aligned (void const* _ptr, uintptr_t _align) { return ((_align - 1) & uintptr_t(_ptr)) == 0; } // // This function aligns a pointer, rounding it to a smaller value. inline void* ptr_align (void const* _ptr, uintptr_t _align) { return (void*)(((uintptr_t)_ptr) & (~(_align - 1))); } // // This function aligns an integer size, rounding it to a higher value. inline size_t size_align (size_t _size, size_t _align) { _align--; return (_size + _align) & (~(_align)); } // // These functions implement bit operations on pointer values. inline void* ptr_and (void* _p1, void* _p2) { return (void*)((uintptr_t)_p1 & (uintptr_t)_p2); } inline void* ptr_or (void* _p1, void* _p2) { return (void*)((uintptr_t)_p1 | (uintptr_t)_p2); } inline void* ptr_xor (void* _p1, void* _p2) { return (void*)((uintptr_t)_p1 ^ (uintptr_t)_p2); } // // This function finds the least significant bit by which two pointers differ // and returns an integer where this bit is set. inline uintptr_t ptr_diff (void const* _p1, void const* _p2) { uintptr_t diff = (uintptr_t)_p1 ^ (uintptr_t)_p2; return ((diff ^ (diff - 1)) >> 1) + 1; } template inline type_t* ptr_add (type_t* _ptr, size_t _value) { return (type_t*)((char*)_ptr + _value); } // // Pointer arithmetic. template inline type_t* ptr_add_offset (type_t* _ptr, ssize_t _value) { return (type_t*)((char*)_ptr + _value); } template inline type_t* ptr_sub_offset (type_t* _ptr, ssize_t _value) { return (type_t*)((char*)_ptr - _value); } template inline ssize_t ptr_sub (type1_t* _ptr1, type2_t* _ptr2) { return ((char*)_ptr1 - (char*)_ptr2); } } #endif // __pxx_common_ih__