Introduced user-defined literal "cs" for centiseconds

Now that ReSharper supports it (see https://youtrack.jetbrains.com/issue/RSCPP-14653)
This commit is contained in:
Daniel Wolf 2016-07-05 21:17:51 +02:00
parent 0447cbb4ff
commit ddcadad710
8 changed files with 167 additions and 161 deletions

View File

@ -37,7 +37,7 @@ std::vector<Timed<Shape>> dummyShapeIfEmpty(const Timeline<Shape>& shapes) {
std::copy(shapes.begin(), shapes.end(), std::back_inserter(result)); std::copy(shapes.begin(), shapes.end(), std::back_inserter(result));
if (result.empty()) { if (result.empty()) {
// Add zero-length empty mouth // Add zero-length empty mouth
result.push_back(Timed<Shape>(centiseconds(0), centiseconds(0), Shape::A)); result.push_back(Timed<Shape>(0cs, 0cs, Shape::A));
} }
return result; return result;
} }

View File

@ -1,7 +1,7 @@
#include "AudioStream.h" #include "AudioStream.h"
TimeRange AudioStream::getTruncatedRange() const { TimeRange AudioStream::getTruncatedRange() const {
return TimeRange(centiseconds::zero(), centiseconds(100 * getSampleCount() / getSampleRate())); return TimeRange(0cs, centiseconds(100 * getSampleCount() / getSampleRate()));
} }
bool AudioStream::endOfStream() const { bool AudioStream::endOfStream() const {

View File

@ -31,7 +31,7 @@ BoundedTimeline<void> webRtcDetectVoiceActivity(AudioStream& audioStream, Progre
// Detect activity // Detect activity
BoundedTimeline<void> activity(audioStream.getTruncatedRange()); BoundedTimeline<void> activity(audioStream.getTruncatedRange());
centiseconds time = centiseconds::zero(); centiseconds time = 0cs;
const size_t bufferCapacity = audioStream.getSampleRate() / 100; const size_t bufferCapacity = audioStream.getSampleRate() / 100;
auto processBuffer = [&](const vector<int16_t>& buffer) { auto processBuffer = [&](const vector<int16_t>& buffer) {
// WebRTC is picky regarding buffer size // WebRTC is picky regarding buffer size
@ -42,9 +42,9 @@ BoundedTimeline<void> webRtcDetectVoiceActivity(AudioStream& audioStream, Progre
bool isActive = result != 0; bool isActive = result != 0;
if (isActive) { if (isActive) {
activity.set(time, time + centiseconds(1)); activity.set(time, time + 1cs);
} }
time += centiseconds(1); time += 1cs;
}; };
process16bitAudioStream(*audioStream.clone(true), processBuffer, bufferCapacity, progressSink); process16bitAudioStream(*audioStream.clone(true), processBuffer, bufferCapacity, progressSink);
@ -54,8 +54,8 @@ BoundedTimeline<void> webRtcDetectVoiceActivity(AudioStream& audioStream, Progre
if (!activity.empty()) { if (!activity.empty()) {
TimeRange firstActivity = activity.begin()->getTimeRange(); TimeRange firstActivity = activity.begin()->getTimeRange();
activity.clear(firstActivity); activity.clear(firstActivity);
unique_ptr<AudioStream> streamStart = createSegment(audioStream.clone(true), TimeRange(centiseconds::zero(), firstActivity.getEnd())); unique_ptr<AudioStream> streamStart = createSegment(audioStream.clone(true), TimeRange(0cs, firstActivity.getEnd()));
time = centiseconds::zero(); time = 0cs;
process16bitAudioStream(*streamStart, processBuffer, bufferCapacity, progressSink); process16bitAudioStream(*streamStart, processBuffer, bufferCapacity, progressSink);
} }

View File

@ -1,8 +1,17 @@
#pragma once #pragma once
#include <chrono> #include <chrono>
#include <ostream>
typedef std::chrono::duration<int, std::centi> centiseconds; typedef std::chrono::duration<int, std::centi> centiseconds;
std::ostream& operator <<(std::ostream& stream, const centiseconds cs); std::ostream& operator <<(std::ostream& stream, const centiseconds cs);
// I know user-defined literals should start with an underscore.
// But chances are slim the standard will introduce a "cs" literal
// with a different meaning than "centiseconds".
#pragma warning(push)
#pragma warning(disable: 4455)
inline constexpr centiseconds operator ""cs(unsigned long long cs) {
return centiseconds(cs);
}
#pragma warning(pop)

View File

@ -13,13 +13,13 @@ using boost::optional;
using AnimationResult = Timeline<Shape>; using AnimationResult = Timeline<Shape>;
AnimationResult animateFixedSound(Shape shape, centiseconds duration) { AnimationResult animateFixedSound(Shape shape, centiseconds duration) {
return AnimationResult{ {centiseconds::zero(), duration, shape} }; return AnimationResult{ {0cs, duration, shape} };
} }
// Diphtong vowels // Diphtong vowels
AnimationResult animateDiphtong(Shape first, Shape second, centiseconds duration) { AnimationResult animateDiphtong(Shape first, Shape second, centiseconds duration) {
return AnimationResult{ return AnimationResult{
{ centiseconds::zero(), duration, first }, { 0cs, duration, first },
{ duration / 2, duration, second } { duration / 2, duration, second }
}; };
} }
@ -32,12 +32,12 @@ AnimationResult animateBilabialStop(centiseconds duration, centiseconds leftPhon
} }
centiseconds closedShapeDuration = leftPhoneDuration / 2; centiseconds closedShapeDuration = leftPhoneDuration / 2;
if (closedShapeDuration.count() < 4) closedShapeDuration = centiseconds(4); if (closedShapeDuration.count() < 4) closedShapeDuration = 4cs;
if (closedShapeDuration.count() > 16) closedShapeDuration = centiseconds(16); if (closedShapeDuration.count() > 16) closedShapeDuration = 16cs;
return AnimationResult{ return AnimationResult{
{ -closedShapeDuration, centiseconds::zero(), Shape::A }, { -closedShapeDuration, 0cs, Shape::A },
{ centiseconds::zero(), duration, openShape } { 0cs, duration, openShape }
}; };
} }
@ -49,7 +49,7 @@ AnimationResult animateFlexibleSound(std::array<Shape, 7> mapping, centiseconds
Shape right = rightShape.value_or(Shape::A); Shape right = rightShape.value_or(Shape::A);
Shape shape = mapping[static_cast<int>(right)]; Shape shape = mapping[static_cast<int>(right)];
return AnimationResult{ { centiseconds::zero(), duration, shape } }; return AnimationResult{ { 0cs, duration, shape } };
} }
AnimationResult animate(optional<Phone> phone, centiseconds duration, centiseconds leftPhoneDuration, optional<Shape> rightShape) { AnimationResult animate(optional<Phone> phone, centiseconds duration, centiseconds leftPhoneDuration, optional<Shape> rightShape) {
@ -130,7 +130,7 @@ ContinuousTimeline<Shape> animate(const BoundedTimeline<Phone> &phones) {
bool hasLeftPhone = std::next(it) != continuousPhones.rend() && std::next(it)->getEnd() == it->getStart(); bool hasLeftPhone = std::next(it) != continuousPhones.rend() && std::next(it)->getEnd() == it->getStart();
centiseconds leftPhoneDuration = hasLeftPhone centiseconds leftPhoneDuration = hasLeftPhone
? std::next(it)->getTimeRange().getLength() ? std::next(it)->getTimeRange().getLength()
: centiseconds::zero(); : 0cs;
Timeline<Shape> result = animate(phone, duration, leftPhoneDuration, lastShape); Timeline<Shape> result = animate(phone, duration, leftPhoneDuration, lastShape);
// Result timing is relative to phone. Make absolute. // Result timing is relative to phone. Make absolute.

View File

@ -2,22 +2,21 @@
#include "BoundedTimeline.h" #include "BoundedTimeline.h"
using namespace testing; using namespace testing;
using cs = centiseconds;
using std::vector; using std::vector;
using boost::optional; using boost::optional;
using std::initializer_list; using std::initializer_list;
TEST(BoundedTimeline, constructors_initializeState) { TEST(BoundedTimeline, constructors_initializeState) {
TimeRange range(cs(-5), cs(55)); TimeRange range(-5cs, 55cs);
auto args = { auto args = {
Timed<int>(cs(-10), cs(30), 1), Timed<int>(-10cs, 30cs, 1),
Timed<int>(cs(10), cs(40), 2), Timed<int>(10cs, 40cs, 2),
Timed<int>(cs(50), cs(60), 3) Timed<int>(50cs, 60cs, 3)
}; };
auto expected = { auto expected = {
Timed<int>(cs(-5), cs(10), 1), Timed<int>(-5cs, 10cs, 1),
Timed<int>(cs(10), cs(40), 2), Timed<int>(10cs, 40cs, 2),
Timed<int>(cs(50), cs(55), 3) Timed<int>(50cs, 55cs, 3)
}; };
EXPECT_THAT( EXPECT_THAT(
BoundedTimeline<int>(range, args.begin(), args.end()), BoundedTimeline<int>(range, args.begin(), args.end()),
@ -30,67 +29,67 @@ TEST(BoundedTimeline, constructors_initializeState) {
} }
TEST(BoundedTimeline, empty) { TEST(BoundedTimeline, empty) {
BoundedTimeline<int> empty(TimeRange(cs(0), cs(10))); BoundedTimeline<int> empty(TimeRange(0cs, 10cs));
EXPECT_TRUE(empty.empty()); EXPECT_TRUE(empty.empty());
EXPECT_THAT(empty, IsEmpty()); EXPECT_THAT(empty, IsEmpty());
BoundedTimeline<int> nonEmpty(TimeRange(cs(0), cs(10)), { Timed<int>(cs(1), cs(2), 1) }); BoundedTimeline<int> nonEmpty(TimeRange(0cs, 10cs), { Timed<int>(1cs, 2cs, 1) });
EXPECT_FALSE(nonEmpty.empty()); EXPECT_FALSE(nonEmpty.empty());
EXPECT_THAT(nonEmpty, Not(IsEmpty())); EXPECT_THAT(nonEmpty, Not(IsEmpty()));
} }
TEST(BoundedTimeline, getRange) { TEST(BoundedTimeline, getRange) {
TimeRange range(cs(0), cs(10)); TimeRange range(0cs, 10cs);
BoundedTimeline<int> empty(range); BoundedTimeline<int> empty(range);
EXPECT_EQ(range, empty.getRange()); EXPECT_EQ(range, empty.getRange());
BoundedTimeline<int> nonEmpty(range, { Timed<int>(cs(1), cs(2), 1) }); BoundedTimeline<int> nonEmpty(range, { Timed<int>(1cs, 2cs, 1) });
EXPECT_EQ(range, nonEmpty.getRange()); EXPECT_EQ(range, nonEmpty.getRange());
} }
TEST(BoundedTimeline, setAndClear) { TEST(BoundedTimeline, setAndClear) {
TimeRange range(cs(0), cs(10)); TimeRange range(0cs, 10cs);
BoundedTimeline<int> timeline(range); BoundedTimeline<int> timeline(range);
// Out of range // Out of range
timeline.set(cs(-10), cs(-1), 1); timeline.set(-10cs, -1cs, 1);
timeline.set(TimeRange(cs(-5), cs(-1)), 2); timeline.set(TimeRange(-5cs, -1cs), 2);
timeline.set(Timed<int>(cs(10), cs(15), 3)); timeline.set(Timed<int>(10cs, 15cs, 3));
// Overlapping // Overlapping
timeline.set(cs(-2), cs(5), 4); timeline.set(-2cs, 5cs, 4);
timeline.set(TimeRange(cs(-1), cs(1)), 5); timeline.set(TimeRange(-1cs, 1cs), 5);
timeline.set(Timed<int>(cs(8), cs(12), 6)); timeline.set(Timed<int>(8cs, 12cs, 6));
// Within // Within
timeline.set(cs(5), cs(9), 7); timeline.set(5cs, 9cs, 7);
timeline.set(TimeRange(cs(6), cs(7)), 8); timeline.set(TimeRange(6cs, 7cs), 8);
timeline.set(Timed<int>(cs(7), cs(8), 9)); timeline.set(Timed<int>(7cs, 8cs, 9));
auto expected = { auto expected = {
Timed<int>(cs(0), cs(1), 5), Timed<int>(0cs, 1cs, 5),
Timed<int>(cs(1), cs(5), 4), Timed<int>(1cs, 5cs, 4),
Timed<int>(cs(5), cs(6), 7), Timed<int>(5cs, 6cs, 7),
Timed<int>(cs(6), cs(7), 8), Timed<int>(6cs, 7cs, 8),
Timed<int>(cs(7), cs(8), 9), Timed<int>(7cs, 8cs, 9),
Timed<int>(cs(8), cs(9), 7), Timed<int>(8cs, 9cs, 7),
Timed<int>(cs(9), cs(10), 6) Timed<int>(9cs, 10cs, 6)
}; };
EXPECT_THAT(timeline, ElementsAreArray(expected)); EXPECT_THAT(timeline, ElementsAreArray(expected));
} }
TEST(BoundedTimeline, shift) { TEST(BoundedTimeline, shift) {
BoundedTimeline<int> timeline(TimeRange(cs(0), cs(10)), { { cs(1), cs(2), 1 }, { cs(2), cs(5), 2 }, { cs(7), cs(9), 3 } }); BoundedTimeline<int> timeline(TimeRange(0cs, 10cs), { { 1cs, 2cs, 1 }, { 2cs, 5cs, 2 }, { 7cs, 9cs, 3 } });
BoundedTimeline<int> expected(TimeRange(cs(2), cs(12)), { { cs(3), cs(4), 1 }, { cs(4), cs(7), 2 }, { cs(9), cs(11), 3 } }); BoundedTimeline<int> expected(TimeRange(2cs, 12cs), { { 3cs, 4cs, 1 }, { 4cs, 7cs, 2 }, { 9cs, 11cs, 3 } });
timeline.shift(cs(2)); timeline.shift(2cs);
EXPECT_EQ(expected, timeline); EXPECT_EQ(expected, timeline);
} }
TEST(BoundedTimeline, equality) { TEST(BoundedTimeline, equality) {
vector<BoundedTimeline<int>> timelines = { vector<BoundedTimeline<int>> timelines = {
BoundedTimeline<int>(TimeRange(cs(0), cs(10))), BoundedTimeline<int>(TimeRange(0cs, 10cs)),
BoundedTimeline<int>(TimeRange(cs(0), cs(10)), { { cs(1), cs(2), 1 } }), BoundedTimeline<int>(TimeRange(0cs, 10cs), { { 1cs, 2cs, 1 } }),
BoundedTimeline<int>(TimeRange(cs(1), cs(10)), { { cs(1), cs(2), 1 } }) BoundedTimeline<int>(TimeRange(1cs, 10cs), { { 1cs, 2cs, 1 } })
}; };
for (size_t i = 0; i < timelines.size(); ++i) { for (size_t i = 0; i < timelines.size(); ++i) {

View File

@ -2,24 +2,23 @@
#include "ContinuousTimeline.h" #include "ContinuousTimeline.h"
using namespace testing; using namespace testing;
using cs = centiseconds;
using std::vector; using std::vector;
using boost::optional; using boost::optional;
using std::initializer_list; using std::initializer_list;
TEST(ContinuousTimeline, constructors_initializeState) { TEST(ContinuousTimeline, constructors_initializeState) {
TimeRange range(cs(-5), cs(55)); TimeRange range(-5cs, 55cs);
int defaultValue = -1; int defaultValue = -1;
auto args = { auto args = {
Timed<int>(cs(-10), cs(30), 1), Timed<int>(-10cs, 30cs, 1),
Timed<int>(cs(10), cs(40), 2), Timed<int>(10cs, 40cs, 2),
Timed<int>(cs(50), cs(60), 3) Timed<int>(50cs, 60cs, 3)
}; };
auto expected = { auto expected = {
Timed<int>(cs(-5), cs(10), 1), Timed<int>(-5cs, 10cs, 1),
Timed<int>(cs(10), cs(40), 2), Timed<int>(10cs, 40cs, 2),
Timed<int>(cs(40), cs(50), defaultValue), Timed<int>(40cs, 50cs, defaultValue),
Timed<int>(cs(50), cs(55), 3) Timed<int>(50cs, 55cs, 3)
}; };
EXPECT_THAT( EXPECT_THAT(
ContinuousTimeline<int>(range, defaultValue, args.begin(), args.end()), ContinuousTimeline<int>(range, defaultValue, args.begin(), args.end()),
@ -32,65 +31,65 @@ TEST(ContinuousTimeline, constructors_initializeState) {
} }
TEST(ContinuousTimeline, empty) { TEST(ContinuousTimeline, empty) {
ContinuousTimeline<int> empty(TimeRange(cs(10), cs(10)), -1); ContinuousTimeline<int> empty(TimeRange(10cs, 10cs), -1);
EXPECT_TRUE(empty.empty()); EXPECT_TRUE(empty.empty());
EXPECT_THAT(empty, IsEmpty()); EXPECT_THAT(empty, IsEmpty());
ContinuousTimeline<int> nonEmpty1(TimeRange(cs(0), cs(10)), -1); ContinuousTimeline<int> nonEmpty1(TimeRange(0cs, 10cs), -1);
EXPECT_FALSE(nonEmpty1.empty()); EXPECT_FALSE(nonEmpty1.empty());
EXPECT_THAT(nonEmpty1, Not(IsEmpty())); EXPECT_THAT(nonEmpty1, Not(IsEmpty()));
ContinuousTimeline<int> nonEmpty2(TimeRange(cs(0), cs(10)), -1, { Timed<int>(cs(1), cs(2), 1) }); ContinuousTimeline<int> nonEmpty2(TimeRange(0cs, 10cs), -1, { Timed<int>(1cs, 2cs, 1) });
EXPECT_FALSE(nonEmpty2.empty()); EXPECT_FALSE(nonEmpty2.empty());
EXPECT_THAT(nonEmpty2, Not(IsEmpty())); EXPECT_THAT(nonEmpty2, Not(IsEmpty()));
} }
TEST(ContinuousTimeline, setAndClear) { TEST(ContinuousTimeline, setAndClear) {
TimeRange range(cs(0), cs(10)); TimeRange range(0cs, 10cs);
int defaultValue = -1; int defaultValue = -1;
ContinuousTimeline<int> timeline(range, defaultValue); ContinuousTimeline<int> timeline(range, defaultValue);
// Out of range // Out of range
timeline.set(cs(-10), cs(-1), 1); timeline.set(-10cs, -1cs, 1);
timeline.set(TimeRange(cs(-5), cs(-1)), 2); timeline.set(TimeRange(-5cs, -1cs), 2);
timeline.set(Timed<int>(cs(10), cs(15), 3)); timeline.set(Timed<int>(10cs, 15cs, 3));
// Overlapping // Overlapping
timeline.set(cs(-2), cs(3), 4); timeline.set(-2cs, 3cs, 4);
timeline.set(TimeRange(cs(-1), cs(1)), 5); timeline.set(TimeRange(-1cs, 1cs), 5);
timeline.set(Timed<int>(cs(8), cs(12), 6)); timeline.set(Timed<int>(8cs, 12cs, 6));
// Within // Within
timeline.set(cs(5), cs(9), 7); timeline.set(5cs, 9cs, 7);
timeline.set(TimeRange(cs(6), cs(7)), 8); timeline.set(TimeRange(6cs, 7cs), 8);
timeline.set(Timed<int>(cs(7), cs(8), 9)); timeline.set(Timed<int>(7cs, 8cs, 9));
auto expected = { auto expected = {
Timed<int>(cs(0), cs(1), 5), Timed<int>(0cs, 1cs, 5),
Timed<int>(cs(1), cs(3), 4), Timed<int>(1cs, 3cs, 4),
Timed<int>(cs(3), cs(5), defaultValue), Timed<int>(3cs, 5cs, defaultValue),
Timed<int>(cs(5), cs(6), 7), Timed<int>(5cs, 6cs, 7),
Timed<int>(cs(6), cs(7), 8), Timed<int>(6cs, 7cs, 8),
Timed<int>(cs(7), cs(8), 9), Timed<int>(7cs, 8cs, 9),
Timed<int>(cs(8), cs(9), 7), Timed<int>(8cs, 9cs, 7),
Timed<int>(cs(9), cs(10), 6) Timed<int>(9cs, 10cs, 6)
}; };
EXPECT_THAT(timeline, ElementsAreArray(expected)); EXPECT_THAT(timeline, ElementsAreArray(expected));
} }
TEST(ContinuousTimeline, shift) { TEST(ContinuousTimeline, shift) {
ContinuousTimeline<int> timeline(TimeRange(cs(0), cs(10)), -1, { { cs(1), cs(2), 1 },{ cs(2), cs(5), 2 },{ cs(7), cs(9), 3 } }); ContinuousTimeline<int> timeline(TimeRange(0cs, 10cs), -1, { { 1cs, 2cs, 1 },{ 2cs, 5cs, 2 },{ 7cs, 9cs, 3 } });
ContinuousTimeline<int> expected(TimeRange(cs(2), cs(12)), -1, { { cs(3), cs(4), 1 },{ cs(4), cs(7), 2 },{ cs(9), cs(11), 3 } }); ContinuousTimeline<int> expected(TimeRange(2cs, 12cs), -1, { { 3cs, 4cs, 1 },{ 4cs, 7cs, 2 },{ 9cs, 11cs, 3 } });
timeline.shift(cs(2)); timeline.shift(2cs);
EXPECT_EQ(expected, timeline); EXPECT_EQ(expected, timeline);
} }
TEST(ContinuousTimeline, equality) { TEST(ContinuousTimeline, equality) {
vector<ContinuousTimeline<int>> timelines = { vector<ContinuousTimeline<int>> timelines = {
ContinuousTimeline<int>(TimeRange(cs(0), cs(10)), -1), ContinuousTimeline<int>(TimeRange(0cs, 10cs), -1),
ContinuousTimeline<int>(TimeRange(cs(0), cs(10)), 1), ContinuousTimeline<int>(TimeRange(0cs, 10cs), 1),
ContinuousTimeline<int>(TimeRange(cs(0), cs(10)), -1, { { cs(1), cs(2), 1 } }), ContinuousTimeline<int>(TimeRange(0cs, 10cs), -1, { { 1cs, 2cs, 1 } }),
ContinuousTimeline<int>(TimeRange(cs(1), cs(10)), -1, { { cs(1), cs(2), 1 } }) ContinuousTimeline<int>(TimeRange(1cs, 10cs), -1, { { 1cs, 2cs, 1 } })
}; };
for (size_t i = 0; i < timelines.size(); ++i) { for (size_t i = 0; i < timelines.size(); ++i) {

View File

@ -4,7 +4,6 @@
#include <functional> #include <functional>
using namespace testing; using namespace testing;
using cs = centiseconds;
using std::vector; using std::vector;
using boost::optional; using boost::optional;
using std::initializer_list; using std::initializer_list;
@ -12,14 +11,14 @@ using boost::none;
TEST(Timeline, constructors_initializeState) { TEST(Timeline, constructors_initializeState) {
auto args = { auto args = {
Timed<int>(cs(-10), cs(30), 1), Timed<int>(-10cs, 30cs, 1),
Timed<int>(cs(10), cs(40), 2), Timed<int>(10cs, 40cs, 2),
Timed<int>(cs(50), cs(60), 3) Timed<int>(50cs, 60cs, 3)
}; };
auto expected = { auto expected = {
Timed<int>(cs(-10), cs(10), 1), Timed<int>(-10cs, 10cs, 1),
Timed<int>(cs(10), cs(40), 2), Timed<int>(10cs, 40cs, 2),
Timed<int>(cs(50), cs(60), 3) Timed<int>(50cs, 60cs, 3)
}; };
EXPECT_THAT( EXPECT_THAT(
Timeline<int>(args.begin(), args.end()), Timeline<int>(args.begin(), args.end()),
@ -40,11 +39,11 @@ TEST(Timeline, empty) {
EXPECT_TRUE(empty1.empty()); EXPECT_TRUE(empty1.empty());
EXPECT_THAT(empty1, IsEmpty()); EXPECT_THAT(empty1, IsEmpty());
Timeline<int> empty2{ Timed<int>(cs(1), cs(1), 1) }; Timeline<int> empty2{ Timed<int>(1cs, 1cs, 1) };
EXPECT_TRUE(empty2.empty()); EXPECT_TRUE(empty2.empty());
EXPECT_THAT(empty2, IsEmpty()); EXPECT_THAT(empty2, IsEmpty());
Timeline<int> nonEmpty{ Timed<int>(cs(1), cs(2), 1) }; Timeline<int> nonEmpty{ Timed<int>(1cs, 2cs, 1) };
EXPECT_FALSE(nonEmpty.empty()); EXPECT_FALSE(nonEmpty.empty());
EXPECT_THAT(nonEmpty, Not(IsEmpty())); EXPECT_THAT(nonEmpty, Not(IsEmpty()));
} }
@ -58,39 +57,39 @@ TEST(Timeline, size) {
EXPECT_EQ(0, empty1.size()); EXPECT_EQ(0, empty1.size());
EXPECT_THAT(empty1, SizeIs(0)); EXPECT_THAT(empty1, SizeIs(0));
Timeline<int> empty2{ Timed<int>(cs(1), cs(1), 1) }; Timeline<int> empty2{ Timed<int>(1cs, 1cs, 1) };
EXPECT_EQ(0, empty2.size()); EXPECT_EQ(0, empty2.size());
EXPECT_THAT(empty2, SizeIs(0)); EXPECT_THAT(empty2, SizeIs(0));
Timeline<int> size1{ Timed<int>(cs(1), cs(10), 1) }; Timeline<int> size1{ Timed<int>(1cs, 10cs, 1) };
EXPECT_EQ(1, size1.size()); EXPECT_EQ(1, size1.size());
EXPECT_THAT(size1, SizeIs(1)); EXPECT_THAT(size1, SizeIs(1));
Timeline<int> size2{ Timed<int>(cs(-10), cs(10), 1), Timed<int>(cs(10), cs(11), 5) }; Timeline<int> size2{ Timed<int>(-10cs, 10cs, 1), Timed<int>(10cs, 11cs, 5) };
EXPECT_EQ(2, size2.size()); EXPECT_EQ(2, size2.size());
EXPECT_THAT(size2, SizeIs(2)); EXPECT_THAT(size2, SizeIs(2));
} }
TEST(Timeline, getRange) { TEST(Timeline, getRange) {
Timeline<int> empty0; Timeline<int> empty0;
EXPECT_EQ(TimeRange(cs(0), cs(0)), empty0.getRange()); EXPECT_EQ(TimeRange(0cs, 0cs), empty0.getRange());
Timeline<int> empty1{}; Timeline<int> empty1{};
EXPECT_EQ(TimeRange(cs(0), cs(0)), empty1.getRange()); EXPECT_EQ(TimeRange(0cs, 0cs), empty1.getRange());
Timeline<int> empty2{ Timed<int>(cs(1), cs(1), 1) }; Timeline<int> empty2{ Timed<int>(1cs, 1cs, 1) };
EXPECT_EQ(TimeRange(cs(0), cs(0)), empty2.getRange()); EXPECT_EQ(TimeRange(0cs, 0cs), empty2.getRange());
Timeline<int> nonEmpty1{ Timed<int>(cs(1), cs(10), 1) }; Timeline<int> nonEmpty1{ Timed<int>(1cs, 10cs, 1) };
EXPECT_EQ(TimeRange(cs(1), cs(10)), nonEmpty1.getRange()); EXPECT_EQ(TimeRange(1cs, 10cs), nonEmpty1.getRange());
Timeline<int> nonEmpty2{ Timed<int>(cs(-10), cs(5), 1), Timed<int>(cs(10), cs(11), 5) }; Timeline<int> nonEmpty2{ Timed<int>(-10cs, 5cs, 1), Timed<int>(10cs, 11cs, 5) };
EXPECT_EQ(TimeRange(cs(-10), cs(11)), nonEmpty2.getRange()); EXPECT_EQ(TimeRange(-10cs, 11cs), nonEmpty2.getRange());
} }
TEST(Timeline, iterators) { TEST(Timeline, iterators) {
Timeline<int> timeline{ Timed<int>(cs(-5), cs(0), 10), Timed<int>(cs(5), cs(15), 9) }; Timeline<int> timeline{ Timed<int>(-5cs, 0cs, 10), Timed<int>(5cs, 15cs, 9) };
auto expected = { Timed<int>(cs(-5), cs(0), 10), Timed<int>(cs(5), cs(15), 9) }; auto expected = { Timed<int>(-5cs, 0cs, 10), Timed<int>(5cs, 15cs, 9) };
EXPECT_THAT(timeline, ElementsAreArray(expected)); EXPECT_THAT(timeline, ElementsAreArray(expected));
vector<Timed<int>> reversedActual; vector<Timed<int>> reversedActual;
@ -103,7 +102,7 @@ TEST(Timeline, iterators) {
void testFind(const Timeline<int>& timeline, FindMode findMode, const initializer_list<Timed<int>*> expectedResults) { void testFind(const Timeline<int>& timeline, FindMode findMode, const initializer_list<Timed<int>*> expectedResults) {
int i = -1; int i = -1;
for (Timed<int>* expectedResult : expectedResults) { for (Timed<int>* expectedResult : expectedResults) {
auto it = timeline.find(cs(++i), findMode); auto it = timeline.find(centiseconds(++i), findMode);
if (expectedResult != nullptr) { if (expectedResult != nullptr) {
EXPECT_NE(it, timeline.end()) << "Timeline: " << timeline << "; findMode: " << static_cast<int>(findMode) << "; i: " << i; EXPECT_NE(it, timeline.end()) << "Timeline: " << timeline << "; findMode: " << static_cast<int>(findMode) << "; i: " << i;
if (it != timeline.end()) { if (it != timeline.end()) {
@ -116,9 +115,9 @@ void testFind(const Timeline<int>& timeline, FindMode findMode, const initialize
} }
TEST(Timeline, find) { TEST(Timeline, find) {
Timed<int> a = Timed<int>(cs(1), cs(2), 1); Timed<int> a = Timed<int>(1cs, 2cs, 1);
Timed<int> b = Timed<int>(cs(2), cs(5), 2); Timed<int> b = Timed<int>(2cs, 5cs, 2);
Timed<int> c = Timed<int>(cs(7), cs(9), 3); Timed<int> c = Timed<int>(7cs, 9cs, 3);
Timeline<int> timeline{ a, b, c }; Timeline<int> timeline{ a, b, c };
testFind(timeline, FindMode::SampleLeft, { nullptr, nullptr, &a, &b, &b, &b, nullptr, nullptr, &c, &c, nullptr }); testFind(timeline, FindMode::SampleLeft, { nullptr, nullptr, &a, &b, &b, &b, nullptr, nullptr, &c, &c, nullptr });
@ -128,15 +127,15 @@ TEST(Timeline, find) {
} }
TEST(Timeline, get) { TEST(Timeline, get) {
Timed<int> a = Timed<int>(cs(1), cs(2), 1); Timed<int> a = Timed<int>(1cs, 2cs, 1);
Timed<int> b = Timed<int>(cs(2), cs(5), 2); Timed<int> b = Timed<int>(2cs, 5cs, 2);
Timed<int> c = Timed<int>(cs(7), cs(9), 3); Timed<int> c = Timed<int>(7cs, 9cs, 3);
Timeline<int> timeline{ a, b, c }; Timeline<int> timeline{ a, b, c };
initializer_list<Timed<int>*> expectedResults = { nullptr, &a, &b, &b, &b, nullptr, nullptr, &c, &c, nullptr, nullptr }; initializer_list<Timed<int>*> expectedResults = { nullptr, &a, &b, &b, &b, nullptr, nullptr, &c, &c, nullptr, nullptr };
int i = -1; int i = -1;
for (Timed<int>* expectedResult : expectedResults) { for (Timed<int>* expectedResult : expectedResults) {
optional<const Timed<int>&> value = timeline.get(cs(++i)); optional<const Timed<int>&> value = timeline.get(centiseconds(++i));
if (expectedResult != nullptr) { if (expectedResult != nullptr) {
EXPECT_TRUE(value) << "i: " << i; EXPECT_TRUE(value) << "i: " << i;
if (value) { if (value) {
@ -149,39 +148,39 @@ TEST(Timeline, get) {
} }
TEST(Timeline, clear) { TEST(Timeline, clear) {
Timeline<int> original{ { cs(1), cs(2), 1 }, { cs(2), cs(5), 2 }, { cs(7), cs(9), 3 } }; Timeline<int> original{ { 1cs, 2cs, 1 }, { 2cs, 5cs, 2 }, { 7cs, 9cs, 3 } };
{ {
auto timeline = original; auto timeline = original;
timeline.clear(cs(-10), cs(10)); timeline.clear(-10cs, 10cs);
EXPECT_THAT(timeline, IsEmpty()); EXPECT_THAT(timeline, IsEmpty());
} }
{ {
auto timeline = original; auto timeline = original;
timeline.clear(cs(1), cs(2)); timeline.clear(1cs, 2cs);
Timeline<int> expected{ { cs(2), cs(5), 2 }, { cs(7), cs(9), 3 } }; Timeline<int> expected{ { 2cs, 5cs, 2 }, { 7cs, 9cs, 3 } };
EXPECT_EQ(expected, timeline); EXPECT_EQ(expected, timeline);
} }
{ {
auto timeline = original; auto timeline = original;
timeline.clear(cs(3), cs(4)); timeline.clear(3cs, 4cs);
Timeline<int> expected{ { cs(1), cs(2), 1 }, { cs(2), cs(3), 2 }, { cs(4), cs(5), 2}, { cs(7), cs(9), 3} }; Timeline<int> expected{ { 1cs, 2cs, 1 }, { 2cs, 3cs, 2 }, { 4cs, 5cs, 2}, { 7cs, 9cs, 3} };
EXPECT_EQ(expected, timeline); EXPECT_EQ(expected, timeline);
} }
{ {
auto timeline = original; auto timeline = original;
timeline.clear(cs(6), cs(8)); timeline.clear(6cs, 8cs);
Timeline<int> expected{ { cs(1), cs(2), 1 }, { cs(2), cs(5), 2 }, { cs(8), cs(9), 3 } }; Timeline<int> expected{ { 1cs, 2cs, 1 }, { 2cs, 5cs, 2 }, { 8cs, 9cs, 3 } };
EXPECT_EQ(expected, timeline); EXPECT_EQ(expected, timeline);
} }
{ {
auto timeline = original; auto timeline = original;
timeline.clear(cs(8), cs(10)); timeline.clear(8cs, 10cs);
Timeline<int> expected{ { cs(1), cs(2), 1 }, { cs(2), cs(5), 2 }, { cs(7), cs(8), 3 } }; Timeline<int> expected{ { 1cs, 2cs, 1 }, { 2cs, 5cs, 2 }, { 7cs, 8cs, 3 } };
EXPECT_EQ(expected, timeline); EXPECT_EQ(expected, timeline);
} }
} }
@ -190,23 +189,23 @@ void testSetter(std::function<void(const Timed<int>&, Timeline<int>&)> set) {
Timeline<int> timeline; Timeline<int> timeline;
vector<optional<int>> expectedValues(20, none); vector<optional<int>> expectedValues(20, none);
auto newElements = { auto newElements = {
Timed<int>(cs(1), cs(2), 4), Timed<int>(1cs, 2cs, 4),
Timed<int>(cs(3), cs(6), 4), Timed<int>(3cs, 6cs, 4),
Timed<int>(cs(7), cs(9), 5), Timed<int>(7cs, 9cs, 5),
Timed<int>(cs(9), cs(10), 6), Timed<int>(9cs, 10cs, 6),
Timed<int>(cs(2), cs(3), 4), Timed<int>(2cs, 3cs, 4),
Timed<int>(cs(0), cs(1), 7), Timed<int>(0cs, 1cs, 7),
Timed<int>(cs(-10), cs(1), 8), Timed<int>(-10cs, 1cs, 8),
Timed<int>(cs(-10), cs(0), 9), Timed<int>(-10cs, 0cs, 9),
Timed<int>(cs(-10), cs(-1), 10), Timed<int>(-10cs, -1cs, 10),
Timed<int>(cs(9), cs(20), 11), Timed<int>(9cs, 20cs, 11),
Timed<int>(cs(10), cs(20), 12), Timed<int>(10cs, 20cs, 12),
Timed<int>(cs(11), cs(20), 13), Timed<int>(11cs, 20cs, 13),
Timed<int>(cs(4), cs(6), 14), Timed<int>(4cs, 6cs, 14),
Timed<int>(cs(4), cs(6), 15), Timed<int>(4cs, 6cs, 15),
Timed<int>(cs(8), cs(10), 15), Timed<int>(8cs, 10cs, 15),
Timed<int>(cs(6), cs(8), 15), Timed<int>(6cs, 8cs, 15),
Timed<int>(cs(6), cs(8), 16) Timed<int>(6cs, 8cs, 16)
}; };
int newElementIndex = -1; int newElementIndex = -1;
for (const auto& newElement : newElements) { for (const auto& newElement : newElements) {
@ -215,23 +214,23 @@ void testSetter(std::function<void(const Timed<int>&, Timeline<int>&)> set) {
set(newElement, timeline); set(newElement, timeline);
// Update expected value for every index // Update expected value for every index
cs elementStart = max(newElement.getStart(), cs(0)); centiseconds elementStart = max(newElement.getStart(), 0cs);
cs elementEnd = newElement.getEnd(); centiseconds elementEnd = newElement.getEnd();
for (cs t = elementStart; t < elementEnd; ++t) { for (centiseconds t = elementStart; t < elementEnd; ++t) {
expectedValues[t.count()] = newElement.getValue(); expectedValues[t.count()] = newElement.getValue();
} }
// Check timeline via indexer // Check timeline via indexer
for (cs t = cs(0); t < cs(10); ++t) { for (centiseconds t = 0cs; t < 10cs; ++t) {
optional<const int&> actual = timeline[t]; optional<const int&> actual = timeline[t];
EXPECT_EQ(expectedValues[t.count()], actual ? optional<int>(*actual) : none); EXPECT_EQ(expectedValues[t.count()], actual ? optional<int>(*actual) : none);
} }
// Check timeline via iterators // Check timeline via iterators
Timed<int> lastElement(cs::min(), cs::min(), std::numeric_limits<int>::min()); Timed<int> lastElement(centiseconds::min(), centiseconds::min(), std::numeric_limits<int>::min());
for (const auto& element : timeline) { for (const auto& element : timeline) {
// No element shound have zero-length // No element shound have zero-length
EXPECT_LT(cs(0), element.getTimeRange().getLength()); EXPECT_LT(0cs, element.getTimeRange().getLength());
// No two adjacent elements should have the same value; they should have been merged // No two adjacent elements should have the same value; they should have been merged
if (element.getStart() == lastElement.getEnd()) { if (element.getStart() == lastElement.getEnd()) {
@ -240,7 +239,7 @@ void testSetter(std::function<void(const Timed<int>&, Timeline<int>&)> set) {
lastElement = element; lastElement = element;
// Element should match expected values // Element should match expected values
for (cs t = std::max(cs::zero(), element.getStart()); t < element.getEnd(); ++t) { for (centiseconds t = std::max(centiseconds::zero(), element.getStart()); t < element.getEnd(); ++t) {
optional<int> expectedValue = expectedValues[t.count()]; optional<int> expectedValue = expectedValues[t.count()];
EXPECT_TRUE(expectedValue) << "Index " << t.count() << " should not have a value, but is within element " << element << ". " EXPECT_TRUE(expectedValue) << "Index " << t.count() << " should not have a value, but is within element " << element << ". "
<< "newElementIndex: " << newElementIndex; << "newElementIndex: " << newElementIndex;
@ -265,9 +264,9 @@ TEST(Timeline, set) {
} }
TEST(Timeline, indexer_get) { TEST(Timeline, indexer_get) {
Timeline<int> timeline{ { cs(1), cs(2), 1 }, { cs(2), cs(4), 2 }, { cs(6), cs(9), 3 } }; Timeline<int> timeline{ { 1cs, 2cs, 1 }, { 2cs, 4cs, 2 }, { 6cs, 9cs, 3 } };
vector<optional<int>> expectedValues{ none, 1, 2, 2, none, none, 3, 3, 3 }; vector<optional<int>> expectedValues{ none, 1, 2, 2, none, none, 3, 3, 3 };
for (cs t = cs(0); t < cs(9); ++t) { for (centiseconds t = 0cs; t < 9cs; ++t) {
{ {
optional<const int&> actual = timeline[t]; optional<const int&> actual = timeline[t];
EXPECT_EQ(expectedValues[t.count()], actual ? optional<int>(*actual) : none); EXPECT_EQ(expectedValues[t.count()], actual ? optional<int>(*actual) : none);
@ -291,25 +290,25 @@ TEST(Timeline, indexer_get) {
TEST(Timeline, indexer_set) { TEST(Timeline, indexer_set) {
testSetter([](const Timed<int>& element, Timeline<int>& timeline) { testSetter([](const Timed<int>& element, Timeline<int>& timeline) {
for (cs t = element.getStart(); t < element.getEnd(); ++t) { for (centiseconds t = element.getStart(); t < element.getEnd(); ++t) {
timeline[t] = element.getValue(); timeline[t] = element.getValue();
} }
}); });
} }
TEST(Timeline, shift) { TEST(Timeline, shift) {
Timeline<int> timeline{ { cs(1), cs(2), 1 },{ cs(2), cs(5), 2 },{ cs(7), cs(9), 3 } }; Timeline<int> timeline{ { 1cs, 2cs, 1 },{ 2cs, 5cs, 2 },{ 7cs, 9cs, 3 } };
Timeline<int> expected{ { cs(3), cs(4), 1 },{ cs(4), cs(7), 2 },{ cs(9), cs(11), 3 } }; Timeline<int> expected{ { 3cs, 4cs, 1 },{ 4cs, 7cs, 2 },{ 9cs, 11cs, 3 } };
timeline.shift(cs(2)); timeline.shift(2cs);
EXPECT_EQ(expected, timeline); EXPECT_EQ(expected, timeline);
} }
TEST(Timeline, equality) { TEST(Timeline, equality) {
vector<Timeline<int>> timelines = { vector<Timeline<int>> timelines = {
Timeline<int>{}, Timeline<int>{},
Timeline<int>{ { cs(1), cs(2), 0 } }, Timeline<int>{ { 1cs, 2cs, 0 } },
Timeline<int>{ { cs(1), cs(2), 1 } }, Timeline<int>{ { 1cs, 2cs, 1 } },
Timeline<int>{ { cs(-10), cs(0), 0 } } Timeline<int>{ { -10cs, 0cs, 0 } }
}; };
for (size_t i = 0; i < timelines.size(); ++i) { for (size_t i = 0; i < timelines.size(); ++i) {