1 #ifndef PhysicsTools_Utilities_Factorize_h 2 #define PhysicsTools_Utilities_Factorize_h 8 #include <boost/type_traits.hpp> 9 #include <boost/integer/common_factor.hpp> 10 #include <boost/mpl/and.hpp> 11 #include <boost/mpl/not.hpp> 12 #include <boost/mpl/int.hpp> 13 #include <boost/mpl/if.hpp> 21 static const bool value =
false;
28 public Divides0<
A> { };
31 public Divides0<
PROD_S(A, B)> { };
34 public Divides<A, void> { };
37 static const bool value =
true;
43 TEMPL(T1) struct Divides<
A, A> :
49 TEMPL(N1T1)
struct Divides<POWER_S(A, NUM(n)),
54 public Divides<POWER(A, NUM(n)), void> { };
57 static const bool value =
true;
59 static const int p = ::boost::mpl::if_c<(n <
m),
60 ::boost::mpl::int_<n>, ::boost::mpl::int_<m> >::
type::value;
66 TEMPL(N2T1) struct Divides<POWER_S(A, NUM(n)),
70 TEMPL(N1T1)
struct Divides<A, POWER_S(A, NUM(n))> :
73 TEMPL(N1T1)
struct Divides<POWER_S(A, NUM(n)), A> :
78 template<
int n,
bool positive = (n>= 0)>
79 struct abs {
enum { value = n }; };
82 struct abs<n, false> {
enum { value = -n }; };
86 TEMPL(N2) struct Divides<NUM(n), NUM(m)> {
88 static const bool value = (gcd != 1);
94 TEMPL(N1) struct Divides<NUM(n), NUM(n)> {
95 static const bool value =
true;
102 public Divides<A,
B> { };
105 public Divides<
PROD_S(A, B),
C> { };
107 TEMPL(T2)
struct Divides<MINUS_S(A), B> {
108 typedef Divides<A, B>
Div;
115 TEMPL(T2) struct Divides<MINUS_S(A), MINUS_S(B)> {
116 typedef Divides<A, B>
Div;
124 typedef Divides<A, PROD_S(B, C)>
Div;
131 TEMPL(T3)
struct Divides<A, PROD_S(B, C)> {
133 typedef Divides<arg, void>
D0;
134 typedef Divides<arg, B>
D1;
135 typedef Divides<arg, C>
D2;
136 typedef typename ::boost::mpl::if_<
D1,
D1,
143 TEMPL(T3) struct Divides<PROD_S(A, B), C> {
145 typedef Divides<arg, void>
D0;
146 typedef Divides<A, C>
D1;
147 typedef Divides<B, C>
D2;
148 typedef typename ::boost::mpl::if_<
D1,
D1,
156 TEMPL(T4) struct Divides<PROD_S(A, B), PROD_S(C, D)> {
158 typedef Divides<arg, void>
D0;
159 typedef Divides<arg, C>
D1;
160 typedef Divides<arg, D>
D2;
161 typedef typename ::boost::mpl::if_<
D1,
D1,
188 inline static type
combine(
const A& _1,
const B& _2) {
190 return f * ((_1 /
f) + (_2 / f));
197 TEMPL(T3)
struct Sum<A, PROD_S(B, C)> :
206 TEMPL(T4)
struct Sum<PROD_S(A, B), PROD_S(C, D)> :
209 TEMPL(T4)
struct Sum<MINUS_S(PROD_S(A, B)),
210 MINUS_S(PROD_S(C, D))> :
212 MINUS_S(PROD_S(C, D))> { };
215 MINUS_S(PROD_S(C, D))> :
217 MINUS_S(PROD_S(C, D))> { };
219 TEMPL(T4)
struct Sum<MINUS_S(PROD_S(A, B)),
224 TEMPL(N1T2)
struct Sum<PROD_S(A, B), NUM(n)> :
227 TEMPL(N1T2)
struct Sum<NUM(n), PROD_S(A, B)> :
const Numerical< n > & num()
typedef POWER(A, NUM(n)) arg
static type combine(const A &_1, const B &_2)
DecomposeProduct< arg, typename Div::arg > D
TEMPL(T1) struct Divides0
typedef PROD(F, SUM(RATIO(A, F), RATIO(B, F))) type
#define COMBINE(A, B, RES)
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
static type get(const PROD_S(A, B)&_)
Power< A, B >::type pow(const A &a, const B &b)
T get(const Candidate &c)
::boost::mpl::if_< D1, D1, typename::boost::mpl::if_< D2, D2, D0 >::type >::type Div