| 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 | |