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
and
MakeXS at Sun Oct 24 17:35:34 PDT 2004