1 | #ifndef ISL_INTERFACE_TEMPLATE_CPP_H |
2 | #define ISL_INTERFACE_TEMPLATE_CPP_H |
3 | |
4 | #include <initializer_list> |
5 | #include <iostream> |
6 | #include <map> |
7 | #include <memory> |
8 | #include <set> |
9 | #include <string> |
10 | #include <unordered_map> |
11 | |
12 | #include "cpp.h" |
13 | |
14 | struct Fixed; |
15 | |
16 | struct TupleKind; |
17 | |
18 | /* A shared pointer to a TupleKind. |
19 | */ |
20 | struct TupleKindPtr : public std::shared_ptr<const TupleKind> { |
21 | using Base = std::shared_ptr<const TupleKind>; |
22 | TupleKindPtr() = default; |
23 | TupleKindPtr(Fixed); |
24 | TupleKindPtr(Base base) : Base(base) {} |
25 | TupleKindPtr(const std::string &name); |
26 | TupleKindPtr(const TupleKindPtr &left, const TupleKindPtr &right); |
27 | }; |
28 | |
29 | /* A substitution mapping leaf tuple kind names to tuple kinds. |
30 | */ |
31 | using Substitution = std::unordered_map<std::string, TupleKindPtr>; |
32 | |
33 | /* A representation of a (possibly improper) tuple kind. |
34 | * That is, this also includes tuple kinds for types |
35 | * that do not have any tuples. |
36 | * |
37 | * The kind could be a name (the base case) or |
38 | * a (currently) unnamed nested pair of tuple kinds. |
39 | */ |
40 | struct TupleKind { |
41 | TupleKind(const std::string &name) : name(name) {} |
42 | |
43 | virtual std::string to_string() const; |
44 | virtual std::vector<std::string> params() const; |
45 | virtual TupleKindPtr apply(const Substitution &subs, |
46 | const TupleKindPtr &self) const; |
47 | virtual TupleKindPtr left() const; |
48 | virtual TupleKindPtr right() const; |
49 | |
50 | const std::string name; |
51 | }; |
52 | |
53 | /* A sequence of tuple kinds, representing a kind of objects. |
54 | */ |
55 | struct Kind : public std::vector<TupleKindPtr> { |
56 | Kind() {} |
57 | Kind(std::initializer_list<TupleKindPtr> list) : vector(list) {} |
58 | |
59 | bool is_anon() const; |
60 | bool is_set() const; |
61 | bool is_anon_set() const; |
62 | std::vector<std::string> params() const; |
63 | Kind apply(const Substitution &subs) const; |
64 | }; |
65 | |
66 | /* A representation of a template class. |
67 | * |
68 | * "class_name" is the name of the template class. |
69 | * "super_name" is the (fully qualified) name of the corresponding |
70 | * plain C++ interface class, from which this template class derives. |
71 | * "clazz" describes the plain class. |
72 | * |
73 | * "class_tuples" contains the specializations. |
74 | * It is initialized with a predefined set of specializations, |
75 | * but may be extended during the generations of the specializations. |
76 | */ |
77 | struct template_class { |
78 | const std::string class_name; |
79 | const std::string super_name; |
80 | const isl_class &clazz; |
81 | |
82 | std::vector<Kind> class_tuples; |
83 | |
84 | bool is_anon() const; |
85 | bool is_anon_set() const; |
86 | void add_specialization(const Kind &kind); |
87 | }; |
88 | |
89 | /* A generator for templated C++ bindings. |
90 | * |
91 | * "template_classes" contains all generated template classes, |
92 | * keyed on their names. |
93 | */ |
94 | class template_cpp_generator : public cpp_generator { |
95 | struct class_printer; |
96 | struct method_decl_printer; |
97 | struct method_impl_printer; |
98 | struct class_decl_printer; |
99 | struct class_impl_printer; |
100 | |
101 | void add_template_class(const isl_class &clazz, const std::string &name, |
102 | const std::vector<Kind> &class_tuples); |
103 | public: |
104 | template_cpp_generator(clang::SourceManager &SM, |
105 | std::set<clang::RecordDecl *> &exported_types, |
106 | std::set<clang::FunctionDecl *> exported_functions, |
107 | std::set<clang::FunctionDecl *> functions); |
108 | |
109 | virtual void generate() override; |
110 | void foreach_template_class( |
111 | const std::function<void(const template_class &)> &fn) const; |
112 | void print_forward_declarations(std::ostream &os); |
113 | void print_friends(std::ostream &os); |
114 | |
115 | std::map<std::string, template_class> template_classes; |
116 | }; |
117 | |
118 | #endif |
119 | |