Re: [boost] Some FC++ comments
Brian McNamara wrote: On Wed, Aug 13, 2003 at 11:27:08PM -0400, Brian McNamara wrote: I've been working on a draft of the documentation for the boostified version of FC++, and it's finally reached a good enough state to be potentially useful to you-all. Check out I've wanted to do dynamic inheritance (DI) for some time now. By DI I mean what Stroustrup described in _Design & Evolution of C++_ in section 12.7 titled "Delegation". I was hoping fc++ or something similar could implement the "Mixin-based Inheritance" described by Bracha and Cook in an article with that name and more recently in http://citeseer.nj.nec.com/11696.html. This dynamic inheritance I think could substitute for the BGL property maps and for the workspaces in polaris (http://polaris.cs.uiuc.edu/ ) which are somewhat lik the BGL propery maps. I think openc++ might also find this useful: http://sourceforge.net/mailarchive/forum.php?thread_id=2031538&forum_id=11832 I'll try my hand it this when I get my current project done; meanwhile, maybe someone else would like to take this on. I think it would be challenging and the result pretty useful. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Any interest in iostream-like pipe?
Larry Evans wrote: Alexander Nasonov wrote: [snip] The following post: http://aspn.activestate.com/ASPN/Mail/Message/boost/1593756 There's also: http://lists.boost.org/MailArchives/boost/msg46513.php indicating some interest in combining thread safety and decoration. It seems to me (a novice in threading) that what needs to be protected is the access to the end of the pipeline, i.e. the final streambuf, which is connected to the actual output medium (a file, or console or pipe). Hence, I'm wondering if it's a good idea to combine the two in a ostream class. I confess I haven't looked at your code, but I think it would be nice if somehow it could be streambuf thread safety could be separated from the {o,i}stream features which are only concerned with formatting. Does that make sense? ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Any interest in iostream-like pipe?
Alexander Nasonov wrote: [snip] The library doesn't use OS pipes. Pipe support is implemented by hand with a help of Boost.Threads. Synchronization occurs only in underflow, overflow, sync, open and close functions which means fast I/O. The library also has two capacity models: limited and unlimited. In the former case, if writer goes ahead of a reader it stops and waits; in the latter case, the writer always allocates new block of memory when overflow occurs. The following post: http://aspn.activestate.com/ASPN/Mail/Message/boost/1593756 indicates there's some interest in thread-safe access to ostreams at least. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: filtered/decorated streambufs
Larry Evans wrote: [snip] I'm trying to get synopsis to translate into Boost guideline form; however, I'm having trouble with getting comments properly attached to the declarations. As soon as that is done, I'll upload it. The comments are properly attached; however, the ASCII formatter only formats the declarations, not the actual definitions. Hence, the executable code is not formatted according to Boost's guideline form. Maybe I'll get around to tweaking synopsis to do this later. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Proposed smart_handle library
John Madsen wrote: > Starting from the smart_ptr headers (shared, scoped, and weak), I've > created corresponding handle classes. The motivation is to provide > RAII semantics for handle based resources. Windows' HANDLEs, > FILE*s, and file descriptors are the most obvious examples. [snip] > > I'd certainly love to hear ideas, criticism, etc. and ultimately see this > become part of boost. wouldn't deadlock detection be another application? Taking the definition directly from my "long-ago" OS course memory, a deadlock occurs when one task or process holds a "handle" to a lock on a resource required by another task, which in turn, holds another "handle" to a lock on another resource required by first task. If a task cannot acquire the resource after a certain amount of time, it might try to find whether another task is holding that resource. Now, if all the "handles" record their location in memory using Detlef's method for smart pointers (and implemented in boost files under shared_cyclic_ptr), wouldn't this make it possible for a task to do this? ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: filtered/decorated streambufs
Paul A. Bristow wrote: | -Original Message- | From: [EMAIL PROTECTED] | [mailto:[EMAIL PROTECTED] Behalf Of Larry Evans [snip] I can see much logic in your layout (much more perhaps than in the C language!) but sadly, I think the balance of pros and cons is in favour of sticking to a consistent style for a library like Boost code guidelines. I'm trying to get synopsis to translate into Boost guideline form; however, I'm having trouble with getting comments properly attached to the declarations. As soon as that is done, I'll upload it. Meanwhile, I've emailed [EMAIL PROTECTED] a copy of the latest version where: The main change is that the ostreambuf_decorator_end, which replaces the ostreambuf_decorator_con, only serves to terminate the pipeline. I thought this was better than having the terminator do two things at once. Also, the code is simpler. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] why no strict ownership smart pointer in boost
Howard Hinnant wrote: On Tuesday, July 1, 2003, at 08:21 PM, Schoenborn, Oliver wrote: On Tuesday, Jul 1, 2003, at 17:36 America/Denver, Schoenborn, Oliver wrote: On Tuesday, Jul 1, 2003, at 14:38 America/Denver, Boost wrote: Why is there no strict-ownership smart-pointer in boost? Just curious to know what the reasons are. Thanks, What do want beyond what boost::scoped_ptr and std::auto_ptr provide? Ability to be used in STL containers, and explicit transfer of ownership capabilities (e.g. *no* move-on-copy etc). So what would the copy semantics be? No copy allowed, except temporarily when inside the container to insert or re-order or transfer from one container to another. Oliver You may be looking for something that just doesn't exist in the language yet: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/ n1377.htm#move_ptr%20Example This is a pointer with move semantics only, no copy semantics. And it does not move with copy syntax. Such a pointer is only a part of the solution. It also needs containers that know how to deal with a movable but non-copyable object. And of course language support makes everything click. :-\ I have experimented (actual working code) with what you're looking for. But the tools are *experimental* and not ready for prime time public use. NTL ( http://www.ntllib.org/ ) claims to have this today (I think). I haven't looked at it closely enough to give a good review, but you might give it a go. There's also: http://pcroot.cern.ch/TaligentDocs/TaligentOnline/DocumentRoot/1.0/Docs/books/FS/FS_59.html whose TInstanceOf or TOnlyPointerTo may be what your wanting. Also, polaris ( http://polaris.cs.uiuc.edu ) had what it called Live and Ref Wrappers corresponding to Strong and Weak pointers; however, there could only be a single LiveWrapper to a heap allocated object. When that went away, the detructor was called; however, the memory was NOT reclaimed until all the RefWrapper's also went away. If a RefWrapper tried to access an object whose LiveWrapper had gone away, a run-time error was diagnosed. This was useful for things like program tree's where there could only be one owner (corresponding to the AST) but maybe several references to an owned object (e.g. a goto referencing another statement). ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: filtered/decorated streambufs
On 28 Jun 2003 01:38:14 -0700 (PDT) Daryle Walker wrote: > On Friday, June 27, 2003, at 8:34 AM, Larry Evans wrote: > >> Paul A. Bristow wrote: > > [SNIP] [snip] > Was the code machine-generated (e.g. Perl script, etc.)? I was > wondering that when I noticed that the statements end (as always) and > _begin_ (sometimes) with semicolons (there's only one semicolon between > consecutive statements), and empty functions still have one semicolon. > What advantages does your style have? Years ago, I noticed one person put all semicolons in the same column. This lead to semicolons in a far right column's, I suppose to make it easier to see missing semicolons. Also, years ago, another person wrote a program to print is program formated with square blocks indicating the nested, e.g. if(x==7) | a := b; | | if(a>c) | | | | | a := c; | | | | b := c; | | | | | c := 2; | I just substituted the ;'s for the left |'s in the blocks closely approximated what both these people intended: ; a := b ; if(a>c) { a := c ; b := c ;} ; c := 2 This first person also put the type and identifier of his declarations in distinct columns: int a; very_long_typenameb; the purpose being, I guess, to easily find the identifier or type. I thought finding the identifier was most important so I thought why not put it in a prominent place, at the left hand margin. Hence: int a; very_long_typename b; This left the problem of semicolons. In the case of declarations, this sometimes serves as a "placeholder" for the definition of a method; hence, the "logical" location for it is the place where the definition would go. Hence: int a ; very_long_typename b ; char a_not_yet_defined_function(void) ; This also has the distinct advantage of enabling cut-and-paste when defining the function: char class_owning_following_function:: a_not_yet_defined_function(void) { ... ;} Now what about beginning elements in argument list with the character "," ? Well this is just an extension of the ";" usage. If you think about the parse-tree, you see another reason why. Each delimiter, either "," in case of arg list or ";" in case of statement list, is the root to a subtree in the parse tree (similar to a cons in lisp). Hence, putting these operators first amounts to turning the parse tree 90 degrees counter-clockwise. In addition, this method resembles a bulleted list, where the bullets are replaced by the delimiters. And the comments. Why: int a_function ( type1 arg1 , type2 arg2 ) //Comments for a_function { //function defintion } instead of: //Comments for a_function int a_function ( type1 arg1 , type2 arg2 ) { //function definition } I had seen comments before a function repeat the listing of arguments. This seemed a needless duplication. If instead, the function name and its arguments were first introduced followed by the comments describing the function, then there would be no need for a duplicate listing of function arguments. In addition, since the comments are a "paraphrase" of the function definition, it makes more sense that they should come just before that definition. It seems that this should also make it easier for a documenter, such as synopsis, to more easily identify which comments belong where. > > I'm still wondering about some of the design decisions, though. I think there are about 4 design decisions: 1) use unbuffered streambuf The reason for this is just to avoid the complication of dealing with buffering. It may lead to more virtual function calls, but I'd prefer not to do optimization until it's needed. 2) use of {attach,detach}_ostream methods These methods keep the destination ostream's streambuf to the "head" of the pipeline of ostreambuf_decorator_abs. The head is the last ostreambuf_decorator_abs added to the pipeline. The tail is the first ostreambuf_decorator_abs added to the pipeline. The m_streambuf of this first ostreambuf_decorator_abs points to the original streambuf of the ostream passed as argument to the CTOR of this first ostreambuf_decorator_abs, which is actually an ostreambuf_decorator_con. 3) use of ostreambuf_decorator_con to start building the pipeline The "pipeline" is the linked list of ostreambuf_decorator_abs's (The _abs suffix is for "abstract". The _con suffix is for "concrete". ) This is needed in order to terminate the recursion of the {attach,detach}_ostream methods. I
Re: [boost] Re: indentation on streams
John Torjo on 23 Apr 2003 06:16:20 -0700 (PDT) wrote: [snip] > > 2. binding marg_stream to a std::ostream& couples them too much IMHO > (that is, the marg_stream variable is coupled to the other stream). > This actually came to me when I wanted to use col_io together with my > thread_safe_log library. > > The point I'm trying to make (the way I see it) is that I'm not sure you > should keep a reference to a std::ostream inside marg_ostream. First of all, > because the reference might become invalid if the underlying stream is > destroyed (which actually happened in my case, since I use > temporaries But doesn't the indent_ostream store an std::ostream& in m_underlyingOut, and doesn't this mean indent_ostream suffers the same problem? > heavily). Second, the underlying stream and the marg_ostream variable might > go out-of-sync (formatting information, state, etc.) which could > cause The code at boost/files/col_io/test_ostreambuf_decorator.zip shows an unbuffered version which, because it's unbuffered, is always in-sync. However, I don't think this is what you want, but maybe a variation of it. I don't think it's what you want because it replaces the streambuf in the "final" ostream with a linked list of ostreambuf_decorator_abs's terminated by the "original" ostreambuf of the ostream. Hence, the final (actually only) ostream writes to the ostreambuf_decorator_abs at the head of the list, which does it's transform and sends the result to the next ostreambuf_decorator_abs or the final ostreambuf, which was the original ostreambuf in the only ostream. However, as you've indicated, this final ostream may disappear; hence, you want "endpoint" this "pipeline" of ostreambuf_decorator_abs's to be changeable. More precisely, you want the endpoint to be: string_stream_type m_pStreamBuffer; defined in: template< class char_type , class traits_type = std::char_traits< char_type> > class basic_message_handler_log_streambuf; where: typedef std::basic_ostringstream< char_type> string_stream_type; as defined in message_handler_log.hpp in your upload: http://groups.yahoo.com/group/boost/files/thread_safe_log.zip And all this means, I think, that if the endpoint of the pipeline is m_pStreamBuffer instead of the final ostream's streambuf, then you'd get what you want. Is that right? ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] filtered/decorated streambufs
Paul A. Bristow wrote: I also have an updated ('C++ 1998 STL standardized') version of James Kanze's of filtering streambuf and filtering streams derived from his files at www.gabi-soft.fr re-built for MSVC 7.1, (Could be posted on request). Please do. and his illuminating articles in C++ Report 1998 (attached). There are also several examples of Inserting (decorating - not sure this term is an improvement) and Extracting on input, and some tests (though not Boost style I guess it depends on whether a person is more used to unix "filtering" term or the person wants to emphasize the "design pattern" of the code (as mentioned by Maxim Egorushkin on about 6/14). [snip] (More sadly, I was much impeded in trying to understand much of Larry's work in progress on account of the bizarre layout - this would be an serious impediment to acceptance by Boosters - see the Boost coding guidelines?) OK. I concede it's bizarre, but I really didn't think it would impede understanding. I've just been using it for years and it has some distinct advantages (IMHO) over the Boost guidelines. However, I been thinking about writing a program to just move the ";"'s to the end of line using maybe spirit or wave. I was also thinking about using a filter or decorator to do that :) Now I have more of a reason to do that. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] decorated streambufs
Larry Evans wrote: [snip] The articles at: http://www.gabi-soft.fr/articles-en.html pretty much confirms that Kanze's code does more (and possibly does it better) than my code at files/col_io/test_ostreambuf_decorator.zip. [snip] http://groups.yahoo.com/group/boost/files/col_io/delta.tar.gz when combined with: http://www.gabi-soft.fr/gabi-lib.tgz demonstrates both adjustable left margins and line numbering. Kanze's software defines the sync method to synchronize the "final" destination streambuf, which makes perfect sense since all other streambufs are empty. It also probably better to put the "final" streambuf at the beginning of the list of streambufs instead of at the end, as test_ostreambuf_decorator.zip does, since that makes inserting more "filters" or, using another term, decorators into the pipe. Maybe someone else could experiment with the code to get a better idea? ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] decorated streambufs
Larry Evans wrote: [snip] The code mentioned MAY be very similar to that of J. Kanze available at: The articles at: http://www.gabi-soft.fr/articles-en.html pretty much confirms that Kanze's code does more (and possibly does it better) than my code at files/col_io/test_ostreambuf_decorator.zip. If we really want an indentor, as well as other filters, I think Kanze's code may be the way to go. However, I think renaming them to use decorater would be good to emphasize their relationship to the decorator pattern as Maxim Egorushki observed. [snip] ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] decorated streambufs (was: Interest in library generatingstreambufs ...)
Larry Evans wrote: > Larry Evans wrote: > > [snip] > >> Please see the just uploaded marg_ostreambuf.cpp for a >> little better version. > > > The just uploaded test_ostreambuf_decorator.zip contains > renamed classes as well as virtual {detach,attach}_ostream > to avoid using ostream* m_ostream==0 as flag indicating > the end of the chain of decorators. The code mentioned MAY be very similar to that of J. Kanze available at: http://www.gabi-soft.fr/code/Util/IO/FilteringOutputStream/gb/FilteringOutputStream.hh I say this because in the comments to the code, in class: class GB_FilteringOutputStreambufBase : public GB_iostd::streambuf and after: private: // insert : // there's the following: // Inserts a character into the destination. This is where // the actual filtering takes place. The function receives // the destination streambuf and the character as arguments; // in case of error, it should return EOF, otherwise, // anything else. Exactly what it does with the character is // upto the function in the derived class: it can pass it on // to the destination, simply drop it, send a dozen or so // other characters as well, or whatever it wants. Since this is essentially what marg_ostreambuf does when it sees a '\n' character( i.e. it outputs the margin before the next output char) , I thought maybe this would be a better, more general, solution to the problem solved by marg_ostreambuf and marg_ostream in: http://groups.yahoo.com/group/boost/files/col_io What do other's think. Would J. Kanze be interested and have time to contribute this work to boost? ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] decorated streambufs (was: Interest in library generatingstreambufs ...)
Larry Evans wrote: [snip] Please see the just uploaded marg_ostreambuf.cpp for a little better version. The just uploaded test_ostreambuf_decorator.zip contains renamed classes as well as virtual {detach,attach}_ostream to avoid using ostream* m_ostream==0 as flag indicating the end of the chain of decorators. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: Re: Interest in library generatingstreambufsfromobjects
Larry Evans wrote: [snip] test_marg_ostreambuf.zip. Also, I was thinking that using the you might want to string together the fwd_ostreambuf's much like a unix pipe. For example, you could provide a Please see the just uploaded marg_ostreambuf.cpp for a little better version. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: Re: Interest in library generatingstreambufsfromobjects
Maxim Egorushkin wrote: "Larry Evans" <[EMAIL PROTECTED]> wrote in message news:[EMAIL PROTECTED] I'll soon upload a commented an simplified version of marg_ostreambuf and maybe a templatized version to parameterize the addedState. I may rename it too to decorated_ostreambuf or something similar. I think there is no need for marg_ostream at all. Why reinvent a bicycle if The only reason is to avoid passing 2 objects, i.e. the ostream& and the accompanying indent_decorator. Of course, you can get the indent_decorator from the ostream with rdbuf and a cast; however, this was demonstrated by the marg_ostreambuf.cpp in the test_marg_ostreambuf.zip which I uploaded yesterday. one can use original std::basic_ostream<>. And it would be great if marg_ostreambuf were parameterized by char and traits types like original std::basic_streambuf<>. Agreed. Here is the code for decorator. This looks pretty much the same as marg_ostreambuf in the test_marg_ostreambuf.zip, except the indent_decorator is not derived from ostreambuf and uses marg_ostreambuf as a member variable. Also, it's not unbuffered. Making it unbuffered allowed simplification of marg_ostreambuf, as you can see by comparing the marg_ostreambuf's in col_io.zip and test_marg_ostreambuf.zip. Also, I was thinking that using the you might want to string together the fwd_ostreambuf's much like a unix pipe. For example, you could provide a lineno_ostreambuf which numbers each line followed by the marg_ostreambuf which indents you code. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: Interest in library generating streambufsfromobjects
Maxim Egorushkin wrote: "Larry Evans" <[EMAIL PROTECTED]> wrote in message news:[EMAIL PROTECTED] [snip] I've examined col_io. At a high point of view it is the decorator pattern - you extend basic_ostream<> interface with identation capabilities. The code I posted, particulary input/output_buffer classes, is the adapter pattern - it adds basic_streambuf<> interface to a sequence. So, this patterns have different purposes. Thanks very much. I hadn't realized col_io (or more particularly the code in test_marg_ostreambuf.zip) was a decorator pattern. However, I see now that the correspondence with the "Structure" secion on p. 177 of the GOF '95 _Design Patterns_ book. More precisely: Component -> streambuf ConcreteComponent -> the streambuf from the original ostream Decorator -> fwd_ostreambuf Decorator::Operation -> fwd_ostreambuf::overflow ConcreteDecoratorA -> marg_ostreambuf ConcreteDecoratorA::addedState -> marg_put I'll soon upload a commented an simplified version of marg_ostreambuf and maybe a templatized version to parameterize the addedState. I may rename it too to decorated_ostreambuf or something similar. If I get you right you want to see how one can add identation capabilites to a buffer using the adapters. Well, it could be done but it would be somewhat onerous. One would have to wrap an existing buffer with a developed sequence OK. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Interest in library generating streambufs fromobjects
Larry Evans wrote: [snip] Any comments? Maybe this method could be used Yeah. What happens when ostream destructor is called. Since this probably calls the streambuf destructor, and if the streambuf is actually a fwd_streambuf, and the ~fwd_streambuf resets the ostream.rdbuf, this just may be a problem :(. IOW, OOPS. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Interest in library generating streambufs fromobjects
Larry Evans wrote: [snip] The prototype of the "using overflow+sputc" method is in files/col_io/test_fwd_streambuf.zip. A more complete marg_ostream example is in files/col_io/test_marg_ostreambuf.zip. It shows how an ostream indentation can be changed without resorting to a wrapper class like marg_ostream in col_io/col_io.zip. It also shows how to change the indentation with use of dynamic_cast and call to marg_ostreambuf member function. It also shows how the original status of the ostream can be restored by simply deleting the result of ostream::rdbuf. Any comments? Maybe this method could be used with Maxim's adaptors? ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Interest in library generating streambufs fromobjects
Larry Evans wrote: [snip] with buffered input. After thinking some more, I thought about just using overflow and sputc to "pipe" the output to the next streambuf. This greatly simplified the code. Would something similar work with [snip] The prototype of the "using overflow+sputc" method is in files/col_io/test_fwd_streambuf.zip. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Interest in library generating streambufs fromobjects
Maxim Egorushkin wrote: [snip] I posted here a while ago streambuf adapters. There was no any answer. May be you might find it intresting. Sorry I overlooked it. The main idea is simple: to present any linear sequence as std::basic_streambuf<>. It sounds like what people, in particular Robert Ramey , wants. Here are the file. I had a brief look and it looks promising. However, I'm wondering if some of the complexity can be avoided. I had a hard time figuring out just how to get marg_ostreambuf in files/col_io/col_io.zip to work with buffered input. After thinking some more, I thought about just using overflow and sputc to "pipe" the output to the next streambuf. This greatly simplified the code. Would something similar work with your code. In particular, can you create an equivalent to marg_ostream from files/col_io/col_io.zip by using your, I guess, stream buffer redirectors? I'd like to see that. Maybe Reece Dunn would also since he's "interested in indentation facilities." ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: interest in library generating streambufs
Jonathan D. Turkanis wrote: I've thought a little more about composition, and I think I see what your getting at. Composing streambufs is easy if the conversion facilities you want to use are expressed as codecvts. A wrapper around the code I posted could be used to generate streambufs like so: template struct compose { }; // Derives from basic_streambuf<.., ..> You could then chain this operation: compose > >. But the interface of std::codevt is complicated by the need to make the member functions const and pass the state as an The code in files/col_io/test_fwd_streambuf.zip shows another way. The fwd_ostreambuf simply implements a linked list of streambuf* each of which forwards the streambuf::overflow arg to the next link in the chain. The marg_ostreambuf in that zip file prototypes a simplification of the marg_ostreambuf in the col_io.zip. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] More refinement for future(?) more_io
Daryle Walker wrote: Since my last announcement (a couple of weeks ago) of refining the more_io files that were reviewed a few months ago, I've done another set of revisions. The altered files are in the Boost Sandbox CVS. Besides an altered "boost/io_fwd.hpp" and "libs/io/doc/index.html", we got: boost/io/array_stream.hpp [snip] libs/io/test/array_stream_test.cpp The array_stream_test.cpp includes: typedef boost::io::basic_array_ostreamaostream; however, that's not defined in array_stream.hpp. Where can I find its definition? ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] RE: Interest in library generating streambufs from
Robert Ramey wrote: In the course of my work I had occasion to make a small family of iterator adaptors for escaping/unescaping ascii text, and things like that. I made the constuction interface so it could use another iterator adaptor as a "source" thereby permiting me to compose iterators in any sequence (sort of like unix pipes). If there is any interest I will post this. Please do. I, or you, could see if the marg_ostreambuf code could be modified to do what you want. Subsequently, I had the need to output unicode as UTF-8 which is char based rather than wchar_t based. I used the code in the vault by Ron Garcia. This implemented code_cvt facet to do the transformation. I should look at the Garcia code, meanwhile... It was irksome to me that that the interface for code_cvt facet was not mapable to my iterator adaptor set - or is it. Now that I have invest the effort to understand stream/streambuf/facet/local/char vs wchar_t/ charsets/etc. I wonder if one can't make a code_cvt facet that would be constructed with an arbitray iterator adaptor. I've created files/col_io/pipe.cpp with output in pipe.exe.output. It demonstrates that two marg_ostreams can be composed. The 1st one changes the margin and at some time puts "xxx" in that margin. The 2nd just puts "yyy" in the margin. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] RE: Interest in library generating streambufs fromobjects
Larry Evans wrote: [snip] I hadn't thought of the "adaptable sequence" idea, but the "composition of streambufs" idea sounds similar to the marg_ostreambuf in files/col_io. The marg_ostreambuf::CTOR takes a streambuf and its member functions forward to that after doing some processing via the marg_buffer_put superclass. Maybe marg_buffer_put is a "sort-of" "adaptable sequence". Anyway, it might give you some ideas. Maybe a modification to double_streambuf or bi_directional_streambuf could be used simlar to pipes in unix. Another template parameter, e.g. one named "Xform", would contain the code to do any transformations on the characters. For example, if Xform=marg_buffer_put, then this would create marg_ostreambuf. This could be the input stream to another such buffer, thus forming the next link in the pipe of streambufs. Does this make sense? ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] RE: Interest in library generating streambufs fromobjects
Jonathan D. Turkanis wrote: Thanks for your interest. I have posted the library at http://groups.yahoo.com/group/boost/files/streambuf_lib/. [snip] Robert Ramey wrote: [snip] out of streambuf and a streambuf built that can use any "adaptable sequence". This is good idea! I had thought about composing streambufs to create new streambufs, and indeed this seems fairly straightforward using my approach (perhaps the most difficult part is selecting suitable names for the composition operations -- how about 'operator+' ?) I hadn't thought of the "adaptable sequence" idea, but the "composition of streambufs" idea sounds similar to the marg_ostreambuf in files/col_io. The marg_ostreambuf::CTOR takes a streambuf and its member functions forward to that after doing some processing via the marg_buffer_put superclass. Maybe marg_buffer_put is a "sort-of" "adaptable sequence". Anyway, it might give you some ideas. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] What is Double Dispatch ?
Bohdan wrote: Hi, Recently i heard something about "Double Dispatch" within FSM discussion. Sorry for bothering, but where can i find something about it ? Sources/Article ? Thanks for help. See "visitor pattern" in _Design Patterns_ by Gamma, Helm, Johnson, Vlissides. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: an XML API in boost
Reece Dunn wrote: Anthony Williams wrote: > Writing an XML parser from scratch for boost should, IMHO, have these > features: [snip] Writing a lexer/parser is a complex task. It wasn't a requirement, more a suggestion/my opinion on what a boost XML library should be like. There are four possible options: [snip] [4] Use another lexer/parser generator. This is an unknown, and again with the Boost distribution. I'd suggest pccts or antlr: http://www.antlr.org It can generate c++ code. IIRC, it has good error recovery, which is something SPIRIT is a bit weak in. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Single ownership w/weak_ptrs? (was Cyclic smartpointers)
Chuck Messenger wrote: Schoenborn, Oliver wrote: [snip] ... Strict ownership means that only one object at any given time can be the owner. This is pretty straightforward and the raw pointer example shows that there is no such thing as cyclic strict ownership that works, at least within the above definition of ownership, Which is why the strict ownership paradigm doesn't work with cyclic structures. Inherently, in the general case, cyclic structures *require* garbage collection (or to be more precise, some dynammic programming cycle-finding algorithm, whether or not you call it "garbage collection") to harvest stranded cycles of objects. Yes, as Peter Dimov suggested, you can sort of "game" the problem by dividing your structures into Vertex and Edge types, allowing for a classic strict ownership hierarchy. But that just leaves the garbage collection problem to the programmer. OTOH, http://groups.google.com/groups?dq=&hl=en&lr=&ie=UTF-8&oe=UTF-8&threadm=dilpugnc13c.fsf%40isolde.research.att.com&rnum=1&prev=/groups%3Fdq%3D%26hl%3Den%26lr%3D%26ie%3DUTF-8%26oe%3DUTF-8%26selm%3Ddilpugnc13c.fsf%2540isolde.research.att.com seems to support Oliver's viewpoint. I remember reading another post somewhere where someone required cycles because he was creating a graph from reading input from a file and couldn't know who owned who. However, if he's reading from a file, he must have some map from vertex_name -> vertex_node, and this map would be the sole owner. All the vertex_nodes would simply be weak_ptr's to other vertex_nodes. The above cited post was in a long thread discussing on this topic. It might be worth reading. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Cyclic pointers - a comparison of known Boost efforts
Chuck Messenger wrote: > Gregory Colvin wrote: [snip] >> There are a few attempts laying around various places in Boost, but >> I've lost track of where they all are, how they all work, and what >> their relative advantages and disadvantages are. If someone could >> pull this information together it might help to get this discussion >> out of the cycle it seems caught in ;-> [snip] > Very briefly, here's what I've found so far -- please tear it apart at > will: > [snip] > > 4. shared_cyclic_ptr - by Larry Evans. See > http://groups.yahoo.com/group/boost/files/shared_cyclic_ptr. > This one seems to be under active development right (new > version uploaded a day or two ago). Again, I haven't studied > this one yet. About the "discovery" problem, Larry writes: > "[it] works around this by using a smart ptr enumerator > function specialized for each type of container". As I > understand this, it means that shared_cyclic_ptr objects > must either be within objects owned by another shared_cyclic_ptr > (as with sp_collector), or they can be in "tagged" STL > containers, e.g.: > > template struct SpecialList : public list, >public SpecialTag { }; > > That would be a best case. Or, it might be necessary to do > something much messier, like this: > > template struct SpecialList { > // Implement wrapper for each std::list function... > private: > list list_; > }; > > Perhaps Larry can comment. As illustrated in: shared_cyclic_ptr.zip (boost/shared_cyclic_ptr/shared_cyclic_ptr.hpp) in class: scoped_cyclic_container < Container , Element , cyclic_count_gc > , public Container > > , private detail ::mk_proxiters_descriptor_static ::proxiter_record the scoped_cyclic_container does not include the STL container (the Container), instead it inherits it. This is simply to make the interface the same without having to forward all method calls. The container is "tagged" by inheritance from proxiter_record. However, it's clearer in: http://groups.yahoo.com/group/boost/files/shared_cyclic_ptr/stl_container.cpp In that file, the function of proxiter_record is done by: prox_container_allocator in: mod::vector > NOTE: One reason for this change is to see if the prox_children design pattern (that's what I started calling it) could be adapted for use with stl with as little change as possible. Hence, by just specializing the container allocator, and then changing all container code to use a prox_container_allocator ::root_pointer in place of the "root pointer" to the container, all containers would be garbage collected. Since, I assumed, each container must have some type of "root pointer" in its implementation, it should work for all stl containers. For uncollected containers, allocator::root_pointer would simply be a do-nothing pointer-wrapper around a Value*. The ONLY reason for making the root_pointer a pointer-wrapper is to enable storing: 1) a constructor for the "smart ptr enumerator function" mentioned above 2) an offset from whatever "subject" (using the GOF terminology ) contains the container. "WHOA...!" you say, "what is this 'subject"? I thought we were talking about the constructor for an stl-like container?" Well, that's where Detlef's genius appears. This "subject" is actually created during construction of a static variable (so it's constructed before the start of main). The SOLE purpose of this variable, namespace prox_children { descriptor_builder descriptor_builder ::this_descriptor ; } is to create a prox_children::prox_descriptor for Subject which precisely describes the smart pointers in Subject which contain pointers to objects to be garbage collected. This description consists of a map of maker_proxiter_abs* to offsets within subject where the proxies are located. Thus, given: Subject* a_subj offset a_offset mk_proxiter_abs* a_maker the collector can enumerate all the proxies contained in a_subj which are of a particular type, i.e. the type corresponding to the a_maker. For example, for a vector, the corresponding a_maker would produce an iterator somehow derived from vector::iterator, and for list, the a_maker would produce an iterator from list::iterator. For a scalar proxy, prox_s
Re: [boost] Re: Cyclic smart pointers (holy grail: the uber-pointer)
Gregory Colvin wrote: > On Friday, May 30, 2003, at 10:18 America/Denver, Larry Evans wrote: > [snip] >> >> http://groups.yahoo.com/group/boost/files/shared_cyclic_ptr/ >> draft-compare.zip might be a good starting point. It >> doesn't include the latest additions and still needs work :(. > > > Wow. Thanks (I guess). Since understanding some of the code was difficult, it would sure help if the authors of each of the codes would analyze their own code to check against what's already in draft-compare, or add to draft-compare, as appropriate. Also, it would most likely avoid the "jumping to conclusions" which I was guilty of when evaluating sp_collector earlier in a (this?) thread. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Cyclic smart pointers (holy grail: the uber-pointer)
Gregory Colvin wrote: On Friday, May 30, 2003, at 09:56 America/Denver, Chuck Messenger wrote: ... What I'm trying to develop (or even better, find) is a workable C++ [snip] their relative advantages and disadvantages are. If someone could pull this information together it might help to get this discussion out of the cycle it seems caught in ;-> http://groups.yahoo.com/group/boost/files/shared_cyclic_ptr/ draft-compare.zip might be a good starting point. It doesn't include the latest additions and still needs work :(. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] interest in dominator tree?
Jeffrey Hsu wrote: Is there any interest in a generic implementation of the Lengauer-Tarjan algorithm to compute the immediate dominator tree of a flow graph in almost-linear time? I'd be interested; however, I've no immediate use. I'm only interested because I'm interested in compilers and analyzing programs. I also think it would be interesting to see how you might adapt the boost graph library to do this. The spirit library could be used for a toy fortran or c like language to demo the algorithm. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] smart_ptr: sp_collector can't handle STL containersof shared_ptr's
Gregory Colvin wrote: [snip] Do you really need a precise collector? Boehm's collector works just fine. Most people don't, but some do. In Jones and Lins _Garbage Collection_ there's mention of "misidentification" or "false" pointers in applications with large compress bitmaps. Also, for highly connected structures, I remember reading that there could be a problem. If so, I don't think you can do it without compiler support. I was hoping stl_container.cpp would be as close as possible w/o compiler support. I think Detlef also mentioned this somewhere in his article. The closer it is, then the less testing would need to be done to change the compiler. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] smart_ptr: sp_collector can't handle STL containersof shared_ptr's
Gregory Colvin wrote: Check out http://www.hpl.hp.com/personal/Hans_Boehm/gc/gcinterface.html [snip] On Thursday, May 29, 2003, at 19:57 America/Denver, Larry Evans wrote: Gregory Colvin wrote: [snip] > It is not that hard to write a new(gc) and gc_allocator > using Boehm's collector, for those who don't want to have > the collector take over all memory allocation. I found John Max Skaller's posts on such a gc_allocator: http://aspn.activestate.com/ASPN/Mail/Message/boost/1150154 Since I still can't figure out how he did it, maybe he could provide code or more details on howto. However, I don't know his email. I may just download his Felix compiler and try deciphering the code. Now, how do we do something similar with a precise gc like that proposed earlier? My first thought is to use some gc_allocator as the allocator argument to each stl_container which might contain gc'ed objects. Now I thought this was where Skaller noticed a problem with the stl containers and suggested boost try a modification of stl to overcome the problem. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] smart_ptr: sp_collector can't handle STL containersof shared_ptr's
Gregory Colvin wrote: [snip] > It is not that hard to write a new(gc) and gc_allocator > using Boehm's collector, for those who don't want to have > the collector take over all memory allocation. I found John Max Skaller's posts on such a gc_allocator: http://aspn.activestate.com/ASPN/Mail/Message/boost/1150154 Since I still can't figure out how he did it, maybe he could provide code or more details on howto. However, I don't know his email. I may just download his Felix compiler and try deciphering the code. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] smart_ptr: sp_collector can't handle STL containersof shared_ptr's
Gregory Colvin wrote: [snip] It seems that rather than take the route of modifying all the standard containers one might as well just provide a special operator new(gc) and gc_allocator that can track all the memory blocks on the heap that might contain a shared_ptr. Then one can either replace global operator new with the special one, or use new(gc) or gc_allocator wherever needed. I'm assuming that the advantage of the suggested method over Boehm's collector would be the precision? I.e. no false pointers are possible? ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Cyclic smart pointers (holy grail: the uber-pointer)
Larry Evans wrote: [snip] See if the current stl_container.cpp can at least traverse your pointer graph correctly. Unfortunately, stl_container.cpp can't work with the stl because it prototypes a "slight" modification to stl to make stl easily gc'ed. If you want to work with the current stl, you'll have to do something similar to scoped_cyclic_container, i.e. derive a class from the stl container whose CTOR stores the method in the descriptor. This is on my todo list. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Cyclic smart pointers (holy grail: the uber-pointer)
Chuck Messenger wrote: Larry Evans wrote: [snip] Right. scoped_cyclic_ptr (in shared_cyclic_ptr.zip) works around this by using a smart ptr enumerator function specialized for each type of container. The specialized function is then used to access all the smart ptrs in the container (via the begin() end() iterator class). OK, I see. In fact, it seems like you don't need any special smart ptr enumerator function. All you do is: you use derived-from versions of the std containers, so you can maintain an up-to-date list of references to each one. During GC, for each such container c, "for (it = c.begin(); it != c.end(); ++it)", you treat *it as a Rangeable -- any {C} references in the range [&*it, &*it + sizeof(*it) - 1] are flagged as internal. Not quite. The scoped_cyclic_ptr was designed to work-around a limitation of Detlef's method: http://www.cs.kent.ac.uk/people/staff/rej/cgi-bin/searchbib?pattern=Detl92 This limitation was that it didn't document how than handle container classes. It only documented how scalars were handled. The adaptation in scoped_cyclic_ptr (and stl_container) is, as you mentioned, to store a pointer and offset into a prox_descriptor (see stl_container.cpp) for each type which contains a proxy (i.e. smart pointer) or a container of proxies. The pointer and offset is stored by the CTOR for either scalar proxies (prox_scalar_typed<...>) or the prox_indirect_typed forming part of any container of proxies (e.g. the test::m_vec_ptest_shared). The pointer points to an instance of maker_proxiter_abs which produces an iterator over proxies contained in a subject class (subject is term used for pointee or referent in GOF) given the start of a subject. (I know, its too complicated, but I can't think of how to simplify it. Any ideas?) Nice! Thanks. [snip] Is stl_container.cpp an experimental Boost lib? Where can I get it? It's in: http://groups.yahoo.com/group/boost/files/shared_cyclic_ptr/stl_container.cpp You'll also need the col_io library in: http://groups.yahoo.com/group/boost/files/col_io/ and then there's a simple trace_scope.hpp which I'll upload. I like your "iterate through tagged STL containers" method. The library writer (the one using the cyclic smart pointer system) has to take care to store {C} objects only in appropriately tagged containers. But they get to use any containers they want. Not too shabby. Thanks. I'd love to examine your scoped_cyclic_ptr lib -- to see if I can make use of it. Perhaps I can help you flesh out requirements, if it's close enough to what I need. Is it available for download? That's at: http://groups.yahoo.com/group/boost/files/shared_cyclic_ptr/shared_cyclic_ptr.zip It uses an earlier version of method to enumerate pointers in an object. It also demonstrates how to adapt shared_ptr for to use the method. It also shows that the enumeration method is pretty much independent of the collection method because it uses two different methods (one using Detlef's, or offset_iterator method and one using Colvin's or assign_op_switch) to implement the same gc method (Lin's local mark-scan). BTW, Lin's method suffers from quadratic behavior with nested cycles as pointed out in Bacon's paper (I think I made a reference to that earlier. I know I did in a post responding to one of Terekov's posts). The work-around is lazy-local mark-scan which maintains a queue of possible garbage nodes. Anyway, I had a version of this also, but it's been rm'ed from boost long ago. See if the current stl_container.cpp can at least traverse your pointer graph correctly. If it can, then it's easy to use any of the cyclic rc algorithms (i.e. lazy local mark scan, eager local mark scan, global mark scan). ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Cyclic smart pointers (holy grail: the uber-pointer)
Peter Dimov wrote: Larry Evans wrote: Chuck Messenger wrote: The basic idea is to intercept all memory allocations -- p = new X; -- saving the info with "map[p] = sizeof(X);". To find the interconnections between objects, you do this: for (map_type::iterator it = map.begin(); it != map.end(); ++it) { char *p = it->first; unsigned size = it->second; for (char *v = p; v + 4 <= p + size; v += 4) { char *q = *(reinterpret_cast(v)); if (map.count(q)) { // connection detected from object p to object q } } } This is similar to Mirek Fidler's code: http://groups.google.com/groups?q=OGC2+-+major+improvement+group:comp.lang.c%2B%2B.moderated&hl=en&lr=&ie=UTF-8&group=comp.lang.c%2B%2B.moderated&selm=3DCD36C3.4090502%40nospam_prodigy.net&rnum=1 If by "similar to" you mean "derived from" or "inspired by" (an euphemism for "plagiarized" or "borrowed" which is itself an e. f. "stolen") then no, it is not "similar". sp_collector.cpp is written entirely from scratch. It I very much apologize for the possible implication made by my poor choice of words. is not even derived from or inspired by (no quotes) Greg's cyclic_ptr although of course as the implemented algorithm is basically the same there are obvious similarities. FWIW, it is not similar (no quotes) to Mirek Fidler's code, either. I just checked. By similarity, I was referring to the fact that each allocated object had it's size stored somewhere (it->second in the above) and that the memory was scanned in each object to see if it contained another pointer ( or a word that could be interpreted as pointer. e.g. in sp_collector this, I believe, the: reinterpret_cast(p) in scan_and_count). Fidler also used a similar method to cylic_ptr's (and Christopher's "global rc mark-scan") to determine roots by finding all objects pointed to by root pointers (by subtracting the count due to pointers from the heap). This is again, similar to sp_collector as you noted above. Of course this is again based on an incomplete understanding of sp_collector. After a closer look, I didn't notice any comment about finding roots, as with Fidler's method. This make quess that sp_collector avoided actually decrementing the reference counts, as in Christopher's and cyclic_ptr) and only stored the count's in a map (the map2_type). Then, during the heap scan, a check was made to see if the reference count was == that in the map2_type, and if so, then the object was garbage (since map2_type contains internal counts). OK, now I'm realizing I need to spend more time understanding sp_collector. Maybe you could clarify. Maybe Fidler could make any corrections of my understanding of his code too. I in no way meant to imply anything negative. I apologize for any ambiguity. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Cyclic smart pointers (holy grail: the uber-pointer)
Chuck Messenger wrote: [snip] Does the Boehm collector likewise do a full scan of the heap? I assume so... Yes. From p. 28 of _Garbage Collection_, 1996 ( http://www.cs.kent.ac.uk/people/staff/rej/gcbook/gcbook.html ) "all cells are examined by the sweep" However, this is theory. In actual implementation, there's workarounds. (See next comment). One big problem with this approach is that you end up having to scan all of your memory. This could (and for me, would) be an outrageous proposition, as only a tiny portion of memory relates to my object set. Most of it will be raw data (e.g. images, etc). You can specify which cells to scan by specifying it's "kind" during allocation ( http://www.hpl.hp.com/personal/Hans_Boehm/gc/gcdescr.html ) thus there's no need to scan the whole heap. cyclic_ptr doesn't really scan the whole heap, only those "cells" allocated by the cyclic_ptr allocator. [snip] Interesting -- thanks! I'll give it a look... However, I thought about deriving from an STL container, and rejected it. The reason is that you don't know how the STL container allocates memory. In order to maintain the system's invariants, it is necessary that all "internal" C objects be contained physically within the bounds of an I:C object, which all derive from some common base class -- Rangeable, say. The Rangeable 'structors add/remove 'this' to map_impl[]. OK, so we make our own map which is-a std::map and is-a Rangeable (multiple inheritance). So far so good. But what happens when std::map allocates memory internally? We need those internal nodes to also be Rangeable, or the system won't work. Right? Right. scoped_cyclic_ptr (in shared_cyclic_ptr.zip) works around this by using a smart ptr enumerator function specialized for each type of container. The specialized function is then used to access all the smart ptrs in the container (via the begin() end() iterator class). Thus, there's only the for the collector to know the start of the container, not the start of each element of the container, which can be derived from the smart ptr enumerator function. (The stl_container.cpp should provide another example of this). The I:C pointers you're referring to I think correspond to the prox_policied and the prox_indirect classes in stl_container.cpp. I suppose we could supply our own allocator to std::map -- hmmm John Skaller suggested a similar solution, but said it wasn't workable with current stl design: ( http://aspn.activestate.com/ASPN/Mail/Message/1149745 ) [snip] ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Cyclic smart pointers (holy grail: the uber-pointer)
Chuck Messenger wrote: [snip] collections, put them in object heirarchies, etc). This freedom should ideally apply both internally (within library L code) and most importantly, externally (in the code of users of library L). Crucially, Would you require the users to use a smart pointer instead of a raw? If not, then you're only option, that I can tell, is use a conservative collector like Boehm's. {C} is recursive -- circular references are normal, in particular externally (which we can't control). I want to ensure the destruction of any {C} objects which are not ultimately reachable externally. Periodically invoking a garbage-collector is fine. - boost/libs/smart_ptr/src/sp_collector.cpp: There is no sample program to compile/run, so I have to guess somewhat at how to use this one. The basic idea is to intercept all memory allocations -- p = new X; -- saving the info with "map[p] = sizeof(X);". To find the interconnections between objects, you do this: for (map_type::iterator it = map.begin(); it != map.end(); ++it) { char *p = it->first; unsigned size = it->second; for (char *v = p; v + 4 <= p + size; v += 4) { char *q = *(reinterpret_cast(v)); if (map.count(q)) { // connection detected from object p to object q } } } This is similar to Mirek Fidler's code: http://groups.google.com/groups?q=OGC2+-+major+improvement+group:comp.lang.c%2B%2B.moderated&hl=en&lr=&ie=UTF-8&group=comp.lang.c%2B%2B.moderated&selm=3DCD36C3.4090502%40nospam_prodigy.net&rnum=1 That is, for each known object p, you scan its allocated memory, examining each 4-byte chunk, q. If map[q] exists, then you assume q refers to an object, and therefore, that a connection exists from p to q. Given this map, you can detect stranded pools of objects (using dynamic programming, presumably, although I don't see any in sp_collector.cpp). You then run this algorithm periodically to detect & destroy stale objects. You might object that you'll sometimes mis-identify q as an object, when in fact it is just some random data. True, although tricks can be (and are, in sp_collector.cpp) used to minimize this to a vanishingly small likelihood (i.e. by marking legit pointers with a signature byte sequence). The consequence of mis-identification is that you may fail to destroy some unused objects. If this leads to nothing worse than some leaked memory, then it's not a real problem -- it will be a vanishingly small amount of memory. This is the justification for Boehm's conservative collector. http://www.hpl.hp.com/personal/Hans_Boehm/gc/ Another problem is, how do you track external references to your objects? Indeed, that's the whole goal -- to find which objects are ultimately referenced from the "outside world" (and to destroy the rest). I don't see how sp_collector.cpp does this. Sample code would be nice -- then I could quickly watch in the debugger and see. Perhaps it depends on the fact that only boost::shared_ptr's are supported, and these store their info in allocated memory. I don't know - just speculating. One big problem with this approach is that you end up having to scan all of your memory. This could (and for me, would) be an outrageous proposition, as only a tiny portion of memory relates to my object set. Most of it will be raw data (e.g. images, etc). This is what Christopher's (alias= global rc mark-scan) algorithm does. It's also what mark-sweep algorithms do, i.e. they have to mark all reachable objects, and then scan thru the whole heap sweeping the unmarked into the garbage collector. However, since this global scan is done, usually, infrequently, the time isn't that big a factor, at least compared with the updating of reference counts during each pointer copy. That's why Boehm's gc should work faster than refcounting. My own semi-uber pointer implementation (concept): [snip] Still, that's something. It would be necessary to implement your own containers for {C} objects, for use within I:C objects -- these containers would themselves be {C} objects. A very simple container you get "for free" is an array, which might be enough for some problem spaces. Note that externally, you could use regular STL containers, or anything you want. This is the solution implemented (by simply deriving from the stl container) by an earlier upload to boost...files/shared_cyclic_ptr. I've just uploaded them again in file, shared_cyclic_ptr.zip. Explanations on output of test are in iplimits.out. The solution for STL containers is in template scoped_cyclic_container in file shared_cyclic_ptr.hpp. [snip] --- Note: any {C} objects on the stack will be considered to be external (hence, not garbage-collected), even if they are on the stack in "internal" (i.e. library) code. That is
Re: [boost] Re: smart_ptr suggestion: Support decrementingshared_ptr'scount,forself-references
Chuck Messenger wrote: Peter Dimov wrote: Chuck Messenger wrote: [snip] Well, it's in too much flux right now -- perhaps if I ever finish it, I'll post it. It's a concurrency library - an implementation of the API described in Concurrent Programming in ML. [snip] Thanks -- that sounds interesting, too -- I've also been told of cyclic_ptr, in the contributions. Even if one/both don't do the job, they should give me some ideas... I'm worried about the Concurrent part since I'm guessing that you'd be using threads. In that case, cyclic_ptr would have to protect it's phase variable (I think that's what it's called) with maybe a mutex. This phase variable governs the action of the smart_ptr::operator=(...). OTOH, I think (since I'm a threads novice ) that the stl_container.cpp I mentioned in previous post might be more suitable because code that calculates the "descriptors" used to traverse the proxy graph can be modified to execute before the 1st statement of main (via the construction of the static variables). However, that still leaves the need to synchronize the graph traversal during garbage collection, which could be done by a "stop-the-world" method, i.e. have a gc thread stop all other threads which the gc thread does the collection. You might also check the reference I gave to [EMAIL PROTECTED] which is more tuned to threads (actually multi-processing). The post containing that reference is at: http://aspn.activestate.com/ASPN/Mail/Message/boost/1647822 ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] smart_ptr suggestion: Support decrementing shared_ptr'scount, forself-references
Schoenborn, Oliver wrote: Circular refs are easy to avoid with smart_ptr lib but idiomatically what you are really looking for is DynObj (and maybe RRef ) in the NoPtr lib (http://noptrlib.sourceforge.net). Strict ownership is ideal for pimpl and in particular your example of circular dependency, as supported by the NoPtr lib. This sounds like the polaris' RefWrapper (similar to boost weak_ptr) and Wrapper (similar to your NoPtr) class. Wrapper's maintain sole "ownership" of the pointee; however, the owning Wrapper will not delete the pointee if there are any RefWrapper's pointing to it. However, any reference to the pointee (which now has no owner) is detected and a warning issued and the program aborted. ( http://polaris.cs.uiuc.edu/polaris/polaris_developer/node42.html#SECTION00043000 ) However, a cycle can still be formed even with single ownership. A pointee can contain a Wrapper which points to itself. I think polaris had the problem, but it was very rare. I mentioned this feature one time on gclist or maybe c++.moderated and someone said it would take a lot of time to detect dangling pointer references. I had to say yes, but maybe it was worth it. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: smart_ptr suggestion: Support decrementingshared_ptr'scount,forself-references
Chuck Messenger wrote: [snip[ Thanks -- it looks very interesting. I did some googling, to see what its status is. Seems it hasn't been mentioned much since the flurry of activity in Jan-May 2001. Pity, since if it works "as advertised", it seems pretty useful. I implemented Lin's local mark-scan and placed it in shared_cyclic_ptr together with a comparison with Colvin's method of traversing the pointer graph. Colvin's was faster; however, Colvin's method of traversing the graph had problems. These were described in an iplimits.txt file which had been in files/shared_cyclic_ptr; however, it didn't generate much interest. Consequently I just removed it a few days ago. I'm currently working on stl_container.cpp which should be much easier to work with. It just implements a method to travers the pointer graph. With that, any gc method can be used with precise traversal of the pointer graph. It should be simple to code the Lin's algorithm or a Christopher's without much problem. I'd appreciate any feedback on stl_container.cpp :) ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: smart_ptr suggestion: Support decrementingshared_ptr'scount,forself-references
Chuck Messenger wrote: [snip] In general, the abstraction is: you have a group of intra-referential objects. When any of the group is constructed, they are all constructed (so that the master count is temporarily > 1), and the master count is reset to 1. When the master count goes to 0, the group is destructed. Hence, the group only remains alive as long as there are any external references (and as long as the intra-group references remain static). Could a standard smart pointer be designed to encapsulate this abstraction? Hmmm Just FYI, this "abstraction" is the basic idea behind recoverying cycles in: http://www.cs.kent.ac.uk/people/staff/rej/cgi-bin/searchbib?pattern=Cyclic+reference+counting+with+lazy+mark-scan. Chrisopher's altorithm: http://www.cs.kent.ac.uk/people/staff/rej/cgi-bin/searchbib?pattern=Christopher+Reference+count+garbage+collection is basically the same, except the "group" is the whole heap. Christopher's is the basis of Colvin's cyclic_ptr: http://groups.yahoo.com/group/boost/files/smart_pointers/cyclic_ptr/ ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: shared_ptr/weak_ptr and thread-safety
Alexander Terekhov wrote: < 2 x Forward Inline > [snip] There's no COW semantics here. It's rather simple, really. Any operation that "updates" the use-count needs to be synchronized with respect to other readers/writers. The basic thread safety is pretty much the same stuff as POSIX's memory synchronization rules stated in 4.10/Base Definitions volume. Note that things like semas and pthread_refcount_t provide STRONG thread-safety (for themselves; from "OO" point of view, if you look at their interface); well, with some "exceptions"... please take a look at pthread_refcount_setvalue(). I'm a newbie, so this might seem a simple question: Wouldn't weighted reference counts eliminate around half the synchronization. This is because, AFAICT, the only time synchronization is needed is when a smart weighted pointer releases it's pointee, but not when it acquires a new pointee (because the reference count is gotten from the other, or source, smart weighted pointer). ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] indentation algorithm for stream objects
Reece Dunn wrote: Larry Evans wrote: [snip] There are two possible ways I see at simplifying your marg_ostream: [1] Overload string operations only since you only really need to intercept '\n' characters - this appears to be the simpler of the two solutions (as there is no real need to overload for integer types, only strings and characters). [2] Write a stream buffer that intercepts the '\n' characters - this seems overly complicated and a little overkill. Agreed. I had to work at it IIRC. NOTE: I have not yet looked at the code for marg_ostream so I cannot give any more detailed comments on it at the moment. Thanks. I'll think some more about it, when I get some time. One of the reasons I chose not to have the '\n' character trigger the code to perform the indentation is that you could have code like: out.indent() << "This is a test" << '\n'; out.beginIndent(); out.indent() << "Indented" << '\n'; out.endIndent(); out.indent() << "End of test" << '\n'; It makes sense to have the new lines at the end of the output. If, however, the '\n' character triggered the indentation, you would need something like: [snip] which is less intuitive and can lead to mistakes if you are not careful. The reason for this is that the indentation will be done at the wrong time and lead to incorrect alignment of the string "Indented". I disagree. The following (almost) line by line translation of your example to marg_ostream: ; marg_ostream mout(cout) ; unsigned i=0 ; mout << "This is a test" < produces: This is a test0 Indented End of test [snip] Another indentor advantage is there's no need to define operator<< for all the primitive types as was done in marg_ostream. That is due to the aim at keeping indentor's design as simple as possible, while giving it as much flexability as possible. Redefining the operator<< would have severly complicated the design. That's why I like your way; however, in the back of my mind, there's a feeling I started out that way (this was done years ago) and for some reason, after running some tests, found it better to do it this other way. I think the problem was I didn't always know when the beginning-of-line occured; hence, I needed the marg_ostream to keep track of this. I can't remember specifics yet. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: indentation algorithm for stream objects
Larry Evans wrote: Jason House wrote: [snip] use make files and perl scripts. I'll post them in another files directory, probably col_io. The test is is files/col_io/col_io.zip. The file: libs/col_io/tests/marg_ostream/generated.mk is a simplified makefile produced with help of save_genmk and zip targets in the toplevel Makefile. Directions are at top of generated.mk. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: indentation algorithm for stream objects
Jason House wrote: Larry Evans wrote: Reece Dunn wrote: Here is the associated code and example program. Wouldn't the following: *this< do essentially what indentor< OutputFileType >::indent() does? I have not read indentor's code, so I'll only comment about the example replacement code. My complaint is basically the same as my complaint about io_manip. The example code looks like it discards the old fill character in favor of a new one... and never sets it back. I'll continue to hope that an official implementation would not do such things. My mistake. The second call to setfill should have used the original fill character, whatever that was. This implementation also requires the user to know when the beginning of line occurs. That does sound pretty reasonable, and I'm kinda wondering why I didn't do it in marg_ostream; however, marg_ostream doesn't require this, and I'm wondering whether other people think this feature is worth the extra complexity in marg_ostream. Another indentor implementation is there's no need to defind operator<< or all the primitive types as was done in marg_ostream. I'll have to check that out, since I have no clue what it does already... But where can I find it? Searching boost... "Your search - marg_ostream - did not match any documents." The location was "indirectly" mentioned in a previous post (on 3/31) to this thread. It's part of: shared_cyclic_ptr.zip in the files/shared_cyclic_ptr directory. I've got a number of tests; however, instead of boost/build, they use make files and perl scripts. I'll post them in another files directory, probably col_io. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] indentation algorithm for stream objects
Larry Evans wrote: Reece Dunn wrote: Here is the associated code and example program. [snip] marg_ostream. Another indentor implementation is there's no need The above should be "indentor advantage" to defind operator<< or all the primitive types as was done in should be "to define operator<< for..." ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] indentation algorithm for stream objects
Reece Dunn wrote: Here is the associated code and example program. Wouldn't the following: *this< do essentially what indentor< OutputFileType >::indent() does? This implementation also requires the user to know when the beginning of line occurs. That does sound pretty reasonable, and I'm kinda wondering why I didn't do it in marg_ostream; however, marg_ostream doesn't require this, and I'm wondering whether other people think this feature is worth the extra complexity in marg_ostream. Another indentor implementation is there's no need to defind operator<< or all the primitive types as was done in marg_ostream. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] indentation algorithm for stream objects
Reece Dunn wrote: This utility class provides a mechanism for adding indentation to an I/O stream. I was wondering who would be interested in it, or if anyone has anything similar. This sounds like marg_ostream. See: http://aspn.activestate.com/ASPN/Mail/Message/1526216 ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] GC
Kevin Cadieux wrote: I'm starting with this project so I can only give you a general description. The GC I am talking about would be omnipresent in the project and almost invisible to the user without affecting the control the programmer would have over it. It could obviously allow multiple instanciations so that the programmer can tune each of his GC's the way he wants to. That would boost up the performance in the case that a programmer would need Is it conservative? If not, how do you access the children of each vertex in the pointer graph? The multiple instantiations sounds similar to cmm (ftp://ftp.di.unipi.it/pub/project/posso/cmm ). If so, I think it's a good idea; however, I'm wondering how you'd mix, for example, rc with mark-sweep. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: GC
Philippe A. Bouchard wrote: Larry Evans wrote: Kevin Cadieux wrote: [snip] It's pretty good. "ip_assign_op_switch" is faster than "ip_offset_iterator" but must be explicit? I was afraid of that(as indicated in 6.2.2 of the .html file); however, ip_offset_iterator is more "robust" (as indicated in 6.2.3 item 2). Maybe some boost template guru's could figure a way to hack a "virtual template member function" as mentioned in item 4 of 6.1.2. An index.html would be great; an objective point of view. I'm still working on it. I thought the uml was pretty clear, but I thought I just implement it to make sure I hadn't missed anything. Sure enough, I had. I'm working on the implementation now and will modify the doc's when that's done. Thanks for the feedback. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] GC
Kevin Cadieux wrote: Would a library enabling Garbage Collecting be of any interest? Yes, but how does it compare with that in: http://groups.yahoo.com/group/boost/files/shared_cyclic_ptr/ ? In particular, see the just uploaded proxchildren-pattern.html. I couldn't upload the class and sequence diagrams referenced by that html file. I'll try later. I'm currently in midst of rewriting code; hence, it maybe better to wait, but the main advantages listed in that html file will still hold. (The file was created using docbook. Thanks to Douglas Gregor for paving the way in that area). ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Any Interest In a Raw Memory Buffer
Brian Gray wrote: A raw memory buffer is a good idea. I've rolled my own on a couple of occasions, but never tried to mimic the style of the STL. That approach opens up a couple issues: Since we don't know what's stored in the memory buffer (image/audio data, chars from an input stream, serialized structs, etc.), it would be useful to be able to parameterize the iterators to the increment size. Could this also be used to make vector implicitly convertible to vector? It seems so if everything is implemented in terms of char* and the only difference is the increment (of char) to move from one element to the next. Of course I guess this would mean the increment op would have to be virtual, but maybe not. If the iterator, as suggested above, the increment size was parameterized, this would eliminate the need for virtual increment. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: resource manager naming
Alisdair Meredith wrote: Phil Nash wrote: [snip] Final disorganised point When you think 'pointer' without a context, what concept do you associate first? Resource-manager? Or dereferencable? The very name suggests the latter to me! [Which could be why I have such a hard time with pointers-that-don't-point] Would the GOF name, proxy, be too non-specific? Policy names might provide the specifics (whether it's a pointer or a resource). ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: io operations for stl containers?
Terje Slettebø wrote: From: "Vladimir Prus" <[EMAIL PROTECTED]> Terje Slettebø wrote: [snip] std::cout << io_format("\n|","|\n","|") << io_format("---","---","---") << board << '\n'; } we get: --- |O|X|O| --- |X|X|O| --- |O|O|X| --- I've used marg_ostream to format output for containers; however, it only used something that changed the margin. I had to use an ostream<< for the particular composite to get it to work. However, being able to adjust the margin seems useful for formating most code. Looking at the code might give you some more ideas about your io_format. Unfortunately, marg_ostream requires wrapping the cout in a marg_ostream. Anyhow, the code is in boost files in shared_cyclic_ptr/shared_cyclic_ptr.zip in boost/col_io directory. Basically, marg_ostream++ increments the margin and marg_ostream-- decrements the margin. You can also specify what's in the margin. This was used to show the nesting in a fortran program in a parallelizing compiler. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Array support [was SmartPtr (Loki)-auto_ptr/movec'torissue]
Ralf W. Grosse-Kunstleve wrote: --- David Abrahams <[EMAIL PROTECTED]> wrote: [EMAIL PROTECTED] (Joerg Walter) writes: I needed something with exactly boost::shared_array's interface to add reference counting to ublas. With shared_array I'm able to run the CLAPACK test suite on ublas containers. I think Ralf Grosse-Kunstleve did something similar in scitbx (http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/cctbx/scitbx/array_family/) The type implemented in shared_plain.h (in the directory above) is a reference All I see there doesn't include shared_plain.h unless it's in a subdirectory. Is it some other place? ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Rewritten "Rationale" for shifted_ptr<>
Philippe A. Bouchard wrote: 1) I have rewritten the "Rationale" section of shifted_ptr<> in file /shifted_ptr/doc/structboost_1_1shifted__ptr.html: http://groups.yahoo.com/group/boost/files/shifted_ptr.zip In my mozilla browser, I opened this html file and did search for "ration" but got nothing. I then found it in index.html. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: Re: shifted_ptr<> w/ lock mechanism
Philippe A. Bouchard wrote: "Larry Evans" <[EMAIL PROTECTED]> wrote in message [EMAIL PROTECTED]">news:[EMAIL PROTECTED]... [...] Only if you want to collect cycles or provide some other means for accessing the arcs in the pointer graph. As a matter of fact, it may be better to do somewhat like shared_ptr does, i.e. instead of storing a ip_descriptor*, just store something like counted_base, where the actual instance is a derived class, counted_impl, which knows the "real" type, T, of the object pointed to. What about typeid(* m_ptr).name() which is also virtual and returns a real compile-time id? But that means m_ptr must point to something with a virtual function, but what I was proposing would allow m_ptr to be non-virtual. Instead, the ip_descriptor would "takeover" to purpose of the virtual dtor with no extra overhead than that required for accessing the internal pointers. Only instead of having a virtual function table pointer, there'd be the ip_descriptor* in the gc_header. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: shifted_ptr<> w/ lock mechanism
Philippe A. Bouchard wrote: [snip] > > Oh no, don't tell me GC_malloc was working this way ;) > > BTW gc_header *must* have (ip_descriptor *) ? > Only if you want to collect cycles or provide some other means for accessing the arcs in the pointer graph. As a matter of fact, it may be better to do somewhat like shared_ptr does, i.e. instead of storing a ip_descriptor*, just store something like counted_base, where the actual instance is a derived class, counted_impl, which knows the "real" type, T, of the object pointed to. Maybe just add another virtual function to descriptor_of, which does what the virtual counted_base_impl::dispose does. This would allow proper destruction without a virtual destructor. IOW, the ip_descriptor* in the gc_header substitutes for the virtual destructor. This is pretty much of the top of my head, so, take it for what it's worth. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: shifted_ptr<> w/ lock mechanism
Philippe A. Bouchard wrote: [snip] I guess it would also be possible to allocate a "shifted object" into some specific memory page, so operator delete will be able to quickly detect weither the object is shifted or not. This way it would be possible to overload the main operator new. I think this is what BW does to distinguish between pointers produced by GC_malloc_uncollectable and gc_malloc. Also, I think cmm does something similar (see ftp://ftp.di.unipi.it/pub/Papers/attardi/SPE.ps.gz ). ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] prox_descriptor feedback?
Philippe: I just wanted to let you know I am looking at your code at: http://groups.yahoo.com/group/boost/files/gc_ptr.zip However, I've not had time to understand it fully. I do like the way you've got a virtual table pointer (VTP) installed in each garbage collected object. Currently, I'm trying to document my stuff with UML and possibly some pattern-like description of all the classes; however, it's taking a long time. One reason I'm interested in the installed VTP is that it could have a slot for returning the: &boost::mem_mgmt::mk_internal_pointers_descriptor_of::the_ip_descriptor() as shown in the http://groups.yahoo.com/group/boost/files/shared_cyclic_ptr/gc.hpp As noted in the comments at the top, this was modified from code by Mirek Fidler which he posted to comp.lang.c++.moderated with: From: "Mirek Fidler" <[EMAIL PROTECTED]> Subject: OGC++: Optional Non-Conservative Garbage Collector for C++: Library solution - possible breakthrough Date: 18 Oct 2002 18:34:09 -0400 What are the gotcha's in adding a pointer to the_ip_descriptor as part of the gc_header in your gc_ptr.hpp? Mirek: The modifications shown in gc_ptr.hpp together with further modifications (i.e. the unshared_ptr) proposed in my previous boost post: Subject: Re: Shared_ptr "mini garbage collector" Date: Tue, 07 Jan 2003 19:55:58 -0600 should solve the problem mentioned by Hans Boehm and which you repeated to me in your email with: Subject: Re: my additional gc.h comments Date: Mon, 18 Nov 2002 16:42:09 +0100 To be more specific, the code in: http://groups.yahoo.com/group/boost/files/shared_cyclic_ptr/main.cpp demonstrates how uncollected and collected objects can be handled: simply use separate descriptors for different types of proxies to be scanned. The descriptor: prox_recorder::the_singleton().m_descriptor[non_collect] is for proxies (smart pointers) containing subjects that are just scanned (like those allocated with BW GC_malloc_uncollectable function) [ see http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gch.txt ] and the yes_collect would be like those created with the BW normal allocator (GC_malloc). The other type of allocator in BW is GC_malloc_atomic, which corresponds to the non_scannable type, i.e. in main.cpp the proxy with CollectPolicy = collect_scan_policy<*,non_scan> Can you see any flaws in that argument? Hans: Could the prox_descriptor somewhat like that in the above main.cpp be used in place of GC_descr [ http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gc_typedh.txt ]? Boosters: If the stl standard could be changed to allow using a proxy for the "container root pointer" (as for example, the prox_vec::m_proxies in the above main.cpp) for all stl containers, then I think maybe very little would have to change in user's code and they could specify gc containers by simply passing another template parameter or possible a different allocator type. This might avoid the reluctance to adopt the shared_array as described in: http://aspn.activestate.com/ASPN/Mail/Message/1183330 What do booster's think? DavidHeld: I've not recieved much feedback on my past posts, and I'm guessing it's because of the lack of documentation that you mentioned in: http://aspn.activestate.com/ASPN/Mail/Message/1383272 How does a pattern description something like: Participants: descriptor_of_singleton - descriptor* descriptor for subject_start - subject_start* start of subject currently being "described" descriptor_of - sets above singleton pointers to descriptor for Subject and start of dummy Subject before constructing Subject. prox_record_scalar - IF subject_start, then records offsets from it. prox_record_container - IF subject_start, then record iterator maker for that container Of course, there'd be more details, but that's basically it. The other details about the gc algorithm (whether Christopher's or Lins or classic mark-sweep) would be left till later or just documented with references to the literature. This is because with prox_descriptor and a bridge_iterator (taking a stack of concrete virtual iterators) the method of getting the children of any node could simply be storing a pointer to it as part of the allocated memory, making it a return from a virtual function, or using the count_base* in shared_ptr to get at the actual type and then retrieve the descriptor from descriptor_of. Comments? Questions? Please let me know what I should do to get more feedback. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Policy-based smart pointers revisisted (was:Re:Preliminarysubmission:command line & config file library)
David B. Held on Sat, 18 Jan 2003 05:07:00 -0600 wrote: > "Edward Diener" <[EMAIL PROTECTED]> wrote in message > b0aro4$5gq$[EMAIL PROTECTED]">news:b0aro4$5gq$[EMAIL PROTECTED]... > >[...] > Actually, the policy_ptr<> code in the sandbox features a policy adaptor > that automagically detects specified policies, and fills in defaults, in any > order. However, it requires that the user specify policies using MPL > Lambda syntax. And that still doesn't avoid the fact that non-default > configurations may require specifying several policies. Finally, the > policy_ptr code has gotten too big for its own good, and has too many > templated c'tors that interfere with each other. Frankly, I don't > understand all the issues with it any more. I will probably try to write > tests for some more policy combinations, and then solicit help to figure > out how to make the conversion c'tors work. They seem to be the last > and biggest hurdle. I volunteer. > [...] > Dave I looked at the documentation in the sandbox: .../libs/policy_ptr/doc/header.html#class-smart_ptr and I'd like to emulate it. Would tell me what tools helped you do this? I noted that on the acknowledgments.html page you have a link with William Kempf 's name; however, when I followed it, I got: .../boost-sandbox/boost-sandbox/people/william_kempf.htm: unknown location Is there's some other url documenting William's method? ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Shared_ptr "mini garbage collector"
Larry Evans wrote: > Peter Dimov wrote: > > From: "Larry Evans" <[EMAIL PROTECTED]> [snip] > I'm pretty sure there a reference to it in some of the compare docs > or code in the files/shared_cyclic_ptr directory. I thought I'd be more help. The reference is: David L. Detlefs. "Garbage collection and runtime typing as a C++ library". In USENIX C++ Conference, Portland, Oregon, August 1992. USENIX Association. The version in shared_cyclic_ptr uses a static flag ( mk_offsets_descriptor_static::c_subject_start_val() )indicating whether or not the "internal pointers" are being calculated for a particular "subject" class. Before this flag is set, memory for an instance of this subject class is allocated ( in mk_internal_pointers_descriptor_of ::CTOR ). The start and end of this memory are also placed in static variables (Or it should be). and then placement new is used to create it. Each smart pointer (or "proxy", to use the shared_cyclic_ptr terminology) as a prox_record superclass which records the offset of the proxy from the start of the subject (available from the aforementioned c_subject_start_val()). These offsets are stored in mk_internal_pointers_descriptor_of ::m_ptr_offsets and subsequently used to find the internal pointers of a subject given the start address of that subject. The above paragraph basicly describes Detlef's method. However, there's a problem with containers, like a vector of proxies. To handle this, a function for accessing the proxies of the container (cyclic_count_ip_offset_iterator::mk_proxiter_fun_type) is stored in the ip descriptor. With scoped_cyclic_container (in shared_cyclic_ptr.hpp), this avoids problems with most stl-like containers. John Maddox enountered this problem with his felix gc. If the definitions of the stl container were modified to specialize the "root" pointer of the container (e.g. the vector::front or the head pointer in list) to be a proxy with the prox_record superclass, then this might be easily added to stl, thus easing the migration to gc for c++. > > does it require programmer > > support? > > > > Yes. It requires declaration of a single static variable for each > class that's garbage collected. It looks like this: > > ip_descriptor_of > ip_descriptor_of > ::c_mk_descriptor > ; At least in my latest incantation of my gc code. However, in the shared_cyclic_ptr directory, this appears as: boost::mk_internal_pointers_descriptor_of > >:: c_my_type ; in the iplimits.cpp file. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Shared_ptr "mini garbage collector"
Peter Dimov wrote: From: "Larry Evans" <[EMAIL PROTECTED]> [snip] This scan will also have to follow plain pointers. Plain pointers would have to be followed by a real collector, but why should a "simple cycle-breaker" bother? The iplimits.txt file in the shared_cyclic_ptr files directory also illustrates why raw pointers need to be followed. Search for: 2)"pointer cycle with raw cut" - This also hints at what was lacking in Detlef's article: an explanation of how to handle containers of smart pointers. This is handled by the shared_cyclic_container template defined in shared_cyclic_ptr.hpp. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Shared_ptr "mini garbage collector"
Peter Dimov wrote: > From: "Larry Evans" <[EMAIL PROTECTED]> [snip] >>Why not use the Delef approach as demonstrated in shared_cyclic_ptr to > > avoid > >>false positives altogether? > > > I'm not familiar with Detlef's approach... I'm pretty sure there a reference to it in some of the compare docs or code in the files/shared_cyclic_ptr directory. > does it require programmer > support? > Yes. It requires declaration of a single static variable for each class that's garbage collected. It looks like this: ip_descriptor_of ip_descriptor_of ::c_mk_descriptor ; The c_mk_descriptor default CTOR creates a descriptor for test_subj. This descriptor is accessed with: bridge_stk_proxiterator::ip_descriptor const& subj_desc = ip_descriptor_of::the_descriptor() The iterator over smart pointers contained within an object of type, test_subj, is created as follows: test_subj a_subj; bridge_stk_proxiterator subj_proxiter(subj_desc, &a_subj); subj_proxiter iterates over all the shared_cyclic_ptr's and (hopefully in the near future) all the unshared_cyclic_ptrs contained within a_subj. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Shared_ptr "mini garbage collector"
Peter Dimov wrote: From: "Larry Evans" <[EMAIL PROTECTED]> [snip] This doesn't look correct to me... did you mean something like struct X { Y * p; explicit X(Y * p): p(p) {} ~X() { delete p; } }; struct Y { shared_ptr p; }; int main() { Y * py = new Y; shared_ptr px(new X(py)); py->p = px; px.reset(); } ? Yes. I had thought about the need to delete the Y* in the X::DTOR, but that was days ago and I forgot to include it. I also thought a little more about it and what I was suggesting was more like: struc Y; struct X { boost::unshared_cyclic_ptr y; //cyclic involves this arc. explicit X(void): y(new Y) {} }; struct Y { boost::shared_cyclic_ptr x; }; Where {unshared|shared}_cyclic_ptr use the detlef method to record their offsets and hence enable tracing the pointer graph. Then I'd imagine you'd ask, why not just use a shared_ptr instead of bothering with unshared. The only answer I can think of is that maybe that reflects better the meaning of the variable y. The programmer knows it's never shared; so, he decides to be explicit about it with unshared_ptr. If he had used shared_ptr, then someone maintaining his code would have to wonder who else is sharing this Y? Also, the overhead for unshared_ptr would be at least a little less than shared_ptr (no reference count or mark bit and no updating the reference count). ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Shared_ptr "mini garbage collector"
Peter Dimov wrote: From: "Larry Evans" <[EMAIL PROTECTED]> 1. Find the two X objects (let's call them x1 and x2) on the heap, and scan Wouldn't this scan have to be either conservative, like BW, or use some way to determine the precise location of the shared_ptr's within, .e.g. p1->get()? Currently I use a conservative scan that assumes that shared_ptr instances have a layout of T * px; counted_base * pi; int id; with pointers being aligned on a DWORD boundary. 'pi' must be in the count map, and 'id' must be detail::shared_count::id. (It's possible to test 'px' for validity too.) False positives should be extremely rare, but could not be ruled out entirely, and hence, breaking cycles may potentially corrupt the object. Would false positives be any less frequent than in the BW conservative collector? Why not use the Delef approach as demonstrated in shared_cyclic_ptr to avoid false positives altogether? This scan will also have to follow plain pointers. Plain pointers would have to be followed by a real collector, but why should a "simple cycle-breaker" bother? Because the following would require it in order to find the cycle: struc Y; struct X { Y* y; //cyclic involves this arc. }; struct Y { boost::shared_ptr x; }; int main() { boost::shared_ptr p1(new X); boost::shared_ptr p2(new X); p1->y.x = p2; p2->y.x = p1; } ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Shared_ptr "mini garbage collector"
Peter Dimov wrote: From: "William E. Kempf" <[EMAIL PROTECTED]> I don't follow this. How does the user prevent the destructors from referencing the other object(s) participating in the cycle which may no longer exist? The only safe way to break the cycle is to have intimate knowledge about the objects participating in the cycle and do what ever clean up is required in a determistic manner *before* the object's are destroyed and the memory is freed. (please use line wrapping) Consider the original example: struct X { boost::shared_ptr p; }; int main() { boost::shared_ptr p1(new X); boost::shared_ptr p2(new X); p1->p = p2; p2->p = p1; p1.reset(); p2.reset(); break_cycles(); } Here is what break_cycles would do: An alternative is to modify the cyclic_count_gc_local_mark_scan.hpp file I uploaded to the shared_cyclic_ptr directory on about 9/21/02. This modifcation would not only restore the refcounts for the live object but also, or almost also, for the dead ones. Whenever the restoration encounters a cycle (it could keep track via some mark on the object indicating it was earlier visted on the stack) it would zero the pointer and not add the 1, thus breaking the cycle. Then it would delete the original arg to local_mark_scan (since if any objects are deleted, this one has to be one of them), and everything would work fine. That is, everything work work fine except you wouldn't know which node in the cycle is the first one to be an argument to local_mark_scan. I haven't tested any of this, but so far I can't see a flaw (except for the uncertainty about the which is the first delete in the cycle). 1. Find the two X objects (let's call them x1 and x2) on the heap, and scan Wouldn't this scan have to be either conservative, like BW, or use some way to determine the precise location of the shared_ptr's within, .e.g. p1->get()? This some way could be, for example, that used in the shared_cyclic_ptr directory. This scan will also have to follow plain pointers. In order to do that precisely using smart pointers and the method in shared_cyclic_ptr, you'd have to use another type of smart pointer, e.g. scoped_uncollected_ptr, which only records its offset in the containing subject, like shared_cyclic_ptr does in the files/shared_cyclic_ptr directory. I'm working on this now. I could post it, but it's incomplete. I could use some feedback though. It's uses a "bridge_iterator" instead of the function stack, cyclic_count_ip_base::graph_traverser_base::m_visit_parent_stk in cyclic_count_ip_base.hpp. Because of this, it should be easier to understand. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Review Request: I/O Manipulators and Adaptors
Daryle Walker wrote: Could we arrange a review of the I/O stuff I currently have in the sandbox? The files are: boost/io/array_stream.hpp boost/io/iomanip.hpp boost/io/streambuf_wrapping.hpp I haven't looked at this code closely, but maybe it can be used instead of the col_io code in http://groups.yahoo.com/group/boost/files/shared_cyclic_ptr/ shared_cyclic_ptr.zip. I'd like to see if it could be used. It might be a good test to see how useful boost/io is. If I have time, I'll try, but maybe you could see if col_io can be modified to use boost/io streambuf_wrapping. col_io simply move's the margin left or right a given amount. This is useful for indenting code or output. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Boost Reference documentation XML/XSLT prototype help
Douglas Gregor wrote: On Tuesday 05 November 2002 01:52 pm, Larry Evans wrote: [snip] I grabbed the stylesheets from http://sourceforge.net/project/showfiles.php?group_id=21935 You'll also need to have an XSLT processor available. I suggest xsltproc (part of libxslt, from the GNOME project), I tried to find a download from http://xmlsoft.org/XSLT/xsltproc2.html without success. I finally got it from: ftp://rpmfind.net/linux/Mandrake/9.0/i586/Mandrake/RPMS/libxslt-proc-1.0.19-4mdk.i586.rpm If you run into more problems, just ask. I think I found a typo. In the examples/Makefile, there's function.docbook in the commands for target, docbook-function; yet, this is not present or created anywhere. I changed this to function_ref.docbook and this worked. Thanks for paving the way. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost