epoc32/include/stdapis/boost/math/common_factor_rt.hpp
author William Roberts <williamr@symbian.org>
Tue, 16 Mar 2010 16:12:26 +0000
branchSymbian2
changeset 2 2fe1408b6811
permissions -rw-r--r--
Final list of Symbian^2 public API header files
     1 //  Boost common_factor_rt.hpp header file  ----------------------------------//
     2 
     3 //  (C) Copyright Daryle Walker and Paul Moore 2001-2002.  Permission to copy,
     4 //  use, modify, sell and distribute this software is granted provided this
     5 //  copyright notice appears in all copies.  This software is provided "as is"
     6 //  without express or implied warranty, and with no claim as to its suitability
     7 //  for any purpose. 
     8 
     9 //  See http://www.boost.org for updates, documentation, and revision history. 
    10 
    11 #ifndef BOOST_MATH_COMMON_FACTOR_RT_HPP
    12 #define BOOST_MATH_COMMON_FACTOR_RT_HPP
    13 
    14 #include <boost/math_fwd.hpp>  // self include
    15 
    16 #include <boost/config.hpp>  // for BOOST_NESTED_TEMPLATE, etc.
    17 #include <boost/limits.hpp>  // for std::numeric_limits
    18 
    19 
    20 namespace boost
    21 {
    22 namespace math
    23 {
    24 
    25 
    26 //  Forward declarations for function templates  -----------------------------//
    27 
    28 template < typename IntegerType >
    29     IntegerType  gcd( IntegerType const &a, IntegerType const &b );
    30 
    31 template < typename IntegerType >
    32     IntegerType  lcm( IntegerType const &a, IntegerType const &b );
    33 
    34 
    35 //  Greatest common divisor evaluator class declaration  ---------------------//
    36 
    37 template < typename IntegerType >
    38 class gcd_evaluator
    39 {
    40 public:
    41     // Types
    42     typedef IntegerType  result_type, first_argument_type, second_argument_type;
    43 
    44     // Function object interface
    45     result_type  operator ()( first_argument_type const &a,
    46      second_argument_type const &b ) const;
    47 
    48 };  // boost::math::gcd_evaluator
    49 
    50 
    51 //  Least common multiple evaluator class declaration  -----------------------//
    52 
    53 template < typename IntegerType >
    54 class lcm_evaluator
    55 {
    56 public:
    57     // Types
    58     typedef IntegerType  result_type, first_argument_type, second_argument_type;
    59 
    60     // Function object interface
    61     result_type  operator ()( first_argument_type const &a,
    62      second_argument_type const &b ) const;
    63 
    64 };  // boost::math::lcm_evaluator
    65 
    66 
    67 //  Implementation details  --------------------------------------------------//
    68 
    69 namespace detail
    70 {
    71     // Greatest common divisor for rings (including unsigned integers)
    72     template < typename RingType >
    73     RingType
    74     gcd_euclidean
    75     (
    76         RingType  a,
    77         RingType  b
    78     )
    79     {
    80         // Avoid repeated construction
    81         #ifndef __BORLANDC__
    82         RingType const  zero = static_cast<RingType>( 0 );
    83         #else
    84         RingType  zero = static_cast<RingType>( 0 );
    85         #endif
    86 
    87         // Reduce by GCD-remainder property [GCD(a,b) == GCD(b,a MOD b)]
    88         while ( true )
    89         {
    90             if ( a == zero )
    91                 return b;
    92             b %= a;
    93 
    94             if ( b == zero )
    95                 return a;
    96             a %= b;
    97         }
    98     }
    99 
   100     // Greatest common divisor for (signed) integers
   101     template < typename IntegerType >
   102     inline
   103     IntegerType
   104     gcd_integer
   105     (
   106         IntegerType const &  a,
   107         IntegerType const &  b
   108     )
   109     {
   110         // Avoid repeated construction
   111         IntegerType const  zero = static_cast<IntegerType>( 0 );
   112         IntegerType const  result = gcd_euclidean( a, b );
   113 
   114         return ( result < zero ) ? -result : result;
   115     }
   116 
   117     // Least common multiple for rings (including unsigned integers)
   118     template < typename RingType >
   119     inline
   120     RingType
   121     lcm_euclidean
   122     (
   123         RingType const &  a,
   124         RingType const &  b
   125     )
   126     {
   127         RingType const  zero = static_cast<RingType>( 0 );
   128         RingType const  temp = gcd_euclidean( a, b );
   129 
   130         return ( temp != zero ) ? ( a / temp * b ) : zero;
   131     }
   132 
   133     // Least common multiple for (signed) integers
   134     template < typename IntegerType >
   135     inline
   136     IntegerType
   137     lcm_integer
   138     (
   139         IntegerType const &  a,
   140         IntegerType const &  b
   141     )
   142     {
   143         // Avoid repeated construction
   144         IntegerType const  zero = static_cast<IntegerType>( 0 );
   145         IntegerType const  result = lcm_euclidean( a, b );
   146 
   147         return ( result < zero ) ? -result : result;
   148     }
   149 
   150     // Function objects to find the best way of computing GCD or LCM
   151 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
   152 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
   153     template < typename T, bool IsSpecialized, bool IsSigned >
   154     struct gcd_optimal_evaluator_helper_t
   155     {
   156         T  operator ()( T const &a, T const &b )
   157         {
   158             return gcd_euclidean( a, b );
   159         }
   160     };
   161 
   162     template < typename T >
   163     struct gcd_optimal_evaluator_helper_t< T, true, true >
   164     {
   165         T  operator ()( T const &a, T const &b )
   166         {
   167             return gcd_integer( a, b );
   168         }
   169     };
   170 #else
   171     template < bool IsSpecialized, bool IsSigned >
   172     struct gcd_optimal_evaluator_helper2_t
   173     {
   174         template < typename T >
   175         struct helper
   176         {
   177             T  operator ()( T const &a, T const &b )
   178             {
   179                 return gcd_euclidean( a, b );
   180             }
   181         };
   182     };
   183 
   184     template < >
   185     struct gcd_optimal_evaluator_helper2_t< true, true >
   186     {
   187         template < typename T >
   188         struct helper
   189         {
   190             T  operator ()( T const &a, T const &b )
   191             {
   192                 return gcd_integer( a, b );
   193             }
   194         };
   195     };
   196 
   197     template < typename T, bool IsSpecialized, bool IsSigned >
   198     struct gcd_optimal_evaluator_helper_t
   199         : gcd_optimal_evaluator_helper2_t<IsSpecialized, IsSigned>
   200            ::BOOST_NESTED_TEMPLATE helper<T>
   201     {
   202     };
   203 #endif
   204 
   205     template < typename T >
   206     struct gcd_optimal_evaluator
   207     {
   208         T  operator ()( T const &a, T const &b )
   209         {
   210             typedef ::std::numeric_limits<T>  limits_type;
   211 
   212             typedef gcd_optimal_evaluator_helper_t<T,
   213              limits_type::is_specialized, limits_type::is_signed>  helper_type;
   214 
   215             helper_type  solver;
   216 
   217             return solver( a, b );
   218         }
   219     };
   220 #else // BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
   221     template < typename T >
   222     struct gcd_optimal_evaluator
   223     {
   224         T  operator ()( T const &a, T const &b )
   225         {
   226             return gcd_integer( a, b );
   227         }
   228     };
   229 #endif
   230 
   231 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
   232 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
   233     template < typename T, bool IsSpecialized, bool IsSigned >
   234     struct lcm_optimal_evaluator_helper_t
   235     {
   236         T  operator ()( T const &a, T const &b )
   237         {
   238             return lcm_euclidean( a, b );
   239         }
   240     };
   241 
   242     template < typename T >
   243     struct lcm_optimal_evaluator_helper_t< T, true, true >
   244     {
   245         T  operator ()( T const &a, T const &b )
   246         {
   247             return lcm_integer( a, b );
   248         }
   249     };
   250 #else
   251     template < bool IsSpecialized, bool IsSigned >
   252     struct lcm_optimal_evaluator_helper2_t
   253     {
   254         template < typename T >
   255         struct helper
   256         {
   257             T  operator ()( T const &a, T const &b )
   258             {
   259                 return lcm_euclidean( a, b );
   260             }
   261         };
   262     };
   263 
   264     template < >
   265     struct lcm_optimal_evaluator_helper2_t< true, true >
   266     {
   267         template < typename T >
   268         struct helper
   269         {
   270             T  operator ()( T const &a, T const &b )
   271             {
   272                 return lcm_integer( a, b );
   273             }
   274         };
   275     };
   276 
   277     template < typename T, bool IsSpecialized, bool IsSigned >
   278     struct lcm_optimal_evaluator_helper_t
   279         : lcm_optimal_evaluator_helper2_t<IsSpecialized, IsSigned>
   280            ::BOOST_NESTED_TEMPLATE helper<T>
   281     {
   282     };
   283 #endif
   284 
   285     template < typename T >
   286     struct lcm_optimal_evaluator
   287     {
   288         T  operator ()( T const &a, T const &b )
   289         {
   290             typedef ::std::numeric_limits<T>  limits_type;
   291 
   292             typedef lcm_optimal_evaluator_helper_t<T,
   293              limits_type::is_specialized, limits_type::is_signed>  helper_type;
   294 
   295             helper_type  solver;
   296 
   297             return solver( a, b );
   298         }
   299     };
   300 #else // BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
   301     template < typename T >
   302     struct lcm_optimal_evaluator
   303     {
   304         T  operator ()( T const &a, T const &b )
   305         {
   306             return lcm_integer( a, b );
   307         }
   308     };
   309 #endif
   310 
   311     // Functions to find the GCD or LCM in the best way
   312     template < typename T >
   313     inline
   314     T
   315     gcd_optimal
   316     (
   317         T const &  a,
   318         T const &  b
   319     )
   320     {
   321         gcd_optimal_evaluator<T>  solver;
   322 
   323         return solver( a, b );
   324     }
   325 
   326     template < typename T >
   327     inline
   328     T
   329     lcm_optimal
   330     (
   331         T const &  a,
   332         T const &  b
   333     )
   334     {
   335         lcm_optimal_evaluator<T>  solver;
   336 
   337         return solver( a, b );
   338     }
   339 
   340 }  // namespace detail
   341 
   342 
   343 //  Greatest common divisor evaluator member function definition  ------------//
   344 
   345 template < typename IntegerType >
   346 inline
   347 typename gcd_evaluator<IntegerType>::result_type
   348 gcd_evaluator<IntegerType>::operator ()
   349 (
   350     first_argument_type const &   a,
   351     second_argument_type const &  b
   352 ) const
   353 {
   354     return detail::gcd_optimal( a, b );
   355 }
   356 
   357 
   358 //  Least common multiple evaluator member function definition  --------------//
   359 
   360 template < typename IntegerType >
   361 inline
   362 typename lcm_evaluator<IntegerType>::result_type
   363 lcm_evaluator<IntegerType>::operator ()
   364 (
   365     first_argument_type const &   a,
   366     second_argument_type const &  b
   367 ) const
   368 {
   369     return detail::lcm_optimal( a, b );
   370 }
   371 
   372 
   373 //  Greatest common divisor and least common multiple function definitions  --//
   374 
   375 template < typename IntegerType >
   376 inline
   377 IntegerType
   378 gcd
   379 (
   380     IntegerType const &  a,
   381     IntegerType const &  b
   382 )
   383 {
   384     gcd_evaluator<IntegerType>  solver;
   385 
   386     return solver( a, b );
   387 }
   388 
   389 template < typename IntegerType >
   390 inline
   391 IntegerType
   392 lcm
   393 (
   394     IntegerType const &  a,
   395     IntegerType const &  b
   396 )
   397 {
   398     lcm_evaluator<IntegerType>  solver;
   399 
   400     return solver( a, b );
   401 }
   402 
   403 
   404 }  // namespace math
   405 }  // namespace boost
   406 
   407 
   408 #endif  // BOOST_MATH_COMMON_FACTOR_RT_HPP