Skip to content

Commit ffb83bc

Browse files
committed
more tests; some fixes
1 parent e509d16 commit ffb83bc

32 files changed

+2332
-3245
lines changed

README.md

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
AM numeric
22
==========
33

4-
Header-only numeric facilities for C++11.
4+
Header-only numeric facilities for C++14.
55

66

77
## Quick Overview
@@ -25,10 +25,8 @@ Header-only numeric facilities for C++11.
2525
### Other
2626
- number conversion factories
2727
- number concept checking
28-
- checking for narrowing
29-
- some tests (not very thorough at the moment)
3028

3129

3230
## Requirements
33-
- requires C++11 conforming compiler
34-
- tested with g++ 4.7.2, 4.9.2, 5.1.0, 5.3.1, 7.2 and clang++ 5.0.1
31+
- requires C++14 conforming compiler
32+
- tested with g++ {5.4, 7.2} and clang++ 5.0.2

include/angle.h

+33-105
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#include <utility>
1616
#include <random>
1717

18-
#include "narrowing.h"
1918
#include "traits.h"
2019

2120

@@ -59,7 +58,7 @@ template<class T = real_t>
5958
struct radians_turn
6059
{
6160
using type = T;
62-
static constexpr type value = static_cast<type>(2 * pi);
61+
static constexpr type value = static_cast<type>(2 * pi<type>);
6362
};
6463

6564

@@ -145,57 +144,38 @@ class angle
145144
template<class T> friend class angle;
146145

147146
public:
148-
//---------------------------------------------------------------
149-
// TYPES
150147
//---------------------------------------------------------------
151148
using turn_type = Turn;
152149
using numeric_type = typename Turn::type;
150+
using value_type = numeric_type;
153151

154152

155-
//---------------------------------------------------------------
156-
// CONSTANTS
157153
//---------------------------------------------------------------
158154
static constexpr numeric_type
159155
turn() noexcept {
160156
return (turn_type::value);
161157
}
162158

163159

164-
//---------------------------------------------------------------
165-
// CONSTRUCTION / DESTRUCTION
166160
//---------------------------------------------------------------
167161
///@brief no default contructor, angle has to be initialized with a value
168162
angle() = delete;
169163

170164
//-----------------------------------------------------
171165
/// @brief implicit conversion from simple values is not allowed
172166
explicit constexpr
173-
angle(numeric_type a):
174-
//TODO doesn't compile with gcc 5.1
175-
//but desirable for move-enabled 'heavy' number types
176-
//v_{std::move(a)}
167+
angle(const numeric_type& a):
177168
v_{a}
178169
{}
179-
//-----------------------------------------------------
180-
/// @brief implicit conversion from simple values is not allowed
181-
template<class T, class = typename std::enable_if<
182-
is_number<T>::value && !is_angle<T>::value>::type>
183-
explicit constexpr
184-
angle(T a):
185-
v_(static_cast<numeric_type>(a))
186-
{
187-
AM_CHECK_NARROWING(numeric_type, T)
188-
}
170+
189171
//-----------------------------------------------------
190172
/// @brief implicit conversion of angles is allowed
191173
/// @details may cause numerical drift when performed repeatedly
192174
template<class T>
193175
constexpr
194176
angle(const angle<T>& a):
195177
v_{a.template as<turn_type>()}
196-
{
197-
AM_CHECK_NARROWING(numeric_type, typename T::type)
198-
}
178+
{}
199179

200180
//-----------------------------------------------------
201181
angle(const angle&) = default;
@@ -205,8 +185,6 @@ class angle
205185
angle&
206186
operator = (const angle<T>& a)
207187
{
208-
AM_CHECK_NARROWING(numeric_type, typename T::type)
209-
210188
v_ = a.template as<turn_type>();
211189
return *this;
212190
}
@@ -230,44 +208,30 @@ class angle
230208
//---------------------------------------------------------------
231209
// ASSIGNING ARITHMETIC OPERATIONS
232210
//---------------------------------------------------------------
233-
template<class T>
234211
angle&
235-
operator += (const angle<T>& a)
212+
operator += (const angle& a)
236213
{
237-
AM_CHECK_NARROWING(numeric_type, typename T::type)
238-
239-
v_ += a.template as<turn_type>();
214+
v_ += a.v_;
240215
return *this;
241216
}
242217
//-----------------------------------------------------
243-
template<class T>
244218
angle&
245-
operator -= (const angle<T>& a)
219+
operator -= (const angle& a)
246220
{
247-
AM_CHECK_NARROWING(numeric_type, typename T::type)
248-
249-
v_ -= a.template as<turn_type>();
221+
v_ -= a.v_;
250222
return *this;
251223
}
252224
//-----------------------------------------------------
253-
template<class T, class = typename std::enable_if<
254-
is_number<T>::value && !is_angle<T>::value>::type>
255225
angle&
256-
operator *= (const T& factor)
226+
operator *= (const numeric_type& factor)
257227
{
258-
AM_CHECK_NARROWING(numeric_type, T)
259-
260228
v_ *= factor;
261229
return *this;
262230
}
263231
//-----------------------------------------------------
264-
template<class T, class = typename std::enable_if<
265-
is_number<T>::value && !is_angle<T>::value>::type>
266232
angle&
267-
operator /= (const T& factor)
233+
operator /= (const numeric_type& factor)
268234
{
269-
AM_CHECK_NARROWING(numeric_type, T)
270-
271235
v_ /= factor;
272236
return *this;
273237
}
@@ -276,42 +240,34 @@ class angle
276240
//---------------------------------------------------------------
277241
// ARITHMETIC OPERATIONS
278242
//---------------------------------------------------------------
279-
template<class T>
280243
constexpr angle
281-
operator + (const angle<T>& a) const
244+
operator + (const angle& a) const
282245
{
283-
return angle{v_ + a.template as<turn_type>()};
246+
return angle{v_ + a.v_};
284247
}
285248
//-----------------------------------------------------
286-
template<class T>
287249
constexpr angle
288-
operator - (const angle<T>& a) const
250+
operator - (const angle& a) const
289251
{
290-
return angle{v_ - a.template as<turn_type>()};
252+
return angle{v_ - a.v_};
291253
}
292254
//-----------------------------------------------------
293-
template<class T, class = typename std::enable_if<
294-
is_number<decay_t<T>>::value && !is_angle<decay_t<T>>::value>::type>
295255
constexpr angle
296-
operator * (const T& factor) const
256+
operator * (const numeric_type& factor) const
297257
{
298258
return angle{v_ * factor};
299259
}
300260
//-----------------------------------------------------
301-
template<class T, class = typename std::enable_if<
302-
is_number<decay_t<T>>::value && !is_angle<decay_t<T>>::value>::type>
303261
constexpr angle
304-
operator / (const T& factor) const
262+
operator / (const numeric_type& factor) const
305263
{
306264
return angle{v_ / factor};
307265
}
308266

309267
//-----------------------------------------------------
310268
/// @brief pre-multiplication
311-
template<class T, class = typename std::enable_if<
312-
is_number<decay_t<T>>::value && !is_angle<decay_t<T>>::value>::type>
313269
inline friend constexpr angle
314-
operator * (const T& factor, const angle& a)
270+
operator * (const numeric_type& factor, const angle& a)
315271
{
316272
return angle{factor * a.v_};
317273
}
@@ -321,7 +277,7 @@ class angle
321277
// inversion (works only on signed domains)
322278
//---------------------------------------------------------------
323279
template<class T = numeric_type, class = typename std::enable_if<
324-
!std::is_unsigned<T>::value && !is_angle<decay_t<T>>::value>::type>
280+
!std::is_unsigned<T>::value && !is_angle<std::decay_t<T>>::value>::type>
325281
constexpr angle
326282
operator - () const {
327283
return angle{-v_};
@@ -363,37 +319,37 @@ class angle
363319
//---------------------------------------------------------------
364320
template<class T>
365321
constexpr bool
366-
operator == (const angle<T>& other) const {
322+
operator == (const angle<T>& other) const noexcept {
367323
return (v_ == other.template as<turn_type>());
368324
}
369325
//-----------------------------------------------------
370326
template<class T>
371327
constexpr bool
372-
operator != (const angle<T>& other) const {
328+
operator != (const angle<T>& other) const noexcept {
373329
return (v_ != other.template as<turn_type>());
374330
}
375331
//-----------------------------------------------------
376332
template<class T>
377333
constexpr bool
378-
operator < (const angle<T>& other) const {
334+
operator < (const angle<T>& other) const noexcept {
379335
return (v_ < other.template as<turn_type>());
380336
}
381337
//-----------------------------------------------------
382338
template<class T>
383339
constexpr bool
384-
operator > (const angle<T>& other) const {
340+
operator > (const angle<T>& other) const noexcept {
385341
return (v_ > other.template as<turn_type>());
386342
}
387343
//-----------------------------------------------------
388344
template<class T>
389345
constexpr bool
390-
operator <= (const angle<T>& other) const {
346+
operator <= (const angle<T>& other) const noexcept {
391347
return (v_ <= other.template as<turn_type>());
392348
}
393349
//-----------------------------------------------------
394350
template<class T>
395351
constexpr bool
396-
operator >= (const angle<T>& other) const {
352+
operator >= (const angle<T>& other) const noexcept {
397353
return (v_ >= other.template as<turn_type>());
398354
}
399355

@@ -492,8 +448,8 @@ class angle
492448
std::enable_if<!std::is_same<turn_type,OutTurn>::value>::type>
493449
constexpr conversion_t<OutTurn>
494450
as() const noexcept {
495-
using res_t = conversion_t<OutTurn>;
496-
return ( (res_t(OutTurn::value) / res_t(turn())) * res_t(v_));
451+
using T = conversion_t<OutTurn>;
452+
return ( (T(OutTurn::value) / T(turn())) * T(v_));
497453
}
498454

499455

@@ -661,11 +617,11 @@ constexpr radians<real_t> operator"" _rad (unsigned long long int x) {
661617
}
662618
//---------------------------------------------------------
663619
constexpr radians<real_t> operator"" _pi_rad(long double x) {
664-
return radians<real_t>{real_t(x * pi)};
620+
return radians<real_t>{real_t(x) * pi<real_t>};
665621
}
666622
//---------------------------------------------------------
667623
constexpr radians<real_t> operator"" _pi_rad(unsigned long long int x) {
668-
return radians<real_t>{real_t(x * pi)};
624+
return radians<real_t>{real_t(x) * pi<real_t>};
669625
}
670626

671627

@@ -713,18 +669,18 @@ template<class U1, class U2>
713669
inline common_numeric_t<typename U1::type, typename U2::type>
714670
operator / (const angle<U1>& a, const angle<U2>& b)
715671
{
716-
using res_t = common_numeric_t<typename U1::type, typename U2::type>;
672+
using T = common_numeric_t<typename U1::type, typename U2::type>;
717673

718-
return radians_cast<res_t>(a) / radians_cast<res_t>(b);
674+
return radians_cast<T>(a) / radians_cast<T>(b);
719675
}
720676
//---------------------------------------------------------
721677
template<class U>
722678
inline typename U::type
723679
operator / (const angle<U>& a, const angle<U>& b)
724680
{
725-
using res_t = typename U::type;
681+
using T = typename U::type;
726682

727-
return radians_cast<res_t>(a) / radians_cast<res_t>(b);
683+
return radians_cast<T>(a) / radians_cast<T>(b);
728684
}
729685

730686

@@ -841,32 +797,6 @@ struct common_numeric_type<angle<T>,angle<T>>
841797

842798

843799

844-
namespace detail {
845-
846-
//-------------------------------------------------------------------
847-
template<class To, class From>
848-
struct is_non_narrowing_helper<true, angle<To>, From> :
849-
public is_non_narrowing_helper<true,typename angle<To>::numeric_type,From>
850-
{};
851-
852-
//---------------------------------------------------------
853-
template<class To, class From>
854-
struct is_non_narrowing_helper<true, angle<To>, angle<From> > :
855-
public is_non_narrowing_helper<true,
856-
typename angle<To>::numeric_type,
857-
typename angle<From>::numeric_type>
858-
{};
859-
860-
//---------------------------------------------------------
861-
template<class To, class From>
862-
struct is_non_narrowing_helper<true, To, angle<From> > :
863-
public is_non_narrowing_helper<true,To,typename angle<From>::numeric_type>
864-
{};
865-
866-
867-
} // namespace detail
868-
869-
870800

871801
/*****************************************************************************
872802
*
@@ -1115,8 +1045,6 @@ rad_atanh(T a)
11151045
template<class Turn, class ValueDistr>
11161046
class angle_distribution
11171047
{
1118-
AM_CHECK_NARROWING(typename Turn::type,typename ValueDistr::result_type)
1119-
11201048
public:
11211049
using param_type = typename ValueDistr::param_type;
11221050
using numeric_type = typename ValueDistr::result_type;

0 commit comments

Comments
 (0)