Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

bitptr.h

Go to the documentation of this file.
00001 // -*- mode: C++; c-file-style: "stroustrup"; c-basic-offset: 4; indent-tabs-mode: nil; -*-
00002 ////////////////////////////////////////////////////////////////////
00003 //
00004 // Filename : bitptr.h (base)
00005 //
00006 // Provides: bitptr_u bitptr_t
00007 //
00008 // This file is a part of the UPPAAL toolkit.
00009 // Copyright (c) 1995 - 2003, Uppsala University and Aalborg University.
00010 // All right reserved.
00011 //
00012 // $Id: bitptr.h,v 1.3 2004/06/14 07:36:53 adavid Exp $
00013 //
00014 ///////////////////////////////////////////////////////////////////
00015 
00016 #ifndef INCLUDE_BASE_BITPTR_H
00017 #define INCLUDE_BASE_BITPTR_H
00018 
00019 #include <assert.h>
00020 #include <stdlib.h>
00021 #include "base/inttypes.h"
00022 
00023 namespace base
00024 {
00025     /** Cast in a nutshell
00026      * Conversion int <-> ptr with a union.
00027      * Use of (u)intptr_t to avoid possible
00028      * endianness problems when manipulating
00029      * the lower bits.
00030      */
00031     typedef union
00032     {
00033         intptr_t ival;
00034         uintptr_t uval;
00035         void *ptr;
00036     } bitptr_u;
00037 
00038     /** Encapsulation of lower bit manipulation of a pointer.
00039      * bitptr_t protects operation on the 2 lower bits
00040      * of a pointer. These bits may contain data.
00041      * Valid operation is done only on those 2 bits.
00042      * Name IntPtr chosen because it is a hybrid type
00043      * both an int and a pointer.
00044      * Name in lower case because it is a wrapper around
00045      * a pointer/int basic scalar type.
00046      */
00047     template<class PtrType>
00048     class bitptr_t
00049     {
00050     public:
00051         
00052         /** Default constructor
00053          */
00054         bitptr_t()
00055         {
00056             assert(sizeof(uintptr_t) == sizeof(void*));
00057             value.ptr = NULL;
00058         }
00059         
00060         /** Pointer constructor
00061          * @param ptr: pointer to represent.
00062          * @pre ptr is 32 bit aligned.
00063          */
00064         bitptr_t(PtrType *ptr)
00065         {
00066             assert(sizeof(uintptr_t) == sizeof(void*));
00067             value.ptr = ptr;
00068             assert(getBits(3) == 0);
00069         }
00070         
00071         /** Bits constructor
00072          * @param mask: bits of the int part.
00073          * @pre mask <= 3.
00074          */
00075         bitptr_t(uintptr_t mask)
00076         {
00077             assert(sizeof(uintptr_t) == sizeof(void*));
00078             assert(mask <= 3);
00079             value.uval = mask;
00080         }
00081         
00082         /** Bits constructor, only a wrapper
00083          * for convenience.
00084          * @param mask: bits of the int part.
00085          * @pre mask <= 3 and mask >= 0
00086          */
00087         bitptr_t(intptr_t mask)
00088         {
00089             assert(sizeof(uintptr_t) == sizeof(void*));
00090             assert(mask <= 3 && mask >= 0);
00091             value.ival = mask;
00092         }
00093         
00094         /** Pointer and bits constructor.
00095          * @param ptr: pointer to represent.
00096          * @param mask: bits of the int part.
00097          * @pre
00098          * - ptr is 32 bits aligned.
00099          * - mask <= 3
00100          */
00101         bitptr_t(PtrType *ptr, uintptr_t mask)
00102         {
00103             assert(sizeof(uintptr_t) == sizeof(void*));
00104             assert(mask <= 3);
00105             value.ptr = ptr;
00106             value.uval |= mask;
00107         }
00108         
00109         /** Pointer and bits constructor, wrapper
00110          * for convenience only.
00111          * @param ptr: pointer to represent.
00112          * @param mask: bits of the int part.
00113          * @pre
00114          * - ptr is 32 bits aligned.
00115          * - mask <= 3 and mask >= 0
00116          */
00117         bitptr_t(PtrType *ptr, intptr_t mask)
00118         {
00119             assert(sizeof(uintptr_t) == sizeof(void*));
00120             assert(mask <= 3 && mask >= 0);
00121             value.ptr = ptr;
00122             value.ival |= mask;
00123         }
00124         
00125         /** IntPtr and new bits for int part.
00126          * Takes pointer from ptr and bits from mask
00127          * @param ptr: pointer part to take.
00128          * @param mask: bits of the int part.
00129          * @pre mask <= 3
00130          */
00131         bitptr_t(bitptr_t<PtrType> ptr, uintptr_t mask)
00132         {
00133             assert(sizeof(uintptr_t) == sizeof(void*));
00134             assert(mask <= 3);
00135             value.uval = (ptr.value.uval & ~3) | mask;
00136         }
00137         
00138         /** IntPtr and new bits for int part, wrapper
00139          * for convenience only. 
00140          * Takes pointer from ptr and bits from mask
00141          * @param ptr: pointer part to take.
00142          * @param mask: bits of the int part.
00143          * @pre mask <= 3 and mask >= 0
00144          */
00145         bitptr_t(bitptr_t<PtrType> ptr, intptr_t mask)
00146         {
00147             assert(sizeof(uintptr_t) == sizeof(void*));
00148             assert(mask <= 3 && mask >= 0);
00149             value.ival = (ptr.value.ival & ~3) | mask;
00150         }
00151         
00152         /** IntPtr and new bits for int part.
00153          * Takes pointer from ptr and bits from mask
00154          * @param ptr: pointer part to take.
00155          * @param bits: bits of the int part.
00156          */
00157         bitptr_t(PtrType *ptr, bitptr_t bits)
00158         {
00159             assert(sizeof(uintptr_t) == sizeof(void*));
00160             value.ptr = ptr;
00161             value.uval |= bits.value.uval & 3;
00162         }
00163         
00164         /** Read the int bits only.
00165          * @return the int part of IntPtr.
00166          */
00167         uintptr_t getBits() const
00168         {
00169             return value.uval & 3;
00170         }
00171         
00172         /** Read some bits only from the int bits.
00173          * @param mask: mask to read the bits.
00174          * @pre mask <= 3
00175          */
00176         uintptr_t getBits(uintptr_t mask) const
00177         {
00178             assert(mask <= 3);
00179             return value.uval & mask;
00180         }
00181         
00182         /** Read some bits only from the int bits,
00183          * wrapper for convenience only.
00184          * @param mask: mask to read the bits.
00185          * @pre mask <= 3 and mask >= 0
00186          */    
00187         intptr_t getBits(intptr_t mask) const
00188         {
00189             assert(mask <= 3 && mask >= 0);
00190             return value.ival & mask;
00191         }
00192         
00193         /** Read the pointer part.
00194          * @return a clean pointer aligned on 32 bits.
00195          */
00196         PtrType* getPtr() const
00197         {
00198             bitptr_u result = value;
00199             result.uval &= ~3;
00200             return reinterpret_cast<PtrType*>(result.ptr);
00201         }
00202         
00203         /** Add bits and don't touche the
00204          * pointer part.
00205          * @param mask: bits to add.
00206          * @pre mask <= 3
00207          */
00208         void addBits(uintptr_t mask)
00209         {
00210             assert(mask <= 3);
00211             value.uval |= mask;
00212         }
00213         
00214         /** Add bits and don't touche the
00215          * pointer part, for convenience
00216          * only.
00217          * @param mask: bits to add.
00218          * @pre mask <= 3 and mask >= 0
00219          */
00220         void addBits(intptr_t mask)
00221         {
00222             assert(mask <= 3 && mask >= 0);
00223             value.ival |= mask;
00224         }
00225         
00226         /** Delete bits and don't touch
00227          * the pointer part.
00228          * @param mask: bits to remove.
00229          * @pre mask <= 3
00230          */
00231         void delBits(uintptr_t mask)
00232         {
00233             assert(mask <= 3);
00234             value.uval &= ~mask;
00235         }
00236         
00237         /** Delete bits and don't touch
00238          * the pointer part, for convenience
00239          * only.
00240          * @param mask: bits to remove.
00241          * @pre mask <= 3 and mask >= 0
00242          */
00243         void delBits(intptr_t mask)
00244         {
00245             assert(mask <= 3 && mask >= 0);
00246             value.ival &= ~mask;
00247         }
00248 
00249         /** Set the pointer part and keep
00250          * the int part.
00251          * @param ptr: new pointer value.
00252          * @pre ptr is 32 bits aligned.
00253          */
00254         void setPtr(PtrType *ptr)
00255         {
00256             bitptr_u uptr;
00257             uptr.ptr = ptr;
00258             value.uval = uptr.uval | (value.uval & 3);
00259         }
00260 
00261     private:
00262         bitptr_u value; /**< value & ~3 is the pointer
00263                            and value & 3 is the int part */
00264     };
00265 
00266 } // namespace base
00267 
00268 #endif // INCLUDE_BASE_BITPTR_H

Generated on Fri Jun 30 00:02:30 2006 for Module base by  doxygen 1.4.2