8
using std::back_inserter;
12
using std::equal_range;
14
#include "gui_action.hxx"
19
const char * const name;
22
// The getActionName() function assumes that the following array is sorted by
23
// action number, and further that it can be indexed by action number based on
24
// the action number of the first entry.
26
const ActionNameNum action_names [] =
28
#define ACT(_name) { ACT_ ## _name, # _name },
29
#include "gui_action.names"
34
const int ACTION_NAME_COUNT = sizeof (action_names) / sizeof (action_names[0]);
36
// One might think to use a map here, instead of a vector (and in fact I did),
37
// but Scott Meyers in _Effective STL_ advises (in item 23) that it is more
38
// efficient to use a sorted vector when we are doing a bunch of insertions
39
// followed by mostly (in our case exclusively) lookups.
41
typedef pair <const char *, Action> ActionNamePair;
42
typedef vector <ActionNamePair> ActionNameVec;
43
typedef ActionNameVec::iterator ActionNameIter;
45
class ActionNameCompare
48
bool operator () (const ActionNamePair & lhs, // for sorting
49
const ActionNamePair & rhs) const
51
return doLess (lhs.first, rhs.first);
54
bool operator () (const ActionNamePair & lhs, // for lookups 1
55
const ActionNamePair::first_type & rhs) const
57
return doLess (lhs.first, rhs);
60
bool operator () (const ActionNamePair::first_type & lhs, // for lookups 2
61
const ActionNamePair & rhs) const
63
return doLess (lhs, rhs.first);
68
bool doLess (const ActionNamePair::first_type & lhs,
69
const ActionNamePair::first_type & rhs) const
71
return (strcasecmp (lhs, rhs) < 0);
75
class MakeActionNamePair
78
ActionNamePair operator () (const ActionNameNum & ann)
80
return make_pair (ann.name, ann.num);
84
static ActionNameVec action_name_vec;
86
void initActionNameVec (void)
88
action_name_vec.reserve (ACTION_NAME_COUNT);
89
transform (action_names, action_names + ACTION_NAME_COUNT,
90
back_inserter (action_name_vec), MakeActionNamePair());
91
sort (action_name_vec.begin(), action_name_vec.end(),
95
Action lookupActionByName (const char * name)
97
if (action_name_vec.empty())
100
pair <ActionNameIter, ActionNameIter> range
101
= equal_range (action_name_vec.begin(),
102
action_name_vec.end(), name,
103
ActionNameCompare());
104
if (range.first == range.second)
107
return range.first->second;
110
const char * getActionName (Action act)
112
uint32_t index = act - action_names [0].num;
113
return (action_names [index].name);
116
void dumpActionNames (const char * filename)
118
if (action_name_vec.empty())
121
printf ("# Action names (which can be used in %s, "
122
"though some should not be):\n", filename);
123
ActionNameIter it = action_name_vec.begin();
124
while (it != action_name_vec.end())
126
printf ("# %s\n", it->first);