Main Page   Modules   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

at_gray_code.h

Go to the documentation of this file.
00001 //
00002 // The Austria library is copyright (c) Gianni Mariani 2004.
00003 // 
00004 // Grant Of License.  Grants to LICENSEE the non-exclusive right to use the Austria
00005 // library subject to the terms of the LGPL.
00006 // 
00007 // A copy of the license is available in this directory or one may be found at this URL:
00008 //      http://www.gnu.org/copyleft/lesser.txt
00009 // 
00016 #ifndef x_at_gray_code_h_x
00017 #define x_at_gray_code_h_x 1
00018 
00019 #include <limits>
00020 
00021 // Austria namespace
00022 namespace at
00023 {
00024         
00031 namespace gray_tools
00032 {
00033 
00041 template <typename T, bool is_signed=std::numeric_limits<T>::is_signed >
00042 struct signed_tester
00043 {
00051     inline static bool gtez( const T & i_rhs )
00052     {
00053         return i_rhs >= 0;
00054     }
00055 };
00056 
00061 template <typename T>
00062 struct signed_tester<T, false>
00063 {
00073     inline static bool gtez( const T & i_rhs )
00074     {
00075         return true;
00076     }
00077 };
00078 
00085 template <typename T>
00086 T bin_to_gray( const T & i_value )
00087 {
00088     
00089     if ( signed_tester<T>::gtez( i_value ) )
00090     {
00091         return i_value ^ ( i_value >> 1 );
00092     }
00093     else
00094     {
00095         return ( ( ~i_value ) ^ ( ( ~i_value ) >> 1 ) ) + std::numeric_limits<T>::min();
00096     }
00097 }
00098 
00099 
00106 template <
00107     typename T,
00108     int shift_count = 1,
00109     bool terminal_calc = ( shift_count >= ( std::numeric_limits<T>::digits ) )
00110 >
00111 struct gray_to_bin_helper
00112 {
00131     inline static void calculate( T & io_value )
00132     {
00133         io_value ^= io_value >> shift_count;
00134         gray_to_bin_helper<T,shift_count*2>::calculate( io_value );
00135     }
00136 };
00137 
00143 template <
00144     typename T,
00145     int shift_count
00146 >
00147 struct gray_to_bin_helper<T,shift_count,true>
00148 {
00152     inline static void calculate( T & value )
00153     {
00154     }
00155 };
00156     
00167 template <typename T>
00168 T gray_to_bin( T value )
00169 {
00170     if ( signed_tester<T>::gtez( value ) )
00171     {
00172         gray_to_bin_helper<T>::calculate( value );
00173     }
00174     else
00175     {
00176         value = value - std::numeric_limits<T>::min();
00177         gray_to_bin_helper<T>::calculate( value );
00178         value = ~ value;
00179     }
00180     
00181     return value;
00182 }
00183 
00184 };
00185 
00197 template <typename T>
00198 class gray_code
00199 {
00200     public:
00201     typedef T           value_type;
00202 
00203     protected:
00204     value_type          m_value;
00205 
00206     public:
00207     template <typename T2> friend class gray_code;
00208 
00212     operator value_type () const throw()
00213     {
00214         return getbin();
00215     }
00216 
00217     value_type getbin() const throw()
00218     {
00219         return gray_tools::gray_to_bin( m_value );
00220     }
00221 
00222     value_type getgray() const throw()
00223     {
00224         return m_value;
00225     }
00226 
00227     void setgray( value_type value ) throw()
00228     {
00229         m_value = value;
00230     }
00231 
00237     enum ArgType
00238     {
00242         is_gray,
00243         
00249         is_binary
00250     };
00251 
00272     gray_code( const T & i_value, ArgType i_arg_type )
00273       : m_value( i_arg_type == is_gray ? i_value : gray_tools::bin_to_gray( i_value ) )
00274     {
00275     }
00276 
00284     gray_code( const T & i_value )
00285       : m_value( gray_tools::bin_to_gray( i_value ) )
00286     {
00287     }
00288 
00295     template <typename RHS_T>
00296     gray_code( const gray_code<RHS_T> & i_other_gray )
00297       : m_value(
00298             std::numeric_limits<value_type>::is_signed == std::numeric_limits<RHS_T>::is_signed
00299             ? i_other_gray.m_value
00300             : gray_tools::bin_to_gray( value_type( i_other_gray.getbin() ) )
00301         )
00302     {
00303     }
00304 
00311     template <typename RHS_T>
00312     gray_code & operator= (const RHS_T & i_other_gray )
00313     {
00314 
00315         m_value = (
00316             std::numeric_limits<value_type>::is_signed == std::numeric_limits<RHS_T>::is_signed
00317             ? i_other_gray.m_value
00318             : gray_tools::bin_to_gray( value_type( i_other_gray.getbin() ) )
00319         );
00320         
00321         return * this;
00322     }
00323 
00331     bool gtez()
00332     {
00333         return gray_tools::signed_tester<T>::gtez( m_value );
00334     }
00335     
00342     bool equal_to_zero()
00343     {
00344         return m_value == 0;
00345     }
00346 };
00347     
00348 }; // namespace
00349 #endif // x_at_gray_code_h_x
00350 

Generated for Austria by doxygen and MakeXS at Sun Oct 24 17:35:34 PDT 2004