Fixed OS X build

This commit is contained in:
Daniel Wolf 2016-08-09 22:31:16 +02:00 committed by Daniel Wolf
parent ce11e59c04
commit 16892ae991
18 changed files with 220 additions and 172 deletions

View File

@ -116,6 +116,9 @@ set(webRTCFiles
)
add_library(webRTC ${webRTCFiles})
target_compile_options(webRTC PRIVATE ${disableWarningsFlags})
if (NOT WIN32)
target_compile_definitions(webRTC PRIVATE WEBRTC_POSIX)
endif()
set_target_properties(webRTC PROPERTIES FOLDER lib)
# ... Flite
@ -242,6 +245,7 @@ set(TEST_FILES
tests/g2pTests.cpp
tests/LazyTests.cpp
src/stringTools.cpp src/stringTools.h
src/platformTools.cpp src/platformTools.h
src/Timeline.h
src/TimeRange.cpp src/TimeRange.h
src/centiseconds.cpp src/centiseconds.h
@ -254,7 +258,7 @@ set(TEST_FILES
src/Lazy.h
)
add_executable(runTests ${TEST_FILES})
target_link_libraries(runTests gtest gmock gmock_main flite cppFormat)
target_link_libraries(runTests ${Boost_LIBRARIES} gtest gmock gmock_main flite cppFormat)
set(CPACK_PACKAGE_NAME ${appName})
string(REPLACE " " "-" CPACK_PACKAGE_NAME "${CPACK_PACKAGE_NAME}")

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>(0cs, 0cs, Shape::A));
result.push_back(Timed<Shape>(0_cs, 0_cs, Shape::A));
}
return result;
}

View File

@ -6,6 +6,7 @@
#include <list>
#include <vector>
#include <mutex>
#include <string>
class ProgressSink {
public:

View File

@ -27,15 +27,15 @@ bool VisemeOption::operator!=(const VisemeOption& rhs) const {
}
Viseme::Viseme(const VisemeOption& option) :
options{ { 0cs, option } }
options{ { 0_cs, option } }
{}
Viseme::Viseme(const VisemeOption& option1, centiseconds threshold, const VisemeOption& option2) :
options{ { 0cs, option1 }, { threshold, option2 } }
options{ { 0_cs, option1 }, { threshold, option2 } }
{}
Viseme::Viseme(const VisemeOption& option1, centiseconds threshold1, const VisemeOption& option2, centiseconds threshold2, const VisemeOption& option3) :
options{ { 0cs, option1 },{ threshold1, option2 }, { threshold2, option3 } }
options{ { 0_cs, option1 },{ threshold1, option2 }, { threshold2, option3 } }
{}
Shape Viseme::getShape(centiseconds duration, Shape context) const {

View File

@ -4,7 +4,7 @@
using std::invalid_argument;
TimeRange AudioClip::getTruncatedRange() const {
return TimeRange(0cs, centiseconds(100 * size() / getSampleRate()));
return TimeRange(0_cs, centiseconds(100 * size() / getSampleRate()));
}
class SafeSampleReader {

View File

@ -1,4 +1,5 @@
#include "DCOffset.h"
#include <cmath>
using std::unique_ptr;
using std::make_unique;

View File

@ -2,6 +2,7 @@
#include <string.h>
#include "WaveFileReader.h"
#include "ioTools.h"
#include "platformTools.h"
using std::runtime_error;
using fmt::format;
@ -46,9 +47,7 @@ std::ifstream openFile(path filePath) {
return std::move(file);
} catch (const std::ifstream::failure&) {
char message[256];
strerror_s(message, sizeof message, errno);
throw runtime_error(message);
throw runtime_error(errorNumberToString(errno));
}
}

View File

@ -35,7 +35,7 @@ BoundedTimeline<void> webRtcDetectVoiceActivity(const AudioClip& audioClip, Prog
// Detect activity
BoundedTimeline<void> activity(audioClip.getTruncatedRange());
centiseconds time = 0cs;
centiseconds time = 0_cs;
const size_t bufferCapacity = audioClip.getSampleRate() / 100;
auto processBuffer = [&](const vector<int16_t>& buffer) {
// WebRTC is picky regarding buffer size
@ -46,9 +46,9 @@ BoundedTimeline<void> webRtcDetectVoiceActivity(const AudioClip& audioClip, Prog
bool isActive = result != 0;
if (isActive) {
activity.set(time, time + 1cs);
activity.set(time, time + 1_cs);
}
time += 1cs;
time += 1_cs;
};
process16bitAudioClip(audioClip, processBuffer, bufferCapacity, pass1ProgressSink);
@ -58,8 +58,8 @@ BoundedTimeline<void> webRtcDetectVoiceActivity(const AudioClip& audioClip, Prog
if (!activity.empty()) {
TimeRange firstActivity = activity.begin()->getTimeRange();
activity.clear(firstActivity);
unique_ptr<AudioClip> streamStart = audioClip.clone() | segment(TimeRange(0cs, firstActivity.getEnd()));
time = 0cs;
unique_ptr<AudioClip> streamStart = audioClip.clone() | segment(TimeRange(0_cs, firstActivity.getEnd()));
time = 0_cs;
process16bitAudioClip(*streamStart, processBuffer, bufferCapacity, pass2ProgressSink);
}

View File

@ -1,17 +1,15 @@
#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) {
inline constexpr centiseconds operator "" _cs(unsigned long long cs) {
return centiseconds(cs);
}
#pragma warning(pop)

View File

@ -2,12 +2,15 @@
#include <tools.h>
#include <iostream>
#include <atomic>
#include <thread>
#include <unordered_map>
using namespace logging;
using std::string;
using std::vector;
using std::shared_ptr;
using std::lock_guard;
using std::unordered_map;
LevelConverter& LevelConverter::get() {
static LevelConverter converter;
@ -37,15 +40,29 @@ std::istream& logging::operator>>(std::istream& stream, Level& value) {
return LevelConverter::get().read(stream, value);
}
// Returns an int representing the current thread.
// This used to be a simple thread_local variable, but Xcode doesn't support that yet
int getThreadCounter() {
using thread_id = std::thread::id;
static std::mutex counterMutex;
lock_guard<std::mutex> lock(counterMutex);
static unordered_map<thread_id, int> threadCounters;
static int lastThreadId = 0;
thread_id threadId = std::this_thread::get_id();
if (threadCounters.find(threadId) == threadCounters.end()) {
threadCounters.insert({threadId, ++lastThreadId});
}
return threadCounters.find(threadId)->second;
}
Entry::Entry(Level level, const string& message) :
level(level),
message(message)
{
time(&timestamp);
static std::atomic<int> lastThreadId = 0;
thread_local int threadCounter = ++lastThreadId;
this->threadCounter = threadCounter;
this->threadCounter = getThreadCounter();
}
string SimpleConsoleFormatter::format(const Entry& entry) {

View File

@ -28,21 +28,21 @@ constexpr Shape X = Shape::X;
Timeline<Viseme> animate(optional<Phone> phone, centiseconds duration, centiseconds previousPhoneDuration) {
auto single = [&](Viseme viseme) {
return Timeline<Viseme>{
{ 0cs, duration, viseme }
{ 0_cs, duration, viseme }
};
};
auto diphtong = [&](Viseme first, Viseme second) {
centiseconds firstDuration = duration_cast<centiseconds>(duration * 0.6);
return Timeline<Viseme>{
{ 0cs, firstDuration, first },
{ 0_cs, firstDuration, first },
{ firstDuration, duration, second }
};
};
auto bilabialStop = [&]() {
centiseconds maxDuration = 12cs;
centiseconds leftOverlap = clamp(previousPhoneDuration / 2, 4cs, maxDuration);
centiseconds maxDuration = 12_cs;
centiseconds leftOverlap = clamp(previousPhoneDuration / 2, 4_cs, maxDuration);
centiseconds rightOverlap = min(duration, maxDuration - leftOverlap);
return Timeline<Viseme>{
{ -leftOverlap, rightOverlap, { A } },
@ -61,7 +61,7 @@ Timeline<Viseme> animate(optional<Phone> phone, centiseconds duration, centiseco
case Phone::EH: return single({ C });
case Phone::IH: return single({ B });
case Phone::UH: return single({ E });
case Phone::AH: return single({ { B, C, D, E, F }, 6cs, { C } }); // Heuristic: < 6cs is schwa
case Phone::AH: return single({ { B, C, D, E, F }, 6_cs, { C } }); // Heuristic: < 6_cs is schwa
case Phone::AE: return single({ D });
case Phone::EY: return diphtong({ C }, { B });
case Phone::AY: return diphtong({ D }, { B });
@ -119,8 +119,8 @@ optional<pair<Shape, TweenTiming>> getTween(Shape first, Shape second) {
}
Timeline<Shape> createTweens(ContinuousTimeline<Shape> shapes) {
centiseconds minTweenDuration = 4cs;
centiseconds maxTweenDuration = 10cs;
centiseconds minTweenDuration = 4_cs;
centiseconds maxTweenDuration = 10_cs;
Timeline<Shape> tweens;
@ -171,7 +171,7 @@ Timeline<Shape> animatePauses(const ContinuousTimeline<Shape>& shapes) {
for (const auto& timedShape : shapes) {
if (timedShape.getValue() != X) continue;
const centiseconds maxPausedOpenMouthDuration = 35cs;
const centiseconds maxPausedOpenMouthDuration = 35_cs;
const TimeRange timeRange = timedShape.getTimeRange();
if (timeRange.getLength() <= maxPausedOpenMouthDuration) {
result.set(timeRange, B);
@ -183,9 +183,9 @@ Timeline<Shape> animatePauses(const ContinuousTimeline<Shape>& shapes) {
if (pause.getValue() != X) return;
centiseconds lastLength = last.getTimeRange().getLength();
const centiseconds minOpenDuration = 20cs;
const centiseconds minOpenDuration = 20_cs;
if (isClosed(secondLast.getValue()) && !isClosed(last.getValue()) && lastLength < minOpenDuration) {
const centiseconds minSpillDuration = 20cs;
const centiseconds minSpillDuration = 20_cs;
centiseconds spillDuration = std::min(minSpillDuration, pause.getTimeRange().getLength());
result.set(pause.getStart(), pause.getStart() + spillDuration, B);
}
@ -203,7 +203,7 @@ ContinuousTimeline<Shape> animate(const BoundedTimeline<Phone> &phones) {
// Create timeline of visemes
ContinuousTimeline<Viseme> visemes(phones.getRange(), { X });
centiseconds previousPhoneDuration = 0cs;
centiseconds previousPhoneDuration = 0_cs;
for (const auto& timedPhone : continuousPhones) {
// Animate one phone
optional<Phone> phone = timedPhone.getValue();

View File

@ -140,3 +140,25 @@ path getTempFilePath() {
string fileName = to_string(generateUuid());
return tempDirectory / fileName;
}
std::tm getLocalTime(const time_t& time) {
// Xcode doesn't support localtime_s.
tm timeInfo;
#if (BOOST_OS_MACOS)
localtime_r(&time, &timeInfo);
#else
localtime_s(&timeInfo, &time);
#endif
return timeInfo;
}
std::string errorNumberToString(int errorNumber) {
// Xcode doesn't support strerror_s.
char message[256];
#if (BOOST_OS_MACOS)
strerror_r(errorNumber, message, sizeof message);
#else
strerror_s(message, sizeof message, errorNumber);
#endif
return message;
}

View File

@ -1,7 +1,12 @@
#pragma once
#include <boost/filesystem.hpp>
#include <ctime>
#include <string>
boost::filesystem::path getBinPath();
boost::filesystem::path getBinDirectory();
boost::filesystem::path getTempFilePath();
std::tm getLocalTime(const time_t& time);
std::string errorNumberToString(int errorNumber);

View File

@ -2,5 +2,6 @@
#include <vector>
#include <functional>
#include <string>
std::vector<std::string> tokenizeText(const std::u32string& text, std::function<bool(const std::string&)> dictionaryContains);

View File

@ -1,4 +1,5 @@
#include "tools.h"
#include "platformTools.h"
#include <format.h>
#include <chrono>
#include <vector>
@ -11,8 +12,7 @@ string formatDuration(duration<double> seconds) {
}
string formatTime(time_t time, const string& format) {
tm timeInfo;
localtime_s(&timeInfo, &time);
tm timeInfo = getLocalTime(time);
std::vector<char> buffer(20);
bool success = false;
while (!success) {

View File

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

View File

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

View File

@ -11,14 +11,14 @@ using boost::none;
TEST(Timeline, constructors_initializeState) {
auto args = {
Timed<int>(-10cs, 30cs, 1),
Timed<int>(10cs, 40cs, 2),
Timed<int>(50cs, 60cs, 3)
Timed<int>(-10_cs, 30_cs, 1),
Timed<int>(10_cs, 40_cs, 2),
Timed<int>(50_cs, 60_cs, 3)
};
auto expected = {
Timed<int>(-10cs, 10cs, 1),
Timed<int>(10cs, 40cs, 2),
Timed<int>(50cs, 60cs, 3)
Timed<int>(-10_cs, 10_cs, 1),
Timed<int>(10_cs, 40_cs, 2),
Timed<int>(50_cs, 60_cs, 3)
};
EXPECT_THAT(
Timeline<int>(args.begin(), args.end()),
@ -39,11 +39,11 @@ TEST(Timeline, empty) {
EXPECT_TRUE(empty1.empty());
EXPECT_THAT(empty1, IsEmpty());
Timeline<int> empty2{ Timed<int>(1cs, 1cs, 1) };
Timeline<int> empty2{ Timed<int>(1_cs, 1_cs, 1) };
EXPECT_TRUE(empty2.empty());
EXPECT_THAT(empty2, IsEmpty());
Timeline<int> nonEmpty{ Timed<int>(1cs, 2cs, 1) };
Timeline<int> nonEmpty{ Timed<int>(1_cs, 2_cs, 1) };
EXPECT_FALSE(nonEmpty.empty());
EXPECT_THAT(nonEmpty, Not(IsEmpty()));
}
@ -57,39 +57,39 @@ TEST(Timeline, size) {
EXPECT_EQ(0, empty1.size());
EXPECT_THAT(empty1, SizeIs(0));
Timeline<int> empty2{ Timed<int>(1cs, 1cs, 1) };
Timeline<int> empty2{ Timed<int>(1_cs, 1_cs, 1) };
EXPECT_EQ(0, empty2.size());
EXPECT_THAT(empty2, SizeIs(0));
Timeline<int> size1{ Timed<int>(1cs, 10cs, 1) };
Timeline<int> size1{ Timed<int>(1_cs, 10_cs, 1) };
EXPECT_EQ(1, size1.size());
EXPECT_THAT(size1, SizeIs(1));
Timeline<int> size2{ Timed<int>(-10cs, 10cs, 1), Timed<int>(10cs, 11cs, 5) };
Timeline<int> size2{ Timed<int>(-10_cs, 10_cs, 1), Timed<int>(10_cs, 11_cs, 5) };
EXPECT_EQ(2, size2.size());
EXPECT_THAT(size2, SizeIs(2));
}
TEST(Timeline, getRange) {
Timeline<int> empty0;
EXPECT_EQ(TimeRange(0cs, 0cs), empty0.getRange());
EXPECT_EQ(TimeRange(0_cs, 0_cs), empty0.getRange());
Timeline<int> empty1{};
EXPECT_EQ(TimeRange(0cs, 0cs), empty1.getRange());
EXPECT_EQ(TimeRange(0_cs, 0_cs), empty1.getRange());
Timeline<int> empty2{ Timed<int>(1cs, 1cs, 1) };
EXPECT_EQ(TimeRange(0cs, 0cs), empty2.getRange());
Timeline<int> empty2{ Timed<int>(1_cs, 1_cs, 1) };
EXPECT_EQ(TimeRange(0_cs, 0_cs), empty2.getRange());
Timeline<int> nonEmpty1{ Timed<int>(1cs, 10cs, 1) };
EXPECT_EQ(TimeRange(1cs, 10cs), nonEmpty1.getRange());
Timeline<int> nonEmpty1{ Timed<int>(1_cs, 10_cs, 1) };
EXPECT_EQ(TimeRange(1_cs, 10_cs), nonEmpty1.getRange());
Timeline<int> nonEmpty2{ Timed<int>(-10cs, 5cs, 1), Timed<int>(10cs, 11cs, 5) };
EXPECT_EQ(TimeRange(-10cs, 11cs), nonEmpty2.getRange());
Timeline<int> nonEmpty2{ Timed<int>(-10_cs, 5_cs, 1), Timed<int>(10_cs, 11_cs, 5) };
EXPECT_EQ(TimeRange(-10_cs, 11_cs), nonEmpty2.getRange());
}
TEST(Timeline, iterators) {
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) };
Timeline<int> timeline{ Timed<int>(-5_cs, 0_cs, 10), Timed<int>(5_cs, 15_cs, 9) };
auto expected = { Timed<int>(-5_cs, 0_cs, 10), Timed<int>(5_cs, 15_cs, 9) };
EXPECT_THAT(timeline, ElementsAreArray(expected));
vector<Timed<int>> reversedActual;
@ -115,9 +115,9 @@ void testFind(const Timeline<int>& timeline, FindMode findMode, const initialize
}
TEST(Timeline, find) {
Timed<int> a = Timed<int>(1cs, 2cs, 1);
Timed<int> b = Timed<int>(2cs, 5cs, 2);
Timed<int> c = Timed<int>(7cs, 9cs, 3);
Timed<int> a = Timed<int>(1_cs, 2_cs, 1);
Timed<int> b = Timed<int>(2_cs, 5_cs, 2);
Timed<int> c = Timed<int>(7_cs, 9_cs, 3);
Timeline<int> timeline{ a, b, c };
testFind(timeline, FindMode::SampleLeft, { nullptr, nullptr, &a, &b, &b, &b, nullptr, nullptr, &c, &c, nullptr });
@ -127,9 +127,9 @@ TEST(Timeline, find) {
}
TEST(Timeline, get) {
Timed<int> a = Timed<int>(1cs, 2cs, 1);
Timed<int> b = Timed<int>(2cs, 5cs, 2);
Timed<int> c = Timed<int>(7cs, 9cs, 3);
Timed<int> a = Timed<int>(1_cs, 2_cs, 1);
Timed<int> b = Timed<int>(2_cs, 5_cs, 2);
Timed<int> c = Timed<int>(7_cs, 9_cs, 3);
Timeline<int> timeline{ a, b, c };
initializer_list<Timed<int>*> expectedResults = { nullptr, &a, &b, &b, &b, nullptr, nullptr, &c, &c, nullptr, nullptr };
@ -148,39 +148,39 @@ TEST(Timeline, get) {
}
TEST(Timeline, clear) {
Timeline<int> original{ { 1cs, 2cs, 1 }, { 2cs, 5cs, 2 }, { 7cs, 9cs, 3 } };
Timeline<int> original{ { 1_cs, 2_cs, 1 }, { 2_cs, 5_cs, 2 }, { 7_cs, 9_cs, 3 } };
{
auto timeline = original;
timeline.clear(-10cs, 10cs);
timeline.clear(-10_cs, 10_cs);
EXPECT_THAT(timeline, IsEmpty());
}
{
auto timeline = original;
timeline.clear(1cs, 2cs);
Timeline<int> expected{ { 2cs, 5cs, 2 }, { 7cs, 9cs, 3 } };
timeline.clear(1_cs, 2_cs);
Timeline<int> expected{ { 2_cs, 5_cs, 2 }, { 7_cs, 9_cs, 3 } };
EXPECT_EQ(expected, timeline);
}
{
auto timeline = original;
timeline.clear(3cs, 4cs);
Timeline<int> expected{ { 1cs, 2cs, 1 }, { 2cs, 3cs, 2 }, { 4cs, 5cs, 2}, { 7cs, 9cs, 3} };
timeline.clear(3_cs, 4_cs);
Timeline<int> expected{ { 1_cs, 2_cs, 1 }, { 2_cs, 3_cs, 2 }, { 4_cs, 5_cs, 2}, { 7_cs, 9_cs, 3} };
EXPECT_EQ(expected, timeline);
}
{
auto timeline = original;
timeline.clear(6cs, 8cs);
Timeline<int> expected{ { 1cs, 2cs, 1 }, { 2cs, 5cs, 2 }, { 8cs, 9cs, 3 } };
timeline.clear(6_cs, 8_cs);
Timeline<int> expected{ { 1_cs, 2_cs, 1 }, { 2_cs, 5_cs, 2 }, { 8_cs, 9_cs, 3 } };
EXPECT_EQ(expected, timeline);
}
{
auto timeline = original;
timeline.clear(8cs, 10cs);
Timeline<int> expected{ { 1cs, 2cs, 1 }, { 2cs, 5cs, 2 }, { 7cs, 8cs, 3 } };
timeline.clear(8_cs, 10_cs);
Timeline<int> expected{ { 1_cs, 2_cs, 1 }, { 2_cs, 5_cs, 2 }, { 7_cs, 8_cs, 3 } };
EXPECT_EQ(expected, timeline);
}
}
@ -189,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>(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)
Timed<int>(1_cs, 2_cs, 4),
Timed<int>(3_cs, 6_cs, 4),
Timed<int>(7_cs, 9_cs, 5),
Timed<int>(9_cs, 10_cs, 6),
Timed<int>(2_cs, 3_cs, 4),
Timed<int>(0_cs, 1_cs, 7),
Timed<int>(-10_cs, 1_cs, 8),
Timed<int>(-10_cs, 0_cs, 9),
Timed<int>(-10_cs, -1_cs, 10),
Timed<int>(9_cs, 20_cs, 11),
Timed<int>(10_cs, 20_cs, 12),
Timed<int>(11_cs, 20_cs, 13),
Timed<int>(4_cs, 6_cs, 14),
Timed<int>(4_cs, 6_cs, 15),
Timed<int>(8_cs, 10_cs, 15),
Timed<int>(6_cs, 8_cs, 15),
Timed<int>(6_cs, 8_cs, 16)
};
int newElementIndex = -1;
for (const auto& newElement : newElements) {
@ -214,14 +214,14 @@ void testSetter(std::function<void(const Timed<int>&, Timeline<int>&)> set) {
set(newElement, timeline);
// Update expected value for every index
centiseconds elementStart = max(newElement.getStart(), 0cs);
centiseconds elementStart = max(newElement.getStart(), 0_cs);
centiseconds elementEnd = newElement.getEnd();
for (centiseconds t = elementStart; t < elementEnd; ++t) {
expectedValues[t.count()] = newElement.getValue();
}
// Check timeline via indexer
for (centiseconds t = 0cs; t < 10cs; ++t) {
for (centiseconds t = 0_cs; t < 10_cs; ++t) {
optional<const int&> actual = timeline[t];
EXPECT_EQ(expectedValues[t.count()], actual ? optional<int>(*actual) : none);
}
@ -230,7 +230,7 @@ void testSetter(std::function<void(const Timed<int>&, Timeline<int>&)> set) {
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(0cs, element.getTimeRange().getLength());
EXPECT_LT(0_cs, element.getTimeRange().getLength());
// No two adjacent elements should have the same value; they should have been merged
if (element.getStart() == lastElement.getEnd()) {
@ -264,9 +264,9 @@ TEST(Timeline, set) {
}
TEST(Timeline, indexer_get) {
Timeline<int> timeline{ { 1cs, 2cs, 1 }, { 2cs, 4cs, 2 }, { 6cs, 9cs, 3 } };
Timeline<int> timeline{ { 1_cs, 2_cs, 1 }, { 2_cs, 4_cs, 2 }, { 6_cs, 9_cs, 3 } };
vector<optional<int>> expectedValues{ none, 1, 2, 2, none, none, 3, 3, 3 };
for (centiseconds t = 0cs; t < 9cs; ++t) {
for (centiseconds t = 0_cs; t < 9_cs; ++t) {
{
optional<const int&> actual = timeline[t];
EXPECT_EQ(expectedValues[t.count()], actual ? optional<int>(*actual) : none);
@ -297,18 +297,18 @@ TEST(Timeline, indexer_set) {
}
TEST(Timeline, shift) {
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);
Timeline<int> timeline{ { 1_cs, 2_cs, 1 },{ 2_cs, 5_cs, 2 },{ 7_cs, 9_cs, 3 } };
Timeline<int> expected{ { 3_cs, 4_cs, 1 },{ 4_cs, 7_cs, 2 },{ 9_cs, 11_cs, 3 } };
timeline.shift(2_cs);
EXPECT_EQ(expected, timeline);
}
TEST(Timeline, equality) {
vector<Timeline<int>> timelines = {
Timeline<int>{},
Timeline<int>{ { 1cs, 2cs, 0 } },
Timeline<int>{ { 1cs, 2cs, 1 } },
Timeline<int>{ { -10cs, 0cs, 0 } }
Timeline<int>{ { 1_cs, 2_cs, 0 } },
Timeline<int>{ { 1_cs, 2_cs, 1 } },
Timeline<int>{ { -10_cs, 0_cs, 0 } }
};
for (size_t i = 0; i < timelines.size(); ++i) {