-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patheasenum.xslt
More file actions
129 lines (124 loc) · 4.54 KB
/
Copy patheasenum.xslt
File metadata and controls
129 lines (124 loc) · 4.54 KB
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
<?xml version="1.0" encoding="UTF-8"?>
<!-- ======================================================================= -->
<!-- Creates a C++ header with a [S]erializable [ENUM]eration. -->
<!-- These are especially useful for categorial knobs in the command line parser. -->
<!-- ======================================================================= -->
<!-- Usage: xsltproc easenum.xslt input.xml > output.hpp -->
<!-- ======================================================================= -->
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:strip-space elements="*"/>
<xsl:template match="/enums">
<xsl:text>#pragma once
/**
* Auto-generated header file.
*/
#include <iostream>
#include <array>
</xsl:text>
<xsl:apply-templates />
</xsl:template>
<xsl:template match="enum">
<xsl:if test="@namespace">
<xsl:text>namespace </xsl:text>
<xsl:value-of select="@namespace" />
<xsl:text> { </xsl:text>
</xsl:if>
<xsl:text>class </xsl:text>
<xsl:value-of select="@name" />
<xsl:text> {
typedef std::array<const char*,</xsl:text>
<xsl:value-of select="count(item)" />
<xsl:text>> container_type;
</xsl:text>
<!-- Private section -->
<xsl:text>private:
</xsl:text>
<xsl:text>typedef uint8_t id_type;
</xsl:text>
<xsl:text>static const container_type value_names, value_descs;
</xsl:text>
<!-- Public section -->
<xsl:text>public:
</xsl:text>
<xsl:text>enum value : id_type {</xsl:text>
<xsl:for-each select="item">
<xsl:if test="position() != 1">
<xsl:text>,</xsl:text>
</xsl:if>
<xsl:value-of select="@name" />
</xsl:for-each>
<xsl:text>};
</xsl:text>
<xsl:text>static inline std::string desc() {
std::ostringstream s;
for (id_type i = 0; i < value_names.size(); ++i) {
if (i != 0) { s << " "; }
s << '[' << value_names[i] << "] " << value_descs[i];
}
return s.str();
}
static inline const char* desc(const value& x) { return value_descs[(id_type)x]; }
static inline const char* to_cstr(const value& x) { return value_names[(id_type)x]; }
static inline value from_cstr(const char* cstr) {
id_type result = value_names.size();
for (id_type i = 0; i < result; ++i) {
if (strcmp(value_names[i], cstr) == 0) {
result = i;
}
}
if (result == value_names.size()) {
std::ostringstream s;
s << "Cannot interpret '" << cstr << "'; excpeted one of {";
for (id_type i = 0; i < value_names.size(); ++i) {
if (i != 0) { s << ','; }
s << to_cstr((value)i);
}
s << "}.";
throw std::runtime_error(s.str());
}
return (value)result;
}
</xsl:text>
<!-- End of class -->
<xsl:text>};
</xsl:text>
<!-- Array of enum names -->
<xsl:text>const </xsl:text>
<xsl:value-of select="@name" />
<xsl:text>::container_type </xsl:text>
<xsl:value-of select="@name" />
<xsl:text>::value_names = {</xsl:text>
<xsl:for-each select="item">
<xsl:if test="position() != 1">
<xsl:text>,</xsl:text>
</xsl:if>
<xsl:text>"</xsl:text>
<xsl:value-of select="@name" />
<xsl:text>"</xsl:text>
</xsl:for-each>
<xsl:text>};
</xsl:text>
<!-- Array of enum descriptions -->
<xsl:text>const </xsl:text>
<xsl:value-of select="@name" />
<xsl:text>::container_type </xsl:text>
<xsl:value-of select="@name" />
<xsl:text>::value_descs = {</xsl:text>
<xsl:for-each select="item">
<xsl:if test="position() != 1">
<xsl:text>,</xsl:text>
</xsl:if>
<xsl:text>"</xsl:text>
<xsl:value-of select="." />
<xsl:text>"</xsl:text>
</xsl:for-each>
<xsl:text>};
</xsl:text>
<!-- (de)serializer functions -->
<xsl:text>inline std::ostream& operator<<(std::ostream& os, const </xsl:text>
<xsl:value-of select="@name" />
<xsl:text>::value& x) { return os << </xsl:text>
<xsl:value-of select="@name" />
<xsl:text>::to_cstr(x); }
</xsl:text>
<xsl:text>inline std::istream& operator>>(std::istream& is, </xsl:text>
<xsl:value-of select="@name" />
<xsl:text>::value& x) { std::string str; is >> str; x = </xsl:text>
<xsl:value-of select="@name" />
<xsl:text>::from_cstr(str.c_str()); return is; }
</xsl:text>
<!-- End namespace -->
<xsl:if test="@namespace">
<xsl:text>}
</xsl:text>
</xsl:if>
</xsl:template>
</xsl:transform>