00001 // -*- mode: C++; c-file-style: "stroustrup"; c-basic-offset: 4; indent-tabs-mode: nil; -*- 00002 //////////////////////////////////////////////////////////////////// 00003 // 00004 // Filename : xorptr.h (base) 00005 // 00006 // This file is a part of the UPPAAL toolkit. 00007 // Copyright (c) 1995 - 2003, Uppsala University and Aalborg University. 00008 // All right reserved. 00009 // 00010 // $Id: xorptr.h,v 1.3 2004/06/14 07:36:54 adavid Exp $ 00011 // 00012 /////////////////////////////////////////////////////////////////// 00013 00014 #ifndef INCLUDE_BASE_XORPTR_H 00015 #define INCLUDE_BASE_XORPTR_H 00016 00017 #include "base/inttypes.h" 00018 #include <assert.h> 00019 00020 namespace base 00021 { 00022 /** xorptr_t encapsulate "safely" 00023 * the concept of swapping between 00024 * 2 pointers with a xor operation. 00025 * 00026 * Xor between a pointer and an int: 00027 * sounds scary but it is a very efficient 00028 * way to swap 2 pointers: 00029 * - init ptr to ptr1 00030 * - init xorPtr to ptr1 ^ ptr2 00031 * - swaping between ptr1 and ptr2 00032 * is now equivalent to ptr ^= xorPtr, 00033 * which is done without jump + we 00034 * need to store only one xorPtr 00035 * and not ptr1 and ptr2. 00036 * 00037 * The original idea of supperposing 2 states into one (here 2 00038 * pointers) in such a way that you get information on one state 00039 * only by observing the other state comes from quantum mechanics. 00040 */ 00041 template<class T> 00042 class xorptr_t 00043 { 00044 public: 00045 00046 /** Constructor: supperpose 00047 * internal values ptr1 and ptr2. 00048 * @param ptr1,ptr2: pointers to 00049 * swap between. 00050 */ 00051 xorptr_t(T* ptr1, T* ptr2) 00052 : ptr1xor2(((uintptr_t)ptr1) ^ 00053 ((uintptr_t)ptr2)) 00054 { 00055 assert(sizeof(T*) >= sizeof(uintptr_t)); 00056 } 00057 00058 00059 /** Swap pointer (between ptr1 and 00060 * ptr2 used originally). 00061 * @return ptr1 if fromPtr == ptr2 00062 * or ptr2 if fromPtr == ptr1 00063 * @pre fromPtr == ptr1 or ptr2 00064 */ 00065 T* swap(T* fromPtr) const 00066 { 00067 return (T*)(((uintptr_t)fromPtr) ^ ptr1xor2); 00068 } 00069 00070 private: 00071 uintptr_t ptr1xor2; /**< supperposition of 2 pointers */ 00072 }; 00073 } 00074 00075 #endif // INCLUDE_BASE_XORPTR_H