// -*- c-basic-offset: 4 -*- #ifndef CLICK_ECLASST_HH #define CLICK_ECLASST_HH #include #include #include #include #include "etraits.hh" class ErrorHandler; class StringAccum; class RouterT; class ElementT; class VariableEnvironment; class ElementMap; class SynonymElementClassT; class ElementClassT { public: ElementClassT(const String &); virtual ~ElementClassT(); static void set_base_type(ElementClassT *); static ElementClassT *base_type(const String &); static ElementClassT *tunnel_type(); void use() { _use_count++; } void unuse() { if (--_use_count <= 0) delete this; } const String &name() const { return _name; } const char *printable_name_c_str(); virtual String landmark() const { return String(); } // 'primitive' means 'not tunnel, not compound, not synonym'. virtual bool primitive() const { return true; } bool tunnel() const { return this == tunnel_type(); } const ElementTraits &traits() const; virtual const ElementTraits *find_traits() const; const String &port_count_code() const; const String &processing_code() const; const String &flow_code() const; bool requires(const String &) const; bool provides(const String &) const; const String &package() const; const String &documentation_name() const; String documentation_url() const; // where was this type declared? virtual RouterT *declaration_scope() const; virtual ElementClassT *overload_type() const; virtual void collect_types(HashMap &) const; virtual void collect_overloads(Vector &) const; static ElementT *expand_element(ElementT *, RouterT *, const String &prefix, VariableEnvironment &, ErrorHandler *); virtual ElementClassT *resolve(int ninputs, int noutputs, Vector &args, ErrorHandler *, const String &landmark); virtual ElementT *complex_expand_element(ElementT *, const String &, Vector &, RouterT *, const String &prefix, VariableEnvironment &, ErrorHandler *); enum UnparseKind { UNPARSE_NAMED, UNPARSE_ANONYMOUS, UNPARSE_OVERLOAD }; virtual void unparse_declaration(StringAccum &, const String &, UnparseKind, ElementClassT *stop); virtual String unparse_signature() const; static String unparse_signature(const String &name, const Vector *formal_types, int nargs, int ninputs, int noutputs); virtual void *cast(const char *) { return 0; } virtual SynonymElementClassT *cast_synonym() { return 0; } virtual RouterT *cast_router() { return 0; } private: String _name; int _use_count; mutable int _traits_version; mutable const ElementTraits *_traits; static ElementClassT *the_tunnel_type; ElementClassT(const ElementClassT &); ElementClassT &operator=(const ElementClassT &); ElementT *direct_expand_element(ElementT *, RouterT *, const String &prefix, VariableEnvironment &, ErrorHandler *); }; class SynonymElementClassT : public ElementClassT { public: SynonymElementClassT(const String &, ElementClassT *, RouterT *); ElementClassT *synonym_of() const { return _eclass; } ElementClassT *resolve(int, int, Vector &, ErrorHandler *, const String &); ElementT *complex_expand_element(ElementT *, const String &, Vector &, RouterT *, const String &prefix, VariableEnvironment &, ErrorHandler *); void collect_types(HashMap &) const; void collect_overloads(Vector &) const; void unparse_declaration(StringAccum &, const String &, UnparseKind, ElementClassT *); bool primitive() const { return false; } const ElementTraits *find_traits() const; RouterT *declaration_scope() const; ElementClassT *overload_type() const { return _eclass; } SynonymElementClassT *cast_synonym() { return this; } RouterT *cast_router(); private: ElementClassT *_eclass; RouterT *_declaration_scope; }; extern int32_t default_element_map_version; inline ElementClassT * ElementClassT::tunnel_type() { assert(the_tunnel_type); return the_tunnel_type; } inline const ElementTraits & ElementClassT::traits() const { if (_traits_version != default_element_map_version) { _traits_version = default_element_map_version; _traits = find_traits(); } return *_traits; } inline const String & ElementClassT::documentation_name() const { return traits().documentation_name; } inline const String & ElementClassT::port_count_code() const { return traits().port_count_code; } inline const String & ElementClassT::processing_code() const { return traits().processing_code; } inline const String & ElementClassT::flow_code() const { return traits().flow_code; } inline bool ElementClassT::requires(const String &req) const { return traits().requires(req); } inline bool ElementClassT::provides(const String &req) const { return traits().provides(req); } #endif