TooN 2.1
internal/debug.hh
00001 namespace TooN {
00002 
00003 namespace Internal
00004 {
00005 
00006     
00007 
00008     #if defined  TOON_CHECK_BOUNDS  || defined TOON_TEST_INTERNALS
00009         static inline void check_index(int s, int i)
00010         {
00011             if(i<0 || i >= s)
00012             {
00013                 #ifdef TOON_TEST_INTERNALS
00014                     throw Internal::BadIndex();
00015                 #else
00016                     std::cerr << "Toon index out of range" << std::endl;
00017                     std::abort();
00018                 #endif
00019             }
00020         }
00021     #else
00022         ///@internal
00023         ///Function used to check bounds.
00024         ///By default it does nothing. See \ref sDebug.
00025         static inline void check_index(int, int){}
00026     #endif
00027 
00028     #if defined TOON_INITIALIZE_SNAN
00029         template<class P> static void debug_initialize(P* data, int n)
00030         {   
00031             using std::numeric_limits;
00032             for(int i=0; i < n; i++)
00033                 data[i] = numeric_limits<P>::signaling_NaN();
00034         }
00035     #elif defined TOON_INITIALIZE_QNAN || defined TOON_INITIALIZE_NAN
00036         template<class P> static void debug_initialize(P* data, int n)
00037         {   
00038             using std::numeric_limits;
00039             for(int i=0; i < n; i++)
00040                 data[i] = numeric_limits<P>::quiet_NaN();
00041         }
00042     #elif defined TOON_INITIALIZE_VAL
00043         template<class P> static void debug_initialize(P* data, int n)
00044         {   
00045             for(int i=0; i < n; i++)
00046                 data[i] = TOON_INITIALIZE_VAL;
00047         }
00048     #elif defined TOON_INITIALIZE_RANDOM
00049         union intbits
00050         {
00051             unsigned long i;
00052             char c[4];
00053         };
00054 
00055         template<class P> union datafail
00056         {
00057             int i;
00058             P p;
00059         };
00060 
00061 
00062         template<class P> static void debug_initialize(P* data, int n)
00063         {
00064             //Get a random seed. Precision limited to 1 second.
00065             static intbits random = { ((std::time(NULL) & 0xffffffff) *1664525L + 1013904223L)& 0xffffffff};
00066             unsigned char* cdata = reinterpret_cast<unsigned char*>(data);
00067 
00068             size_t bytes = sizeof(P)*n, i=0;
00069             
00070             //Do nothing except for noisy failure with non-POD types.
00071             datafail<P> d={0};
00072             bytes+=d.i;
00073             
00074             switch(bytes & 0x3 )
00075             {
00076                 for(i=0; i < bytes;)
00077                 {
00078                     //Really evil random number generator from NR.
00079                     //About 4x faster than Mersenne twister. Good quality
00080                     //is not needed, since it's only used to shake up the program
00081                     //state to test for uninitialized values. Also, it doesn't disturb
00082                     //the standard library random number generator.
00083                     
00084                     case 0:
00085                         cdata[i++] = random.c[0];   
00086                     case 3:
00087                         cdata[i++] = random.c[1];   
00088                     case 2:
00089                         cdata[i++] = random.c[2];   
00090                     case 1:
00091                         cdata[i++] = random.c[3];   
00092                     random.i = (1664525L * random.i + 1013904223L) & 0xffffffff;
00093                 }
00094             }
00095         }
00096     #else
00097         ///@internal
00098         ///@brief This function is called on any uninitialized data. By default, no action is taken. 
00099         ///See \ref sDebug
00100         template<class P> static void debug_initialize(P*, int)
00101         {
00102         }
00103     #endif
00104     
00105 
00106 }
00107 
00108 }