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
|
#ifndef _AST_ATTRS_HPP_
#define _AST_ATTRS_HPP_
namespace AST {
//
class MetaItem;
class MetaItems
{
public:
Span m_span;
::std::vector<MetaItem> m_items;
virtual ~MetaItems();
MetaItems() {}
MetaItems(MetaItems&&) = default;
MetaItems& operator=(MetaItems&&) = default;
MetaItems(const MetaItems&) = delete;
MetaItems(Span sp, ::std::vector<MetaItem> items):
m_span( mv$(sp) ),
m_items( mv$(items) )
{
}
void push_back(MetaItem i);
MetaItems clone() const;
MetaItem* get(const char *name) { return const_cast<MetaItem*>( const_cast<const MetaItems*>(this)->get(name)); }
const MetaItem* get(const char *name) const;
bool has(const char *name) const {
return get(name) != 0;
}
friend ::std::ostream& operator<<(::std::ostream& os, const MetaItems& x) {
return os << "[" << x.m_items << "]";
}
};
TAGGED_UNION(MetaItemData, None,
(None, struct {}),
(String, struct {
::std::string val;
}),
(List, struct {
::std::vector<MetaItem> sub_items;
})
);
class MetaItem
{
::std::string m_name;
MetaItemData m_data;
public:
virtual ~MetaItem();
MetaItem() {}
MetaItem(MetaItem&& ) = default;
MetaItem& operator=(MetaItem&& ) = default;
MetaItem(::std::string name):
m_name(name),
m_data( MetaItemData::make_None({}) )
{
}
MetaItem(::std::string name, ::std::string str_val):
m_name(name),
m_data( MetaItemData::make_String({mv$(str_val)}) )
{
}
MetaItem(::std::string name, ::std::vector<MetaItem> items):
m_name(name),
m_data( MetaItemData::make_List({mv$(items)}) )
{
}
MetaItem clone() const;
void mark_used() {}
const ::std::string& name() const { return m_name; }
bool has_noarg() const { return m_data.is_None(); }
bool has_string() const { return m_data.is_String(); }
const ::std::string& string() const { return m_data.as_String().val; }
bool has_sub_items() const { return m_data.is_List(); }
const ::std::vector<MetaItem>& items() const { return m_data.as_List().sub_items; }
::std::vector<MetaItem>& items() { return m_data.as_List().sub_items; }
friend ::std::ostream& operator<<(::std::ostream& os, const MetaItem& x) {
os << x.m_name;
TU_MATCH(MetaItemData, (x.m_data), (e),
(None,
),
(String,
os << "=\"" << e.val << "\"";
),
(List,
os << "(" << e.sub_items << ")";
)
)
return os;
}
};
} // namespace AST
#endif
|