[boost] Re: Small thing: yes_type and no_type made public?
"Terje Slettebø" <[EMAIL PROTECTED]> wrote in message 05ab01c2b695$2f125c70$cb6c6f50@pc">news:05ab01c2b695$2f125c70$cb6c6f50@pc... > Sure, that would be fine. I'm not that familiar with Boost.PP, though, > so I think I leave it to someone else to write that version. As quite a > bit of code uses yes_type/no_type, now, it may be a good idea to keep > them, as well, anyway, for backwards compatibility and simplicity. Using the PP lib seems like overkill to me. Dave ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] max, min, width, precision, promotion and other toys(0/1)
Gennaro Prota <[EMAIL PROTECTED]> writes: > Hi everybody, > > the attached files contain a bunch of trivial stuff related to > integral types that I need in a lot of situations. Any interest for > inclusion into boost? Here's a summary: > Didn't Daryle Walker already implement some of these in the Boost.Integer library? -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Metaprogramming: Using static const or enum?
Terje Slettebø <[EMAIL PROTECTED]> writes: >>From: "Paul Mensonides" <[EMAIL PROTECTED]> >> >> > Just my 2 cents. >> >> Make that 3 cents... >> >> In summary, enumerations are distinct types and therefore can interfere > with >> the rest of the language. Particularly, constant expressions, > overloading, >> operator overloading, template type deduction, etc.. Personally, I think >> that is a strong case *against* using enumerations. > > I agree. > > And since there are techniques for making out-of-class definitions easier > (and automatic), which may be instantiated if needed, like you showed, then > static const seems clearly best. That's not nearly so easy to take care of if the metafunction in question is something like alignment_of which could potentially have lots of values, depending on the T chosen. -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ 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
[boost] Re: Hello MPL World!
Since I was fairly recently starting with MPL, I thought I would chime in here. If MPL had to be installed and configured, then I would be more concerned with a Hello, World example. In my opinion, the point of Hello, World type programs was just to verify that your toolchain was set up properly and that you could get anything to work at all. Since MPL is just a bunch of header files, the problems you're going to run into are compiler compatability problems, and I doubt that Hello, World will really expose those. For example, when I ran into the nested template limit, my program was more involved than Hello, World.If there are other compiler switches that need to be set for "real world" MPL programs to work on various compilers, then a sample that stresses those would be useful. Compile this and you're ready to rock'n'roll kind of example. Along those lines, figuring out what headers to include and namespaces to use was troublesome. Since there's no blanket coverage available, a simple example will be of no help here. We'll have to trust to the documentation staying up to date. For motivitating "Why MPL?" and educational purposes, I think that longer examples are entirely appropriate. Not that I have a good one! Cheers- Augustus __ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Metaprogramming: Using static const or enum?
>From: "Gennaro Prota" <[EMAIL PROTECTED]> > On Wed, 8 Jan 2003 01:23:05 +0100, Terje Slettebø > <[EMAIL PROTECTED]> wrote: > > >>From: "Gennaro Prota" <[EMAIL PROTECTED]> > > >> It *may* need out-of-class definition, as you say. > > > >Actually, it's pretty clear that in this case, the out-of-class definition > >is required. > > Indeed. > > > Intel C++ 7.0, running in strict mode, certainly needs it. It > >gives a link-error without it, for the program I gave. GCC 3.2 gives a > >link-error, as well. > > > >> This could also be a boost FAQ ;-) > >> http://lists.boost.org/MailArchives/boost/msg35797.php > > > >I am well aware of the DR that allows static const in-class initialisation > >to omit having an external definition (I read that DR item, earlier _today_, > >:) as I was browsing through the list), and I've also read that posting, > >earlier, so this was nothing new to me. Don't you think I know this? :) > > Sure you do. It's just that being a little tired (it's 2.00 AM here) I > didn't read your whole post. Of course this means that I shouldn't > have replied, but my intent was to be useful, by pointing out the DR. > Sorry. No problem. :) I hope you didn't mind my posting, either. I kind of just replied the same way. :) > BTW I've seen that compilers tend to not follow the new wording > of 3.2 literally. For instance with most compilers I guess this > compiles fine thanks to the conversion to rvalue made by static_cast > > struct Test > { > static const int value=1 ; > }; > > //const int Test::value; > > void f(const int &) > { > } > > int main() > { > f( static_cast (Test::value) ); > } > > > despite the fact that the expression Test::value is, as far as I > understand the standard, potentially evaluated. I think this is more a > problem in the standard than in the compilers though, because this > behavior appears natural to me. Intel C++ accepts it, at least, and gives the following remark: remark #383: value copied to temporary, reference to temporary used f( static_cast (Test::value) ); ^ Yeah. It's not easy to see if making a copy constitutes "use" (which also happens in pass by value, of course). It seems compilers typically don't consider it "use". Regards, Terje ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Metaprogramming: Using static const or enum?
On Wed, 8 Jan 2003 01:23:05 +0100, Terje Slettebø <[EMAIL PROTECTED]> wrote: >>From: "Gennaro Prota" <[EMAIL PROTECTED]> >> It *may* need out-of-class definition, as you say. > >Actually, it's pretty clear that in this case, the out-of-class definition >is required. Indeed. > Intel C++ 7.0, running in strict mode, certainly needs it. It >gives a link-error without it, for the program I gave. GCC 3.2 gives a >link-error, as well. > >> This could also be a boost FAQ ;-) >> http://lists.boost.org/MailArchives/boost/msg35797.php > >I am well aware of the DR that allows static const in-class initialisation >to omit having an external definition (I read that DR item, earlier _today_, >:) as I was browsing through the list), and I've also read that posting, >earlier, so this was nothing new to me. Don't you think I know this? :) Sure you do. It's just that being a little tired (it's 2.00 AM here) I didn't read your whole post. Of course this means that I shouldn't have replied, but my intent was to be useful, by pointing out the DR. Sorry. BTW I've seen that compilers tend to not follow the new wording of 3.2 literally. For instance with most compilers I guess this compiles fine thanks to the conversion to rvalue made by static_cast struct Test { static const int value=1 ; }; //const int Test::value; void f(const int &) { } int main() { f( static_cast (Test::value) ); } despite the fact that the expression Test::value is, as far as I understand the standard, potentially evaluated. I think this is more a problem in the standard than in the compilers though, because this behavior appears natural to me. Genny. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Shared_ptr "mini garbage collector"
At 04:02 PM 1/7/2003, David Abrahams wrote: >... > >I can barely think of a reasonable design where GC is a big design win >;-) A Python interpreter? ___ 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"
From: "Larry Evans" <[EMAIL PROTECTED]> > > 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? BW = Boehm-Weiser? AFAIK BW false positives happen when a memory location resembles a valid heap address, and are much more likely. > 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... does it require programmer support? > > 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; > > } 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(); } ? ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Metaprogramming: Using static const or enum?
>From: "Paul Mensonides" <[EMAIL PROTECTED]> > > > Just my 2 cents. > > Make that 3 cents... > > In summary, enumerations are distinct types and therefore can interfere with > the rest of the language. Particularly, constant expressions, overloading, > operator overloading, template type deduction, etc.. Personally, I think > that is a strong case *against* using enumerations. I agree. And since there are techniques for making out-of-class definitions easier (and automatic), which may be instantiated if needed, like you showed, then static const seems clearly best. Regards, Terje ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] max, min, width, precision, promotion and other toys (1/1)
begin 644 intconst_log2.hpp M+R\@:6YT8V]NR`@("`@("`@("`@("`@("`@("`@("`@("!< M#0H@("`@("`@('-T871I8R!C;VYS="!P7!E('9A;'5E(#T@=F%L.R`@("!<#0H@("`@?2`@("`@("`@("`@ M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@ M("`@("`@("!<#0H@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@ M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("\J("HO#0H-"@T*("!- M24Y?3T9?4U!%0TE!3$E:051)3TXH8F]O;"P@("`@9F%L0T*($U!6%]/1E]34$5# M24%,25I!5$E/3BAS:6=N960@8VAA7!E7!E(B!I;B!T:&4@2!S:6=N(&%N9"!P861D:6YG(&)I=',N#0HO+PT* M=&5M<&QA=&4@/'1Y<&5N86UE(%0^#0IS=')U8W0@<')E8VES:6]N('L-"B`@ M("!S=&%T:6,@8V]N7!E M;F%M92!4/@T*2!T:&4@;&%S="!T=V\@='EP97,@87)E M('5S960@9F]R('=C:&%R7W0@;VYL>0T*+R\-"F5N=6T@<')O;6]T961?='EP M95]I9',@>R!I;G1?:60@/2`Q+"!U;G-I9VYE9%]I;G1?:60@/2`R+`T*("`@ M("`@("`@("`@("`@("`@("`@("`@(&QO;F=?:60@/2`S+"!U;G-I9VYE9%]L M;VYG7VED(#T@-`T*("`@("`@("`@("`@("`@("`@("`@("!].PT*#0HO+R!4 M7!E.R!].PT*=&5M M<&QA=&4@/#X@R!T>7!E9&5F M(&QO;F<@='EP93L@?3L-"G1E;7!L871E(#P^('-T7!E M/'5NPT* M("`@('1Y<&5D968@8VAA7!E9&5F(&-H87(@*"9T;U]L;VYG*2!;;&]N9U]I M9%T[#0H@("`@='EP961E9B!C:&%R("@F=&]?=6QO;F7!E#0H@("`@("`@ M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@('!R M;VUO=&5D7W1Y<&4[#0H-"B`@("!].PT*#0I]("\O(&YA;65S<&%C92!D971A M:6P-"@T*#0H-"G1E;7!L871E(#QT>7!E;F%M92!4/B!S=')U8W0@<')O;6]T M97-?=&\@>PT*("`@='EP961E9B!4('1Y<&4[("\O(&1E9F%U;'0@9F]R('1Y M<&5S('1H870@87)E(&YO="!S=6)J96-T('1O('!R;VUO=&EO;B`M($7!E/B![("`@("`@("!<#0H@("`@ M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@ M("`@("`@("`@("`@("`@("`@("`@("!<#0H@("`@("`@("`@("`@("`@("`@ M('!U8FQI8SH@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@ M("`@("`@("!<#0H@("`@("`@("`@("!T>7!E9&5F('!R;VUO=&5D7W1Y<&4@ M='EP93L@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("!<#0I]("`@ M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@ M("`@("`@("`@("`@("`@("`@("`@("!<#0H@("`@("`@("`@("`@("`@("`@ M("`@("`@("`@("`@("`@("`@("`@("`@("\J(&5N9"`M(&YO=&4Z(&YO('-E M;6EC;VQO;BHO#0H-"@T*#0H@4%)/34]415-?5$]?24Y47T]27U5.4TE'3D5$ M7TE.5"AC:&%R*3L-"B!04D]-3U1%4U]43U])3E1?3U)?54Y324=.141?24Y4 M*'-I9VYE9"!C:&%R*3L-"B!04D]-3U1%4U]43U])3E1?3U)?54Y324=.141? M24Y4*'5NPT*#0H@("`@('!U8FQI8SH-"B`@("`@='EP961E9B!D971A:6PZ.FED M7W1O7W1Y<&4\#0H@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@('-I M>F5O9BAD971A:6PZ.FEN=%]U:6YT7VQO;F=?;W)?=6QO;F7!E('1Y<&4[#0H-"B!].PT*#0H-"B!T96UP;&%T92`\/@T* M('-T"!O9B`B(#P\('1Y<&5I9"AT>7!E*2YN86UE*"D@/#P@ M(B`B(#P\(&UA>%]O9CQT>7!E/CHZ=F%L=64@/#P@)UQN)SL-"B`@("!S=&0Z M.F-O=70@/#P@(DUI;B!O9B`B(#P\('1Y<&5I9"AT>7!E*2YN86UE*"D@/#P@ M(B`B(#P\(&UI;E]O9CQT>7!E/CHZ=F%L=64@/#P@)UQN)SL-"B`@("!S=&0Z M.F-O=70@/#P@(E!R96-I7!E/CHZ=F%L M=64@/#P@)UQN)SL-"B`@("!S=&0Z.F-O=70@/#P@(E=I9'1H.B`B("`@(#P\ M('=I9'1H/'1Y<&4^.CIV86QU92`@("`@/#P@)UQN)SL-"B`@("!S=&0Z.F-O M=70@/#P@(DAA7!E*2YN86UE*"D@/#P-"B`@("`@("`@(B!P M7!E:60H='EP96YA;64@<')O;6]T97-?=&\\ M='EP93XZ.G1Y<&4I+FYA;64H*2`\/"`B72([#0H@("`@http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Metaprogramming: Using static const or enum?
>From: "Gennaro Prota" <[EMAIL PROTECTED]> > On Tue, 7 Jan 2003 15:35:56 +0100, Terje Slettebø > <[EMAIL PROTECTED]> wrote: > > [...] > >I like static const, as I think it conveys more succinctly what it's about, > >and the enum appears more like a hack (for compilers not handling static > >const in-class initialisation). However, if this means it may need an > >out-of-class definition, as well, perhaps this could need to be > >reconsidered? > > It *may* need out-of-class definition, as you say. Actually, it's pretty clear that in this case, the out-of-class definition is required. Intel C++ 7.0, running in strict mode, certainly needs it. It gives a link-error without it, for the program I gave. GCC 3.2 gives a link-error, as well. > This could also be a boost FAQ ;-) > http://lists.boost.org/MailArchives/boost/msg35797.php I am well aware of the DR that allows static const in-class initialisation to omit having an external definition (I read that DR item, earlier _today_, :) as I was browsing through the list), and I've also read that posting, earlier, so this was nothing new to me. Don't you think I know this? :) However, what is new here, is that the example program took the integral constant by const reference ("using the object", in standardese), which meant that it required the definition outside the class, as well. This is not the case if you use enum. DR 48 says: "The member shall still be defined in a namespace scope if it is used in the program in the manner described in 3.2 basic.def.odr . The namespace scope definition shall not contain an initializer." 3.2 (DR version): "An expression is potentially evaluated unless it appears where an integral constant expression is required (see 5.19 expr.const ), is the operand of the sizeof operator (5.3.3 expr.sizeof ), or is the operand of the typeid operator and the expression does not designate an lvalue of polymorphic class type (5.2.8 expr.typeid ). An object or non-overloaded function is used if its name appears in a potentially-evaluated expression." 5.19: "Constant expressions [...] An integral constant-expression can involve [...] In particular, except in sizeof expressions, functions, class objects, pointers, or *references* shall not be used, and assignment, increment, decrement, function-call, or comma operators shall not be used." (My emphasis) > As to deprecating BOOST_STATIC_CONSTANT, which David B. Held proposed, > I don't think it is a good idea. There is code that works well either > with static const and with the enum in its 'normal' use, but fails > miserably when used in other contexts where the type of the constant > matters. BOOST_STATIC_CONSTANT allows at least the most common uses > with broken compilers. It is true that there are issues with the type of the constant, so that it may select the base template or a wrong specialisation, if it expects bool, but gets an enum. So maybe it's best after all, to leave it as it is. Regards, Terje ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] max, min, width, precision, promotion and other toys (0/1)
Hi everybody, the attached files contain a bunch of trivial stuff related to integral types that I need in a lot of situations. Any interest for inclusion into boost? Here's a summary: 1. max_of and min_of: give the maximum and minimum value of any integral type as an integral constant expression; care is taken so that max_of::value [min_of::value] has the same type of the corresponding climits constant (CHAR_MAX, INT_MAX, etc.), i.e. the type to which an expression of type T is converted according to integral promotions. 2. promotes_to: gives the type which the integral type T promotes to 3. has_sign: simply defined as template struct has_sign { static const bool value = min_of::value < 0; }; Tells whether T is able to represent any negative value, regardless of whether the C++ standard calls it a signed integral type or not. 4. precision: gives the precision of an integral type, which is the number of bits it uses to represent values, excluding any sign and padding bits. 5. width: same as precision, but including any sign bit 6. has_padding: says whether T has padding or not. The file intconst_log2.hpp is just used for the implementation of the remaining stuff. Genny. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Metaprogramming: Using static const or enum?
- Original Message - From: "Paul Mensonides" <[EMAIL PROTECTED]> > Just my 2 cents. Make that 3 cents... In summary, enumerations are distinct types and therefore can interfere with the rest of the language. Particularly, constant expressions, overloading, operator overloading, template type deduction, etc.. Personally, I think that is a strong case *against* using enumerations. Paul Mensonides ___ 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] Re: Metaprogramming: Using static const or enum?
- Original Message - From: "Gennaro Prota" <[EMAIL PROTECTED]> [...] >I like static const, as I think it conveys more succinctly what it's about, >and the enum appears more like a hack (for compilers not handling static >const in-class initialisation). However, if this means it may need an >out-of-class definition, as well, perhaps this could need to be >reconsidered? I like the strong-typing implied by the use of static const, and therefore the overload simplication if it is ever used in such a fashion. The out-of-class definition is annoying, so I tend to do this: template struct map_integral { static const T value = V; }; template const T map_integral::value; ...and then reuse it: template struct is_ptr : map_integral { }; template struct is_ptr : map_integral { }; This removes the need to make the out-of-class definition unless more than one value is present (which can be handled similarly). It also maps each value to the same storage. So, for example, there are only two addresses necessary for boolean values. Furthermore, enumerations can have overloaded operators. Consider the case of "x + y" where both are enumerators. By default, everything is fine because you have int(x) + int(y). If a template operator+ just happens to be defined though, suddenly a bunch of "constant expressions" are no longer constant. Actually, this seems to be a bug in Comeau C++: #include #include struct A { enum type { x, y }; }; template struct B { }; template inline T operator+(T lhs, T rhs) { throw 0; } int main() try { std::cout << typeid( B ).name() << &std::endl // ^ // Comeau C++ doesn't flag this, // but I think it should. // Am I wrong here? << A::x + A::y << &std::endl; } catch (int) { std::cout << "template operator used" << &std::endl; return 0; } Better yet, if you remove the name "type" from the enumeration (ala 'enum { x, y }') you'll get a compile-time error for attempting to use an unnamed type as a template argument. Just my 2 cents. Paul Mensonides ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] [C++-sig] weird bug of addressof in MSVC 7
On Tuesday 07 January 2003 06:08 pm, David Abrahams wrote: > This compiler bug was reported on the Python/C++-sig. Probably we > should stick a const_cast in addressof just for vc7? Would you mind doing it? I don't have access to VC7 to test any changes. Doug ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Metaprogramming: Using static const or enum?
On Tue, 7 Jan 2003 15:35:56 +0100, Terje Slettebø <[EMAIL PROTECTED]> wrote: [...] >I like static const, as I think it conveys more succinctly what it's about, >and the enum appears more like a hack (for compilers not handling static >const in-class initialisation). However, if this means it may need an >out-of-class definition, as well, perhaps this could need to be >reconsidered? It *may* need out-of-class definition, as you say. This could also be a boost FAQ ;-) http://lists.boost.org/MailArchives/boost/msg35797.php As to deprecating BOOST_STATIC_CONSTANT, which David B. Held proposed, I don't think it is a good idea. There is code that works well either with static const and with the enum in its 'normal' use, but fails miserably when used in other contexts where the type of the constant matters. BOOST_STATIC_CONSTANT allows at least the most common uses with broken compilers. Genny. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] [C++-sig] weird bug of addressof in MSVC 7
This compiler bug was reported on the Python/C++-sig. Probably we should stick a const_cast in addressof just for vc7? --- Begin Message --- Hi, I stumbled upon a weird compilation error due to function 'addressof' in MSVC7. Here is my test case : class Test { public: struct Parameters { }; }; BOOST_PYTHON_MODULE( test ) { python::class_ Parameters_class("Parameters");/* this line causes the compile bug */ }; Here is what the compiler tells me : d:\Sources\mgd\include\boost\utility\addressof.hpp(28) : error C2440: 'return' : cannot convert from 'const Test::Parameters *' to 'Test::Parameters *' Conversion loses qualifiers d:\Sources\mgd\include\boost\ref.hpp(40) : see reference to function template instantiation 'Test::Parameters *boost::addressof(const T &)' being compiled with [ T=Test::Parameters ] d:\Sources\mgd\include\boost\ref.hpp(40) : while compiling class-template member function 'boost::reference_wrapper::reference_wrapper(const Test::Parameters &)' with [ T=const Test::Parameters ] d:\Sources\mgd\include\boost\python\object\make_instance.hpp(64) : see reference to class template instantiation 'boost::reference_wrapper' being compiled with [ T=const Test::Parameters ] d:\Sources\mgd\include\boost\python\object\class_wrapper.hpp(27) : see reference to class template instantiation 'boost::python::objects::make_instance' being compiled with [ T=Test::Parameters, Holder=holder ] d:\Sources\mgd\include\boost\python\object\class_wrapper.hpp(26) : while compiling class-template member function 'PyObject *boost::python::objects::class_cref_wrapper::convert(const Src &)' with [ Src=Test::Parameters, MakeInstance=boost::python::objects::make_instance ] d:\Sources\mgd\include\boost\python\class.hpp(88) : see reference to class template instantiation 'boost::python::objects::class_cref_wrapper' being compiled with [ Src=Test::Parameters, MakeInstance=boost::python::objects::make_instance ] d:\Sources\mgd\include\boost\python\class.hpp(479) : see reference to function template instantiation 'void boost::python::detail::register_copy_constructor(const boost::mpl::bool_c &,const boost::python::objects::detail::select_value_holder &,Test::Parameters *)' being compiled with [ C=true, T=Test::Parameters, Held=Test::Parameters ] c:\Program Files\Microsoft Visual Studio .NET\Vc7\include\xlocnum(80) : while compiling class-template member function 'void boost::python::class_::register_(void) const' with [ T=Test::Parameters, X1=boost::python::detail::not_specified, X2=boost::python::detail::not_specified, X3=boost::python::detail::not_specified ] c:\Program Files\Microsoft Visual Studio .NET\Vc7\include\xmemory(136) : while compiling class-template member function 'boost::python::class_::class_(const char *,const char *)' with [ T=Test::Parameters, X1=boost::python::detail::not_specified, X2=boost::python::detail::not_specified, X3=boost::python::detail::not_specified ] d:\Sources\mgd\Tests\Python\Python.cpp(232) : see reference to class template instantiation 'boost::python::class_' being compiled with [ T=Test::Parameters, X1=boost::python::detail::not_specified, X2=boost::python::detail::not_specified, X3=boost::python::detail::not_specified ] What is quite weird is that I added a '#pragma message (__FUNCSIG__)' in 'addressof' code ; and the faulty compiled function has the follwing signature: struct Test::Parameters *__cdecl boost::addressof(const struct Test::Parameters &) It seems to me that this signature should be : const struct Test::Parameters *__cdecl boost::addressof(const struct Test::Parameters &) It looks like a compiler bug to me. This only seems to happen for classes of structs contained in another class (or struct). I'm no expert in compiler bug workaround so I could not find anything interesting - but maybe am I just missing something ?! Any thoughts ? Thanks, Nicolas. ___ C++-sig mailing list [EMAIL PROTECTED] http://mail.python.org/mailman/listinfo/c++-sig --- End Message --- -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: UTF library available for review
Alberto Barbati wrote: > One can use a char traits class different from > std::char_traits, that defines a suitable state type. This is not really viable due to 27.8.1.1 paragraph 4: An instance of basic_filebuf behaves as described in lib.filebuf provided traits::pos_type is fpos. Otherwise the behavior is undefined. It would be possible to create a conversion stream buffer (which is probably a good idea anyway) which removes this requirement but even then things don't really work out: stream using a different character traits are not compatible with the normal streams. I haven't worked much with wide character and don't know how important it is to have eg. the possibility of using a wide character file stream and one of the standard wide character streams (eg. 'std::wcout') be replacable. I think it is crucial that the library supports 'std::mbstate_t' although this will require platform specific stuff. It should be factored out and documented such that porting to new platform consists basically of looking up how 'std::mbstate_t' is defined. > I forgot to say in my previous post that this version of the library > only supports platforms where type char is exactly 8 bits. This > assumption is required because I have to work at the octet level while > reading from/writing to a stream. I don't see why this would be required, however. This would only be necessary if you try to cast a sequence of 'char's into a sequence of 'wchar_t's. Converting between these is also possible in a portable way (well, at least portable across platforms with identical size of 'wchar_t' even if 'char' has different sizes). > Such decision is very strong, I know. Yet, one of the main problems with > the acceptance of Unicode as a standard is that there are too many > applications around that uses only a subset of it. For example, one of > the first feedback I got, at the beginning of this work, was "I don't > need to handle surrogates, could you provide an optimized facet for that > case?". The answer was "Yes, I could, but I won't". As I said, I don't have strong feelings about this (and I have implemented such a facet myself already anyway...). However, note that I requested something quite different: I definitely want to detect if a character cannot be represented using the internally used character. In fact, I would like to see this happen even for a 16 bit internal type because UTF-16 processing is considerably more complex than UC2 processing and I can see people falling into the trap of testing only cases where UC2 is used. That is, the implicit choice of using UTF-16 is actually a pretty dangerous one, IMO. > There already exist a facility to select the correct facet according to > the byte order mark. It's very simple to use: > > std::wifstream file("MyFile", std::ios_base::binary); > boost::utf::imbue_detect_from_bom(file); > > that's it. I have seen this possibility and I disagree that it is very simple to use for several reasons: - There is at least one implementation which does not allow changing the locale after the file was opened. This is a reasonable restriction which seems to be covered by the standard (I thought otherwise myself but haven't found any statement supporting a different view). Thus, changing the code conversion facet without closing the file may or may not be possible. Closing and reopening a file may also be impossible for certain kinds of files. - Your approach assumes a seekable stream which is not necessarily the case: At least on UNIXes I can open a file stream to read from a named pipe which is definitely non-seekable. Adjusting the state internally can avoid the need to do any seeking, although admittedly at the cost some complexity encapsulated by the facet. > I considered separating the facets class from the conversion > implementation code, but I decided to keep the design one facet == one > encoding. There are a couple of minor advantages: > > 1) the user can have just one or two encondings in your executable > without taking all of them. (Of course if you use imbue_detect_from_bom > you will need all encodings, anyway... ;) I'm not saying that all encoding have to be folded into only one facet! I would envision an UTF-8 facet, an UTF-16BE facet, etc. However, I would also envision a Unicode facet which internally uses whatever of these encodings it detects. > 2) I avoid one indirection. The cost of this cannot be underestimated. The respective conversion function can be a specific inline function. I doubt that there would be any cost incured by calling such inline functions. > The VS.NET implementation is quite brain-dead about codecvt: it will > call the do_in function (which is virtual!) up to 4 times *per > character*. Three times the function will return "partial", the fourth > times it will succeed. For every character. Yes, I know. It is, BTW, not that brain-dead: Doing it differently does not necessarily work because a 'std:
Re: [boost] Shared_ptr "mini garbage collector"
"Peter Dimov" <[EMAIL PROTECTED]> writes: > From: "David Abrahams" <[EMAIL PROTECTED]> >> >> Yes, but IIUC the reason the library's not doing it is because you >> might get the order wrong, which could cause a problem like a dangling >> pointer needed for some destructor. > > Not really... The library's not currently doing it because it hasn't been my > goal to provide a "real" garbage collected pointer. sp_debug_hooks.cpp is an > example that demonstrates what can be done with the debug hooks called by > shared_ptr; code using it operates in "safe mode" (or slightly safer mode.) > IOW a shared_ptr cycle is still not supposed to happen in bug free programs. > > That aside, can you think of a reasonable design that does not depend on > intentionally created shared_ptr cycles, but still needs a correct > destruction order when a cycle is broken? I can barely think of a reasonable design where GC is a big design win ;-) In my work, ownership relationships are usually very obvious. When they're not, destruction does nothing but release resources. -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Shared_ptr "mini garbage collector"
From: "David Abrahams" <[EMAIL PROTECTED]> > > Yes, but IIUC the reason the library's not doing it is because you > might get the order wrong, which could cause a problem like a dangling > pointer needed for some destructor. Not really... The library's not currently doing it because it hasn't been my goal to provide a "real" garbage collected pointer. sp_debug_hooks.cpp is an example that demonstrates what can be done with the debug hooks called by shared_ptr; code using it operates in "safe mode" (or slightly safer mode.) IOW a shared_ptr cycle is still not supposed to happen in bug free programs. That aside, can you think of a reasonable design that does not depend on intentionally created shared_ptr cycles, but still needs a correct destruction order when a cycle is broken? ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Shared_ptr "mini garbage collector"
"Peter Dimov" <[EMAIL PROTECTED]> writes: > Currently I use a conservative scan that assumes that shared_ptr instances > have a layout of > > T * px; > counted_base * pi; > int id; It's easy enough to enforce that by inheriting from a POD struct. Don't know about the next part, though: > with pointers being aligned on a DWORD boundary. -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Shared_ptr "mini garbage collector"
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. > 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? ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Small thing: yes_type and no_type made public?
[EMAIL PROTECTED] (Hartmut Kaiser) writes: > Within the Boost.Spirit library we have the need to have not only > two distinct (size-)types, but something around a dozen. Not surprising. I use three in boost/python/detail/indirect_traits.hpp. -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Shared_ptr "mini garbage collector"
"Peter Dimov" <[EMAIL PROTECTED]> writes: > From: "David Abrahams" <[EMAIL PROTECTED]> >> "Peter Dimov" <[EMAIL PROTECTED]> writes: >> >> > It's true that, in general, there is no safe way to break the cycle; x1 > may >> > keep a raw pointer to x2, or it might be a X invariant that X::p is >> > non-empty, causing ~X to fail. This is why the final decision to break > the >> > cycles should be left to the user, and the collector should not >> > automatically reclaim memory. Still, most reasonable classes would be >> > collect-friendly. >> >> Isn't the biggest problem one of system design? How does the user >> write the cycle-breaking code which does different things based on the >> dynamic type of the objects being referenced? > > The user doesn't need to write any cycle-breaking code. All that is > needed is to reset() the shared_ptr instances that keep the cycle > alive. I.e. the requirement is that the object's invariants must not > be broken if a shared_ptr member is suddenly reset. > > It's not necessary to know the T in shared_ptr in order to reset it if > shared_ptrs are layout-compatible (true on most implementations.) Yes, but IIUC the reason the library's not doing it is because you might get the order wrong, which could cause a problem like a dangling pointer needed for some destructor. How will the user decide the order if not by examining T? -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: Hello MPL world!
"Joel de Guzman" <[EMAIL PROTECTED]> wrote in message 01c701c2b602$dde18750$06d117d2@kim">news:01c701c2b602$dde18750$06d117d2@kim... > [...] > Well, I meant the targetted audience, of course, the C++ newbies :-) That's because the C++ noobs presumably don't know much about programming yet. However, MPL noobs probably will, and will likely be much more discriminating when it comes to an introductory example. Dave ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: UTF library available for review
First of all, thanks to everybody for your feedback. I realized that my message was a bit arrogant about the lack of interest... I apologize for that and I promise I'll give my best to get this library to boost standards! Dietmar Kuehl wrote: - The 'state' argument for the various facet functions is normally accessed as a plain integer in your code. However, eg. 'std::mbstate_t' is not an integer at all. In fact, it is implementation defined and can thus be something entirely different on each platform. I'd suggest to provide some from of accessor functions to read or write objects of this type, possibly in the form of some traits class. This could then be used to cope with differences and/or more complex organization of the state type. That's a good point. On my platform (Win32) mbstate_t indeed is a typedef to "int" and thus satisfies all requirements (i.e.: being an integer type capable of containing an unsigned 21-bit value). I was aware that this is not the case on other platforms, but I made the assumption anyway simply because the user is not really required to use mbstate_t. One can use a char traits class different from std::char_traits, that defines a suitable state type. For example: template struct MyTraits : public std::char_traits { typedef boost::uint32_t state_type; }; then use basic_fstream > instead of basic_fstream. [I just tried that and found a typo in correctness_test.hpp that prevents the test suite to compile, but nothing too serious] Of course I have to document this ;) If you believe that harnessing with the char traits class is undesirable, or simply "too much", I see no problems in adding those accessors function as you suggest. - Falling back to UTF-16 in cases where the Unicode characters may not fit into the words is one possible approach to deal with the characters. Another approach is to just indicate an error. For example, I know that certain XML-files I'm using exclusively store ASCII characters and there is no need to use a different internal character type than 'char'. If I ever come across a non-ASCII character I don't really want to have it encoded in something like UTF-8 but I want to fail reading the file (and possibly retry reading using a bigger character type). I would appreciate if such a possibility would be incorporated, too (this is, however, nothing I feel too strongly about). I forgot to say in my previous post that this version of the library only supports platforms where type char is exactly 8 bits. This assumption is required because I have to work at the octet level while reading from/writing to a stream. That said, I have deliberately decided not to allow "char" as the internal type. The internal type must be an integral type able to represent an unsigned 16-bit value (for UTF-16) or an unsigned 21-bit value (UTF-32). The choice between UTF-16 and UTF-32 as the internal encoding is done at compile-time based on the sizeof of the internal char type, which must be either 2 or 4. Such decision is very strong, I know. Yet, one of the main problems with the acceptance of Unicode as a standard is that there are too many applications around that uses only a subset of it. For example, one of the first feedback I got, at the beginning of this work, was "I don't need to handle surrogates, could you provide an optimized facet for that case?". The answer was "Yes, I could, but I won't". Yours is a very special case. Frankly, I'd rather not support it. In fact, it would be extremely very simple to do: you just take the facet declared in file detail/degenerate.hpp and change a few lines. However, it would be out of the intent of this library, which is to provide UTF conversion according to Unicode 3.2 requirements, no more, no less. - In the context I want to use the facets [at least those I'm implementing] I don't really want to bother about the details of the encoding. That is, I just want to 'imbue()' an appropriate 'std::locale' object to the stream and have the facet figure out what encoding is used, especially when reading from some file. The basic idea is that each file is either started by a byte order mark from which UTF-16BE or UTF16LE can be deduced or it is in UTF-8. The encoding could eg. be stored in typical 'std::mbstate_t' objects (these are often a struct with a 'wchar_t' and a count or something like this). To enable something like this, it would be helpful if the actual conversion functions were actually separated from the facets: The facets would just call the corresponding conversion functions. The actual conversion is, apart from the state argument, entirely stateless and there is no need to bind it to any facet. There already exist a facility to select the correct facet according to the byte order mark. It's very simple to use: std::wifstream file("MyFile", std::ios_base::binary); boost::utf::imbue_detect_from_bom(file); that's it
RE: [boost] Re: Small thing: yes_type and no_type made public?
David B. Held wrote: > "Hartmut Kaiser" <[EMAIL PROTECTED]> wrote in message > 000f01c2b691$45a3a1a0$0b00a8c0@fortytwo">news:000f01c2b691$45a3a1a0$0b00a8c0@fortytwo... > > Terje Slettebø wrote: > > > [...] > > > typedef char (&yes_type)[1]; > > > typedef char (&no_type)[2]; > > > > Within the Boost.Spirit library we have the need to have not only > > two distinct (size-)types, but something around a dozen. Wouldn't it > > be better to provide something more general as the two (size-)type > > yes/no solution? With Boost.PP this shouldn't be any problem. > > You mean like: > > template struct size_type { char s[N]; }; > > typedef size_type<1> false_t; > typedef size_type<2> true_t; > typedef size_type<3> some_other_t; > ... Yes. Sorry for beeing too inconsise. Regards Hartmut ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Small thing: yes_type and no_type made public?
>From: "Hartmut Kaiser" <[EMAIL PROTECTED]> > Terje Slettebø wrote: > > > > typedef char (&yes_type)[1]; > > typedef char (&no_type)[2]; > > Within the Boost.Spirit library we have the need to have not only two > distinct (size-)types, but something around a dozen. Wouldn't it be > better to provide something more general as the two (size-)type yes/no > solution? With Boost.PP this shouldn't be any problem. Sure, that would be fine. I'm not that familiar with Boost.PP, though, so I think I leave it to someone else to write that version. As quite a bit of code uses yes_type/no_type, now, it may be a good idea to keep them, as well, anyway, for backwards compatibility and simplicity. Regards, Terje ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Small thing: yes_type and no_type made public?
"Hartmut Kaiser" <[EMAIL PROTECTED]> wrote in message 000f01c2b691$45a3a1a0$0b00a8c0@fortytwo">news:000f01c2b691$45a3a1a0$0b00a8c0@fortytwo... > Terje Slettebø wrote: > > [...] > > typedef char (&yes_type)[1]; > > typedef char (&no_type)[2]; > > Within the Boost.Spirit library we have the need to have not only > two distinct (size-)types, but something around a dozen. Wouldn't it > be better to provide something more general as the two (size-)type > yes/no solution? With Boost.PP this shouldn't be any problem. You mean like: template struct size_type { char s[N]; }; typedef size_type<1> false_t; typedef size_type<2> true_t; typedef size_type<3> some_other_t; ... Dave ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Metaprogramming: Using static const or enum?
>From: "David B. Held" <[EMAIL PROTECTED]> > "Terje Slettebø" <[EMAIL PROTECTED]> wrote in message > 023f01c2b65a$1758e990$cb6c6f50@pc">news:023f01c2b65a$1758e990$cb6c6f50@pc... > > [...] > > Thus, it prefers static const, if it's possible to initialise it in-class, > > on the given compiler, as allowed in the standard. However, > > "C++ Templates: The Complete Guide" says about the difference > > between the two (p. 304): > > [...] > > I agree that Vandevoorde & Josuttis give a pretty compelling > argument in favor of enum. I think it should be considered a > best practice for Boost code, and BOOST_STATIC_CONSTANT > should be deprecated, unless there is a reason that enum is > inferior on some platforms. Unfortunately, there is, but maybe not enough to offset the advantage of enum (also what Daniel mentioned). Borland C++ Builder 6.0 doesn't handle enum very well (this is also mentioned in the Boost integral constants guideline). It occurs especially in more complex metaprogramming expressions. Even if you use the other guidelines (fully qualify names, etc.), it may still fail. I tested modifying Loki's Conversion template to use enum rather than static const int (in the Borland port). The original works, but the enum-version gave a cryptic compiler error. Simpler things, like altering Length in the same way, worked fine. In this respect it's kind of the opposite of MSVC 6, which doesn't handle static const int (with in-class initialisation), at all. Of course, it would be possible to change BOOST_STATIC_CONST to have the opposite guideline as today - prefer enum unless the compile doesn't handle it. Regards, Terje ___ 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] Small thing: yes_type and no_type made public?
Terje Slettebø wrote: > >From: "David Abrahams" <[EMAIL PROTECTED]> > > > Terje Slettebø <[EMAIL PROTECTED]> writes: > > > > >> Sure! Submit a patch (with docs) for the utility library. > > > > > > Ok. Here's . > > > > > > I just used the file > , changed > the > > > include guard, moved it from boost::type_traits to boost > namespace (is > that > > > ok? > > > > You probably want to fix the copyright. > > > > > // (C) Copyright John Maddock and Steve Cleary 2000. > > Nah, that was intentional. After all, this existed from > before, and it's > very simple, :) so I need no credit for anything. Perhaps for > the docs, > though (to come). > > By the way, I see there are several suggested ways of > defining these types, > such as char and struct { char[2] } used in "C++ Templates", > as Dave B. Held > mentioned. It's the same for me what is used, as long as it > works. :) Either > form will likely be the same for the compiler, as well. I > think the form > used is quite nice and symmetric, though, but it may be > changed, should > anyone want to: > > typedef char (&yes_type)[1]; > typedef char (&no_type)[2]; Within the Boost.Spirit library we have the need to have not only two distinct (size-)types, but something around a dozen. Wouldn't it be better to provide something more general as the two (size-)type yes/no solution? With Boost.PP this shouldn't be any problem. Regards Hartmut ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Shared_ptr "mini garbage collector"
From: "David Abrahams" <[EMAIL PROTECTED]> > "Peter Dimov" <[EMAIL PROTECTED]> writes: > > > It's true that, in general, there is no safe way to break the cycle; x1 may > > keep a raw pointer to x2, or it might be a X invariant that X::p is > > non-empty, causing ~X to fail. This is why the final decision to break the > > cycles should be left to the user, and the collector should not > > automatically reclaim memory. Still, most reasonable classes would be > > collect-friendly. > > Isn't the biggest problem one of system design? How does the user > write the cycle-breaking code which does different things based on the > dynamic type of the objects being referenced? The user doesn't need to write any cycle-breaking code. All that is needed is to reset() the shared_ptr instances that keep the cycle alive. I.e. the requirement is that the object's invariants must not be broken if a shared_ptr member is suddenly reset. It's not necessary to know the T in shared_ptr in order to reset it if shared_ptrs are layout-compatible (true on most implementations.) ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Small thing: yes_type and no_type made public?
>From: "David Abrahams" <[EMAIL PROTECTED]> > Terje Slettebø <[EMAIL PROTECTED]> writes: > > > The types yes_type and no_type (or equivalent) - that is, two types which > > are guaranteed to have different size - is used extensively for Boost type > > traits, and also in some other libraries (iterator.hpp, > > named_template_params.hpp, multi_array, Phyton and signals). Some places use > > the type traits ones (), other > > define them themselves. > > > > In the type traits docs (or any other docs I've found), these aren't > > mentioned (and they are defined in the "detail"-directory, suggesting it's > > an implementation detail). Yet, other libraries use them, as well. Perhaps > > these should be documented, so they may be relied on, and other libraries > > may avoid having to define them, themselves? > > Sure! Submit a patch (with docs) for the utility library. Ok. Here's . I just used the file , changed the include guard, moved it from boost::type_traits to boost namespace (is that ok? After all, the other components in utility.hpp is in the boost namespace, too), and changed the definition of the types to the ones suggested (using reference to array). It might be a good idea for those who have libraries that use them (especially if they use char and double for the types), to use the new ones, to ensure that it works on all platforms. I'll write suggested docs, as well. > > I haven't found that guarantee in the C++ or C > > standard. Theoretically, you might have an architecture which > > operated only on values of one size, so that char and double would > > have the same size. > > > > In that case, maybe something like this could be safer: > > > > typedef char yes_type[1]; > > typedef char no_type[2]; > > They have to be references or you can't return them ;-) Right. Changed now. Regards, Terje yes_no_type.hpp Description: Binary data ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: Re: [boost] Shared_ptr "mini garbage collector"
(Sorry for any line break problems... more normal mail system is down because my Linux box has crashed, and the temporary access I have to e-mail is a cheap webmail interface for which I have little control over the formatting.) > From: David Abrahams <[EMAIL PROTECTED]> > "Peter Dimov" <[EMAIL PROTECTED]> writes: > > > It's true that, in general, there is no safe way to break the cycle; x1 may > > keep a raw pointer to x2, or it might be a X invariant that X::p is > > non-empty, causing ~X to fail. This is why the final decision to break the > > cycles should be left to the user, and the collector should not > > automatically reclaim memory. Still, most reasonable classes would be > > collect-friendly. > > Isn't the biggest problem one of system design? How does the user > write the cycle-breaking code which does different things based on the > dynamic type of the objects being referenced? That's basically the question I had, but much better worded. With out a solution for this, I think it's better to just call the destructors and leave it up to the user to write "garbage collector safe destructors", which is the norm any way. William E. Kempf [EMAIL PROTECTED] ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Small thing: yes_type and no_type made public?
Terje Slettebø <[EMAIL PROTECTED]> writes: >> Sure! Submit a patch (with docs) for the utility library. > > Ok. Here's . > > I just used the file , changed the > include guard, moved it from boost::type_traits to boost namespace (is that > ok? You probably want to fix the copyright. > // (C) Copyright John Maddock and Steve Cleary 2000. -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Shared_ptr "mini garbage collector"
At 01:23 PM 1/7/2003, Peter Dimov wrote: >From: "Peter Dimov" <[EMAIL PROTECTED]> >> From: "Greg Colvin" <[EMAIL PROTECTED]> >> > My old cyclic_ptr code is still somewhere on the Boost pages, >> > and might offer a better solution to these problems. >> >> Indeed. After having reinvented that wheel, I am now (finally) able to >> understand cyclic_ptr. ;-) > >As it turns out, that wheel has been invented by > >Christopher, Thomas W. >Reference Count Garbage Collection >Software-Practice and Experience >Vol.14(6), pp.503-507, June 1984 Yes, Christopher's work was the inspiration for cyclic_ptr, but I made some changes to adapt it to C++. >as referenced in Larry Evans' comparison > >http://groups.yahoo.com/group/boost/files/shared_cyclic_ptr/draft-compare.zi >p > >___ >Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Metaprogramming: Using static const or enum?
"Terje Slettebø" <[EMAIL PROTECTED]> wrote in message 023f01c2b65a$1758e990$cb6c6f50@pc">news:023f01c2b65a$1758e990$cb6c6f50@pc... > [...] > Thus, it prefers static const, if it's possible to initialise it in-class, > on the given compiler, as allowed in the standard. However, > "C++ Templates: The Complete Guide" says about the difference > between the two (p. 304): > [...] I agree that Vandevoorde & Josuttis give a pretty compelling argument in favor of enum. I think it should be considered a best practice for Boost code, and BOOST_STATIC_CONSTANT should be deprecated, unless there is a reason that enum is inferior on some platforms. Dave ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Small thing: yes_type and no_type made public?
(Sorry, the previous sending of this posting was sent "back in time", due to the time having been set back temporarily a couple of months. Therefore, I resend it. Sorry about that) >From: "David Abrahams" <[EMAIL PROTECTED]> > Terje Slettebø <[EMAIL PROTECTED]> writes: > > >> Sure! Submit a patch (with docs) for the utility library. > > > > Ok. Here's . > > > > I just used the file , changed the > > include guard, moved it from boost::type_traits to boost namespace (is that > > ok? > > You probably want to fix the copyright. > > > // (C) Copyright John Maddock and Steve Cleary 2000. Nah, that was intentional. After all, this existed from before, and it's very simple, :) so I need no credit for anything. Perhaps for the docs, though (to come). By the way, I see there are several suggested ways of defining these types, such as char and struct { char[2] } used in "C++ Templates", as Dave B. Held mentioned. It's the same for me what is used, as long as it works. :) Either form will likely be the same for the compiler, as well. I think the form used is quite nice and symmetric, though, but it may be changed, should anyone want to: typedef char (&yes_type)[1]; typedef char (&no_type)[2]; Regards, Terje ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Small thing: yes_type and no_type made public?
>From: "David Abrahams" <[EMAIL PROTECTED]> > Terje Slettebø <[EMAIL PROTECTED]> writes: > > >> Sure! Submit a patch (with docs) for the utility library. > > > > Ok. Here's . > > > > I just used the file , changed the > > include guard, moved it from boost::type_traits to boost namespace (is that > > ok? > > You probably want to fix the copyright. > > > // (C) Copyright John Maddock and Steve Cleary 2000. Nah, that was intentional. After all, this existed from before, and it's very simple, :) so I need no credit for anything. Perhaps for the docs, though (to come). By the way, I see there are several suggested ways of defining these types, such as char and struct { char[2] } used in "C++ Templates", as Dave B. Held mentioned. It's the same for me what is used, as long as it works. :) Either form will likely be the same for the compiler, as well. I think the form used is quite nice and symmetric, though, but it may be changed, should anyone want to: typedef char (&yes_type)[1]; typedef char (&no_type)[2]; Regards, Terje ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Shared_ptr "mini garbage collector"
From: "Peter Dimov" <[EMAIL PROTECTED]> > From: "Greg Colvin" <[EMAIL PROTECTED]> > > My old cyclic_ptr code is still somewhere on the Boost pages, > > and might offer a better solution to these problems. > > Indeed. After having reinvented that wheel, I am now (finally) able to > understand cyclic_ptr. ;-) As it turns out, that wheel has been invented by Christopher, Thomas W. Reference Count Garbage Collection Software-Practice and Experience Vol.14(6), pp.503-507, June 1984 as referenced in Larry Evans' comparison http://groups.yahoo.com/group/boost/files/shared_cyclic_ptr/draft-compare.zi p ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: Re: [boost] Shared_ptr "mini garbage collector"
At 11:04 AM 1/7/2003, William E. Kempf wrote: >> From: Greg Colvin <[EMAIL PROTECTED]> >> At 09:23 AM 1/7/2003, Peter Dimov wrote: >> >From: "William E. Kempf" <[EMAIL PROTECTED]> >> >> >> >> I think that extending it to free memory in cycles would be a great idea. >> >Of course, this opens a large can of worms about how to handle destruction >> >of objects which refer to each other...< >> > >> >One possible approach is to return a list of references to the "offending" >> >shared_ptr instances to the user, who can then reset() them as appropriate. >> >Actually it's not as simple as that since a reset() can invalidate some of >> >the returned references; the shared_ptr instances would first need to be >> >copied to a temporary container, the originals reset(), and the temporary >> >container destroyed, but the general idea is the same. >> >> Finalization semantics is of course a very big can of worms >> that has kept a lot of GC experts arguing for years. But I >> take the success of Java as evidence that getting it right >> might not be all that important. > >The "Java solution" is to not have a solution. Finalizers need never be called in >Java. Right. You need finally clauses for most resource management. A GC for C++ could just as easily never call destructors, and provide a separate mechanism for optional finalizers. > I'd prefer to always call the destructors, with the knowledge that dereferencing a >GC pointer that's participating in a cycle during the destructor results in undefined >behavior. I can usually avoid doing this. That is one reasonable approach. The collector can make it easier by providing a topological sort of the soon-to-be-dead objects, so that you can safely dereference pointers in the destructors. But then you have to do something else for cycles. Like I said, the GC experts have been discussing this for years without any clear resolution. >> >> I think that full GC is one of the major things missing from the C++ >> >language, and the appeal of a smart pointer approach, where I pay for GC >> >only when I want/need it, is a great idea.< >> >> A smart pointer approach is the only way I know to write a >> portable collector, but it is not really the best way to >> write a high-performance collector. My preference is to >> have a special new(gc) allocator for collectable objects, >> and compiler support for a collector that can scan all >> objects for pointers to collectable objects. If new(gc) >> is never called there need be no overhead. > >Creating an efficient GC system is tricky, yes, but I don't see why a smart pointer >approach can't be just as efficient as a compiler solution? It probably can be, but the literature so far indicates that it isn't. A collector that has compiler support and knows all about how the stack and heap are laid out and can take advantage of the virtual memory hardware and so on has a big advantage. It's also nice to be able to use raw pointers to collected objects. Still, a portable smart pointer GC would be nice to have, as it will take years of work to see GC added to C++, if it ever happens at all. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Metaprogramming: Using static const or enum?
Terje Slettebø <[EMAIL PROTECTED]> writes: > Static constant members are lvalues. So, if you have a declaration such as > > void foo(int const&); > > and you pass it the result of a metaprogram > > foo(Pow3<7>::result); > > a compiler must pass the address of Pow3<7>::result, which forces > the compiler to instantiate and allocate the definition for the > static member. As a result, the computation is no longer limited to > a pure "compile-time" effect. I buy everything but the last sentence. What do they mean? Does the thing go into the link map? If not, what? > Enumerations aren't lvalues (that is, they don't have an address). So when > you pass them "by reference," no static memory is used. It's almost exactly > as if you passed the computed value as a literal. These considerations > motivate us to use enumeration values in all metaprograms throughout this > book. > > --- End quote --- > > I like static const, as I think it conveys more succinctly what it's about, > and the enum appears more like a hack (for compilers not handling static > const in-class initialisation). However, if this means it may need an > out-of-class definition, as well, perhaps this could need to be > reconsidered? > > The point is also confirmed by the following test (on Intel C++, which uses > static const): > > struct Test > { > enum { value=1 }; // Ok > // BOOST_STATIC_CONSTANT(int, value=1); // Gives link-error > }; > > void f(const int &) > { > } > > int main() > { > f(Test::value); > } > > If pass by value is used in f(), it works, of course. So maybe pass by const > reference for integral constants typically isn't used, so that this isn't a > problem? The rule is that you can't in general take the address of a BOOST_STATIC_CONSTANT. -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: file_system prefomace problem (?)
"Beman Dawes" <[EMAIL PROTECTED]> wrote in message [EMAIL PROTECTED]">news:[EMAIL PROTECTED]... > At 11:12 AM 1/5/2003, Daniel Yerushalmi wrote: > >Hi All > > > >I have code that iterate on directory tree (the recursive function) > >addFolder. I had profiled it (MSVC 6.5) > >Func Func+Child Hit > >Time % Time % Count Function > >- > > 28.780 43.2 31.818 47.8 567 > >boost::filesystem::is_directory(class boost::filesystem::path const &) > >(operations_posix_windows.obj) > > 10.136 15.2 22.666 34.0 151 > >boost::filesystem::directory_iterator::directory_iterator(class > >boost::filesystem::path const &) (operations_posix_windows.obj) > > 7.249 10.97.249 10.9 592 `anonymous > >namespace'::find_next_file(void *,class boost::filesystem::path const > >&,struct _WIN32_FIND_DATAA &) (operations_posix_windows.obj) > >(operations_posix_windows.obj) > > > >As you can see most of the time is spent in the is_directory function. I > >know that (in Win32 - ::FindNextFileA at least) the information for > >"is_directory" can be fetched in the "::find_next_file". I suggest to add > >m_is_directory attribute to the path class (initial value "unknown") and > >have is_directory read from this attribute if possible. (For my > application > >the is_directory time is swamped by other things but for other directory > >iterating applications this may be significant) > > Before answering the question "How can we cache file attributes between > calls to filesystem function?" we need to answer the question "Should we > cache file attributes between filesystem functions?" > > The problem is race-conditions. "c:/foo/bar" may have been a directory the > last time we saw it, but now is a file. I'd want to think about that a bit > more before doing any caching. > > I'd like the filesystem library to mature and see wider use before worrying > about optimizations, too. > > Thanks for the profiling, > > --Beman I agree with you about the maturing (in fact in my application the iteration does not take that much time so even speeding it by factor of 9 will not help so much :( ) When you recursivly iterate on directories you implicitly cache the is_directory information... (You use it to access the next level for this path). I recall that I have seen in boost (in the sandbox?) something called recursive_directory_iterator...) maybe we should do the cache only for this case (when more pepole will use this library) . By the way - the speedup is only relevant to Win32 - the Posix API does not fetch path attribute when iterating on a directory. > > > ___ > Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost > ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Shared_ptr "mini garbage collector"
"Peter Dimov" <[EMAIL PROTECTED]> writes: > It's true that, in general, there is no safe way to break the cycle; x1 may > keep a raw pointer to x2, or it might be a X invariant that X::p is > non-empty, causing ~X to fail. This is why the final decision to break the > cycles should be left to the user, and the collector should not > automatically reclaim memory. Still, most reasonable classes would be > collect-friendly. Isn't the biggest problem one of system design? How does the user write the cycle-breaking code which does different things based on the dynamic type of the objects being referenced? -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: Re: [boost] Shared_ptr "mini garbage collector"
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: 1. Find the two X objects (let's call them x1 and x2) on the heap, and scan them for shared_ptr instances, finding x1.p and x2.p; determine that x1 and x2 are unreachable. 2. Create a temporary vector< shared_ptr > v and copy x1.p and x2.p into it. 3. Reset x1.p and x2.p. 4. Clear v. This will cause x1 and x2 to be destroyed. It's true that, in general, there is no safe way to break the cycle; x1 may keep a raw pointer to x2, or it might be a X invariant that X::p is non-empty, causing ~X to fail. This is why the final decision to break the cycles should be left to the user, and the collector should not automatically reclaim memory. Still, most reasonable classes would be collect-friendly. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Shared_ptr "mini garbage collector"
From: "Greg Colvin" <[EMAIL PROTECTED]> > My old cyclic_ptr code is still somewhere on the Boost pages, > and might offer a better solution to these problems. Indeed. After having reinvented that wheel, I am now (finally) able to understand cyclic_ptr. ;-) ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: Re: [boost] Shared_ptr "mini garbage collector"
> From: "Peter Dimov" <[EMAIL PROTECTED]> > From: "William E. Kempf" <[EMAIL PROTECTED]> > > > No, the user would not be expected to do any bookkeeping. He would only > need > > > to call find_unreachable_objects() that would return a list of the > > > unreachable objects, and then, optionally, call break_cycles() with that > > > list as an argument. Or something like that. :-) > > > > And how would break_cycles() accomplish its task with out book keeping? > > The information that is needed to break the cycles (a list of unreachable > shared_ptr instances) is generated by find_unreachable_objects for free, > since to determine object reachability, objects are scanned for shared_ptr > subobjects. When those shared_ptrs are reset() by break_cycles(), all > unreachable objects will be freed, their destructors will run, and any > weak_ptrs to those objects will correctly expire. 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. William E. Kempf [EMAIL PROTECTED] ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] file_system prefomace problem (?)
At 11:12 AM 1/5/2003, Daniel Yerushalmi wrote: >Hi All > >I have code that iterate on directory tree (the recursive function) >addFolder. I had profiled it (MSVC 6.5) >Func Func+Child Hit >Time % Time % Count Function >- > 28.780 43.2 31.818 47.8 567 >boost::filesystem::is_directory(class boost::filesystem::path const &) >(operations_posix_windows.obj) > 10.136 15.2 22.666 34.0 151 >boost::filesystem::directory_iterator::directory_iterator(class >boost::filesystem::path const &) (operations_posix_windows.obj) > 7.249 10.97.249 10.9 592 `anonymous >namespace'::find_next_file(void *,class boost::filesystem::path const >&,struct _WIN32_FIND_DATAA &) (operations_posix_windows.obj) >(operations_posix_windows.obj) > >As you can see most of the time is spent in the is_directory function. I >know that (in Win32 - ::FindNextFileA at least) the information for >"is_directory" can be fetched in the "::find_next_file". I suggest to add >m_is_directory attribute to the path class (initial value "unknown") and >have is_directory read from this attribute if possible. (For my application >the is_directory time is swamped by other things but for other directory >iterating applications this may be significant) Before answering the question "How can we cache file attributes between calls to filesystem function?" we need to answer the question "Should we cache file attributes between filesystem functions?" The problem is race-conditions. "c:/foo/bar" may have been a directory the last time we saw it, but now is a file. I'd want to think about that a bit more before doing any caching. I'd like the filesystem library to mature and see wider use before worrying about optimizations, too. Thanks for the profiling, --Beman ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] function_traits.hpp: a little inconsistency
(Boost 1.29): File type_traits/function_traits.hpp includes other headers using #include <...> convention. All other sources use #include "..." convention. Maybe it can be made consistent accros the library. /Pavel ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: Re: [boost] Shared_ptr "mini garbage collector"
> From: Greg Colvin <[EMAIL PROTECTED]> > At 09:23 AM 1/7/2003, Peter Dimov wrote: > >From: "William E. Kempf" <[EMAIL PROTECTED]> > >> > >> I think that extending it to free memory in cycles would be a great idea. > >Of course, this opens a large can of worms about how to handle destruction > >of objects which refer to each other...< > > > >One possible approach is to return a list of references to the "offending" > >shared_ptr instances to the user, who can then reset() them as appropriate. > >Actually it's not as simple as that since a reset() can invalidate some of > >the returned references; the shared_ptr instances would first need to be > >copied to a temporary container, the originals reset(), and the temporary > >container destroyed, but the general idea is the same. > > Finalization semantics is of course a very big can of worms > that has kept a lot of GC experts arguing for years. But I > take the success of Java as evidence that getting it right > might not be all that important. The "Java solution" is to not have a solution. Finalizers need never be called in Java. I'd prefer to always call the destructors, with the knowledge that dereferencing a GC pointer that's participating in a cycle during the destructor results in undefined behavior. I can usually avoid doing this. > >> I think that full GC is one of the major things missing from the C++ > >language, and the appeal of a smart pointer approach, where I pay for GC > >only when I want/need it, is a great idea.< > > A smart pointer approach is the only way I know to write a > portable collector, but it is not really the best way to > write a high-performance collector. My preference is to > have a special new(gc) allocator for collectable objects, > and compiler support for a collector that can scan all > objects for pointers to collectable objects. If new(gc) > is never called there need be no overhead. Creating an efficient GC system is tricky, yes, but I don't see why a smart pointer approach can't be just as efficient as a compiler solution? William E. Kempf [EMAIL PROTECTED] ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: Re: [boost] Shared_ptr "mini garbage collector"
From: "William E. Kempf" <[EMAIL PROTECTED]> > > No, the user would not be expected to do any bookkeeping. He would only need > > to call find_unreachable_objects() that would return a list of the > > unreachable objects, and then, optionally, call break_cycles() with that > > list as an argument. Or something like that. :-) > > And how would break_cycles() accomplish its task with out book keeping? The information that is needed to break the cycles (a list of unreachable shared_ptr instances) is generated by find_unreachable_objects for free, since to determine object reachability, objects are scanned for shared_ptr subobjects. When those shared_ptrs are reset() by break_cycles(), all unreachable objects will be freed, their destructors will run, and any weak_ptrs to those objects will correctly expire. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] string_algo lib
Hi, String Algorithm Library is in the feature complete state available in the sand-box. ( :sandbox:/boost/string_algo, :sandbox:/libs/string_algo ) Short summary of the features can be found in the boost WIKI http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?STLAlgorithmExtensions/StringAlgorithms Library contains full set of tests together with Jamfile. Documentation is still missing :( . I'll try to have it done soon. Check the tests for usage scenario. New features: - Boost.Build compatible tests - full regex support - optimized replace algorithms - improved scalability I'll be gratefull for any comments and suggestions. Pavol ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Small thing: yes_type and no_type made public?
"Pavel Vozenilek" <[EMAIL PROTECTED]> wrote in message aveup0$8jc$[EMAIL PROTECTED]">news:aveup0$8jc$[EMAIL PROTECTED]... > [...] > There are many variants, e.g.: > > typedef double yes_type; > typedef yes_type no_type[2]; Same problem as Terje's example...can't return array types. ;) Vandevoorde and Josuttis use char and struct { char[2] }. I guess the best choice would be the one that taxes the compiler least, but I'm not sure how to determine that (short of asking the compiler vendors). Dave ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: Re: [boost] Shared_ptr "mini garbage collector"
> From: "Peter Dimov" <[EMAIL PROTECTED]> > From: "William E. Kempf" <[EMAIL PROTECTED]> > > > From: "Peter Dimov" <[EMAIL PROTECTED]> > > > From: "William E. Kempf" <[EMAIL PROTECTED]> > > > > I think that extending it to free memory in cycles would be a great > idea. > > > Of course, this opens a large can of worms about how to handle > destruction > > > of objects which refer to each other...< > > > > > > One possible approach is to return a list of references to the > "offending" > > > shared_ptr instances to the user, who can then reset() them as > appropriate. > > > Actually it's not as simple as that since a reset() can invalidate some > of > > > the returned references; the shared_ptr instances would first need to be > > > copied to a temporary container, the originals reset(), and the > temporary > > > container destroyed, but the general idea is the same. > > > > This just pushes the issue off on the end user... who may not be any more > capable of dealing with the problem either. If he can't do a lot of book > keeping to handle the circular problem, then pushing it off on him is not > much help. And if he can do the book keeping, there's probably a solution > he can code into the destructors themselves.< > > No, the user would not be expected to do any bookkeeping. He would only need > to call find_unreachable_objects() that would return a list of the > unreachable objects, and then, optionally, call break_cycles() with that > list as an argument. Or something like that. :-) And how would break_cycles() accomplish its task with out book keeping? William E. Kempf [EMAIL PROTECTED] ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Hello MPL world!
At 05:09 PM 1/6/2003, David B. Held wrote: >"David Abrahams" <[EMAIL PROTECTED]> wrote in message >[EMAIL PROTECTED]">news:[EMAIL PROTECTED]... >> Howard Hinnant <[EMAIL PROTECTED]> writes: >> >> OK, I see your point. How about: >> >> template >> struct my_container >> : if_< >> and_< >>is_pointer >> , is_POD > >> > >> , impl1 >> , impl2 >>>::type >> { >> ... >> }; > >I think if you provided a copy c'tor that called memcpy() for >impl1, or some other POD optimization, that would motivate the >example for people who might be a little slow on the uptake >(like I am sometimes!). Otherwise, it seems like a decent >introduction. You might even be a little suggestive and call it >my_vector, to imply that you are creating a POD-optimized >vector (which people should be able to relate to easily enough). I like this suggestion a lot. A simple, useful example that can't easily be done without something like MPL. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Shared_ptr "mini garbage collector"
At 09:23 AM 1/7/2003, Peter Dimov wrote: >From: "William E. Kempf" <[EMAIL PROTECTED]> >> >> I think that extending it to free memory in cycles would be a great idea. >Of course, this opens a large can of worms about how to handle destruction >of objects which refer to each other...< > >One possible approach is to return a list of references to the "offending" >shared_ptr instances to the user, who can then reset() them as appropriate. >Actually it's not as simple as that since a reset() can invalidate some of >the returned references; the shared_ptr instances would first need to be >copied to a temporary container, the originals reset(), and the temporary >container destroyed, but the general idea is the same. Finalization semantics is of course a very big can of worms that has kept a lot of GC experts arguing for years. But I take the success of Java as evidence that getting it right might not be all that important. >> I think that full GC is one of the major things missing from the C++ >language, and the appeal of a smart pointer approach, where I pay for GC >only when I want/need it, is a great idea.< A smart pointer approach is the only way I know to write a portable collector, but it is not really the best way to write a high-performance collector. My preference is to have a special new(gc) allocator for collectable objects, and compiler support for a collector that can scan all objects for pointers to collectable objects. If new(gc) is never called there need be no overhead. >Making a real "zero overhead" collector is a bit harder, and I'm not sure I >have the time to do it. > >The main requirement is the ability to discover all active counted_base >objects; currently I maintain a global std::map of their addresses, and >that's probably not acceptable for production code. A dedicated allocator >that provides the ability to enumerate allocations may help here. > >An additional requirement is to be able to discover shared_ptr subobjects >and to distinguish a shared_ptr from a weak_ptr; I've used a "magic >constant" but this increases sizeof(shared/weak_ptr) from 8 to 12 on a >typical implementation. It is possible to "mangle" the object pointer (by >XOR-ing it, for example) in weak_ptr and replace the magic constant test >with a valid pointer test, but I'm not sure whether this is a good idea. :-) My old cyclic_ptr code is still somewhere on the Boost pages, and might offer a better solution to these problems. But I just haven't had time or motivation to integrate it with shared_ptr. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: Re: [boost] Shared_ptr "mini garbage collector"
> From: David Abrahams <[EMAIL PROTECTED]> > "William E. Kempf" <[EMAIL PROTECTED]> writes: > > From: "Peter Dimov" <[EMAIL PROTECTED]> > >> One possible approach is to return a list of references to the > >> "offending" shared_ptr instances to the user, who can then reset() > >> them as appropriate. Actually it's not as simple as that since a > >> reset() can invalidate some of the returned references; the > >> shared_ptr instances would first need to be copied to a temporary > >> container, the originals reset(), and the temporary container > >> destroyed, but the general idea is the same. > > > > This just pushes the issue off on the end user... who may not be any > > more capable of dealing with the problem either. If he can't do a lot > > of book keeping to handle the circular problem, then pushing it off on > > him is not much help. And if he can do the book keeping, there's > > probably a solution he can code into the destructors themselves. > > What Python does is to collect only the memory from cycles, without > calling __del__ (the equivalent of a destructor). It also provides a > similar function which gets you a list of the objects that are in > cycles. A solution like this for C++ could easily result in memory leaks. If the object in question did it's own internal memory allocations which would normally be cleaned up in the destructor, you've got a leak when the "collector" releases the object's memory with out calling its destructor. William E. Kempf [EMAIL PROTECTED] ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: Re: [boost] Shared_ptr "mini garbage collector"
From: "William E. Kempf" <[EMAIL PROTECTED]> > > From: "Peter Dimov" <[EMAIL PROTECTED]> > > From: "William E. Kempf" <[EMAIL PROTECTED]> > > > I think that extending it to free memory in cycles would be a great idea. > > Of course, this opens a large can of worms about how to handle destruction > > of objects which refer to each other...< > > > > One possible approach is to return a list of references to the "offending" > > shared_ptr instances to the user, who can then reset() them as appropriate. > > Actually it's not as simple as that since a reset() can invalidate some of > > the returned references; the shared_ptr instances would first need to be > > copied to a temporary container, the originals reset(), and the temporary > > container destroyed, but the general idea is the same. > > This just pushes the issue off on the end user... who may not be any more capable of dealing with the problem either. If he can't do a lot of book keeping to handle the circular problem, then pushing it off on him is not much help. And if he can do the book keeping, there's probably a solution he can code into the destructors themselves.< No, the user would not be expected to do any bookkeeping. He would only need to call find_unreachable_objects() that would return a list of the unreachable objects, and then, optionally, call break_cycles() with that list as an argument. Or something like that. :-) ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Shared_ptr "mini garbage collector"
From: "David Abrahams" <[EMAIL PROTECTED]> > "Peter Dimov" <[EMAIL PROTECTED]> writes: > > > I've added a simple mark and sweep "garbage collector" to > > libs/smart_ptr/sp_debug_hooks.cpp > > Where's the code? I don't see it. In libs/smart_ptr/sp_debug_hooks.cpp? ;-) http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/boost/boost/libs/smart_ptr/sp _debug_hooks.cpp.diff?r1=1.1&r2=1.2 ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Shared_ptr "mini garbage collector"
"William E. Kempf" <[EMAIL PROTECTED]> writes: > From: "Peter Dimov" <[EMAIL PROTECTED]> >> One possible approach is to return a list of references to the >> "offending" shared_ptr instances to the user, who can then reset() >> them as appropriate. Actually it's not as simple as that since a >> reset() can invalidate some of the returned references; the >> shared_ptr instances would first need to be copied to a temporary >> container, the originals reset(), and the temporary container >> destroyed, but the general idea is the same. > > This just pushes the issue off on the end user... who may not be any > more capable of dealing with the problem either. If he can't do a lot > of book keeping to handle the circular problem, then pushing it off on > him is not much help. And if he can do the book keeping, there's > probably a solution he can code into the destructors themselves. What Python does is to collect only the memory from cycles, without calling __del__ (the equivalent of a destructor). It also provides a similar function which gets you a list of the objects that are in cycles. I know that re-using memory which contains an object without a trivial destructor is technically undefined behavior, but it's hard to imagine an implementation where it would be a problem. This would still "simulate infinite memory", though if you were comparing memory addresses you might notice some repetition ;-). I don't know if an approach like this is possible for shared_ptr. -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: Re: [boost] Shared_ptr "mini garbage collector"
> From: "Peter Dimov" <[EMAIL PROTECTED]> > From: "William E. Kempf" <[EMAIL PROTECTED]> > > I think that extending it to free memory in cycles would be a great idea. > Of course, this opens a large can of worms about how to handle destruction > of objects which refer to each other...< > > One possible approach is to return a list of references to the "offending" > shared_ptr instances to the user, who can then reset() them as appropriate. > Actually it's not as simple as that since a reset() can invalidate some of > the returned references; the shared_ptr instances would first need to be > copied to a temporary container, the originals reset(), and the temporary > container destroyed, but the general idea is the same. This just pushes the issue off on the end user... who may not be any more capable of dealing with the problem either. If he can't do a lot of book keeping to handle the circular problem, then pushing it off on him is not much help. And if he can do the book keeping, there's probably a solution he can code into the destructors themselves. I don't know what the real answer is (if there is one), but personally I can live with this case simply being undefined behavior, since it can often (usually?) be avoided in the first place. > > I think that full GC is one of the major things missing from the C++ > language, and the appeal of a smart pointer approach, where I pay for GC > only when I want/need it, is a great idea.< > > Making a real "zero overhead" collector is a bit harder, and I'm not sure I > have the time to do it. Yep. I thought you were volunteering, though, from your post and question ;). > An additional requirement is to be able to discover shared_ptr subobjects > and to distinguish a shared_ptr from a weak_ptr; I've used a "magic > constant" but this increases sizeof(shared/weak_ptr) from 8 to 12 on a > typical implementation. It is possible to "mangle" the object pointer (by > XOR-ing it, for example) in weak_ptr and replace the magic constant test > with a valid pointer test, but I'm not sure whether this is a good idea. :-) Yep... a GC smart pointer is a non-trivial task. It would probably be best to make it a seperate smart pointer, so as not to impact usage of the ref-counted shared_ptr. I know that this topic has been brought up numerous times, but I do think it would be very beneficial for someone to submit a quality GC smart pointer to Boost. William E. Kempf [EMAIL PROTECTED] ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Shared_ptr "mini garbage collector"
"Peter Dimov" <[EMAIL PROTECTED]> writes: > I've added a simple mark and sweep "garbage collector" to > libs/smart_ptr/sp_debug_hooks.cpp Where's the code? I don't see it. -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Small thing: yes_type and no_type made public?
If there would be voting if to put these two types in Boost, I would vote for it. They are usuful and it is not a good practice to define them on many different places. On Tue, Jan 07, 2003 at 04:29:55PM +0100, Terje Sletteb? wrote: > The types yes_type and no_type (or equivalent) - that is, two types which > are guaranteed to have different size - is used extensively for Boost type > traits, and also in some other libraries (iterator.hpp, > named_template_params.hpp, multi_array, Phyton and signals). Some places use > the type traits ones (), other > define them themselves. > > In the type traits docs (or any other docs I've found), these aren't > mentioned (and they are defined in the "detail"-directory, suggesting it's > an implementation detail). Yet, other libraries use them, as well. Perhaps > these should be documented, so they may be relied on, and other libraries > may avoid having to define them, themselves? > > By the way, these are defined as char and double, respectively. Are these > required to have different size? I haven't found that guarantee in the C++ > or C standard. Theoretically, you might have an architecture which operated > only on values of one size, so that char and double would have the same > size. > > In that case, maybe something like this could be safer: > > typedef char yes_type[1]; > typedef char no_type[2]; > > > Regards, > > Terje > > ___ > Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Shared_ptr "mini garbage collector"
From: "William E. Kempf" <[EMAIL PROTECTED]> > > I think that extending it to free memory in cycles would be a great idea. Of course, this opens a large can of worms about how to handle destruction of objects which refer to each other...< One possible approach is to return a list of references to the "offending" shared_ptr instances to the user, who can then reset() them as appropriate. Actually it's not as simple as that since a reset() can invalidate some of the returned references; the shared_ptr instances would first need to be copied to a temporary container, the originals reset(), and the temporary container destroyed, but the general idea is the same. > I think that full GC is one of the major things missing from the C++ language, and the appeal of a smart pointer approach, where I pay for GC only when I want/need it, is a great idea.< Making a real "zero overhead" collector is a bit harder, and I'm not sure I have the time to do it. The main requirement is the ability to discover all active counted_base objects; currently I maintain a global std::map of their addresses, and that's probably not acceptable for production code. A dedicated allocator that provides the ability to enumerate allocations may help here. An additional requirement is to be able to discover shared_ptr subobjects and to distinguish a shared_ptr from a weak_ptr; I've used a "magic constant" but this increases sizeof(shared/weak_ptr) from 8 to 12 on a typical implementation. It is possible to "mangle" the object pointer (by XOR-ing it, for example) in weak_ptr and replace the magic constant test with a valid pointer test, but I'm not sure whether this is a good idea. :-) ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Small thing: yes_type and no_type made public?
"Terje Slettebø" <[EMAIL PROTECTED]> wrote in message 031901c2b661$a1f9c9a0$cb6c6f50@pc">news:031901c2b661$a1f9c9a0$cb6c6f50@pc... > The types yes_type and no_type (or equivalent) - that is, two types which > are guaranteed to have different size - [snip] > By the way, these are defined as char and double, respectively. Are these > required to have different size? I haven't found that guarantee in the C++ > or C standard. Theoretically, you might have an architecture which operated > only on values of one size, so that char and double would have the same > size. > > In that case, maybe something like this could be safer: > > typedef char yes_type[1]; > typedef char no_type[2]; > > There are many variants, e.g.: typedef double yes_type; typedef yes_type no_type[2]; /Pavel ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Small thing: yes_type and no_type made public?
Terje Slettebø <[EMAIL PROTECTED]> writes: > The types yes_type and no_type (or equivalent) - that is, two types which > are guaranteed to have different size - is used extensively for Boost type > traits, and also in some other libraries (iterator.hpp, > named_template_params.hpp, multi_array, Phyton and signals). Some places use > the type traits ones (), other > define them themselves. > > In the type traits docs (or any other docs I've found), these aren't > mentioned (and they are defined in the "detail"-directory, suggesting it's > an implementation detail). Yet, other libraries use them, as well. Perhaps > these should be documented, so they may be relied on, and other libraries > may avoid having to define them, themselves? Sure! Submit a patch (with docs) for the utility library. > By the way, these are defined as char and double, respectively. Are these > required to have different size? No. I thought we changed them to char(&)[1] and char(&)[2]. > I haven't found that guarantee in the C++ or C > standard. Theoretically, you might have an architecture which > operated only on values of one size, so that char and double would > have the same size. > > In that case, maybe something like this could be safer: > > typedef char yes_type[1]; > typedef char no_type[2]; They have to be references or you can't return them ;-) -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Shared_ptr "mini garbage collector"
> From: "Peter Dimov" <[EMAIL PROTECTED]> > > I've added a simple mark and sweep "garbage collector" to > libs/smart_ptr/sp_debug_hooks.cpp that is able to detect unreachable objects > kept alive by shared_ptr cycles. At the moment it's more a debugging aid, > and doesn't attempt to free memory, athough it is possible to extend it to > do so. This is mainly a research project; if you think that it might have a > practical use let me know. :-) I think that extending it to free memory in cycles would be a great idea. Of course, this opens a large can of worms about how to handle destruction of objects which refer to each other... I think that full GC is one of the major things missing from the C++ language, and the appeal of a smart pointer approach, where I pay for GC only when I want/need it, is a great idea. William E. Kempf [EMAIL PROTECTED] ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Shared_ptr "mini garbage collector"
I've added a simple mark and sweep "garbage collector" to libs/smart_ptr/sp_debug_hooks.cpp that is able to detect unreachable objects kept alive by shared_ptr cycles. At the moment it's more a debugging aid, and doesn't attempt to free memory, athough it is possible to extend it to do so. This is mainly a research project; if you think that it might have a practical use let me know. :-) Example: (compile with -DBOOST_ENABLE_SP_DEBUG_HOOKS, link with sp_debug_hooks.cpp) #include #include struct X { boost::shared_ptr p; }; void report_unreachable_objects(); // in sp_debug_hooks.cpp int main() { boost::shared_ptr p1(new X); boost::shared_ptr p2(new X); p1->p = p2; p2->p = p1; report_unreachable_objects(); std::cout << "--\n"; p1.reset(); report_unreachable_objects(); std::cout << "--\n"; p2.reset(); report_unreachable_objects(); } Output: C:\Documents and Settings\pdimov\My Documents\Projects\testbed>a -- -- Unreachable object at 0x3d2c78, 12 bytes long. Unreachable object at 0x3d2cc0, 12 bytes long. -- Peter Dimov http://www.pdimov.com ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Small thing: yes_type and no_type made public?
The types yes_type and no_type (or equivalent) - that is, two types which are guaranteed to have different size - is used extensively for Boost type traits, and also in some other libraries (iterator.hpp, named_template_params.hpp, multi_array, Phyton and signals). Some places use the type traits ones (), other define them themselves. In the type traits docs (or any other docs I've found), these aren't mentioned (and they are defined in the "detail"-directory, suggesting it's an implementation detail). Yet, other libraries use them, as well. Perhaps these should be documented, so they may be relied on, and other libraries may avoid having to define them, themselves? By the way, these are defined as char and double, respectively. Are these required to have different size? I haven't found that guarantee in the C++ or C standard. Theoretically, you might have an architecture which operated only on values of one size, so that char and double would have the same size. In that case, maybe something like this could be safer: typedef char yes_type[1]; typedef char no_type[2]; Regards, Terje ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Metaprogramming: Using static const or enum?
Terje Slettebø wrote: > > BOOST_STATIC_CONST is defined in Boost.Config as: > > # ifdef BOOST_NO_INCLASS_MEMBER_INITIALIZATION > # define BOOST_STATIC_CONSTANT(type, assignment) enum { assignment } > # else > # define BOOST_STATIC_CONSTANT(type, assignment) static const type > assignment > # endif > > Thus, it prefers static const, if it's possible to initialise it in-class, > on the given compiler, as allowed in the standard. However, "C++ Templates: I prefer the enum-variant, but for other reasons which may not apply here. With enums, the compilation might be much faster. I wrote a small mandelbrot-metaprogram some time ago where the different in compilation was a factor (!) of 3 on some compilers. It has to do with how many (anonymous) types a compiler has to generate. To speed up compilation, I put several values into a single enum. Instead of: struct huhu { enum { foo = ... }; enum { bar = ... }; }; I used: struct huhu { enum { foo = ..., bar = ..., }; }; This is IMHO more readable when the list of values gets longer and the compiler has less work to do. The question is, whether compilation time is an issue for boost and if yes, how we can fix it ('static const int' is comparable to the first version when talking about compilation speed). To play with the compile-time, here's the code I used (you might merge some lines as my mailer will split them :) If you have trouble, drop me a mail and I'll send it as an archive) /*/ 2>/dev/null #-- # # ASCII-Mandelbrot - Template-Metaprogramming-Version # # Copyright (c) 2001 by Daniel Frey # # This is both a C++ source code and a bash script. # Just start it and it will compile itself and # (if compilation was successful) will start itself. # # Configure the program by adjusting the exported values below, # but do not set CONFIG_DEPTH to a value > 26. # Start playing with really small values like X=20, Y=9, DEPTH=10 # # Also, try not to look like this smily when analysing this file: =8*/ #define export static const int export CONFIG_SIZE_X=40; export CONFIG_SIZE_Y=21; export CONFIG_DEPTH=15; #undef export #include /*/ 2>/dev/null time g++ -Wall -O2 -ftemplate-depth-$(( ( $CONFIG_SIZE_X + 1 ) * $CONFIG_SIZE_Y + $CONFIG_DEPTH )) $0 -o $0.exe && time ./$0.exe exit; */ using std::cout; //- // Configuration: // The shown section of the mandelbrot-fractal: static const double MIN_X = -2.5, MAX_X = 1.5; static const double MIN_Y = -1.5, MAX_Y = 1.5; static const int NORM_LIMIT = 1; // Use this "mapping" to store floats in ints: static const int SCALE = 1024; //- // Mapped configuration: static const int MAPPED_MIN_X = int( MIN_X * SCALE ); static const int MAPPED_MAX_X = int( MAX_X * SCALE ); static const int MAPPED_MIN_Y = int( MIN_Y * SCALE ); static const int MAPPED_MAX_Y = int( MAX_Y * SCALE ); static const int MAPPED_RANGE_X = MAPPED_MAX_X - MAPPED_MIN_X; static const int MAPPED_RANGE_Y = MAPPED_MAX_Y - MAPPED_MIN_Y; static const int MAPPED_SIZE_X = CONFIG_SIZE_X - 1; static const int MAPPED_SIZE_Y = CONFIG_SIZE_Y - 1; static const int MAPPED_ITERATIONS = CONFIG_DEPTH - 1; static const int MAPPED_NORM_LIMIT = NORM_LIMIT * SCALE; //- // The calculation: template< int X, int Y, int I = 0 > class Value { enum { z_real = Value< X, Y, I - 1 >::real, z_imag = Value< X, Y, I - 1 >::imag, c_real = MAPPED_RANGE_X * X / MAPPED_SIZE_X + MAPPED_MIN_X, c_imag = MAPPED_RANGE_Y * Y / MAPPED_SIZE_Y + MAPPED_MIN_Y, }; public: enum { // z' = z^2 + c real = ( z_real * z_real - z_imag * z_imag ) / SCALE + c_real, imag = 2 * z_real * z_imag / SCALE + c_imag, RET = ( ( real * real + imag * imag > MAPPED_NORM_LIMIT ) ? I : ( Value< X, Y, I + 1 >::RET ) ), }; }; template< int X, int Y > struct Value< X, Y, -1 > { enum { real = 0, imag = 0, }; }; template< int X, int Y > struct Value< X, Y, MAPPED_ITERATIONS > { enum { RET = -1, }; }; //- // The loop: template< int X = 0, int Y = 0 > class Loop { enum { value = Value< X, Y >::RET, }; public: static inline void f() { cout << ( ( value == -1 ) ? ' ' : char( 'a' + value ) ); Loop< X + 1, Y >::f(); } }; template< int Y > struct Loop< CONFIG_SIZE_X, Y > { static inline void f() { cout << '\n'; Loop< 0, Y + 1 >::f(); } }; template<> struct Loop< 0, CONFIG_SIZE_Y > { static inline void f() {} }; //- // Main: int main() { Loop<>::f(); } In the class Value, you might want to replace the enum-blocks by single enums to
Re: [boost] Re: Hello MPL world!
"Yitzhak Sapir" <[EMAIL PROTECTED]> writes: > The original version I suggested used fold, and for that, you do > need to use if_ since you need to determine whether to call > Prev::eval(). I didn't post my implementation since it took me > quite a while to get it working with VC6.5 and I thought only the > general concepts were necessary, not a full blown example. > In any > case, I think just using if_ and type traits lacks the "small rush > of excitement when you see it work." Yeah, it doesn't do very well in that department. > Regarding the "much more code," metaprogramming is used to produce a > lot of inline code in Blitz style templates. This is considered a > type of optimization, mainly in speed. If there weren't a > cout.write, I think my example would work faster than the equivalent > of using streaming operators <<. Dave's mention of efficiency was the weakest part of the argument, but significant nonetheless. > As for usefulness, I agree that the next thought after the rush of > excitement, is "so what?" I could argue that doing for_each on the > vector_c is not different than doing for_each on a compile time > vector of types. In fact, the functor receives a type, not a > character. Yep. I'm nervous about showing iteration and sequences in a this example, though. There's nothing that sophisticated going on in "hello, world." > Generation of long sequences of code is one use of metaprogramming. > A vector of pairs, might be used to implement read serialization of > a discriminated union. This is much more useful, whether for a > library author or not, but much more complex for a beginning example > to understand: ... Sure, it's comparitively easy to come up with useful examples that are more complicated. Incidentally, yours needs some tweaks for generality. The main reason is that for_each tries to value-initialize an instance of each of the types it processes and passes that to the function object. If the type isn't default-constructible, it won't compile. I'm not sure that preserving this property is worthwhile. Opinions, Aleksey? typedef list< pair, int> , pair, double> , pair, string> > typelist; int discriminator; stream >> discriminator; variant::type> v; for_each(serialize_if_appropriate(discriminator, stream, v)); with the following definition: struct serialize_if_appropriate { public: ... template void operator()(W&) const { typedef W::type T; // <-- if (T::first::value == discriminator) { T::second::type t; stream >> t; v = t; } } private: istream& stream; int discriminator; variant v; }; -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Metaprogramming: Using static const or enum?
Hi. BOOST_STATIC_CONST is defined in Boost.Config as: # ifdef BOOST_NO_INCLASS_MEMBER_INITIALIZATION # define BOOST_STATIC_CONSTANT(type, assignment) enum { assignment } # else # define BOOST_STATIC_CONSTANT(type, assignment) static const type assignment # endif Thus, it prefers static const, if it's possible to initialise it in-class, on the given compiler, as allowed in the standard. However, "C++ Templates: The Complete Guide" says about the difference between the two (p. 304): --- Start quote --- Static constant members are lvalues. So, if you have a declaration such as void foo(int const&); and you pass it the result of a metaprogram foo(Pow3<7>::result); a compiler must pass the address of Pow3<7>::result, which forces the compiler to instantiate and allocate the definition for the static member. As a result, the computation is no longer limited to a pure "compile-time" effect. Enumerations aren't lvalues (that is, they don't have an address). So when you pass them "by reference," no static memory is used. It's almost exactly as if you passed the computed value as a literal. These considerations motivate us to use enumeration values in all metaprograms throughout this book. --- End quote --- I like static const, as I think it conveys more succinctly what it's about, and the enum appears more like a hack (for compilers not handling static const in-class initialisation). However, if this means it may need an out-of-class definition, as well, perhaps this could need to be reconsidered? The point is also confirmed by the following test (on Intel C++, which uses static const): struct Test { enum { value=1 }; // Ok // BOOST_STATIC_CONSTANT(int, value=1); // Gives link-error }; void f(const int &) { } int main() { f(Test::value); } If pass by value is used in f(), it works, of course. So maybe pass by const reference for integral constants typically isn't used, so that this isn't a problem? Regards, Terje ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
RE: [boost] Re: Hello MPL world!
> -Original Message- > From: David B. Held [mailto:[EMAIL PROTECTED]] > Sent: Monday, January 06, 2003 8:14 PM > To: [EMAIL PROTECTED] > Subject: [boost] Re: Hello MPL world! > > While this is a cute idea, my first impression would be: "Uh...is this > really something I could use in my own code?" On the other hand, > I seem to use compile-time if more than anything else, even in "user > code". I suspect that most people will use mpl::if_ and type traits > more than anything else, so I think Dave's original example with > is_pointer<> would connect with the most programmers. On the > other hand, I suspect that library authors are more likely to use the > type containers and algorithms, so an example illustrating those might > be more appropriate for them. So I guess it depends on the > intended audience. > P.S. Outputting "Hello, world" in a way that generates significantly > more code than the run-time version is probably not a good way to > endear users to metaprogramming. ;> The original version I suggested used fold, and for that, you do need to use if_ since you need to determine whether to call Prev::eval(). I didn't post my implementation since it took me quite a while to get it working with VC6.5 and I thought only the general concepts were necessary, not a full blown example. In any case, I think just using if_ and type traits lacks the "small rush of excitement when you see it work." Regarding the "much more code," metaprogramming is used to produce a lot of inline code in Blitz style templates. This is considered a type of optimization, mainly in speed. If there weren't a cout.write, I think my example would work faster than the equivalent of using streaming operators <<. As for usefulness, I agree that the next thought after the rush of excitement, is "so what?" I could argue that doing for_each on the vector_c is not different than doing for_each on a compile time vector of types. In fact, the functor receives a type, not a character. Generation of long sequences of code is one use of metaprogramming. A vector of pairs, might be used to implement read serialization of a discriminated union. This is much more useful, whether for a library author or not, but much more complex for a beginning example to understand: list< pair, int>, pair, double>, pair, string> > int discriminator; stream >> discriminator; variant::type> v; for_each(serialize_if_appropriate(discriminator, stream, v)); with the following definition: struct serialize_if_appropriate { public: ... template void operator()(T&) const { if (T::first::value == discriminator) { T::second::type t; stream >> t; v = t; } } private: istream& stream; int discriminator; variant v; }; ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Incorrect extensions for cygwin gcc builds
Pavol Droba <[EMAIL PROTECTED]> writes: > Hi, > > I have encoutered a problem when building under win2k with cygwin gcc 3.2. > > Boost.Build select an extension for binary files according to OS platform. > So for the Windows paltform it selects .lib for library files and .obj for object >files. > > However cygwin is using unix-like .a for libs. When I have compiled regex library, > I got libboost_regex.lib as an output, and cygwin ld did not recognized it. > I had to build regex with sSUFLIB=.a > > Is this a feature or a bug? A known bug. We'll fix it for v2. The architecture of v1 doesn't make it easy. -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
RE: [boost] UTF library available for review
I am even less informed, but I can see even without the documentation that those (poor unfortunates) having to deal with these problems badly need such libraries. Documentation and examples (including simple ones for those who don't yet know if they need this stuff) are of course vital. Paul Paul A Bristow, Prizet Farmhouse, Kendal, Cumbria, LA8 8AB UK +44 1539 561830 Mobile +44 7714 33 02 04 Mobile mailto:[EMAIL PROTECTED] mailto:[EMAIL PROTECTED] > -Original Message- > From: [EMAIL PROTECTED] > [mailto:[EMAIL PROTECTED]]On Behalf Of William E. Kempf > Sent: Monday, January 06, 2003 3:43 PM > To: Boost mailing list > Subject: Re: [boost] UTF library available for review > > > > From: Alberto Barbati <[EMAIL PROTECTED]> > > Hi Boosters, > > > > I have put in the Boost file section the first version of my UTF > > library. You can find it here: > > > > http://groups.yahoo.com/group/boost/files/utf/ > > > > A couple of months ago, I posted a message to check if there was > > interest in such a library and I got just one answer from Vladimir Prus > > (hi, Vladimir!). I hope that in front of a full-blown and working > > library I might get more attention. > > Well, you have my attention, but this stuff is outside of my > expertise, so I've not spoken up previously. I definately want a > library that does this sort of stuff, I just can't comment on the > design or implementation since I don't have the expertise here. But > don't feel frustrated from a lack of interest! Keep working on this, please. > > > > William E. Kempf > [EMAIL PROTECTED] > > ___ > Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost > ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Incorrect extensions for cygwin gcc builds
Hi, I have encoutered a problem when building under win2k with cygwin gcc 3.2. Boost.Build select an extension for binary files according to OS platform. So for the Windows paltform it selects .lib for library files and .obj for object files. However cygwin is using unix-like .a for libs. When I have compiled regex library, I got libboost_regex.lib as an output, and cygwin ld did not recognized it. I had to build regex with sSUFLIB=.a Is this a feature or a bug? Pavol ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost