Here's a minor patch in case it's of use - but feel free to tell me to
shut up if it isn't.
Looking at some of the file-handling code I noticed that a lot of places
check a string for a particular prefix or suffix with this kind of pattern:
if (
(text.size() >= suffix.size()) &&
(text.substr(text.size()-suffix.size()) == suffix)) {
It's a bit hard to read, and could lead to strange crashes if you forget
the length check. For example, checking for...
filename.substr(filename.size()-3) == ".gz"
...would crash if filename was less than 3 characters long.
If anyone's interested, I'm attaching a patch that replaces all
prefix/suffix checks that I could find with BOOST's starts_with() and
ends_with(). It's a little safer and easier to follow, and doesn't make
you count the characters in a fixed-length suffix:
if (ends_with(text, suffix)) {
if (ends_with(filename, ".gz")) {
if (starts_with(item, "[") && ends_with(item, "]")) {
None of these cases looked particularly performance-sensitive, but I
checked just in case. If anything, the BOOST code looks more
optimizer-friendly. It compares characters in-place (so no need to copy
a substring) and seems to optimize for the known length of string
constants (so it knows at compile time that ".gz" is 3 characters long).
I haven't done any manual testing, but the unit tests pass. Is that
considered a reasonable guarantee?
Jeroen
diff --git a/OnDiskPt/Word.cpp b/OnDiskPt/Word.cpp
index 9e6fb65..8932732 100644
--- a/OnDiskPt/Word.cpp
+++ b/OnDiskPt/Word.cpp
@@ -18,6 +18,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
***********************************************************************/
+#include <boost/algorithm/string/predicate.hpp>
#include "moses/FactorCollection.h"
#include "moses/Util.h"
#include "moses/Word.h"
@@ -27,6 +28,7 @@
#include "util/exception.hh"
using namespace std;
+using namespace boost::algorithm;
namespace OnDiskPt
{
@@ -41,7 +43,7 @@ Word::~Word()
void Word::CreateFromString(const std::string &inString, Vocab &vocab)
{
- if (inString.substr(0, 1) == "[" && inString.substr(inString.size() - 1, 1) == "]") {
+ if (starts_with(inString, "[") && ends_with(inString, "]")) {
// non-term
m_isNonTerminal = true;
string str = inString.substr(1, inString.size() - 2);
diff --git a/contrib/other-builds/manual-label/EnOpenNLPChunker.cpp b/contrib/other-builds/manual-label/EnOpenNLPChunker.cpp
index 67c2e9d..e2c2935 100644
--- a/contrib/other-builds/manual-label/EnOpenNLPChunker.cpp
+++ b/contrib/other-builds/manual-label/EnOpenNLPChunker.cpp
@@ -8,10 +8,12 @@
#include <stdio.h>
#include <algorithm>
#include <fstream>
+#include <boost/algorithm/string/predicate.hpp>
#include "EnOpenNLPChunker.h"
#include "moses/Util.h"
using namespace std;
+using namespace boost::algorithm;
EnOpenNLPChunker::EnOpenNLPChunker(const std::string &openNLPPath)
:m_openNLPPath(openNLPPath)
@@ -85,7 +87,7 @@ void EnOpenNLPChunker::MosesReformat(const string &line, std::ostream &out, cons
inLabel = true;
}
}
- else if (tok.substr(tok.size()-1, 1) == "]") {
+ else if (ends_with(tok, "]")) {
// end of chunk
if (tok.size() > 1) {
if (tok.substr(1,1) == "_") {
diff --git a/moses/FF/LexicalReordering/LexicalReordering.cpp b/moses/FF/LexicalReordering/LexicalReordering.cpp
index 7be2f1d..0630d10 100644
--- a/moses/FF/LexicalReordering/LexicalReordering.cpp
+++ b/moses/FF/LexicalReordering/LexicalReordering.cpp
@@ -1,4 +1,5 @@
#include <sstream>
+#include <boost/algorithm/string/predicate.hpp>
#include "moses/FF/FFState.h"
#include "LexicalReordering.h"
@@ -6,6 +7,7 @@
#include "moses/StaticData.h"
using namespace std;
+using namespace boost::algorithm;
namespace Moses
{
@@ -29,7 +31,7 @@ LexicalReordering::LexicalReordering(const std::string &line)
m_factorsE =Tokenize<FactorType>(args[1]);
} else if (args[0] == "path") {
m_filePath = args[1];
- } else if (args[0].substr(0,7) == "sparse-") {
+ } else if (starts_with(args[0], "sparse-")) {
sparseArgs[args[0].substr(7)] = args[1];
} else if (args[0] == "default-scores") {
vector<string> tokens = Tokenize(args[1],",");
diff --git a/moses/Parameter.cpp b/moses/Parameter.cpp
index cd9d3b2..c5677b7 100644
--- a/moses/Parameter.cpp
+++ b/moses/Parameter.cpp
@@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#include <fstream>
#include <sstream>
#include <algorithm>
+#include <boost/algorithm/string/predicate.hpp>
#include "Parameter.h"
#include "Util.h"
#include "InputFileStream.h"
@@ -32,6 +33,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#include "util/exception.hh"
using namespace std;
+using namespace boost::algorithm;
namespace Moses
{
@@ -270,8 +272,9 @@ bool Parameter::isOption(const char* token)
if (! token) return false;
std::string tokenString(token);
size_t length = tokenString.size();
- if (length > 0 && tokenString.substr(0,1) != "-") return false;
- if (length > 1 && tokenString.substr(1,1).find_first_not_of("0123456789") == 0) return true;
+ if (length <= 1) return false;
+ if (!starts_with(tokenString, "-")) return false;
+ if (tokenString.substr(1,1).find_first_not_of("0123456789") == 0) return true;
return false;
}
@@ -975,7 +978,7 @@ void Parameter::WeightOverwrite()
for (size_t i = 0; i < toks.size(); ++i) {
const string &tok = toks[i];
- if (tok.substr(tok.size() - 1, 1) == "=") {
+ if (starts_with(tok, "=")) {
// start of new feature
if (name != "") {
diff --git a/moses/ScoreComponentCollection.cpp b/moses/ScoreComponentCollection.cpp
index b8c93c1..a1c8646 100644
--- a/moses/ScoreComponentCollection.cpp
+++ b/moses/ScoreComponentCollection.cpp
@@ -1,5 +1,6 @@
// $Id$
#include <vector>
+#include <boost/algorithm/string/predicate.hpp>
#include "util/exception.hh"
#include "ScoreComponentCollection.h"
#include "StaticData.h"
@@ -7,6 +8,7 @@
#include "moses/FF/StatefulFeatureFunction.h"
using namespace std;
+using namespace boost::algorithm;
namespace Moses
{
@@ -87,7 +89,7 @@ void ScoreComponentCollection::MultiplyEquals(const FeatureFunction* sp, float s
for(FVector::FNVmap::const_iterator i = m_scores.cbegin(); i != m_scores.cend(); i++) {
std::stringstream name;
name << i->first;
- if (name.str().substr( 0, prefix.length() ).compare( prefix ) == 0)
+ if (starts_with(name.str(), prefix))
m_scores[i->first] = i->second * scalar;
}
}
@@ -100,7 +102,7 @@ size_t ScoreComponentCollection::GetNumberWeights(const FeatureFunction* sp)
for(FVector::FNVmap::const_iterator i = m_scores.cbegin(); i != m_scores.cend(); i++) {
std::stringstream name;
name << i->first;
- if (name.str().substr( 0, prefix.length() ).compare( prefix ) == 0)
+ if (starts_with(name.str(), prefix))
weights++;
}
return weights;
@@ -285,7 +287,7 @@ FVector ScoreComponentCollection::GetVectorForProducer(const FeatureFunction* sp
for(FVector::FNVmap::const_iterator i = m_scores.cbegin(); i != m_scores.cend(); i++) {
std::stringstream name;
name << i->first;
- if (name.str().substr( 0, prefix.length() ).compare( prefix ) == 0)
+ if (starts_with(name.str(), prefix))
fv[i->first] = i->second;
}
return fv;
diff --git a/moses/StaticData.cpp b/moses/StaticData.cpp
index ce6d765..94d5381 100644
--- a/moses/StaticData.cpp
+++ b/moses/StaticData.cpp
@@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
***********************************************************************/
#include <string>
+#include <boost/algorithm/string/predicate.hpp>
#include "moses/FF/Factory.h"
#include "TypeDef.h"
@@ -50,6 +51,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#endif
using namespace std;
+using namespace boost::algorithm;
namespace Moses
{
@@ -1176,7 +1178,7 @@ void StaticData::ResetWeights(const std::string &denseWeights, const std::string
for (size_t i = 0; i < toks.size(); ++i) {
const string &tok = toks[i];
- if (tok.substr(tok.size() - 1, 1) == "=") {
+ if (ends_with(tok, "=")) {
// start of new feature
if (name != "") {
diff --git a/moses/TranslationModel/RuleTable/LoaderStandard.cpp b/moses/TranslationModel/RuleTable/LoaderStandard.cpp
index 410a53e..95463fe 100644
--- a/moses/TranslationModel/RuleTable/LoaderStandard.cpp
+++ b/moses/TranslationModel/RuleTable/LoaderStandard.cpp
@@ -26,6 +26,7 @@
#include <iostream>
#include <sys/stat.h>
#include <stdlib.h>
+#include <boost/algorithm/string/predicate.hpp>
#include "Trie.h"
#include "moses/FactorCollection.h"
#include "moses/Word.h"
@@ -42,6 +43,7 @@
#include "util/exception.hh"
using namespace std;
+using namespace boost::algorithm;
namespace Moses
{
@@ -67,8 +69,7 @@ void ReformatHieroRule(int sourceTarget, string &phrase, map<size_t, pair<size_t
for (size_t i = 0; i < toks.size(); ++i) {
string &tok = toks[i];
- size_t tokLen = tok.size();
- if (tok.substr(0, 1) == "[" && tok.substr(tokLen - 1, 1) == "]") {
+ if (starts_with(tok, "[") && ends_with(tok, "]")) {
// no-term
vector<string> split = Tokenize(tok, ",");
UTIL_THROW_IF2(split.size() != 2,
diff --git a/moses/TranslationModel/UG/generic/file_io/ug_stream.cpp b/moses/TranslationModel/UG/generic/file_io/ug_stream.cpp
index 4e0c7cb..073b64d 100644
--- a/moses/TranslationModel/UG/generic/file_io/ug_stream.cpp
+++ b/moses/TranslationModel/UG/generic/file_io/ug_stream.cpp
@@ -2,11 +2,13 @@
// (c) 2006,2007,2008 Ulrich Germann
// makes opening files a little more convenient
+#include <boost/algorithm/string/predicate.hpp>
#include "ug_stream.h"
namespace ugdiss
{
using namespace std;
+ using namespace boost::algorithm;
using namespace boost::iostreams;
filtering_istream*
@@ -28,11 +30,11 @@ namespace ugdiss
void
open_input_stream(string fname, filtering_istream& in)
{
- if (fname.size()>3 && fname.substr(fname.size()-3,3)==".gz")
+ if (ends_with(fname, ".gz"))
{
in.push(gzip_decompressor());
}
- else if (fname.size() > 4 && fname.substr(fname.size()-4,4)==".bz2")
+ else if (ends_with(fname, "bz2"))
{
in.push(bzip2_decompressor());
}
@@ -42,13 +44,11 @@ namespace ugdiss
void
open_output_stream(string fname, filtering_ostream& out)
{
- if ((fname.size() > 3 && fname.substr(fname.size()-3,3)==".gz") ||
- (fname.size() > 4 && fname.substr(fname.size()-4,4)==".gz_"))
+ if (ends_with(fname, ".gz") || ends_with(fname, ".gz_"))
{
out.push(gzip_compressor());
}
- else if ((fname.size() > 4 && fname.substr(fname.size()-4,4)==".bz2") ||
- (fname.size() > 5 && fname.substr(fname.size()-5,5)==".bz2_"))
+ else if (ends_with(fname, ".bz2") || ends_with(fname, ".bz2_"))
{
out.push(bzip2_compressor());
}
diff --git a/moses/TranslationModel/UG/mm/mtt-build.cc b/moses/TranslationModel/UG/mm/mtt-build.cc
index 49fd7f6..f49895e 100644
--- a/moses/TranslationModel/UG/mm/mtt-build.cc
+++ b/moses/TranslationModel/UG/mm/mtt-build.cc
@@ -4,6 +4,7 @@
// recognized based on the number of fields per line) into memory-mapped
// format. (c) 2007-2013 Ulrich Germann
+#include <boost/algorithm/string/predicate.hpp>
#include <boost/program_options.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
@@ -32,6 +33,7 @@ using namespace std;
using namespace ugdiss;
using namespace Moses;
using namespace boost;
+using namespace boost::algorithm;
namespace po=boost::program_options;
int with_pfas;
@@ -200,7 +202,7 @@ process_tagged_input(ostream& out,
vector<string> w; string f; istringstream buf(line);
while (buf>>f) w.push_back(f);
- if (w.size() == 0 || (w[0].size() >= 4 && w[0].substr(0,4) == "SID="))
+ if (w.size() == 0 || starts_with(w[0], "SID="))
new_sent = true;
else if (w.size() == 1 && w[0] == "<P>")
diff --git a/moses/TranslationModel/UG/spe-check-coverage.cc b/moses/TranslationModel/UG/spe-check-coverage.cc
index 039b4cd..4ab2d74 100644
--- a/moses/TranslationModel/UG/spe-check-coverage.cc
+++ b/moses/TranslationModel/UG/spe-check-coverage.cc
@@ -1,6 +1,7 @@
#include "mmsapt.h"
#include "moses/TranslationModel/PhraseDictionaryTreeAdaptor.h"
#include "moses/TranslationModel/UG/generic/program_options/ug_splice_arglist.h"
+#include <boost/algorithm/string/predicate.hpp>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <boost/tokenizer.hpp>
@@ -12,6 +13,7 @@ using namespace Moses;
using namespace bitext;
using namespace std;
using namespace boost;
+using namespace boost::algorithm;
vector<FactorType> fo(1,FactorType(0));
@@ -111,7 +113,7 @@ int main(int argc, char* argv[])
int dynprovidx = -1;
for (size_t i = 0; i < fname.size(); ++i)
{
- if (fname[i].substr(0,7) == "prov-1.")
+ if (starts_with(fname[i], "prov-1."))
dynprovidx = i;
}
cout << endl;
@@ -189,8 +191,8 @@ int main(int argc, char* argv[])
size_t j = x-idx.first;
float f = (mmsapt && mmsapt->isLogVal(j)) ? exp(scores[x]) : scores[x];
string fmt = (mmsapt && mmsapt->isInteger(j)) ? "%10d" : "%10.8f";
- if (fname[j].substr(0,3) == "lex") fmt = "%10.3e";
- if (fname[j].substr(0,7) == "prov-1.")
+ if (starts_with(fname[j], "lex")) fmt = "%10.3e";
+ else if (starts_with(fname[j], "prov-1."))
{
f = round(f/(1-f));
fmt = "%10d";
diff --git a/moses/Util.cpp b/moses/Util.cpp
index 24323f6..5b6f16e 100644
--- a/moses/Util.cpp
+++ b/moses/Util.cpp
@@ -32,6 +32,7 @@
#include <stdio.h>
#include <iostream>
#include <iomanip>
+#include <boost/algorithm/string/predicate.hpp>
#include "TypeDef.h"
#include "Util.h"
#include "Timer.h"
@@ -42,6 +43,7 @@
#include "moses/StaticData.h"
using namespace std;
+using namespace boost::algorithm;
namespace Moses
{
@@ -54,7 +56,7 @@ string GetTempFolder()
#ifdef _WIN32
char *tmpPath = getenv("TMP");
string str(tmpPath);
- if (str.substr(str.size() - 1, 1) != "\\")
+ if (!ends_with(str, "\\"))
str += "\\";
return str;
#else
diff --git a/moses/XmlOption.cpp b/moses/XmlOption.cpp
index 3ac4f6c..38b767d 100644
--- a/moses/XmlOption.cpp
+++ b/moses/XmlOption.cpp
@@ -24,6 +24,7 @@
#include <vector>
#include <string>
#include <iostream>
+#include <boost/algorithm/string/predicate.hpp>
#include <boost/foreach.hpp>
#include <boost/unordered_map.hpp>
#include "Util.h"
@@ -40,6 +41,7 @@
namespace Moses
{
using namespace std;
+using namespace boost::algorithm;
string ParseXmlTagAttribute(const string& tag,const string& attributeName)
{
@@ -73,7 +75,7 @@ string TrimXml(const string& str, const std::string& lbrackStr, const std::strin
if (str.size() < lbrackStr.length()+rbrackStr.length() ) return str;
// strip first and last character
- if (str.substr(0,lbrackStr.length()) == lbrackStr && str.substr(str.size()-rbrackStr.length()) == rbrackStr) {
+ if (starts_with(str, lbrackStr) && ends_with(str, rbrackStr)) {
return str.substr(lbrackStr.length(), str.size()-lbrackStr.length()-rbrackStr.length());
}
// not an xml token -> do nothing
@@ -371,7 +373,7 @@ bool ProcessAndStripXMLTags(string &line, vector<XmlOption*> &res, ReorderingCon
vector<float> ffWeights;
vector<string> toks = Tokenize(ParseXmlTagAttribute(tagContent,"weights"));
BOOST_FOREACH(string const& tok, toks) {
- if (tok.substr(tok.size() - 1, 1) == "=") {
+ if (ends_with(tok, "=")) {
// start new feature
if (ffName != "") {
// set previous feature weights
diff --git a/phrase-extract/OutputFileStream.cpp b/phrase-extract/OutputFileStream.cpp
index a61ce1a..15c2bd7 100644
--- a/phrase-extract/OutputFileStream.cpp
+++ b/phrase-extract/OutputFileStream.cpp
@@ -19,11 +19,13 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
***********************************************************************/
+#include <boost/algorithm/string/predicate.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include "OutputFileStream.h"
#include "gzfilebuf.h"
using namespace std;
+using namespace boost::algorithm;
namespace Moses
{
@@ -51,7 +53,7 @@ bool OutputFileStream::Open(const std::string &filePath)
return false;
}
- if (filePath.size() > 3 && filePath.substr(filePath.size() - 3, 3) == ".gz") {
+ if (ends_with(filePath, ".gz")) {
this->push(boost::iostreams::gzip_compressor());
}
this->push(*m_outFile);
diff --git a/phrase-extract/ScoreFeature.cpp b/phrase-extract/ScoreFeature.cpp
index c037ab5..0795ed7 100644
--- a/phrase-extract/ScoreFeature.cpp
+++ b/phrase-extract/ScoreFeature.cpp
@@ -17,11 +17,13 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
***********************************************************************/
+#include <boost/algorithm/string/predicate.hpp>
#include "ScoreFeature.h"
#include "DomainFeature.h"
#include "InternalStructFeature.h"
using namespace std;
+using namespace boost::algorithm;
namespace MosesTraining
{
@@ -41,7 +43,7 @@ void ScoreFeatureManager::configure(const std::vector<std::string> args)
for (size_t i = 0; i < args.size(); ++i) {
if (args[i] == "--IgnoreSentenceId") {
m_includeSentenceId = true;
- } else if (args[i].substr(0,8) == "--Domain") {
+ } else if (starts_with(args[i], "--Domain")) {
string type = args[i].substr(8);
++i;
UTIL_THROW_IF(i == args.size(), ScoreFeatureArgumentException, "Missing domain file");
@@ -59,7 +61,7 @@ void ScoreFeatureManager::configure(const std::vector<std::string> args)
}
domainAdded = true;
m_includeSentenceId = true;
- } else if (args[i].substr(0,14) == "--SparseDomain") {
+ } else if (starts_with(args[i], "--SparseDomain")) {
string type = args[i].substr(14);
++i;
UTIL_THROW_IF(i == args.size(), ScoreFeatureArgumentException, "Missing domain file");
diff --git a/phrase-extract/extract-mixed-syntax/InputFileStream.cpp b/phrase-extract/extract-mixed-syntax/InputFileStream.cpp
index d111903..ef77414 100644
--- a/phrase-extract/extract-mixed-syntax/InputFileStream.cpp
+++ b/phrase-extract/extract-mixed-syntax/InputFileStream.cpp
@@ -22,8 +22,10 @@
#include "InputFileStream.h"
#include "gzfilebuf.h"
#include <iostream>
+#include <boost/algorithm/string/predicate.hpp>
using namespace std;
+using namespace boost::algorithm;
namespace Moses
{
@@ -31,8 +33,7 @@ InputFileStream::InputFileStream(const std::string &filePath)
: std::istream(NULL)
, m_streambuf(NULL)
{
- if (filePath.size() > 3 &&
- filePath.substr(filePath.size() - 3, 3) == ".gz") {
+ if (ends_with(filePath, ".gz")) {
m_streambuf = new gzfilebuf(filePath.c_str());
} else {
std::filebuf* fb = new std::filebuf();
diff --git a/phrase-extract/lexical-reordering/InputFileStream.cpp b/phrase-extract/lexical-reordering/InputFileStream.cpp
index 013781c..89667a6 100755
--- a/phrase-extract/lexical-reordering/InputFileStream.cpp
+++ b/phrase-extract/lexical-reordering/InputFileStream.cpp
@@ -22,8 +22,10 @@
#include "InputFileStream.h"
#include "gzfilebuf.h"
#include <iostream>
+#include <boost/algorithm/string/predicate.hpp>
using namespace std;
+using namespace boost::algorithm;
namespace Moses
{
@@ -41,8 +43,7 @@ InputFileStream::~InputFileStream()
void InputFileStream::Open(const std::string &filePath)
{
- if (filePath.size() > 3 &&
- filePath.substr(filePath.size() - 3, 3) == ".gz") {
+ if (ends_with(filePath, ".gz")) {
m_streambuf = new gzfilebuf(filePath.c_str());
} else {
std::filebuf* fb = new std::filebuf();
diff --git a/phrase-extract/score-main.cpp b/phrase-extract/score-main.cpp
index bd1b54b..d652b2b 100644
--- a/phrase-extract/score-main.cpp
+++ b/phrase-extract/score-main.cpp
@@ -28,6 +28,7 @@
#include <set>
#include <vector>
#include <algorithm>
+#include <boost/algorithm/string/predicate.hpp>
#include <boost/unordered_map.hpp>
#include "ScoreFeature.h"
@@ -38,6 +39,7 @@
#include "OutputFileStream.h"
using namespace std;
+using namespace boost::algorithm;
using namespace MosesTraining;
namespace MosesTraining
@@ -904,10 +906,10 @@ void loadOrientationPriors(const std::string &fileNamePhraseOrientationPriors,
bool l2rFlag = false;
bool r2lFlag = false;
- if (!key.substr(0,4).compare("L2R_")) {
+ if (starts_with(key, "L2R_")) {
l2rFlag = true;
}
- if (!key.substr(0,4).compare("R2L_")) {
+ if (starts_with(key, "R2L_")) {
r2lFlag = true;
}
if (!l2rFlag && !r2lFlag) {
diff --git a/vw/ClassifierFactory.cpp b/vw/ClassifierFactory.cpp
index 286bf84..4d8ee4e 100644
--- a/vw/ClassifierFactory.cpp
+++ b/vw/ClassifierFactory.cpp
@@ -2,6 +2,9 @@
#include "vw.h"
#include "../moses/Util.h"
#include <iostream>
+#include <boost/algorithm/string/predicate.hpp>
+
+using namespace boost::algorithm;
namespace Discriminative
{
@@ -15,7 +18,7 @@ ClassifierFactory::ClassifierFactory(const std::string &modelFile, const std::st
ClassifierFactory::ClassifierFactory(const std::string &modelFilePrefix)
: m_lastId(0), m_train(true)
{
- if (modelFilePrefix.size() > 3 && modelFilePrefix.substr(modelFilePrefix.size() - 3, 3) == ".gz") {
+ if (ends_with(modelFilePrefix, ".gz")) {
m_modelFilePrefix = modelFilePrefix.substr(0, modelFilePrefix.size() - 3);
m_gzip = true;
} else {
diff --git a/vw/VWTrainer.cpp b/vw/VWTrainer.cpp
index dff58a1..e513de3 100644
--- a/vw/VWTrainer.cpp
+++ b/vw/VWTrainer.cpp
@@ -1,8 +1,10 @@
#include "Util.h"
#include "Classifier.h"
+#include <boost/algorithm/string/predicate.hpp>
#include <boost/iostreams/device/file.hpp>
using namespace std;
+using namespace boost::algorithm;
using namespace Moses;
namespace Discriminative
@@ -10,7 +12,7 @@ namespace Discriminative
VWTrainer::VWTrainer(const std::string &outputFile)
{
- if (outputFile.size() > 3 && outputFile.substr(outputFile.size() - 3, 3) == ".gz") {
+ if (ends_with(outputFile, ".gz")) {
m_bfos.push(boost::iostreams::gzip_compressor());
}
m_bfos.push(boost::iostreams::file_sink(outputFile));
_______________________________________________
Moses-support mailing list
[email protected]
http://mailman.mit.edu/mailman/listinfo/moses-support