forked from CleverRaven/Cataclysm-DDA
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathitem_search.h
100 lines (90 loc) · 3.42 KB
/
item_search.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#pragma once
#ifndef CATA_SRC_ITEM_SEARCH_H
#define CATA_SRC_ITEM_SEARCH_H
#include <algorithm>
#include <cstddef>
#include <functional>
#include <iosfwd>
#include <string>
#include <vector>
#include "output.h"
/**
* Get a function that returns true if the value matches the query.
*/
template<typename T>
std::function<bool( const T & )> filter_from_string( std::string filter,
std::function<std::function<bool( const T & )>( const std::string & )> basic_filter )
{
if( filter.empty() ) {
// Variable without name prevents unused parameter warning
return []( const T & ) {
return true;
};
}
// remove curly braces (they only get in the way)
if( filter.find( '{' ) != std::string::npos ) {
filter.erase( std::remove( filter.begin(), filter.end(), '{' ), filter.end() );
}
if( filter.find( '}' ) != std::string::npos ) {
filter.erase( std::remove( filter.begin(), filter.end(), '}' ), filter.end() );
}
if( filter.find( ',' ) != std::string::npos ) {
// functions which only one of which must return true
std::vector<std::function<bool( const T & )> > functions;
// Functions that must all return true
std::vector<std::function<bool( const T & )> > inv_functions;
size_t comma = filter.find( ',' );
while( !filter.empty() ) {
const std::string ¤t_filter = trim( filter.substr( 0, comma ) );
if( !current_filter.empty() ) {
auto current_func = filter_from_string( current_filter, basic_filter );
if( current_filter[0] == '-' ) {
inv_functions.push_back( current_func );
} else {
functions.push_back( current_func );
}
}
if( comma != std::string::npos ) {
filter = trim( filter.substr( comma + 1 ) );
comma = filter.find( ',' );
} else {
break;
}
}
return [functions, inv_functions]( const T & it ) {
auto apply = [&]( const std::function<bool( const T & )> &func ) {
return func( it );
};
const bool p_result = std::any_of( functions.begin(), functions.end(),
apply );
const bool n_result = std::all_of(
inv_functions.begin(),
inv_functions.end(),
apply );
if( !functions.empty() && inv_functions.empty() ) {
return p_result;
}
if( functions.empty() && !inv_functions.empty() ) {
return n_result;
}
return p_result && n_result;
};
}
const bool exclude = filter[0] == '-';
if( exclude ) {
return [filter, basic_filter]( const T & i ) {
return !filter_from_string( filter.substr( 1 ), basic_filter )( i );
};
}
return basic_filter( filter );
}
class item;
/**
* Get a function that returns true if the item matches the query.
*/
std::function<bool( const item & )> item_filter_from_string( const std::string &filter );
/**
* Get a function that returns true if the value matches the basic query (no commas or minuses).
*/
std::function<bool( const item & )> basic_item_filter( std::string filter );
#endif // CATA_SRC_ITEM_SEARCH_H