| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

Bit.h

Go to the documentation of this file.
00001 // $Id: Bit.h,v 1.3 2008/08/02 10:14:05 ibelyaev Exp $
00002 // ============================================================================
00003 #ifndef LHCBMATH_BIT_H 
00004 #define LHCBMATH_BIT_H 1
00005 // ============================================================================
00006 // Include files
00007 // ============================================================================
00008 // STD & STL 
00009 // ============================================================================
00010 #include <functional>
00011 // ============================================================================
00012 // LHCbMath
00013 // ============================================================================
00014 #include "LHCbMath/TypeWrapper.h"
00015 // ============================================================================
00016 // Boost
00017 // ============================================================================
00018 #include "boost/integer_traits.hpp"
00019 #include "boost/static_assert.hpp"
00020 // ============================================================================
00061 // ============================================================================
00062 namespace Gaudi
00063 {
00064   namespace Math 
00065   {
00066     namespace detail 
00067     {
00068       // ======================================================================
00075       template <class TYPE,unsigned int N>
00076       struct Check 
00077       {
00078         // ====================================================================
00079         BOOST_STATIC_ASSERT( boost::integer_traits<TYPE>::is_specialized
00080                              && boost::integer_traits<TYPE>::is_integral 
00081                              &&!boost::integer_traits<TYPE>::is_signed ) ;      
00082         // ====================================================================
00083         enum { value =  N < (unsigned int) boost::integer_traits <TYPE>::digits } ;
00084         // ====================================================================
00085       };
00086       // ======================================================================
00092       template <class TYPE, 
00093                 typename Gaudi::Math::TypeWrapper<TYPE>::value_type I, 
00094                 unsigned int N>
00095       struct _IBit
00096       {
00097       private:
00098         // ====================================================================
00099         BOOST_STATIC_ASSERT( boost::integer_traits<TYPE>::is_specialized 
00100                              &&!boost::integer_traits<TYPE>::is_signed   ) ;
00101         // ====================================================================
00102       public:
00103         // ====================================================================
00104         enum { value = 0 < ( I & ( static_cast<TYPE>(1) << N ) ) } ;
00105         // ====================================================================
00106       };
00107       // ======================================================================
00114       template <class TYPE,
00115                 typename Gaudi::Math::TypeWrapper<TYPE>::value_type I, 
00116                 unsigned int N1,
00117                 unsigned int N2>
00118       struct _IBits
00119       {
00120       private:
00121         // ====================================================================
00122         BOOST_STATIC_ASSERT( boost::integer_traits<TYPE>::is_specialized 
00123                              &&!boost::integer_traits<TYPE>::is_signed   ) ;
00124         // ====================================================================
00125       public:
00126         // ====================================================================
00127         enum 
00128           { 
00129             value = 
00130             ( I & ( static_cast<TYPE> ( -1 )
00131                     << ( boost::integer_traits<TYPE>::digits + N1 - N2 ) 
00132                     >> ( boost::integer_traits<TYPE>::digits      - N2 ) ) ) 
00133             >> N1
00134           } ;
00135         // ====================================================================
00136       };
00137       // ======================================================================
00143       template <class TYPE, unsigned int N>
00144       struct _Bit : public std::unary_function<TYPE,bool>
00145       {
00146       private:
00147         // ====================================================================
00148         BOOST_STATIC_ASSERT( boost::integer_traits<TYPE>::is_specialized
00149                              && boost::integer_traits<TYPE>::is_integral 
00150                              &&!boost::integer_traits<TYPE>::is_signed ) ;
00151         // ====================================================================
00152       public:
00153         // ====================================================================
00154         inline bool operator() ( const TYPE value ) const
00155         {
00156           static const TYPE s_mask = static_cast<TYPE> ( 1 ) << N  ;
00157           return value & s_mask ;
00158         } 
00159         // ====================================================================
00160       };
00161       // ======================================================================
00167       template <class TYPE,unsigned int N1,unsigned int N2>
00168       struct _Bits : public std::unary_function<TYPE,TYPE> 
00169       {
00170       private:
00171         // ====================================================================
00172         BOOST_STATIC_ASSERT( boost::integer_traits<TYPE>::is_specialized
00173                              && boost::integer_traits<TYPE>::is_integral 
00174                              &&!boost::integer_traits<TYPE>::is_signed      ) ;
00175         // ====================================================================
00176         BOOST_STATIC_ASSERT( N1 < N2  &&
00177                              N1 <  (unsigned int) boost::integer_traits<TYPE>::digits && 
00178                              N2 <= (unsigned int) boost::integer_traits<TYPE>::digits ) ;
00179         // ====================================================================
00180       public:
00181         // ====================================================================
00182         inline TYPE operator() ( const TYPE value ) const
00183         {
00184           // ==================================================================
00185           static const TYPE s_mask = 
00186             ( static_cast<TYPE> ( -1 ) 
00187               << ( boost::integer_traits<TYPE>::digits + N1 - N2 ) )  
00188               >> ( boost::integer_traits<TYPE>::digits      - N2 ) ;
00189           // =================================================================
00190           return ( value & s_mask ) >> N1 ;
00191           // ==================================================================
00192         }
00193         // ====================================================================
00194       } ;
00195       // ======================================================================
00196     } // end of namespace detail
00197     // ========================================================================
00215     template <class TYPE, 
00216               typename Gaudi::Math::TypeWrapper<TYPE>::value_type I, 
00217               unsigned int  N>
00218     struct IBit : public detail::_IBit<TYPE,I,N>
00219     {
00220       // ======================================================================
00221       BOOST_STATIC_ASSERT ( ( detail::Check<TYPE,N>::value ) ) ;
00222       BOOST_STATIC_ASSERT( boost::integer_traits<TYPE>::is_specialized
00223                            && boost::integer_traits<TYPE>::is_integral 
00224                            &&!boost::integer_traits<TYPE>::is_signed   ) ;
00225       // ======================================================================
00226     };
00227     // ========================================================================
00244     template <class TYPE,
00245               typename Gaudi::Math::TypeWrapper<TYPE>::value_type I, 
00246               unsigned int N1,
00247               unsigned int N2>
00248     struct IBits : public detail::_IBits<TYPE,I,N1,N2>
00249     {
00250       // ======================================================================
00251       BOOST_STATIC_ASSERT( N1 < N2 
00252                            && boost::integer_traits<TYPE>::is_specialized
00253                            && boost::integer_traits<TYPE>::is_integral 
00254                            &&!boost::integer_traits<TYPE>::is_signed   ) ;
00255       // ======================================================================
00256       BOOST_STATIC_ASSERT( N1 < (unsigned int) boost::integer_traits<TYPE>::digits && 
00257                            N2 < 1 +            boost::integer_traits<TYPE>::digits ) ;
00258       // ======================================================================
00259     };
00260     // ========================================================================
00280     template <class TYPE, unsigned int N>
00281     struct Bit : public detail::_Bit<TYPE,N>
00282     {
00283       // ======================================================================
00284       BOOST_STATIC_ASSERT ( ( detail::Check<TYPE,N>::value ) ) ;
00285       BOOST_STATIC_ASSERT ( boost::integer_traits<TYPE>::is_specialized
00286                             && boost::integer_traits<TYPE>::is_integral 
00287                             &&!boost::integer_traits<TYPE>::is_signed   ) ;
00288       // ======================================================================
00289     };
00290     // ========================================================================
00309     template <class TYPE, unsigned int N1, unsigned int N2>
00310     struct Bits : public detail::_Bits<TYPE,N1,N2>
00311     {
00312       // ======================================================================
00313       BOOST_STATIC_ASSERT( N1 < N2 
00314                            && boost::integer_traits<TYPE>::is_specialized
00315                            && boost::integer_traits<TYPE>::is_integral 
00316                            &&!boost::integer_traits<TYPE>::is_signed    ) ;
00317       // ====================================================================
00318       BOOST_STATIC_ASSERT( N1 < (unsigned int) boost::integer_traits<TYPE>::digits && 
00319                            N2 < 1 +            boost::integer_traits<TYPE>::digits ) ;
00320       // ======================================================================
00321     };
00322     // ========================================================================
00339     template <class TYPE>
00340     inline bool bit ( const TYPE value , const unsigned int N  ) 
00341     {
00342       // ======================================================================
00343       BOOST_STATIC_ASSERT( boost::integer_traits<TYPE>::is_specialized
00344                            && boost::integer_traits<TYPE>::is_integral 
00345                            &&!boost::integer_traits<TYPE>::is_signed ) ;
00346       // ======================================================================
00347       static const TYPE one = static_cast<TYPE>(1) ;
00348       return N < (unsigned int) boost::integer_traits <TYPE>::digits ? 
00349         ( value & ( one << N ) ) : 0 ;
00350       // ======================================================================
00351     }  
00352     // ========================================================================
00353     template <class TYPE>
00354     inline TYPE bits ( const TYPE         value , 
00355                        const unsigned int N1    , 
00356                        const unsigned int N2    )
00357     {
00358       // ======================================================================
00359       BOOST_STATIC_ASSERT( boost::integer_traits<TYPE>::is_specialized
00360                            && boost::integer_traits<TYPE>::is_integral 
00361                            &&!boost::integer_traits<TYPE>::is_signed ) ;
00362       // ======================================================================
00363       if ( N2 >  (unsigned int) boost::integer_traits<TYPE>::digits ) 
00364       { return bits ( value , N1 , boost::integer_traits<TYPE>::digits ) ; } 
00365       // 
00366       if ( N1 >= N2 ||
00367            N1 >= (unsigned int) boost::integer_traits<TYPE>::digits ) { return 0 ; }
00368       // ======================================================================
00369       const TYPE mask = 
00370         ( static_cast<TYPE> ( -1 ) 
00371           << ( boost::integer_traits<TYPE>::digits + N1 - N2 ) )
00372           >> ( boost::integer_traits<TYPE>::digits      - N2 ) ;
00373       // ======================================================================
00374       return ( value & mask ) >> N1 ;
00375       // ======================================================================
00376     }
00377     // ========================================================================
00378   } // end of namespace Gaudi::Math
00379   // ==========================================================================
00380 } // end of namespace Gaudi
00381 // ============================================================================
00382 // The END 
00383 // ============================================================================
00384 #endif // LHCBMATH_DIGIT_H
00385 // ============================================================================
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 20:02:57 2011 for LHCbMath by doxygen 1.4.7