[boost] Re: Re: Re: Re: Re: what happened to allocators in boost?
Peter Dimov wrote: [snip] I see your point but what is the alternative? Forcing people to replace global new/delete? In a word, yes. Although replacing global new/delete is forced by the system allocator being not up to the task and not by us. I understand that for some applications region-based memory management can be a big performance win. I also understand that some (uncommon in my experience) cases can't be supported by a global allocator (when two independent regions are active at once, in a single thread.) But I'm not sure that Allocators (as spelled in the standard) are the answer, and I'm entertaining the thought that in the long term this kind of customization harms the C++ community. Maybe not one's particular corner of the community, but the community as a whole. I agree but we're stuck with a hen/egg problem, as you have already pointed out. Today, quite a few system allocators are not up to the task, so people absolutely need customization. For cross-platform stuff this is true until the very last platform has come around, which might be never :(. Moreover, for some platforms compiler implementers can always argue that they cannot satisfy most of the crowd anyway, so customization and the sub-standard allocators will remain. E.g. I hope to convince some of the embedded systems/real-time crowd to use the fsm lib I'm currently implementing. I would bet that even in 10 years most of them wouldn't even consider using it unless they were able to totally control how memory is allocated... Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: Re: what happened to allocators in boost?
Peter Dimov wrote: Andreas Huber wrote: [snip] So far my experience indicates that people only bother with allocators when std::allocator is inadequate, i.e. slow. ... or non-deterministic. Using such an allocator in a hard real-time system is simply not an option. AFAIK, a deterministic allocator must inevitably have a separate heap for each possible object size. The difficult part is reserving enough slots in each heap at startup, before deterministic reaction is necessary. I don't see how a system could do this automatically when memory is scarce. The usual approach is to borrow an entry from the 2*N heap and split it in two when the N heap is empty. [snip] Which brings back non-determinism, as the 2*N heap could be full also and thus be borrowing from 4*N already. You can of course guarantee an upper limit for an allocation, as some heap must have a slot available. However, for some systems this upper limit is already too slow, so someone inevitably has to configure heap sizes *before* startup. Even if the system allocator does not work for you, why would you want to only replace function's allocator but leave all other allocations non-deterministic? Because function objects absolutely have to be allocated during the phase when a system has to react deterministically. Other objects might be allocated before this phase. I guess your hinting at replacing global new/delete, which almost always works but only almost as Eugene explained. And how would the ability help you if you want to use a third party library that has signatures of the form void f(functionvoid() const g); Yep, no luck here. [snip] I won't even go into details like whether std::allocator's interface is suited for the task or whether the function's specification as it currently stands gives you any guarantees for deterministic behavior. I didn't say std::allocator is perfect, but it's standard ;-). function's spec indeed doesn't guarantee determinism, but I couldn't think of a reasonable implementation that isn't deterministic. Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: Re: Re: what happened to allocators in boost?
[snip] However, for a certain class of systems one almost never can avoid customization, no matter how ingenious the platform is. This may well be true, but I'm not convinced that platform-specific customizations (an implementation detail) absolutely need to be supported by a portable mechanism affecting the interface. I see your point but what is the alternative? Forcing people to replace global new/delete? Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: Re: Re: what happened to allocators in boost?
Peter Dimov wrote: Andreas Huber wrote: Peter Dimov wrote: The usual approach is to borrow an entry from the 2*N heap and split it in two when the N heap is empty. [snip] Which brings back non-determinism, as the 2*N heap could be full also and thus be borrowing from 4*N already. You can of course guarantee an upper limit for an allocation, as some heap must have a slot available. Actually it's possible that all free memory already went to the N/2 heap but this case is (even more) unsolvable with predetermined heap sizes, too. :-) However, for some systems this upper limit is already too slow, so someone inevitably has to configure heap sizes *before* startup. I agree, but I still don't see why a quality system allocator on such a system should not give you the ability to do so. True, but this is just not yet standard. Not that I have an awful lot of experience with such systems but the (very popular) platform of the one project I was involved with was far away from providing such a quality allocator. Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: what happened to allocators in boost?
[snip] So far my experience indicates that people only bother with allocators when std::allocator is inadequate, i.e. slow. ... or non-deterministic. Using such an allocator in a hard real-time system is simply not an option. AFAIK, a deterministic allocator must inevitably have a separate heap for each possible object size. The difficult part is reserving enough slots in each heap at startup, before deterministic reaction is necessary. I don't see how a system could do this automatically when memory is scarce. Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: Re: what happened to allocators in boost?
E. Gladyshev wrote: [snip] ... or non-deterministic. Using such an allocator in a hard real-time system is simply not an option. AFAIK, a deterministic allocator must inevitably have a separate heap for each possible object size. The difficult part is reserving enough slots in each heap at startup, before deterministic reaction is necessary. I don't see how a system could do this automatically when memory is scarce. Depending on the requirements, you can try to overload new/delete for your data types and make it deterministic. I know it is not always an option. I know, I just mentioned this because Peter seems to suggest that the need for memory management customization is rare if the compiler folks did their job right. However, for a certain class of systems one almost never can avoid customization, no matter how ingenious the platform is. BTW: Having separate heaps is one of the reasons why I could not use boost::shared_ptr. I ended up writing my own. :( Yeah, I ended up using intrusive_ptr. Not always an option either ... Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: what happened to allocators in boost?
Douglas Gregor wrote: The allocator design focused on the benefits one could get from specialized allocators for containers, e.g., data structures that may allocate large chunks of memory that are expected to be used together. They don't really give us much for components like shared_ptr that allocate one thing (and note that shared_ptr does not allocate the pointer it stores, although it does allocate a reference count). boost::function supports an allocator argument, but the C++ committee is considering removing this allocator from the library TR version of function for precisely this reason. If function no longer has the allocator argument, how should we then use function in a hard real-time environment? Does the committee assume that such systems have deterministic allocators or that users replace global new/delete anyway? Thanks Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Virus defense
[snip] Spamcop looks like an excellent service; I'm planning on signing up for it myself in the next month or so, but it will not protect against virii (such as this current attack) AFAIK. Yes it does, I can tell from personal experience (you get a notification when this happens): http://mail.spamcop.net/individuals.php (see How does it work?) Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: number64 proposal
Philippe, You might be interested in the following: http://www.cuj.com/documents/s=8020/cuj0111ring/ring.htm (MAPM, A Portable Arbitrary Precision Math Library in C) AFAICS fairly complete and there's also a handy C++ wrapper... Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] [fsm] Support for MT and asynchronous state machines added
Hi The preliminary fsm submission has been updated: - Added support for multi-threading and asynchronous state machines (using boost::thread out of the box, customizable for other threading libs or even OS-less systems) - Updated documentation - Fixed various minor bugs and improved code (no breaking interface changes) - Added more examples - Added .pdf documentation The files can be found in boost-sandbox CVS in the fsm directories and here: http://groups.yahoo.com/group/boost/files/FSM/ Any feedback is most welcome. Thanks, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] MSVC7.1 bug not yet fixed
Dave, I've just downloaded 1.30.1 and the bug I reported a while ago http://aspn.activestate.com/ASPN/Mail/Message/boost/1622190 (Missing BOOST_HAS_THREADS on MSVC with /Za and /MT) is still there. I don't know config at all but if nobody else has time I'll try to submit a patch (I believe it'd be less than half an hour for someone knowing config). Just let me know. Thanks Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: Draft of new Boost Software License
Beman, Thanks for your work on this. Looks good to me. One minor thing: No change from the current status. If your project does not redistribute Boost source code, you don't have to redistribute the license, regardless of how much non-Boost source code is redistributed. Hope that helps, What about html files? Are they considered to be under the the Software umbrella? Html or any other form of electronic documentation can be seen as software but you could just as well argue that it's only data (which AFAICT would not fall under the license then). BTW, I (German mother-tongue) agree with Rene that the long sentences are a bit difficult to grasp. However, I don't care that much as long as it's legally bullet-proof. Thanks Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Inter-FSM protocol discussion
Chris, Sorry for the long delay, I was swamped with other stuff. The longer I think about your suggestions about FSM protocols the more do I think that coded FSM protocol specifications are not worth the effort. Even worse, I believe they will inevitably lead to code duplication. However, since I don't understand all of what you said, I may well have overlooked some important points. Before I start, I'll try to define my understanding of a protocol: *When* (timing and/or state) and *how* (effects) a particular entity will react to what kind of input. Please note: - The general term effects, which can be just about everything (modifying an internal counter, flushing a buffer, calling a callback object, returning a value, etc.). - Sender and receiver entities were deliberately left out of the definition because this would only complicate the matter without any benefit, IMO. - Even more deliberately, the terms FSM (replaced with entity) and event (replaced with input) were avoided. Replace entity with class or function and you'll see that both define what I believe a protocol is. The last note brings us to my point: The interface and the implementation of an entity (function, class, FSM, etc.) already define its protocol. There's no point in specifying the *whole* protocol once more with more code as this would inevitably duplicate some information, even if the specification is on a higher level. Granted, asserts sometimes partly do exactly that, but never fully. You mentioned concept checking between communicating state machines. IIUC, you would want to define some kind of a channel between the two machines. The channel would: 1. Anonymize, i.e ensure that there are no cyclic dependencies between the two machines. 2. Check the type and maybe even the contents of events going through the channel. That is, it checks that the channel protocol is not violated. - I realize that it could sometimes be desirable to have support for 1, especially if you want to have complete anonymization (the client does not know the server and vice versa). However, as handcrafting this amounts to only a couple of LOCs I doubt that it would be worth the effort. - Either explicitly or implicitly, the participating state machines must implement all of the checking done in the channel. Essentially the channel would duplicate most of these checks. The only difference is that state machines ignore bad events by default, while the channel would presumably throw after detecting such an error. In my last project we needed exactly such behavior (throwing of an exception if the receiving state machine fails to consume a particular event). boost::fsm does not currently support this, mainly because I'm still struggling to find a proper name for such an event. Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: Re: Re: Some questions on the FSM submission
Hi Scott, [snip] But it seemed to be a successful modeling and I had to concede; why should a niche concept such as protocols foul the global namespace of a generic modeling language? I see... [snip] 1. Events that can carry parameters 2. A call-back mechanism a la boost::function, so that an FSM that is answering a request does not have to know who it is answering to. [snip] boost::intrusive_ptr Request pRequest = new Request(); // set params A machine = context A (); pRequest-callback = boost::bind( A::queue_event, machine, _1 ); B::instance().queue_event( pRequest ); So, IMO there's no need for boost::fsm to provide communication protocol primitives, because their functionality is pretty orthogonal to what my library does. Users would want to use what they're accustomed to. Most would presumably use boost::function. Yes. Think with 1, 2 and putting distance between boost::fsm and comms you have nailed something for me. Maybe there will eventually be a boost::signaling (damn thats somewhat overused) or boost::eventing (sounds like a horse race) that will complement your current targets? I'm not sure I understand what such a library would do (there's already boost::signals which covers publish-subscribe pattern, which BTW could be interesting for certain types of inter-FSM communication too). Can you elaborate? [snip] I feel responsible for something of a detour into the subject of SDL and the comparison of UML with SDL. I don't see it as a detour. It was valuable to see SDL's approach to FSMs. It is even more valuable to see what questions might arise when people not familiar with UML consider using boost::fsm. I hope that this detour has uncovered something of use for you (certainly has for me) It definitely has. All that remains is that tiny last question ;-) above. Thanks Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: Re: Some questions on the FSM submission
Jeff, http://www.rational.com/products/whitepapers/441.jsp?SMSESSION=NO From one of the tool vendors: http://www.telelogic.com/products/tau/languages/uml_sdl/background.cfm Interesting. Thanks for the links. 4) I think you are right that your submission can cover most of the ground of both. That said, I for one, think that coverage of UML is the more important of the two. I agree, especially after seeing that the newest version of SDL (2000) has copied many UML (Harel) state chart concepts. Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Inter-FSM protocol discussion
Hi guys, That's all *very* interesting but unfortunately I'm running out of time. In less than an hour I'll be off for my holidays. I'll be back next Sunday. Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: Re: Some questions on the FSM submission
Scott Woods wrote: this is a product i used a few years ago. its a pretty complete implementation of SDL - you draw SDL, push a button and it generates the target system in C (that's what the brochures say ;-). it is very much targeted at large communities of FSMs. the sort of thing that i queried a while ago (and i think related to what chris was asking) was; where is the [separate] definition of the protocols? right or wrong i believe that FSMs interact through sending of signals (presentation of events?). this interaction is a protocol and a protocol has its own existence - it is not owned by the FSMs. neither UML or SDL highlights this. using SDL i was certainly able to implement protocols but it would have been a royal pain to uplift that protocol and reuse it in another project. H. Apologies. Just had a read of some of the UML material and have to take this back. My knowledge of UML needs updating. It looks like OMG is competing with ITU pretty damn successfully these days. Putting that fight aside for a moment (UML vs SDL) the separation of protocol from FSMs is maybe a concept of interest to you and your library. But truly see this as just future stuff. Looking forward to current functionality. I don't know what part in the UML specs you're referring to (I don't really know UML apart from class diagrams and state charts). A quick search did not reveal much apart from protocol state machines which AFAICT don't have anything to do with FSM interaction. SDL defines channels, gates and connections which sort of define a protocol. To me, these primitives are only necessary to *document* which FSM is talking to which other FSM. There's little semantics behind them. Maybe I'm seeing this too easy but I think in C++ all you need for inter-FSM communication is: 1. Events that can carry parameters 2. A call-back mechanism a la boost::function, so that an FSM that is answering a request does not have to know who it is answering to. Let's assume we already have a thread-enabled boost::fsm. We would then have something like concurrent_state_machine::queue_event( const intrusive_ptr const event_base ) Now if FSM A wants to send a request to FSM B and make B send an event back as soon as the request is processed, we could write something like this *B.hpp*: struct Answer : fsm::event Answer { /* answer params */ }; struct Request : fsm::event Request { /* request parameters */ boost::function void ( const intrusive_ptr const Answer ) callback; }; struct B : fsm::concurrent_state_machine B, /* ... */ { static B instance(); }; *B.cpp*: // X is some state of B fsm::result X::react( const Request req ) { // ... intrusive_ptr const Answer pAnswer( new Answer() ); req.callback( pAnswer ); } *A.cpp*: #include B.hpp // somewhere inside A's logic: boost::intrusive_ptr Request pRequest = new Request(); // set params A machine = context A (); pRequest-callback = boost::bind( A::queue_event, machine, _1 ); B::instance().queue_event( pRequest ); So, IMO there's no need for boost::fsm to provide communication protocol primitives, because their functionality is pretty orthogonal to what my library does. Users would want to use what they're accustomed to. Most would presumably use boost::function. Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: What is Double Dispatch ?
Bohdan wrote: [snip] BTW, this double dispatch variant is only cool ;-) for cases where the second stage of the double dispatch has to choose from only a few different possibilities. That's because the second stage performs a linear search. Second stage means inner states ? No, I was referring to the second stage of double dispatch. The first stage is done with a virtual function while the second stage is a linear search as discussed. In contrast to GOF-visitor, which is essentially constant-time, this variant becomes slower the more choices it has in the second stage. But it scales much better in terms of dependencies. Does it mean that for some use cases your lib can be event slower than FSM implementation with acyclic visitor ? IMHO inner states are not too rare thing in practice ... Not a chance, at least according to my benchmarks on the MSVC7.1 platform. For flat machines, acyclic vistitor needs one dynamic_cast and two virtual calls per dispatched event. This looks like constant-time, but it isn't because dynamic_cast needs longer the more reactions a given state defines. Moreover, if there are inner states an additional dynamic_cast is needed each time the dispatch algorithm moves to an outer state because the inner state did not define a reaction. So, acyclic visitor gets slower with the number of reactions per state *and* the state nesting depth. The current algorithm essentially only gets slower with the total number of reactions seen from the current innermost state. You can nest your states as much as you like, you only pay a more or less fixed amount of time per reaction that has to be considered during event dispatch. See double dispatch section in the rationale.html for more information. Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: Re: Some questions on the FSM submission
Chris Russell wrote: [snip] Andreas wrote: So, IMO there's no need for boost::fsm to provide communication protocol primitives, because their functionality is pretty orthogonal to what my library does. Users would want to use what they're accustomed to. Most would presumably use boost::function. ... but given some set of two or more FSM's for which you want to define a new protocol, it seems like some sort of concept checking would be useful. This will likely have some impact on the design of the FSM framework itself - maybe... Perhaps it's just some metadata that non-invasively characterizes the FSM? If the later, then Andreas' assertion that the FSM lib doesn't need to support protocol primitives seems reasonable. Ok, I see that concept checking could be helpful... I've been staring at the Wikipedia sections on Morphisms [1] and Group Theory [2] looking for a suitable nomenclature for describing these protocol concepts. Basically my idea is that the actual protocol would formally specify what flavor of *morphism it's attempting to establish and use information from FSM's in the group to determine if such a mapping is possible (the concept check) and if so, affect the mapping generically somehow (i.e. the protocol itself doesn't doesn't get involved with event types and data semantics directly). Unclear to me if this is done at compile time, runtime, or gasp both... What do you guys think of these ideas? Errr, while I got what a group is I don't really get what a *morphism is. The description is too formal for me and the examples don't help either. Moreover, I also fail to see the connection between groups and FSMs. Have I been drinking too much lately ;o)? Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: Some questions on the FSM submission
Scott, Specification and Description Language also known as ITU Z.100. Check it out at; http://www.sdl-forum.org/SDL/ Thanks for the link. I've had a look at the SDL-2000 slide show. http://www.informatik.hu-berlin.de/~holz/SDLTutorial/SDL2000Tutorial.zip AFAICT, SDL FSMs are *very* similar to UML FSMs. Not all that surprising, given the fact that both languages base on Harel's state charts. The terminology and the charts are slightly different for some concepts but I'm quite sure one could implement just about every SDL state machine with a threading-enabled version of boost::fsm, with very few or no workarounds. About the only concept missing in my library is a triggerless transition (SDL: non-deterministic input), which currently is the last item on my to-do list. Here's a terminology mapping: UML/boost::fsm - SDL --- event - signal reaction - input guard(ed reaction) - constrained input junction point/choice point - decision entry action - initialisation exit action - finalisation state with two or more orthogonal regions - state aggregation inner state - composite state terminator - stop state The remaining concepts (transition, deferral) have the same names in both languages. Interestingly, SDL also defines exception handlers (supported by boost::fsm), which UML lacks completely. Moreover, SDL specifies block and process agents, which are not supported by UML and my library but could be implemented on top of it. I therefore think that boost::fsm could be useful for domains where behavior is specified with SDL. As a consequence its pretty good for specifying large communities of distributed, co-operating FSMs. There is a large quantity of code running in switching networks that is based on SDL documentation, e.g. ITU-T Q.931 (ISDN PRI). How is that code usually implemented? Are there SDL code generators and/or widely used libraries or do people normally handcraft such systems? Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: What is Double Dispatch ?
Bohdan, Ooops, sorry ... i was terribly unclear. Andreas Huber wrote: boost::fsm no longer uses acyclic visitor! The current double dispatch implementation (which was inspired by Aleksey's fsm lib) uses one virtual call followed by a linear search for a suitable reaction, using one RTTI comparison per visited reaction. Although you cannot change the double dispatch implementation itself, you can change one aspect of it, i.e. RTTI. I mean : Where can i find something about cool double dispatch used in recently submitted FSM code ? Or Aleksey's fsm lib sources ? You can find Aleksey's fsm lib here: http://www.mywikinet.com/mpl/fsm_example_25_jul_02.zip In my library, you can look for simple_state::react_impl() which is the override for the abstract state_base::react_impl(). The implementation is quite simple: all reactions are contained in an mpl::list, which is passed to a function. The function then calls the front reaction. If the reaction returns that there was a match the result is returned. Otherwise, the function calls itself again with the front of the list removed. Of course, there is a specialisation for an empty list which does nothing. BTW, this double dispatch variant is only cool ;-) for cases where the second stage of the double dispatch has to choose from only a few different possibilities. That's because the second stage performs a linear search. In contrast to GOF-visitor, which is essentially constant-time, this variant becomes slower the more choices it has in the second stage. But it scales much better in terms of dependencies. Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Some questions on the FSM submission
Chris Russell wrote: I understand. I need to design a state-based harness for a plug-in system and I'm going to use your FSM submission code and see how it goes. Likely the review will be over before I'm done, but at a minimum I will be able to give you feedback on how it works out with the Intel compiler. I'm delighted to hear that you want to use the library in a real-world project but I must also warn you: You'd be the first to do so! Intel should be quite conformant but I wouldn't be surprised if you encounter non-trivial problems. I started out developing on MSVC7.0 and MSVC7.1 but I had to drop 7.0 because it caused too many problems. Please do not hesitate to contact me if I can be of any help! This plug-in subsystem has a fairly simple and well-defined synchronization model so the fact that the library doesn't explicitly deal with threading issues is fine - I'll take care of that NP. BTW, I assume you are going to pass fsm::event subclass objects between threads. fsm::event is intrusively reference counted and already does the necessary locking when you use boost::intrusive_ptr. However, nobody else has reviewed the locking for potential race-conditions and the like (as should be done with all multithreading code). If you want to be on the safe side you can use boost::shared_ptr, but can then no longer use event deferral (see also Event deferral chapter in the tutorial). Parenthetically, when we do get around to talking about FSM, systems, and protocols (using Scott Wood's terminology), it would be good to solicit input and advice from William Kempf and Jeremy Siek. Referring back to a post I made here over a year ago (see [1]) I see FSM, threads, and BGL all working together to address these high level system/protocol design issues. More on that later. [1] Offlist and slightly over topic: Boost.Threads locking dilemma http://news.gmane.org/onethread.php?group=gmane.comp.lib.boost.develroot=%3COE2389SfBkHqzX5Yrbjf875%40hotmail.com%3E I think there's little I can do. When it comes to inter-FSM communication, one needs to make sure that a) the FSM event queue is absolutely bullet-proof regarding MT, b) FSMs commuicate with events only and c) the events will never contain references and pointers to data that is simultaneously accessed by multiple FSMs. As a library writer I can only influence a), which is tricky to get right but definitely not rocket-science. The rest lies in the hands of the users. I've identified Petri Networks as something that I may be able to use to model (and hopefully simplify) some nasty sections of my code. I'm still trying to get a handle on the subject myself. I've found Petri Nets World http://www.daimi.au.dk/PetriNets/ to be a good source of information on the subject. Something to be aware of, but definitely beyond the scope of the current discussion. Thanks, I will have a look... Scott Woods pointed out SDL (an ITU coding standard?) and remarks that in his opinion, it does a better job of handling FSM systems than UML. I'm not familiar with SDL. Check Scott's post for more information. I'll get in touch with Scott regarding SDL... Thanks very much for your feedback, I'm looking forward to hear about your Intel porting experiences. Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Preliminary submission: Finite State Machine framework
Bohdan wrote: I'll port to borland, but i'm not exprert in gcc build system. For gcc better ask somebody else. Thanks, I will get back to you as soon as I think the code is ready for porting. [snip] Hmmm, I never liked it that much myself but I was forced to design it this way due to some constraints of an earlier design. Now that you mention it, I think it should be possible to specify the inner initial state with the initiate() function, which could be called as follows: Pump.hpp: class Pump : public fsm::state_machine Pump { public: void Start(); }; Pump.cpp: struct Idle : public fsm::simple_state Idle, Pump void Pump::Start() { initiate Idle (); // * here * } Did you have something like this in mind? Definitely! After posting I realized that the current interface already allows you to hide states. E.g. you often want to ensure that a machine is initiated during construction: *StopWatch.hpp*: struct Active; // the only visible forward struct StopWatch : fsm::state_machine StopWatch, Active { StopWatch(); }; *StopWatch.cpp*: struct Stopped; struct Active : fsm::simple_state Active, StopWatch, fsm::transition EvReset, Active , Stopped {}; struct Running : fsm::simple_state Running, Active, fsm::transition EvStartStop, Stopped {}; struct Stopped : fsm::simple_state Stopped, Active, fsm::transition EvStartStop, Running {}; StopWatch::StopWatch() { initiate(); } The trick is to place the initiate(); call in a location where all states are known. So, clients see only one forward declaration of the initial state while all the other states are hidden in the .cpp file. However, this approach still exposes the whole state_machine interface to the clients (StopWatch *must* derive publicly from state_machine), which is often not what you want. In real-world code you'd probably more often have the state_machine subclass as a data member, maybe even more hidden with a pimpl. I therefore think that it is not necessary to change the current interface for information hiding purposes. Granted, it's not perfect, but the alternative I've outlined in my previous post isn't either, as Reece has pointed out. I might support both interfaces if there are other use cases that don't work with the current interface. Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Preliminary submission: Finite State Machine framework
Bohdan wrote: [snip] I therefore think that it is not necessary to change the current interface for information hiding purposes. Granted, it's not perfect, but the alternative I've outlined in my previous post isn't either, as Reece has pointed out. I might support both interfaces if there are other use cases that don't work with the current interface. Regards, Andreas I vote for both interfaces. If feature is easy to implement and if it allows to avoid even forward state declaration than why not ? I think you are right and initial state template parameter will simpify code, but allowing default InnerInitial = detail::empty_list as you did it for state template will allow complete removing of initial state from interface. BTW what about run-time selection of initial states ? : StopWatch::StopWatch() { if( ... ) initiateMyInitialState1(); else { initiateMyInitialState2(); initiateMyOrthohonalInitialState2(); } } That'd be such a use case then ;-). I'll support this in the next release (in about a week). Thanks, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Some questions on the FSM submission
Chris Russell wrote: I read through the documentation but haven't tried coding against the library yet. It looks quite useful for building isolated FSM mechanisms. I observe in my own work that I typically have many FSM that interact with each other. Yep, I think that's the case for almost all non-trivial programs using FSMs. It could be argued that this is really just one large FSM, but I like to think of them in terms of discrete FSM that It is indeed sometimes beneficial to use orthogonal regions instead of multiple FSMs, but only sometimes. interact with each other because it makes it easier to conceptualize class structure, threading, and occasionally inter-process or in the case of a distributed application, inter-system partitioning. I absolutely agree. That being said, I have the following questions (note these are not criticisms of the library or even a formal review - I'm trying to understand how it fits into my own work to decide how much time to invest in it). If I understand the documentation correctly, the submission is geared more towards creating hermetically sealed FSM mechanisms than for describing multiple interacting FSM's. Is this correct? No, but you are right in your observation that there's currently not much support for interacting FSMs. Most importantly, the current library is single-threaded, there's no support yet for FSMs running in their own threads. I made the current submission so that people can review the event processor and the way how they can build FSMs, which IMO is the most important part of an FSM library. Threading-support (and support for inter-FSM communication) will follow as soon as I'm convinced that there are no major problems with the current code. Also, I have some need to deal formally with Petri Networks. Related to FSM and automata theory in general, has any thought been given to supporting this class of FSA? No. I know little about these subjects. Can you recommend any books? I'm not a big UML fan so this aspect of the submission troubles me a little. Do we have a lot of UML fans here? I would be happier if it AFAICT, UML is the only internationally standardized modelling language for FSMs. However, I assume FSMs work more or less the same no matter what graphical representation you use. I guess the only thing needed would be a mapping from your preferred modeling language to boost::fsm. No? Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Preliminary submission: Finite State Machine framework
Aleksey, [snip] So, while here at work we have developed an in-house technology that achieves that goal for small-to-medium FSMs (the first prototype of which is outlined in the MPL paper), I am really looking forward to studying experts' work on the subject. Thanks, but I'm by no means an expert! All experience I have is some 1.5 years of heavy exposure. I was hoping that an expert would maybe tune into the discussion here at boost. BTW, an adapted version of your double-dispatch implementation made it into my library. Well, meanwhile, besides the above, my first comment is going to be really minor - I browsed over the tutorial (which looks great!), and although I am sure you know it, I thought it would be worth to point out that the 'public' specifier is redundant when the derived class is declared as 'struct'; if you omit those, the examples' syntax would become even more DSL-like (== better :). Good point (I didn't know as I'm not using structs all that often), I will change code and docs accordingly. However, I won't release for about two weeks, as reviewers might get confused if changes happen more often. Thanks, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Preliminary submission: Finite State Machine framework
Bohdan wrote: Hi Andreas, It is really nice to hear that FSM lib is ready for submission. Here are my comments : 1. Can you port your library to other compilers, at least for gcc ? I was trying to port older fersion of your lib to Borland, but code is too complicated to make it shortly. Unfortunately, I don't have much experience with anything else than MS compilers. I will try to port to gcc, but I'll probably need help for not-so-conforming compilers like Borland. 2. I think that nice thing about state machine is that you can remove its actual states from interface. I mean : is it conceptually good idea to pass initial inner state as a template parameter ? Hmmm, I never liked it that much myself but I was forced to design it this way due to some constraints of an earlier design. Now that you mention it, I think it should be possible to specify the inner initial state with the initiate() function, which could be called as follows: Pump.hpp: class Pump : public fsm::state_machine Pump { public: void Start(); }; Pump.cpp: struct Idle : public fsm::simple_state Idle, Pump void Pump::Start() { initiate Idle (); // * here * } Did you have something like this in mind? 3. Why we need state_machine class, wouldn't it better to have a single state class for both state state_machine. IMO state_machine is just state, which can't be changed and which doesn't have outer state. Am i wrong ? The state_machine and simple_state templates have quite differing interfaces and implementation so I'm not sure what that would buy you. Of course, it would be a simple matter to automatically make a state without an outer state derive from state_machine behind the scenes but I believe that would confuse people more than anything else. A state machine handles states and queues events while a state is not much more than an identifier. 4. Is it possible to use inherited events? ex: class MouseEvent; class MouseUpEvent : public MouseEvent; class MouseDownEvent : public MouseEvent code bool react( MouseEvent const event ) { ... } /code No, not exactly as you are suggesting. Although you can derive events from each other to write common code only once, you must always pass the most derived type to the fsm::event class template: template class MostDerived class MouseEvent : public fsm::event MostDerived { /* common mouse event code */ }; class MouseUpEvent : public MouseEvent MouseUpEvent {}; class MouseDownEvent : public MouseEvent MouseDownEvent {}; The best approximation of what you want to do is the following: struct Idle : public fsm::simple_state Idle, Whatever, mpl::list fsm::custom_reaction MouseUpEvent , fsm::custom_reaction MouseDownEvent { template class MostDerived fsm::result react( const MouseEvent MostDerived ) { /* ... */ } }; That is, you can write one react member function for all mouse events but you have to explicitly mention all most derived classes in the reaction list. I did consider polymorphic events but I wasn't able to make double dispatch work *automatically* (i.e. without requiring the user to write parts of the dispatch code themselves). I personally need polymorphic events only very rarely. Whenever I did, I was always able to change event granularity so that the need would go away. In your case that would mean to get rid of MouseUpEvent and MouseDownEvent alltogether and add the information to MouseEvent: struct MouseEvent : public fsm::event MouseEvent { enum ButtonMode { Up, Down }; ButtonMode mode_; }; In reactions where you need to discriminate on Up/Down you simply use a guard. Does the library/code generator you're currently using work with polymorphic events? Is not having polymorphic events a showstopper for you? If yes, I would be interested in a as-real-world-as-possible example. 5. Is it possible to inherit state machines: some states replaced, some removed ... ? Unfortunately not. I believe that is only practicable with a code generator. 6. Is there any way to get rid of Acyclic Visitor. Some dispatch policies ... ? Hope this question isn't too annoying :) boost::fsm no longer uses acyclic visitor! The current double dispatch implementation (which was inspired by Aleksey's fsm lib) uses one virtual call followed by a linear search for a suitable reaction, using one RTTI comparison per visited reaction. Although you cannot change the double dispatch implementation itself, you can change one aspect of it, i.e. RTTI. The BitMachine example shows how to replace native C++ RTTI with integers. I think only acyclic visitor and the above implementation fit the scalability requirements as documented in the rationale. While it should be possible to abstract them in a policy I think that effort would be a waste of time because the current approach is
Re: [boost] Re: Preliminary submission: Finite State Machineframework
Reece, Unfortunately, I don't have much experience with anything else than MS compilers. I will try to port to gcc, but I'll probably need help for not-so-conforming compilers like Borland. I have experience with GCC, MS and Borland if you need help porting the code. Cool, I could probably use some help with the gcc-port in about a month or so. Borland could follow. [snip] void Pump::Start() { initiate Idle (); // * here * } Wouldn't this complicate the code that the programmer has to write, whereas your version was simpler to implement. (Just my opinion). True. After posting I realized that the current design already allows you to hide the states in the .cpp file anyway. All that remains in the .hpp is one forward declaration of the initial state. The above approach is only necessary if you want to hide that as well. I guess most people wouldn't bother. Does the library/code generator you're currently using work with polymorphic events? Is not having polymorphic events a showstopper for you? If yes, I would be interested in a as-real-world-as-possible example. I'm not sure on this, but would Windows-based code that redirects events to a Window class be a polymorphic event, e.g. class WindowBase { public: virtual void Paint( win::api::DC hDC ); // ... }; class MyGUIWindow: public WindowBase { public: void Paint( win::api::DC hDC ); // custom window graphics }; Not sure how you would integrate this with a FSM though! AFAICT, WindowBase and MyGuiWindow objects are both state machines producing different reactions for the same Paint event, which is therefore not polymorphic. A state machine supports polymorphic events, only if ... - Events can derive from each other without restrictions (see Bohdan's MouseEvent example) - You can specify reactions for nodes as well as leaves of the event inheritance tree. That is for MouseEvent, MouseDownEvent and MouseUpEvent in Bohdan's example. Thanks for the feedback! Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Preliminary submission: Finite State Machineframework
Reece, Unfortunately, I don't have much experience with anything else than MS compilers. I will try to port to gcc, but I'll probably need help for not-so-conforming compilers like Borland. I have experience with GCC, MS and Borland if you need help porting the code. Cool, I could probably use some help with the gcc-port in about a month or so. Borland could follow. [snip] void Pump::Start() { initiate Idle (); // * here * } Wouldn't this complicate the code that the programmer has to write, whereas your version was simpler to implement. (Just my opinion). True. After posting I realized that the current design already allows you to hide the states in the .cpp file anyway. All that remains in the .hpp is one forward declaration of the initial state. The above approach is only necessary if you want to hide that as well. I guess most people wouldn't bother. Does the library/code generator you're currently using work with polymorphic events? Is not having polymorphic events a showstopper for you? If yes, I would be interested in a as-real-world-as-possible example. I'm not sure on this, but would Windows-based code that redirects events to a Window class be a polymorphic event, e.g. class WindowBase { public: virtual void Paint( win::api::DC hDC ); // ... }; class MyGUIWindow: public WindowBase { public: void Paint( win::api::DC hDC ); // custom window graphics }; Not sure how you would integrate this with a FSM though! AFAICT, WindowBase and MyGuiWindow objects are both state machines producing different reactions for the same Paint event, which is therefore not polymorphic. A state machine supports polymorphic events, only if ... - Events can derive from each other without restrictions (see Bohdan's MouseEvent example) - You can specify reactions for nodes as well as leaves of the event inheritance tree. That is for MouseEvent, MouseDownEvent and MouseUpEvent in Bohdan's example. Thanks for the feedback! Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Preliminary submission: Finite State Machine framework
Hi, Whenever I had to develop an FSM in the past, I chose either of the following paths: - For small and simple machines I often resorted to the IMHO ugly nested switch-case approach. - For bigger and more complex machines, I often used a code-generation approach because I failed to find a satisfactory library. No matter what solution I chose, I have always been missing code-expressiveness, ease-of-use and good maintainability. An attempt at an easy-to-use FSM library that supports well-maintainable and code-expressive machines of almost any size and does not require a code generator can be found in the fsm directories in the boost-sandbox and here: http://groups.yahoo.com/group/boost/files/FSM/ There is comprehensive tutorial and rationale documentation. All code has been tested with MSVC7.1 and boost 1.30.0 Features include: - Straightforward transformation from UML state chart to executable C++ code and vice versa - Comprehensive UML semantics support: - Hierarchical (composite, nested) states - Orthogonal (concurrent) states - Entry-, exit- and transition-actions - Guards - Event deferral - Error handling support - Full type-safety - State-local storage - Customizable resource management Any feedback is most welcome. Thanks, Andreas P.S. For people who are not yet using the boost library and would like to run the examples, FSM.zip contains a 4-step quick start guide. P.P.S. Developer summary ;-), copy-paste into your code editor: // The following code implements the state-machine: // // || // | O Active | // | || // | v| | EvReset // | | | // | || |- // | | Stopped| | // | | // | | ^ | // | | EvStartStop | EvStartStop |-O // | v | | // | | // | || | // | | Running| | // | | // #include boost/fsm/event.hpp #include boost/fsm/state_machine.hpp #include boost/fsm/simple_state.hpp #include boost/fsm/transition.hpp namespace fsm = boost::fsm; class EvStartStop : public fsm::event EvStartStop {}; class EvReset : public fsm::event EvReset {}; struct Active; struct StopWatch : public fsm::state_machine StopWatch, Active {}; struct Stopped; struct Active : public fsm::simple_state Active, StopWatch, fsm::transition EvReset, Active , Stopped {}; struct Running : public fsm::simple_state Running, Active, fsm::transition EvStartStop, Stopped {}; struct Stopped : public fsm::simple_state Stopped, Active, fsm::transition EvStartStop, Running {}; int main( int argc, char * argv[] ) { StopWatch myWatch; myWatch.initiate(); myWatch.process_event( EvStartStop() ); myWatch.process_event( EvStartStop() ); myWatch.process_event( EvStartStop() ); myWatch.process_event( EvReset() ); return 0; } ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: When to use which ETI workaround?
Sorry for the late reply, got too many things on my plate. No problem, I happen to have abandoned development on MSVC7.0 temporarily, for other reasons. Yep, in most cases that's enough. It's _always_ enough with MSVC 6.0, but 7.0 sometimes uses another, unknown, type for the instantiation's placeholder argument, so you cannot simply specialize the template anymore, Interesting, I wonder why they changed this :-(. I guess I'll drop 7.0 as soon as 7.1 is officially released what would obviously save quite a bit of trouble. The VC 7.0-specific case is rare enough to always try the 'int' specialization first (which is obviously less painful than the other), and then switch to the 'is_msvc_eti_arg'-based workaround if that doesn't help. VC 7.0 is not our production environment here at work, so I didn't have enough experience with it to be able to figure out when exactly these cases occur. Good to know, I feared that there are a few more incompatible ways to circumvent ETI. Thanks a lot! Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] When to use which ETI workaround?
Hi Aleksey, I've stumbled over ETI again. Browsing through MPL I have found different ways to circumvent it. In my case the following workaround seems to be sufficient: template class State struct get_context_ptr_type { typedef typename State::context_ptr_type type; }; template struct get_context_ptr_type int { typedef int type; }; I.e. by simply specializing a given metafunction with int. How do you decide when to use which workaround? Have you established rules or do you simply work your way through them until one works? Thanks, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] [type_traits] Missing comma in boost/type_traits/is_class.hpp
Hi there, The subject says it all (I'm using the CVS state from 5 minutes ago)... === RCS file: /cvsroot/boost/boost/boost/type_traits/is_class.hpp,v retrieving revision 1.6 diff -r1.6 is_class.hpp 84c84 ::boost::type_traits::ice_not ::boost::is_voidT::value ::value --- ::boost::type_traits::ice_not ::boost::is_voidT::value ::value, Thanks, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Regressions in type_traits and lexical_cast (was: Re:Questionabout boost::function)
[ ... ] Index: is_class.hpp === RCS file: /cvsroot/boost/boost/boost/type_traits/is_class.hpp,v retrieving revision 1.5 retrieving revision 1.6 diff -r1.5 -r1.6 84a85 ::boost::type_traits::ice_not ::boost::is_functionT::value ::value John? This is due to the missing comma I reported in http://lists.boost.org/MailArchives/boost/msg45211.php Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Regressions in type_traits and lexical_cast (was: Re:Questionabout boost::function)
Ah, yes it is. I've applied the patch (actually, Daniel Frey's version: no need to duplicate code) on mainline and the RC_1_30_0 branch. Thanks! :) Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] [optional] Possible alignment bug?
Hi there I found the following lines (57-61) in boost/optional.hpp union dummy_u { char data[ sizeof(T) ]; type_with_alignment ::boost::alignment_ofT::value aligner_; } dummy_ ; Not that I understand a lot about alignment issues, but shouldn't line 60 read: typename type_with_alignment ::boost::alignment_ofT::value ::type aligner_; I.e. ::type is missing? Thanks, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] [mpl] Patch for mpl::aux::msvc_eti_base for MSVC7.0
Hi Aleksey Sometimes I have to pass an abstract class to mpl::aux::msvc_eti_base. On MSVC7.0 the compiler complains with the following error: d:\Data\boostCvsRoot\boost\boost\mpl\aux_\is_msvc_eti_arg.hpp(48) : error C2259: 'boost::mpl::inherit2T1,T2' : cannot instantiate abstract class ... The following patch to the current CVS version seems to fix this: RCS file: /cvsroot/boost/boost/boost/mpl/aux_/is_msvc_eti_arg.hpp,v retrieving revision 1.1 diff -r1.1 is_msvc_eti_arg.hpp 48c48 static T get(); --- static const T get(); Since T is never cv-qualified or a reference, this should work under all circumstances. Thanks Regards, Andreas P.S. Just to make sure you've seen it: http://lists.boost.org/MailArchives/boost/msg44601.php It's definitely low prio because it's a *warning* appearing only on MSVC7.1. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] MSVC7.1 warning in boost/mpl/advance.hpp (low prio)
Hi Aleksey For warning levels = 2 the attached program produces the given warning. AFAICT, the code in advance.hpp should be correct, so this has low priority. However, to avoid the warning, the if_ expression should probably be replaced with its apply_if equivalent. Thanks, Andreas --- #include boost/mpl/list.hpp #include boost/mpl/distance.hpp #include boost/mpl/advance.hpp namespace mpl = boost::mpl; typedef mpl::list int my_list; typedef mpl::distance mpl::begin my_list ::type, mpl::end my_list ::type ::type my_distance; typedef mpl::advance mpl::begin my_list ::type, my_distance ::type my_iter; int main() { return 0; } --- D:\Data\Private\boostCvsRoot\boost\boost\mpl\negate.hpp(36) : warning C4146: unary minus operator applied to unsigned type, result still unsigned D:\Data\Private\boostCvsRoot\boost\boost\mpl\advance.hpp(51) : see reference to class template instantiation 'boost::mpl::negateT' being compiled with [ T=my_distance ] D:\Data\Private\boostCvsRoot\boost\boost\mpl\advance.hpp(78) : see reference to class template instantiation 'boost::mpl::aux::advance_implCategory,Iterator,N' being compiled with [ Category=boost::mpl::list_iteratorboost::mpl::listint::type::category, Iterator=boost::mpl::beginmy_list::type, N=my_distance ] TestPartial.cpp(11) : see reference to class template instantiation 'boost::mpl::advanceIterator,N' being compiled with [ Iterator=boost::mpl::beginmy_list::type, N=my_distance ] --- ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Glitch with mpl::placeholder(s)?
Hi Aleksey I have got mpl out of CVS 5 minutes ago. Code that previously compiled fine now shows the following error: d:\Data\boostCvsRoot\boost\boost\mpl\aux_\include_preprocessed.hpp(27) : fatal error C1083: Cannot open include file: 'boost/mpl/aux_/preprocessed/msvc70/placeholder.hpp': No such file or directory MPL can be fixed as follows: diff -r1.5 placeholder.hpp 33c33 # define BOOST_MPL_PREPROCESSED_HEADER placeholder.hpp --- # define BOOST_MPL_PREPROCESSED_HEADER placeholders.hpp OR users can fix their code by replacing #include boost/mpl/placeholder.hpp with #include boost/mpl/placeholders.hpp and mpl::placeholder; with mpl::placeholders; Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Glitch with mpl::placeholder(s)?
David Abrahams [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] Hi Andreas, Aleksey just did a big round of renaming before the first official release of MPL (including changes like int_c - int_, and placeholder - placeholders); I believe that placeholder.hpp is obsolete and should have been removed from CVS. In this case we could keep it for backwards-compatibility reasons, but in general that was deemed a bad idea for most names. Ok, then I believe it's better to completely remove placeholder.hpp from CVS. Thanks, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: More metaprogramming problems with MSVC7.0
[ ... ] Has anyone else ever encountered similar problems with either 7.0 or 6.5? Yep, it's a known bug called early template instantiation (ETI). It's briefly described here - http://lists.boost.org/MailArchives/boost/msg39915.php. Are there any workarounds? Sure. In your case, it would be as simple as this: #include boost/mpl/aux_/msvc_eti_base.hpp ... template class Derived, class Context, class Transitions = empty_list, class InnerInitial = empty_list class simple_state : public mpl::aux::msvc_eti_base typename state_base_type // Derived, Context, Transitions, InnerInitial ::type ::type {}; Thanks very much! I wouldn't have dreamt that convincing 7.0 to compile it will be s easy! Best Regards, Andreas P.S. Is it a good idea to use mpl::aux::msvc_eti_base on all platforms (on conforming compilers I'd expect it to call mpl::identity) or should I #ifdef my way around it? ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: More metaprogramming problems with MSVC7.0
Dave, David Abrahams [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] This looks seriously like ETI (early template instantiation) again. Unfortunately I'm not sure exactly what the fix is; Aleksey is the only person I know who really understands how to work around this. One thing you could try: template class Derived, class Context, class Transitions = empty_list, class InnerInitial = empty_list class simple_state : public mpl::identity // Here typename state_base_type Derived, Context, Transitions, InnerInitial ::type ::type// Here {}; Unfortunately this doesn't help, 7.0 reports d:\Data\StopWatch\StopWatch.cpp(58) : error C2516: 'boost::mpl::identityT::type' : is not a legal base class with [ T=state_base_typeDerived,Context,Transitions,InnerInitial::type ] But thanks anyway! I'll wait for Aleksey then... Regards, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: More metaprogramming problems with MSVC7.0
One last shot-in-the-dark: add this specialization: template class simple_stateint, int, int, int {}; What ETI does is to use an instantiation of some template with all int parameters internally as a stopgap measure while it's waiting to discover what the parameters really are. After this, I give up! No luck either. Compilation fails with exactly the same error. Thanks again, Andreas ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: [mpl] More problems with MSVC 7.0, 8-/
Aleksey, Thanks again for the speedy fixes. The test program works now, but there still seems to be a quirk with fold in my main sources. I will be off to London soon, so I don't have time for a new test program. I will get back to you in about a week. day-to-day work), and I just hope you didn't spent too much time figuring out what was happening there. FYI, MSVC 6.5 is much more I only spent too much time on the error I reported first. Now, I always also try with MSVC 7.1, which is so much better. Before I got hold of 7.1, with 7.0 learning mpl was a bit tedious because you never know whether its you or the @#!* compiler ;-). Best regards, Andreas P.S. I can't say how grateful I am that you are battling the various broken compilers for the benefit of all of us! MPL does a nice job at hiding all that crap. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: mpl::is_sequence incomplete_type ?
Aleksey, Yep, I understand that; but I was specifically interested whether _incomplete types_ are an important case here. If it's more than just a corner-case situation, I'll look into fixing it. [snip] But 'is_sequence' does work on MSVC 7.0, in general. So, unless passing an incomplete type is a common-place situation, I would recommend just to document the pitfall itself. In my application the argument passed to is_sequence is _never_ a complete type. See below for reasons. It was. Fixed now in the CVS. Thank you very much! Both apply and apply1 work now. I will use apply1 as you recommended. Best regards, Andreas P.S. The following is an outline of how I define the states of a statemachine. Inner states must know their outer state for much the same reasons as a derived class must know its base. However, an outer state must also be able to define which of its inner states is the initial state (see 1). This leads to a circular dependency that can only be broken if the InnerInitial parameter is permitted to be an incomplete type. To support concurrent (or orthogonal) states an outer state can have multiple inner initial states, that's why the user can also specify a list. Finally, an empty list means that the defined state does not have an inner state, i.e. it is itself a leaf state (2). // our statemachine (context of all outermost states) class StopWatch : public /* */ { /* */ }; template class Derived, class Context, // either an outer state or a state_machine class InnerInitial = mpl::list class state { /* */ }; // forward declare the inner initial state class Running; // the outer state class Active : public state Active, StopWatch, Running /* 1 */ {}; // an inner state that happens to be the initial state class Running : public state Running, Active /* 2 */ {}; // another inner state class Paused : public state Paused, Active /* 2 */ {}; ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] [mpl] More problems with MSVC 7.0, 8-/
Aleksey, The attached code works like a dream on MSVC 7.1, but MSVC 7.0 again has its problems: Problem No. 1: Expression 1 does not seem to work, because Derived is an incomplete type: To reproduce, you might want to comment-out expression 3 and uncomment expression 4. Problem No. 2: mpl::fold produces errors similar to the ones I had with transform yesterday In the original file, please comment out expression 1 and uncomment expression 2 to reproduce. Luckily, I can continue with MSVC7.1 now, so these bugs have low priority. Thank you! Best regards, Andreas #include boost/mpl/placeholder.hpp #include boost/mpl/apply_if.hpp #include boost/mpl/identity.hpp #include boost/mpl/apply.hpp #include boost/mpl/list.hpp #include boost/mpl/front.hpp #include boost/mpl/is_sequence.hpp #include boost/mpl/transform.hpp #include boost/mpl/fold.hpp template class Event class event_handler { protected: event_handler() {} ~event_handler() {} private: virtual bool handle_event( const Event theEvent ) = 0; }; template class Derived, class Event, class Destination class transition_handler : public event_handler Event { private: virtual bool handle_event( const Event ) { /* */ } }; template class Event, class Destination struct transition { template class Derived struct apply { typedef transition_handler Derived, Event, Destination type; }; }; namespace mpl = boost::mpl; template class T struct make_list : public mpl::apply_if mpl::is_sequence T , mpl::identity T , mpl::identity mpl::list T{}; class empty_type {}; template class Base1, class Base2 struct derive { struct type : public Base1, public Base2 {}; }; class EvPause {}; class EvStop {}; class Paused {}; class Stopped {}; using namespace mpl::placeholder; template class Derived, class Transitions struct state_base_type { private: typedef typename make_list Transitions ::type transition_list; // The following is a problem, because Derived is incomplete typedef typename mpl::transform /* 1 */ transition_list, mpl::apply1 _, Derived ::type handler_list; //typedef mpl::list transition_handler Derived, EvPause, Paused // handler_list; /* 2 */ public: // There are problems with the following as well, errors are similar // to the ones I had with transform yesterday typedef typename mpl::fold /* 3 */ handler_list, empty_type, derive _1, _2 ::type type; //typedef empty_type type; /* 4 */ }; class Running : public state_base_type Running, mpl::list transition EvPause, Paused , transition EvStop, Stopped ::type {}; int main() { // this is just to see the type in the debugger Running * pState1 = 0; pState1; return 0; } ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: mpl::is_sequence incomplete_type ?
Aleksey, It might be possible to fix it, but it will require some work. Let me know if it's important for you, and I'll move it up in my TODO list. Well, it is not that important since mpl::is_sequence is only used to provide some syntactic sugar. I could just as well tell my users that they always have to specify an mpl::list containing a single type instead of a type under MSVC... Thanks, Andreas P.S. While making my first serious steps with mpl yesterday, I ran into some weird errors while trying to compile the following with MSVC 7.0. Could this also be a limitation of my platform? Am I using some functions that are a problem for MSVC, or am I just missing something? #include boost/mpl/placeholder.hpp #include boost/mpl/apply.hpp #include boost/mpl/list.hpp #include boost/mpl/transform.hpp template class Event class event_handler { protected: event_handler() {} ~event_handler() {} private: virtual bool handle_event( const Event theEvent ) = 0; }; template class Derived, class Event, class Destination class transition_handler : public event_handler Event { private: virtual bool handle_event( const Event ) { /* */ } }; template class Event, class Destination struct transition { template class Derived struct apply { typedef transition_handler Derived, Event, Destination type; }; }; class Paused {}; class Running {}; class EvPause {}; // Since I can write this: typedef boost::mpl::apply transition EvPause, Paused , Running ::type handler1; // I should be able to write the following, or am I missing something? // Does not compile under MSVC7.0 using namespace boost::mpl::placeholder; typedef boost::mpl::list transition EvPause, Paused trans_list; typedef boost::mpl::transform trans_list, boost::mpl::apply _, Running ::type handler_list; typedef boost::mpl::front handler_list ::type handler2; int main() { // this is just to see the type in the debugger handler1 * pHandler1 = 0; pHandler1; handler2 * pHandler2 = 0; pHandler2; return 0; } ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost