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