[boost] Re: Any interest in a stats class
Somewhere in the E.U., le 25/02/2003 Bonjour In article [EMAIL PROTECTED], Jason D Schmidt [EMAIL PROTECTED] wrote: I know this is well after the discussion on the stats class has ended, but I think I have a good idea here. Scott Kirkwood proposed a class that behaves something like this: stats myStats; for (int i = 0; i 100; ++i) { myStats.add(i); } cout Average: myStats.getAverage() \n; cout Max: myStats.getMax() \n; cout Standard deviation: myStats.getStd() \n; In one of my classes in grad school, I found it quite useful and effecient to do statistics on the fly like this, so this stats class interests me. Anyway, Scott has already alluded to the point I'm about to make. I think it's important and useful for this stats class to integrate with the STL well. This example code was inspired by the PointAverage example from Effective STL p. 161: // this class reports statistics template typename value_type class stats { public: stats(const size_t n, const value_type sum, const value_type sum_sqr): m_n(n), m_sum(sum), m_sum_sqr(sum_sqr) {} value_type sum() const { return m_sum; } value_type mean() const { return m_sum/m_n; } value_type var() const { return m_sum_sqr - m_sum*m_sum/m_n; } value_type delta() const // aka, standard dev { return sqrt(var() / (m_n-1)); } private: value_type m_n, m_sum, m_sum_sqr; }; // this class accumulates results that can be used to // compute meaningful statistics template typename value_type class stats_accum: public std::unary_functionconst value_type, void { public: stats_accum(): n(0), sum(0), sum_sqr(0) {} // use this to operate on each value in a range void operator()(argument_type x) { ++n; sum += x; sum_sqr += x*x; } statsvalue_type result() const { return statsvalue_type(n, sum, sum_sqr); } private: size_t n; value_type sum, sum_sqr; }; int main(int argc, char *argv[]) { typedef float value_type; const size_t n(10); float f[n] = {0, 2, 3, 4, 5, 6, 7, 8, 9, 8}; // accumulate stats over a range of iterators my_stats = std::for_each(f, f+n, stats_accumvalue_type()).result(); m = my_stats.mean(); m = my_stats.delta(); // aka, standard deviation return 0; } In this example, what is the advantage over filling a valarray and using a stat class which uses that as a constructor argument? You would get sum for free, and hopefully (yeah, right...) operations on valarrays could be hardware accelerated, whereas direct coding might not be. That is, at least, one of the ideas I encoded in the file I just uploaded on Yahoo (statistical_descriptor.h.gz). This seems to be pretty similar to what Scott has proposed, and it turns out that this method is very fast. In my tests it has been nearly as fast as if we got rid of the classes and used a hand-written loop. It's certainly much faster than storing the data in a std::valarray object, and using functions that calculate the mean standard deviation separately. This is just a neat application of Scott's idea. I think this stats could be pretty useful for scientific computing, and in this example it works very well with the STL and has great performance. I'd like to see more code like this in Boost, but most of my work is numerical. Take my opinion or leave it. Jason Schmidt I agree with you that if the cardinal of the population is not known then your approach is still useable whereas mine is not realistic. But in that case you might have to reset the class periodically (if you are doing statistics on the fly and want to just test a sample). Your method might also be usefull when the amount of data is too big to be properly placed at once in memory. So, we need classes for sequences, either in memory or via some iterator, one dimensional or multi dimensional, and we also need classes for (experimental) densities. We also need generators for the usual densities. Since we aready have implementations of random, we should hitch our code to it. This also ties in with the request for special functions such as erf. Since we now have uBlas, we can also try to aim for more complex statistical constructs such as Gaussian Mixture Models, though to train the Neural Networks which produce them, we also need good optimisation code, which we lack completely at present (and which in turn usually need some LA code). Anybody want to try to get the COOOL (http://coool.mines.edu/) people aboard Boost? A bientot Hubert Holin ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
RE: [boost] [random] Minor problem with lognormal_distribution
From: Michael Stevens [mailto:[EMAIL PROTECTED] Correction required for boost/random/lognormal_distribution. Fixed, thanks! Bjorn Karlsson ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Thread-Local Storage (TLS) and templates
Ken Hagan wrote: Alexander Terekhov wrote: Uhmm. In return, I venture to suggest that MS-TLS can and shall be characterized as ``utterly busted.'' Fine, but the OP asked about existing practice and the bugs don't change the fact that k can be a template parameter if the compiler is willing to thunk its way around the TLS implementation under the hood. Okay. Let's go back. The OP wrote: :extern int k; :template int* V class C { ... }; :Ck ck; : :But what if k is designated thread-local? The actual variable :referred to by the address of k will differ among threads. :(I'm assuming an implementation where k results in a link-time :constant whether k is an ordinary or thread-local variable.) : :In favor of allowing k to be thread-local: :Converting a multi-process program to multi-thread is simple. ^ Huh? :Just declare per-process variables to be thread local. Template and :other usage of such variables remains separate per thread as it was :per process. per process aside, this won't necessarily make the template *thread- safe*. OTOH, it might actually break a fully thread-safe template that was written under the assumption that k IS a global variable. I have yet to see a compelling reason to embrace the MS ``TLS-template'' innovation. regards, alexander. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Thread-Local Storage (TLS) and templates
Ken Hagan [EMAIL PROTECTED] writes: | Alexander Terekhov wrote: | | Uhmm. In return, I venture to suggest that MS-TLS can and shall be | characterized as ``utterly busted.'' | | Fine, but the OP asked about existing practice and the bugs | don't change the fact that k can be a template parameter | if the compiler is willing to thunk its way around the TLS | implementation under the hood. I think extreme caution should be exercised with that line of reasoning. There is what that particular implementation does with its extensions and there are various mulit-threading models, what the standard language is defined to be and ways to extend it to support multi-thread and thread local storage. In that regard, bugs in either the design or the implementation don't count as arguments for not being cautious about what that implementation does. That may sound obvious but I feel that need to be stated. -- Gaby ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] possible addition to operators library
Hi, While making myself an interim shared_resource class, I found myself reusing the shared_ptr safe-bool conversion, and thought that really the idiom ought to go into the operators library. I am unsure about the name, but for now bool_testable seems to match the naming style used by the rest of operators, and be reasonably clear about its intent. Any suggestions gratefully received Essentially you supply a operator! and it supplies an unspecified-bool-type conversion operator. //Key //T: primary operand type //t: values of type T // TemplateSupplied Operations Requirements // // bool_testableT operator unspecified-bool-type() !t template class T, class B = ::boost::detail::empty_base struct bool_testable : B { private: void safe_bool_conversion() const { } public: typedef void (bool_testableT, B::*unspecified_bool_type)() const; operator unspecified_bool_type() const { return !static_castconst T(*this) ? 0 : bool_testableT, B::safe_bool_conversion; } }; Any problems with this? Sam ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] regular expression standardisation proposal
Guys, In case any of you don't have enough to do (!) I've placed the next draft of my regular expression standardisation proposal at http://www.regex.fsnet.co.uk/n1429dft.htm, as ever comments, nit picks etc are very welcome (the deadline for this revision is Monday the 3rd March). For those of you that volunteered to look at this last week - I have two apologies - first for this being so late, and secondly for loosing your email addresses - both the result of a rather badly timed hard drive death. If you can get back in touch I would appreciate it. Many thanks, John Maddock ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] [MPL] Doc nitpick
Hi, There is a reference to the 1.29.0 distribution in boost/libs/mpl/doc/index.html#source Shouldn't this be removed before 1.30 is branched? Thomas -- Dipl.-Ing. Thomas Witt Institut fuer Verkehrswesen, Eisenbahnbau und -betrieb, Universitaet Hannover voice: +49(0) 511 762 - 4273, fax: +49(0) 511 762-3001 http://www.ive.uni-hannover.de ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: More metaprogramming problems with MSVC7.0
Andreas Huber wrote: P.S. Is it a good idea to use mpl::aux::msvc_eti_base on all platforms (on conforming compilers I'd expect it to call mpl::identity) or should I #ifdef my way around it? Yep, it's intentionally written in the way so that you don't have to #ifdef in your code. Aleksey ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: Re: partial proposal
Sorry for confusion, the reply below obviously belongs to a different thread. Aleksey Gurtovoy wrote: Andreas Huber wrote: P.S. Is it a good idea to use mpl::aux::msvc_eti_base on all platforms (on conforming compilers I'd expect it to call mpl::identity) or should I #ifdef my way around it? Yep, it's intentionally written in the way so that you don't have to #ifdef in your code. Aleksey ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: Thread-Local Storage (TLS) and templates
Gabriel Dos Reis [EMAIL PROTECTED] writes: Ken Hagan [EMAIL PROTECTED] writes: | Gabriel Dos Reis wrote: | | This analgoy does not cut it: You don't have a function fk by | thread. You have a -single- function designator. And the return | value depends on the calling thread. | | Whereas with a TLS variable you have a single variable name and | the value of that variable when referenced at run-time depends | on the calling thread. Untrue. See Dave's analogy with data member. Hm? I think you'd better explain, Gaby, because up 'till now I'm pretty much in agreement with Ken. I think his analogy to function is actually better than mine. -- Dave Abrahams Boost Consulting www.boost-consulting.com ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] [random] Minor problem with lognormal_distribution
Michael Stevens [EMAIL PROTECTED] writes: Dear Boosters, This is just a quick reminder of regression before boost_1_30_0 gets released. Without CVS access I can fix it myself and Jens seems to be offline at the moment. It would be great if someone could step in and make a simple correction. The regression is the the return values of the mean and sigma values of boost::random::lognormal_distribution. Correction required for boost/random/lognormal_distribution. hpp line 67-68 RealType mean() const { return _mean; } RealType sigma() const { return _sigma; } should read. RealType mean() const { return _mean; } RealType sigma() const { return _sigma; } The correction makes the return values identical with those of other real distributions, cf. normal_distribution line 62 The problem can simply be tested by instantiating the template thus template boost::normal_distributionboost::mt19937, float; It should be noted that the problem is NOT picked up by regression tests in random_test.cpp. The current test procedure void instantiate_dist(const char * name, const Dist dist) uses a reference to a constant distribution. It therefore fails to pickup on the return of non constant member reference. Michael, Could you please suggest a patch for the regression tests which will detect this problem? It's always better to get the test to fail first before we check in any fixes. Thanks, Dave -- Dave Abrahams Boost Consulting www.boost-consulting.com ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Thread-Local Storage (TLS) and templates
Alexander Terekhov [EMAIL PROTECTED] writes: I have yet to see a compelling reason to embrace the MS ``TLS-template'' innovation. Ah. Well, that's an entirely different matter ;-). I was going on the assumption that there was a reasonable argument for the existence of the feature, and just arguing that it is possible. I have no position on whether it's desirable. -- Dave Abrahams Boost Consulting www.boost-consulting.com ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] possible addition to operators library
Sam Partington [EMAIL PROTECTED] writes: Hi, While making myself an interim shared_resource class, I found myself reusing the shared_ptr safe-bool conversion, and thought that really the idiom ought to go into the operators library. I am unsure about the name, but for now bool_testable seems to match the naming style used by the rest of operators, and be reasonably clear about its intent. Any suggestions gratefully received Essentially you supply a operator! and it supplies an unspecified-bool-type conversion operator. //Key //T: primary operand type //t: values of type T // TemplateSupplied Operations Requirements // // bool_testableT operator unspecified-bool-type() !t template class T, class B = ::boost::detail::empty_base struct bool_testable : B { private: void safe_bool_conversion() const { } public: typedef void (bool_testableT, B::*unspecified_bool_type)() const; operator unspecified_bool_type() const { return !static_castconst T(*this) ? 0 : bool_testableT, B::safe_bool_conversion; } }; Any problems with this? None that I can see. If you want to submit it, make a patch that includes changes to the tests and the documentation, and post it here *as an attachment* so that line-wrapping doesn't wreck it ;-) -- Dave Abrahams Boost Consulting www.boost-consulting.com ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] checked_delete.hpp fix
Daniel Frey wrote: Hi, I came across the following problem: When I have a class X which lives in a namespace where there's a function 'checked_delete' declared that can take a X*, smart_ptr (and probably others) that use checked_deleter (note the 'r'!) cannot call checked_delete. It's ambiguous due to argument dependent lookup. Fixed, thanks. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] [MPL] Doc nitpick
Thomas Witt [EMAIL PROTECTED] writes: Hi, There is a reference to the 1.29.0 distribution in boost/libs/mpl/doc/index.html#source Shouldn't this be removed before 1.30 is branched? I think Aleksey is planning to check in completely new docs before 1.30 goes out. -- Dave Abrahams Boost Consulting www.boost-consulting.com ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Question about boost::thread::yield for Win32
Is yield intended to always yield to another thread if one can run? Because the code for yield is void thread::yield() { #if defined(BOOST_HAS_WINTHREADS) Sleep(0); #elif defined(BOOST_HAS_PTHREADS) # if defined(BOOST_HAS_SCHED_YIELD) int res = 0; res = sched_yield(); assert(res == 0); # elif defined(BOOST_HAS_PTHREAD_YIELD) int res = 0; res = pthread_yield(); assert(res == 0); # else xtime xt; xtime_get(xt, TIME_UTC); sleep(xt); # endif #elif defined(BOOST_HAS_MPTASKS) MPYield(); #endif } Taken from the main CVS. Sleep(0) on Win32 will only yield to another thread of equal or higher priority, not to lower priority threads. In boost::detail::lightweight_mutex::scoped_lock, it is mentioned that Sleep(1) will get around. Is the behaviour of Sleep(0) the intended use of yield? explicit scoped_lock(lightweight_mutex m): m_(m) { while( InterlockedExchange(m_.l_, 1) ) { // Note: changed to Sleep(1) from Sleep(0). // According to MSDN, Sleep(0) will never yield // to a lower-priority thread, whereas Sleep(1) // will. Performance seems not to be affected. Sleep(1); } } (I don't actually use yield yet, so currently have no preference for either, but just wondered what the intended use of yield was) Thanks Russell ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] possible addition to operators library
Essentially you supply a operator! and it supplies an unspecified-bool-type conversion operator. Nice idea! I already had something similar in mind, but you managed to make it really generic. //Key //T: primary operand type //t: values of type T // TemplateSupplied Operations Requirements // // bool_testableT operator unspecified-bool-type() !t template class T, class B = ::boost::detail::empty_base struct bool_testable : B { private: void safe_bool_conversion() const { } public: typedef void (bool_testableT, B::*unspecified_bool_type)() const; operator unspecified_bool_type() const { return !static_castconst T(*this) ? 0 : bool_testableT, B::safe_bool_conversion; } The only problem I see is that an instance of safe_bool_conversion is created which is not really needed. I suggest to rely on the operator! provided by T: template class T, class B = ::boost::detail::empty_base struct bool_testable : B { private: typedef bool (T::*unspecified_bool_type)() const; public: operator unspecified_bool_type() const { return !static_cast const T ( *this ) ? 0 : T::operator!(); } }; Regards, Daniel -- Daniel Frey aixigo AG - financial training, research and technology Schloß-Rahe-Straße 15, 52072 Aachen, Germany fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99 eMail: [EMAIL PROTECTED], web: http://www.aixigo.de ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: Re: Re: Re: Re: partial proposal
Peter Dimov [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] David Abrahams wrote: Fernando Cacciola [EMAIL PROTECTED] writes: No, right're right :-) Is perfectly possible to simply discard it, though to me it looks kind of akward in anything but deeply low-level code. Anyway, doesn't this require a definition of placement operator new for each T? I don't know, possibly so. It's been so long I've forgotten more than I ever knew ;-) It only requires templateclass T void * operator new(size_t n, optionalT t); I think. One problem is that there is no reliable way to prevent optionalX opt; new(opt) Y; // oops since the type being created is not communicated to operator new, only its size is. Yes, that's why I was thinking of something that were overloaded for T rather than for optionalT. Anyway, there are still problems with this: operator new is called _before_ the T is constructed, so there won't be a way, AFAICT, to properly set the initialized flag ('cause if T ctor throws, placement new won't be aware of it) -- Fernando Cacciola ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] checked_delete.hpp fix
Beman Dawes [EMAIL PROTECTED] writes: Go ahead and make the change, unless someone voices an objection. I'm wondering how may other places we have similar problems? Now you know why I've been making such a stink about insidious ADL! Is there any programatic way to detect them? I've been trying to get compiler vendors to add a warning for names to which ADL applies but which are found in the local namespace. This, at least, would give us a way to detect likely candidates. No takers yet :(. I wonder if a tool like GCC_XML could be of help? -- Dave Abrahams Boost Consulting www.boost-consulting.com ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: Re: Re: Re: partial proposal
Philippe A. Bouchard wrote: [...] It's true. Imagine we have some partial specialization of arraybool, size_t: template unsigned int I struct arraybool, I { char value_[I 3]; // Read-only version: bool operator [] (unsigned int a_index) const { return value_[a_index 3] (1u (a_index % 8)); } }; Please excuse me for writing to way, I am taking for granted a char is 8 bits long. I do not wish to bypass any portability rules... Philippe A. Bouchard ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: Re: Re: Re: Re: Re: partial proposal
Philippe A. Bouchard [EMAIL PROTECTED] writes: David Abrahams wrote: [...] What will happen to a normal type then? What is a normal type? Any type besides optionalT. { T storage = T(x, y, z); // throws // storage.~T() destroys non-existent T Storage never gets constructed if T(x,y,z) throws, so it is also never destroyed. It is never destroyed, because the program counter returns from the function before it reaches the object's destruction? And more-importantly, before it reaches the object's construction. If so, the same will happen to aligned_storageT::type if it trows an exception? Once again, the case was: { aligned_storageT::type storage; new ((void*)storage) T(x, y, z); // throws // ~aligned_storageT() destroys non-existent T } The question is not what happens if aligned_storageT::type throws. It will never throw, since it is POD. The question is what happens if T throws. If, as you say, you don't know much about EH, please do a little bit of research about how it works before you argue with me on this one :-) -- Dave Abrahams Boost Consulting www.boost-consulting.com ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] checked_delete.hpp fix
At 08:34 AM 2/25/2003, David Abrahams wrote: Beman Dawes [EMAIL PROTECTED] writes: Go ahead and make the change, unless someone voices an objection. I'm wondering how may other places we have similar problems? Now you know why I've been making such a stink about insidious ADL! Is there any programatic way to detect them? I've been trying to get compiler vendors to add a warning for names to which ADL applies but which are found in the local namespace. This, at least, would give us a way to detect likely candidates. No takers yet :(. Hum, it looks like Microsoft took you up on it. See the shared_ptr_test warning on the VC++ 7.1 beta regression test. --Beman ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
RE: [boost] regular expression standardisation proposal
A Nit Pick : The column headings in the first table are displaced to the left ( see ECMAScript - comparing ECMA and POSIX regular expressions ) Keith Burton [EMAIL PROTECTED] wrote: Guys, In case any of you don't have enough to do (!) I've placed the next draft of my regular expression standardisation proposal at http://www.regex.fsnet.co.uk/n1429dft.htm, as ever comments, nit picks etc are very welcome (the deadline for this revision is Monday the 3rd March). For those of you that volunteered to look at this last week - I have two apologies - first for this being so late, and secondly for loosing your email addresses - both the result of a rather badly timed hard drive death. If you can get back in touch I would appreciate it. Many thanks, John Maddock ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: Re: Re: Re: Re: Re: Re: partial proposal
David Abrahams wrote: [...] Once again, the case was: { aligned_storageT::type storage; new ((void*)storage) T(x, y, z); // throws // ~aligned_storageT() destroys non-existent T } The question is not what happens if aligned_storageT::type throws. It will never throw, since it is POD. The question is what happens if T throws. If, as you say, you don't know much about EH, please do a little bit of research about how it works before you argue with me on this one :-) Sorry about it. I'm going back into my books... Philippe A. Bouchard ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] possible addition to operators library
Daniel Frey wrote: The only problem I see is that an instance of safe_bool_conversion is created which is not really needed. I suggest to rely on the operator! provided by T: template class T, class B = ::boost::detail::empty_base struct bool_testable : B { private: typedef bool (T::*unspecified_bool_type)() const; public: operator unspecified_bool_type() const { return !static_cast const T ( *this ) ? 0 : T::operator!(); Should be ...operator!; without the braces, sorry. } }; It has another advantage: It makes the compiler complain if the user didn't provided an operator! with the right signature. This is - in this case and IMHO - a good thing. Regards, Daniel -- Daniel Frey aixigo AG - financial training, research and technology Schloß-Rahe-Straße 15, 52072 Aachen, Germany fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99 eMail: [EMAIL PROTECTED], web: http://www.aixigo.de ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] possible addition to operators library
Daniel Frey wrote: Nice idea! I already had something similar in mind, but you managed to make it really generic. Not really, all I've done is to borrow the code from shared_ptr, and to put into a shape like one of the existing unary operator helpers in operator.hpp. Thanks anyway though :-) The only problem I see is that an instance of safe_bool_conversion is created which is not really needed. I suggest to rely on the operator! provided by T: template class T, class B = ::boost::detail::empty_base struct bool_testable : B { private: typedef bool (T::*unspecified_bool_type)() const; public: operator unspecified_bool_type() const { return !static_cast const T ( *this ) ? 0 : T::operator!(); } }; I thought of this too, but this limits the user to using a member based operator!. So I couldn't do this : class A : public boost::bool_testableA { public: int get(); }; bool operator!(const A a) { return a.get() == 0; } Of course I've never actually wanted to do that, so its maybe not a problem. After all the conversion operator itself has to be a member, so it probably isn't much of a restriction at all. Then again, how much does the safe_bool_conversion function cost? Sam ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] checked_delete.hpp fix
Beman Dawes wrote: At 08:34 AM 2/25/2003, David Abrahams wrote: Beman Dawes [EMAIL PROTECTED] writes: Go ahead and make the change, unless someone voices an objection. I'm wondering how may other places we have similar problems? Now you know why I've been making such a stink about insidious ADL! I told you so! ;-) Is there any programatic way to detect them? I've been trying to get compiler vendors to add a warning for names to which ADL applies but which are found in the local namespace. This, at least, would give us a way to detect likely candidates. No takers yet :(. Hum, it looks like Microsoft took you up on it. See the shared_ptr_test warning on the VC++ 7.1 beta regression test. No, C4675 is the opposite of what Dave wants. Earlier MSVC didn't support ADL at all, and MSVC 7.1 is now issuing the warning for every place ADL kicks in since this may alter the behavior of existing code. Dave wants a warning when ADL could have kicked in but didn't. Sounds like a neat plan to solicit _many_ user complaints. ;-) ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] checked_delete.hpp fix
Daniel Frey wrote: Any reason why you went for 'boost::' instead of '::boost::' for the prefix? IMO only the latter expresses exactly what we want or do we rely on user to never create sub-namespaces called 'boost'? Although this is not very likely, we shouldn't place any restrictions on users that are not needed. What we want is to disable ADL, any qualification does that. There's really no practical difference between boost:: and ::boost:: in this case; the user is not expected to just drop identifiers into boost and expect things to work. They won't. We aren't required to document all identifiers in boost, so we reserve the right to not compile if there is a collision. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] possible addition to operators library
Sam Partington [EMAIL PROTECTED] writes: I thought of this too, but this limits the user to using a member based operator!. So I couldn't do this : class A : public boost::bool_testableA { public: int get(); }; bool operator!(const A a) { return a.get() == 0; } Of course I've never actually wanted to do that, so its maybe not a problem. After all the conversion operator itself has to be a member, so it probably isn't much of a restriction at all. Ahem. The operators library is *all about* defining free function operators. I don't think you should introduce a dependence on being a member function. Then again, how much does the safe_bool_conversion function cost? More than I'd like. I'd prefer to use a single data member pointer, since it's likely to be more efficient. struct safe_bool { #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS private: template class T, class B friend class bool_testable; #endif int x; typedef int safe_bool::*type; }; -- Dave Abrahams Boost Consulting www.boost-consulting.com ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] checked_delete.hpp fix
Beman Dawes [EMAIL PROTECTED] writes: At 08:34 AM 2/25/2003, David Abrahams wrote: Beman Dawes [EMAIL PROTECTED] writes: Go ahead and make the change, unless someone voices an objection. I'm wondering how may other places we have similar problems? Now you know why I've been making such a stink about insidious ADL! Is there any programatic way to detect them? I've been trying to get compiler vendors to add a warning for names to which ADL applies but which are found in the local namespace. This, at least, would give us a way to detect likely candidates. No takers yet :(. Hum, it looks like Microsoft took you up on it. Well, it was MS I was haranguing most-loudly about it. See the shared_ptr_test warning on the VC++ 7.1 beta regression test. I've seen that. It's a different warning IIUC. Doesn't it go off whether or not you find the overload in the same namespace the search started from? -- Dave Abrahams Boost Consulting www.boost-consulting.com ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] checked_delete.hpp fix
Peter Dimov [EMAIL PROTECTED] writes: Hum, it looks like Microsoft took you up on it. See the shared_ptr_test warning on the VC++ 7.1 beta regression test. No, C4675 is the opposite of what Dave wants. Earlier MSVC didn't support ADL at all, and MSVC 7.1 is now issuing the warning for every place ADL kicks in since this may alter the behavior of existing code. Dave wants a warning when ADL could have kicked in but didn't. Or rather, where it did kick in but it found nothing, so the fallback was the name in the local namespace. Sounds like a neat plan to solicit _many_ user complaints. ;-) No kidding! -- Dave Abrahams Boost Consulting www.boost-consulting.com ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: Re: Re: Re: Re: partial proposal
Fernando Cacciola wrote: [...] Yes, that's why I was thinking of something that were overloaded for T rather than for optionalT. Anyway, there are still problems with this: operator new is called _before_ the T is constructed, so there won't be a way, AFAICT, to properly set the initialized flag ('cause if T ctor throws, placement new won't be aware of it) It's a costs / benefits situation... I never thought exception handlings what that much of a problem AFAIK. Philippe A. Bouchard ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: Re: Thread-Local Storage (TLS) and templates
Edward Diener said: William E. Kempf wrote: You can clean up your own TLS index ( or indices ) in your DllMain routine when the seond parameter is DLL_PROCESS_DETACH, meaning that your process is being exited. AFAIK this is the standard way to do this. (Note: The issue is more with cleaning up TLS data then with cleaning up TLS indices/slots. So we're really talking about DLL_THREAD_DETACH here.) Then perhaps the weakness is not really with TLS on Windows but rather with limitations to actions one can perform at DLL_THREAD_DETACH time. No, the issue is that the only mechanism provided for TLS cleanup is to hook DllMain, or to explicitly clean up the data in the thread before it exits. The former is unusable in several cases, while the latter can only be done if you control the creation of the thread. Would you describe these issues specifically ? I did, below. This is the MS way, not the standard way. This referring to what above ? Using DllMain to cleanup TLS data. And it's full of issues. You are quite limited in what you can safely do within DllMain. Any calls to synchronization routines is likely to deadlock the entire process. I agree that this is so. You can't sit and wait until some other thread has done something, via a Windows synchronization primitive, when you are processing DLL_THREAD_DETACH. What is the situation where this is necessary ? There are numerous situations where this is necessary. For example, the cleanup mechanism in both Boost.Threads and pthreads-win32 use mutexes, which can potentially cause *process* deadlock. If the TLS data is shared across threads, or references data shared across threads, or simply calls a routine that does synchronization in the cleanup, all of which are not that uncommon, and some of which are hard for the programmer to avoid (do you know what routines do synchronization internally?), you risk deadlock. As is calling any routines that load/unload a DLL. The workaround is not to dynamically load/unload a DLL as part of thread processing. Do you know what routines do this as part of their implementation? To quote the MSDN Calling imported functions other than those located in Kernel32.dll may result in problems that are difficult to diagnose. And since a very large number of Win32 API functions are imported... I think you see the issue. Yes, it is cleaner to do so when one only needs a DLL for a specific time but the overhead of statically linking a DLL into a process instead is minimal, although I agree that dynamic loading is often a cleaner design. I do agree with you that the inability to dynamically load and unload a DLL at DLL_THREAD_ATTACH/DLL_THREAD_DETACH is an unfortunate imposition and that this is poor design on MS's part. I am still not clear whay this is so and why this limitation exists on Windows. I honestly don't care. The only time I've ever found this design to be unusable is when dealing specifically with the cleanup of TLS data, which would be much better implemented as a registered cleanup routine in the first place. Fix this, and I don't care about this artifact of the DLL system on Win32 platforms. There's also the issue of forcing the use of a DLL with this scheme, which many users rightfully dislike (this is why there are so many thread creation routines on Windows). I could be mistaken but I believe that TLS works just as effectively in static LIBs as it does with DLLs. The difference is that one must do manual initialization routines and finalization routines of TLS data for different threads, as opposed to what one may do automatically using DLL_THREAD_ATTACH/DLL_THREAD_DETACH. But certainly one is not forced to use only DLLs or only static LIBs if the implementation supports both. Initialization isn't really an issue, as you can do lazy initialization (synchronization issues aside, as they are solvable). It's the finalization that's an issue, and it's resulted in the numerous thread creation routines and the rules for when to use which one. If you call any C RTL routines (which may allocate TLS) you can't call CreateThread, but must instead call _beginthread(ex). Likewise, if you call any MFC routines you can't call CreateThread or _beginthread(ex) but instead must call AfxBeginThread, lest you leak TLS data allocated by these routines. This is an issue for Boost.Threads, which has it's own thread creation routines, because I don't know how a user will use the thread. It's a problem for other libraries if they have thread creation routines, or have user registered callbacks executed by the threads created by the library. It's a problem if you want to make use of the built in Win32 thread pooling mechanisms, since those threads will be created using CreateThread. And so on. I won't be as critical as Alexander, but I will agree that the MS TLS implementation has serious design issues which need to be corrected. OK, this isn't the place to
Re: [boost] checked_delete.hpp fix
Daniel Frey wrote: I wasn't thinking of the user to drop things into boost, this is obvbiously not supported. I was thinking of this: namespace foo { namespace boost { // -- Is this allowed by boost? template typename T void checked_delete( T* ); } class A {}; } foo::A* bar = new foo::A(); ::boost::checked_deleter A ()( bar ); Your example works for me. Qualified identifiers such as boost::checked_delete disable ADL, and foo::boost::checked_delete isn't found. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] possible addition to operators library
Sam Partington wrote: I thought of this too, but this limits the user to using a member based operator!. So I couldn't do this : class A : public boost::bool_testableA { public: int get(); }; bool operator!(const A a) { return a.get() == 0; } Of course I've never actually wanted to do that, so its maybe not a problem. In fact this is what I want to prevent. Consider a global operator! with a template parameter: template typename T bool operator!( const T t ) { return t.get() == 0; } This may lead to accidents I tried to avoid. We now have to decide whether want to allow it or to prevent it. Sadly you cannot use T::~T :) Then again, how much does the safe_bool_conversion function cost? Not much. I think we should find an agreed on goal to achive, the implementation follows naturally. What do you (and others) think? Should we allow or prevent non-const-member-function-operator!-implementations? Regards, Daniel -- Daniel Frey aixigo AG - financial training, research and technology Schloß-Rahe-Straße 15, 52072 Aachen, Germany fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99 eMail: [EMAIL PROTECTED], web: http://www.aixigo.de ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] possible addition to operators library
I think I agree, we want to provide as little restrictions as possible. Also seems to me that anyone who declares a global template operator! deserves some problems! So, now with David's suggestion, I've attached what I propose. I've tested to a small extent on MSVC6 and gcc 2.95, which are all the compilers I have access to now. (First time I've used a patch file so apologies if I've messed it up) Sam PS Did anyone who uses OE-Quote notice what a mess it made of the wrapping, interpreting B:: as three seperate reply inserts? and so miss out the B, and substitute . ;-) Great program 99% of the time though. David Abrahams wrote: Sam Partington [EMAIL PROTECTED] writes: I thought of this too, but this limits the user to using a member based operator!. So I couldn't do this : class A : public boost::bool_testableA { public: int get(); }; bool operator!(const A a) { return a.get() == 0; } Of course I've never actually wanted to do that, so its maybe not a problem. After all the conversion operator itself has to be a member, so it probably isn't much of a restriction at all. Ahem. The operators library is *all about* defining free function operators. I don't think you should introduce a dependence on being a member function. Then again, how much does the safe_bool_conversion function cost? More than I'd like. I'd prefer to use a single data member pointer, since it's likely to be more efficient. struct safe_bool { #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS private: template class T, class B friend class bool_testable; #endif int x; typedef int safe_bool::*type; }; bool_testable.patch Description: Binary data ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] checked_delete.hpp fix
Peter Dimov wrote: Your example works for me. Qualified identifiers such as boost::checked_delete disable ADL, and foo::boost::checked_delete isn't found. I wasn't aware of this, so I assume that this is the standard's way of handling it and not just some compilers. Thanks. Regards, Daniel -- Daniel Frey aixigo AG - financial training, research and technology Schloß-Rahe-Straße 15, 52072 Aachen, Germany fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99 eMail: [EMAIL PROTECTED], web: http://www.aixigo.de ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] possible addition to operators library
Daniel Frey [EMAIL PROTECTED] writes: Sam Partington wrote: I thought of this too, but this limits the user to using a member based operator!. So I couldn't do this : class A : public boost::bool_testableA { public: int get(); }; bool operator!(const A a) { return a.get() == 0; } Of course I've never actually wanted to do that, so its maybe not a problem. In fact this is what I want to prevent. Consider a global operator! with a template parameter: template typename T bool operator!( const T t ) { return t.get() == 0; } I would probably never write that. This, however: template class T bool operator( foobarT const ); is just fine. This may lead to accidents I tried to avoid. We now have to decide whether want to allow I vote allow. it or to prevent it. Sadly you cannot use T::~T :) Then again, how much does the safe_bool_conversion function cost? Not much. Depends what you're measuring. Number of template instantiations? Compilation time? Link time? Executable image size? All of these may be affected. -- Dave Abrahams Boost Consulting www.boost-consulting.com ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Question about boost::thread::yield for Win32
William E. Kempf wrote: [...] explicit scoped_lock(lightweight_mutex m): m_(m) { while( InterlockedExchange(m_.l_, 1) ) { // Note: changed to Sleep(1) from Sleep(0). // According to MSDN, Sleep(0) will never yield // to a lower-priority thread, whereas Sleep(1) // will. Performance seems not to be affected. Sleep(1); } } (I don't actually use yield yet, so currently have no preference for either, but just wondered what the intended use of yield was) ^ Well, quoting Butenhof sched_yield() can be used to resolve some problems on a uniprocessor, though such problems can usually be solved more cleanly in other ways. Using sched_yield() will never solve a problem (unless the problem statement is the performance is too good) on a multiprocessor, and you should never use it there. http://groups.google.com/groups?selm=LiSt9.14%24jw2.278613%40news.cpqcorp.net (Subject: Re: relinquishing a time-slice) http://groups.google.com/groups?selm=rzdE7.1198%24RL6.17634%40news.cpqcorp.net (Subject: Re: Thread yield question (repost)) I'll look into this and fix it. Thanks. Other than breaking the yield() it won't fix anything, I'm afraid. regards, alexander. -- It's Unix if it has the x sound in its name - the Xbox must be Unix then. --from a discussion on slashdot.org ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] possible addition to operators library
Sam Partington [EMAIL PROTECTED] writes: I think I agree, we want to provide as little restrictions as possible. Also seems to me that anyone who declares a global template operator! deserves some problems! I don't know why you think so. So, now with David's suggestion, I've attached what I propose. I've tested to a small extent on MSVC6 and gcc 2.95, which are all the compilers I have access to now. (First time I've used a patch file so apologies if I've messed it up) It's very nice, but you left out the most-important parts: patches for the docs and testsuite. Sam PS Did anyone who uses OE-Quote notice what a mess it made of the wrapping, interpreting B:: as three seperate reply inserts? and so miss out the B, and substitute . ;-) Great program 99% of the time though. Yep. I went back to emacs, though. It's still better overall for my needs. -- Dave Abrahams Boost Consulting www.boost-consulting.com ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: smart_ptr vs smart_resource
From: Jason House [EMAIL PROTECTED] Well, being relatively a newbie at all this stuff, I have to admit that the initial discussion of performing a lock using a (smart) pointer, seemed odd to me. Someone later clarified that a smart pointer doesn't need to use * and - operators... something very non-pointer-like to me... * The one argument seems to be that the name will cause confusion * The other argument seems to be that anyone who uses it will already know what it means. (either the library writer who buries the definition deep inside... or those who should know resource management when they hear the term smart pointer) As a newbie, I lean towards the first argument. I want to learn about the boost libraries for future use, but I also feel that all coding resources should be as idiot proof as possible. The idea being that people will look at the library list and not realize that they should be using a specific library for a seemingly unrelated problem. This is an excellent point. One doesn't go looking for a class named smart_ptr or a library named Boost.SmartPointer when looking to manage the lifetime of some arbitrary resource. When one uses pointers, it makes sense. It is a shame for things to simply be the way that they are simply because they started out from a specific beginning... History always has a way of biting us. In this case, we are creating something brand new in Boost. There isn't a PBSP in boost. Therefore, if it is a manifestation of a SmartResource concept or is implemented in terms of a smart_resource class isn't as important as the recognition that it is a special case of the more abstract concept. As far as my true stance on naming, I'm torn. I think that the majority of the use really will be as as a pointer. It almost seems like there can be some kind of higher than smart pointer resource management feature... something that simply restricts/prevents copying/access, and can call a custom resource freeing routine... There can still be a smart_ptr class, even if there's a smart_resource class. Both may be separate manifestations, possibly sharing some implementation details, of a SmartResource concept. Equally plausible, smart_ptr could be implemented in terms of smart_resource somehow (derivation, aggregation, whatever). Even the name smart_ptr will not be commonly exposed; one will use typedefs to hide its configuration in order to leave open the possiblity for future changes to a given SP type. (Reasonable policy defaults may give a good, common SP type that can be used in most circumstances. If that's the case, then one may refer to smart_ptr rather frequently.) Names are important. Witness the recent discussion about whether pointers are resources, refer to resources, or may refer to resources. Words convey meaning. The wrong words confuse. The right words clarify. The same is true for names. Yes, one can learn that smart_ptr means resource manager for which pointer semantics may be appropriate. But, far better is to have smart_resource and smart_ptr as separate classes. The latter provides a superset of the behavior of the former, but the former may be precisely what's needed in a given context. With the counter examples of pointers to non-resources, would scoped_ptr or shared_ptr even make sense? It seems that if there's a smart_ptr to something within another another object, the destruction of what is pointed to will never actually be controlled by smart_ptr... I'm not sure what you're asking here. -- Rob Stewart [EMAIL PROTECTED] Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer; ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] possible addition to operators library
Daniel Frey [EMAIL PROTECTED] writes: That won't work as you made it a nested struct so it is still different for all instantiations. I think Dave meant to go for this one: Yup, that's what I meant. BTW, so this safe_bool thing can get further re-used it might make sense to make a special friend class which just has access to the type... or at that point, just make the type publicly accessible. -- Dave Abrahams Boost Consulting www.boost-consulting.com ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] possible addition to operators library
David Abrahams wrote: Daniel Frey [EMAIL PROTECTED] writes: That won't work as you made it a nested struct so it is still different for all instantiations. I think Dave meant to go for this one: Yup, that's what I meant. BTW, so this safe_bool thing can get further re-used it might make sense to make a special friend class which just has access to the type... or at that point, just make the type publicly accessible. Can you elaborate a bit? I imagine that although the technical implementation might be identical, the sematics of the names could be a problem. Helping the compiler to remove unneeded instantiations is a good thing, but it shouldn't affect readability, so I'd like to see some more concrete uses and whether we can use safe_bool (or any other name) that matches all these typical uses. Regards, Daniel -- Daniel Frey aixigo AG - financial training, research and technology Schloß-Rahe-Straße 15, 52072 Aachen, Germany fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99 eMail: [EMAIL PROTECTED], web: http://www.aixigo.de ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] partial proposal
Hi all, On Tue, 25 Feb 2003, Fernando Cacciola wrote: Peter Dimov [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] templateclass T void * operator new(size_t n, optionalT t); Anyway, there are still problems with this: operator new is called _before_ the T is constructed, so there won't be a way, AFAICT, to properly set the initialized flag ('cause if T ctor throws, placement new won't be aware of it) Additionally, I think writing into the object in operator new before the object is constructed leads to undefined behavior, or, at least, not the behavior you want. I tried something similar once, where operator new filled in a data member of the object being created, and the constructors for the object left that data member unitialized. However, it turned out that Intel C++ 7.0 zeroed out the entire object via memset() before invoking my constructor, wiping out the data stored by operator new. I could find nothing in the standard that prohibited icc from doing this. The fix is to move the data member either before or after the object, and have operator new allocate extra memory. Perhaps you could put the initialized flag before the optional, and have operator new initialize this bool to false. If optional's constructor knows that there is a bool located immediately before the optional in memory, it can calculate the address of it and access it, even though it lives outside the actual optional object. I don't understand all the issues here, so I am not sure if this helps at all. Also, there are alignment issues that need to be dealt with, to assure that both the bool and the optionalT are properly aligned, but I'm sure these can be handled. Regards, -Tom Wenisch Computer Architecture Lab Carnegie Mellon University ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] possible addition to operators library
Daniel Frey [EMAIL PROTECTED] writes: David Abrahams wrote: Daniel Frey [EMAIL PROTECTED] writes: That won't work as you made it a nested struct so it is still different for all instantiations. I think Dave meant to go for this one: Yup, that's what I meant. BTW, so this safe_bool thing can get further re-used it might make sense to make a special friend class which just has access to the type... or at that point, just make the type publicly accessible. Can you elaborate a bit? I imagine that although the technical implementation might be identical, the sematics of the names could be a problem. Can you elaborate a bit? How could the semantics be a problem? Helping the compiler to remove unneeded instantiations is a good thing, but it shouldn't affect readability, so I'd like to see some more concrete uses and whether we can use safe_bool (or any other name) that matches all these typical uses. namespace boost { struct safe_bool { int value; typedef int safe_bool::*type; }; } struct myclass { operator boost::safe_bool::type() const { return expression ? boost::safe_bool::value : 0; } }; HTH, -- Dave Abrahams Boost Consulting www.boost-consulting.com ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] possible addition to operators library
On Tue, 25 Feb 2003, David Abrahams wrote: namespace boost { struct safe_bool { int value; typedef int safe_bool::*type; }; } struct myclass { operator boost::safe_bool::type() const { return expression ? boost::safe_bool::value : 0; } }; You don't want to do that. Add: struct yourclass { operator boost::safe_bool::type() const { return expression? boost::safe_bool::value : 0; } }; myclass m; yourclass y; if (m == y) { // what's this mean? } This is the reason boost::function has poisoned operator== and operator!=. Doug ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: possible addition to operators library
On Tue, 25 Feb 2003 21:14:14 +0100, David Abrahams wrote: Daniel Frey [EMAIL PROTECTED] writes: David Abrahams wrote: Daniel Frey [EMAIL PROTECTED] writes: That won't work as you made it a nested struct so it is still different for all instantiations. I think Dave meant to go for this one: Yup, that's what I meant. BTW, so this safe_bool thing can get further re-used it might make sense to make a special friend class which just has access to the type... or at that point, just make the type publicly accessible. Can you elaborate a bit? I imagine that although the technical implementation might be identical, the sematics of the names could be a problem. Can you elaborate a bit? How could the semantics be a problem? As Doug already showed it's a problem when you use the same safe_bool for all your classes as a replacement for operator bool. I though that you have some other uses in mind that are more than just a replacement for operator bool. If so, I wondered what this could be and if the name would then be a problem. If it's just meant to replace operator bool, the names are perfect - although the problem Doug mentioned remains. Regards, Daniel ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: Re: Re: Thread-Local Storage (TLS) and templates
William E. Kempf wrote: Edward Diener said: William E. Kempf wrote: And it's full of issues. You are quite limited in what you can safely do within DllMain. Any calls to synchronization routines is likely to deadlock the entire process. I agree that this is so. You can't sit and wait until some other thread has done something, via a Windows synchronization primitive, when you are processing DLL_THREAD_DETACH. What is the situation where this is necessary ? There are numerous situations where this is necessary. For example, the cleanup mechanism in both Boost.Threads and pthreads-win32 use mutexes, which can potentially cause *process* deadlock. If the TLS data is shared across threads, or references data shared across threads, or simply calls a routine that does synchronization in the cleanup, all of which are not that uncommon, and some of which are hard for the programmer to avoid (do you know what routines do synchronization internally?), you risk deadlock. My understanding of TLS data is that it is thread specific and not meant to be shared across threads. The whole idea is that every thread in a process gets their own copy of the same data. Why then do you say that TLS data is shared across threads, or references data shared across threads ? The last issue of doing synchronization in the cleanup I can understand but not that the data which needs to be synchronized is TLS data itself. I completely agree with you that there is a serious problem in the DLL_THREAD_DETACH attempting to do synchronized cleanup, but I am guessing that you may be using TLS data itself in ways in which it was not intended. I don't believe TLS data was ever intended as a way to share data between threads but was intended, as its name implies, to create data that is specific only to a single thread. As is calling any routines that load/unload a DLL. The workaround is not to dynamically load/unload a DLL as part of thread processing. Do you know what routines do this as part of their implementation? To quote the MSDN Calling imported functions other than those located in Kernel32.dll may result in problems that are difficult to diagnose. And since a very large number of Win32 API functions are imported... I think you see the issue. I see the issue and although I haven't investigated what Windows API functions may load/unload a DLL dynamically, something tells me that MS must publish such a list somewhere so that one knows what to avoid at DLL_THREAD_DETACH time at least within their own Windows APIs. Yes, it is cleaner to do so when one only needs a DLL for a specific time but the overhead of statically linking a DLL into a process instead is minimal, although I agree that dynamic loading is often a cleaner design. I do agree with you that the inability to dynamically load and unload a DLL at DLL_THREAD_ATTACH/DLL_THREAD_DETACH is an unfortunate imposition and that this is poor design on MS's part. I am still not clear whay this is so and why this limitation exists on Windows. I honestly don't care. The only time I've ever found this design to be unusable is when dealing specifically with the cleanup of TLS data, which would be much better implemented as a registered cleanup routine in the first place. Fix this, and I don't care about this artifact of the DLL system on Win32 platforms. OK, given that a registered cleanup routine would not have the restrictions which DLL_THREAD_DETACH has. I still don't think it is a TLS issue but rather a thread cleanup issue and the restrictions imposed by MS's design of that situation. So I can well understand your chagrin at the tricks you must do in order to cleanup internal thread data when a thread exits under Windows. There's also the issue of forcing the use of a DLL with this scheme, which many users rightfully dislike (this is why there are so many thread creation routines on Windows). I could be mistaken but I believe that TLS works just as effectively in static LIBs as it does with DLLs. The difference is that one must do manual initialization routines and finalization routines of TLS data for different threads, as opposed to what one may do automatically using DLL_THREAD_ATTACH/DLL_THREAD_DETACH. But certainly one is not forced to use only DLLs or only static LIBs if the implementation supports both. Initialization isn't really an issue, as you can do lazy initialization (synchronization issues aside, as they are solvable). It's the finalization that's an issue, and it's resulted in the numerous thread creation routines and the rules for when to use which one. If you call any C RTL routines (which may allocate TLS) you can't call CreateThread, but must instead call _beginthread(ex). Likewise, if you call any MFC routines you can't call CreateThread or _beginthread(ex) but instead must call AfxBeginThread, lest you leak TLS data allocated by these routines. This is an issue for Boost.Threads, which
[boost] [optional] Polymorphism
I think optional might be perfect for an issue I have, but there is one catch. I have a polymorphic hierarchy that I would like to use with optional, but optionalBase is not a base of optionalDerived. Of course, this isn't really a problem with optional, par se, but any suggestions on how to store pointers to optionalT when T is polymorphic would be appreciated. I know I can use aggregation like so: class Base { virtual ~Base() { } }; template typename T class PolyOptional : public Base { optionalT value_; }; and then just store Base*, but this requires explicit run-time checking of types which would otherwise be automatic with pointers to T instead of optionalT. If this is the only solution, so be it; but any clever alternatives are welcome. Dave ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: Re: Re: Thread-Local Storage (TLS) and templates
Edward Diener said: William E. Kempf wrote: Edward Diener said: William E. Kempf wrote: And it's full of issues. You are quite limited in what you can safely do within DllMain. Any calls to synchronization routines is likely to deadlock the entire process. I agree that this is so. You can't sit and wait until some other thread has done something, via a Windows synchronization primitive, when you are processing DLL_THREAD_DETACH. What is the situation where this is necessary ? There are numerous situations where this is necessary. For example, the cleanup mechanism in both Boost.Threads and pthreads-win32 use mutexes, which can potentially cause *process* deadlock. If the TLS data is shared across threads, or references data shared across threads, or simply calls a routine that does synchronization in the cleanup, all of which are not that uncommon, and some of which are hard for the programmer to avoid (do you know what routines do synchronization internally?), you risk deadlock. My understanding of TLS data is that it is thread specific and not meant to be shared across threads. That's the most common use, but it's not mandated by anything. However, sharing the TLS data is the less common of the cases I gave. The whole idea is that every thread in a process gets their own copy of the same data. Why then do you say that TLS data is shared across threads, or references data shared across threads ? The last issue of doing synchronization in the cleanup I can understand but not that the data which needs to be synchronized is TLS data itself. I completely agree with you that there is a serious problem in the DLL_THREAD_DETACH attempting to do synchronized cleanup, but I am guessing that you may be using TLS data itself in ways in which it was not intended. I don't believe TLS data was ever intended as a way to share data between threads but was intended, as its name implies, to create data that is specific only to a single thread. An example of the former, and I believe a valid example, exists in the next revision to Boost.Threads. The thread representation is sharable, i.e. boost::thread uses a ref-counted pimpl idiom to make it copyable and assignable. The implementation holds some state information that's specific to the thread, such as it's running state. The default constructor and/or thread::self() needs to be able to access this shared state, which means it must be contained in a TLS slot. There you have TLS data that's shared across threads. More importantly, this data must be cleaned up at thread exit by decrementing the ref-count (which has to be synchronized) and if the ref-count goes to zero, by actually deleting the data. But again, the latter is the more likely case, and is likely to occur quite frequently in MT C++ code. As is calling any routines that load/unload a DLL. The workaround is not to dynamically load/unload a DLL as part of thread processing. Do you know what routines do this as part of their implementation? To quote the MSDN Calling imported functions other than those located in Kernel32.dll may result in problems that are difficult to diagnose. And since a very large number of Win32 API functions are imported... I think you see the issue. I see the issue and although I haven't investigated what Windows API functions may load/unload a DLL dynamically, something tells me that MS must publish such a list somewhere so that one knows what to avoid at DLL_THREAD_DETACH time at least within their own Windows APIs. *chuckles* Sorry, there's no such list. The MSDN pretty much says the only routines you can trust are those in kernel32.dll. But even if MS did publish such a list, do you think third party vendors do? Have you ensured you document which of your own routines call such routines? Yes, it is cleaner to do so when one only needs a DLL for a specific time but the overhead of statically linking a DLL into a process instead is minimal, although I agree that dynamic loading is often a cleaner design. I do agree with you that the inability to dynamically load and unload a DLL at DLL_THREAD_ATTACH/DLL_THREAD_DETACH is an unfortunate imposition and that this is poor design on MS's part. I am still not clear whay this is so and why this limitation exists on Windows. I honestly don't care. The only time I've ever found this design to be unusable is when dealing specifically with the cleanup of TLS data, which would be much better implemented as a registered cleanup routine in the first place. Fix this, and I don't care about this artifact of the DLL system on Win32 platforms. OK, given that a registered cleanup routine would not have the restrictions which DLL_THREAD_DETACH has. I still don't think it is a TLS issue but rather a thread cleanup issue and the restrictions imposed by MS's design of that situation. So I can well understand your chagrin at the tricks you must do in order to cleanup
RE: [boost] Re: smart_ptr vs smart_resource
This is an excellent point. One doesn't go looking for a class named smart_ptr or a library named Boost.SmartPointer when looking to manage the lifetime of some arbitrary resource. When one uses pointers, it makes sense. I would be searching namely for smart_ptr. I know that smart pointer is the name for the resource management idiom. It is a shame for things to simply be the way that they are simply because they started out from a specific beginning... History always has a way of biting us. In this case, we are creating something brand new in Boost. There isn't a PBSP in boost. Therefore, if it is a manifestation of a SmartResource concept or is implemented in terms of a smart_resource class isn't as important as the recognition that it is a special case of the more abstract concept. There can still be a smart_ptr class, even if there's a smart_resource class. Both may be separate manifestations, possibly sharing some implementation details, of a SmartResource concept. Equally plausible, smart_ptr could be implemented in terms of smart_resource somehow (derivation, aggregation, whatever). This all would make sense if you could find at least 10 differences between smart resource and smart pointer. Names are important. Witness the recent discussion about whether pointers are resources, refer to resources, or may refer to resources. Words convey meaning. The wrong words confuse. The right words clarify. The same is true for names. Yes, one can learn that smart_ptr means resource manager for which pointer semantics may be appropriate. But, far better is to have smart_resource and smart_ptr as separate classes. The latter provides a superset of the behavior of the former, but the former may be precisely what's needed in a given context. In general I agree that names are important. In general, but not in this particular case. If names are so important for you here, why do you try to use the name smart resource? What is smart here? May be we should use clever or cunning or wise? And what word resource is doing here? It almost never the resource itself, but the manager code for some resource (it may not even hold reference to the resource itself inside). As I sad before IMO most close name would be resource_manager. But I still do not see a reason in introducing new terms, while already exist well established idiom with name smart pointer Gennadiy. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
RE: [boost] Re: smart_ptr vs smart_resource
When Mark Terribile proposed a class like this way back in the last century I think he called it releaser. At 04:00 PM 2/25/2003, Rozental, Gennadiy wrote: This is an excellent point. One doesn't go looking for a class named smart_ptr or a library named Boost.SmartPointer when looking to manage the lifetime of some arbitrary resource. When one uses pointers, it makes sense. I would be searching namely for smart_ptr. I know that smart pointer is the name for the resource management idiom. It is a shame for things to simply be the way that they are simply because they started out from a specific beginning... History always has a way of biting us. In this case, we are creating something brand new in Boost. There isn't a PBSP in boost. Therefore, if it is a manifestation of a SmartResource concept or is implemented in terms of a smart_resource class isn't as important as the recognition that it is a special case of the more abstract concept. There can still be a smart_ptr class, even if there's a smart_resource class. Both may be separate manifestations, possibly sharing some implementation details, of a SmartResource concept. Equally plausible, smart_ptr could be implemented in terms of smart_resource somehow (derivation, aggregation, whatever). This all would make sense if you could find at least 10 differences between smart resource and smart pointer. Names are important. Witness the recent discussion about whether pointers are resources, refer to resources, or may refer to resources. Words convey meaning. The wrong words confuse. The right words clarify. The same is true for names. Yes, one can learn that smart_ptr means resource manager for which pointer semantics may be appropriate. But, far better is to have smart_resource and smart_ptr as separate classes. The latter provides a superset of the behavior of the former, but the former may be precisely what's needed in a given context. In general I agree that names are important. In general, but not in this particular case. If names are so important for you here, why do you try to use the name smart resource? What is smart here? May be we should use clever or cunning or wise? And what word resource is doing here? It almost never the resource itself, but the manager code for some resource (it may not even hold reference to the resource itself inside). As I sad before IMO most close name would be resource_manager. But I still do not see a reason in introducing new terms, while already exist well established idiom with name smart pointer Gennadiy. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: Re: Re: Re: Thread-Local Storage (TLS) and templates
William E. Kempf wrote: Edward Diener said: William E. Kempf wrote: I still don't think it is a TLS issue but rather a thread cleanup issue and the restrictions imposed by MS's design of that situation. So I can well understand your chagrin at the tricks you must do in order to cleanup internal thread data when a thread exits under Windows. That's a minor fine hair your splitting. What's the difference between a TLS issue and a thread cleanup issue of TLS data? Because it is a thread cleanup issue of any thread specific data, not just TLS. No matter what the data that exists for a thread when the thread is exited, it musty be cleaned up efficiently. A user could have objects associated with only a particular thread and if the thread ends, it must be able to cleanup while other threads continue running. The fact that MS says no to this in DLL_THREAD_DETACH, that you are effectively blocking other threads in the process until you exit the DllMain routine, is for me the central weakness. And if you look back, I said I wouldn't call it broken, just that the implementation has serious design issues. So it looks like we're in agreement now. Want to join in my mini campaign to convince MS to fix this one? As long as the suggested fix is to allow thread cleanup without the current restructions on synchronization or DLL loading/unloading, sure. I don't think you are going to change anything in the way that TLS currently works nor should you. I am going to guess that MS is aware of this issue of thread cleanup and that the main fix on their part would be to allow re-entrancy in the current DllMain routine, which of course may be a big job on their part given the amount of underlying intertwined code. The other solution(s) involves some sort of callback as you suggested, or some other way to ensure that a thread can be exited cleanly without blocking other threads from running in the meantime, whether in an executable, a static LIB, or a DLL. Knowing MS from their track record, a campaign to get them to change anything entails working closely with one or more of their techies who can actually understand the issues involved and get the changes to be seriously considered. Just voicing displeasure in any public way won't do anything. If there is a VC++ rep who now works closely with Boost to ensure VC++ .NET conformance, he's the guy I would badger first, and then through him you might be able to get to other MS techie employees. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
RE: [boost] checked_delete.hpp fix
From: David Abrahams Hum, it looks like Microsoft took you up on it. Well, it was MS I was haranguing most-loudly about it. I don't recall a discussion on warnings about ADL, I'll need a refresher. I do recall a discussion we had on non-dependent names. See the shared_ptr_test warning on the VC++ 7.1 beta regression test.I've seen that. It's a different warning IIUC. Doesn't it go offwhether or not you find the overload in the same namespace the searchstarted from? The warning we added in VC7.1 was purely to diagnose behavior changes due to the implementation of ADL on ordinary function calls. I can't think of a scenario where it would warn as you suggest. Jason Shirk VC++ Compiler Team ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: io operations for stl containers?
From: Jason House [EMAIL PROTECTED] std::vectorstd::pairchar,int test; std::cout test: // Using defaults (('A',1),('B',2),('C',3)) I would suspect that chars don't get output with '' around them... Right. I was just thinking C++ code, here. :) Is there even a way to specify/change that? It isn't currently, as the fundamental types aren't handled as composite types, and therefore aren't formatted using any set format. Also, it seems it may not be possible in an obvious way. For example, the following addition to the header doesn't work: templateclass CharType,class CharTraits std::basic_ostreamCharType,CharTraits operator (std::basic_ostreamCharType,CharTraits stream,char value) { typedef basic_composite_formatCharType,char format_type; const format_type format=format_type::format(stream); stream format.start; stream.operator(value); stream format.end; return stream; } It appears to prefer the operator(char) stream member function, to this free function, as it isn't called when doing std::cout 'A';. In this case, it's not possible to set the format for each type separately. Maybe it could be good to keep that feature of the current composite operators, as well, something like: typedef std::pairchar,int map; typedef std::vectorMap map_list; map_list test; std::cout io::set_delimitermap(\n) test; Output: (('A',1) ('B',2) (C,3)) so basically, you would like to combine tuple-like output specification (ie for all tuples) and type specific such as composite_format? I was thinking of that, yes. As well as a default, possibly user-settable, for any type not having set an explicit format. This would let you control the formatting in layers, so to speak: - You could use/set the default format for all types. - You could use/set the format for all instantiations of a given template, e.g. std::vector. - You could use/set the format for specific types. If possible, it would apply the most specific format set (i.e. it would prefer 3 to 2, to 1). Another thing is if this layering is practically possible. :) We get into this below here. templateclass CharType, class CharTrait, class T1, class T2 inline std::basic_ostreamCharType, CharTrait operator(std::basic_ostreamCharType, CharTrait o, const consT1, T2 t) As you say, this may be a problem to call from a debugger, unless it supports calling function templates. If one need to call it from a debugger, one could always wrap the code in a function. :( Debugger friendly manipulation would be good. I still haven't thought about how exactly outputting of an arbitrary composite variable will work in the debugger by default... I agree that having a wrapper makes it easy for the output formatting of general types, but actually being able to execute std::cout my_suspect_variable in the debugger without premeditation still poses a significant problem. Why can't bugs be predicted before you notice them? You're right, good point. Would it be possible to get some information on what kind of functions, if any, may be called in e.g. your debugger? From this, we may find what we can do. There was a suggestion for allowing generic formats, though, using the same format for all instantiations of a template. The question is how to do it. The current version stores the format for each specific type, as you say. Volodya suggested a couple of ways it could be done, partial specialisation, or storing the template name in a map. However, it could be hard to use the latter, as it could be hard to find the right type to look up, when outputting, given that you have specific types, not templates. Overloading of class templates might have helped, here. E.g.: std::cout io::set_formatstd::vectorstd::pairchar,int (...); // Set specific format (io::format is a class template) std::cout io::set_formatstd::vector(...); // Set generic format for std::vector (io::format overloaded with a version taking template template parameter, and specialised for std::vector) Well, std::vector would cause trouble because the std::vector requires extra arguments... I don't think you could get that to compile. True, it doesn't, because it's not currently legal C++. :) That's what I meant with Overloading of class templates might have helped, here. It's not possible to overload class templates. However, this is mentioned as a possible extension, in the Future Directions chapter of Josuttis/Vandevoorde. Together with partial specialisation of function templates, etc. Using a string might work... but using it as a template argument would probably cause trouble. Yes, you can't use string literals as template parameters. I don't know if there is a way to use partial template specialization. There is, as I showed in the following example. However, it means you have to provide the parameters to the template, as well (e.g. std::vector), even if you just mean to
[boost] resource manager naming
I would be searching namely for smart_ptr. I know that smart pointer is the name for the resource management idiom. But those that don't would look for resource_manager or resource_mgr (and might even find res_mgr). The smart_ prefix is quite useless in this context, there isn't an old resource manager that is being replaced. Dave ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: [optional] Polymorphism
David B. Held [EMAIL PROTECTED] escribió en el mensaje news:[EMAIL PROTECTED] I think optional might be perfect for an issue I have, but there is one catch. I have a polymorphic hierarchy that I would like to use with optional, but optionalBase is not a base of optionalDerived. Of course, this isn't really a problem with optional, par se, but any suggestions on how to store pointers to optionalT when T is polymorphic would be appreciated. I know I can use aggregation like so: class Base { virtual ~Base() { } }; template typename T class PolyOptional : public Base { optionalT value_; }; and then just store Base*, but this requires explicit run-time checking of types which would otherwise be automatic with pointers to T instead of optionalT. If this is the only solution, so be it; but any clever alternatives are welcome. Dave I think I have bad news... Let me see: Given: struct B { virtual ~B() ; } ; struct D : B {} ; You can have optionalB and optionalD; but as you say, they are not inheritance related. You would like to be dealing with: optionalB* and optionalD* but you can do this as well, so I figure that what you really need is a 'dynamic-type preserving' conversion between these optionals. Something that would allow the following: D dval ; optionalD dopt(dval); optionalB bopt ( optional_castB(dopt) ) ; optionalD dopt2 ( optional_castD(bopt) ) ; assert ( dval == *dopt2); Is this what you need? If it is, I'm afraid it's not possible: The problem is that even though the conversion will succeed (it would probably work with the current optional as it is now), it will inevitably _slice_. The reason is that optionalB will get exactly the B subobject within D and there's no way to get back the rest of D from the B subobject alone. AFAICT, this can only be done with pointers because the shallow copy semantics of pointers is which retains the dynamic type (that is, the object is always the same, you just refer to different parts of it). This can't be done with value semantics, unless not if you don't cheat and traffic always the most derived object by-value. I think that a solution which uses the PolyOptionalT technique is the only way to go. BTW, that technique is essentialy the same one used by boost::any, thus, you can store the different optionals in a 'any' object and traffic the 'anies' instead. HTH, Fernando Cacciola ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: Re: Re: Re: partial proposal
Fernando Cacciola wrote: [...] That would have to be _measured_; my guess is that it could be twice slower, specially considering that I don't think boost sources will ever include assembly code; it's a portability nightmere. I've just generated some code, and the compiler can even optimize more when the parameter of operator [] is compile-time constant: 0x8048606 main+6: movsbl 0x(%ebp),%eax 0x804860a main+10: shr$0x3,%eax 0x804860d main+13: add$0xfff8,%esp 0x8048610 main+16: and$0x1,%eax The only thing that would not be portable up to now is the number of bits in a char (8). I do not wish to include assembler code directly, what I meant was the generated machine code by the compiler. So, what are you trying to optimize with this bool array? and most importantly, why do you feel that such optimization is needed? Consider that gaining storage, say 31 bits, per optional will incurr in a significant overhead, so in order to think that the gain is needed you need to weight size/speed benefits. This sort of things are typically considered only afer some benchmarks shown the need for the optimization. Even tough arraybool is not optimized, the boolean values will follow each other and will not waste any space between themselves. Yes, though I still can't see if this would be _needed_. Well boost::type_with_alignment would be more meaningful in optional. Also I am pretty sure the number of optional instances will be greater than 1. Placement operator new will be able to deal with external initializations also. I have to take a break... ;) Philippe A. Bouchard ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: checked_delete.hpp fix
Daniel Frey wrote: On Tue, 25 Feb 2003 08:34:43 +0100, Nicola Musatti wrote: [...] I don't have a strong opinion in either direction, but I do feel that it is important that this is thought over. Overloading checked_delete() on purpose in a user defined namespace might be considered a way to provide a smart pointer with a custom deleter. Is this really something bad? It won't work as the call is ambiguous and thus rejected by the compiler. But the user it free to provide his own checked_deleter along with his own checked_delete, so there is no limitation that would result from the above fix AFAICS. If you agree, I will make the change in CVS. No objections. Cheers, Nicola Musatti ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost