Skip to content

Commit ff6df8e

Browse files
committed
[Ref] mpt/base/saturate_round.hpp: Add full set of _trunc, _round, _ceil, _floor variants.
[Ref] mpt/base/saturate_round.hpp: Template on floating point type. git-svn-id: https://source.openmpt.org/svn/openmpt/trunk/OpenMPT@22568 56274372-70c3-4bfc-bfc3-4c3a0b034d27
1 parent c9af477 commit ff6df8e

File tree

3 files changed

+55
-29
lines changed

3 files changed

+55
-29
lines changed

soundlib/SampleFormats.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,11 +1618,11 @@ bool CSoundFile::ReadCAFSample(SAMPLEINDEX nSample, FileReader &file, bool mayNo
16181618
return false;
16191619
}
16201620

1621-
if(!mpt::in_range<uint32>(mpt::saturate_round<int64>(audioFormat.mSampleRate)))
1621+
if(!mpt::in_range<uint32>(mpt::saturate_round<int64>(audioFormat.mSampleRate.get())))
16221622
{
16231623
return false;
16241624
}
1625-
uint32 sampleRate = static_cast<uint32>(mpt::saturate_round<int64>(audioFormat.mSampleRate));
1625+
uint32 sampleRate = static_cast<uint32>(mpt::saturate_round<int64>(audioFormat.mSampleRate.get()));
16261626
if(sampleRate <= 0)
16271627
{
16281628
return false;

src/mpt/base/saturate_round.hpp

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
#include "mpt/base/math.hpp"
1111

1212
#include <limits>
13+
#include <type_traits>
14+
15+
#include <cmath>
1316

1417

1518

@@ -18,23 +21,13 @@ inline namespace MPT_INLINE_NS {
1821

1922

2023

21-
template <typename Tdst>
22-
constexpr Tdst saturate_trunc(double src) {
23-
if (src >= static_cast<double>(std::numeric_limits<Tdst>::max())) {
24-
return std::numeric_limits<Tdst>::max();
25-
}
26-
if (src <= static_cast<double>(std::numeric_limits<Tdst>::min())) {
27-
return std::numeric_limits<Tdst>::min();
28-
}
29-
return static_cast<Tdst>(src);
30-
}
31-
32-
template <typename Tdst>
33-
constexpr Tdst saturate_trunc(float src) {
34-
if (src >= static_cast<float>(std::numeric_limits<Tdst>::max())) {
24+
template <typename Tdst, typename Tsrc>
25+
constexpr Tdst saturate_trunc(Tsrc src) {
26+
static_assert(std::is_floating_point<Tsrc>::value);
27+
if (src >= static_cast<Tsrc>(std::numeric_limits<Tdst>::max())) {
3528
return std::numeric_limits<Tdst>::max();
3629
}
37-
if (src <= static_cast<float>(std::numeric_limits<Tdst>::min())) {
30+
if (src <= static_cast<Tsrc>(std::numeric_limits<Tdst>::min())) {
3831
return std::numeric_limits<Tdst>::min();
3932
}
4033
return static_cast<Tdst>(src);
@@ -44,22 +37,27 @@ constexpr Tdst saturate_trunc(float src) {
4437
// Rounds given double value to nearest integer value of type T.
4538
// Out-of-range values are saturated to the specified integer type's limits.
4639

47-
template <typename T>
48-
inline T saturate_round(float val) {
49-
static_assert(std::numeric_limits<T>::is_integer);
50-
return mpt::saturate_trunc<T>(mpt::round(val));
40+
template <typename Tdst, typename Tsrc>
41+
inline Tdst saturate_round(Tsrc val) {
42+
static_assert(std::is_floating_point<Tsrc>::value);
43+
static_assert(std::numeric_limits<Tdst>::is_integer);
44+
return mpt::saturate_trunc<Tdst>(mpt::round(val));
5145
}
5246

53-
template <typename T>
54-
inline T saturate_round(double val) {
55-
static_assert(std::numeric_limits<T>::is_integer);
56-
return mpt::saturate_trunc<T>(mpt::round(val));
47+
48+
template <typename Tdst, typename Tsrc>
49+
inline Tdst saturate_ceil(Tsrc val) {
50+
static_assert(std::is_floating_point<Tsrc>::value);
51+
static_assert(std::numeric_limits<Tdst>::is_integer);
52+
return mpt::saturate_trunc<Tdst>(std::ceil(val));
5753
}
5854

59-
template <typename T>
60-
inline T saturate_round(long double val) {
61-
static_assert(std::numeric_limits<T>::is_integer);
62-
return mpt::saturate_trunc<T>(mpt::round(val));
55+
56+
template <typename Tdst, typename Tsrc>
57+
inline Tdst saturate_floor(Tsrc val) {
58+
static_assert(std::is_floating_point<Tsrc>::value);
59+
static_assert(std::numeric_limits<Tdst>::is_integer);
60+
return mpt::saturate_trunc<Tdst>(std::floor(val));
6361
}
6462

6563

src/mpt/base/tests/tests_base_saturate_round.hpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,34 @@ MPT_TEST_GROUP_INLINE("mpt/base/saturate_round")
4444
MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int8>(110.1), 110);
4545
MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int8>(-110.1), -110);
4646

47+
MPT_TEST_EXPECT_EQUAL(mpt::saturate_trunc<int8>(-0.6), 0);
48+
MPT_TEST_EXPECT_EQUAL(mpt::saturate_trunc<int8>(-0.5), 0);
49+
MPT_TEST_EXPECT_EQUAL(mpt::saturate_trunc<int8>(-0.4), 0);
50+
MPT_TEST_EXPECT_EQUAL(mpt::saturate_trunc<int8>(0.4), 0);
51+
MPT_TEST_EXPECT_EQUAL(mpt::saturate_trunc<int8>(0.5), 0);
52+
MPT_TEST_EXPECT_EQUAL(mpt::saturate_trunc<int8>(0.6), 0);
53+
54+
MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int8>(-0.6), -1);
55+
MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int8>(-0.5), -1);
56+
MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int8>(-0.4), 0);
57+
MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int8>(0.4), 0);
58+
MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int8>(0.5), 1);
59+
MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int8>(0.6), 1);
60+
61+
MPT_TEST_EXPECT_EQUAL(mpt::saturate_ceil<int8>(-0.6), 0);
62+
MPT_TEST_EXPECT_EQUAL(mpt::saturate_ceil<int8>(-0.5), 0);
63+
MPT_TEST_EXPECT_EQUAL(mpt::saturate_ceil<int8>(-0.4), 0);
64+
MPT_TEST_EXPECT_EQUAL(mpt::saturate_ceil<int8>(0.4), 1);
65+
MPT_TEST_EXPECT_EQUAL(mpt::saturate_ceil<int8>(0.5), 1);
66+
MPT_TEST_EXPECT_EQUAL(mpt::saturate_ceil<int8>(0.6), 1);
67+
68+
MPT_TEST_EXPECT_EQUAL(mpt::saturate_floor<int8>(-0.6), -1);
69+
MPT_TEST_EXPECT_EQUAL(mpt::saturate_floor<int8>(-0.5), -1);
70+
MPT_TEST_EXPECT_EQUAL(mpt::saturate_floor<int8>(-0.4), -1);
71+
MPT_TEST_EXPECT_EQUAL(mpt::saturate_floor<int8>(0.4), 0);
72+
MPT_TEST_EXPECT_EQUAL(mpt::saturate_floor<int8>(0.5), 0);
73+
MPT_TEST_EXPECT_EQUAL(mpt::saturate_floor<int8>(0.6), 0);
74+
4775
// These should fail to compile
4876
//mpt::saturate_round<std::string>(1.0);
4977
//mpt::saturate_round<int64>(1.0);

0 commit comments

Comments
 (0)