Honeycomb  0.1
Component-Model Framework
Ratio.h
Go to the documentation of this file.
1 // Honeycomb, Copyright (C) 2015 NewGamePlus Inc. Distributed under the Boost Software License v1.0.
2 #pragma once
3 
4 #include "Honey/Core/Core.h"
5 
6 namespace honey
7 {
8 
10 template<int64 Num, int64 Den = 1>
11 struct Ratio
12 {
13 private:
14  friend struct Ratio;
15  template<class rhs> struct lessImpl;
16 public:
17 
18  static_assert(Den != 0, "Denominator can't be 0");
19 
22 
24  template<class rhs>
25  struct add
26  {
27  private:
28  static const int64 gcd1 = mt::gcd<den, rhs::den>::value;
29  static const int64 n = num * (rhs::den / gcd1) + rhs::num * (den / gcd1);
30  static const int64 gcd2 = mt::gcd<n, gcd1>::value;
31 
32  public:
33  typedef Ratio<n / gcd2, (den / gcd2) * (rhs::den / gcd1)> type;
34  };
35 
37  template<class rhs>
38  struct sub { typedef typename add<Ratio<-rhs::num, rhs::den>>::type type; };
39 
41  template<class rhs>
42  struct mul
43  {
44  private:
45  static const int64 gcd1 = mt::gcd<num, rhs::den>::value;
46  static const int64 gcd2 = mt::gcd<rhs::num, den>::value;
47  public:
48  typedef Ratio<(num / gcd1) * (rhs::num / gcd2), (den / gcd2) * (rhs::den / gcd1)> type;
49  };
50 
52  template<class rhs>
53  struct div { static_assert(rhs::num != 0, "Divide by 0"); typedef typename mul<Ratio<rhs::den, rhs::num>>::type type; };
54 
56  template<class rhs>
57  struct equal : mt::Value<bool, num == rhs::num && den == rhs::den> {};
58 
60  template<class rhs>
61  struct notEqual : mt::Value<bool, !equal<rhs>::value> {};
62 
64  template<class rhs>
65  struct less : mt::Value<bool, lessImpl<rhs>::value> {};
66 
68  template<class rhs>
69  struct lessEqual : mt::Value<bool, !rhs::template less<Ratio>::value> {};
70 
72  template<class rhs>
73  struct greater : mt::Value<bool, rhs::template less<Ratio>::value> {};
74 
76  template<class rhs>
77  struct greaterEqual : mt::Value<bool, !less<rhs>::value> {};
78 
79 private:
80  template<class lhs, class rhs> struct lessCmpFrac;
81 
82  template< class rhs,
83  int64 q1 = num / den,
84  int64 q2 = rhs::num / rhs::den,
85  bool eq = q1 == q2>
86  struct lessCmpWhole;
87 
89  template< class rhs,
90  bool = (num == 0 || rhs::num == 0 || (mt::sign<num>::value != mt::sign<rhs::num>::value)),
91  bool = (mt::sign<num>::value == -1 && mt::sign<rhs::num>::value == -1)>
92  struct lessCmpSign : lessCmpWhole<rhs> {};
93 
95  template<class rhs>
96  struct lessCmpSign<rhs, true, false> : mt::Value<bool, (num < rhs::num)> {};
97 
99  template<class rhs>
100  struct lessCmpSign<rhs, false, true> :
101  Ratio<-rhs::num, rhs::den>::
102  template lessCmpWhole<
103  Ratio<-num, den>
104  > {};
105 
107  template<class rhs> struct lessImpl : lessCmpSign<rhs> {};
108 
110  template<class rhs, int64 q1, int64 q2, bool eq>
111  struct lessCmpWhole :
112  lessCmpFrac<
113  Ratio<num % den, den>,
114  Ratio<rhs::num % rhs::den, rhs::den>
115  > {};
116 
118  template<class rhs, int64 q1, int64 q2>
119  struct lessCmpWhole<rhs, q1, q2, false> : mt::Value<bool, (q1 < q2)> {};
120 
122  template<class lhs, class rhs>
123  struct lessCmpFrac :
124  Ratio<rhs::den, rhs::num>::
125  template lessCmpWhole<
126  Ratio<lhs::den, lhs::num>
127  > {};
128 
130  template<class lhs, int64 Den2>
131  struct lessCmpFrac<lhs, Ratio<0, Den2>> : mt::Value<bool, false> {};
132 
134  template<int64 Den1, class rhs>
135  struct lessCmpFrac<Ratio<0, Den1>, rhs> : mt::Value<bool, true> {};
136 
138  template<int64 Den1, int64 Den2>
139  struct lessCmpFrac<Ratio<0, Den1>, Ratio<0, Den2>> : mt::Value<bool, false> {};
140 };
141 
143 namespace ratio
144 {
145  typedef Ratio<1, 1000000000000000000> Atto;
146  typedef Ratio<1, 1000000000000000> Femto;
147  typedef Ratio<1, 1000000000000> Pico;
148  typedef Ratio<1, 1000000000> Nano;
149  typedef Ratio<1, 1000000> Micro;
150  typedef Ratio<1, 1000> Milli;
151  typedef Ratio<1, 100> Centi;
152  typedef Ratio<1, 10> Deci;
153  typedef Ratio<1, 1> Unit;
154  typedef Ratio<10, 1> Deca;
155  typedef Ratio<100, 1> Hecto;
156  typedef Ratio<1000, 1> Kilo;
157  typedef Ratio<1000000, 1> Mega;
158  typedef Ratio<1000000000, 1> Giga;
159  typedef Ratio<1000000000000, 1> Tera;
160  typedef Ratio<1000000000000000, 1> Peta;
161  typedef Ratio<1000000000000000000, 1> Exa;
162 }
163 
164 }
165 
166 namespace std
167 {
169 
170  template<honey::int64 Num, honey::int64 Den, honey::int64 Num2, honey::int64 Den2>
171  struct common_type<honey::Ratio<Num,Den>, honey::Ratio<Num2,Den2>>
172  {
173  private:
174  static const honey::int64 gcdNum = honey::mt::gcd<Num, Num2>::value;
175  static const honey::int64 gcdDen = honey::mt::gcd<Den, Den2>::value;
176  public:
177  typedef honey::Ratio<gcdNum, (Den / gcdDen) * Den2> type;
178  };
179 }
mul< Ratio< rhs::den, rhs::num > >::type type
Definition: Ratio.h:53
operator*
Definition: Ratio.h:42
Class to hold compile-time finite rational numbers, ie. the fraction num / den.
Definition: Ratio.h:11
Ratio<(num/gcd1)*(rhs::num/gcd2),(den/gcd2)*(rhs::den/gcd1)> type
Definition: Ratio.h:48
operator/
Definition: Ratio.h:53
static const int64 num
Definition: Ratio.h:20
static const int64 den
Definition: Ratio.h:21
operator<
Definition: Ratio.h:65
Ratio< n/gcd2,(den/gcd2)*(rhs::den/gcd1)> type
Definition: Ratio.h:33
std::integral_constant< T, val > Value
Holds a constant integral value.
Definition: Meta.h:29
Value< int64,(val< 0)?-val:val > abs
Get the absolute value of a number.
Definition: Meta.h:307
add< Ratio<-rhs::num, rhs::den > >::type type
Definition: Ratio.h:38
operator-
Definition: Ratio.h:38
operator==
Definition: Ratio.h:57
operator+
Definition: Ratio.h:25
Value< int64,(val< 0)?-1:1 > sign
Get the sign of a number.
Definition: Meta.h:309
operator>=
Definition: Ratio.h:77
Calc greatest common divisor of a and b.
Definition: Meta.h:316
friend struct Ratio
Definition: Ratio.h:14
operator<=
Definition: Ratio.h:69
long long int64
Definition: Core.h:21
operator>
Definition: Ratio.h:73
operator!=
Definition: Ratio.h:61
Global Honeycomb namespace.