From 2dd1da833365b4dcedbc049119634c36c58af4a5 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Tue, 13 Nov 2012 06:07:39 -0800 Subject: [PATCH] Use C++11 stuff in libaegisub --- aegisub/libaegisub/common/charset.cpp | 6 +- aegisub/libaegisub/common/charset_6937.cpp | 7 +- aegisub/libaegisub/common/charset_conv.cpp | 24 ++--- aegisub/libaegisub/common/hotkey.cpp | 55 +++++------ aegisub/libaegisub/common/keyframe.cpp | 35 +++---- aegisub/libaegisub/common/log.cpp | 12 +-- aegisub/libaegisub/common/mru.cpp | 12 +-- aegisub/libaegisub/common/option.cpp | 49 +++++---- aegisub/libaegisub/common/option_visit.cpp | 12 +-- aegisub/libaegisub/common/thesaurus.cpp | 29 +++--- aegisub/libaegisub/common/util.cpp | 13 +-- aegisub/libaegisub/common/vfr.cpp | 99 +++++++------------ .../libaegisub/include/libaegisub/signal.h | 11 +-- aegisub/libaegisub/windows/access.cpp | 2 +- aegisub/libaegisub/windows/util_win.cpp | 4 +- 15 files changed, 147 insertions(+), 223 deletions(-) diff --git a/aegisub/libaegisub/common/charset.cpp b/aegisub/libaegisub/common/charset.cpp index 4c7024859..079fefee1 100644 --- a/aegisub/libaegisub/common/charset.cpp +++ b/aegisub/libaegisub/common/charset.cpp @@ -22,13 +22,11 @@ namespace agi { namespace charset { std::string Detect(const std::string &file) { - UCDetect ucd(file); - return ucd.Single(); + return UCDetect(file).Single(); } void DetectAll(const std::string& file, CharsetListDetected &list) { - UCDetect ucd(file); - ucd.List(list); + UCDetect(file).List(list); } } // namespace util diff --git a/aegisub/libaegisub/common/charset_6937.cpp b/aegisub/libaegisub/common/charset_6937.cpp index 3120a54c5..530358de2 100644 --- a/aegisub/libaegisub/common/charset_6937.cpp +++ b/aegisub/libaegisub/common/charset_6937.cpp @@ -27,6 +27,8 @@ #include +#include + namespace { // ISO-6937-2 values for the first 383 codepoints @@ -160,9 +162,8 @@ int get_iso6937(int codepoint) { if (static_cast(codepoint) < countof(iso6937_codepoints)) return iso6937_codepoints[codepoint]; - const extended_range *end = iso6937_extended_codepoints + countof(iso6937_extended_codepoints); - const extended_range *ext = std::lower_bound(iso6937_extended_codepoints, end, codepoint); - if (ext == end || ext->codepoint != codepoint) + auto ext = boost::lower_bound(iso6937_extended_codepoints, codepoint); + if (ext == std::end(iso6937_extended_codepoints) || ext->codepoint != codepoint) return 0; return ext->value; } diff --git a/aegisub/libaegisub/common/charset_conv.cpp b/aegisub/libaegisub/common/charset_conv.cpp index 4c06cb3af..fd87bb2bf 100644 --- a/aegisub/libaegisub/common/charset_conv.cpp +++ b/aegisub/libaegisub/common/charset_conv.cpp @@ -65,7 +65,7 @@ namespace { # undef ADD } - std::map::iterator real = pretty_names.find(name); + auto real = pretty_names.find(name); if (real != pretty_names.end()) return real->second; return name; @@ -146,16 +146,14 @@ namespace { { const char *dstEnc = get_real_encoding_name(destEncoding); cd = iconv_open(dstEnc, "UTF-8"); - if (cd == iconv_invalid) { + if (cd == iconv_invalid) throw agi::charset::UnsupportedConversion(std::string(dstEnc) + " is not a supported character set"); - } bomSize = get_bom_size(cd); iconv_close(cd); cd = iconv_open(dstEnc, get_real_encoding_name(sourceEncoding)); - if (cd == iconv_invalid) { + if (cd == iconv_invalid) throw agi::charset::UnsupportedConversion(std::string("Cannot convert from ") + sourceEncoding + " to " + destEncoding); - } } ~ConverterImpl() { if (cd != iconv_invalid) iconv_close(cd); @@ -232,10 +230,10 @@ namespace { if (subst) { data = this; - mb_to_uc_fallback = NULL; - mb_to_wc_fallback = NULL; + mb_to_uc_fallback = nullptr; + mb_to_wc_fallback = nullptr; uc_to_mb_fallback = fallback; - wc_to_mb_fallback = NULL; + wc_to_mb_fallback = nullptr; int transliterate = 1; iconvctl(cd, ICONV_SET_TRANSLITERATE, &transliterate); @@ -316,7 +314,7 @@ void IconvWrapper::Convert(std::string const& source, std::string &dest) { char *dst = buff; size_t dstLen = sizeof(buff); res = conv->Convert(&src, &srcLen, &dst, &dstLen); - if (res == 0) conv->Convert(NULL, NULL, &dst, &dstLen); + if (res == 0) conv->Convert(nullptr, nullptr, &dst, &dstLen); dest.append(buff, sizeof(buff) - dstLen); } while (res == iconv_failed && errno == E2BIG); @@ -341,13 +339,11 @@ void IconvWrapper::Convert(std::string const& source, std::string &dest) { } size_t IconvWrapper::Convert(const char* source, size_t sourceSize, char *dest, size_t destSize) { - if (sourceSize == (size_t)-1) { + if (sourceSize == (size_t)-1) sourceSize = SrcStrLen(source); - } - size_t res = conv->Convert(&source, &sourceSize, &dest, &destSize); - if (res == 0) res = conv->Convert(NULL, NULL, &dest, &destSize); + if (res == 0) res = conv->Convert(nullptr, nullptr, &dest, &destSize); if (res == iconv_failed) { switch (errno) { @@ -390,7 +386,7 @@ size_t IconvWrapper::RequiredBufferSize(const char* src, size_t srcLen) { char* dst = buff; size_t dstSize = sizeof(buff); res = conv->Convert(&src, &srcLen, &dst, &dstSize); - conv->Convert(NULL, NULL, &dst, &dstSize); + conv->Convert(nullptr, nullptr, &dst, &dstSize); charsWritten += dst - buff; } while (res == iconv_failed && errno == E2BIG); diff --git a/aegisub/libaegisub/common/hotkey.cpp b/aegisub/libaegisub/common/hotkey.cpp index e259d51df..068bb0944 100644 --- a/aegisub/libaegisub/common/hotkey.cpp +++ b/aegisub/libaegisub/common/hotkey.cpp @@ -33,18 +33,14 @@ #include "libaegisub/json.h" #include "libaegisub/log.h" +#include +#include + namespace agi { namespace hotkey { std::string Combo::Str() const { - if (key_map.empty()) return ""; - - std::string str(key_map[0]); - str.reserve(str.size() + (key_map.size() - 1) * 2); - for (unsigned int i=1; i < key_map.size(); i++) { - str.append("-" + key_map[i]); - } - return str; + return boost::algorithm::join(key_map, "-"); } std::string Combo::StrMenu() const { @@ -52,8 +48,8 @@ std::string Combo::StrMenu() const { } void Hotkey::ComboInsert(Combo const& combo) { - str_map.insert(std::make_pair(combo.Str(), combo)); - cmd_map.insert(std::make_pair(combo.CmdName(), combo)); + str_map.insert(make_pair(combo.Str(), combo)); + cmd_map.insert(make_pair(combo.CmdName(), combo)); } Hotkey::Hotkey(const std::string &file, const std::string &default_config) @@ -62,29 +58,28 @@ Hotkey::Hotkey(const std::string &file, const std::string &default_config) LOG_D("hotkey/init") << "Generating hotkeys."; json::Object object(agi::json_util::file(config_file, default_config)); - for (json::Object::const_iterator index(object.begin()); index != object.end(); ++index) - BuildHotkey(index->first, index->second); + for (auto const& hotkey_context : object) + BuildHotkey(hotkey_context.first, hotkey_context.second); } +void Hotkey::BuildHotkey(std::string const& context, json::Object const& hotkeys) { + for (auto const& command : hotkeys) { + const json::Array& command_hotkeys = command.second; -void Hotkey::BuildHotkey(std::string const& context, const json::Object& object) { - for (json::Object::const_iterator index(object.begin()); index != object.end(); ++index) { - const json::Array& array = index->second; - - for (json::Array::const_iterator arr_index(array.begin()); arr_index != array.end(); ++arr_index) { + for (auto const& hotkey : command_hotkeys) { std::vector keys; try { - const json::Array& arr_mod = (*arr_index)["modifiers"]; + const json::Array& arr_mod = hotkey["modifiers"]; keys.reserve(arr_mod.size() + 1); copy(arr_mod.begin(), arr_mod.end(), back_inserter(keys)); - keys.push_back((*arr_index)["key"]); + keys.push_back(hotkey["key"]); } catch (json::Exception const& e) { - LOG_E("agi/hotkey/load") << "Failed loading hotkey for command '" << index->first << "': " << e.what(); + LOG_E("agi/hotkey/load") << "Failed loading hotkey for command '" << command.first << "': " << e.what(); } - ComboInsert(Combo(context, index->first, keys)); + ComboInsert(Combo(context, command.first, keys)); } } } @@ -151,18 +146,16 @@ std::string Hotkey::GetHotkey(const std::string &context, const std::string &com void Hotkey::Flush() { json::Object root; - for (HotkeyMap::iterator index = str_map.begin(); index != str_map.end(); ++index) { - std::vector const& combo_map(index->second.Get()); - + for (auto const& combo : str_map | boost::adaptors::map_values) { json::Object hotkey; - if (combo_map.size()) { - hotkey["key"] = combo_map.back(); + if (combo.Get().size()) { + hotkey["key"] = combo.Get().back(); json::Array& modifiers = hotkey["modifiers"]; - copy(combo_map.begin(), combo_map.end() - 1, std::back_inserter(modifiers)); + modifiers.insert(modifiers.end(), combo.Get().begin(), combo.Get().end() - 1); } - json::Array& combo_array = root[index->second.Context()][index->second.CmdName()]; - combo_array.push_back(hotkey); + json::Array& combo_array = root[combo.Context()][combo.CmdName()]; + combo_array.push_back(std::move(hotkey)); } io::Save file(config_file); @@ -173,8 +166,8 @@ void Hotkey::SetHotkeyMap(HotkeyMap const& new_map) { cmd_map = new_map; str_map.clear(); - for (HotkeyMap::iterator it = cmd_map.begin(); it != cmd_map.end(); ++it) - str_map.insert(make_pair(it->second.Str(), it->second)); + for (auto const& combo : cmd_map | boost::adaptors::map_values) + str_map.insert(make_pair(combo.Str(), combo)); Flush(); HotkeysChanged(); diff --git a/aegisub/libaegisub/common/keyframe.cpp b/aegisub/libaegisub/common/keyframe.cpp index 24e9f7702..1825c3989 100644 --- a/aegisub/libaegisub/common/keyframe.cpp +++ b/aegisub/libaegisub/common/keyframe.cpp @@ -30,6 +30,9 @@ #include "libaegisub/keyframe.h" #include "libaegisub/vfr.h" +#include +#include + namespace { std::vector agi_keyframes(std::istream &file) { double fps; @@ -37,9 +40,7 @@ std::vector agi_keyframes(std::istream &file) { file >> fps_str; file >> fps; - std::vector ret; - copy(std::istream_iterator(file), std::istream_iterator(), back_inserter(ret)); - return ret; + return std::vector(std::istream_iterator(file), std::istream_iterator()); } std::vector other_keyframes(std::istream &file, char (*func)(std::string const&)) { @@ -48,12 +49,10 @@ std::vector other_keyframes(std::istream &file, char (*func)(std::string co agi::line_iterator end; for (agi::line_iterator iter(file); iter != end; ++iter) { char c = tolower(func(*iter)); - if (c == 'i') { + if (c == 'i') ret.push_back(count++); - } - else if (c == 'p' || c == 'b') { + else if (c == 'p' || c == 'b') ++count; - } } return ret; } @@ -77,34 +76,28 @@ char x264(std::string const& line) { if (pos == line.npos || pos + 5 >= line.size()) return 0; return line[pos + 5]; } - -template -bool starts_with(std::string const& str, const char (&test)[N]) { - if (str.size() < N) return false; - return std::mismatch(str.begin(), str.begin() + N - 1, test).first == str.begin() + N - 1; -} } namespace agi { namespace keyframe { - void Save(std::string const& filename, std::vector const& keyframes) { +void Save(std::string const& filename, std::vector const& keyframes) { io::Save file(filename); std::ofstream& of = file.Get(); of << "# keyframe format v1" << std::endl; of << "fps " << 0 << std::endl; - copy(keyframes.begin(), keyframes.end(), std::ostream_iterator(of, "\n")); + boost::copy(keyframes, std::ostream_iterator(of, "\n")); } std::vector Load(std::string const& filename) { - std::auto_ptr file(io::Open(filename)); - std::istream &is(*file.get()); + std::unique_ptr file(io::Open(filename)); + std::istream &is(*file); std::string header; - std::getline(is, header); + getline(is, header); if (header == "# keyframe format v1") return agi_keyframes(is); - if (starts_with(header, "# XviD 2pass stat file")) return other_keyframes(is, xvid); - if (starts_with(header, "##map version")) return other_keyframes(is, divx); - if (starts_with(header, "#options:")) return other_keyframes(is, x264); + if (boost::starts_with(header, "# XviD 2pass stat file")) return other_keyframes(is, xvid); + if (boost::starts_with(header, "##map version")) return other_keyframes(is, divx); + if (boost::starts_with(header, "#options:")) return other_keyframes(is, x264); throw Error("Unknown keyframe format"); } diff --git a/aegisub/libaegisub/common/log.cpp b/aegisub/libaegisub/common/log.cpp index da92272bb..b6e128817 100644 --- a/aegisub/libaegisub/common/log.cpp +++ b/aegisub/libaegisub/common/log.cpp @@ -34,6 +34,8 @@ #include "libaegisub/types.h" #include "libaegisub/util.h" +#include + namespace agi { namespace log { @@ -53,7 +55,7 @@ SinkMessage::SinkMessage(const char *section, Severity severity, , func(func) , line(line) , tv(tv) -, message(NULL) +, message(nullptr) , len(0) { } @@ -75,11 +77,7 @@ LogSink::~LogSink() { void LogSink::log(SinkMessage *sm) { sink.push_back(sm); - - for_each( - emitters.begin(), - emitters.end(), - bind2nd(std::mem_fun(&Emitter::log), sm)); + boost::for_each(emitters, [=](Emitter *em) { em->log(sm); }); } void LogSink::Subscribe(Emitter *em) { @@ -139,7 +137,7 @@ JsonEmitter::~JsonEmitter() { entry["line"] = sink[i]->line; entry["message"] = std::string(sink[i]->message, sink[i]->len); - array.push_back(entry); + array.push_back(std::move(entry)); } json::Array &timeval_open = root["timeval"]["open"]; diff --git a/aegisub/libaegisub/common/mru.cpp b/aegisub/libaegisub/common/mru.cpp index c6917c4c1..e744654bc 100644 --- a/aegisub/libaegisub/common/mru.cpp +++ b/aegisub/libaegisub/common/mru.cpp @@ -46,8 +46,8 @@ MRUManager::MRUManager(std::string const& config, std::string const& default_con LOG_D("agi/mru") << "Loading MRU List"; json::Object root(json_util::file(config, default_config)); - for (json::Object::const_iterator it(root.begin()); it != root.end(); ++it) - Load(it->first, it->second); + for (auto const& it : root) + Load(it.first, it.second); } MRUManager::~MRUManager() { @@ -93,9 +93,9 @@ std::string const& MRUManager::GetEntry(std::string const& key, const size_t ent void MRUManager::Flush() { json::Object out; - for (MRUMap::const_iterator i = mru.begin(); i != mru.end(); ++i) { - json::Array &array = out[i->first]; - copy(i->second.begin(), i->second.end(), std::back_inserter(array)); + for (auto const& mru_map : mru) { + json::Array &array = out[mru_map.first]; + array.insert(array.end(), mru_map.second.begin(), mru_map.second.end()); } json::Writer::Write(out, io::Save(config_name).Get()); @@ -106,7 +106,7 @@ void MRUManager::Flush() { void MRUManager::Prune(std::string const& key, MRUListMap& map) const { size_t limit = 16u; if (options) { - std::map::const_iterator it = option_names.find(key); + auto it = option_names.find(key); if (it != option_names.end()) limit = (size_t)options->Get(it->second)->GetInt(); } diff --git a/aegisub/libaegisub/common/option.cpp b/aegisub/libaegisub/common/option.cpp index 92aa60924..22569c62e 100644 --- a/aegisub/libaegisub/common/option.cpp +++ b/aegisub/libaegisub/common/option.cpp @@ -38,6 +38,8 @@ #include "option_visit.h" +#include + namespace { /// @brief Write an option to a json object /// @param[out] obj Parent object @@ -50,12 +52,8 @@ namespace { assert(obj.find(path) == obj.end()); obj[path] = value; } - else { - put_option( - obj[path.substr(0, pos)], - path.substr(pos + 1), - value); - } + else + put_option(obj[path.substr(0, pos)], path.substr(pos + 1), value); } template @@ -80,13 +78,11 @@ Options::Options(const std::string &file, const std::string& default_config, con } Options::~Options() { - if ((setting & FLUSH_SKIP) != FLUSH_SKIP) { + if ((setting & FLUSH_SKIP) != FLUSH_SKIP) Flush(); - } - for (OptionValueMap::iterator i = values.begin(); i != values.end(); i++) { - delete i->second; - } + for (auto option_value : values | boost::adaptors::map_values) + delete option_value; } void Options::ConfigNext(std::istream& stream) { @@ -94,7 +90,7 @@ void Options::ConfigNext(std::istream& stream) { } void Options::ConfigUser() { - std::auto_ptr stream; + std::unique_ptr stream; try { stream.reset(agi::io::Open(config_file)); @@ -125,9 +121,8 @@ void Options::LoadConfig(std::istream& stream, bool ignore_errors) { } OptionValue* Options::Get(const std::string &name) { - OptionValueMap::iterator index; - - if ((index = values.find(name)) != values.end()) + auto index = values.find(name); + if (index != values.end()) return index->second; LOG_E("option/get") << "agi::Options::Get Option not found: (" << name << ")"; @@ -137,46 +132,46 @@ OptionValue* Options::Get(const std::string &name) { void Options::Flush() { json::Object obj_out; - for (OptionValueMap::const_iterator i = values.begin(); i != values.end(); ++i) { - switch (i->second->GetType()) { + for (auto const& ov : values) { + switch (ov.second->GetType()) { case OptionValue::Type_String: - put_option(obj_out, i->first, i->second->GetString()); + put_option(obj_out, ov.first, ov.second->GetString()); break; case OptionValue::Type_Int: - put_option(obj_out, i->first, i->second->GetInt()); + put_option(obj_out, ov.first, ov.second->GetInt()); break; case OptionValue::Type_Double: - put_option(obj_out, i->first, i->second->GetDouble()); + put_option(obj_out, ov.first, ov.second->GetDouble()); break; case OptionValue::Type_Color: - put_option(obj_out, i->first, i->second->GetColor().GetRgbFormatted()); + put_option(obj_out, ov.first, ov.second->GetColor().GetRgbFormatted()); break; case OptionValue::Type_Bool: - put_option(obj_out, i->first, i->second->GetBool()); + put_option(obj_out, ov.first, ov.second->GetBool()); break; case OptionValue::Type_List_String: - put_array(obj_out, i->first, "string", i->second->GetListString()); + put_array(obj_out, ov.first, "string", ov.second->GetListString()); break; case OptionValue::Type_List_Int: - put_array(obj_out, i->first, "int", i->second->GetListInt()); + put_array(obj_out, ov.first, "int", ov.second->GetListInt()); break; case OptionValue::Type_List_Double: - put_array(obj_out, i->first, "double", i->second->GetListDouble()); + put_array(obj_out, ov.first, "double", ov.second->GetListDouble()); break; case OptionValue::Type_List_Color: - put_array(obj_out, i->first, "color", i->second->GetListColor()); + put_array(obj_out, ov.first, "color", ov.second->GetListColor()); break; case OptionValue::Type_List_Bool: - put_array(obj_out, i->first, "bool", i->second->GetListBool()); + put_array(obj_out, ov.first, "bool", ov.second->GetListBool()); break; } } diff --git a/aegisub/libaegisub/common/option_visit.cpp b/aegisub/libaegisub/common/option_visit.cpp index 8f0b8ce72..83a13e7be 100644 --- a/aegisub/libaegisub/common/option_visit.cpp +++ b/aegisub/libaegisub/common/option_visit.cpp @@ -50,14 +50,12 @@ void ConfigVisitor::Error(const char *message) { } void ConfigVisitor::Visit(const json::Object& object) { - json::Object::const_iterator index(object.begin()), index_end(object.end()); - if (!name.empty()) name += "/"; - for (; index != index_end; ++index) { - ConfigVisitor config_visitor(values, name + index->first, ignore_errors, replace); - index->second.Accept(config_visitor); + for (auto const& obj : object) { + ConfigVisitor config_visitor(values, name + obj.first, ignore_errors, replace); + obj.second.Accept(config_visitor); } } @@ -66,9 +64,7 @@ OptionValue *ConfigVisitor::ReadArray(json::Array const& src, std::string const& std::vector arr; arr.reserve(src.size()); - for (json::Array::const_iterator it = src.begin(); it != src.end(); ++it) { - json::Object const& obj = *it; - + for (json::Object const& obj : src) { if (obj.size() != 1) { Error("Invalid array member"); return 0; diff --git a/aegisub/libaegisub/common/thesaurus.cpp b/aegisub/libaegisub/common/thesaurus.cpp index 50127d620..511fe9534 100644 --- a/aegisub/libaegisub/common/thesaurus.cpp +++ b/aegisub/libaegisub/common/thesaurus.cpp @@ -22,22 +22,15 @@ #include "libaegisub/io.h" #include "libaegisub/line_iterator.h" +#include +#include +#include + #ifndef LAGI_PRE #include #endif -template -static void split(String const& str, Char sep, Container *out) { - typename String::size_type pos, prev = 0; - out->reserve(2); - while ((pos = str.find(sep, prev)) != String::npos) { - if (pos > prev) - out->push_back(str.substr(prev, pos - prev)); - prev = pos + 1; - } - if (prev < str.size()) - out->push_back(str.substr(prev)); -} +using boost::phoenix::placeholders::_1; namespace agi { @@ -54,10 +47,9 @@ Thesaurus::Thesaurus(std::string const& dat_path, std::string const& idx_path) // Read the list of words and file offsets for those words for (line_iterator iter(*idx, encoding_name), end; iter != end; ++iter) { std::vector chunks; - split(*iter, '|', &chunks); - if (chunks.size() == 2) { + boost::split(chunks, *iter, _1 == '|'); + if (chunks.size() == 2) offsets[chunks[0]] = atoi(chunks[1].c_str()); - } } conv.reset(new charset::IconvWrapper(encoding_name.c_str(), "utf-8")); @@ -67,9 +59,10 @@ Thesaurus::~Thesaurus() { } void Thesaurus::Lookup(std::string const& word, std::vector *out) { out->clear(); + if (!dat.get()) return; std::map::const_iterator it = offsets.find(word); - if (!dat.get() || it == offsets.end()) return; + if (it == offsets.end()) return; dat->seekg(it->second, std::ios::beg); if (!dat->good()) return; @@ -78,7 +71,7 @@ void Thesaurus::Lookup(std::string const& word, std::vector *out) { std::string temp; getline(*dat, temp); std::vector header; - split(conv->Convert(temp), '|', &header); + boost::split(header, conv->Convert(temp), _1 == '|'); if (header.size() != 2) return; int meanings = atoi(header[1].c_str()); @@ -86,7 +79,7 @@ void Thesaurus::Lookup(std::string const& word, std::vector *out) { for (int i = 0; i < meanings; ++i) { std::vector line; getline(*dat, temp); - split(conv->Convert(temp), '|', &line); + boost::split(line, conv->Convert(temp), _1 == '|'); // The "definition" is just the part of speech plus the word it's // giving synonyms for (which may not be the passed word) diff --git a/aegisub/libaegisub/common/util.cpp b/aegisub/libaegisub/common/util.cpp index ee345536a..3a96d6452 100644 --- a/aegisub/libaegisub/common/util.cpp +++ b/aegisub/libaegisub/common/util.cpp @@ -24,24 +24,20 @@ #include #endif - #include "libaegisub/util.h" +#include + namespace agi { namespace util { - void str_lower(std::string &str) { - std::locale loc; - for (size_t i=0; i < str.length(); ++i) { - str[i] = std::tolower(str[i], loc); - } + boost::to_lower(str); } - int strtoi(std::string &str) { errno = 0; - long l = strtol(str.c_str(), NULL, 10); + long l = strtol(str.c_str(), nullptr, 10); if ((errno == ERANGE) || (l < INT_MIN) || (l > INT_MAX)) return 0; @@ -49,6 +45,5 @@ int strtoi(std::string &str) { return (int)l; } - } // namespace util } // namespace agi diff --git a/aegisub/libaegisub/common/vfr.cpp b/aegisub/libaegisub/common/vfr.cpp index a92dee04b..9bbd041ec 100644 --- a/aegisub/libaegisub/common/vfr.cpp +++ b/aegisub/libaegisub/common/vfr.cpp @@ -32,6 +32,8 @@ #include "libaegisub/line_iterator.h" #include "libaegisub/scoped_ptr.h" +#include + namespace std { template<> void swap(agi::vfr::Framerate &lft, agi::vfr::Framerate &rgt) { lft.swap(rgt); @@ -43,27 +45,20 @@ static const int64_t default_denominator = 1000000000; namespace agi { namespace vfr { -static int is_increasing(int prev, int cur) { - if (prev > cur) - throw UnorderedTimecodes("Timecodes are out of order"); - return cur; -} - /// @brief Verify that timecodes monotonically increase /// @param timecodes List of timecodes to check static void validate_timecodes(std::vector const& timecodes) { - if (timecodes.size() <= 1) { + if (timecodes.size() <= 1) throw TooFewTimecodes("Must have at least two timecodes to do anything useful"); - } - std::accumulate(timecodes.begin()+1, timecodes.end(), timecodes.front(), is_increasing); + if (!is_sorted(timecodes.begin(), timecodes.end())) + throw UnorderedTimecodes("Timecodes are out of order"); } /// @brief Shift timecodes so that frame 0 starts at time 0 /// @param timecodes List of timecodes to normalize static void normalize_timecodes(std::vector &timecodes) { - if (int front = timecodes.front()) { - std::transform(timecodes.begin(), timecodes.end(), timecodes.begin(), std::bind2nd(std::minus(), front)); - } + if (int front = timecodes.front()) + boost::for_each(timecodes, [=](int &tc) { tc -= front; }); } // A "start,end,fps" line in a v1 timecode file @@ -74,7 +69,8 @@ struct TimecodeRange { bool operator<(TimecodeRange const& cmp) const { return start < cmp.start; } - TimecodeRange() : fps(0.) { } + TimecodeRange(int start=0, int end=0, double fps=0.) + : start(start), end(end), fps(fps) { } }; /// @brief Parse a single line of a v1 timecode file @@ -87,57 +83,38 @@ static TimecodeRange v1_parse_line(std::string const& str) { TimecodeRange range; char comma1, comma2; ss >> range.start >> comma1 >> range.end >> comma2 >> range.fps; - if (ss.fail() || comma1 != ',' || comma2 != ',' || !ss.eof()) { + if (ss.fail() || comma1 != ',' || comma2 != ',' || !ss.eof()) throw MalformedLine(str); - } - if (range.start < 0 || range.end < 0) { + if (range.start < 0 || range.end < 0) throw UnorderedTimecodes("Cannot specify frame rate for negative frames."); - } - if (range.end < range.start) { + if (range.end < range.start) throw UnorderedTimecodes("End frame must be greater than or equal to start frame"); - } - if (range.fps <= 0.) { + if (range.fps <= 0.) throw BadFPS("FPS must be greater than zero"); - } - if (range.fps > 1000.) { + if (range.fps > 1000.) // This is our limitation, not mkvmerge's // mkvmerge uses nanoseconds internally throw BadFPS("FPS must be at most 1000"); - } return range; } -/// @brief Is the timecode range a comment line? -static bool v1_invalid_timecode(TimecodeRange const& range) { - return range.fps == 0.; -} - /// @brief Generate override ranges for all frames with assumed fpses /// @param ranges List with ranges which is mutated /// @param fps Assumed fps to use for gaps static void v1_fill_range_gaps(std::list &ranges, double fps) { // Range for frames between start and first override - if (ranges.empty() || ranges.front().start > 0) { - TimecodeRange range; - range.fps = fps; - range.start = 0; - range.end = ranges.empty() ? 0 : ranges.front().start - 1; - ranges.push_front(range); - } + if (ranges.empty() || ranges.front().start > 0) + ranges.emplace_front(0, ranges.empty() ? 0 : ranges.front().start - 1, fps); + std::list::iterator cur = ++ranges.begin(); std::list::iterator prev = ranges.begin(); for (; cur != ranges.end(); ++cur, ++prev) { - if (prev->end >= cur->start) { + if (prev->end >= cur->start) // mkvmerge allows overlapping timecode ranges, but does completely // broken things with them throw UnorderedTimecodes("Override ranges must not overlap"); - } if (prev->end + 1 < cur->start) { - TimecodeRange range; - range.fps = fps; - range.start = prev->end + 1; - range.end = cur->start - 1; - ranges.insert(cur, range); + ranges.emplace(cur, prev->end + 1, cur->start -1, fps); ++prev; } } @@ -150,24 +127,23 @@ static void v1_fill_range_gaps(std::list &ranges, double fps) { /// @param[out] last Unrounded time of the last frame /// @return Assumed fps times one million static int64_t v1_parse(line_iterator file, std::string line, std::vector &timecodes, int64_t &last) { - using namespace std; double fps = atof(line.substr(7).c_str()); if (fps <= 0.) throw BadFPS("Assumed FPS must be greater than zero"); if (fps > 1000.) throw BadFPS("Assumed FPS must not be greater than 1000"); - list ranges; - transform(file, line_iterator(), back_inserter(ranges), v1_parse_line); - ranges.erase(remove_if(ranges.begin(), ranges.end(), v1_invalid_timecode), ranges.end()); + std::list ranges; + transform(file, line_iterator(), back_inserter(ranges), v1_parse_line); + ranges.erase(boost::remove_if(ranges, [](TimecodeRange const& r) { return r.fps == 0; }), ranges.end()); ranges.sort(); v1_fill_range_gaps(ranges, fps); timecodes.reserve(ranges.back().end); double time = 0.; - for (list::iterator cur = ranges.begin(); cur != ranges.end(); ++cur) { - for (int frame = cur->start; frame <= cur->end; frame++) { + for (auto const& range : ranges) { + for (int frame = range.start; frame <= range.end; ++frame) { timecodes.push_back(int(time + .5)); - time += 1000. / cur->fps; + time += 1000. / range.fps; } } timecodes.push_back(int(time + .5)); @@ -229,20 +205,18 @@ Framerate::Framerate(std::string const& filename) : denominator(default_denominator) , numerator(0) { - using namespace std; - scoped_ptr file(agi::io::Open(filename)); - string encoding = agi::charset::Detect(filename); - string line = *line_iterator(*file, encoding); + scoped_ptr file(agi::io::Open(filename)); + std::string encoding = agi::charset::Detect(filename); + std::string line = *line_iterator(*file, encoding); if (line == "# timecode format v2") { copy(line_iterator(*file, encoding), line_iterator(), back_inserter(timecodes)); SetFromTimecodes(); return; } if (line == "# timecode format v1" || line.substr(0, 7) == "Assume ") { - if (line[0] == '#') { - line = *line_iterator(*file, encoding); - } - numerator = v1_parse(line_iterator(*file, encoding), line, timecodes, last); + if (line[0] == '#') + line = *line_iterator(*file, encoding); + numerator = v1_parse(line_iterator(*file, encoding), line, timecodes, last); return; } @@ -254,10 +228,9 @@ void Framerate::Save(std::string const& filename, int length) const { std::ofstream &out = file.Get(); out << "# timecode format v2\n"; - std::copy(timecodes.begin(), timecodes.end(), std::ostream_iterator(out, "\n")); - for (int written = (int)timecodes.size(); written < length; ++written) { + boost::copy(timecodes, std::ostream_iterator(out, "\n")); + for (int written = (int)timecodes.size(); written < length; ++written) out << TimeAtFrame(written) << std::endl; - } } int Framerate::FrameAtTime(int ms, Time type) const { @@ -274,12 +247,10 @@ int Framerate::FrameAtTime(int ms, Time type) const { // Combining these allows us to easily calculate START and END in terms of // EXACT - if (type == START) { + if (type == START) return FrameAtTime(ms - 1) + 1; - } - if (type == END) { + if (type == END) return FrameAtTime(ms - 1); - } if (ms < 0) return int((ms * numerator / denominator - 999) / 1000); diff --git a/aegisub/libaegisub/include/libaegisub/signal.h b/aegisub/libaegisub/include/libaegisub/signal.h index 88aa20e96..770493efb 100644 --- a/aegisub/libaegisub/include/libaegisub/signal.h +++ b/aegisub/libaegisub/include/libaegisub/signal.h @@ -115,7 +115,7 @@ namespace detail { /// Used by the signal when the signal wishes to end a connection (such /// as if the signal is being destroyed while slots are still connected /// to it) - void DisconnectToken(ConnectionToken *tok) { tok->signal = NULL; } + void DisconnectToken(ConnectionToken *tok) { tok->signal = nullptr; } /// @brief Has a token been claimed by a scoped connection object? bool TokenClaimed(ConnectionToken *tok) { return tok->claimed; } @@ -129,7 +129,7 @@ namespace detail { inline void ConnectionToken::Disconnect() { if (signal) signal->Disconnect(this); - signal = NULL; + signal = nullptr; } /// @brief Templated common code for signals @@ -176,7 +176,7 @@ namespace detail { } #define SIGNALS_H_FOR_EACH_SIGNAL(...) \ - for (typename super::SlotMap::iterator cur = slots.begin(); cur != slots.end();) { \ + for (auto cur = slots.begin(); cur != slots.end();) { \ if (Blocked(cur->first)) \ ++cur; \ else \ @@ -261,16 +261,11 @@ class Signal : public detail::SignalBaseImpl > { using super::slots; public: Signal() { } -// Work around compilters that can't tell this is a template context due to it -// being fully specified, making typename invalid here. -#define typename - /// @brief Trigger this signal /// /// The order in which connected slots are called is undefined and should /// not be relied on void operator()() { SIGNALS_H_FOR_EACH_SIGNAL() } -#undef typename }; #undef SIGNALS_H_FOR_EACH_SIGNAL diff --git a/aegisub/libaegisub/windows/access.cpp b/aegisub/libaegisub/windows/access.cpp index 38ab15cd2..d90b299bd 100644 --- a/aegisub/libaegisub/windows/access.cpp +++ b/aegisub/libaegisub/windows/access.cpp @@ -105,7 +105,7 @@ void Check(const std::string &file, acs::Type type) { SECURITY_INFORMATION info = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION; DWORD len = 0; - GetFileSecurity(wfile.c_str(), info, NULL, 0, &len); + GetFileSecurity(wfile.c_str(), info, nullptr, 0, &len); if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) LOG_W("acs/check") << "GetFileSecurity: fatal: " << util::ErrorString(GetLastError()); diff --git a/aegisub/libaegisub/windows/util_win.cpp b/aegisub/libaegisub/windows/util_win.cpp index 2c84d1b11..ba70c355b 100644 --- a/aegisub/libaegisub/windows/util_win.cpp +++ b/aegisub/libaegisub/windows/util_win.cpp @@ -60,9 +60,9 @@ void Rename(const std::string& from, const std::string& to) { } std::string ErrorString(DWORD error) { - LPWSTR lpstr = NULL; + LPWSTR lpstr = nullptr; - if(FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, reinterpret_cast(&lpstr), 0, NULL) == 0) { + if(FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, nullptr, error, 0, reinterpret_cast(&lpstr), 0, nullptr) == 0) { /// @todo Return the actual 'unknown error' string from windows. return "Unknown Error"; }