Disk ARchive  2.3.11
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Defines
limitint.hpp
Go to the documentation of this file.
00001 /*********************************************************************/
00002 // dar - disk archive - a backup/restoration program
00003 // Copyright (C) 2002-2052 Denis Corbin
00004 //
00005 // This program is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 //
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018 //
00019 // to contact the author : dar.linux@free.fr
00020 /*********************************************************************/
00021 // $Id: limitint.hpp,v 1.18.2.5 2011/01/04 16:27:13 edrusb Rel $
00022 //
00023 /*********************************************************************/
00024 
00032 
00033 #ifndef LIMITINT_HPP
00034 #define LIMITINT_HPP
00035 
00036 #include "../my_config.h"
00037 
00038 extern "C"
00039 {
00040 #if HAVE_SYS_TYPES_H
00041 #include <sys/types.h>
00042 #endif
00043 
00044 #if HAVE_UNISTD_H
00045 #include <unistd.h>
00046 #endif
00047 } // end extern "C"
00048 
00049 #include <typeinfo>
00050 #include "integers.hpp"
00051 #include "erreurs.hpp"
00052 #include "special_alloc.hpp"
00053 #include "int_tools.hpp"
00054 
00055 namespace libdar
00056 {
00057 
00058     class generic_file;
00059     class user_interaction;
00060 
00062 
00072 
00073     template<class B> class limitint
00074     {
00075     public :
00076 
00077 #if SIZEOF_OFF_T > SIZEOF_TIME_T
00078 #if SIZEOF_OFF_T > SIZEOF_SIZE_T
00079         limitint(off_t a = 0)
00080             { E_BEGIN; limitint_from(a); E_END("limitint::limitint", "off_t"); };
00081 #else
00082         limitint(size_t a = 0)
00083             { E_BEGIN; limitint_from(a); E_END("limitint::limitint", "size_t"); };
00084 #endif
00085 #else
00086 #if SIZEOF_TIME_T > SIZEOF_SIZE_T
00087         limitint(time_t a = 0)
00088             { E_BEGIN; limitint_from(a); E_END("limitint::limitint", "time_t"); };
00089 #else
00090         limitint(size_t a = 0)
00091             { E_BEGIN; limitint_from(a); E_END("limitint::limitint", "size_t"); };
00092 #endif
00093 #endif
00094 
00095         limitint(user_interaction & dialog, S_I *fd, generic_file *x); // read an limitint from a file
00096 
00097 
00098         void dump(user_interaction & dialog, S_I fd) const; // write byte sequence to file
00099         void dump(generic_file &x) const; // write byte sequence to file
00100         void read(generic_file &f) { build_from_file(f); };
00101 
00102         limitint & operator += (const limitint & ref);
00103         limitint & operator -= (const limitint & ref);
00104         limitint & operator *= (const limitint & ref);
00105         template <class T> limitint power(const T & exponent) const;
00106         limitint & operator /= (const limitint & ref);
00107         limitint & operator %= (const limitint & ref);
00108         limitint & operator &= (const limitint & ref);
00109         limitint & operator |= (const limitint & ref);
00110         limitint & operator ^= (const limitint & ref);
00111         limitint & operator >>= (U_32 bit);
00112         limitint & operator >>= (limitint bit);
00113         limitint & operator <<= (U_32 bit);
00114         limitint & operator <<= (limitint bit);
00115         limitint operator ++(int a)
00116             { E_BEGIN; limitint ret = *this; ++(*this); return ret; E_END("limitint::operator ++", "int"); };
00117         limitint operator --(int a)
00118             { E_BEGIN; limitint ret = *this; --(*this); return ret; E_END("limitint::operator --", "int"); };
00119         limitint & operator ++()
00120             { E_BEGIN; return *this += 1; E_END("limitint::operator ++", "()"); };
00121         limitint & operator --()
00122             { E_BEGIN; return *this -= 1; E_END("limitint::operator --", "()"); };
00123 
00124         U_32 operator % (U_32 arg) const;
00125 
00126             // increment the argument up to a legal value for its storage type and decrement the object in consequence
00127             // note that the initial value of the argument is not ignored !
00128             // when the object is null the value of the argument stays the same as before
00129         template <class T>void unstack(T &v)
00130             { E_BEGIN; limitint_unstack_to(v); E_END("limitint::unstack", typeid(v).name()); }
00131 
00132         limitint get_storage_size() const;
00133             // it returns number of byte of information necessary to store the integer
00134 
00135         unsigned char operator [] (const limitint & position) const;
00136             // return in big endian order the information byte storing the integer
00137 
00138 
00139         bool operator < (const limitint &x) const { return field < x.field; };
00140         bool operator == (const limitint &x) const { return field == x.field; };
00141         bool operator > (const limitint &x) const { return field > x.field; };
00142         bool operator <= (const limitint &x) const { return field <= x.field; };
00143         bool operator != (const limitint &x) const { return field != x.field; };
00144         bool operator >= (const limitint &x) const { return field >= x.field; };
00145 
00146         static bool is_system_big_endian();
00147 
00148 #ifdef LIBDAR_SPECIAL_ALLOC
00149         USE_SPECIAL_ALLOC(limitint);
00150 #endif
00151 
00152         B debug_get_max() const { return max_value; };
00153         B debug_get_bytesize() const { return bytesize; };
00154 
00155     private :
00156         static const int TG = 4;
00157         static const U_32 sizeof_field = sizeof(B);
00158 
00159         enum endian { big_endian, little_endian, not_initialized };
00160         typedef unsigned char group[TG];
00161 
00162         B field;
00163 
00164         void build_from_file(generic_file & x);
00165         template <class T> void limitint_from(T a);
00166         template <class T> void limitint_unstack_to(T &a);
00167 
00169             // static statments
00170             //
00171         static endian used_endian;
00172         static const U_I bytesize = sizeof(B);
00173         static const B max_value = ~B(0) > 0 ? ~B(0) : ~(B(1) << (bytesize*8 - 1));
00174         static void setup_endian();
00175     };
00176 
00177     template <class B> limitint<B> operator + (const limitint<B> &, const limitint<B> &);
00178     template <class B> inline limitint<B> operator + (const limitint<B> & a, U_I b)
00179     { return a + limitint<B>(b); }
00180     template <class B> limitint<B> operator - (const limitint<B> &, const limitint<B> &);
00181     template <class B> inline limitint<B> operator - (const limitint<B> & a, U_I b)
00182     { return a - limitint<B>(b); }
00183     template <class B> limitint<B> operator * (const limitint<B> &, const limitint<B> &);
00184     template <class B> inline limitint<B> operator * (const limitint<B> & a, U_I b)
00185     { return a * limitint<B>(b); }
00186     template <class B> limitint<B> operator / (const limitint<B> &, const limitint<B> &);
00187     template <class B> limitint<B> operator / (const limitint<B> & a, U_I b)
00188     { return a / limitint<B>(b); }
00189     template <class B> limitint<B> operator % (const limitint<B> &, const limitint<B> &);
00190     template <class B> limitint<B> operator >> (const limitint<B> & a, U_32 bit);
00191     template <class B> limitint<B> operator >> (const limitint<B> & a, const limitint<B> & bit);
00192     template <class B> limitint<B> operator << (const limitint<B> & a, U_32 bit);
00193     template <class B> limitint<B> operator << (const limitint<B> & a, const limitint<B> & bit);
00194     template <class B> limitint<B> operator & (const limitint<B> & a, U_32  bit);
00195     template <class B> limitint<B> operator & (const limitint<B> & a, const limitint<B> & bit);
00196     template <class B> limitint<B> operator | (const limitint<B> & a, U_32  bit);
00197     template <class B> limitint<B> operator | (const limitint<B> & a, const limitint<B> & bit);
00198     template <class B> limitint<B> operator ^ (const limitint<B> & a, U_32  bit);
00199     template <class B> limitint<B> operator ^ (const limitint<B> & a, const limitint<B> & bit);
00200 
00201     template <class T> inline void euclide(T a, T b, T & q, T &r)
00202     {
00203         E_BEGIN;
00204         q = a/b; r = a%b;
00205         E_END("euclide", "");
00206     }
00207 
00208     template <class B> inline void euclide(limitint<B> a, U_I b, limitint<B> & q, limitint<B> &r)
00209     {
00210         euclide(a, limitint<B>(b), q, r);
00211     }
00212 
00213 #ifndef INFININT_BASE_TYPE
00214 #error INFININT_BASE_TYPE not defined cannot instantiate template
00215 #else
00216     typedef limitint<INFININT_BASE_TYPE> infinint;
00217 #endif
00218 } // end of namespace
00222 
00223 #include "generic_file.hpp"
00224 #include "user_interaction.hpp"
00225 
00226 namespace libdar
00227 {
00228 
00229     template <class B> typename limitint<B>::endian limitint<B>::used_endian = not_initialized;
00230 
00231     template <class B> limitint<B>::limitint(user_interaction & dialog, S_I *fd, generic_file *x)
00232     {
00233         if(fd != NULL && x != NULL)
00234             throw Erange("limitint::limitint(file, file)", "Both arguments are not NULL, please choose one or the other, not both"); // message not translated, expected
00235         if(fd != NULL)
00236         {
00237             fichier f = fichier(dialog, dup(*fd));
00238             build_from_file(f);
00239         }
00240         else
00241             if(x != NULL)
00242                 build_from_file(*x);
00243             else
00244                 throw Erange("limitint::limitint(file, file)", "Cannot read from file, both arguments are NULL"); // message not translated, expected
00245     }
00246 
00247     template <class B> void limitint<B>::dump(user_interaction & dialog, S_I fd) const
00248     {
00249         fichier f = fichier(dialog, dup(fd));
00250         dump(f);
00251     }
00252 
00253     template <class B> void limitint<B>::build_from_file(generic_file & x)
00254     {
00255         E_BEGIN;
00256         unsigned char a;
00257         bool fin = false;
00258         limitint<B> skip = 0;
00259         char *ptr = (char *)&field;
00260         S_I lu;
00261         int_tools_bitfield bf;
00262 
00263         while(!fin)
00264         {
00265             lu = x.read((char *)&a, 1);
00266 
00267             if(lu <= 0)
00268                 throw Erange("limitint::build_from_file(generic_file)", gettext("Reached end of file before all data could be read"));
00269 
00270             if(a == 0)
00271                 ++skip;
00272             else // end of size field
00273             {
00274                     // computing the size to read
00275                 U_I pos = 0;
00276 
00277                 int_tools_expand_byte(a, bf);
00278                 for(S_I i = 0; i < 8; ++i)
00279                     pos += bf[i];
00280                 if(pos != 1)
00281                     throw Erange("limitint::build_from_file(generic_file)", gettext("Badly formed infinint or not supported format")); // more than 1 bit is set to 1
00282 
00283                 pos = 0;
00284                 while(bf[pos] == 0)
00285                     ++pos;
00286                 pos += 1; // bf starts at zero, but bit zero means 1 TG of length
00287 
00288                 skip *= 8;
00289                 skip += pos;
00290                 skip *= TG;
00291 
00292                 if(skip.field > bytesize)
00293                     throw Elimitint();
00294 
00295                 field = 0; // important to also clear "unread" bytes by the following call
00296                 lu = x.read(ptr, skip.field);
00297 
00298                 if(used_endian == not_initialized)
00299                     setup_endian();
00300                 if(used_endian == big_endian)
00301                     int_tools_swap_bytes((unsigned char *)ptr, skip.field);
00302                 else
00303                     field >>= (bytesize - skip.field)*8;
00304                 fin = true;
00305             }
00306         }
00307         E_END("limitint::read_from_file", "generic_file");
00308     }
00309 
00310 
00311     template <class B> void limitint<B>::dump(generic_file & x) const
00312     {
00313         E_BEGIN;
00314         B width = bytesize;
00315         B pos;
00316         unsigned char last_width;
00317         B justification;
00318         S_I direction = +1;
00319         unsigned char *ptr, *fin;
00320 
00321 
00322         if(used_endian == not_initialized)
00323             setup_endian();
00324 
00325         if(used_endian == big_endian)
00326         {
00327             direction = -1;
00328             ptr = (unsigned char *)(&field) + (bytesize - 1);
00329             fin = (unsigned char *)(&field) - 1;
00330         }
00331         else
00332         {
00333             direction = +1;
00334             ptr = (unsigned char *)(&field);
00335             fin = (unsigned char *)(&field) + bytesize;
00336         }
00337 
00338         while(ptr != fin && *ptr == 0)
00339         {
00340             ptr += direction;
00341             --width;
00342         }
00343         if(width == 0)
00344             width = 1; // minimum size of information is 1 byte
00345 
00346             // "width" is the informational field size in byte
00347             // TG is the width in TG, thus the number of bit that must have
00348             // the preamble
00349         euclide(width, (const B)(TG), width, justification);
00350         if(justification != 0)
00351                 // in case we need to add some bytes to have a width multiple of TG
00352             ++width;  // we need then one more group to have a width multiple of TG
00353 
00354         euclide(width, (const B)(8), width, pos);
00355         if(pos == 0)
00356         {
00357             width--; // division is exact, only last bit of the preambule is set
00358             last_width = 0x80 >> 7;
00359                 // as we add the last byte separately width gets shorter by 1 byte
00360         }
00361         else // division non exact, the last_width (last byte), make the rounding
00362         {
00363             U_16 pos_s = (U_16)(0xFFFF & pos);
00364             last_width = 0x80 >> (pos_s - 1);
00365         }
00366 
00367             // now we write the preamble except the last byte. All these are zeros.
00368 
00369         unsigned char u = 0x00;
00370 
00371         while(width-- > 0)
00372             if(x.write((char *)(&u), 1) < 1)
00373                 throw Erange("limitint::dump(generic_file)", gettext("Cannot write data to file"));
00374 
00375 
00376             // now we write the last byte of the preambule, which as only one bit set
00377 
00378         if(x.write((char *)&last_width, 1) < 1)
00379             throw Erange("limitint::dump(generic_file)", gettext("Cannot write data to file"));
00380 
00381             // we need now to write some justification byte to have an informational field multiple of TG
00382 
00383         if(justification != 0)
00384         {
00385             justification = TG - justification;
00386             while(justification-- > 0)
00387                 if(x.write((char *)(&u), 1) < 1)
00388                     throw Erange("limitint::dump(generic_file)", gettext("Cannot write data to file"));
00389         }
00390 
00391             // now we continue dumping the informational bytes:
00392         if(ptr == fin) // field is equal to zero
00393         {
00394             if(x.write((char *)(&u), 1) < 1)
00395                 throw Erange("limitint::dump(generic_file)", gettext("Cannot write data to file"));
00396         }
00397         else // we have some bytes to write down
00398             while(ptr != fin)
00399             {
00400                 if(x.write((char *)ptr, 1) < 1)
00401                     throw Erange("limitint::dump(generic_file)", gettext("Cannot write data to file"));
00402                 else
00403                     ptr += direction;
00404             }
00405 
00406         E_END("limitint::dump", "generic_file");
00407     }
00408 
00409     template<class B> limitint<B> & limitint<B>::operator += (const limitint & arg)
00410     {
00411         E_BEGIN;
00412         B res = field + arg.field;
00413         if(res < field || res < arg.field)
00414             throw Elimitint();
00415         else
00416             field = res;
00417 
00418         return *this;
00419         E_END("limitint::operator +=", "");
00420     }
00421 
00422     template <class B> limitint<B> & limitint<B>::operator -= (const limitint & arg)
00423     {
00424         E_BEGIN;
00425         if(field < arg.field)
00426             throw Erange("limitint::operator", gettext("Subtracting a infinint greater than the first, infinint cannot be negative"));
00427 
00428             // now processing the operation
00429 
00430         field -= arg.field;
00431         return *this;
00432         E_END("limitint::operator -=", "");
00433     }
00434 
00435 
00436     template <class B> limitint<B> & limitint<B>::operator *= (const limitint & arg)
00437     {
00438         E_BEGIN;
00439         static const B max_power = bytesize*8 - 1;
00440 
00441         B total = int_tools_higher_power_of_2(field) + int_tools_higher_power_of_2(arg.field) + 1; // for an explaination about "+2" see NOTES
00442         if(total > max_power) // this is a bit too much restrictive, but unless remaking bit by bit, the operation,
00443                 // I don't see how to simply (and fast) know the result has not overflowed.
00444                 // of course, it would be fast and easy to access the CPU flag register to check for overflow,
00445                 // but that would not be portable, and unfortunately I haven't found any standart C++ expression that
00446                 // could transparently access to it.
00447             throw Elimitint();
00448 
00449         total = field*arg.field;
00450         if(field != 0 && arg.field != 0)
00451             if(total < field || total < arg.field)
00452                 throw Elimitint();
00453         field = total;
00454         return *this;
00455         E_END("limitint::operator *=", "");
00456     }
00457 
00458     template <class B> template<class T> limitint<B> limitint<B>::power(const T & exponent) const
00459     {
00460         limitint ret = 1;
00461         for(T count = 0; count < exponent; ++count)
00462             ret *= *this;
00463 
00464         return ret;
00465     }
00466 
00467     template <class B> limitint<B> & limitint<B>::operator /= (const limitint & arg)
00468     {
00469         E_BEGIN;
00470         if(arg == 0)
00471             throw Einfinint("limitint.cpp : operator /=", gettext("Division by zero"));
00472 
00473         field /= arg.field;
00474         return *this;
00475         E_END("limitint::operator /=", "");
00476     }
00477 
00478     template <class B> limitint<B> & limitint<B>::operator %= (const limitint & arg)
00479     {
00480         E_BEGIN;
00481         if(arg == 0)
00482             throw Einfinint("limitint.cpp : operator %=", gettext("Division by zero"));
00483 
00484         field %= arg.field;
00485         return *this;
00486         E_END("limitint::operator /=", "");
00487     }
00488 
00489     template <class B> limitint<B> & limitint<B>::operator >>= (U_32 bit)
00490     {
00491         E_BEGIN;
00492         if(bit >= sizeof_field)
00493             field = 0;
00494         else
00495             field >>= bit;
00496         return *this;
00497         E_END("limitint::operator >>=", "U_32");
00498     }
00499 
00500     template <class B> limitint<B> & limitint<B>::operator >>= (limitint bit)
00501     {
00502         E_BEGIN;
00503         field >>= bit.field;
00504         return *this;
00505         E_END("limitint::operator >>=", "limitint");
00506     }
00507 
00508     template <class B> limitint<B> & limitint<B>::operator <<= (U_32 bit)
00509     {
00510         E_BEGIN;
00511         if(bit + int_tools_higher_power_of_2(field) >= bytesize*8)
00512             throw Elimitint();
00513         field <<= bit;
00514         return *this;
00515         E_END("limitint::operator <<=", "U_32");
00516     }
00517 
00518     template <class B> limitint<B> & limitint<B>::operator <<= (limitint bit)
00519     {
00520         E_BEGIN;
00521         if(bit.field + int_tools_higher_power_of_2(field) >= bytesize*8)
00522             throw Elimitint();
00523         field <<= bit.field;
00524         return *this;
00525         E_END("limitint::operator <<=", "limitint");
00526     }
00527 
00528     template <class B> limitint<B> & limitint<B>::operator &= (const limitint & arg)
00529     {
00530         E_BEGIN;
00531         field &= arg.field;
00532         return *this;
00533         E_END("limitint::operator &=", "");
00534     }
00535 
00536     template <class B> limitint<B> & limitint<B>::operator |= (const limitint & arg)
00537     {
00538         E_BEGIN;
00539         field |= arg.field;
00540         return *this;
00541         E_END("limitint::operator |=", "");
00542     }
00543 
00544     template <class B> limitint<B> & limitint<B>::operator ^= (const limitint & arg)
00545     {
00546         E_BEGIN;
00547         field ^= arg.field;
00548         return *this;
00549         E_END("limitint::operator ^=", "");
00550     }
00551 
00552     template <class B> U_32 limitint<B>::operator % (U_32 arg) const
00553     {
00554         E_BEGIN;
00555         return U_32(field % arg);
00556         E_END("limitint::modulo", "");
00557     }
00558 
00559     template <class B> template <class T> void limitint<B>::limitint_from(T a)
00560     {
00561         E_BEGIN;
00562         if(sizeof(a) <= bytesize || a <= (T)(max_value))
00563             field = B(a);
00564         else
00565             throw Elimitint();
00566         E_END("limitint::limitint_from", "");
00567     }
00568 
00569     template <class B> template <class T> void limitint<B>::limitint_unstack_to(T &a)
00570     {
00571         E_BEGIN;
00572             // T is supposed to be an unsigned "integer"
00573             // (ie.: sizeof returns the width of the storage bit field  and no sign bit is present)
00574             // Note : static here avoids the recalculation of max_T at each call
00575         static const T max_T = ~T(0) > 0 ? ~T(0) : ~int_tools_rotate_right_one_bit(T(1));
00576         T step = max_T - a;
00577 
00578         if(field < (B)(step) && (T)(field) < step)
00579         {
00580             a += field;
00581             field = 0;
00582         }
00583         else
00584         {
00585             field -= step;
00586             a = max_T;
00587         }
00588 
00589         E_END("limitint::limitint_unstack_to", "");
00590     }
00591 
00592     template <class B> limitint<B> limitint<B>::get_storage_size() const
00593     {
00594         B tmp = field;
00595         B ret = 0;
00596 
00597         while(tmp != 0)
00598         {
00599             tmp >>= 8;
00600             ret++;
00601         }
00602 
00603         return limitint<B>(ret);
00604     }
00605 
00606     template <class B> unsigned char limitint<B>::operator [] (const limitint & position) const
00607     {
00608         B tmp = field;
00609         B index = position.field; // C++ has only class protection, not object protection
00610 
00611         while(index > 0)
00612         {
00613             tmp >>= 8;
00614             index--;
00615         }
00616 
00617         return (unsigned char)(tmp & 0xFF);
00618     }
00619 
00620     template <class B> void limitint<B>::setup_endian()
00621     {
00622         E_BEGIN;
00623         U_16 u = 1;
00624         unsigned char *ptr = (unsigned char *)(&u);
00625 
00626         if(ptr[0] == 1)
00627             used_endian = big_endian;
00628         else
00629             used_endian = little_endian;
00630         E_END("limitint::setup_endian", "");
00631     }
00632 
00633 
00634     template <class B> bool limitint<B>::is_system_big_endian()
00635     {
00636         if(used_endian == not_initialized)
00637             setup_endian();
00638 
00639         switch(used_endian)
00640         {
00641         case big_endian:
00642             return true;
00643         case little_endian:
00644             return false;
00645         case not_initialized:
00646             throw SRC_BUG;
00647         default:
00648             throw SRC_BUG;
00649         }
00650     }
00651 
00652 
00656 
00657     template <class B> limitint<B> operator + (const limitint<B> & a, const limitint<B> & b)
00658     {
00659         E_BEGIN;
00660         limitint<B> ret = a;
00661         ret += b;
00662 
00663         return ret;
00664         E_END("operator +", "limitint");
00665     }
00666 
00667     template <class B> limitint<B> operator - (const limitint<B> & a, const limitint<B> & b)
00668     {
00669         E_BEGIN;
00670         limitint<B> ret = a;
00671         ret -= b;
00672 
00673         return ret;
00674         E_END("operator -", "limitint");
00675     }
00676 
00677     template <class B> limitint<B> operator * (const limitint<B> & a, const limitint<B> & b)
00678     {
00679         E_BEGIN;
00680         limitint<B> ret = a;
00681         ret *= b;
00682 
00683         return ret;
00684         E_END("operator *", "limitint");
00685     }
00686 
00687     template <class B> limitint<B> operator / (const limitint<B> & a, const limitint<B> & b)
00688     {
00689         E_BEGIN;
00690         limitint<B> ret = a;
00691         ret /= b;
00692 
00693         return ret;
00694         E_END("operator / ", "limitint");
00695     }
00696 
00697     template <class B> limitint<B> operator % (const limitint<B> & a, const limitint<B> & b)
00698     {
00699         E_BEGIN;
00700         limitint<B> ret = a;
00701         ret %= b;
00702 
00703         return ret;
00704         E_END("operator %", "limitint");
00705     }
00706 
00707     template <class B> limitint<B> operator >> (const limitint<B> & a, U_32 bit)
00708     {
00709         E_BEGIN;
00710         limitint<B> ret = a;
00711         ret >>= bit;
00712         return ret;
00713         E_END("operator >>", "limitint, U_32");
00714     }
00715 
00716     template <class B> limitint<B> operator >> (const limitint<B> & a, const limitint<B> & bit)
00717     {
00718         E_BEGIN;
00719         limitint<B> ret = a;
00720         ret >>= bit;
00721         return ret;
00722         E_END("operator >>", "limitint");
00723     }
00724 
00725     template <class B> limitint<B> operator << (const limitint<B> & a, U_32 bit)
00726     {
00727         E_BEGIN;
00728         limitint<B> ret = a;
00729         ret <<= bit;
00730         return ret;
00731         E_END("operator <<", "limitint, U_32");
00732     }
00733 
00734     template <class B> limitint<B> operator << (const limitint<B> & a, const limitint<B> & bit)
00735     {
00736         E_BEGIN;
00737         limitint<B> ret = a;
00738         ret <<= bit;
00739         return ret;
00740         E_END("operator <<", "limitint");
00741     }
00742 
00743     template <class B> limitint<B> operator & (const limitint<B> & a, U_32 bit)
00744     {
00745         E_BEGIN;
00746         limitint<B> ret = a;
00747         ret &= bit;
00748         return ret;
00749         E_END("operator &", "limitint");
00750     }
00751 
00752     template <class B> limitint<B> operator & (const limitint<B> & a, const limitint<B> & bit)
00753     {
00754         E_BEGIN;
00755         limitint<B> ret = a;
00756         ret &= bit;
00757         return ret;
00758         E_END("operator &", "limitint");
00759     }
00760 
00761     template <class B> limitint<B> operator | (const limitint<B> & a, U_32 bit)
00762     {
00763         E_BEGIN;
00764         limitint<B> ret = a;
00765         ret |= bit;
00766         return ret;
00767         E_END("operator |", "U_32");
00768     }
00769 
00770     template <class B> limitint<B> operator | (const limitint<B> & a, const limitint<B> & bit)
00771     {
00772         E_BEGIN;
00773         limitint<B> ret = a;
00774         ret |= bit;
00775         return ret;
00776         E_END("operator |", "limitint");
00777     }
00778 
00779     template <class B> limitint<B> operator ^ (const limitint<B> & a, U_32 bit)
00780     {
00781         E_BEGIN;
00782         limitint<B> ret = a;
00783         ret ^= bit;
00784         return ret;
00785         E_END("operator ^", "U_32");
00786     }
00787 
00788     template <class B> limitint<B> operator ^ (const limitint<B> & a, const limitint<B> & bit)
00789     {
00790         E_BEGIN;
00791         limitint<B> ret = a;
00792         ret ^= bit;
00793         return ret;
00794         E_END("operator ^", "limitint");
00795     }
00796 
00797 
00798 } // end of namespace
00799 
00800 #endif
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Defines