[boost] Standard interface for adaptable function objects?
David Abrahams writes: Do we have any precedent for ways to find out what the arity and argument types of an arbitrary function object is (I'm not talking about function pointers, here, but functors)? Given that a functor might support more than one argument set, the only way I can think of is to say do you support this argument set? rather than what argument set do you accept?; in which case you can use the mechanism implemented in boost.lambda, and in my function composition library, to deduce the return type --- have a member template that takes a typelist representing the arguments you wish to pass, and returns the corresponding return type where that argument set is valid, or something else (such as invalid_argument_set) where it isn't (assuming you want to do something else in the case where it isn't, rather than just abort compilation) Does this give you what you want? Anthony -- Anthony Williams Senior Software Engineer, Beran Instruments Ltd. Remove NOSPAM when replying, for timely response. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] pointer to member
Martin Bosticky writes: Does anybody know if it is possible to extract a class type from a pointer-to-member type/object? ie if i have templateclass pointer_to_member_type void foo(pointer_to_member_type AMember) { ... //? can i figure out here what the type is for the object to which the pointer-to-member pointer belongs? } For data members, it's quite straight forward: templatetypename T struct get_pointer_to_member_details; templatetypename Class,typename Member struct get_pointer_to_member_detailsMember Class::* { typedef Class class_type; typedef Member member_type; }; then use it like so: templatetypename pointer_to_member_type void foo(pointer_to_member_type AMember) { // extract class from pointer to member typedef typename get_pointer_to_member_details pointer_to_member_type::class_type class_type; } I can't remember OTOMH whether or not this will match pointer-to-member-functions; I've a feeling that you'll have to partially specialize get_pointer_to_member_details for each member function type you want to match (number of args and cv-qualification) HTH Anthony -- Anthony Williams Senior Software Engineer, Beran Instruments Ltd. Remove NOSPAM when replying, for timely response. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Implicit conversions in dynamic_any / extract
Hello Boosters, I am trying to use dynamic_any to store either objects or pointers to (polymorphic) objects. I am able to extract a pointer to the base class of a contained object: class B { }; class D: public B { }; void Test() { any d(D()); B* pb = extractB(d); } This is alread quite useful. However the following code does not work: void Test2() { D d; any pd(d); B* pb = extractB*(pd);// pb = 0 char c; any AnyChar(c); int i = extractint(AnyChar); // bad_extract } So I have to know the exact type of the contained object and cannot rely on implicit conversions (D* - B* or char - int) to work. This is quite understandable from the fact that any wraps non-class types into unrelated classes. Now my question: is there a way to make these implicit conversions work? My best answer at the moment: explicitly register conversion functions from one type to the other in a mappairtype_info const, type_info const, void* (*)(void*) and look up the right function based on the type contained and the type requested. But there has to be a better way, hasn't it? Best regards. --Remy Remove anti-spam sequence in reply address for a timely response. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Continuations (was: tandard interface for adaptable function objects?)
Anthony Williams wrote: Given that a functor might support more than one argument set, the only way I can think of is to say do you support this argument set? rather than what argument set do you accept?; in which case you can use the mechanism implemented in boost.lambda, and in my function composition library, to deduce the return type --- have a member template that takes a typelist representing the arguments you wish to pass, and returns the corresponding return type where that argument set is valid, or something else (such as invalid_argument_set) where it isn't (assuming you want to do something else in the case where it isn't, rather than just abort compilation) Does this give you what you want? Actually I was digging through lambda for something like this just yesterday (and found nothing). Shouldn't goodies like this be separated (and documented) into their own library? (the other thing I'd *really* like to see separated from lambda is operator argument promoting... the name of the header escapes me). Incidentally, since I've already spent too much time on something that is basically a cool side-project.. has anybody implemented lightweight continuations in C++? I'm trying to convert functions of the form void foo(functor) into objects that can be operated on (kinda like lambda placeholders), and the results of the operation can then take functor - then lazilly evaluate all the calls (possibly with backtracking) and pass all the answers to the functor. Basically, the conversion itself then behaves like call/cc, while the compilation is somewhat like DS-CPS conversion. Except that unlike Scheme's continuations, these would just be shorthand for passing lambdas (and would be able to return after invocation). The idea is that if a function cont_iterate calls a sink function over all the elements of a vector (can't use for_each here, because of the template issues), cond_apply calls a function on a bunch of continuations, and the_sink is a function that takes pairs of vector elements, you could do something like cont_apply(pair, bind(cont_iterate, a_vector, _1), bind(cont_iterate, another_vector, _1)) (sink) and the sink will be called with all the pairs of elements (but this will be done in a natural way, through backtracking). The code would expand into something like: int r2; void temporary1(int r) { sink(pair(r2, r)); } void temporary2(int r) { r2 = r; cont_iterate(another_vector, temporary1); } void invocation() { cont_iterate(a_vector, temporary2); } Fun thing about the continuations is that with these, you can implement microthreads VERY efficiently, as well as priority evaluation, and similar tricks. Basically most things you can do with Scheme's continuations - the only difference is that backtracking only happens up-the-stack. The issue is that continuation objects need to maintain some state - at least the temporary results - and I need to query the functors for the result type. This is a problem. Note also that the implementation of continuations should probably be something like lambda in reverse. The problem is that I'm not experienced enough with metaprogramming, so I could use any comments and advice that people here might have. Especially the pointers to the code I might want to reuse or look into. Miro ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] ublas regression test problems
- Original Message - From: Aleksey Gurtovoy [EMAIL PROTECTED] To: 'Boost mailing list' [EMAIL PROTECTED] Sent: Thursday, November 21, 2002 9:57 AM Subject: RE: [boost] ublas regression test problems Joerg Walter wrote: OK. The mpl::if_ problem vanished, the remaining problems with VC7 are home-grown (I'll look into these later). But now all ublas GCC tests fail to compile due to In file included from C:/boost/site/boost/type_traits.hpp:43, from C:/boost/site/boost/numeric/ublas/config.hpp:24, from C:/boost/site/libs/numeric/ublas/concepts.cpp:12: C:/boost/site/boost/type_traits/is_polymorphic.hpp:20: warning: `typename boost::remove_cvT::type' is implicitly a typename C:/boost/site/boost/type_traits/is_polymorphic.hpp:20: warning: implicit typename is deprecated, please see the documentation for details C:/boost/site/boost/type_traits/is_polymorphic.hpp:28: duplicate base type ` boost::remove_cvT::type' invalid I'm lost again. A missing 'typename', fixed in the CVS. Thanks. On an aside note, including individual type traits headers you need (e.g. boost/type_traits/add_reference.hpp) instead of monolithic boost/type_traits.hpp would reduce chances for the library to be broken down on the events like this. Fixed in my local copy. Best regards Joerg ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] intrusive_ptr ?
Hello, the shared_ptr pages (.hpp) are apprently not accessible any more from www.boost.org. I was looking for some documentation on using intrusive_ptr but they are apparently not documented. Looking at the header files I got some hints how to use them. Why are the intrusive_ptr not documented ? Does it mean that it is not standard and official ? Would we have portability problem if we use them ? The performance comparision of different solution shows that intrusive_ptr are more efficient and in some circumstances this might have a significant impact on the whole program performance. What wish would be that the intrusive_ptr and scoped_intrusive_ptr are described as part of the official smart pointer library. To be sure I could eventually rely on them. Did I missed an epsiode about this ? -- Cheers, Ch. Meessen ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] implicit_cast
From: David Abrahams [EMAIL PROTECTED] Here's what I think might be a correct implementation: template class T, class U T implicit_cast(U const x) { return x; } template class T, class U T implicit_cast(U x) { return x; } The correct implementation IIRC is templateclass T T implicit_cast(typename identityT::type x) { return x; } ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: [Jason Shirk jasonsh@microsoft.com]boost\dynamic_bitset.hppneeds update for Everett
On Wed, 20 Nov 2002 16:34:50 -0500, David Abrahams [EMAIL PROTECTED] wrote: I just checked CVS, and boost\dynamic_bitset.hpp needs a change to avoid a warning with Everett: Here is the patch: 50c50 #ifdef BOOST_MSVC --- #if (BOOST_MSVC = 1300) It's worth remembering that Microsoft's are not the only compilers supported. Genny. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Do we need a boost_exception class or idiom?
From: William E. Kempf [EMAIL PROTECTED] Peter Dimov said: I see, ambiguous usage of user. Let's rephrase: in most cases the what() string is supplied by the throw point, not the catch point, right? I.e. library authors decide what to return from what(), library users do not. Except it's not just libraries that throw, and in some corner cases libraries have to deal with exceptions thrown by user code. (Whether or not it's appropriate for library code to do logging in these cases is questionable, however.) That's correct (Boost.Threads eating thread exceptions immediately comes to mind ;-) ) but how does this affect our discussion? I understood that, too. My point was that non-localized but readable strings is meaningless, unless you define what readable means. Readable to a Bulgarian? Readable to at least 26% of the audience? Readable to whoever we consider important? Mostly the latter, which to me mostly means the programmer. We can bear the burden of having to interpret a non-localized string, even if it's not in our native language. The interesting thing to note here is that to the programmer boost::thread_resource_error is just as readable as Required thread resource is unavaliable. Sometimes the former is _more_ readable, if the programmer's native language is not English. Please do understand that I'm just trying to provide some perspective here. Of course I know what the intuitive meaning of readable but non-localized is - English text. English-speaking countries have earned that right, WRT computers. Still, an international standard should be, well, international. 1) I wasn't proposing a change to the standard here. I think it's premature to be looking at that. Fix the issue of memory allocation requirements on the standard provided exceptions and I think you've done enough as far as the standard is concerned. The exception issue is too broad; it simply cannot be fixed by local changes. Application X has to deal with exceptions thrown by the standard library implementation, by third party libraries Y and Z, by low-level libraries (some of them Boost, some not) used by Y and Z... If we aren't aiming for a standard fix, I'm not interested. It simply will not make my job easier. There's also the additional problem that the current what(), if left as-is, does not guarantee, and often does not produce, an useful readable string, even if we accept the above readability definition. Well, other than the fact that the what() text is user specified, I'd consider this a QoI issue and not that important. Especially if there's a mechanism available for the user to specify what the message will be in a localized fashion. Application programmers that need to actually do something with that what() string consider the problem important. When you receive a bug report related to a text that your application displays, you can't shrug it off claiming that this is a QoI issue in a standard/Boost/third party library. You need to fix the problem. From a technical point of view, it's obviously easier to just leave what() as is (i.e. of questionable utility outside of toy programs), introduce another function, and get it right this time. I'd tend to agree, but the question is still how to design it so that it's right this time. My answer is that specifying the precise semantics of what() for every documented exception type is a necessary prerequisite. (Implies that the standard needs to be fixed, too.) And to be fair, it is a valid argument that logging for exceptions is something outside of the domain of exception propagation and handling. We could never touch the what() method but instead build an elaborate scheme of mapping type_info to localized messages for logging with out having to change the design of the exceptions at all. I personally don't like that answer, but from the standards point of view it might be the correct answer. To repeat, type_info instances make a good default, but they cannot be used as is. Sometimes different logical exceptions are represented by the same physical class. Sometimes an undocumented derived class is thrown instead of the documented base. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Do we need a boost_exception class or idiom?
From: David Bergman [EMAIL PROTECTED] I have always interpreted non-localized as comprehensible to some 60% of scientifically inclined Americans ;-) Looks like a joke but hides a relevant point. Sometimes you need to localize to plain (nontechnical) English, too. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Implicit conversions in dynamic_any / extract
Remy Blank [EMAIL PROTECTED] writes: Hello Boosters, I am trying to use dynamic_any to store either objects or pointers to (polymorphic) objects. I am able to extract a pointer to the base class of a contained object: class B { }; class D: public B { }; void Test() { any d(D()); B* pb = extractB(d); } This is alread quite useful. However the following code does not work: void Test2() { D d; any pd(d); B* pb = extractB*(pd);// pb = 0 char c; any AnyChar(c); int i = extractint(AnyChar); // bad_extract } So I have to know the exact type of the contained object and cannot rely on implicit conversions (D* - B* or char - int) to work. This is quite understandable from the fact that any wraps non-class types into unrelated classes. Now my question: is there a way to make these implicit conversions work? Heh. Boost.Python does it with a complicated class registry and upcast/downcast system. I don't know if you want to pay for that. My best answer at the moment: explicitly register conversion functions from one type to the other in a mappairtype_info const, type_info const, void* (*)(void*) and look up the right function based on the type contained and the type requested. Oh, well, if you're willing to do that... But there has to be a better way, hasn't it? Yes**. The mechanism in Boost.Python allows you to register just the relationships between adjacent base and derived classes, and it fills in the rest of the graph. Maybe it's time to refactor this code for general use in Boost... The code is in libs/python/src/object/inheritance.cpp. -Dave **Of course, there's always the mythical typeid-guided-dynamic-cast feature I want as a language feature dynamic_cast(void_ptr, src_typeid, dst_typeid) but sadly it's mythical :( -- 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] Standard interface for adaptable function objects?
David Abrahams writes: Anthony Williams [EMAIL PROTECTED] writes: David Abrahams writes: Do we have any precedent for ways to find out what the arity and argument types of an arbitrary function object is (I'm not talking about function pointers, here, but functors)? Given that a functor might support more than one argument set, the only way I can think of is to say do you support this argument set? rather than what argument set do you accept?; in which case you can use the mechanism implemented in boost.lambda, and in my function composition library, to deduce the return type --- have a member template that takes a typelist representing the arguments you wish to pass, and returns the corresponding return type where that argument set is valid, or something else (such as invalid_argument_set) where it isn't (assuming you want to do something else in the case where it isn't, rather than just abort compilation) Does this give you what you want? No, the inputs are fully-polymorphic Python objects. If I knew what arguments I wish to pass, I'd be all set. I'm only interested in the cases where that's deducible from the function object. For the other cases, the user can pass me a type sequence directly. OK, so you have a set of any objects, and a functor, and you want to know what types to extract from your any objects to pass as arguments to the functor? Well, given that you can only work with a functor of defined arity and argument types for that information to be available at all, you could just use the type of Functor::operator() to determine the required information: struct get_member_func_info; templatetypename Functor,typename Res,typename Arg1 struct get_member_func_infoRes (Functor::*)(Arg1) { enum {arity=1}; typedef Arg1 arg1_type; }; templatetypename Functor,typename Res,typename Arg1,typename Arg2 struct get_member_func_infoRes (Functor::*)(Arg1,Arg2) { enum {arity=2}; typedef Arg1 arg1_type; typedef Arg2 arg2_type; }; not forgetting to handle const/volatile/const volatile member functions too, then just use get_member_func_infoMyFunctor::operator()::arity, ::arg1_type, ::arg2_type, etc. Of course, it won't work if operator() is overloaded, but if there's a defined arity and argument type set, then you should only be talking about cv-qualification, and it strikes me as bad design to have a member function overloaded exclusively on cv-qualification --- this implies that the constness of the object affects its behaviour. Anthony -- Anthony Williams Senior Software Engineer, Beran Instruments Ltd. Remove NOSPAM when replying, for timely response. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Implicit conversions in dynamic_any / extract
On Fri, 22 Nov 2002 07:17:24 -0500, David Abrahams [EMAIL PROTECTED] wrote: Remy Blank [EMAIL PROTECTED] writes: Hello Boosters, I am trying to use dynamic_any to store either objects or pointers to (polymorphic) objects. I am able to extract a pointer to the base class of a contained object: class B { }; class D: public B { }; void Test() { any d(D()); B* pb = extractB(d); } This is alread quite useful. However the following code does not work: void Test2() { D d; any pd(d); B* pb = extractB*(pd);// pb = 0 char c; any AnyChar(c); int i = extractint(AnyChar); // bad_extract } So I have to know the exact type of the contained object and cannot rely on implicit conversions (D* - B* or char - int) to work. This is quite understandable from the fact that any wraps non-class types into unrelated classes. Now my question: is there a way to make these implicit conversions work? Heh. Boost.Python does it with a complicated class registry and upcast/downcast system. I don't know if you want to pay for that. Yes, if there's no better way. My best answer at the moment: explicitly register conversion functions from one type to the other in a mappairtype_info const, type_info const, void* (*)(void*) and look up the right function based on the type contained and the type requested. Oh, well, if you're willing to do that... I didn't say that. I said that that was my best current answer. I'm not satisfied with it, though. But there has to be a better way, hasn't it? Yes**. The mechanism in Boost.Python allows you to register just the relationships between adjacent base and derived classes, and it fills in the rest of the graph. Maybe it's time to refactor this code for general use in Boost... This sounds good. I'm trying to develop an introspection framework for C++ classes (and later dynamically created classes), so I will already have the inheritance information. I expect your implementation makes heavy use of typeid() and dynamic_cast? Other conversions would have to be registered explicitly (char - int, char const* - std::string, ...), possibly half-automated by using typelists and mpl algorithms. It's too bad that we have to replicate at runtime what the compiler already knows how to do at compile time (namely navigating inheritance hierarchies)... I have looked at Boost.Python, and it is very similar to what I had in mind. Would it be possible to make Boost.Python more general to describe C++ class information for runtime use, and have Boost.Python be a subset? I don't have a lot of time on my hands, but if you think this would be a good idea, I would love to give it a try (except that I'm a little scared by Boost.Python's complexity, and I don't know Python (yet)). BTW, how does Boost.Python compare to SWIG (http://www.swig.org/) ? It seems to supports Python, amongst others. The code is in libs/python/src/object/inheritance.cpp. I'll look into that. Thanks for the pointer. Best regards. --Remy Remove anti-spam sequence in reply address for a timely response. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Serialization XML (was Serialization Library
Since no-one seemed to notice my prior post which I think addressed some of these issues; I am reattaching it here. On Thu, Nov 21, 2002 at 07:45:55AM -0800, Robert Ramey wrote: My question is whether XML can capture an arbitrary C++ structure in a meaningful and useful way. So far no one has presented any XML that captures that one proposed example. I did. Well, I don't know that. In general it is extremely difficult to know ahead of time what facilities a serialization library would need to be permit an XML archive to be generated. One would have to take a the library, make changes necessary to provide the desired result and check to see what changes are necessary. You will not need any hooks; to fully bracket the data, you can use a type-conversion trick made concrete below. * Some approaches, including XML, allow a practically unlimited number of different ways to represent the same data. The user rather than the serialization library should choose the particular design. XSLT will allow this. As long as the serialization library can output to SOME form of useful XML (such as the hierarchical format I propose), the mapping between any particular schema and this format can be done as a relatively straight-forward stylesheet. In the current system the following concepts are orthogonal a) The description of the which data should be saved for each class (save/load/version) b) composition of the above to handle arbitrary C++ data structures (serialization) c) description of how fundamental types should be encoded as a byte stream into a storage medium (archive) Assuming that the questions in my Thought experiment could be answered in the afirmative. What would have to be added to this system to permit it to handle XML. Another concept has to be added - that of reflection. A useful XML representation needs the name of the variable. So some system needs to be designed to hold that information and keep it related to each serializable member. Presumably this would be a orthogonal concept d) Yes; I had proposed in an earlier email a seperate serializor which included the name strings: return o bar bar foo foo ... This would provide the needed names to the system. The trick below provides the required hierachical information. The XSLT provides user-customizable formats. Your existing system for bases classes can do the diamond work. Alternately, the normal streamer could be adapated to take these names by default, and ignore them simpler data streams. A clever use of macros might also make this automatic. Given this, without too much effort and maybe adding some virtual functions to archive one could add begin/end tags to archive. Of course many would object to this on efficiency grounds but it would be possible. But things start to appear. What about versioning? where does that fit into XML? But what about pointers, inheritance, etc. to properly capture this in XML one would have to start altering b) . Its the automatic composition that guarentees that this system can serialize/deserialize any C++ structure. I doubt this would be worth it. I think that these are non-issues. Write them into the hierarchy in whatever way is most convenient and still restorable. The user needs to decide how he wants to represent these things himself in the style-sheet. When deserializing, another style-sheet should fill in whatever extras the user dropped from the output XML; such as version numbers, etc. Of course, anyone is free to the the current serialization system and experiment to see what it would really take to accomodate XML. (After all, its should be easy if I'm wrong). But won't be me. Here is a start: (but also the end of my contribution; I just thought this type conversion was a neat trick that someone might want to use) --- // Example begins // Compiles and works with g++-2.95.4 #include iostream using namespace std; // Common Framework class object_stream; class streamer { protected: object_stream* m_impl; streamer(object_stream* stream) : m_impl(stream) { } public: template class T object_stream operator (const T x); friend class object_stream; }; class object_stream { protected: streamer m_helper; virtual void object_begin() = 0; virtual void object_end () = 0; public: object_stream() : m_helper(this) { } virtual ~object_stream() { } operator streamer () { // Casted on return from method object_end(); return m_helper; } // All fundamental types go here virtual object_stream operator (int x) = 0; // This catches all non-fundamental types and safely preserves // our type information while calling template class T
Re: [boost] functor adapter
From: Martin Bosticky [EMAIL PROTECTED] [...] Example: struct Option { string m_Name; string m_OptionParameters; }; vectorOption AVector_vec; ... // Find the preffered option vectorOption::iterator AVector_it = find_if ( AVector.begin(), AVector.end(), // // Identify when Option.vm_Member == c bind1st(adapt2ndArgumentOption(equal_tostring(), Option::m_Name), c) bindbool(equal_tostring(), bind(Option::m_Name, _1), c) ); ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Formal Review Request: class optional
Fernando Cacciola wrote: Dirk Gerrits wrote in message arjgo5$o25$[EMAIL PROTECTED]">news:arjgo5$o25$[EMAIL PROTECTED]... Fernando Cacciola wrote: [snip] void recieve_async_message() { optional rcv ; while ( !!(rcv = get_async_input()) !timeout() ) output(*rcv); } [snip] Maybe it's a minor point, but I think the !! is really ugly. Have you considered the safe_bool idiom that's used in some other Boost libraries? (smart_ptr to name one.) Yes, I did. safe_bool (among other alternatives) was rejected because of the following (this specific point is explained in detail on the documentation) Sorry, I only read your post, not the documentation. void foo() { optional opt = get_some(); bool is_it = opt; } What is the intention of 'is_it'? Does it refer to the 'value' of 'opt', or to its initialized state? Makes sense. Thanks for the explanation. The problem is that safe_bool allows for a conversion to bool in certain contexts, but this violates the design premise that there is no implicit conversion from optional to T for the case when T=bool. With the current design, the above will fail to compile, requiring the user to disambiguate the meaning by choosing either: bool is_it_initialized = !!opt; bool is_it_true = *opt ; For similar reasons, the following is not supported either: if ( opt == 0 ) or if ( opt != 0 ) But if you really dislike the syntax, there is an alternative spelling: if ( peek(opt) ) peek() returns a pointer to the optional value if it is initialized, or NULL if it isn't. Such a pointer can be directly used in a boolean context with the expected meaning. I guess I'd use if (peek(opt) != 0) or something. It's not that !! is so ugly, but it's not very clear IMHO. Dirk Gerrits ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
RE: [boost] BOOST_CHECK_EQUAL() dangers
From: Alisdair Meredith Gennadiy Rozental wrote: In majority of the cases when user is comparing two character pointers he need namely string comparison. Requiring to cast both sides to std::string is a big burden IMO. So I would choose solution 2. Could we not go with option three and a ne macro, BOOST_CHECK_EQUAL_STRING? With a bit of effort, you might even allow comparison of disparate string types (he says, pushing in a feature request!) IMHO, implementing a new macro would set a precedent for creating other equality macros for other types, which could get bloated quickly. I'd go with option 3 and std::string creation if you really want a string comparison. That forces the user to explicitly state which comparison they would like without cluttering up the test library. -Chris PS: first post - hi all ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: functor adapter
Thanks wery much for both commets, Douglas and Peter I will have a look at bind and lambda libraries but i remember i had trouble using the lambda library under VC6 together with bind1st Martin. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Implicit conversions in dynamic_any / extract
Remy Blank [EMAIL PROTECTED] writes: But there has to be a better way, hasn't it? Yes**. The mechanism in Boost.Python allows you to register just the relationships between adjacent base and derived classes, and it fills in the rest of the graph. Maybe it's time to refactor this code for general use in Boost... This sounds good. I'm trying to develop an introspection framework for C++ classes (and later dynamically created classes), so I will already have the inheritance information. I expect your implementation makes heavy use of typeid() and dynamic_cast? Yes. Other conversions would have to be registered explicitly (char - int, char const* - std::string, ...), possibly half-automated by using typelists and mpl algorithms. That's a whole different beast, since it involves creating a new object. It's too bad that we have to replicate at runtime what the compiler already knows how to do at compile time (namely navigating inheritance hierarchies)... I have looked at Boost.Python, and it is very similar to what I had in mind. Would it be possible to make Boost.Python more general to describe C++ class information for runtime use, and have Boost.Python be a subset? ?? There's no way that Boost.Python could be a subset of the facility we're talking about. It does way, way more than casting around an inheritance hierarchy. IOW, it's already way more general. I don't have a lot of time on my hands, but if you think this would be a good idea, I would love to give it a try (except that I'm a little scared by Boost.Python's complexity, and I don't know Python (yet)). I don't understand. The stuff in inheritance.cpp doesn't touch Python at all. It's pure C++. BTW, how does Boost.Python compare to SWIG (http://www.swig.org/) ? It seems to supports Python, amongst others. There's an outdated comparisons page at http://www.boost.org/libs/python/doc/comparisons.html. SWIG and Boost.Python are both much better now than when that was written. -- 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: Formal Review Request: class optional
- Original Message - From: Dirk Gerrits [EMAIL PROTECTED] To: [EMAIL PROTECTED] Sent: Friday, November 22, 2002 12:36 PM Subject: [boost] Re: Formal Review Request: class optional [snipped] I guess I'd use if (peek(opt) != 0) or something. It's not that !! is so ugly, but it's not very clear IMHO. Another supported alternative which I forgot to mention is: if ( initialized(opt) ) ... Fernando Cacciola ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Formal Review Request: class optional
Hi, I have one comment and one question. So first the comment I was recently thinking about a similar thing for a slightly different purpose. You seem to concentrate on option return values, what about optional arguments. e.g. void fn(int iImportant, optionalint iNotImportant = optionalint()); The reasoning for this is similar to for the return the function could tell if the user had passed in an argument and act accordingly Normally you can have a special default value but cases can occur where and int is valid but none might be required. The reason I assume you don't allow for this is that your constructor is explicit and for easier calling sytax in this case that would not be best (I think) i.e. I would want to be able to call the above as fn(1, 3); The most common reason, though, would be the desire to use references rather than pointers int fn1(optionalint iMayNotWant = optionalint()); instead of int fn2(int* piMayNotWant = NULL); I assume this isn't possible since references aren't default constructable but it would be nice :-) --- And now the question can this be used with VC6 ? I have tried at it won't compile (I'm compiling with boost 1.29) I get the following error in optional optional_detail.hpp(91) : error C2371: 'proxy' : redefinition; different basic types optional_detail.hpp(90) : see declaration of 'proxy' optional_detail.hpp(171) : see reference to class template instantiation 'boost::optional_detail::value_based_optionalT' being compiled and lots of errors in mpl\logical\and.hpp e.g mpl\logical\and.hpp(115) : error C2039: 'type' : is not a member of '`global namespace'' mpl\logical\and.hpp(115) : error C2146: syntax error : missing ',' before identifier 'value' and a lot more :-( Vin ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: implicit_cast
On Fri, 22 Nov 2002 13:48:01 +0200, Peter Dimov [EMAIL PROTECTED] wrote: From: David Abrahams [EMAIL PROTECTED] Here's what I think might be a correct implementation: template class T, class U T implicit_cast(U const x) { return x; } template class T, class U T implicit_cast(U x) { return x; } The correct implementation IIRC is templateclass T T implicit_cast(typename identityT::type x) { return x; } Nice. I'm curious: besides preventing a call to implicit_cast without an explicit specification of the destination type, is there any other reason why identity is used? Genny. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: New smart pointer library feature: debug hooks
Peter Dimov [EMAIL PROTECTED] wrote in message 00e101c29161$c6f16800$1d00a8c0@pdimov2">news:00e101c29161$c6f16800$1d00a8c0@pdimov2... When the macro BOOST_ENABLE_SP_DEBUG_HOOKS is defined, the Boost smart pointers will call the following debug hook routines: [...] Do you need this functionality personally, or have users requested this? Dave ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: New smart pointer library feature: debug hooks
From: David B. Held [EMAIL PROTECTED] Peter Dimov [EMAIL PROTECTED] wrote in message 00e101c29161$c6f16800$1d00a8c0@pdimov2">news:00e101c29161$c6f16800$1d00a8c0@pdimov2... When the macro BOOST_ENABLE_SP_DEBUG_HOOKS is defined, the Boost smart pointers will call the following debug hook routines: [...] Do you need this functionality personally, or have users requested this? Neither, really. It is mostly a proof of concept that debugging implementations are possible, as it has been suggested that the pointer constructor is too dangerous. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: Implicit conversions in dynamic_any / extract
On Fri, 22 Nov 2002 11:10:19 -0500, David Abrahams [EMAIL PROTECTED] wrote: Remy Blank [EMAIL PROTECTED] writes: I have looked at Boost.Python, and it is very similar to what I had in mind. Would it be possible to make Boost.Python more general to describe C++ class information for runtime use, and have Boost.Python be a subset? ?? There's no way that Boost.Python could be a subset of the facility we're talking about. It does way, way more than casting around an inheritance hierarchy. IOW, it's already way more general. This is not what I meant. The word subset was badly chosen. Sorry for the confusion. As I understand, Boost.Python features a class description and object management framework, which allows to describe the type of a class, its inheritance, the members it contains, and to instantiate, access and modify objects of these classes. This can be called an introspection and object management facility, can't it? That was the goal of the library I am trying to develop. Looking at Boost.Python, I saw that much (if not all) I needed was already there, and much more. So my question was: could the introspection and object management parts be separated from the Python-specific code? Agreed, my question was badly formulated. I don't have a lot of time on my hands, but if you think this would be a good idea, I would love to give it a try (except that I'm a little scared by Boost.Python's complexity, and I don't know Python (yet)). I don't understand. The stuff in inheritance.cpp doesn't touch Python at all. It's pure C++. I haven't yet looked at inheritance.cpp, but your comment confirms that there is some very generic, not Python-dependent, code in Boost.Python that provides the functionality needed for an introspection framework. Anyway, I'll dive into inheritance.cpp and friends, and if positive, I'll come back with a proposal. Thanks for your answers! Best regards. --Remy Remove anti-spam sequence in reply address for a timely response. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Formal Review Request: class optional
- Original Message - From: Vincent Finn [EMAIL PROTECTED] To: [EMAIL PROTECTED] Sent: Friday, November 22, 2002 1:38 PM Subject: [boost] Re: Formal Review Request: class optional Hi, I have one comment and one question. So first the comment I was recently thinking about a similar thing for a slightly different purpose. You seem to concentrate on option return values, what about optional arguments. e.g. void fn(int iImportant, optionalint iNotImportant = optionalint()); The reasoning for this is similar to for the return the function could tell if the user had passed in an argument and act accordingly Normally you can have a special default value but cases can occur where and int is valid but none might be required. Good point. On a few ocasions I have use optional to pass optional parameters. However, I've came to the following: Take you example for instance: void fn(int iImportant, optionalint iNotImportant = optionalint()) { if ( !!iNotImportant ) { // not important argument recieved, use it. foo ( * iNotImportant ) ; } } Since optional uses pointer semantics, the above code could have been written using a true pointer with nearly the same syntatic usage of the optional parameter: void fn(int iImportant, int* iNotImportant = NULL ) { if ( !!iNotImportant ) { // not important argument recieved, use it. foo ( * iNotImportant ) ; } } So, from the recieving function perspective, there is little -if any- benefit in using optional for this. The NULL default value for the pointer is idiomatic enough to document the fact that the parameter is optional. Now, from the caller perspective, using a pointer parameter has a drawback: the parameter must be an lvalue (it requires storage), so you can't write: fn(1,3) and you are forced to use a local variable: int b=3; fn(1,b); However, the true problem here is not that using a pointer in the function signature is cumbersome, but that passing it can be problematic if we want to use a literal (let's assume that prefixing '' is not big deal). I've found more convenient to solve this specific problem instead of cluttering a function interface with optional as a parameter. For example, if the optional parameter is constant: void foo ( int const* x = NULL ) ; You can pass literals on the fly using the following helper: templateclass T T const lvalue( T const v ) { return v; } int main() { foo(lvalue(3)); } And if the optional parameter is not constant, you can use a more sophisticated helper: templateclass T struct lvalue_wrapper { lvalue_wrapper( T val ) : data(val) {} operator T() const { return data ; } T* operator () const { return data ; } mutable T data ; } ; templateclass T lvalue_wrapperT lvalue( T v ) { return lvalue_wrapperT(v) ; } void bar( int* x = NULL ) ; int main() { foo(lvalue(3)); bar(lvalue(3)); } Concluding, I think optional is not really necessary for optional parameters since these can be expressed very well by a true pointers and that the calling syntax can be arranged to be simple . The reason I assume you don't allow for this is that your constructor is explicit and for easier calling sytax in this case that would not be best (I think) i.e. I would want to be able to call the above as fn(1, 3); The constructor must be explicit in order to disable unexpected implicit conversions. If you happen to use optional in a parameter list, you can always pass it using: fn(1, optionalT(3)); The most common reason, though, would be the desire to use references rather than pointers int fn1(optionalint iMayNotWant = optionalint()); instead of int fn2(int* piMayNotWant = NULL); Notice that optional itself has pointer semantics, so you wouldn't be able to handle iMayNotWant by value as you would if it were a reference; you would handle it exactly as you would if it were a true pointer. This is by it rarely makes sense to have optional in a parameter list. I assume this isn't possible since references aren't default constructable but it would be nice :-) Actually, optionalT does not require T to be default constructable. The reason why you can't have optionalT is -at least- that you cannot have a reference to a reference, and optionalT uses T {const} (for example, in the constructor). --- And now the question can this be used with VC6 ? Yes, that's my intention. I will see to make it compile with all compilers I receive reports from. Which version of VC6 are you using? I have tried at it won't compile (I'm compiling with boost 1.29) I get the following error in optional optional_detail.hpp(91) : error C2371: 'proxy' : redefinition; different basic types optional_detail.hpp(90) : see declaration of 'proxy' optional_detail.hpp(171) : see reference to class template instantiation 'boost::optional_detail::value_based_optionalT' being compiled and lots of errors in mpl\logical\and.hpp e.g mpl\logical\and.hpp(115) : error
RE: [boost] Do we need a boost_exception class or idiom?
Peter, It unfortunately reveals my true semantics of non-localized... I am getting better at internationalizing, though, which definitely should include your point, of mundanizing. In the argument about the what() between you, Dave and Bill, I must say that what() should reveal something according to my narrow semantics of non-localized, i.e., should be directly intelligible to most English-speaking developers. If it can *also* serve as a key to a localized (or, rather, an instance of an internationalized) lookup table, the better. Such a key is good. It is no secret that the Boost community, as the rest of the C++ world, tacitly assumes the developer to be English-speaking, so that developer-focused messages are in English (even biased to American word choices and spelling...) should not incur any problem, or? This implies that system information targetted at either the developer (as in a program error or tracing) or the service technician (as in the logging) can actually be in (American) English. But, there should be a way to map that message to a (Unicode or other) message for the end user, although I think the system catching the exception would probably present something less granular than the information contained in the exception anyhow, such as Could not read 'C:\Documents\Hello.txt'. Tackling the problem of localized messages in exceptions in a totally satisfying manner would most probably extend to the general problem of internationalizing, with resource files (explicit or embedded in the C++ code). That general problem is a big one (not very complex, but time-consuming...), and a Boost solution to that internationalizion, in order to be platform-independent, would have to interact with all the various predominant internationalization layers on the different platforms. What I am trying to say is that we should not try too hard to solve the internationalization of exception messages (I can see the worms...), an integer key is enough. The mechanism of getting the proper localized message is up to the developer (two applications of std::map or similar platform-specific mapping should do...) If we indeed add a boost_exception, which I think is a bad idea (since then the developer would have to either use the boost::boost_exception subgraph or the std::exception subgraph when picking a base class for his exceptions, unless we are comfortable with multi-inherited user exceptions), it should definitely include a unique key as a separate property, such as code(). /Tack för ordet/ David -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] On Behalf Of Peter Dimov Sent: Friday, November 22, 2002 7:12 AM To: Boost mailing list Subject: Re: [boost] Do we need a boost_exception class or idiom? From: David Bergman [EMAIL PROTECTED] I have always interpreted non-localized as comprehensible to some 60% of scientifically inclined Americans ;-) Looks like a joke but hides a relevant point. Sometimes you need to localize to plain (nontechnical) English, too. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Formal Review Request: class optional
Fernando Cacciola wrote: - Original Message - From: Dirk Gerrits To: Sent: Friday, November 22, 2002 12:36 PM Subject: [boost] Re: Formal Review Request: class optional [snipped] I guess I'd use if (peek(opt) != 0) or something. It's not that !! is so ugly, but it's not very clear IMHO. Another supported alternative which I forgot to mention is: if ( initialized(opt) ) ... Ooh. Nice! :) Dirk Gerrits ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
RE: [boost] Standard interface for adaptable function objects?
In general, accomplishing the mapping Dave sought seems to be a game of traversing alternative argument sets, properly embedded in template definitions, such as in Boost.Lambda. The problem would then be reduced (converted is a better word, since the resultant problem is not exactly simple...) to have a meta tool for traversing those templated argument sets. It looks like we have such a tool in MPL. It would be nice if one could use one template choice for each argument, to not have to write down N^M (where N are the number of types supported in this reverse type mapping, and M the maximum number of arguments supported) templates... I know a lot of this machinery is to be found in MPL. /David -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] On Behalf Of Anthony Williams Sent: Friday, November 22, 2002 4:05 AM To: Boost mailing list Subject: [boost] Standard interface for adaptable function objects? David Abrahams writes: Do we have any precedent for ways to find out what the arity and argument types of an arbitrary function object is (I'm not talking about function pointers, here, but functors)? Given that a functor might support more than one argument set, the only way I can think of is to say do you support this argument set? rather than what argument set do you accept?; in which case you can use the mechanism implemented in boost.lambda, and in my function composition library, to deduce the return type --- have a member template that takes a typelist representing the arguments you wish to pass, and returns the corresponding return type where that argument set is valid, or something else (such as invalid_argument_set) where it isn't (assuming you want to do something else in the case where it isn't, rather than just abort compilation) Does this give you what you want? Anthony -- Anthony Williams Senior Software Engineer, Beran Instruments Ltd. Remove NOSPAM when replying, for timely response. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] String algorithm library
Hi, This message is mostly for people who are interested in the string algorithm library. New version is in the sandbox. I have redesigned major part of the library, and I think that now its structure is in quite stable state. I want to start writing the documentation, but first I'd like to be sure, that the library will not change too much. ( I'm not very good documenter, and I hate to do this kind of things twice if I don't have to :) ) So I kindly ask you again, to post any comments, additions and proposals. Summary of changes: (i) General naming conventions have changed to be more compliant with STL naming scheme. It means that: - Non-mutable version of algorithm have suffix _copy. - Variants which take a predicate as a selector ( f.e. trim ) have suffix _if. - Find, replace and erase algorithm can have suffix _first, _last or _nth depending on the find functor thay you ( will be explained later ) Convention is that a semantic specification have precendece over parameters. so there is for example erase_first_copy and trim_left_copy_if. (ii) All trim functions have now _if variant which take a selection predicate as a parameter. There are 3 predefined functors available through contruct functions. Function names ar if_isclassified, if_isspace, if_isfrom. ( Check string_funct.hpp for details ) Standard version without suffix map to isspace predicate which I found most common. (iii) find-replace algorithms have been wholy redesigned. - string_algo::compare_traits and string_algo::search_traits has added. Element comparison predicate is now part of traits instead of being a parameter in algorithms. search_traits is a template defined over iterators and provides compare_function_type ( from compare_traits ) and range_type used as a return value for find functions. - all algorithms ( except for _all versions ) has been generalized. They now accept a find algorith as a parameter. There are 3 functors provided for this: find_firstF, find_lastF and find_nthF. User can write his own find function which is supposed to find range representin a subsequence in the given input sequence. For each algorithm there are wrappers for all default find functors. ( f.e there is replace - generic and replace_first, replace_last, replace_nth ) Algorithms included: (i) Trimming: trim, trim_left, trim_right. All in interator, sequence, mutable and non-mutable variants. There are also _if variants for all. (ii) Case conversion: to_lower, to_lower_copy, to_upper and to_upper_copy. (iii) Predicates: start_with (both iterator and sequence version), end_with (sequence version only), contains (both versions) (iv)Find algorithms: find, find_first, find_last, find_nth in iterator and sequence versions (v) Replace algorithms replace, replace_first, replace_last, replace_nth in iterator and sequence version. sequence version in mutable and non-mutable variant (vi)Erase algorithms Same as replace. Please check sources and test code in the sandbox for more datails and usage scenario. Last but not least, I'd like to ask what is needed for library to be commited for submission rewiev? Thats all folks. Regards, Pavol ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
RE: [boost] boost::pool feature requests
-Original Message- From: Alberto Barbati [mailto:[EMAIL PROTECTED]] 1) purge_memory() does not reset the member next_size Yes, this is in fact a bug, and it will be fixed. 2) the name release_memory() confuses me. It makes me think that all memory is being released, a task accomplished by purge_memory(). I think a better name could be release_unused_memory(). This function also should reduce the value of next_size, for example by considering the size of the largest block left in the pool. The current name will remain, for backwards compatibility. Does anyone else want a release_unused_memory alias? And it will also be updated to change next_size in a manner similar to the way you describe. 3) I would like to have a function to free the entire pool _without_ releasing the memory. The rationale for this is in the example above. Most probably, the number of objects allocated in each iteration of my application is almost the same. At the end of an iteration, I would like to free all allocated objects with one single call (as I have thousands of objects, it makes the difference) yet it's a waste of time to free the memory, because I will need the same amount again in the next iteration. Such function could be called free_all_chunks() or something similar. This should certainly be possible, and sounds reasonable; I'll look into it. 4) what's the use of ordered_alloc/ordered_free? I made a few tests and they are indeed a bit slower than regular alloc/free, without any apparent advantage. Am I missing something? Keeping the free list ordered allows algorithms that traverse the free list along with the memory owned by pool to work correctly/more efficiently: 1) array allocations will be more efficient (pool_allocator keeps its free list ordered, whereas fast_pool_allocator does not) 2) release_memory() will work correctly 3) object_pool uses the ordered property to efficiently implement the automatic destructor calls for allocated objects -Steve ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: functor adapter
On Friday 22 November 2002 10:53 am, Martin Bosticky wrote: Thanks wery much for both commets, Douglas and Peter I will have a look at bind and lambda libraries but i remember i had trouble using the lambda library under VC6 together with bind1st Martin. Bind will work on VC6, Lambda will not. Doug ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
RE: [boost] Re: Formal Review Request: class optional
Good point. On a few ocasions I have use optional to pass optional parameters. However, I've came to the following: Take you example for instance: void fn(int iImportant, optionalint iNotImportant = optionalint()) { if ( !!iNotImportant ) { // not important argument recieved, use it. foo ( * iNotImportant ) ; } } Since optional uses pointer semantics, the above code could have been written using a true pointer with nearly the same syntatic usage of the optional parameter: void fn(int iImportant, int* iNotImportant = NULL ) { if ( !!iNotImportant ) { // not important argument recieved, use it. foo ( * iNotImportant ) ; } } We already talked about this: pointer will add extra memory access, optional should not (in fact it should be inlined and won't be different from by value parameter) The constructor must be explicit in order to disable unexpected implicit conversions. Some may still prefer sometime foo(3) to foo(lvalue(3)); foo(optionalT(3)); implicit conversion to optional should not be dangerous anyway. Actually, optionalT does not require T to be default constructable. The reason why you can't have optionalT is -at least- that you cannot have a reference to a reference, and optionalT uses T {const} (for example, in the constructor). use add_reference instead? Gennadiy. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Do we need a boost_exception class or idiom?
Peter Dimov wrote: [...] My answer is that specifying the precise semantics of what() for every documented exception type is a necessary prerequisite. (Implies that the standard needs to be fixed, too.) [...] Would it be worthwhile to define a different member function (possibly in a std::exception-derived boost_exception) that returns the precisely specified key that you desire (rather than changing the requirements for what())? Perhaps boost_exception.key()? Dave ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Formal Review Request: class optional
- Original Message - From: Vincent Finn [EMAIL PROTECTED] To: [EMAIL PROTECTED] Sent: Friday, November 22, 2002 1:38 PM Subject: [boost] Re: Formal Review Request: class optional And now the question can this be used with VC6 ? Yes :-)) I've uploaded the new version which compiles and runs properly with VC6.0 NOTE: I've found when running the test that VC6.0 creates a temporary copy in the following situation: void foo() { MyStruct v = 2; optionalMyStruct opt(v); (*opt == v ) ; // A temporary copy of the value inside 'opt' is created here! } The weird thing is that (*opt) is a proxy with a 'operator T const() const' and this operator *is* called -as can be seen with the debugger- but only to create the temporary that is passed to operator == Anyway, with a small twist of the test it now passes with VC6.0 Fernando Cacciola ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Do we need a boost_exception class or idiom?
Peter Dimov wrote: From: David B. Held Peter Dimov wrote: My answer is that specifying the precise semantics of what() for every documented exception type is a necessary prerequisite. (Implies that the standard needs to be fixed, too.) Would it be worthwhile to define a different member function (possibly in a std::exception-derived boost_exception) that returns the precisely specified key that you desire (rather than changing the requirements for what())? What _are_ the requirements for what()? Well, as you were saying, that it return a unique documented value for each exception type. Or did I not understand you correctly? Dave ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Do we need a boost_exception class or idiom?
From: David B. Held [EMAIL PROTECTED] Peter Dimov wrote: From: David B. Held Peter Dimov wrote: My answer is that specifying the precise semantics of what() for every documented exception type is a necessary prerequisite. (Implies that the standard needs to be fixed, too.) Would it be worthwhile to define a different member function (possibly in a std::exception-derived boost_exception) that returns the precisely specified key that you desire (rather than changing the requirements for what())? What _are_ the requirements for what()? Well, as you were saying, that it return a unique documented value for each exception type. Or did I not understand you correctly? You said: (rather than changing the requirements for what()). What are the requirements for what() that I, supposedly, want changed? ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
RE: [boost] Re: Formal Review Request: class optional
We already talked about this: pointer will add extra memory access, optional should not (in fact it should be inlined and won't be different from by value parameter) You are mis-remembering our previous talk. No. I do remembr that we agreed that pointer semantics is better. I still agree with that. Nevertheless my point above was following: Even if optionalT has pointer semantics, unlike pointers *optionalT won't produce extra memory access. implicit conversion to optional should not be dangerous anyway. I disagree. Implicit conversions are usually problematic, but with optional, it is even worst, since (1) a conversion from an uninitialized optional is undefined -^ we talked about to conversion (2) the distinction between (a) the operation of testing whether an optional is initialized or not (b) the operation of accesing the optional value (in this case via a conversion) we talked about to conversion Maybe, but actually, I don't think optional should work with references. It is supposed to wrap a 'value', not a reference/pointer. Fernando Cacciola Why? I always did not like the fact that I need to switch to pointers when my reference argument became optional. Gennadiy. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Serialization XML (was Serialization Library
In-Reply-To: [EMAIL PROTECTED] On Fri, 22 Nov 2002 15:33:47 +0100 Wesley W. Terpstra ([EMAIL PROTECTED]) wrote: You will not need any hooks; to fully bracket the data, you can use a type-conversion trick made concrete below. It's a neat trick, but I'd rather not rely on tricks. I might want: ar one two three; //... ar four five six; return ar; to all be serialized as a single group. I'd rather have a clean design at bottom, with a layer of tricks on top for people who want the convenience. Eg: ar start_group(); ar one two three; //... ar four five six; ar end_group(); return ar; or: grouper raii(ar); ar one two three; //... ar four five six; return ar; or: return grouper(ar) one two three four five six; all producing the same archive data. Yes; I had proposed in an earlier email a seperate serializor which included the name strings: return o bar bar foo foo ... This would provide the needed names to the system. As I understood it, this also relied on a trick - on the XML oarchive assuming that alternate writes were names rather than values. If we sent the same output to a different oarchive, it presumably wouldn't make that assumption and they would be treated as values and repeated in the data of each object serialised. That is quite an overhead. The alternative, that non-XML archives also ignore alternate string writes, is bad too because one archive format should not have to work to indulge vagarities of another. A third alternative, for the object to somehow know when it is writing to an XML archive and serialise differently, is also bad. I think such tricks are a bad way to go. I would much rather have something explicit like: ar tag(bar) bar tag(foo) foo; where the oarchive has a virtual function for writing tags. This also allows: ar tag(point) x y; where there is no need for the tags to alternate with values. It'd be possible to implement such stuff on top of the current submission, without adding virtual functions to the base classes, by using dynamic_cast. Eg: struct tag { tag( const char *str ) : str(str) {} const char *str; }; basic_oarchive operator( basic_oarchive ar, const tag t ) { if (basic_tagged_oarchive *p = dynamic_castbasic_tagged_oarchive *( ar )) p-tag( t.str ); return ar; } where basic_tagged_oarchive inherits from basic_oarchive, and xml_oarchive inherits from basic_tagged_oarchive. (I imagine there may be other types of tagged archive, such as for HTML or for human-readable output, such as debugging or error-logging.) Personally I'd rather add the virtual functions, because I prefer to avoid dynamic_cast. I'd rather have dynamic_cast than make assumptions about alternate writes, though. Really we are just talking about 3 functions: start_group(), end_group() and tag(). People who don't need XML output wouldn't need to use them. In practice I think using them would help a lot in producing human readable output. We could probably get rid of the newline() function, for example. -- Dave Harris ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
RE: [boost] Re:Serlialization Library
In-Reply-To: [EMAIL PROTECTED] On Tue, 19 Nov 2002 21:38:09 -0800 Robert Ramey ([EMAIL PROTECTED]) wrote: How do we intialize the const member? MyClass::MyClass( basic_iarchive ar ) : i(loadint(ar)) { } What about version 2 MyClass::MyClass( basic_iarchive ar ) : i( loadint(ar) ), j( version(ar) = 2 ? loadint(ar) : 0 ) { } In some cases it would be simpler to give up the const member: MyClass::MyClass( basic_iarchive ar ) { version_type v = version(ar); if (v 0 || v 2) throw unexpected version; ar i; if (v = 2) ar j; } The first 3 lines should be refactored into a single function, and it is best to start version numbers at around 10, so the real code would be: MyClass::MyClass( basic_iarchive ar ) { version_type version = version( ar, 10, 11 ); ar i; if (v = 11) ar j; } given the above, I never even got to the point of considering how to get the version number out of the stream at the right time. maybe it easy. I never thought about it. OK. I'll drop it. It can probably be done without support from the core library anyway. -- Dave Harris ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] RE: Serialization Library Review
In-Reply-To: [EMAIL PROTECTED] On Tue, 19 Nov 2002 08:09:13 +0100 Matthias Troyer ([EMAIL PROTECTED]) wrote: The only solution which comes to my mind is additional virtual functions for writing blocks of primitive types, which default to just calling the operator () n times, but can be overridden by optimized functions for those archive types where optimized writes (load) are possible. Nothing else would need to be changed. What is objectionable in that approach? Well, it is a lot of new virtual functions - one per type, almost doubling the size of the archive interface. Is it worth it? I am inclined to say it is, because I generally favour giving the archive more information about what is going on. And efficiency matters, especially for such a fundamental library as serialisation. It does not lead to more work for serialisation users or for the archive implementers. Still, it is a lot of new functions, and once added they can never be taken away. It may be better to leave them out now, and add them in 12 months time, when we have had more experience with the library and its cost. Incidently, an alternative would be to add the new virtual functions but remove the current ones, replacing them with non-virtual, inline versions which just use a count of 1, eg: basic_oarchive operator( basic_oarchive ar, int x ) { ar.save( x, x+1 ); } This makes some overhead for the single-int case. I have no idea whether the cost is worth the benefit in practice. -- Dave Harris ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: Do we need a boost_exception class or idiom?
Peter Dimov [EMAIL PROTECTED] wrote in message 01d801c29268$c6496cb0$1d00a8c0@pdimov2">news:01d801c29268$c6496cb0$1d00a8c0@pdimov2... From: David B. Held [EMAIL PROTECTED] [...] Well, as you were saying, that it return a unique documented value for each exception type. Or did I not understand you correctly? You said: (rather than changing the requirements for what()). What are the requirements for what() that I, supposedly, want changed? Ah...I see. It is that you want to increase the requirements for what, since there really are no requirements presently. By change, I meant increase (which is a change, no?). Dave ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: Do we need a boost_exception class or idiom?
From: David B. Held [EMAIL PROTECTED] Peter Dimov [EMAIL PROTECTED] wrote in message 01d801c29268$c6496cb0$1d00a8c0@pdimov2">news:01d801c29268$c6496cb0$1d00a8c0@pdimov2... From: David B. Held [EMAIL PROTECTED] [...] Well, as you were saying, that it return a unique documented value for each exception type. Or did I not understand you correctly? You said: (rather than changing the requirements for what()). What are the requirements for what() that I, supposedly, want changed? Ah...I see. It is that you want to increase the requirements for what, since there really are no requirements presently. By change, I meant increase (which is a change, no?). Yes, but the change is fully backward compatible, as far as the standard is concerned. There are also the implicit requirements on what() that everyone seems to take for granted, that what() produces a human readable string that contains (some form of) useful information about the reason for the failure. The interesting thing to note is that my proposed changes to what() actually make it better suited for this purpose, too, something that's not immediately obvious. ;-) ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: Formal Review Request: class optional
Rozental, Gennadiy [EMAIL PROTECTED] wrote in message [EMAIL PROTECTED]">news:[EMAIL PROTECTED]... We already talked about this: pointer will add extra memory access, optional should not (in fact it should be inlined and won't be different from by value parameter) You are mis-remembering our previous talk. No. I do remembr that we agreed that pointer semantics is better. I still agree with that. Nevertheless my point above was following: Even if optionalT has pointer semantics, unlike pointers *optionalT won't produce extra memory access. OK. Now I understand what you meant, sorry. You are right, the dereference from an optionalT parameter won't compile as an extra indirection as will be the case with a true pointer. A good point if performance is important at this level. implicit conversion to optional should not be dangerous anyway. I disagree. Implicit conversions are usually problematic, but with optional, it is even worst, since (1) a conversion from an uninitialized optional is undefined -^ we talked about to conversion (2) the distinction between (a) the operation of testing whether an optional is initialized or not (b) the operation of accesing the optional value (in this case via a conversion) we talked about to conversion OK, I missed your point again. Two sorries :-)) Your are asking why can't the constructor be not explicit, right? Well, this would allow the 'direct' syntax fn(1,3) that Vincent wanted, but... It would entirely break the pointer semantics because the following would be allowed: void foo() { optionalint opt ; opt = 3 ; // This will construct a temporary optionalint(3) if ( opt == 0 ) // tmp optionalint(0) here. } Maybe, but actually, I don't think optional should work with references. It is supposed to wrap a 'value', not a reference/pointer. Fernando Cacciola Why? I always did not like the fact that I need to switch to pointers when my reference argument became optional. Wait... maybe I keep misundestanding you, but... Even if it would be allowed to have optionalint, you would still have to use it as if it were a pointer: void foo ( optionalint p = optionalint() ) { if ( !!p ) // or ( peek(p) ) or ( initialized(p) ) { int the_p = *p ; the_p = 3 ; etc... } } So you still gain little, from foo() perspective, by using optional since you can write it almost exactly the same as: void foo ( int* p = NULL ) { if ( !!p ) { int the_p = *p ; the_p = 3 ; etc... } } -- Fernando Cacciola ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: sub string and string algo.
On Fri, Nov 22, 2002 at 02:03:49PM -0500, Alexei Novakov wrote: Pavol Droba [EMAIL PROTECTED] wrote in message [EMAIL PROTECTED]">news:[EMAIL PROTECTED]... Hi, On Thu, Nov 21, 2002 at 02:48:09PM -0500, Alexei Novakov wrote: [snip] Alexei. Cool, I'd definitely use it Seeing as there is a move to submit a library of string helpers at the moment it might be worth submitting this at the same time! Vin I think that these two libs (sub_string and string_algo) could benefit from each other. How do I share the code so that members could see it and try it? Alexei. I'm working on the string_algo library. It has a different orientation in some way, but I think there are places in which these two libs can benefit from each other. There is the boost sandbox cvs and you can read about it from boost web page. If you gain access to is, you can have a look into my string_algo lib. Then we can maybe try to find out where we could join our efforts. Regards, Pavol Oh yes, I did so some time ago and played with string_algo. It seams to me that more convenient and natural return type for kinds of trimmers and sub_string extractors would be dedicated sub_string class rather than pair of iterators. You are using a little bit different approach - your algorithms are sequence oriented rather than string oriented. On one hend string is a sequence of chars, but on the other there is a good reason why dedicated string class was introduced instead of vectorchar. Consider the code: string str( ***123 ); sub_string ss = trim(str); // ss == ***123, but no allocation is done yet. // work with ss as with basic_string. // We need to do another trim. ss = left_trim(ss, *); // ss == 123, still no allocation. // Let's create real string now; string str1 = ss; // str1 == 123 sub_string is not really usable without a good set of string oriented algorithms, as well as algorithms look pretty bulky without being backed up by good utility classes. What do you think? Well, in the current state, the string_algo library provides a generic set of string related algorithm. There are many reasons I choose to support any sequence not just the string. I understand quite well, that in most cases the lib will be used with variants of a the string, however I don't like to sacrifice functionality in the favor of general pattern when it is not needed. As you can see, library is not just about trim function for which the usage of substring is very obvious. For most of others in the current implementation the usage of substring is questionable. There are places however where we benefit from each other. For example ther was proposal for functions like substr_until( const string str, const string substr ) which should give you the string from beginning until the first occurenc of the substr. This looks like perfect contructor for your sub_subtring. Also find algorithms can be used for sub_string construction If I thinking about joining, I have one idea. In the similar way you have substring, if may be possible to define generic sub_sequence class which would adapt to a sequence container. I think this could be quite handy and I assume that with a little bit of refactoring you can make the sub_string class a specialization of this generic sub_sequence. Such a class could be then easily integrated with string_algo. So what do you think aboout this? Pavol ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
RE: [boost] Re: [MPL Lambda]
David B. Held wrote: For your own metafunctions, you have to intrude them a little bit, but otherwise it works as well: template typename T struct f { typedef T type; BOOST_MPL_AUX_LAMBDA_SUPPORT(1,f,(T)) // here }; [...] I assume it's safe to have this stuff in even for compilers that don't need it? Yes. If I recall, it gets evaluated to nothing on conforming platforms? Yes. Also, I assume the first argument is the arity, and the last argument is a parenthesized list of the template parameters? Exactly! Aleksey ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: Implicit conversions in dynamic_any / extract
Remy Blank [EMAIL PROTECTED] writes: On Fri, 22 Nov 2002 11:10:19 -0500, David Abrahams [EMAIL PROTECTED] wrote: Remy Blank [EMAIL PROTECTED] writes: I have looked at Boost.Python, and it is very similar to what I had in mind. Would it be possible to make Boost.Python more general to describe C++ class information for runtime use, and have Boost.Python be a subset? ?? There's no way that Boost.Python could be a subset of the facility we're talking about. It does way, way more than casting around an inheritance hierarchy. IOW, it's already way more general. This is not what I meant. The word subset was badly chosen. Sorry for the confusion. OK As I understand, Boost.Python features a class description and object management framework, Not sure what you mean by object management, but OK... which allows to describe the type of a class, its inheritance, the members it contains, and to instantiate, access and modify objects of these classes. Well, yeah, but from Python. This can be called an introspection and object management facility, can't it? Sort of. A big part of what it does is concerned with exposing C++ functions to Python. That was the goal of the library I am trying to develop. I'm trying to imagine what you have in mind. How could this library be used? Why would one use your library vs., for example, Boost.Python? Looking at Boost.Python, I saw that much (if not all) I needed was already there, and much more. So my question was: could the introspection and object management parts be separated from the Python-specific code? I'm not sure which parts you think those are. However, factoring out Python-independent functionality is probably a good idea in general, and has been discussed a few times on this list. One obvious reason to do so would be to build new back-ends for different languages. I don't have a lot of time on my hands, but if you think this would be a good idea, I would love to give it a try (except that I'm a little scared by Boost.Python's complexity, and I don't know Python (yet)). I don't understand. The stuff in inheritance.cpp doesn't touch Python at all. It's pure C++. I haven't yet looked at inheritance.cpp, but your comment confirms that there is some very generic, not Python-dependent, code in Boost.Python Yes. that provides the functionality needed for an introspection framework. I'm not as sure about that part. I'd have to see what you're talking about first. -- 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: Serialization Library Review
I have been following the discussion thread for the serialization library review with some interest, as I think the topic is of extreme importance. Right up there with smart pointers and threading, it's something that would be used by many people for many different things. I want to thank Robert for the obviously extensive amount of thought and effort that he has put into this. I have this nagging feeling, though, that we all need to step back for a moment and re-examine our first principles. Based on reading the documentation, carefully reading the discussion from Unicode support to XML archive formats, to registration issues, etc, and based on my own thoughts on the subject, I get the distinct impression that we're not at all in agreement about what exactly a serialization library is supposed to do. From the documentation, it is clear that Robert is most familiar with MFC's serialization mechanism, and the library follows in that general mold. He also states that this is a serialization library, and not a persistence library (like what you find with an OO database). I think that this is an extremeley important point that I don't remember really being discussed at all. The discussion about alternate archive formats, especially XML, CSV, and other formats for interchange with other systems, make sense in the context of serialization. A discussion questioning whether these formats could truly represent all C++ structures (especially diamond inheritance) ensued, but this point is only relevant to persistence, not to serialization. Because I think that a lot of the discussion hinges around this point, I'm going to venture to make a distinction, and I'd like to know if people agree. Persistence: A transformation-less transfer of application native data to an alternate storage medium. Only useful and only intended to be useful to applications that apriori agree on object type and layout, presumably by sharing headers. May optionally account for differences in architecture or compiler. Must be symmetric--support both store and load. Alternate storage formats would only differ for effeciency reasons, perhaps at the expense of not supporting constructs not needed by a given application. Serialization: A transformation of application native data into a serial intermediate exchange format specified by the application writer. Whether objects can be read back in an order different than they were stored, or if there is any object identification of any kind, is up to each individual format. Because it is not presumed that applications share apriori knowledge, it may be necessary to include meta-data regarding data types. Various structuring mechanisms may be used, coming in various flavours--header, pre/post tags, post (ie,terminated), length prepended, packeted, etc. Metadata may be independant or mixed with structure. Also, it is not presumed that all expressable object layouts or relationships can be serialized to all possible formats; it is the responsibility of the format writer to account for this. Often, only store or load will be supported--the symmetric operation is performed by the application one is exchanging data with (really, the point of the excersise). The library up for review strikes me as a serialization library intended to function as a persistence library, and I think this sparked everyone to ask for different things in the confusion. To me, a persistence library must take into account object factories, object lifetime management, versioning, and should be fairly transparent (praying for MPL magic here), while a serialization library must deal with the archive format issues and explicit conversion logic. While either task is huge, I really think we need to clarify the purpose and scope of a boost serialization library that we would accept--that's only fair to Robert. So here's my thoughts: 1) We explicity acknowledge that persistance is a seperate topic requiring a seperate, mostly unrelated, library. It is very important itself, but we should start a different thread later. That thread should talk about factories and lifetime management, and not get confused about whether or not XML is pertinent (it's not, keep it on this thread). 2) Assuming I can now focus on serialization, the most important requirement relates to what styles of archive can be generated. In other words, defining the set of hooks in the serialization process to insert tags and/or metadata. For starters, very simple examples demonstrating JPEG style headers, XML style pre/post tags, SWF style length prepended tags, CSV style terminated lists, and perhaps protocol style packets. 3) We understand that the library still requires that archives be written. A couple of the examples should probably be useful, but other boost members should be encouraged to write and submit archives for their own pet format. 4) Having introduced tags and metadata issues, escaping schemes need to be introduced.
[boost] RE: Serialization Library Review
Date: Fri, 22 Nov 2002 16:34:46 -0800 (PST) From: Augustus Saunders [EMAIL PROTECTED] Persistence: A transformation-less transfer of application native data to an alternate storage medium. Only useful and only intended to be useful to applications that apriori agree on object type and layout, presumably by sharing headers. May optionally account for differences in architecture or compiler. Must be symmetric--support both store and load. Alternate storage formats would only differ for effeciency reasons, perhaps at the expense of not supporting constructs not needed by a given application. Serialization: A transformation of application native data into a serial intermediate exchange format specified by the application writer. Whether objects can be read back in an order different than they were stored, or if there is any object identification of any kind, is up to each individual format. Because it is not presumed that applications share apriori knowledge, it may be necessary to include meta-data regarding data types. I edited out alot of the message that expanded upon these definitions. I think the distinction is important. But actually I think the definitions should interchanged !!! The goals of the serialization library are clearly stated in the first part of the documentation. Basically it is to be able to convert of any arbitrary structure of data created by a C++ program into a string of bytes and back again. I called this Serialization to distinguish it from other data storage methods that have a diffferent purpose. I didn't try to define Persistence as I see it as a more general notion. Other data storate/recovery methods have different focus. e.g. Database systems support a relational algebra accross multiple platforms and languages. Other things are considered important such as transactional integrity, security, logging and rollback, etc that are not of interest in this context. XML, as I understand its motavation, attempts to package data along with its metadata in a more general way to promote portability across different applications. No logically transparent system can address all of these situtations. They conflict in fundamental ways. Of course, it can be proved that all data is equivalent in some sense, but in the sense that we use it an think about it its not equivalent. We impose a structure to think about it operators to manipulate it in accordance with a larger purpose. The archives used for serialization ar really small bridges to the i/o system. Attempts to make them something they are not can only lead to a system which lacks elegance and simplicity and is hard to use for its intended purpose. I realize that the system as presented can benefit from some improvements. But, as far as I know, there is no system which addresses so comprehensively the question of Serialization (as I have used it). I could find no such system. Certainly none has been submitted has been submitted to boost. That's why I wrote this one. I was strongly influenced by my experience with Microsoft MFC. It was a basically a good and useful system with a fair number of short comings that I sought to remedy. I believe I have largely accomplished that purpose. Thats all for now. I will have much more to say on this topic in the coming days. Robert Ramey ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] FW: Serialisation library review
Note: This was sent directly to me by Pavel Vozenilek. I am posting it to the list. Robert Ramey I recommend to accept serialisation library into Boost. I played with the library for few hours and used Intel C++ 6.0 plugged in Visual C++ 6.0 IDE (and Visual C++ 6.0 STL) to compile examples and debug the code. I also read the documentation available. I like the library interface: within C++ limits it is minimal and natural. I had coded serialisation code few times in similar way (and didn't like to write the infrastructure over and over). The implementation needs a quite lot of effort to understand: probably more comments on internal structures would help. From pragmatic point of view I see this as the smallest problem. The documentation is IMHO the weakest point. Serialisation probably isn't highest priority for application programmer and lack of easily understandable documentation can drive him/her of this library to some ad-hoc quick and dirty code. I recommend: - complete redo of the documentation (the text should be made more clear on many places), - many more of code examples in documentation (and these being complete and compilable), - the code examples should have different background, e.g. like it is in Spirit library documentation, it is then much easier to read them, - reference documentation should be broken into few parts, More issues are in attached text file. None of them, however looks to me as showstopper. /Pavel _ Help STOP SPAM with the new MSN 8 and get 2 months FREE* http://join.msn.com/?page=features/junkmail -- MAJOR ISSUES: 1) Is there any exception for disk-full error? Also exception for invalid state stream should exists. 2) function text_archive.init() should not call seekp(0). The stream may contain other data that would be overwritten. 3) This is a bit nitpicking: volatile members/pointers/classes may be also serialised. Currently it doesn't work. 4) I could not make demo.cpp working: there's some problem with is_polymorphic. I will be glad to provide more info if asked. 5) function get_guid() isn't mentioned in the documentation. -- MINOR ISSUES: 1) Is there any possibility to plug-in compression of data (or make archive subclass for it)? If, can it be documented with small example? 2) Likewise, is there any chance to plug-in OS specific file routines? (e.g. WIN32 non-buffered reads and/or scattered reads/writes). This may be important for performance reasons. 3) If exception happens during writing data to file, shouldn't the stream be rewinded back to original position? 4) set, multiset, hash_set and hash_multiset don't seem to be included in stl.hpp. Also maybe rope ('big string' from SGI STL) can be included. 5) The function text_archive::newtoken(): does it really need to be virtual function? It is pretty big overhead to call it for each member field. -- CONSISTENCY CHECK SUPPORT: (manually written serialisation code can be very dangerous during maintenance) 1) Can consistency between save() and load() functions supported? I mean e.g. number of items saved/loaded needs to be the same, their names/types the same etc. Maybe if there is macro or runtime parameter to enable/disable this type of check. 2) Can we have some function returning size of data being written for an object? It could be used for checking, like: void AClass::save(...) { ar field1; ar field2; ... assert(sizeof(AClass) == ar.writtenBytes()); // check } (Such a check is applicable only under circumstances.) 3) Can we have save()/load() functionality merged together not to duplicate code and make hand-written code safer? Something like: void load_save(..., bool is_saving) { ar.load_or_save(field1, is_saving); ar.load_or_save(field2, is_saving); } Maybe such a functionality can be provided in addition to current code. 4) Can there be library version (maybe enabled/disabled by macro) that doesn't require (and doesn't store) version()? This may be of use for high performance stable systems. 5) Can the call to base class save()/load() from derived save()/load() be recognized (and assert()ed) in debug version? (As opposite to valid call base_object().) -- DOCUMENTATION ISSUES: 1) Can space requirements be documented for ASCII/UNICODE/binary archiving? Can it be documented on example? 2) First example in tutorial.html includes iostream twice. Also using namespace std; is missing. ofs.close() should be replaces by ifs.close(), ar by ia. Also information what *.cpp file to add to the project
[boost] FW: The results of your email commands
From: Alberto Barbati [EMAIL PROTECTED] One note: the library, as it is, *does not* support Unicode output, as stated. [snip] Well I quadriple checked and ran your example and of course you are right. The text archive eliminated the high order byte. I have addressed the problem with the code below. Naturally there is an analogous alteration in the output archive. My reasoning is as follws text files created/read as part of serialzation are not designed to be read/interpreted by humans. The important thing is that the store all the data and recover it without alteration. Since archives might be passed accross locales, all serlialzation files should use the same locale. Of course that locale should correctly support wide characters and not alter the data. The text should be embeddible in other texts.So the system is: Open the archive save the current locale create a new locale classic + override for codecvt facet to supress code conversion use archive OnClose restore previous locale. This seems to me to address the issues of wide characters. Robert Ramey / // class text_iarchive - read serialized objects from a input text stream templateclass Stream, class Elem class text_iarchive : public basic_iarchive { private: class codecvt : public std::codecvtElem, char, mbstate_t { virtual bool do_always_noconv( ) const{ return true; } public: codecvt() : std::codecvtElem, char, mbstate_t(1) {}; } archive_codecvt; // locale when stream was passed here std::locale previous_locale; // use special local for serialization - no character conversion std::locale archive_locale; // stream which contains the archive Stream is; public: virtual void init(){ basic_iarchive::init(); } text_iarchive(Stream _is) : is(_is), archive_locale( std::locale::classic(), archive_codecvt ) { // archives always use classic locale #ifndef BOOST_NO_STD_LOCALE previous_locale = is.imbue(archive_locale); #endif init(); } ~text_iarchive(){ #ifndef BOOST_NO_STD_LOCALE is.imbue(previous_locale); #endif } - Done. ---BeginMessage--- Date: Tue, 12 Nov 2002 23:07:19 +0100 From: Alberto Barbati [EMAIL PROTECTED] One note: the library, as it is, *does not* support Unicode output, as stated. [snip] Well I quadriple checked and ran your example and of course you are right. The text archive eliminated the high order byte. I have addressed the problem with the code below. Naturally there is an analogous alteration in the output archive. My reasoning is as follws text files created/read as part of serialzation are not designed to be read/interpreted by humans. The important thing is that the store all the data and recover it without alteration. Since archives might be passed accross locales, all serlialzation files should use the same locale. Of course that locale should correctly support wide characters and not alter the data. The text should be embeddible in other texts.So the system is: Open the archive save the current locale create a new locale classic + override for codecvt facet to supress code conversion use archive OnClose restore previous locale. This seems to me to address the issues of wide characters. Robert Ramey / // class text_iarchive - read serialized objects from a input text stream templateclass Stream, class Elem class text_iarchive : public basic_iarchive { private: class codecvt : public std::codecvtElem, char, mbstate_t { virtual bool do_always_noconv( ) const{ return true; } public: codecvt() : std::codecvtElem, char, mbstate_t(1) {}; } archive_codecvt; // locale when stream was passed here std::locale previous_locale; // use special local for serialization - no character conversion std::locale archive_locale; // stream which contains the archive Stream is; public: virtual void init(){ basic_iarchive::init(); } text_iarchive(Stream _is) : is(_is), archive_locale( std::locale::classic(), archive_codecvt ) { // archives always use classic locale