libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
fma_impl.hpp
Go to the documentation of this file.
1 /******************************************************************************
2 ** Copyright © 2015 by J.M.McGuiness, coder@hussar.me.uk
3 **
4 ** This library is free software; you can redistribute it and/or
5 ** modify it under the terms of the GNU Lesser General Public
6 ** License as published by the Free Software Foundation; either
7 ** version 2.1 of the License, or (at your option) any later version.
8 **
9 ** This library is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 ** Lesser General Public License for more details.
13 **
14 ** You should have received a copy of the GNU Lesser General Public
15 ** License along with this library; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18 
19 namespace jmmcg { namespace LIBJMMCG_VER_NAMESPACE { namespace fma {
20 
21 namespace private_ {
22 
23 inline constexpr
24 dbl_mul_add::dbl_mul_add(dbl_mul const &m, double const a) noexcept(true)
25 : mul_(m), add_(a) {}
26 
27 inline constexpr
28 dbl_mul_add::dbl_mul_add(dbl_add const &a, double const m) noexcept(true)
29 : mul_(m, a.lhs_), add_(a.rhs_) {}
30 
31 inline constexpr
32 dbl_mul_add::dbl_mul_add(dbl_sub const &a, double const m) noexcept(true)
33 : mul_(m, a.lhs_), add_(-a.rhs_) {}
34 
35 inline
36 dbl_mul_add::operator double () const noexcept(true) {
37  return std::fma(mul_.lhs_, mul_.rhs_, add_);
38 }
39 
40 inline constexpr
41 dbl_mul::dbl_mul(double const &l, double const &r) noexcept(true)
42 : lhs_(l), rhs_(r) {}
43 
44 inline constexpr dbl_mul
45 dbl_mul::operator*(const double r) const noexcept(true) {
46  return dbl_mul(lhs_, rhs_*r);
47 }
48 
49 inline constexpr dbl_mul
50 dbl_mul::operator*(const dbl r) const noexcept(true) {
51  return dbl_mul(lhs_, rhs_*r.lhs_);
52 }
53 
54 inline constexpr dbl_mul_add
55 dbl_mul::operator+(const double a) const noexcept(true) {
56  return dbl_mul_add(*this, a);
57 }
58 
59 inline constexpr dbl_mul_add
60 dbl_mul::operator+(const dbl a) const noexcept(true) {
61  return dbl_mul_add(*this, a.lhs_);
62 }
63 
64 inline constexpr dbl_mul_add
65 dbl_mul::operator-(const double a) const noexcept(true) {
66  return dbl_mul_add(*this, -a);
67 }
68 
69 inline constexpr dbl_mul_add
70 dbl_mul::operator-(const dbl a) const noexcept(true) {
71  return dbl_mul_add(*this, -a.lhs_);
72 }
73 
74 inline constexpr dbl_mul_add
75 operator+(const double a, dbl_mul const &d) noexcept(true) {
76  return dbl_mul_add(d, a);
77 }
78 
79 inline constexpr dbl_mul_add
80 operator-(const double a, dbl_mul const &d) noexcept(true) {
82 }
83 
84 inline constexpr
85 dbl_add::dbl_add(double const l, double const r) noexcept(true)
86 : lhs_(l), rhs_(r) {}
87 
88 
89 inline constexpr
90 dbl_sub::dbl_sub(double const l, double const r) noexcept(true)
91 : lhs_(l), rhs_(r) {}
92 
93 inline double &
94 operator*=(double &l, dbl_add const &r) noexcept(true) {
95  l=std::fma(l, r.lhs_, r.rhs_);
96  return l;
97 }
98 
99 inline double &
100 operator*=(double &l, dbl_sub const &r) noexcept(true) {
101  l=std::fma(l, r.lhs_, -r.rhs_);
102  return l;
103 }
104 
105 inline double &
106 operator+=(double &a, dbl_mul const &m) noexcept(true) {
107  a=std::fma(m.lhs_, m.rhs_, a);
108  return a;
109 }
110 
111 inline double &
112 operator-=(double &a, dbl_mul const &m) noexcept(true) {
113  a=std::fma(m.lhs_, m.rhs_, -a);
114  return a;
115 }
116 
117 }
118 
119 inline constexpr
120 dbl::dbl(double const l) noexcept(true)
121 : lhs_(l) {}
122 
123 inline
124 dbl::dbl(private_::dbl_mul_add const &l) noexcept(true)
125 : lhs_(static_cast<double>(l)) {}
126 
127 inline constexpr bool
128 dbl::operator==(const double r) const noexcept(true) {
129  return lhs_==r;
130 }
131 
132 inline constexpr bool
133 dbl::operator==(const dbl r) const noexcept(true) {
134  return lhs_==r.lhs_;
135 }
136 
137 inline constexpr private_::dbl_mul
138 dbl::operator*(const dbl r) const noexcept(true) {
139  return private_::dbl_mul(lhs_*r);
140 }
141 
142 inline constexpr private_::dbl_mul
143 dbl::operator*(const double r) const noexcept(true) {
144  return private_::dbl_mul(lhs_, r);
145 }
146 
147 inline constexpr private_::dbl_add
148 dbl::operator+(const double r) const noexcept(true) {
149  return private_::dbl_add(lhs_, r);
150 }
151 
152 inline constexpr private_::dbl_sub
153 dbl::operator-(const double r) const noexcept(true) {
154  return private_::dbl_sub(lhs_, r);
155 }
156 
157 inline constexpr private_::dbl_mul_add
158 operator+(const dbl a, private_::dbl_mul const &d) noexcept(true) {
160 }
161 
162 inline constexpr private_::dbl_mul_add
163 operator-(const dbl a, private_::dbl_mul const &d) noexcept(true) {
165 }
166 
167 inline constexpr private_::dbl_mul
168 operator*(const double l, dbl const r) noexcept(true) {
169  return private_::dbl_mul(l, r.lhs_);
170 }
171 
172 inline std::ostream &
173 operator<<(std::ostream &os, dbl const d) noexcept(false) {
174  return os<<d.lhs_;
175 }
176 
177 } } }