Disk ARchive 2.3.10
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.4 2009/04/07 08:45:29 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 #ifdef LIBDAR_SPECIAL_ALLOC
00147         USE_SPECIAL_ALLOC(limitint);
00148 #endif
00149 
00150         B debug_get_max() const { return max_value; };
00151         B debug_get_bytesize() const { return bytesize; };
00152 
00153     private :
00154         static const int TG = 4;
00155         static const U_32 sizeof_field = sizeof(B);
00156 
00157         enum endian { big_endian, little_endian, not_initialized };
00158         typedef unsigned char group[TG];
00159 
00160         B field;
00161 
00162         void build_from_file(generic_file & x);
00163         template <class T> void limitint_from(T a);
00164         template <class T> void limitint_unstack_to(T &a);
00165 
00167             // static statments
00168             //
00169         static endian used_endian;
00170         static const U_I bytesize = sizeof(B);
00171         static const B max_value = ~B(0) > 0 ? ~B(0) : ~(B(1) << (bytesize*8 - 1));
00172         static void setup_endian();
00173     };
00174 
00175     template <class B> limitint<B> operator + (const limitint<B> &, const limitint<B> &);
00176     template <class B> inline limitint<B> operator + (const limitint<B> & a, U_I b)
00177     { return a + limitint<B>(b); }
00178     template <class B> limitint<B> operator - (const limitint<B> &, const limitint<B> &);
00179     template <class B> inline limitint<B> operator - (const limitint<B> & a, U_I b)
00180     { return a - limitint<B>(b); }
00181     template <class B> limitint<B> operator * (const limitint<B> &, const limitint<B> &);
00182     template <class B> inline limitint<B> operator * (const limitint<B> & a, U_I b)
00183     { return a * limitint<B>(b); }
00184     template <class B> limitint<B> operator / (const limitint<B> &, const limitint<B> &);
00185     template <class B> limitint<B> operator / (const limitint<B> & a, U_I b)
00186     { return a / limitint<B>(b); }
00187     template <class B> limitint<B> operator % (const limitint<B> &, const limitint<B> &);
00188     template <class B> limitint<B> operator >> (const limitint<B> & a, U_32 bit);
00189     template <class B> limitint<B> operator >> (const limitint<B> & a, const limitint<B> & bit);
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 
00199     template <class T> inline void euclide(T a, T b, T & q, T &r)
00200     {
00201         E_BEGIN;
00202         q = a/b; r = a%b;
00203         E_END("euclide", "");
00204     }
00205 
00206     template <class B> inline void euclide(limitint<B> a, U_I b, limitint<B> & q, limitint<B> &r)
00207     {
00208         euclide(a, limitint<B>(b), q, r);
00209     }
00210 
00211 #ifndef INFININT_BASE_TYPE
00212 #error INFININT_BASE_TYPE not defined cannot instantiate template
00213 #else
00214     typedef limitint<INFININT_BASE_TYPE> infinint;
00215 #endif
00216 } // end of namespace
00220 
00221 #include "generic_file.hpp"
00222 #include "user_interaction.hpp"
00223 
00224 namespace libdar
00225 {
00226 
00227     template <class B> typename limitint<B>::endian limitint<B>::used_endian = not_initialized;
00228 
00229     template <class B> limitint<B>::limitint(user_interaction & dialog, S_I *fd, generic_file *x)
00230     {
00231         if(fd != NULL && x != NULL)
00232             throw Erange("limitint::limitint(file, file)", "Both arguments are not NULL, please choose one or the other, not both"); // message not translated, expected
00233         if(fd != NULL)
00234         {
00235             fichier f = fichier(dialog, dup(*fd));
00236             build_from_file(f);
00237         }
00238         else
00239             if(x != NULL)
00240                 build_from_file(*x);
00241             else
00242                 throw Erange("limitint::limitint(file, file)", "Cannot read from file, both arguments are NULL"); // message not translated, expected
00243     }
00244 
00245     template <class B> void limitint<B>::dump(user_interaction & dialog, S_I fd) const
00246     {
00247         fichier f = fichier(dialog, dup(fd));
00248         dump(f);
00249     }
00250 
00251     template <class B> void limitint<B>::build_from_file(generic_file & x)
00252     {
00253         E_BEGIN;
00254         unsigned char a;
00255         bool fin = false;
00256         limitint<B> skip = 0;
00257         char *ptr = (char *)&field;
00258         S_I lu;
00259         int_tools_bitfield bf;
00260 
00261         while(!fin)
00262         {
00263             lu = x.read((char *)&a, 1);
00264 
00265             if(lu <= 0)
00266                 throw Erange("limitint::build_from_file(generic_file)", gettext("Reached end of file before all data could be read"));
00267 
00268             if(a == 0)
00269                 ++skip;
00270             else // end of size field
00271             {
00272                     // computing the size to read
00273                 U_I pos = 0;
00274 
00275                 int_tools_expand_byte(a, bf);
00276                 for(S_I i = 0; i < 8; ++i)
00277                     pos += bf[i];
00278                 if(pos != 1)
00279                     throw Erange("limitint::build_from_file(generic_file)", gettext("Badly formed infinint or not supported format")); // more than 1 bit is set to 1
00280 
00281                 pos = 0;
00282                 while(bf[pos] == 0)
00283                     ++pos;
00284                 pos += 1; // bf starts at zero, but bit zero means 1 TG of length
00285 
00286                 skip *= 8;
00287                 skip += pos;
00288                 skip *= TG;
00289 
00290                 if(skip.field > bytesize)
00291                     throw Elimitint();
00292 
00293                 field = 0; // important to also clear "unread" bytes by the following call
00294                 lu = x.read(ptr, skip.field);
00295 
00296                 if(used_endian == not_initialized)
00297                     setup_endian();
00298                 if(used_endian == big_endian)
00299                     int_tools_swap_bytes((unsigned char *)ptr, skip.field);
00300                 else
00301                     field >>= (bytesize - skip.field)*8;
00302                 fin = true;
00303             }
00304         }
00305         E_END("limitint::read_from_file", "generic_file");
00306     }
00307 
00308 
00309     template <class B> void limitint<B>::dump(generic_file & x) const
00310     {
00311         E_BEGIN;
00312         B width = bytesize;
00313         B pos;
00314         unsigned char last_width;
00315         B justification;
00316         S_I direction = +1;
00317         unsigned char *ptr, *fin;
00318 
00319 
00320         if(used_endian == not_initialized)
00321             setup_endian();
00322 
00323         if(used_endian == big_endian)
00324         {
00325             direction = -1;
00326             ptr = (unsigned char *)(&field) + (bytesize - 1);
00327             fin = (unsigned char *)(&field) - 1;
00328         }
00329         else
00330         {
00331             direction = +1;
00332             ptr = (unsigned char *)(&field);
00333             fin = (unsigned char *)(&field) + bytesize;
00334         }
00335 
00336         while(ptr != fin && *ptr == 0)
00337         {
00338             ptr += direction;
00339             --width;
00340         }
00341         if(width == 0)
00342             width = 1; // minimum size of information is 1 byte
00343 
00344             // "width" is the informational field size in byte
00345             // TG is the width in TG, thus the number of bit that must have
00346             // the preamble
00347         euclide(width, (const B)(TG), width, justification);
00348         if(justification != 0)
00349                 // in case we need to add some bytes to have a width multiple of TG
00350             ++width;  // we need then one more group to have a width multiple of TG
00351 
00352         euclide(width, (const B)(8), width, pos);
00353         if(pos == 0)
00354         {
00355             width--; // division is exact, only last bit of the preambule is set
00356             last_width = 0x80 >> 7;
00357                 // as we add the last byte separately width gets shorter by 1 byte
00358         }
00359         else // division non exact, the last_width (last byte), make the rounding
00360         {
00361             U_16 pos_s = (U_16)(0xFFFF & pos);
00362             last_width = 0x80 >> (pos_s - 1);
00363         }
00364 
00365             // now we write the preamble except the last byte. All these are zeros.
00366 
00367         unsigned char u = 0x00;
00368 
00369         while(width-- > 0)
00370             if(x.write((char *)(&u), 1) < 1)
00371                 throw Erange("limitint::dump(generic_file)", gettext("Cannot write data to file"));
00372 
00373 
00374             // now we write the last byte of the preambule, which as only one bit set
00375 
00376         if(x.write((char *)&last_width, 1) < 1)
00377             throw Erange("limitint::dump(generic_file)", gettext("Cannot write data to file"));
00378 
00379             // we need now to write some justification byte to have an informational field multiple of TG
00380 
00381         if(justification != 0)
00382         {
00383             justification = TG - justification;
00384             while(justification-- > 0)
00385                 if(x.write((char *)(&u), 1) < 1)
00386                     throw Erange("limitint::dump(generic_file)", gettext("Cannot write data to file"));
00387         }
00388 
00389             // now we continue dumping the informational bytes:
00390         if(ptr == fin) // field is equal to zero
00391         {
00392             if(x.write((char *)(&u), 1) < 1)
00393                 throw Erange("limitint::dump(generic_file)", gettext("Cannot write data to file"));
00394         }
00395         else // we have some bytes to write down
00396             while(ptr != fin)
00397             {
00398                 if(x.write((char *)ptr, 1) < 1)
00399                     throw Erange("limitint::dump(generic_file)", gettext("Cannot write data to file"));
00400                 else
00401                     ptr += direction;
00402             }
00403 
00404         E_END("limitint::dump", "generic_file");
00405     }
00406 
00407     template<class B> limitint<B> & limitint<B>::operator += (const limitint & arg)
00408     {
00409         E_BEGIN;
00410         B res = field + arg.field;
00411         if(res < field || res < arg.field)
00412             throw Elimitint();
00413         else
00414             field = res;
00415 
00416         return *this;
00417         E_END("limitint::operator +=", "");
00418     }
00419 
00420     template <class B> limitint<B> & limitint<B>::operator -= (const limitint & arg)
00421     {
00422         E_BEGIN;
00423         if(field < arg.field)
00424             throw Erange("limitint::operator", gettext("Subtracting a infinint greater than the first, infinint cannot be negative"));
00425 
00426             // now processing the operation
00427 
00428         field -= arg.field;
00429         return *this;
00430         E_END("limitint::operator -=", "");
00431     }
00432 
00433 
00434     template <class B> limitint<B> & limitint<B>::operator *= (const limitint & arg)
00435     {
00436         E_BEGIN;
00437         static const B max_power = bytesize*8 - 1;
00438 
00439         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
00440         if(total > max_power) // this is a bit too much restrictive, but unless remaking bit by bit, the operation,
00441                 // I don't see how to simply (and fast) know the result has not overflowed.
00442                 // of course, it would be fast and easy to access the CPU flag register to check for overflow,
00443                 // but that would not be portable, and unfortunately I haven't found any standart C++ expression that
00444                 // could transparently access to it.
00445             throw Elimitint();
00446 
00447         total = field*arg.field;
00448         if(field != 0 && arg.field != 0)
00449             if(total < field || total < arg.field)
00450                 throw Elimitint();
00451         field = total;
00452         return *this;
00453         E_END("limitint::operator *=", "");
00454     }
00455 
00456     template <class B> template<class T> limitint<B> limitint<B>::power(const T & exponent) const
00457     {
00458         limitint ret = 1;
00459         for(T count = 0; count < exponent; ++count)
00460             ret *= *this;
00461 
00462         return ret;
00463     }
00464 
00465     template <class B> limitint<B> & limitint<B>::operator /= (const limitint & arg)
00466     {
00467         E_BEGIN;
00468         if(arg == 0)
00469             throw Einfinint("limitint.cpp : operator /=", gettext("Division by zero"));
00470 
00471         field /= arg.field;
00472         return *this;
00473         E_END("limitint::operator /=", "");
00474     }
00475 
00476     template <class B> limitint<B> & limitint<B>::operator %= (const limitint & arg)
00477     {
00478         E_BEGIN;
00479         if(arg == 0)
00480             throw Einfinint("limitint.cpp : operator %=", gettext("Division by zero"));
00481 
00482         field %= arg.field;
00483         return *this;
00484         E_END("limitint::operator /=", "");
00485     }
00486 
00487     template <class B> limitint<B> & limitint<B>::operator >>= (U_32 bit)
00488     {
00489         E_BEGIN;
00490         if(bit >= sizeof_field)
00491             field = 0;
00492         else
00493             field >>= bit;
00494         return *this;
00495         E_END("limitint::operator >>=", "U_32");
00496     }
00497 
00498     template <class B> limitint<B> & limitint<B>::operator >>= (limitint bit)
00499     {
00500         E_BEGIN;
00501         field >>= bit.field;
00502         return *this;
00503         E_END("limitint::operator >>=", "limitint");
00504     }
00505 
00506     template <class B> limitint<B> & limitint<B>::operator <<= (U_32 bit)
00507     {
00508         E_BEGIN;
00509         if(bit + int_tools_higher_power_of_2(field) >= bytesize*8)
00510             throw Elimitint();
00511         field <<= bit;
00512         return *this;
00513         E_END("limitint::operator <<=", "U_32");
00514     }
00515 
00516     template <class B> limitint<B> & limitint<B>::operator <<= (limitint bit)
00517     {
00518         E_BEGIN;
00519         if(bit.field + int_tools_higher_power_of_2(field) >= bytesize*8)
00520             throw Elimitint();
00521         field <<= bit.field;
00522         return *this;
00523         E_END("limitint::operator <<=", "limitint");
00524     }
00525 
00526     template <class B> limitint<B> & limitint<B>::operator &= (const limitint & arg)
00527     {
00528         E_BEGIN;
00529         field &= arg.field;
00530         return *this;
00531         E_END("limitint::operator &=", "");
00532     }
00533 
00534     template <class B> limitint<B> & limitint<B>::operator |= (const limitint & arg)
00535     {
00536         E_BEGIN;
00537         field |= arg.field;
00538         return *this;
00539         E_END("limitint::operator |=", "");
00540     }
00541 
00542     template <class B> limitint<B> & limitint<B>::operator ^= (const limitint & arg)
00543     {
00544         E_BEGIN;
00545         field ^= arg.field;
00546         return *this;
00547         E_END("limitint::operator ^=", "");
00548     }
00549 
00550     template <class B> U_32 limitint<B>::operator % (U_32 arg) const
00551     {
00552         E_BEGIN;
00553         return U_32(field % arg);
00554         E_END("limitint::modulo", "");
00555     }
00556 
00557     template <class B> template <class T> void limitint<B>::limitint_from(T a)
00558     {
00559         E_BEGIN;
00560         if(sizeof(a) <= bytesize || a <= (T)(max_value))
00561             field = B(a);
00562         else
00563             throw Elimitint();
00564         E_END("limitint::limitint_from", "");
00565     }
00566 
00567     template <class B> template <class T> void limitint<B>::limitint_unstack_to(T &a)
00568     {
00569         E_BEGIN;
00570             // T is supposed to be an unsigned "integer"
00571             // (ie.: sizeof returns the width of the storage bit field  and no sign bit is present)
00572             // Note : static here avoids the recalculation of max_T at each call
00573         static const T max_T = ~T(0) > 0 ? ~T(0) : ~int_tools_rotate_right_one_bit(T(1));
00574         T step = max_T - a;
00575 
00576         if(field < (B)(step) && (T)(field) < step)
00577         {
00578             a += field;
00579             field = 0;
00580         }
00581         else
00582         {
00583             field -= step;
00584             a = max_T;
00585         }
00586 
00587         E_END("limitint::limitint_unstack_to", "");
00588     }
00589 
00590     template <class B> limitint<B> limitint<B>::get_storage_size() const
00591     {
00592         B tmp = field;
00593         B ret = 0;
00594 
00595         while(tmp != 0)
00596         {
00597             tmp >>= 8;
00598             ret++;
00599         }
00600 
00601         return limitint<B>(ret);
00602     }
00603 
00604     template <class B> unsigned char limitint<B>::operator [] (const limitint & position) const
00605     {
00606         B tmp = field;
00607         B index = position.field; // C++ has only class protection, not object protection
00608 
00609         while(index > 0)
00610         {
00611             tmp >>= 8;
00612             index--;
00613         }
00614 
00615         return (unsigned char)(tmp & 0xFF);
00616     }
00617 
00618     template <class B> void limitint<B>::setup_endian()
00619     {
00620         E_BEGIN;
00621         U_16 u = 1;
00622         unsigned char *ptr = (unsigned char *)(&u);
00623 
00624         if(ptr[0] == 1)
00625             used_endian = big_endian;
00626         else
00627             used_endian = little_endian;
00628         E_END("limitint::setup_endian", "");
00629     }
00630 
00631 
00632 
00633 
00637 
00638     template <class B> limitint<B> operator + (const limitint<B> & a, const limitint<B> & b)
00639     {
00640         E_BEGIN;
00641         limitint<B> ret = a;
00642         ret += b;
00643 
00644         return ret;
00645         E_END("operator +", "limitint");
00646     }
00647 
00648     template <class B> limitint<B> operator - (const limitint<B> & a, const limitint<B> & b)
00649     {
00650         E_BEGIN;
00651         limitint<B> ret = a;
00652         ret -= b;
00653 
00654         return ret;
00655         E_END("operator -", "limitint");
00656     }
00657 
00658     template <class B> limitint<B> operator * (const limitint<B> & a, const limitint<B> & b)
00659     {
00660         E_BEGIN;
00661         limitint<B> ret = a;
00662         ret *= b;
00663 
00664         return ret;
00665         E_END("operator *", "limitint");
00666     }
00667 
00668     template <class B> limitint<B> operator / (const limitint<B> & a, const limitint<B> & b)
00669     {
00670         E_BEGIN;
00671         limitint<B> ret = a;
00672         ret /= b;
00673 
00674         return ret;
00675         E_END("operator / ", "limitint");
00676     }
00677 
00678     template <class B> limitint<B> operator % (const limitint<B> & a, const limitint<B> & b)
00679     {
00680         E_BEGIN;
00681         limitint<B> ret = a;
00682         ret %= b;
00683 
00684         return ret;
00685         E_END("operator %", "limitint");
00686     }
00687 
00688     template <class B> limitint<B> operator >> (const limitint<B> & a, U_32 bit)
00689     {
00690         E_BEGIN;
00691         limitint<B> ret = a;
00692         ret >>= bit;
00693         return ret;
00694         E_END("operator >>", "limitint, U_32");
00695     }
00696 
00697     template <class B> limitint<B> operator >> (const limitint<B> & a, const limitint<B> & bit)
00698     {
00699         E_BEGIN;
00700         limitint<B> ret = a;
00701         ret >>= bit;
00702         return ret;
00703         E_END("operator >>", "limitint");
00704     }
00705 
00706     template <class B> limitint<B> operator << (const limitint<B> & a, U_32 bit)
00707     {
00708         E_BEGIN;
00709         limitint<B> ret = a;
00710         ret <<= bit;
00711         return ret;
00712         E_END("operator <<", "limitint, U_32");
00713     }
00714 
00715     template <class B> limitint<B> operator << (const limitint<B> & a, const limitint<B> & bit)
00716     {
00717         E_BEGIN;
00718         limitint<B> ret = a;
00719         ret <<= bit;
00720         return ret;
00721         E_END("operator <<", "limitint");
00722     }
00723 
00724     template <class B> limitint<B> operator & (const limitint<B> & a, U_32 bit)
00725     {
00726         E_BEGIN;
00727         limitint<B> ret = a;
00728         ret &= bit;
00729         return ret;
00730         E_END("operator &", "limitint");
00731     }
00732 
00733     template <class B> limitint<B> operator & (const limitint<B> & a, const limitint<B> & bit)
00734     {
00735         E_BEGIN;
00736         limitint<B> ret = a;
00737         ret &= bit;
00738         return ret;
00739         E_END("operator &", "limitint");
00740     }
00741 
00742     template <class B> limitint<B> operator | (const limitint<B> & a, U_32 bit)
00743     {
00744         E_BEGIN;
00745         limitint<B> ret = a;
00746         ret |= bit;
00747         return ret;
00748         E_END("operator |", "U_32");
00749     }
00750 
00751     template <class B> limitint<B> operator | (const limitint<B> & a, const limitint<B> & bit)
00752     {
00753         E_BEGIN;
00754         limitint<B> ret = a;
00755         ret |= bit;
00756         return ret;
00757         E_END("operator |", "limitint");
00758     }
00759 
00760     template <class B> limitint<B> operator ^ (const limitint<B> & a, U_32 bit)
00761     {
00762         E_BEGIN;
00763         limitint<B> ret = a;
00764         ret ^= bit;
00765         return ret;
00766         E_END("operator ^", "U_32");
00767     }
00768 
00769     template <class B> limitint<B> operator ^ (const limitint<B> & a, const limitint<B> & bit)
00770     {
00771         E_BEGIN;
00772         limitint<B> ret = a;
00773         ret ^= bit;
00774         return ret;
00775         E_END("operator ^", "limitint");
00776     }
00777 
00778 
00779 } // end of namespace
00780 
00781 #endif
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Defines