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));
if (result.empty()) {
// 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;
}

View File

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

View File

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

View File

@ -1,8 +1,17 @@
#pragma once
#include <chrono>
#include <ostream>
typedef std::chrono::duration<int, std::centi> centiseconds;
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>;
AnimationResult animateFixedSound(Shape shape, centiseconds duration) {
return AnimationResult{ {centiseconds::zero(), duration, shape} };
return AnimationResult{ {0cs, duration, shape} };
}
// Diphtong vowels
AnimationResult animateDiphtong(Shape first, Shape second, centiseconds duration) {
return AnimationResult{
{ centiseconds::zero(), duration, first },
{ 0cs, duration, first },
{ duration / 2, duration, second }
};
}
@ -32,12 +32,12 @@ AnimationResult animateBilabialStop(centiseconds duration, centiseconds leftPhon
}
centiseconds closedShapeDuration = leftPhoneDuration / 2;
if (closedShapeDuration.count() < 4) closedShapeDuration = centiseconds(4);
if (closedShapeDuration.count() > 16) closedShapeDuration = centiseconds(16);
if (closedShapeDuration.count() < 4) closedShapeDuration = 4cs;
if (closedShapeDuration.count() > 16) closedShapeDuration = 16cs;
return AnimationResult{
{ -closedShapeDuration, centiseconds::zero(), Shape::A },
{ centiseconds::zero(), duration, openShape }
{ -closedShapeDuration, 0cs, Shape::A },
{ 0cs, duration, openShape }
};
}
@ -49,7 +49,7 @@ AnimationResult animateFlexibleSound(std::array<Shape, 7> mapping, centiseconds
Shape right = rightShape.value_or(Shape::A);
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) {
@ -130,7 +130,7 @@ ContinuousTimeline<Shape> animate(const BoundedTimeline<Phone> &phones) {
bool hasLeftPhone = std::next(it) != continuousPhones.rend() && std::next(it)->getEnd() == it->getStart();
centiseconds leftPhoneDuration = hasLeftPhone
? std::next(it)->getTimeRange().getLength()
: centiseconds::zero();
: 0cs;
Timeline<Shape> result = animate(phone, duration, leftPhoneDuration, lastShape);
// Result timing is relative to phone. Make absolute.

View File

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

View File

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

View File

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