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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
//
// It is expected that the code of this program will be extended by the
// users of the "geners" package as they develop their storable classes.
// To add printing capability for archived objects of a new class,
// make sure that "operator<<" is defined between std::ostream and this
// class. Then add the relevant header file below and insert the
// "printable_type" statement for your class together with other similar
// statements already present in this program.
//
#include <memory>
#include "Alignment/Geners/interface/ClassId.hh"
#include "Alignment/Geners/interface/MultiFileArchive.hh"
#include "Alignment/Geners/interface/Reference.hh"
#include "Alignment/Geners/interface/complexIO.hh"
#include "CmdLine.hh"
#include <iostream>
#include <map>
#include <memory>
#include <set>
using namespace gs;
using namespace std;
static void print_usage(const char *progname) {
cout << "\nUsage: " << progname << " [-n] [-c] archive_name item_name item_category\n\n"
<< "Optional switches \"-n\" and \"-c\" turn on regular expression "
"search for item\n"
<< "name and category, respectively. For each matching item, the "
"program prints\n"
<< "its class and its text representation, as defined by \"operator "
"<<\".\n"
<< endl;
}
namespace {
typedef unsigned long (*PrinterFunction)(MultiFileArchive &, const SearchSpecifier &, const SearchSpecifier &);
template <class T>
struct Printer {
static unsigned long print(MultiFileArchive &ar, const SearchSpecifier &name, const SearchSpecifier &category) {
ClassId id(ClassId::makeId<T>());
Reference<T> ref(ar, name, category);
const unsigned long nItems = ref.size();
for (unsigned long i = 0; i < nItems; ++i)
cout << id.name() << " " << *ref.get(i) << endl;
return nItems;
}
};
} // namespace
#define printable_type(sometype) \
do { \
ClassId id(ClassId::makeId<sometype>()); \
typemap[id.name()] = &Printer<sometype>::print; \
} while (0);
int main(int argc, char const *argv[]) {
typedef std::map<std::string, PrinterFunction> Typemap;
CmdLine cmdline(argc, argv);
if (argc == 1) {
print_usage(cmdline.progname());
return 0;
}
bool useRegexForName = false, useRegexForCategory = false;
std::string archiveName, nameIn, categoryIn;
try {
useRegexForName = cmdline.has("-n");
useRegexForCategory = cmdline.has("-c");
cmdline.optend();
const unsigned cmdargc = cmdline.argc();
if (cmdargc != 3)
throw CmdLineError("wrong number of command line arguments");
cmdline >> archiveName >> nameIn >> categoryIn;
} catch (CmdLineError &e) {
cerr << "Error in " << cmdline.progname() << ": " << e.str() << endl;
print_usage(cmdline.progname());
return 1;
}
MultiFileArchive mar(archiveName.c_str(), "r");
if (!mar.isOpen()) {
cerr << mar.error() << endl;
return 1;
}
SearchSpecifier name(nameIn, useRegexForName);
SearchSpecifier category(categoryIn, useRegexForCategory);
std::vector<unsigned long long> found;
mar.itemSearch(name, category, &found);
const unsigned long nfound = found.size();
if (!nfound) {
cout << "No items found" << endl;
return 0;
}
Typemap typemap;
// You can add more printable types to the following collection
// as long as the type supports "<<" operator with ostream
printable_type(bool);
printable_type(char);
printable_type(unsigned char);
printable_type(signed char);
printable_type(short);
printable_type(unsigned short);
printable_type(int);
printable_type(long);
printable_type(long long);
printable_type(unsigned);
printable_type(unsigned long);
printable_type(unsigned long long);
printable_type(float);
printable_type(double);
printable_type(long double);
printable_type(std::complex<float>);
printable_type(std::complex<double>);
printable_type(std::complex<long double>);
printable_type(std::string);
// We need to call the generic printer exactly once for each distinct
// type of the items satisfying the search criterion
std::set<std::string> typenames;
unsigned long nprinted = 0;
for (unsigned long i = 0; i < nfound; ++i) {
std::shared_ptr<const CatalogEntry> entry = mar.catalogEntry(found[i]);
const ClassId &type = entry->type();
const std::string &tname = type.name();
if (typenames.insert(tname).second) {
Typemap::iterator it = typemap.find(tname);
if (it != typemap.end())
nprinted += (*it->second)(mar, name, category);
}
}
if (nprinted != nfound) {
const unsigned long notprinted = nfound - nprinted;
cout << "Found " << notprinted << " non-printable item" << (notprinted == 1UL ? "" : "s") << endl;
}
return 0;
}
|