Please suggest use-cases for introspective code generation
Hi folks,
I'm looking for a few more interesting use cases to help validate and
mature the design / implementation, and use as case studies in the
documentation, of a C++ introspective preprocessor / code generator.
A few examples to get you started (hopefully not enough to get you
bored):
- auto-generation of object serialisation / deserialisation member
functions
- based on operator<<(std::ostream&, ) / binary / XML
- run-time execution based on textual identifier/params
- member functions ala
std::string get_member_variable(const char identifier[]) const;
std::string call_member_function(const char fn_identifier,
std::vector<const std::string& args);
std::string call_member_function(const char fn_identifier,
std::vector<const std::string& args) const;
( requires operator>> able to stream into actual argument types )
- class/object registries
- abstract interfaces for the union or intersection of members in an
arbitrary list of concrete class
- associated factories
- abstract interfaces for the members in a template (example at end of
email)
- associated code for polymorphic access to existing object, factory
method
- incorporation of code from external utilities - e.g. generation of
perfect hash-tables, database metadata etc.
....
Anyway, creative but practical suggestions very much appreciated...
Regards,
Tony
--- compile-time to run-time polymorphic handover ---
just a quick example of the kind of techniques I'm aiming to support -
nothing new or exciting about the below - but automating generation
makes it practical on a larger scale...
#include <iostream>
// > generated
struct Abstract_C {
virtual ~Abstract_C() { }
virtual double add(double) const = 0;
};
// < generated
template <typename A>
struct C {
C(const A& a) : a_(a) { }
double add(double b) const {
std::cout << __PRETTY_FUNCTION__ << '\n';
return a_ + b;
}
private:
A a_;
// > generated
struct AbstractPtr : public Abstract_C {
AbstractPtr(C* p) : p_(p) { }
double add(double b) const { return p_->add(b); }
private:
C* p_;
};
public:
AbstractPtr* accessor() { return new AbstractPtr(this); }
private:
struct Abstract : C, public Abstract_C {
Abstract(const A& a) : C(a) { }
double add(double b) const { return C::add(b); }
};
public:
static Abstract_C* factory(const A& a) { return new Abstract(a); }
// < generated
};
int main()
{
C<int> c1(-5);
assert(c1.add(10) == 5);
Abstract_C* p_c1 = c1.accessor();
assert(p_c1->add(-5) == -10);
delete p_c1;
assert(c1.add(100) == 95); // c1 still exists...
Abstract_C* p_c2 = C<float>::factory(12.5);
assert(p_c2->add(29.5) == 42);
delete p_c2;
// no c2...
}
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]