32 std::vector<bool> mask_;
40 : base_(base), f1_(f1), f2_(f2) {
44 size_t l = pattern.length();
45 bool exact = (l > 2 && pattern[l -1] ==
'"' && pattern[0] ==
'"');
47 Init_exact(n, name_type, pattern.substr(1, l -2));
49 Init_icase_ignoreSpaces(n, name_type, pattern.c_str());
53 void Init_exact (
idNumberT n,
nameT name_type, std::string pattern) {
57 mask_[i] = (name == pattern);
61 void Init_icase_ignoreSpaces(
idNumberT n,
nameT name_type,
const char* pattern) {
69 bool operator() (
gamenumT gnum)
const {
71 if (!res && f2_ != 0) {
78 class SearchSiteCountry {
80 std::vector<bool> mask_;
89 std::transform(country.begin(), country.end(), country.begin(), ::toupper);
93 const char* it = site;
94 while (*it != 0) it++;
95 if (std::distance(site, it) > 3) it -= 3;
97 std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::toupper);
98 mask_[i] = (tmp == country);
102 bool operator() (
gamenumT gnum)
const {
119 bool operator() (
gamenumT gnum)
const {
134 while (*results != 0) {
136 if (it != end) result_[std::distance(
RESULT_CHAR, it)] =
true;
141 bool operator() (
gamenumT gnum)
const {
147 template <
typename T>
148 class SearchRange :
public StrRange {
156 : base_(base), f_(f) {}
162 :
StrRange(range), base_(base), f_(f) {}
164 bool operator() (
gamenumT gnum)
const {
170 class SearchRangeDate :
public SearchRange<dateT> {
175 : SearchRange<
dateT>(base, f) {
181 if (min_ > max_) std::swap(min_, max_);
185 class SearchRangeEco :
public SearchRange<ecoT> {
190 : SearchRange<
ecoT>(base, f) {
196 if (min_ > max_) std::swap(min_, max_);
203 class SearchRangeGamenum :
public SearchRange<gamenumT> {
205 SearchRangeGamenum(
const scidBaseT* base,
207 : SearchRange<
gamenumT>(base, range, 0) {
211 if (min_ < 0) min_ += base->
numGames();
213 if (max_ < 0) max_ += base->
numGames();
215 if (min_ > max_) std::swap(min_, max_);
218 bool operator() (
gamenumT gnum)
const {
219 if (static_cast<long>(gnum) < min_ ||
220 static_cast<long>(gnum) > max_)
return false;
225 class SearchRangeElo :
public SearchRange<eloT> {
236 : SearchRange<
eloT>(base, range, 0), fElo1_(f1), fElo2_(f2) {
240 bool operator() (
gamenumT gnum)
const {
243 if (fElo2_ != 0) v2 = (base_->
getIndexEntry(gnum)->*fElo2_)(nb_);
244 if (v1 < min_ || v1 > max_ || v2 < min_ || v2 > max_)
return false;
249 class SearchRangeEloDiff :
public SearchRangeElo {
251 SearchRangeEloDiff(
const scidBaseT* base,
255 : SearchRangeElo(base, range, f1, f2) {}
257 bool operator() (
gamenumT gnum)
const {
261 if (v < min_ || v > max_)
return false;
284 SearchParam(
const char* op,
const char* value)
285 : value_(value), opNot_(false), opOr_(false) {
286 if (op != 0 && value_ != 0 && value_[0] != 0) {
288 if (op_.length() > 1 && op_[0] ==
'-') {
291 size_t extra = op_.find_last_not_of(
"!|");
292 if (extra == std::string::npos) {
294 }
else if (++extra < op_.length()) {
295 if (op_.find(
'!', extra) != std::string::npos) opNot_ =
true;
296 if (op_.find(
'|', extra) != std::string::npos) opOr_ =
true;
309 bool operator!()
const {
return op_.empty(); }
316 const char* getValue()
const {
return value_; }
317 bool isNot()
const {
return opNot_; }
318 bool isOr()
const {
return opOr_; }
327 std::vector<SearchParam> parseParams(
int argc,
const char ** argv,
filterOpT& filterOp) {
328 std::vector<SearchParam> res;
330 for (
int i=0; (i+1) < argc; i += 2) {
331 SearchParam p(argv[i], argv[i+1]);
359 std::vector<gamenumT> res;
366 res.resize(filter->
size());
371 res.resize(excluded.size());
372 std::copy(excluded.begin(), excluded.end(), res.begin());
390 I doSearch(I itB, I itR, I itE,
const scidBaseT* base, SearchParam& param) {
391 if (param ==
"player")
return std::stable_partition(itB, itE,
394 if (param ==
"white")
return std::stable_partition(itB, itE,
397 if (param ==
"black")
return std::stable_partition(itB, itE,
400 if (param ==
"event")
return std::stable_partition(itB, itE,
403 if (param ==
"site")
return std::stable_partition(itB, itE,
406 if (param ==
"sitecountry")
return std::stable_partition(itB, itE,
407 SearchSiteCountry(base, param.getValue())
409 if (param ==
"round")
return std::stable_partition(itB, itE,
412 if (param ==
"date")
return std::stable_partition(itB, itE,
415 if (param ==
"eventdate")
return std::stable_partition(itB, itE,
418 if (param ==
"elo")
return std::stable_partition(itB, itE,
421 if (param ==
"welo")
return std::stable_partition(itB, itE,
424 if (param ==
"belo")
return std::stable_partition(itB, itE,
427 if (param ==
"delo")
return std::stable_partition(itB, itE,
430 if (param ==
"eco")
return std::stable_partition(itB, itE,
433 if (param ==
"gnum")
return std::stable_partition(itB, itE,
434 SearchRangeGamenum(base, param.getValue())
436 if (param ==
"length")
return std::stable_partition(itB, itE,
439 if (param ==
"n_variations")
return std::stable_partition(itB, itE,
442 if (param ==
"n_comments")
return std::stable_partition(itB, itE,
445 if (param ==
"n_nags")
return std::stable_partition(itB, itE,
448 if (param ==
"flag")
return std::stable_partition(itB, itE,
449 SearchFlag(base, param.getValue())
451 if (param ==
"result")
return std::stable_partition(itB, itE,
452 SearchResult(base, param.getValue())
502 const char** argv,
const Progress& progress) {
507 std::vector<SearchParam> params = parseParams(argc, argv, filterOp);
508 std::vector<gamenumT> glist = collectGames(filter, filterOp);
512 typedef std::vector<gamenumT>::iterator iter;
513 iter it_begin = glist.begin();
514 iter it_end = glist.end();
515 iter it_res = glist.end();
516 for (
size_t i = 0, n = params.size(); i < n; i++) {
519 if (params[i].isOr()) {
525 it_begin = glist.begin();
532 it_res = doSearch(it_begin, it_res, it_end, base, params[i]);
534 if (params[i].isNot()) {
538 std::rotate(it_begin, it_res, it_end);
539 it_res = it_begin + (it_end - it_res);
545 for (iter it = it_res; it != glist.end(); ++it)
550 for (iter it = glist.begin(); it != it_res; ++it)
const IndexEntry * getIndexEntry(gamenumT g) const
const_iterator end() const
const uint NUM_RESULT_TYPES
resultT GetResult() const
static uint32_t StrToFlagMask(const char *flags)
ecoT eco_LastSubCode(ecoT eco)
idNumberT GetSite() const
idNumberT GetEvent() const
void erase(gamenumT gnum)
class StrRange - parse a string interpreting its content as 1 or 2 integers separated by whitespace...
uint16_t GetNumHalfMoves() const
const char * GetName(nameT nt, idNumberT id) const
Retrieve a name.
errorT search_index(const scidBaseT *base, HFilter &filter, int argc, const char **argv, const Progress &progress)
search_index() - search for games using game's IndexEntry info
int find(const char *filename)
find() - search for a database.
bool GetFlag(uint32_t mask) const
This class stores the database's names (players, events, sites and rounds).
filterOpT strGetFilterOp(const char *str)
const errorT ERROR_UserCancel
idNumberT GetRound() const
idNumberT GetWhite() const
const char RESULT_CHAR[4]
bool strAlphaContains(const char *longStr, const char *keyStr)
uint GetCommentCount() const
idNumberT GetBlack() const
bool operator==(const simpleMoveT &a, const cmpMove &b)
const char * strNextWord(const char *str)
bool report(size_t done, size_t total) const
const char * strFirstWord(const char *str)
gamenumT numGames() const
ecoT eco_FromString(const char *ecoStr)
const_iterator begin() const
idNumberT GetNumNames(nameT nt) const
const NameBase * getNameBase() const
void set(gamenumT gnum, byte value)
dateT date_EncodeFromString(const char *str)
uint GetVariationCount() const
dateT GetEventDate() const
class HFilterInverted - iterate through games excluded from a filter