
Hello All, I know that my idea is trivial but this thing is missing in Boost. In some cases it is useful to have copy-on-write objects. For example, everybody knows that returning std::string from a function is not very efficient (actually that's why in Qt strings are implemented as copy-on-write ones). Consider following code: copy_on_write< std::string > concatenate( const std::string &first, const std::string &second ) { copy_on_write< std::string > result; result->assign( first ); result->append( second ); return result; } // somewhere else std::cout << *concatenate( "Hello,", " world!" ) << std::endl; Here no string copy occurs. One can invent a lot of different applications of copy-on-write techinque (strings, iterators, memory pages). I have an implementation, now let community decide if this can be a part of Boost. Sincerely yours, Maksym Motornyy.

On 5/31/05, Maksym Motornyy <mmotorny@yandex.ru> wrote:
I know that my idea is trivial but this thing is missing in Boost. In some cases it is useful to have copy-on-write objects. For example, everybody knows that returning std::string from a function is not very efficient (actually that's why in Qt strings are implemented as copy-on-write ones).
There's a pretty nice implementation of COW objects in the Adobe Open Source library (http://opensource.adobe.com). You might take a look at that.
copy_on_write< std::string > concatenate( const std::string &first, const std::string &second ) { copy_on_write< std::string > result; result->assign( first ); result->append( second ); return result; }
Not that COW wouldn't be a nice tool to have in the Boost arsenel, this is not a great example of how and when to use it. A compiler that implements NRVO (Named Return Value Optimization) can return an object (essentially) by const reference without any special COW wrapper classes. Also, some C++ Standard Library implementations use a reference-counted std::string implementation, so this extra effort would be wasted. -- Caleb Epstein caleb dot epstein at gmail dot com

There's a pretty nice implementation of COW objects in the Adobe Open Source library (http://opensource.adobe.com). You might take a look at that. I saw it. Honestly, after I implemented COW myself :) Do you want to say it's no sence to double existing things?
A compiler that implements NRVO (Named Return Value Optimization) can return an object (essentially) by const reference without any special COW wrapper classes. Agree, this is not the best example for such a compiler. AFAIK VC++ doesn't implement this optimization.
Also, some C++ Standard Library implementations use a reference-counted std::string implementation, so this extra effort would be wasted. STLport and Dinkumware (I suppose most widely used) doesn't belong to that implementations. That's why personally I require COW-wrapper.

Hmm .... you know that COW implementations of strings tend not to be thread-safe, or if they are thread-safe, deadly slow? For example DinkumWare switched from a COW implementation of strings to a small string optimization in the 7.1 release of VC. We run a million-plus transactions through our system every day, and monitor every crash. We've observed two things from this change: - crashes due to accidently passing strings between threads have disappeared. - speed has not changed detectably. In fact, if anything, seems to have increased slightly. So, I'd never use a COW implementation again in a multithreaded environment - it's just simply impossible to make thread safe. "Maksym Motornyy" <mmotorny@yandex.ru> wrote in message news:d7hvcu$usf$1@sea.gmane.org...
There's a pretty nice implementation of COW objects in the Adobe Open Source library (http://opensource.adobe.com). You might take a look at that. I saw it. Honestly, after I implemented COW myself :) Do you want to say it's no sence to double existing things?
A compiler that implements NRVO (Named Return Value Optimization) can return an object (essentially) by const reference without any special COW wrapper classes. Agree, this is not the best example for such a compiler. AFAIK VC++ doesn't implement this optimization.
Also, some C++ Standard Library implementations use a reference-counted std::string implementation, so this extra effort would be wasted. STLport and Dinkumware (I suppose most widely used) doesn't belong to that implementations. That's why personally I require COW-wrapper.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

It's perfectly possible to write threadsafe fast COW containers. The trick is to separate mutatable and immutable objects. Right now I'm writing const_containers library (inspired by const_string). For example, I have two classes for strings: string_builder and const_string. string_builder (it is noncopyable, btw) is used to create strings which then are passed as refcounted const_strings: ========================================== const_string<char> doSomething() { string_builder<char> str; str+="blah-blah"+another_string; return const_string<char>(str.yield()); } string_builder str_again(doSomething().yieled()); str_again+="something"; ========================================== 'yield' method is used to transfer ownership of memory block (without any coping if block is owned exclusively). Robert Mathews wrote:
Hmm .... you know that COW implementations of strings tend not to be thread-safe, or if they are thread-safe, deadly slow?
For example DinkumWare switched from a COW implementation of strings to a small string optimization in the 7.1 release of VC. We run a million-plus transactions through our system every day, and monitor every crash. We've observed two things from this change: - crashes due to accidently passing strings between threads have disappeared. - speed has not changed detectably. In fact, if anything, seems to have increased slightly.
So, I'd never use a COW implementation again in a multithreaded environment - it's just simply impossible to make thread safe.
"Maksym Motornyy" <mmotorny@yandex.ru> wrote in message news:d7hvcu$usf$1@sea.gmane.org...
There's a pretty nice implementation of COW objects in the Adobe Open Source library (http://opensource.adobe.com). You might take a look at that. I saw it. Honestly, after I implemented COW myself :) Do you want to say it's no sence to double existing things?
A compiler that implements NRVO (Named Return Value Optimization) can return an object (essentially) by const reference without any special COW wrapper classes. Agree, this is not the best example for such a compiler. AFAIK VC++ doesn't implement this optimization.
Also, some C++ Standard Library implementations use a reference-counted std::string implementation, so this extra effort would be wasted. STLport and Dinkumware (I suppose most widely used) doesn't belong to that implementations. That's why personally I require COW-wrapper.
-- With respect, Alex Besogonov (alexy@izh.com)

At 08:27 2005-05-31, you wrote:
There's a pretty nice implementation of COW objects in the Adobe Open Source library (http://opensource.adobe.com). You might take a look at that. I saw it. Honestly, after I implemented COW myself :) Do you want to say it's no sence to double existing things?
A compiler that implements NRVO (Named Return Value Optimization) can return an object (essentially) by const reference without any special COW wrapper classes. Agree, this is not the best example for such a compiler. AFAIK VC++ doesn't implement this optimization.
Also, some C++ Standard Library implementations use a reference-counted std::string implementation, so this extra effort would be wasted. STLport and Dinkumware (I suppose most widely used) doesn't belong to that implementations. That's why personally I require COW-wrapper.
IIRC there was an article written with the title something like "Pessimization" which discussed the drawbacks to COW in a multi-threading/tasking world. It's one of the reasons that quit using that paradigm. I think you need to re-evaluate your "requirement"
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Victor A. Wagner Jr. http://rudbek.com The five most dangerous words in the English language: "There oughta be a law"

"Victor A. Wagner Jr." wrote: [...]
IIRC there was an article written with the title something like "Pessimization" which discussed the drawbacks to COW in a multi-threading/tasking world. It's one of the reasons that quit using that paradigm.
Interesting. Do you have a link? regards, alexander.

At 11:59 2005-05-31, Alexander Terekhov wrote:
"Victor A. Wagner Jr." wrote: [...]
IIRC there was an article written with the title something like "Pessimization" which discussed the drawbacks to COW in a multi-threading/tasking world. It's one of the reasons that quit using that paradigm.
Interesting. Do you have a link?
http://www.gotw.ca/publications/optimizations.htm I guess I mis-remembered the title
regards, alexander.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Victor A. Wagner Jr. http://rudbek.com The five most dangerous words in the English language: "There oughta be a law"

on 5/31/05 2:59 PM, Alexander Terekhov at terekhov@web.de wrote:
"Victor A. Wagner Jr." wrote: [...]
IIRC there was an article written with the title something like "Pessimization" which discussed the drawbacks to COW in a multi-threading/tasking world. It's one of the reasons that quit using that paradigm.
Interesting. Do you have a link?
It was an article by Herb Sutter. It is on his web site here http://www.gotw.ca/publications/optimizations.htm with a related article here http://www.gotw.ca/gotw/045.htm. Chris

Chris Little wrote: [...]
It was an article by Herb Sutter. It is on his web site here http://www.gotw.ca/publications/optimizations.htm with a related article here http://www.gotw.ca/gotw/045.htm.
Ah that. Yeah, Sutter's myths die hard. Thanks anyway. regards, alexander.

Thanks for articles. Well, I understand that multithreaded environment can be a bad place for COW optimization. But my experience shows that in single-threaded programs COW works just great. Does the feature inapplicability in one case mean that feature is useless at all?

Maksym Motornyy wrote:
Thanks for articles. Well, I understand that multithreaded environment can be a bad place for COW optimization.
That's a myth. Apart from copying elimination (small string optimization can be done in addition to COW for large strings), COW's msync is much more efficient (naked increments to begin with) than allocator's msync. Brain-dead implementations and "test harnesses" (gotw 45) don't really change the reality. regards, alexander.

That's a myth. Apart from copying elimination (small string optimization can be done in addition to COW for large strings), COW's msync is much more efficient (naked increments to begin with) than allocator's msync. Brain-dead implementations and "test harnesses" (gotw 45) don't really change the reality.
I have a little experience with multithreaded programming. All the more isn't COW deserve to be part of Boost? (I don't insist however :))

Alexander Terekhov wrote:
Maksym Motornyy wrote:
Thanks for articles. Well, I understand that multithreaded environment can be a bad place for COW optimization.
That's a myth.
It depends on the interface of the class. Returning pointers and references into the object is bad, as is const/non-const overloading where the non-const version can be used for read access. Non-const member functions of the begin()/end() variety are worse than just returning a single reference into the object, because you can't "copy on write" between the two, or they'll get out of sync. Reference-counting immutable objects is fine, but COW can be a pain.

Peter Dimov wrote:
Alexander Terekhov wrote:
Maksym Motornyy wrote:
Thanks for articles. Well, I understand that multithreaded environment can be a bad place for COW optimization.
That's a myth.
It depends on the interface of the class. Returning pointers and references into the object is bad, as is const/non-const overloading where the non-const version can be used for read access.
Use const reference/const_cast<> for read access (and non-const object) to avoid unwanted mutations.
Non-const member functions of the begin()/end() variety are worse than just returning a single reference into the object, because you can't "copy on write" between the two, or they'll get out of sync.
Yeah, simply put, mutations of std::string object may invalidate references and iterators (with COW inspired semantics for non- const operator[]() et al. )... threads or no threads, COW or no COW.
Reference-counting immutable objects is fine, but COW can be a pain.
Only in wrong hands. ;-) regards, alexander.

Alexander Terekhov wrote:
Yeah, simply put, mutations of std::string object may invalidate references and iterators (with COW inspired semantics for non- const operator[]() et al. )... threads or no threads, COW or no COW.
Umm, not exactly. int x = s[0]; (with non-const s) does not invalidate if COW isn't used, and two such "reads" are MT safe. COW is visible in the presence of such functions. It's still usable, but it isn't transparent.

Peter Dimov wrote:
Alexander Terekhov wrote:
Yeah, simply put, mutations of std::string object may invalidate references and iterators (with COW inspired semantics for non- const operator[]() et al. )... threads or no threads, COW or no COW.
Umm, not exactly.
int x = s[0];
(with non-const s) does not invalidate if COW isn't used,
Uhmm, that's not what the standard says. Well, apart from http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#263 http://groups-beta.google.com/group/comp.lang.c++.moderated/msg/1fc8476dbadf... I suggest you simply read between the lines of "These rules are formulated to allow, but not require, a reference counted implemenation. A reference counted implementation must have the same semantics as a non-reference counted implementation" note having efficient COW implementation in your mind. (Among other things I mean invalidation on refcount > 1 with refcount == 0 representing unshareable state.) ;-) regards, alexander.

Alexander Terekhov wrote:
Peter Dimov wrote:
Alexander Terekhov wrote:
Yeah, simply put, mutations of std::string object may invalidate references and iterators (with COW inspired semantics for non- const operator[]() et al. )... threads or no threads, COW or no COW.
Umm, not exactly.
int x = s[0];
(with non-const s) does not invalidate if COW isn't used,
Uhmm, that's not what the standard says.
I know what the standard says. ;-) It's still true. An uncounted string, a vector<> and an ordinary array do not invalidate and do not "write" when the above is used. COW is visible because it changes the semantics of a "non-const read". My point was that a COW-friendly class should have had class cow_friendly_string { public: char get( int i ) const; void set( int i, char ch ); }; sidestepping the above problem.

Peter Dimov wrote: [... regarding (busted) 21.3/5 ...]
My point was that a COW-friendly class should have had
class cow_friendly_string { public:
char get( int i ) const; void set( int i, char ch ); };
sidestepping the above problem.
I take it that you'd like to sorta castrate "cow_unfriendly_string" (the standard one) to make it more user (read: looser) friendly. ;-) It can be done using private std::string. Oder? regards, alexander.

Alexander Terekhov wrote:
Peter Dimov wrote:
[... regarding (busted) 21.3/5 ...]
My point was that a COW-friendly class should have had
class cow_friendly_string { public:
char get( int i ) const; void set( int i, char ch ); };
sidestepping the above problem.
I take it that you'd like to sorta castrate "cow_unfriendly_string" (the standard one) to make it more user (read: looser) friendly. ;-)
No, I was just saying that some interfaces are more COW-friendly than others, that's all. Designing a good std::string is hard and not on my list of issues at the moment. ;-)

Wow! Really cognitive discussion :) But wait a moment, can someone tell me is COW worth to be a part of Boost or not?

Maksym Motornyy wrote:
Wow! Really cognitive discussion :) But wait a moment, can someone tell me is COW worth to be a part of Boost or not?
Interface considerations to make COW'd stuff like containers and strings somewhat less surprising (to uninformed) aside for a moment, with respect to threading it all boils down to having efficient COW_refcount<size_t, thread_safety::basic>, so to speak. < Forward Inline > Subject: Re: Quetions about Mac OS X synchronization primitives On Apr 10, 2005 5:38 PM, Alexander Terekhov wrote:
"Peter Dimov" schrieb am 09.04.05 12:15:25:
Philip Koch wrote:
On Apr 8, 2005, at 3:31 AM, Peter Dimov wrote:
It would be nice if we could do that and achieve a near-optimal implementation. At the moment we need
- an increment without a barrier
OSAtomicIncreement32
- an increment when the old value is nonzero without a barrier - a decrement that is a release when the new value is nonzero and an acquire when the new value is zero
Send me a more precise description of what you need, and we'll consider putting them in a future release. If as you say they will be needed by c++, we'll probably need to.
Consider putting a bunch of additional decrements tailored for immutable shared_ptr<>-managed client objects and mad std::string cows (I mean COW with "unsharing" on nonconst operator[] and alike).
SInt32 OSAtomicIncrementIfNonzero32( SInt32 * address );
Atomically increments *address if its old value is nonzero. Returns the old value of *address.
SInt32 OSAtomicDecrementRelAcq32( SInt32 * address );
Atomically decrements *address.
If the new value of *address is nonzero, has release memory synchronization semantics.
Otherwise (when the new value of *address is zero), has acquire memory synchronization semantics.
Returns the old value of *address.
(or they could also return the new value; it doesn't matter.)
SInt32 OSAtomicDecrementWeakRelAcq32()
As above, but optimized for "old value == 1" case and allowed to drop zero store.
SInt32 OSAtomicDecrementSlbHsb32( SInt32 * address ); Same as OSAtomicDecrementRelAcq32() above, but it doesn't put a barrier on sinking stores (puts a barrier on sinking loads only) when the new value of *address is nonzero, and, in the case of zero new value, it doesn't put a barrier on hoisting loads (puts a barrier on hoisting stores only). You can probably drop trailing isync for it (IIRC Power doesn't hoist stores above control conditions). As for mad std::string cows... hmm, I need more time. Quick shot is that it needs something along the lines of OSAtomicDecrementWeakUnbiasedSlbHsb32() and OSAtomicDecrementIfGreaterThanOneSlbHsb32() with checking and no msync for zero ("unsharable" indicator").
Plus OSAtomicFetch32() and OSAtomicStore32() (naked ones) in order to remove dependency on C/C++ volatiles.
And OSNonatomicStore32() to properly label exclusive noncompeting store of "unsharable" (zero) indication for mad std::string cows. BTW, I don't know exactly what SInt32 means, but for refcounting, an opaque (so that it can be a structure or whatever providing proper isolation -- alignment and padding if needed) SAtomicUnsignedCount32 with corresponding INIT macro would do better. Almost as good as refcount<size_t, thread_safety::basic>... ;-) regards, alexander.

Hi, between the lines of the "copy on write" thread I found to read the statement: "There are threads in a program, so everything has to thread-safe." I believe this is not exactly true. In fact, the need for "wild & freestyle" shared read/write access most often indicates poor software design. Another closely related statement is something like: "Dynamic memory allocation always needs synchronization." Not necessarily. Not unless memory management is done globally. I know, the language isn't very supportive in this field. But it brings me to a question which has been on my mind for quite some time and I never found the time to ask: "Why aren't there more Boost components to customize memory management ?" If there was a way for me to express e.g. "these objects are very likely to get reallocated with different sizes, so leave some space" for a string buffer pool or "give me a custom heap allocator" for for thread specific data, it would increase my willingness to do so and a few seconds of typing for a significant ammount of performance is generally a good deal. The downside is, that it is unlikely to be possible to find an error-proof design (one whithout traps only detectable at runtime, that is - e.g. providing a standard allocator based on object_pool in Boost.Pool). However, I don't think requiring a debug session from a user who's ignoring advise from the documentation should stop any efforts in this direction. Anything in the pipeline (perhaps further development of Boost.Pool) ? Any others interested in this ? Am I missing something ? Volunteers ? Regards, Tobias

On 06/02/2005 12:01 PM, Tobias Schwinger wrote:
Anything in the pipeline (perhaps further development of Boost.Pool) ? Any others interested in this ? Am I missing something ? Volunteers ?
I'm wondering why the customizable memory management described here: ftp://ftp.di.unipi.it/pub/project/posso/cmm/ couldn't be adapted to boost. It allows separate heaps for different memory management schemes. It also allows precise collection if one takes the trouble to create a pointer map for each class. However, creating such a map for any field, not just smart pointer fields, is the purpose of: http://cvs.sourceforge.net/viewcvs.py/boost-sandbox/boost-sandbox/boost/fiel... so I don't see that as a big problem.

Larry Evans wrote:
On 06/02/2005 12:01 PM, Tobias Schwinger wrote:
Anything in the pipeline (perhaps further development of Boost.Pool) ? Any others interested in this ? Am I missing something ? Volunteers ?
I'm wondering why the customizable memory management described here:
ftp://ftp.di.unipi.it/pub/project/posso/cmm/
couldn't be adapted to boost.
Nice! Thanks for the link. However, the paper very much focusses on the aspect of garbage collection, which is not exactly what I was talking about and seems a bit out-dated in regard to the design discussion. The code is released under an aggressive open source license.
It allows separate heaps for different memory management schemes. It also allows precise collection if one takes the trouble to create a pointer map for each class.
Explicit lifetime management (manual or "smart") should be enough in most cases... A lame excuse because I find non-deterministic algorithms scary, perhaps ;-).
However, creating such a map for any field, not just smart pointer fields, is the purpose of:
http://cvs.sourceforge.net/viewcvs.py/boost-sandbox/boost-sandbox/boost/fiel...
so I don't see that as a big problem.
IIRC, I have looked at this code before. A brief example (maybe in form of a @code block) would be a great. Regards, Tobias

Larry Evans wrote: [snip] However, the paper very much focusses on the aspect of garbage collection, which is not exactly what I was talking about and seems a Well, I was mostly thinking of the allocation aspects. Since it was based on c++, I was guessing that it would have some useful code. I was thinking of using it's allocator to speed-up allocation and
On 06/03/2005 08:37 AM, Tobias Schwinger wrote: then enumeration of the sp_counted_base's in Dimov's: libs/smart_ptr/src/sp_collector.cpp
bit out-dated in regard to the design discussion. The code is released under an aggressive open source license. OOPS. I hadn't considered that. [snip]
However, creating such a map for any field, not just smart pointer fields, is the purpose of:
http://cvs.sourceforge.net/viewcvs.py/boost-sandbox/boost-sandbox/boost/fiel...
so I don't see that as a big problem.
IIRC, I have looked at this code before. A brief example (maybe in form of a @code block) would be a great.
Sorry, I don't know what a @code block is; however, I've just uploaded some test code to the vault in the: cppljevans/field_visitor_test/simple_record_field_traversal_test.zip That code shows two versions of a record: record<visitable_not> record<visitable_yes> the first contains fields<visitable_not,i> which are not visitable, the 2nd contains the the same fields except they're fields<visitable_yes,i>, where i=0..2. This should illustrate what's needed to make a field "visitable". Hope you're interested ;) -regards, Larry illustrate what's needed to make a field

Hello Larry, sorry for the late reply. Larry Evans wrote:
On 06/03/2005 08:37 AM, Tobias Schwinger wrote:
Larry Evans wrote:
[...] http://cvs.sourceforge.net/viewcvs.py/boost-sandbox/boost-sandbox/boost/fiel...
IIRC, I have looked at this code before. A brief example (maybe in form of a @code block) would be a great.
Sorry, I don't know what a @code block is; however, I've just uploaded some test code to the vault in the:
I meant something like: //! @code //! <brief example> //! @endcode
cppljevans/field_visitor_test/simple_record_field_traversal_test.zip
That code shows two versions of a record:
record<visitable_not> record<visitable_yes>
the first contains fields<visitable_not,i> which are not visitable, the 2nd contains the the same fields except they're fields<visitable_yes,i>, where i=0..2. This should illustrate what's needed to make a field "visitable".
Hope you're interested ;)
Downloaded it, but didn't find the time to use it, yet. It looks "potentially useful" and having an example rather than just plain code will help a lot getting into it. Thanks, Tobias

On 06/10/2005 09:47 AM, Tobias Schwinger wrote:
Hello Larry, Howdy.
sorry for the late reply. No problem.
Larry Evans wrote: [snip]
Sorry, I don't know what a @code block is; however, I've just uploaded some test code to the vault in the:
I meant something like:
//! @code //! <brief example> //! @endcode
OK. I've never seen (or don't remember) that type of comment. [snip]
Downloaded it, but didn't find the time to use it, yet.
It looks "potentially useful" and having an example rather than just plain code will help a lot getting into it.
Great! However, I think there may be a problem with some of the files in boost/mpl/aux_/preprocessed/ being able to handle enumeration values rather than numbers. For example, in: boost/mpl/aux_/preprocessed/gcc/vector_c.hpp I had to, by hand, replace each: vectorX_c< T,C0 > where X is some number=1...SomeMaxValue, with: vectorX_c< T,T(C0) > to get the program to compile when C0 is an element in an enumeration. I'll go ahead and just upload the file to the sandbox. User's should realize that for each class, RECORD, containing fields to be visited, they need to have: SELECTED_FIELDS_DESCRIPTION_OF_RECORD(RECORD) For example, in the uploaded file, this was: SELECTED_FIELDS_DESCRIPTION_OF_RECORD(record<visitable_yes>) I mention this also because it plays a role similar, AFAICT, to managed c++'s __gc keyword. I've never used managed c++; so, that's just a guess and I'd like to hear corrections from those knowing more. OTOH, containers, like stl's vector, need, instead to be wrapped in the template defined in: boost/fields_visitor/container_extern/single.hpp

On 06/10/2005 10:40 AM, Larry Evans wrote: [snip]
SELECTED_FIELDS_DESCRIPTION_OF_RECORD(record<visitable_yes>)
I mention this also because it plays a role similar, AFAICT, to managed c++'s __gc keyword. I've never used managed c++; so, that's just a
OOPS. I need to clarify that since the apparent purpose of fields_visitor is to allow accessing selected fields in a record, and managed c++'s __gc keyword flags a class as being garbage collected. Well, if the selected_fields in the record are the smart pointers, then the similarity beteen __gc and SELECTED_FIELDS_DESCRIPTION_OF_RECORD should be a bit clearer.

Larry Evans <cppljevans@cox-internet.com> wrote:
[..]
Sorry, I don't know what a @code block is; however, I've just uploaded some test code to the vault in the:
I meant something like:
//! @code //! <brief example> //! @endcode
OK. I've never seen (or don't remember) that type of comment.
I think this is JavaDoc style. AFAIK, doxygen (www.doxygen.org) also parses this.
[...]
Schobi -- SpamTrap@gmx.de is never read I'm Schobi at suespammers dot org "Coming back to where you started is not the same as never leaving" Terry Pratchett

Hendrik Schober wrote:
Larry Evans <cppljevans@cox-internet.com> wrote:
[..]
Sorry, I don't know what a @code block is; however, I've just uploaded some test code to the vault in the:
I meant something like:
//! @code //! <brief example> //! @endcode
OK. I've never seen (or don't remember) that type of comment.
I think this is JavaDoc style. AFAIK, doxygen also parses this.
Well, IIRC JavaDoc doesn't know 'code' & 'endcode'. I used the "@<cmd> - Notation" because the file we were talking about uses it. Regards, Tobias

On 06/10/2005 10:40 AM, Larry Evans wrote: [snip]
On 06/10/2005 09:47 AM, Tobias Schwinger wrote: Great! However, I think there may be a problem with some of the files in boost/mpl/aux_/preprocessed/ being able to handle enumeration values rather than numbers. For example, in:
boost/mpl/aux_/preprocessed/gcc/vector_c.hpp
I had to, by hand, replace each:
vectorX_c< T,C0 >
where X is some number=1...SomeMaxValue, with:
vectorX_c< T,T(C0) >
to get the program to compile when C0 is an element in an enumeration. I'll go ahead and just upload the file to the sandbox.
Rather than upload individual files for each subdirectory of aux_/preprocessed/, I changed the file: boost/mpl/aux/sequence_wrapper.hpp at about line 127 to what's described in: http://article.gmane.org/gmane.comp.lib.boost.devel/126075 To make the changes effective, in: libs/mpl/preprocessed do: python preprocess.py all $(BOOST_ROOT) vector_c.cpp HTH. -Regards, Larry
participants (12)
-
Alex Besogonov
-
Alexander Terekhov
-
Caleb Epstein
-
Chris Little
-
Hendrik Schober
-
Jonathan Turkanis
-
Larry Evans
-
Maksym Motornyy
-
Peter Dimov
-
Robert Mathews
-
Tobias Schwinger
-
Victor A. Wagner Jr.