| Register | FAQ | Calendar | Search | Today's Posts | Mark Forums Read |
|
#1
| |||
| |||
| 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: stream&, ) / 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! ] |
|
#2
| |||
| |||
| On Sep 4, 11:23 pm, Tony Delroy <tony_in_da...@yahoo.co.uk> wrote: > A few examples to get you started (hopefully not enough to get you > bored): I must admit that I am having hard time understanding exactly what is it that you are offering, based on your code sample. > - auto-generation of object serialisation / deserialisation member > functions > - based on operator<<(std: stream&, ) / binary / XMLIMHO, there is no such thing as auto-generation of any type of serialization. C++ (and pseudo-C++) programmers the world over have been trying in vain to add introspection to C++ with no success. The reason is that it is not possible. Computers cannot read. A thinking being (person) will always need to indicate whether variable should be serialized or not, and once that indication becomes necessary all bets are off - the brain energy would have just as well been spent in writing the serialization code. > - 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); Why? > 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 Why? > - abstract interfaces for the union or intersection of members in an > arbitrary list of concrete class > - associated factories Why? > - abstract interfaces for the members in a template (example at end of > email) > - associated code for polymorphic access to existing object, factory > method Why? > - incorporation of code from external utilities - e.g. generation of > perfect hash-tables, database metadata etc. Tomorrow, when I wake up, I am going to use Google to find the crème de la crème of open-source projects, the top 1% of 1% of 1%. I am going to use my development system to create a Super Project that contains say, 10 of these ultra-high quality projects. I will mix these projects together in a common directory, and offer each of them a warm blanket, a teddy bear, hot chocolate, and The Communist Manifesto by Marx and Engels so that they have something to read while they enjoy each other's company in harmony with each other. I will then hit the compile button, stand back, and watch the social magic. Surely the whole concoction will be at least as beautiful, functional, useable, as any of the individual parts. If it is not, I will endlessly refactor the code until I at least see some blinking lights. Software, and other primitives of science and engineering, are inanimate artifacts, not people. ![]() -Le Chaud Lapin- -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
#3
| |||
| |||
| On Sep 5, 6:34 pm, Le Chaud Lapin <jaibudu...@gmail.com> wrote: > On Sep 4, 11:23 pm, Tony Delroy <tony_in_da...@yahoo.co.uk> wrote: > > I must admit that I am having hard time understanding exactly what is > it that you are offering, based on your code sample. Hi. Thanks for taking the time to write. Actually, I'm not offering anything. I'm asking for something: suggestions. > > - auto-generation of object serialisation / deserialisation member > > functions > > - based on operator<<(std: stream&, ) / binary / XML> > IMHO, there is no such thing as auto-generation of any type of > serialization. C++ (and pseudo-C++) programmers the world over have > been trying in vain to add introspection to C++ with no success. The > reason is that it is not possible. Computers cannot read. A thinking > being (person) will always need to indicate whether variable should be > serialized or not, and once that indication becomes necessary all bets > are off - the brain energy would have just as well been spent in > writing the serialization code. Actually, it's not that hard. OpenC++ is one example. In fact, it's more systematic and complex than what I'm doing. I believe its problem is that it's slow work injecting new code or modifying old if you're forced to do it at the parsed tree level, rather than by writing a big chunk of raw textual source code in the familiar everyday format. To match your one brief diversion into specifics, in my tool whether to include a variable can be controlled by a mixture of a default and an explicit override. This is most easily achieved by adding to the multimap of attributes associated with each elements in the declaration tree: ... int x `serialise = false`; ... These attributes can be easily inspected during code generation. Anyway, how to achieve the introspective preprocessing it is not what I'm interested in discussing - it's a done deal. What I am interested in is finding a few more useful applications of the tool with which to mature and highlight capabilities. > > - 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); > > Why? I would hope you're not serious, but anyway: this is a simplistic but powerful step towards run-time control of a C++ system. > > 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 > > Why? ....as above... > > - abstract interfaces for the union or intersection of members in an > > arbitrary list of concrete class > > - associated factories > > Why? It basically lets you trivially throw together a list of types that you want to manage polymorphically, either limiting yourself to the commonality or a fat interface. Why? Why? Again, I can only hope your experience has suggested some use for polymorphism. > > - abstract interfaces for the members in a template (example at end of > > email) > > - associated code for polymorphic access to existing object, factory > > method > > Why? Handover from compile-time to run-time polymorphism is extremely important in large systems. Techniques like those in Modern C++ Design clearly have enormous potential to deliver high performance and extremely customisable objects allowing one implementation to embrace arbitrary combinations of policies representing distinct design choices. Really, really nice. But if you have a large system and need to pass types across system interfaces, you find writing a function to work on a policy-templated data type is a non-trivial commitment. You either have to make your function a template and explose the interface, creating recompilation coupling (i.e. opposite characteristics of pImpl idiom) or achieve some compile-time to run- time handoff. That's what the technique mentioned above automates. > > - incorporation of code from external utilities - e.g. generation of > > perfect hash-tables, database metadata etc. > > Tomorrow, when I wake up, I am going to use Google to find the crème > de la crème of open-source projects, the top 1% of 1% of 1%. I am > going to use my development system to create a Super Project that > contains say, 10 of these ultra-high quality projects. I will mix > these projects together in a common directory, and offer each of them > a warm blanket, a teddy bear, hot chocolate, and The Communist > Manifesto by Marx and Engels so that they have something to read while > they enjoy each other's company in harmony with each other. I will > then hit the compile button, stand back, and watch the social magic. > Surely the whole concoction will be at least as beautiful, functional, > useable, as any of the individual parts. If it is not, I will > endlessly refactor the code until I at least see some blinking lights. > > Software, and other primitives of science and engineering, are > inanimate artifacts, not people. ![]() What was that all about? You think I'm off dreaming my little dreams? Fine, I'm not interested in changing your mind, just requesting suggestions from anyone kind enough to offer such, and replying to you primarily because I don't want them discouraged. Secondarily because I'm pedantic enough to always want the last word. Time will tell. ( Just in case your final flight of fancy was provoked by the common confusion over the term "perfect hash table" I'll mention it has a well-defined non-romantic down-to-earth technical meaning: not two keys hash to the same bucket. ) Regards, Tony -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
#4
| |||
| |||
| On 5 sep, 06:23, Tony Delroy <tony_in_da...@yahoo.co.uk> wrote: > - 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 I really fail to see the point of this. That kind of information would be much more useful at compile-time, and it wouldn't bloat code size for no reason. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
#5
| |||
| |||
| On Sep 6, 2:14 am, Mathias Gaunard <loufo...@gmail.com> wrote: > On 5 sep, 06:23, Tony Delroy <tony_in_da...@yahoo.co.uk> wrote: > > > - 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 > > I really fail to see the point of this. > That kind of information would be much more useful at compile-time, > and it wouldn't bloat code size for no reason. Hi Mathias, Thanks for taking the time to respond, and asking about this. I'm certainly not suggesting every program wants to maintain all this baggage, just that some programs, for anything from a single class with lots of data members through an entire subsystem or three, may find it useful. Applications: - facilitating access to C++ functionality from scripting languages; - setting variables or modal states during parsing of configuration files; - last-resort but powerful run-time control of a C++ system to help nurse it through production issues or correct bogus data (may well be impractical - and unmaintainable to attempt - to provide anything like the same pervasiveness of control through explicitly coded points of access); - interactive use of a system (for some kinds of objects, a great way to learn how to use them is to create one then poke and prod it to see how it responds. This often works well in say tcl/tk and Ruby: far more tangible and immediate than C++'s "add a few couts, re-compile, re-run, search through all the old couts to find the new, check the doco to see what you're allowed to try next" cycles); - automated testing. Re your suggestion of utility at compile time: certainly got me asking myself if I've covered all the bases, as I'm not quite sure what you're thinking of. So a bit of background, and I hope you'll comment further.... The preprocessor in question performs on-the-fly compilation of arbitrary C++, so any code that's useful to call at compile time can be compiled and called in a more traditional C++ style. Functions like those above are relatively inefficient, sloppy run-time mechanisms. That's fine for limited applications like those mentioned above, but not generally desirable when avoidable. Also note that the functions suggested above are of the "get me the value of the variable called X", or "get me the result of calling function Y with argument A and B" which make sense in a running system, but might not at compile time. For example, "Image::get_background_colour()" isn't much use without a loaded Image object. Apologies if I've failed to address your point. Regards, Tony -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
#6
| |||
| |||
| On 6 sep, 00:28, Tony Delroy <tony_in_da...@yahoo.co.uk> wrote: > On Sep 6, 2:14 am, Mathias Gaunard <loufo...@gmail.com> wrote: > > > On 5 sep, 06:23, Tony Delroy <tony_in_da...@yahoo.co.uk> wrote: > > > > - 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 > > > I really fail to see the point of this. > > That kind of information would be much more useful at compile-time, > > and it wouldn't bloat code size for no reason. > > Hi Mathias, > > Thanks for taking the time to respond, and asking about this. I'm > certainly not suggesting every program wants to maintain all this > baggage, just that some programs, for anything from a single class > with lots of data members through an entire subsystem or three, may > find it useful. Applications: > - facilitating access to C++ functionality from scripting languages; > - setting variables or modal states during parsing of configuration > files; > - last-resort but powerful run-time control of a C++ system to help > nurse it through production issues or correct bogus data (may well be > impractical - and unmaintainable to attempt - to provide anything like > the same pervasiveness of control through explicitly coded points of > access); > - interactive use of a system (for some kinds of objects, a great way > to learn how to use them is to create one then poke and prod it to see > how it responds. This often works well in say tcl/tk and Ruby: far > more tangible and immediate than C++'s "add a few couts, re-compile, > re-run, search through all the old couts to find the new, check the > doco to see what you're allowed to try next" cycles); > - automated testing. > > Re your suggestion of utility at compile time: certainly got me asking > myself if I've covered all the bases, as I'm not quite sure what > you're thinking of. So a bit of background, and I hope you'll comment > further.... template<typename T> struct reflection { }; template<> struct reflection<MyClass> { typedef mpl::map< mpl: air<mpl::string<'f', 'o', 'o'>, some_functor_type >, ... > member_variables; typedef mpl::map< mpl: air<mpl::string<'b', 'a', 'r'>, some_other_functor_type >, ... > static_variables; typedef mpl::map< mpl: air<mpl::string<'b', 'a', 'z'>, yet_another_functor_type >, ... > member_functions; typedef ... static_functions; typedef mpl::map< mpl: air<mpl::string<'t', 'y', 'p', 'e'>, TypeInQuestion >, ... > typedefs; typefef mpl::vector< Base1, ... > bases; }; It's only types, so it adds no overhead in size. It also adds no overhead at runtime if you want to make use of it. If the information is needed at runtime, you're free to copy parts of it. Making the information compile-time allows it to be much more useful since the compiler is aware of the typing system. The code before is just an example. Member variables would expose a functor that takes an object and returns the member. Static variables would expose a nullary functor that takes nothing and returns the static variable. Of course, the functors would expose the returned type, i.e. the type of the member. Member and static (member) functions are more complicated, though, since there can be multiple overloads, templates, etc. A solution would be to expose simple functors that behaves exactly like the combination of all overloads, and expose those overloads with the result_of protocol. It however doesn't really expose the various signatures. You may think of a way to mangle a signature using metaprogramming so that more advanced uses can be made. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
#7
| |||
| |||
| On Sep 6, 2:14 am, Mathias Gaunard <loufo...@gmail.com> wrote: > On 5 sep, 06:23, Tony Delroy <tony_in_da...@yahoo.co.uk> wrote: > > > - 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 > > I really fail to see the point of this. > That kind of information would be much more useful at compile-time, > and it wouldn't bloat code size for no reason. Another scenario's just came to mind. If someone's written an application in VB/Access, and the user says "I want to be able to enter a query", then they say "yeah, just type it in using this notation called SQL and I'll spit out all the results for you". The C+ + programmer with all their data sitting snug in a few STL containers might have been feeling smug about their performance, but that user request will be a lot more hassle for them. Of course they could start using a database, but that's got downsides and may be overkill. A reasonable query capability can be facilitated by functions like those above, providing run-time access keyed on identifier for objects from the containers.... Regards, Tony -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
#8
| |||
| |||
| On Sep 5, 2:34 am, Le Chaud Lapin <jaibudu...@gmail.com> wrote: > On Sep 4, 11:23 pm, Tony Delroy <tony_in_da...@yahoo.co.uk> wrote: > IMHO, there is no such thing as auto-generation of any type of > serialization. C++ (and pseudo-C++) programmers the world over have > been trying in vain to add introspection to C++ with no success. The > reason is that it is not possible. Computers cannot read. A thinking > being (person) will always need to indicate whether variable should be > serialized or not, and once that indication becomes necessary all bets > are off - the brain energy would have just as well been spent in > writing the serialization code. Introspection is very useful, and has applications such as binding C++ to scripting languages, marshalling objects for RPC, and debugging. In fact, if your compiler did not generate introspective information about your program, your debugger would not be very useful. It should be a simple matter to define a standard way of inspecting the static object model and type system of a C++ program. Why has this not been done yet? -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
#9
| |||
| |||
| On Sep 6, 11:22 pm, Mathias Gaunard <loufo...@gmail.com> wrote: > On 6 sep, 00:28, Tony Delroy <tony_in_da...@yahoo.co.uk> wrote: > > On Sep 6, 2:14 am, Mathias Gaunard <loufo...@gmail.com> wrote: > > > On 5 sep, 06:23, Tony Delroy <tony_in_da...@yahoo.co.uk> wrote: > > > > > - 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 > > > > I really fail to see the point of this. > > > That kind of information would be much more useful at compile-time, > > > and it wouldn't bloat code size for no reason. > > > [...] I'm not quite sure what > > you're thinking of. So a bit of background, and I hope you'll comment > > further.... > > template<typename T> > struct reflection { }; > > template<> > struct reflection<MyClass> > { > typedef mpl::map< > mpl: air<> mpl::string<'f', 'o', 'o'>, > some_functor_type > >, > ... > > member_variables; > > [ ...snipped by Tony... ] > }; > > It's only types, so it adds no overhead in size. It also adds no > overhead at runtime if you want to make use of it. I do believe we've finally synced up... thank you Mathias for your patient and lucid explanation. On the one hand, the potential uses of the Reflection<> traits are more squarely addressed by the introspective preprocessor and usages it supports, so it seems an almost perverse thing having got all that metadata into an STL-ish container that you can query with the simplicity and freedom of normal C++ code just to use the freedom to re-encode it all in templates :-). Remember the preprocessor's run- time is still the application's compile time, so there is no runtime cost to using the preprocessor's declaration tree as the basis of code generation. On the other hand, the existing familiarity of traits to C++ programmers is unarguable, and the C++ compiler proper has some smarts built in that would be tedious to emulate, and may simplify things for the end-user/developer. I think a point you made (I've quoted it out of order), makes a good argument along these lines... > Making the information compile-time allows it to be much more useful > since the compiler is aware of the typing system. I'm sold: thank you for the suggestion. But I'm sold on the idea of generating traits, rather than sold on not adding the functions I suggested. What's discussed above is all a layer below the intended usage of the functions you queried. Those are only intended to address those cases where you'd also end up doing the "copy parts of it" that you mention below... > If the information is needed at runtime, you're free to copy parts of > it. Writing the code for the introspective preprocessor (frustrating verbose to keep calling it that, but the name might change before release) to generate traits code, then more code to support run-time queries based on the traits, would be very much the long way around. When supporting run-time usage, the results from the approach you're suggesting are bounded to at best equal what the preprocessor could generate, but as the preprocessor isn't restricted to what's convenient when querying templates, and can generate perfect-hash tables / sorted static containers etc on the fly, it may actually do a little better. > The code before is just an example. > Member variables would expose a functor that takes an object and > returns the member. Static variables would expose a nullary functor > that takes nothing and returns the static variable. Of course, the > functors would expose the returned type, i.e. the type of the member. > Member and static (member) functions are more complicated, though, > since there can be multiple overloads, templates, etc. A solution > would be to expose simple functors that behaves exactly like the > combination of all overloads, and expose those overloads with the > result_of protocol. It however doesn't really expose the various > signatures. You may think of a way to mangle a signature using > metaprogramming so that more advanced uses can be made. A wealth of insight and experience there... thanks! All up, this is an interesting divide: the preprocessor can support all the body of template hackery and magic that's already a rich repository of programmer's work, linking up loose ends and filling in the bits that were being done manually, scaling and maintaining techniques that are otherwise error prone or prohibitively tedious. Alternatively, it can be used to allow even programmers unfamiliar with all that to do powerful introspective-based tasks in a style like high-level OO application development. Best tool for the job and all that. Really, thank you very much for your time. Made for an interesting and stimulating couple hours. Best regards, Tony P.S. At some transient moment during the drafting of my response I ended up reacting to your mention of "bloat" by writing an explanation on the general issues around controlling the scope of automated code generation. Now, it seems tangential to our discussion re these functions, but since it's written, thought I'd put it somewhere for anyone with a strong stomach for tedious detail... not suggesting you or anyone read it unless you're bored and want to be more so :-). "Taking a more general look at potential executable bloat: when the introspective preprocessor is processing an inline code-generation instruction, a common requirement is knowledge of the scope within the declaration tree to work on. Sometimes this will be the scope in which the instruction appears. Sometimes that scope and all enclosed scopes. Sometimes global. Sometimes using some manner of search, and possibly consulting the per-node multimap of attributes/properties for developer-specified explicit guidance. When writing instructions you can hardcode any of these, or accept an argument from the in-line invocation. So, the functions I mentioned need not be generated in every scope in an entire program. One can be selective in order to control overheads. Still, another way of reducing the change of generating run-time access functions for scopes in which the compiler can tell they'll never be used is to make the generated functions I advocated templates. Maybe not always ideal, but perhaps workable, especially as both using the preprocessor to control the scope of generation and the compiler to perform only-on-use instantiation might be freely and usefully combined in many cases. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
#10
| |||
| |||
| On Sep 7, 1:29 am, Mathieu Mazerolle <mathieu.mazero...@gmail.com> wrote: > On Sep 5, 2:34 am, Le Chaud Lapin <jaibudu...@gmail.com> wrote: > > > On Sep 4, 11:23 pm, Tony Delroy <tony_in_da...@yahoo.co.uk> wrote: > > IMHO, there is no such thing as auto-generation of any type of > > serialization. C++ (and pseudo-C++) programmers the world over have > > been trying in vain to add introspection to C++ with no success. The > > reason is that it is not possible. Computers cannot read. A thinking > > being (person) will always need to indicate whether variable should be > > serialized or not, and once that indication becomes necessary all bets > > are off - the brain energy would have just as well been spent in > > writing the serialization code. > > Introspection is very useful, and has applications such as binding C++ > to scripting languages, marshalling objects for RPC, and debugging. In > fact, if your compiler did not generate introspective information about > your program, your debugger would not be very useful. > > It should be a simple matter to define a standard way of inspecting the > static object model and type system of a C++ program. Why has this not > been done yet? It is. It has. I had a prototype 4 years ago with serialisation and a few other basic applications working but didn't pursue it then because it seemed so blindingly obvious and easy that I was sure some mega-company would be coming out with their big-corporate-backed tool any day thereafter, and the code I'd wasn't mine. It was fast too... ripped through all the masses of STL headers accurately and in a fraction of a second, so I'm not interested in going the whole hog and learning how to do it all within GCC or something when it can be done cleanly and in a compiler-independent way. Some people probably make the problem much harder than it has to be. Years on and I'm wondering why I'm working 8-7:30 for a bank 5 days a week, and figure this is as good a bet as any for changing that, reimplementing everything from scratch with the benefit of 4 extra years' experience and I like the way it's shaping up, though doing it in spare time is harder than full- time. As for others, perhaps they've been held back by Le Chaud pronouncing it impossible... ;-P. Tony -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
![]() |
| Thread Tools | |
| Display Modes | |
In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.