Truncate.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //=============================================================================
00004 /**
00005  * @file Truncate.h
00006  *
00007  * $Id: Truncate.h 81462 2008-04-28 11:39:40Z johnnyw $
00008  *
00009  * @author Steve Huston  <shuston@riverace.com>
00010  * @author Ossama Othman <ossama_othman@symantec.com>
00011  * @author Russell Mora  <russell_mora@symantec.com>
00012  */
00013 //=============================================================================
00014 
00015 #ifndef ACE_TRUNCATE_H
00016 #define ACE_TRUNCATE_H
00017 
00018 #include /**/ "ace/pre.h"
00019 
00020 #include "ace/config-all.h"
00021 
00022 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00023 # pragma once
00024 #endif /* ACE_LACKS_PRAGMA_ONCE */
00025 
00026 #include "ace/Global_Macros.h"
00027 #include "ace/If_Then_Else.h"
00028 #include "ace/Numeric_Limits.h"
00029 
00030 #if defined (ACE_LACKS_LONGLONG_T) \
00031     || defined (__BORLANDC__) && __BORLANDC__ < 0x590
00032 # include "ace/Basic_Types.h"
00033 #endif  /* ACE_LACKS_LONGLONG_T || __BORLANDC__ < 0x590 */
00034 
00035 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00036 
00037 namespace ACE_Utils
00038 {
00039 
00040 #if !defined (__BORLANDC__) || __BORLANDC__ >= 0x590
00041 
00042   template<typename T> struct Sign_Check;
00043 
00044   // Specialize the unsigned signed cases.
00045   template<> struct Sign_Check<unsigned char>  { ACE_STATIC_CONSTANT (bool, is_signed = 0); };
00046   template<> struct Sign_Check<unsigned short> { ACE_STATIC_CONSTANT (bool, is_signed = 0); };
00047   template<> struct Sign_Check<unsigned int>   { ACE_STATIC_CONSTANT (bool, is_signed = 0); };
00048   template<> struct Sign_Check<unsigned long>  { ACE_STATIC_CONSTANT (bool, is_signed = 0); };
00049 #if !(defined(ACE_LACKS_LONGLONG_T) || defined(ACE_LACKS_UNSIGNEDLONGLONG_T))
00050 # ifdef __GNUC__
00051   // Silence g++ "-pedantic" warnings regarding use of "long long"
00052   // type.
00053   __extension__
00054 # endif  /* __GNUC__ */
00055   template<> struct Sign_Check<unsigned long long> { ACE_STATIC_CONSTANT (bool, is_signed = 0); };
00056 #else
00057   template<> struct Sign_Check<ACE_U_LongLong> { ACE_STATIC_CONSTANT (bool, is_signed = 0); };
00058 #endif  /* !ACE_LACKS_LONGLONG_T */
00059 
00060   // Specialize the signed cases.
00061   template<> struct Sign_Check<signed char>  { ACE_STATIC_CONSTANT (bool, is_signed = 1); };
00062   template<> struct Sign_Check<signed short> { ACE_STATIC_CONSTANT (bool, is_signed = 1); };
00063   template<> struct Sign_Check<signed int>   { ACE_STATIC_CONSTANT (bool, is_signed = 1); };
00064   template<> struct Sign_Check<signed long>  { ACE_STATIC_CONSTANT (bool, is_signed = 1); };
00065 #ifndef ACE_LACKS_LONGLONG_T
00066 # ifdef __GNUC__
00067   // Silence g++ "-pedantic" warnings regarding use of "long long"
00068   // type.
00069   __extension__
00070 # endif  /* __GNUC__ */
00071   template<> struct Sign_Check<signed long long> { ACE_STATIC_CONSTANT (bool, is_signed = 1); };
00072 #endif  /* !ACE_LACKS_LONGLONG_T */
00073 
00074   // -----------------------------------------------------
00075 
00076   /**
00077    * @struct To_Unsigned
00078    *
00079    * @brief Retrieve unsigned counterpart to given type or value.
00080    *
00081    * Retrieve unsigned counterpart to given type or value.
00082    */
00083   template<typename T> struct To_Unsigned;
00084 
00085   template<>
00086   struct To_Unsigned<unsigned char>
00087   {
00088     typedef unsigned char unsigned_type;
00089 
00090     unsigned_type operator() (unsigned_type x) { return x; }
00091   };
00092 
00093   template<>
00094   struct To_Unsigned<unsigned short>
00095   {
00096     typedef unsigned short unsigned_type;
00097 
00098     unsigned_type operator() (unsigned_type x) { return x; }
00099   };
00100 
00101   template<>
00102   struct To_Unsigned<unsigned int>
00103   {
00104     typedef unsigned int unsigned_type;
00105 
00106     unsigned_type operator() (unsigned_type x) { return x; }
00107   };
00108 
00109   template<>
00110   struct To_Unsigned<unsigned long>
00111   {
00112     typedef unsigned long unsigned_type;
00113 
00114     unsigned_type operator() (unsigned_type x) { return x; }
00115   };
00116 
00117 #if !(defined(ACE_LACKS_LONGLONG_T) || defined(ACE_LACKS_UNSIGNEDLONGLONG_T))
00118 # ifdef __GNUC__
00119   // Silence g++ "-pedantic" warnings regarding use of "long long"
00120   // type.
00121   __extension__
00122 # endif  /* __GNUC__ */
00123   template<>
00124   struct To_Unsigned<unsigned long long>
00125   {
00126     typedef unsigned long long unsigned_type;
00127 
00128     unsigned_type operator() (unsigned_type x) { return x; }
00129   };
00130 #else
00131   template<>
00132   struct To_Unsigned<ACE_U_LongLong>
00133   {
00134     typedef ACE_U_LongLong unsigned_type;
00135 
00136     unsigned_type operator() (unsigned_type x) { return x; }
00137   };
00138 #endif  /* !ACE_LACKS_LONGLONG_T */
00139 
00140   // ----------------
00141 
00142   template<>
00143   struct To_Unsigned<signed char>
00144   {
00145     typedef signed char   signed_type;
00146     typedef unsigned char unsigned_type;
00147 
00148     unsigned_type operator() (signed_type x)
00149     {
00150       return static_cast<unsigned_type> (x);
00151     }
00152   };
00153 
00154   template<>
00155   struct To_Unsigned<signed short>
00156   {
00157     typedef signed short   signed_type;
00158     typedef unsigned short unsigned_type;
00159 
00160     unsigned_type operator() (signed_type x)
00161     {
00162       return static_cast<unsigned_type> (x);
00163     }
00164   };
00165 
00166   template<>
00167   struct To_Unsigned<signed int>
00168   {
00169     typedef signed int   signed_type;
00170     typedef unsigned int unsigned_type;
00171 
00172     unsigned_type operator() (signed_type x)
00173     {
00174       return static_cast<unsigned_type> (x);
00175     }
00176   };
00177 
00178   template<>
00179   struct To_Unsigned<signed long>
00180   {
00181     typedef signed long   signed_type;
00182     typedef unsigned long unsigned_type;
00183 
00184     unsigned_type operator() (signed_type x)
00185     {
00186       return static_cast<unsigned_type> (x);
00187     }
00188   };
00189 
00190 #if !(defined(ACE_LACKS_LONGLONG_T) || defined(ACE_LACKS_UNSIGNEDLONGLONG_T))
00191 # ifdef __GNUC__
00192   // Silence g++ "-pedantic" warnings regarding use of "long long"
00193   // type.
00194   __extension__
00195 # endif  /* __GNUC__ */
00196   template<>
00197   struct To_Unsigned<signed long long>
00198   {
00199     typedef signed long long   signed_type;
00200     typedef unsigned long long unsigned_type;
00201 
00202     unsigned_type operator() (signed_type x)
00203     {
00204       return static_cast<unsigned_type> (x);
00205     }
00206   };
00207 #endif  /* !ACE_LACKS_LONGLONG_T */
00208 
00209   // -----------------------------------------------------
00210 
00211   /**
00212    * @struct Safe_Comparator
00213    *
00214    * @brief Conservative comparison of types that may not be safely
00215    *        promoted and/or converted to each other.
00216    *
00217    * The comparison operations provided by this structure perform
00218    * negative value checking when necessary to prevent wrap-around
00219    * when explicitly casting to an unsigned type.
00220    *
00221    * @internal This structure is not meant for general use.
00222    */
00223   template<typename LEFT,
00224            typename RIGHT,
00225            bool IS_LEFT_SIGNED,
00226            bool IS_RIGHT_SIGNED> struct Safe_Comparator;
00227 
00228   // LEFT: signed, RIGHT: unsigned
00229   template<typename LEFT, typename RIGHT>
00230   struct Safe_Comparator<LEFT, RIGHT, true, false>
00231   {
00232     static bool greater_than (LEFT lhs, RIGHT rhs)
00233     {
00234       // Prevent wrap-around when casting to unsigned.
00235       if (lhs < 0)
00236         return false;  // since rhs is always positive
00237       else
00238         {
00239           // Implicit promotion of unsigned LEFT and RIGHT types here.
00240           return To_Unsigned<LEFT>() (lhs) > rhs;
00241         }
00242     }
00243   };
00244 
00245   // LEFT: unsigned, RIGHT: signed
00246   template<typename LEFT, typename RIGHT>
00247   struct Safe_Comparator<LEFT, RIGHT, false, true>
00248   {
00249     static bool greater_than (LEFT lhs, RIGHT rhs)
00250     {
00251       // Prevent wrap-around when casting to unsigned.
00252       if (rhs < 0)
00253         return true;  // since lhs is always positive
00254       else
00255         {
00256           // Implicit promotion of unsigned LEFT and RIGHT types here.
00257           return lhs > To_Unsigned<RIGHT>() (rhs);
00258         }
00259     }
00260   };
00261 
00262   // LEFT: unsigned, RIGHT: unsigned
00263   template<typename LEFT, typename RIGHT>
00264   struct Safe_Comparator<LEFT, RIGHT, false, false>
00265   {
00266     static bool greater_than (LEFT lhs, RIGHT rhs)
00267     {
00268       // Implicit promotion of unsigned LEFT and RIGHT types here.
00269       return lhs > rhs;
00270     }
00271   };
00272 
00273   // LEFT: signed, RIGHT: signed
00274   template<typename LEFT, typename RIGHT>
00275   struct Safe_Comparator<LEFT, RIGHT, true, true>
00276   {
00277     static bool greater_than (LEFT lhs, RIGHT rhs)
00278     {
00279       // Implicit promotion of signed LEFT and RIGHT types here.
00280       return lhs > rhs;
00281     }
00282   };
00283 
00284   // -----------------------------------------------------
00285 
00286   /**
00287    * @struct Fast_Comparator
00288    *
00289    * @brief Quick comparison of types that can be safely promoted
00290    *        and/or converted to each other.
00291    *
00292    * The comparison operations provided by this structure perform no
00293    * negative value checking, meaning it is not applicable to all
00294    * types.  Check the value of the @c USABLE enumerator to determine
00295    * if it applies to the types in question.
00296    *
00297    * @internal This structure is not meant for general use.
00298    */
00299   template<typename LEFT, typename RIGHT>
00300   struct Fast_Comparator
00301   {
00302     ACE_STATIC_CONSTANT (
00303       bool,
00304       USE_LEFT  = ((sizeof (LEFT) > sizeof (RIGHT)
00305                     && (Sign_Check<LEFT>::is_signed == 1
00306                         || Sign_Check<RIGHT>::is_signed == 0))
00307 
00308                    // The following is basically the case where LEFT
00309                    // and RIGHT are the same integral type.
00310                    || (sizeof (LEFT) == sizeof (RIGHT)
00311                        // Can't portably do
00312                        // Sign_Check<LEFT>::is_signed ==
00313                        // Sign_Check<RIGHT>::is_signed,
00314                        // i.e. comparison of anonymous enumerations,
00315                        // without triggering a compiler diagnostic
00316                        // so expand the comparison.
00317                        && ((Sign_Check<LEFT>::is_signed == 1
00318                             && Sign_Check<RIGHT>::is_signed == 1)
00319                            || (Sign_Check<LEFT>::is_signed == 0
00320                                && Sign_Check<RIGHT>::is_signed == 0)))));
00321 
00322     ACE_STATIC_CONSTANT (
00323       bool,
00324       USE_RIGHT = (sizeof (RIGHT) > sizeof (LEFT)
00325                    && (Sign_Check<RIGHT>::is_signed == 1
00326                        || Sign_Check<LEFT>::is_signed == 0)));
00327 
00328     ACE_STATIC_CONSTANT (bool, USABLE = (USE_LEFT || USE_RIGHT));
00329 
00330     typedef typename ACE::If_Then_Else<
00331       USE_LEFT,
00332       LEFT,
00333       typename ACE::If_Then_Else<
00334         USE_RIGHT,
00335         RIGHT,
00336         void>::result_type>::result_type promote_type;
00337 
00338     static bool greater_than (LEFT lhs, RIGHT rhs)
00339     {
00340       // The explicit cast is assumed to change the type of rhs without
00341       // changing its value.
00342       return
00343         (static_cast<promote_type> (lhs) > static_cast<promote_type> (rhs));
00344     }
00345 
00346   };
00347 
00348   // -----------------------------------------------------
00349 
00350   /**
00351    * @struct Comparator
00352    *
00353    * @brief Structure that provides optimal comparison operation for
00354    *        given types.
00355    *
00356    * The comparison operations provided by this structure are chosen
00357    * at compile time based on the signs and sizes of types being
00358    * compared.
00359    * @par
00360    * Comparisons of values with the same sign or those with types that
00361    * can be promoted safely are done quickly, without any range
00362    * checking.
00363    * @par
00364    * Comparisons of values of different types that cannot be safely
00365    * promoted incur an additional check for a negative value to allow
00366    * the compiler to perform the appropriate implicit unsigned type
00367    * promotion.
00368    *
00369    * @note In general, the operations found in this structure should
00370    *       not be used to work around compiler diagnostics regarding
00371    *       comparison of signed and unsigned types.  Verify that your
00372    *       types are correct before relying on those operations.
00373    *
00374    * @internal This structure is not meant for general use.
00375    */
00376   template<typename LEFT, typename RIGHT>
00377   struct Comparator
00378   {
00379     typedef typename ACE::If_Then_Else<
00380       Fast_Comparator<LEFT, RIGHT>::USABLE,
00381       Fast_Comparator<LEFT, RIGHT>,
00382       Safe_Comparator<LEFT,
00383                       RIGHT,
00384                       Sign_Check<LEFT>::is_signed,
00385                       Sign_Check<RIGHT>::is_signed> >::result_type comp_type;
00386   };
00387 
00388   // -----------------------------------------------------
00389 
00390   /**
00391    * @struct Truncator
00392    *
00393    * @brief Truncate value of type @c FROM to value of type @c TO.
00394    *
00395    * Truncate a value of type @c FROM to value of type @c TO, if the
00396    * value is larger than the maximum of value of type @c TO.
00397    */
00398   template<typename FROM, typename TO>
00399   struct Truncator
00400   {
00401     ACE_STATIC_CONSTANT (
00402       bool,
00403       // max FROM always greater than max TO
00404       MAX_FROM_GT_MAX_TO = (sizeof(FROM) > sizeof (TO)
00405                             || (sizeof(FROM) == sizeof (TO)
00406                                 && Sign_Check<FROM>::is_signed == 0)));
00407 
00408     typedef typename ACE::If_Then_Else<
00409       MAX_FROM_GT_MAX_TO,
00410       FROM,
00411       TO>::result_type comp_to_type;
00412 
00413     // Take advantage of knowledge that we're casting a positive value
00414     // to a type large enough to hold it so that we can bypass
00415     // negative value checks at compile-time.  Otherwise fallback on
00416     // the safer comparison.
00417     typedef typename ACE::If_Then_Else<
00418       MAX_FROM_GT_MAX_TO,
00419       Fast_Comparator<FROM, comp_to_type>,
00420       typename Comparator<FROM, comp_to_type>::comp_type>::result_type comparator;
00421 
00422     /// Truncate a value of type @c FROM to value of type @c TO, if
00423     /// the value is larger than the maximum of value of type @c TO.
00424     TO operator() (FROM val)
00425     {
00426       return
00427         (comparator::greater_than (val, ACE_Numeric_Limits<TO>::max ())
00428          ? ACE_Numeric_Limits<TO>::max ()
00429          : static_cast<TO> (val));
00430     }
00431 
00432   };
00433 
00434   // Partial specialization for the case where the types are the same.
00435   // No truncation is necessary.
00436   template<typename T>
00437   struct Truncator<T, T>
00438   {
00439     T operator() (T val)
00440     {
00441       return val;
00442     }
00443   };
00444 
00445 
00446 #if defined (ACE_LACKS_LONGLONG_T) || defined (ACE_LACKS_UNSIGNEDLONGLONG_T)
00447   // Partial specialization for the case where we're casting from
00448   // ACE_U_LongLong to a smaller integer.  We assume that we're always
00449   // truncating from ACE_U_LongLong to a smaller type.  The partial
00450   // specialization above handles the case where both the FROM and TO
00451   // types are ACE_U_LongLong.
00452   template<typename TO>
00453   struct Truncator<ACE_U_LongLong, TO>
00454   {
00455     TO operator() (ACE_U_LongLong const & val)
00456     {
00457       // If val less than or equal to ACE_Numeric_Limits<TO>::max(),
00458       // val.lo() must be less than or equal to
00459       // ACE_Numeric_Limits<TO>::max (), as well.
00460       return
00461         (val > ACE_Numeric_Limits<TO>::max ()
00462          ? ACE_Numeric_Limits<TO>::max ()
00463          : static_cast<TO> (val.lo ()));
00464     }
00465   };
00466 #endif /* ACE_LACKS_LONGLONG_T || ACE_LACKS_UNSIGNEDLONGLONG_T */
00467 
00468   // -----------------------------------------------------
00469   /**
00470    * @struct Noop_Truncator
00471    *
00472    * @brief No-op truncation.
00473    *
00474    * This structure/functor performs no truncation since it assumes
00475    * that @c sizeof(FROM) @c < @c sizeof(TO), meaning that
00476    * @c numeric_limits<FROM>::max() @c < @c numeric_limits<TO>::max().
00477    */
00478   template<typename FROM, typename TO>
00479   struct Noop_Truncator
00480   {
00481     TO operator() (FROM val)
00482     {
00483       return static_cast<TO> (val);
00484     }
00485   };
00486   // -----------------------------------------------------
00487 
00488   /**
00489    * @class truncate_cast
00490    *
00491    * @brief Helper function to truncate an integral value to the
00492    *        maximum  value of the given type.
00493    *
00494    *        Very useful since ACE methods return @c int very often and
00495    *        the value's source is often a different-size integral
00496    *        type, such as @c size_t.  This function hides the
00497    *        truncation logic and resolves compiler diagnostics.
00498    *
00499    * @internal Internal use only.
00500    */
00501   template<typename TO, typename FROM>
00502   inline TO truncate_cast (FROM val)
00503   {
00504     // If the size of FROM is less than the size of TO, "val" will
00505     // never be greater than the maximum "TO" value, so there is no
00506     // need to attempt to truncate.
00507     typedef typename ACE::If_Then_Else<
00508       (sizeof (FROM) < sizeof (TO)),
00509       Noop_Truncator<FROM, TO>,
00510       Truncator<FROM, TO> >::result_type truncator;
00511 
00512     return truncator() (val);
00513   }
00514 
00515 #else
00516 
00517   // Borland can't handle the template meta-programming above so
00518   // provide explicit specializations for a few types.  More will be
00519   // added if necessary.
00520 
00521   /**
00522    * @deprecated Borland ACE_Utils::Truncator<> specializations should
00523    *             be removed.
00524    */
00525 
00526   template<typename FROM, typename TO> struct Truncator;
00527 
00528   //----------------------------------------------------------
00529   // sizeof(FROM) >  sizeof(TO)
00530   //----------------------------------------------------------
00531 
00532   template<>
00533   struct Truncator<ACE_INT32, ACE_INT8>
00534   {
00535     ACE_INT8 operator() (ACE_INT32 val)
00536     {
00537       return
00538         (val > ACE_Numeric_Limits<ACE_INT8>::max ()
00539          ? ACE_Numeric_Limits<ACE_INT8>::max ()
00540          : static_cast<ACE_INT8> (val));
00541     }
00542   };
00543 
00544   template<>
00545   struct Truncator<ACE_UINT32, ACE_UINT8>
00546   {
00547     ACE_UINT8 operator() (ACE_UINT32 val)
00548     {
00549       return
00550         (val > static_cast<ACE_UINT32> (ACE_Numeric_Limits<ACE_UINT8>::max ())
00551          ? ACE_Numeric_Limits<ACE_UINT8>::max ()
00552          : static_cast<ACE_UINT8> (val));
00553     }
00554   };
00555 
00556   template<>
00557   struct Truncator<ACE_INT32, ACE_UINT8>
00558   {
00559     ACE_UINT8 operator() (ACE_INT32 val)
00560     {
00561       return
00562         (val > static_cast<ACE_INT32> (ACE_Numeric_Limits<ACE_UINT8>::max ())
00563          ? ACE_Numeric_Limits<ACE_UINT8>::max ()
00564          : static_cast<ACE_UINT8> (val));
00565     }
00566   };
00567 
00568   template<>
00569   struct Truncator<ACE_UINT32, ACE_INT8>
00570   {
00571     ACE_INT8 operator() (ACE_UINT32 val)
00572     {
00573       return
00574         (val > static_cast<ACE_UINT32> (ACE_Numeric_Limits<ACE_INT8>::max ())
00575          ? ACE_Numeric_Limits<ACE_INT8>::max ()
00576          : static_cast<ACE_INT8> (val));
00577     }
00578   };
00579 
00580 #if defined (ACE_SIZEOF_LONG) && ACE_SIZEOF_LONG < 8
00581   template<>
00582   struct Truncator<ACE_INT64, signed long>
00583   {
00584     signed long operator() (ACE_INT64 val)
00585     {
00586       return
00587         (val > ACE_Numeric_Limits<signed long>::max ()
00588          ? ACE_Numeric_Limits<signed long>::max ()
00589          : static_cast<signed long> (val));
00590     }
00591   };
00592 
00593   template<>
00594   struct Truncator<ACE_INT64, unsigned long>
00595   {
00596     unsigned long operator() (ACE_INT64 val)
00597     {
00598       return
00599         (val > static_cast<ACE_INT64> (ACE_Numeric_Limits<unsigned long>::max ())
00600          ? ACE_Numeric_Limits<unsigned long>::max ()
00601          : static_cast<unsigned long> (val));
00602     }
00603   };
00604 
00605   template<>
00606   struct Truncator<ACE_UINT64, unsigned long>
00607   {
00608     unsigned long operator() (ACE_UINT64 val)
00609     {
00610       return
00611         (val > static_cast<ACE_UINT64> (ACE_Numeric_Limits<unsigned long>::max ())
00612          ? ACE_Numeric_Limits<unsigned long>::max ()
00613          : static_cast<unsigned long> (val));
00614     }
00615   };
00616 
00617   template<>
00618   struct Truncator<ACE_UINT64, signed long>
00619   {
00620     signed long operator() (ACE_UINT64 val)
00621     {
00622       return
00623         (val > static_cast<ACE_UINT64> (ACE_Numeric_Limits<signed long>::max ())
00624          ? ACE_Numeric_Limits<signed long>::max ()
00625          : static_cast<signed long> (val));
00626     }
00627   };
00628 
00629   template<>
00630   struct Truncator<const ACE_UINT64, signed long>
00631   {
00632     signed long operator() (const ACE_UINT64 val)
00633     {
00634       return
00635         (val > static_cast<ACE_UINT64> (ACE_Numeric_Limits<signed long>::max ())
00636          ? ACE_Numeric_Limits<signed long>::max ()
00637          : static_cast<signed long> (val));
00638     }
00639   };
00640 
00641 #endif  /* ACE_SIZEOF_LONG < 8 */
00642 
00643 #if defined (ACE_SIZEOF_INT) && ACE_SIZEOF_INT < 8
00644   template<>
00645   struct Truncator<ACE_INT64, signed int>
00646   {
00647     ACE_INT32 operator() (ACE_INT64 val)
00648     {
00649       return
00650         (val > ACE_Numeric_Limits<signed int>::max ()
00651          ? ACE_Numeric_Limits<signed int>::max ()
00652          : static_cast<signed int> (val));
00653     }
00654   };
00655 
00656   template<>
00657   struct Truncator<ACE_INT64, unsigned int>
00658   {
00659     ACE_UINT32 operator() (ACE_INT64 val)
00660     {
00661       return
00662         (val > static_cast<ACE_INT64> (ACE_Numeric_Limits<unsigned int>::max ())
00663          ? ACE_Numeric_Limits<unsigned int>::max ()
00664          : static_cast<unsigned int> (val));
00665     }
00666   };
00667 
00668   template<>
00669   struct Truncator<ACE_UINT64, unsigned int>
00670   {
00671     ACE_UINT32 operator() (ACE_UINT64 val)
00672     {
00673       return
00674         (val > static_cast<ACE_UINT64> (ACE_Numeric_Limits<unsigned int>::max ())
00675          ? ACE_Numeric_Limits<unsigned int>::max ()
00676          : static_cast<unsigned int> (val));
00677     }
00678   };
00679 
00680   template<>
00681   struct Truncator<ACE_UINT64, signed int>
00682   {
00683     signed int operator() (ACE_UINT64 val)
00684     {
00685       return
00686         (val > static_cast<ACE_UINT64> (ACE_Numeric_Limits<signed int>::max ())
00687          ? ACE_Numeric_Limits<signed int>::max ()
00688          : static_cast<signed int> (val));
00689     }
00690   };
00691 
00692 #endif  /* ACE_SIZEOF_INT < 8 */
00693 
00694   //----------------------------------------------------------
00695   // sizeof(FROM) == sizeof(TO)
00696   //----------------------------------------------------------
00697 
00698   template<>
00699   struct Truncator<signed int, unsigned int>
00700   {
00701     unsigned int operator() (signed int val)
00702     {
00703       return static_cast<unsigned int> (val);
00704     }
00705   };
00706 
00707   template<>
00708   struct Truncator<unsigned int, signed int>
00709   {
00710     signed int operator() (unsigned int val)
00711     {
00712       return
00713         (val > static_cast<unsigned int> (ACE_Numeric_Limits<signed int>::max ())
00714          ? ACE_Numeric_Limits<signed int>::max ()
00715          : static_cast<signed int> (val));
00716     }
00717   };
00718 
00719   template<>
00720   struct Truncator<signed long, unsigned long>
00721   {
00722     unsigned long operator() (signed long val)
00723     {
00724       return static_cast<unsigned long> (val);
00725     }
00726   };
00727 
00728   template<>
00729   struct Truncator<unsigned long, signed long>
00730   {
00731     signed long operator() (unsigned long val)
00732     {
00733       return
00734         (val > static_cast<unsigned long> (ACE_Numeric_Limits<signed long>::max ())
00735          ? ACE_Numeric_Limits<signed long>::max ()
00736          : static_cast<signed long> (val));
00737     }
00738   };
00739 
00740 #if defined (ACE_SIZEOF_INT) && defined (ACE_SIZEOF_LONG) \
00741     && ACE_SIZEOF_INT == ACE_SIZEOF_LONG
00742 
00743   template<>
00744   struct Truncator<signed int, unsigned long>
00745   {
00746     unsigned long operator() (signed int val)
00747     {
00748       return static_cast<unsigned long> (val);
00749     }
00750   };
00751 
00752   template<>
00753   struct Truncator<unsigned long, signed int>
00754   {
00755     signed int operator() (unsigned long val)
00756     {
00757       return
00758         (val > static_cast<unsigned long> (ACE_Numeric_Limits<signed int>::max ())
00759          ? ACE_Numeric_Limits<signed int>::max ()
00760          : static_cast<signed int> (val));
00761     }
00762   };
00763 
00764   template<>
00765   struct Truncator<signed long, signed int>
00766   {
00767     signed int operator() (signed long val)
00768     {
00769       return static_cast<signed int> (val);
00770 //      This code causes asserts and compiler crashes with BCB6 Static and
00771 //      BCB2007 Static
00772 //      return
00773 //        (val > static_cast<signed long> (ACE_Numeric_Limits<signed int>::max ())
00774 //         ? ACE_Numeric_Limits<signed int>::max ()
00775 //         : static_cast<signed int> (val));
00776     }
00777   };
00778 
00779   template<>
00780   struct Truncator<signed long, unsigned int>
00781   {
00782     unsigned int operator() (signed long val)
00783     {
00784       return static_cast<unsigned int> (val);
00785     }
00786   };
00787 
00788   template<>
00789   struct Truncator<const signed long, unsigned int>
00790   {
00791     unsigned int operator() (const signed long val)
00792     {
00793       return static_cast<unsigned int> (val);
00794     }
00795   };
00796 
00797 
00798   template<>
00799   struct Truncator<unsigned int, signed long>
00800   {
00801     signed long operator() (unsigned int val)
00802     {
00803       return
00804         (val > static_cast<unsigned int> (ACE_Numeric_Limits<signed long>::max ())
00805          ? ACE_Numeric_Limits<signed long>::max ()
00806          : static_cast<signed long> (val));
00807     }
00808   };
00809 
00810 #endif  /* ACE_SIZEOF_INT == ACE_SIZEOF_LONG */
00811 
00812   template<>
00813   struct Truncator<ACE_INT64, ACE_UINT64>
00814   {
00815     ACE_UINT64 operator() (ACE_INT64 val)
00816     {
00817       return static_cast<ACE_UINT64> (val);
00818     }
00819   };
00820 
00821   template<>
00822   struct Truncator<ACE_UINT64, ACE_INT64>
00823   {
00824     ACE_INT64 operator() (ACE_UINT64 val)
00825     {
00826       return
00827         (val > static_cast<ACE_UINT64> (ACE_Numeric_Limits<ACE_INT64>::max ())
00828          ? ACE_Numeric_Limits<ACE_INT64>::max ()
00829          : static_cast<ACE_INT64> (val));
00830     }
00831   };
00832 
00833   //----------------------------------------------------------
00834   // sizeof(FROM) <  sizeof(TO)
00835   //----------------------------------------------------------
00836 
00837   template<>
00838   struct Truncator<ACE_INT8, ACE_INT32>
00839   {
00840     ACE_INT32 operator() (ACE_INT8 val)
00841     {
00842       return static_cast<ACE_INT32> (val);
00843     }
00844   };
00845 
00846   template<>
00847   struct Truncator<ACE_UINT8, ACE_UINT32>
00848   {
00849     ACE_UINT32 operator() (ACE_UINT8 val)
00850     {
00851       return static_cast<ACE_UINT32> (val);
00852     }
00853   };
00854 
00855   template<>
00856   struct Truncator<ACE_UINT8, ACE_INT32>
00857   {
00858     ACE_INT32 operator() (ACE_UINT8 val)
00859     {
00860       return static_cast<ACE_INT32> (val);
00861     }
00862   };
00863 
00864   template<>
00865   struct Truncator<ACE_INT8, ACE_UINT32>
00866   {
00867     ACE_UINT32 operator() (ACE_INT8 val)
00868     {
00869       return static_cast<ACE_UINT32> (val);
00870     }
00871   };
00872 
00873 #if defined (ACE_SIZEOF_LONG) && ACE_SIZEOF_LONG < 8
00874   template<>
00875   struct Truncator<signed long, ACE_INT64>
00876   {
00877     ACE_INT64 operator() (signed long val)
00878     {
00879       return static_cast<ACE_INT64> (val);
00880     }
00881   };
00882 
00883   template<>
00884   struct Truncator<signed long, ACE_UINT64>
00885   {
00886     ACE_UINT64 operator() (signed long val)
00887     {
00888       return static_cast<ACE_UINT64> (val);
00889     }
00890   };
00891 
00892   template<>
00893   struct Truncator<const signed long, ACE_UINT64>
00894   {
00895     ACE_UINT64 operator() (const signed long val)
00896     {
00897       return
00898         (val > static_cast<ACE_UINT64> (ACE_Numeric_Limits<signed long>::max ())
00899          ? ACE_Numeric_Limits<signed long>::max ()
00900          : static_cast<signed long> (val));
00901     }
00902   };
00903 
00904   template<>
00905   struct Truncator<unsigned long, ACE_UINT64>
00906   {
00907     ACE_UINT64 operator() (unsigned long val)
00908     {
00909       return static_cast<ACE_UINT64> (val);
00910     }
00911   };
00912 
00913   template<>
00914   struct Truncator<unsigned long, ACE_INT64>
00915   {
00916     ACE_INT64 operator() (unsigned long val)
00917     {
00918       return static_cast<ACE_INT64> (val);
00919     }
00920   };
00921 #endif  /* ACE_SIZEOF_LONG < 8 */
00922 
00923 #if defined (ACE_SIZEOF_INT) && ACE_SIZEOF_INT < 8
00924   template<>
00925   struct Truncator<signed int, ACE_INT64>
00926   {
00927     ACE_INT64 operator() (signed int val)
00928     {
00929       return static_cast<ACE_INT64> (val);
00930     }
00931   };
00932 
00933   template<>
00934   struct Truncator<signed int, ACE_UINT64>
00935   {
00936     ACE_UINT64 operator() (signed int val)
00937     {
00938       return static_cast<ACE_UINT64> (val);
00939     }
00940   };
00941 
00942   template<>
00943   struct Truncator<unsigned int, ACE_UINT64>
00944   {
00945     ACE_UINT64 operator() (unsigned int val)
00946     {
00947       return static_cast<ACE_UINT64> (val);
00948     }
00949   };
00950 
00951   template<>
00952   struct Truncator<unsigned int, ACE_INT64>
00953   {
00954     ACE_INT64 operator() (unsigned int val)
00955     {
00956       return static_cast<ACE_INT64> (val);
00957     }
00958   };
00959 #endif  /* ACE_SIZEOF_INT < 8 */
00960 
00961   template<>
00962   struct Truncator<size_t, unsigned long>
00963   {
00964     unsigned long operator() (size_t val)
00965     {
00966       return
00967         (val > static_cast<unsigned long> (ACE_Numeric_Limits<size_t>::max ())
00968          ? ACE_Numeric_Limits<size_t>::max ()
00969          : static_cast<size_t> (val));
00970     }
00971   };
00972 
00973   // Partial specialization for the case where the types are the same.
00974   // No truncation is necessary.
00975   template<typename T>
00976   struct Truncator<T, T>
00977   {
00978     T operator() (T val)
00979     {
00980       return val;
00981     }
00982   };
00983 
00984   // Partial specialization for the case where the types are the same,
00985   // but the from type is const.  No truncation is necessary.
00986   //
00987   // This is only necessary to workaround a problem with the BCB6
00988   // compiler.
00989   template<typename T>
00990   struct Truncator<T const, T>
00991   {
00992     T operator() (T val)
00993     {
00994       return val;
00995     }
00996   };
00997 
00998   // -------------------------------------
00999 
01000   template<typename TO, typename FROM>
01001   inline TO truncate_cast (FROM val)
01002   {
01003     typedef Truncator<FROM, TO> truncator;
01004 
01005     return truncator() (val);
01006   }
01007 
01008 #endif  /* !__BORLANDC__ || __BORLANDC__ >= 0x590 */
01009 
01010 } // namespace ACE_Utils
01011 
01012 ACE_END_VERSIONED_NAMESPACE_DECL
01013 
01014 #include /**/ "ace/post.h"
01015 
01016 #endif /* ACE_TRUNCATE_H*/

Generated on Tue Feb 2 17:18:43 2010 for ACE by  doxygen 1.4.7