[boost] Re: adaptable_any vs any_with
Douglas Gregor wrote: Between the two: adaptable_any is better, I think. Because I like throwing wrenches: have you considered a very different name such as polymorphic or just poly. The idea is that we read: polyless_than_comparable, equality_comparable as a type that is polymorphic over all less_than_comparable equality_comparable types. And because I'm feeling silly and reading a book on lattice theory... it could also be named models_meet, as in a type that models the meet of the following concepts in the concept lattice. Doug Both suggestions are too extreme, IMHO. -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: variant questions
Eric Friedman wrote: But suppose I have a variant v3, with content of a different type (call it T3). Then the assignment v1 = v3 is far more complicated (we can't use T1::operator=) and, without double storage, far more dangerous. The single storage implementation behaves as follows: destroy v1 content copy v3 content into v1 Assuming that memcpy to new location followed by memcpy back to original allocation is safe, you would do it using two additional storages local to operator= function. Let's call them local1 and local2. memcpy variant storage containing value1 into local1 initialize variant storage with copy of value3 content (may throw) memcpy variant storage containing value3 into local2 memcpy local1 back to variant storage destroy the content of variant storage (value1) memcpy local2 back to variant storage If second line of the algorithm above throws then: memcpy variant storage containing value1 into local1 initialize variant storage with copy of value3 content (throws!) memcpy local1 back to variant storage Too complicated? may be ... -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: variant questions
Eric Friedman wrote: If I understand you correctly, earlier versions of variant did precisely what you describe. Unfortunately, the assumption you make is false in general. See http://aspn.activestate.com/ASPN/Mail/Message/boost/1311813. Eric Well, is_polymorphicT based on compiler properties beyond the standrad. Why not optimize variant for compilers which safely memcpy forth and back? -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: [boost.variant] It is possible to make a variant LessThanComparable
David Abrahams wrote: Dirk Schreib [EMAIL PROTECTED] writes: I would like a variant to be LessThanComparable if all BoundedTypes are LessThanComparable. In this example typedef boost::variantT1, T2, ..., TN V; V v1 = T1( x ); V v2 = T2( y ); V v3 = T1( z ); v1 v2 should always be true. And v1 v3 should be the same as T1( x ) T1( z ). I assume that the resulting variant class will be StrictWeaklyComparable if all BoundedTypes are StrictWeaklyComparable. Sounds like maybe you want dynamic_any. Have you looked at Alexander Nasonov's work? I would like to emphasize one difference with variant library. User should _add_ less operation to the list of supported operations to enable operator. This operator isn't enabled by default. This protects from undesirable effects because if the user added less I can assume that she knows what she's doing. But the problem of different order is still persist. I think we should coordinate our work on variant and dynamic_any library. The discussed problem is one point where coordination is needed. Both libraries work with some set of types by (i) storing value of one selected type and (ii) calling some operation for stored value. This is done with some differences, though. In assumption that typedefs for variant and dynamic_any fixed I can say that: 1. variant operates with _fixed_ set of stored types but with _open_ set of supported operations (through static_visitor) 2. dynamic_any has _open_ set of stored type but _fixed_ set of supported operations There is also some differences in operation support. Variant's operation looks like: struct print : static_visitorvoid { std::ostream out_; print(std::ostream out) : out_(out) {} templateclass T void operator()(const T value) const { out_ value; } }; while dynamic_any operation looks like: struct print : functionprint, void (std::ostream, const anyT) { templateclass T void call(std::ostream out, const T value) const { out value; } }; On one hand, variant uses operator() which is good for anonymous operations (obviously, it's not possible for dynamic_any): variantint, char v(0); // anonymous function is ok apply_visitor(v, std::cout _1); // error, attempt to call std::cout v for_each(v, v + 1, std::cout _1); // ok for_each(v, v + 1, print(std::cout)); On the other hand, dynamic_any has better support for std algorithms, lambda, bind, etc (well, in variant case it's also possible by binding apply_visitor): dynamic_any::anympl::listprint a(0); // ok, direct call print()(std::cout, a); // ok if result of print doesn't contain anyT (void doesn't) // otherwise, bindR is required for_each(a, a + 1, bind(print(), std::cout, _1)); Other advantage of dynamic_any is a possibility to mix normal arguments and anyT-based. Due to nature of dynamic_any it's not possible to call the operation containing two or more anyT-based arguments for arbitrary arguments. Call can be made only if all any arguments hold same type or are derived publicly from one type T stored by one any argument. However, less works fine with arbitrary types because I added call_ex/no_call mechanism to the library. In variant the set of stored types is fixed and all combinations can be considered (be careful, it may cause combinatorial explosion): struct plus : variant::functionplus, variantT (variantT, variantT) { templateclass T1, class T2 typeof(v1 + v2) call(T1 v1, T2 v2) const { // Note that T1 and T2 are in general // different (in opposite to dynamic_any) return v1 + v2; } templateclass T2 std::string call(std::string v1, T2 v2) const { return v1 + lexical_caststd::string(v2); } templateclass T1 std::string call(T1 v1, std::string v2) const { return lexical_caststd::string(v1) + v2; } // ... }; variantstd::string,int,char s(s); variantstd::string,int,char i(0); variantstd::string,int,char s0 = plus()(s, i); // s2 == std::string(s0) -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] adaptable_any vs any_with
I'm asking for voting for the new name of dynamic_any. Please, give you preference. Here is my discussion about the name with Kevlin Henney ( and empty prefix - Kevlin, - me) --- cut --- Have you had any more thoughts on an alternative name? Something like adaptable_any or extensible_any? I really don't like the current name and I don't like the fact that namespace has different name. If I understand meaning of the word, extensible_any is not a right name because when you extend operation list you narrow a set of supported types. Good point! reducible_any ;-) Sometimes this set can be so narrow that I doubt about 'any' in name! adaptable_any is much better. I like it. It seemed to be the best of the rest. Another thought might be to take advantage of the way you might read what is written. Instead of naming the operation list operation_list, name it io_operations. Instead of dynamic_any, or even adaptable_any, use the name any_with. This would give you any_withio_operations, which reads as a perfectly accurate description in English. Kevlin --- end of cut --- -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Any progress in bit_iterator?
Google shows me a few links about bit_iterator. http://lists.boost.org/MailArchives/boost/msg03435.php http://groups.yahoo.com/group/Boost-Users/message/994 Any progress since these messages have been posted? Definitely, I have an interest in bit_iterator. But I don't have enough time to implement it :( I see two different designs of bit_iterator. It can be implemented as a class that works with raw memory or as an adaptor to other iterator (which is dereferenced to integral type). // Design one struct bit_iterator { bit_iterator(void* raw_memory); bit_iterator operator++(); // ... }; // Design two templateclass Iter Iter get_iter_for_typeof(); templateclass Iter, class T = typeof(*get_iter_for_typeof()) struct bit_iterator { static_assertis_integralT ; bit_iterator(Iter); bit_iterator operator++(); // ... }; -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Any interest in iostream-like pipe?
graydon hoare wrote: an inter-thread pipe might also be referred to as a synchronization channel, if you want to avoid confusion about names (pipes being a particular OS object). -graydon Synchronization channel sounds good except that stream names are too long. synchronization_channel channel; // good // too long? synchronization_channel_istream in(channel); synchronization_channel_ostream out(channel); -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Any interest in iostream-like pipe?
All of you know what is pipe and what are iostreams. In this library they work together. Writer-thread put objects into pipes while reader-thread get them from the pipe. Ã…lthough objects are copied to/from pipe, this is often a better alternative to object sharing because the pipe manages inter-thread communication for you. Thus, you can concentrate on domain logic rather then on threading primitives. Unlike OS-provided pipes that operate with bytes of data this library is iostream based. It means that you work with objects. The library doesn't use OS pipes. Pipe support is implemented by hand with a help of Boost.Threads. Synchronization occurs only in underflow, overflow, sync, open and close functions which means fast I/O. The library also has two capacity models: limited and unlimited. In the former case, if writer goes ahead of a reader it stops and waits; in the latter case, the writer always allocates new block of memory when overflow occurs. Example: // main thread pipe pp; // limited_capacity by default // in thread1 opipestream out(pp); out data; // in thread2 ipipestream in(pp); in data; thread1.join(); thread2.join(); reference: http://groups.yahoo.com/group/boost/files/pipes.zip -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Any interest in iostream-like pipe?
Philippe A. Bouchard wrote: There is another pipestream project you can take a look at: http://pstreams.sourceforge.net/ May be I missed something but this library is about reading from stdin and writing to stdout of other process. It's not about inter-thread pipes. -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Any interest in iostream-like pipe?
Bohdan wrote: Alexander Nasonov [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] graydon hoare wrote: an inter-thread pipe might also be referred to as a synchronization channel, if you want to avoid confusion about names (pipes being a particular OS object). -graydon Synchronization channel sounds good except that stream names are too long. synchronization_channel channel; // good // too long? synchronization_channel_istream in(channel); synchronization_channel_ostream out(channel); What about shell_stream ? Mine is not shell stream. It has nothing common with stdin/stdout of shell commands :) There are two kinds of pipe: (a) shell feature (aka out_cmd | in_cmd under unix) and (b) OS object. Win32 pipe objects are described here: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ipc/base/pipes.asp UNIX pipe function: http://www.umbi.umd.edu/cgi-bin/man-cgi?pipe+2 UNIX popen/pclose (these functions are close to shell_stream) http://dell5.ma.utexas.edu/cgi-bin/man-cgi?popen+3 -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Any interest in iostream-like pipe?
Larry Evans wrote: [snip] indicating some interest in combining thread safety and decoration. It seems to me (a novice in threading) that what needs to be protected is the access to the end of the pipeline, i.e. the final streambuf, which is connected to the actual output medium (a file, or console or pipe). Mine isn't connected to the actual medium. It works for yourself (and for pipe streams). Hence, I'm wondering if it's a good idea to combine the two in a ostream class. I confess I haven't looked at your code, but I think it would be nice if somehow it could be streambuf thread safety could be separated from the {o,i}stream features which are only concerned with formatting. Does that make sense? Only pipestream is thread safe. Iostreams are not. -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Announce: dynamic_any in the Boost Corner
http://www.cuj.com/documents/s=8470/cujweb0309nasonov/ -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Thread locking
Sometimes I have to write code like this: timed_mutex mtx; void foo() { { xtime xt = get_it(); timed_mutex::scoped_timed_lock lock1(mtx, xt); if(lock1) { // ... } } { boost::xtime xt = get_it(); timed_mutex::scoped_timed_lock lock2(mtx, xt); if(lock2) { // ... } } } I don't like extra scope needed to control locking. IMO, ScopeGuard idiom can be used to get rid of it. In example below class lock plays the role of ScopeGuard: void foo() { xtime xt = get_it(); if(lock lock1 = timed_mutex::scoped_timed_lock(mtx, xt)) { // ... } xt = get_it(); if(lock lock2 = timed_mutex::scoped_timed_lock(mtx, xt)) { // ... } } -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Boost.Threads bug?
There is a less comparison in several places of time-related stuff. I believe that less-or-equal is better. Take a look for example at if statement here: inline void to_timespec(const boost::xtime xt, timespec ts) { ts.tv_sec = static_castint(xt.sec); ts.tv_nsec = static_castint(xt.nsec); if(ts.tv_nsec static_castconst int(NANOSECONDS_PER_SECOND)) { ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND; ts.tv_nsec %= NANOSECONDS_PER_SECOND; } } if ts.tv_nsec equal to NANOSECONDS_PER_SECOND then you should add one second and set nanoseconds to zero. -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Visitor-based framework to describe classes with exampleofobjectdump in XML format
Alexander Nasonov wrote: class base_node // represent a base of a concrete class { // ... // virtual void* derived_to_base(void* base_ptr) const = 0; }; Oops, I made a little naming mistake: base_ptr should be derived_ptr. BTW, compile-time retrospection could be used to find library-specific constructor. For example, Driver could have it: class Driver : public Person { std::string licence_id; Date licence_issue_date; public: Driver(const raw_object raw) : Person(raw) , licence_id(raw.get(Driver::licence_id)) , licence_issue_date(raw.get(Driver::licence_issue_date)) { } // .. }; If this information isn't available at compile-time you have to tell the framework about the constructor: void describe_Driver(descriptorDriver class_) { class_(Driver).derived_fromPerson() [ constructorconst raw_object(), // here member(Driver::licence_id, licence_id), member(Driver::licence_issue_date, licence_issue_date) ]; } -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Visitor-based framework to describe classes with exampleofobjectdump in XML format
David Abrahams wrote: A problem with this is that the introspection information is only available at runtime. A more-flexible system would use GCC-XML output to generate something like: template struct class_Driver { typedef mpl::vectorPerson bases; typedef mpl::vector memberint Driver::*, Driver::licence_id , memberDate Driver::*, Driver::licence_issue_date , membervoid (Driver::*)(), Driver::accelerate members; ... }; So all the introspection information could be available at compile-time. Sometimes it's fine to have an introspection only at runtime. I just want to avoid duplications of class descriptions by multiple libraries. For example, Python and luabind could share common introspection information. This is why I'm using visitors. Every intronspection elelemnt has correspondent node that can be visited. The challenge is to build a complete set of nodes with a complete set of operations. -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Visitor-based framework to describe classes with example ofobjectdump in XML format
This framework might be interested to those who wishes to read and write members of classes using member-names. Stuff like serialization, messaging, automatic binding of class members with GUI/Web forms and OODBs (although they have ODMG C++ binding). From user point of view it's easy. Every class is described using intuitive class-decl-like style: void describe_Driver(descriptorDriver class_) { class_(Driver).derived_fromPerson() [ member(Driver::licence_id, licence_id), // note comma operator member(Driver::licence_issue_date, licence_issue_date) ]; } then it's registered: namespace { register_classDriver, describe_Driver reg_Driver; } and that's all! The framework is low level access to class and member information but it's made using visitor, so it's very flexible and different add-ons can be built on top of it. I implemented XML dump of objects. Currently, only limited set of basic types are supported (int, char and std::string) but it's easy to extend it. Pointers are not yet supported, it's a task for a future. Get it from here: http://groups.yahoo.com/group/boost/files/describe_classes.tar.gz BTW, I can imagine HTML form where members are grouped by classes (bases and end class), types of form elements are determined automatically from member information and pointers are represented as references. Most exciting is that you get it using one function call! (if you described all classes earlier). -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] objects serializing (from comp.lang.c++.moderated)
Below is a copy of my post to comp.lang.c++.moderated http://groups.google.co.uk/groups?q=author:alnsn-mycop%40yandex.ruhl=enlr=ie=UTF-8selm=3eef18d6%40news.fhg.dernum=1 --- cut --- Thomas Hansen wrote: BTW! Serialization of objects in C++ or any other language for that reason is one of the hardest part to keep up with your OOP mantras... The reason is that all that nice polymorphisme and your beautifule inheritence tree basically becomes pure C since you'll end up with a file stuffed with enums and magic numbers anyway... No man alive today has been able to solve this problem completely... I took some ideas from boost archive and played around with a code several days ago. The idea is to set relations between pointers to data members (or to get/set member functions) and names of serialized fields. Then, during object loading/saving it's possible to access the member using member pointer. The framework will find appropriate field in the storage by name and static_cast it automatically. So, you don't need to make those tricky casts. Realtions can be built using describe function: // Parent.hpp struct Parent : Person { Parent* partner; std::listPerson* children; static void describe(db::typeParent t) { // Looks like class definition t db::class_(Parent) db::derived_fromPerson() db::field(Parent::partner, partner) db::field(Parent::children, children); } }; It should be registered in Parent.cpp file using static object: namespace { db::register_typeParent,Parent::describe r; } Access to members is easy: templateclass Class, class T T db::get(T Class::* p, db::raw_object obj); db::raw_object father = find_my_father(parents_database); Parent* mother = db::get(Parent::partner, father); In addition to better static type control you can track pointers or a list of pointers at compile-time and then use it at runtime to set up the schema and to load an object with all its relations. --- cut --- -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: checked_delete without assignment to 0 - why?
Markus Werle wrote: Hi! In one of Herb Sutters articles I saw that after deleting a pointer (a pimpl) he assigns 0 afterwards which seems to me like a good idea. (see e.g. http://www.gotw.ca/gotw/028.htm or http://tinyurl.com/bq8o) Maybe there is a good reason (efficiency?) why checked_delete omits this extra step. Please explain. templateclass T inline void checked_delete(T * x) { typedef char type_must_be_complete[sizeof(T)]; delete x; // why not ? x = 0; } checked_delete only checks, it doesn't improve you code :) Seriously, the question can be redirected to C++98 level: why delete operator doesn't assign deleted pointer to 0? I'm sure it has already been discussed. You can search for the topic in comp.std.c++ and comp.lang.c++.moderated. -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: dynamic_any
Alexander Nasonov wrote: I agree that a-move(10, 10) is clearer then move()(a, 10, 10). One big plus of it is ability to overload move member-function: a-move(Point(10, 10)). You can't do that with move operation: move()(a, 10, 10); move()(a, Point(10, 10)); // error You have to implement two operations move_to_xy and move_to_point: move_to_xy()(a, 10, 10); move_to_point()(a, Point(10, 10)); // ok But, looking at the single interface bottleneck and less clear implementation of supported operations, I prefer to use my-own move()(a, 10, 10). One addition. I always thought about dynamic_any as a concrete class and I never considered deriving from it. But you can: struct moveable : dynamic_any::anympl::listmove_to_xy, move_to_point { void move(int x, int y) { move_to_xy()(*this, x, y); } void move(const Point point) { move_to_point()(*this, point); } }; int main() { moveable a = get_moveable(); a.move(10, 10); a.move(Point(10, 10)); } The problem is closed. -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: boost::tuple to MPL sequence
Eric Friedman wrote: I am a bit uneasy about any proposal making adding MPL sequence semantics to an otherwise-typical value type. If such proposals are implemented, I see a significant ambiguity problem arising in generic code: given a type T that is an MPL sequence, should we treat it as a sequence or as a value type? In particular, if we were to implement boost::tuple as an MPL sequence, the following code would seem to me quite unclear insofar as its intended behavior: typedef mpl::listint, std::string some_types; typedef boost::tupleint, std::string some_tuple; typedef boost::variantsome_types v1; // ok, unambiguous typedef boost::variantsome_tuple v2; // ambiguity!? It seems clear that objects of type v1 should behave equivalently to boost::variantint, std::string. However, if boost::tuple were an MPL sequence, it seems less clear whether objects of type v2 should behave likewise or instead as a variant holding a 2-tuple. Thus, this question is of particular importance for boost::variant. But also, I imagine, it is important for any other type implementing a pseudo-variadic template interface as I intend for the final release of variant (which is coming, by the way). Input? I agree. -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: lambda support for dynamic_any
Alexander Nasonov wrote: Lambda cannot deduce return type of *begin. What should I do? May be some kind of traits or nested template should be defined for any? I've just found it in lambda documentation. BTW, I have some progress in the library. Reference section is partially done: http://cpp-experiment.sourceforge.net/boost/libs/dynamic_any/doc/any.html But there are number of problems. I hope to discuss some of them at ACCU. -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: boost::any feature request
Vladimir Prus wrote: Aha, that's what I was trying to say, but not very clearly. Yes, *this* will work. But... it means that if you do any a1; anyfast_allocator a2 = a1; Then value stored in a2 will be allocated using a1's allocator, not a2's. Once any is created with a specific allocator, all copies will use the same allocator, which is doubtful behaviour. In the example above, the fast_allocator parameter has no effect at all. Even if this behavior is desirable, you don't need to add template parameter to 'any'. I agree, there is no need for the template parameter for any. You can add template parameter to 'holder' only, and another constructor, which allows to specify allocator. But then you can't make static_cast to holderKnownType, UnknownAllocator inside any_castKnownType(a); May be wrap allocator specific stuff into separate interface? There are two allocator types: (a) type specific ones like std::allocatorint and (b) catch-all allocators. Option (a) is probably better when you know the type: any a(1); // a uses new/delete any b(2, fast_allocatorint()); I don't know whether to leave the original allocator or replace it with another one while making a copy: any c(a); // c uses new/delete any d(b); // d uses fast_allocatorint? -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: boost::any feature request
Alexander Nasonov wrote: Vladimir Prus wrote: You can add template parameter to 'holder' only, and another constructor, which allows to specify allocator. But then you can't make static_cast to holderKnownType, UnknownAllocator inside any_castKnownType(a); May be wrap allocator specific stuff into separate interface? You can if you add one more level of inheritance: templateclass T, class Allocator class holder_with_allocator : public holderT // make static_cast to it { // ... }; There are two allocator types: (a) type specific ones like std::allocatorint and (b) catch-all allocators. Option (a) is probably better when you know the type: any a(1); // a uses new/delete any b(2, fast_allocatorint()); I don't know whether to leave the original allocator or replace it with another one while making a copy: any c(a); // c uses new/delete any d(b); // d uses fast_allocatorint? I forgot that we're allocating a memory for holderT not for type T. But there is a solution called rebind. So, I really don't know what to choose. -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: boost::any feature request
Maxim Egorushkin wrote: I think it would be great to make boost::any's memory allocation strategy for value holder customizable. It would allow to use not only global new operator, but any other special fast allocators like, for example, Loki::SmallObject. I can add it to dynamic_any. All that I need is just an allocator interface. It would be also nice not to use dynamic allocations at all for built-in types. -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Boost talks at ACCU
Beman Dawes wrote: There are going to be several talks about Boost libraries or related topics at the ACCU conference in Oxford, UK, April 2nd through 5th: I'm going to present dynamic_any library there after the main program ( Birds of a Feather meetings section). Though it's not yet in Boost but it may be of interest anyway. Details already discussed with Francis Glassborow, David Abrahams and Douglas Gregor through private e-mail. See you there! -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Proposal: static_string library
Robert Klarer wrote: The syntax for declaring a static_string is unfortunate, but once it has been declared, a static_string's interface is (almost*) the same as that of a const std::string. Yes, you right it's unfortunate and IMHO is not appropriate for a wide use. typedef boost::static_string's', 't', 'a', 't', 'i', 'c', '_' StrType1; This syntax may be good for some specific (and not widely used) tasks such as building hashing algorithm at compile-time for a given set of static strings but not for normal strings. I beveive it's better to wait for a new compiler which can optimize dynamic memory allocations (a possibly even more) away. -- Alexander Nasonov Remove minus and all between minus and at from my e-mail for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Boost.dynamic_any vs Boost.Function
Douglas Paul Gregor wrote: On Tue, 18 Feb 2003, Alexander Nasonov wrote: With a help of boost::dynamic_any::call operation (not yet implemented) it's possible to use boost::dynamic_any::any instead of Boost.Function. Though this new solution is less specialized and probably slower then Boost.Function it has one advantage demonstrated in the example below: typedef boost::dynamic_any boost::mpl::list boost::dynamic_any::callvoid (int ), boost::dynamic_any::callvoid (double ) flexible_function; // 2 in 1! That's great! 'Tis a good week for dynamic polymorphism. There is the same code bloat problem as in early Boost.Function release. Unfortunately, I have to use polymorphic classes to store a value because they are essential parts of extraction mechanism. So, I can only recommend to use this feature only when it's _really_ necessary. -- Alexander Nasonov Remove - m y c o p from my e-mail address for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Formal review or Variant Library (Ed B.)
Peter Dimov wrote: The other option is to support a dynamic_cast-style extract: T * p = extractT*(var); T r = extractT(var); but it would likely require partial ordering/specialization. I don't have access to a compiler with broken partial ordering/specialization but I tried to keep it in mind when I implemented extraction for dynamic_any. This code fragment is taken from dynamic_any/any.hpp. Start reading from the bottom. // T is not a class. templateclass T const T * extract_const_ptr(const placeholder * p, bool_idfalse) { if(p == 0 || p-type(sig()) != typeid(T)) return 0; typedef const nonclass_holderT holder_type; holder_type * ptr = static_castholder_type *(p); return ptr-value; } // T is a class. templateclass T const T * extract_const_ptr(const placeholder * p, bool_idtrue) { return dynamic_castconst T *(p); } templateclass T const T * extract_const_ptr(const placeholder * p, type_idconst T) { bool_id ::boost::is_classT::value id; return extract_const_ptrT(p, id); } // T is not a class. templateclass T T * extract_nonconst_ptr(placeholder * p, bool_idfalse) { if(p == 0 || p-type(sig()) != typeid(T)) return 0; typedef nonclass_holderT holder_type; holder_type * ptr = static_castholder_type *(p); return ptr-value; } // T is a class. templateclass T T * extract_nonconst_ptr(placeholder * p, bool_idtrue) { return dynamic_castT *(p); } templateclass T T * extract_nonconst_ptr(placeholder * p, type_idT) { bool_id ::boost::is_classT::value id; return extract_nonconst_ptrT(p, id); } // T is const. templateclass T T * extract_ptr(const placeholder * p, bool_idtrue) { return extract_const_ptr(p, type_idT()); } // T is not const. templateclass T T * extract_ptr(placeholder * p, bool_idfalse) { return extract_nonconst_ptr(p, type_idT()); } // Placeholder is 'placeholder' or 'const placeholder'. templateclass T, class Placeholder T * extract_ptr(Placeholder * p) { bool_id ::boost::is_constT::value id; // Note to users: if you get compile error here then you are trying // to extract non-const pointer or reference from const 'any'. return extract_ptrT(p, id); } templateclass T, class Placeholder T extract_ref(Placeholder * p, type_idT ) { if(T * ptr = extract_ptrT(p)) return *ptr; throw bad_extract(); } // T is a reference. templateclass T, class Placeholder T extract(Placeholder * p, bool_idtrue) { return extract_ref(p, type_idT()); } // T is not a reference. templateclass T, class Placeholder T extract(Placeholder * p, bool_idfalse) { return extract_ref(p, type_idconst T ()); } templateclass T, class Placeholder T extract(Placeholder * p) { bool_id ::boost::is_referenceT::value id; return extractT(p, id); } -- Alexander Nasonov Remove -mycop from my e-mail address for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Boost.dynamic_any vs Boost.Function
{This is a second attempt to post} With a help of boost::dynamic_any::call operation (not yet implemented) it's possible to use boost::dynamic_any::any instead of Boost.Function. Though this new solution is less specialized and probably slower then Boost.Function it has one advantage demonstrated in the example below: typedef boost::dynamic_any boost::mpl::list boost::dynamic_any::callvoid (int ), boost::dynamic_any::callvoid (double ) flexible_function; // 2 in 1! int main() { flexible_function f; f = ++_1; // increment for int and double int i = 2; f(i); // ++i double d = 3; f(d); // ++d } -- Alexander Nasonov Remove - m y c o p from my e-mail address for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: any_cast improvement
Unai Uribarri RodrÃguez wrote: any_cast, as is implemented in boost 1.29, has one weakness; it doesn't allow to compile this piece of code: any x=int(5); ++any_castint(x); because any_cast tries to instanciate a pointer to int. The attached patch solved this problem using boost::remove_reference from boost/type_traits.hpp. any_castT(x) will return a reference to value contained in x if its type is T, or raise bad_cast otherwise. Boost.dynamic_any has extract functinos which work this way. -- Alexander Nasonov Remove -mycop from my e-mail address for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Boost.dynamic_any tutorial
http://cpp-experiment.sourceforge.net/boost/libs/dynamic_any/doc/tutorial.html It's very raw but I don't have time now to fishish it. Anonymous CVS access to sources: cvs -d:pserver:[EMAIL PROTECTED]:/cvsroot/cpp-experiment login cvs -z3 -d:pserver:[EMAIL PROTECTED]:/cvsroot/cpp-experiment co dynamic_any -- Alexander Nasonov Remove -mycop from my e-mail address for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Implicit conversions in dynamic_any / extract
Remy Blank wrote: I checked out dynamic_any from CVS but the function... syntax seems to be missing, so I replaced it by function1 Is there something missing in the repository? Yes, you are right, it's missing. I have not enough time to implement all features. Currently only functionN (N=1,...10) are available. After some trimming, this works perfectly! dynamic_any is truly awesome! Thanks for the advice. Best regards. --Remy It's nice for me to see these words! I'm waiting with bated breath when this library becomes available to many people. Some of them can apply dynamic_any in a way that I can't even imagine. It promises to be very interesting time. -- Alexander Nasonov Remove -nospam from my e-mail address for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Implicit conversions in dynamic_any / extract
Alexander Nasonov wrote: You can create your own framework for dynamic_any using dynamic_any::function. In a combination with simple and typesafe interface it could make great library. Basic idea is here: namespace your_framework { // ... namespace detail { // ... struct raw_convert : boost::dynamic_any::function convert, void * (boost::dynamic_any::arg ) Oops, here is a typo. Should be struct raw_convert : boost::dynamic_any::function raw_convert, // typo was here void * (boost::dynamic_any::arg ) -- Alexander Nasonov Remove -nospam from my e-mail address for timely response ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: function redesign for dynamic_any
Douglas Gregor wrote: On Monday 11 November 2002 08:32 am, Alexander Nasonov wrote: Additionally, two types of control are desired: 1) Control over real types of arguments. It is a limitation of dynamic_any library that arguments must be converted to _one_ type before a call. But they can be of different types. Problem can be easily solved by adding additional arguments to the 'call' member-function: templatetypename Arg bool less::call(const Arg a, const std::type_info ta, const Arg b, const std::type_info tb) const { return a b; } I'm not sure I see why we need this functionality, but perhaps I'm not being imaginative enough at this hour. Do you have an example where this would help? It was at the end of my post. I know how it's hard to understand details without sufficient knowledge of the topic. I tried to start documentation but it still unusable. This functionality can be usefull but not quite often. I think it's better to keep 'call' member function for simple use and introduce different name (call_ex?) for advanced use. So, you can use one of: // 1) templatetypename Arg bool call(const Arg a, const Arg b) const; // 2 templatetypename Arg bool call_ex(const Arg a, const std::type_info ta, const Arg b, const std::type_info tb) const; Implementation can first try to call 'call_ex' and if it throws internal exception (default behavoir) then revert to 'call' member-function. Some further thoughts and questions. 1. Support for N-unary functions (currently N=1,2). With increase of N complexity is aslo increased. Imagine that you have N 'any' arguments a1 ... aN that hold values v1 ...vN of type T1 .. TN and you would like to call a foo defined as: struct foo : functionfoo, void (const arg , , const arg ) // 'const arg ' repeated N times { templateclass Arg void call_ex(const Arg v1, const std::type_info , ... const Arg vN, const std::type_info ) const { // user defined implementation } }; Current algorithm takes first argument a1 (which holds value v1 of type T1) and tries to extract T1 from a2 ... aN. If all extractions are ok then invoke the foo: foo func = ... func.call_ex(v1, typeid(v1), extractT1 (a2), a2.type(), ... extractT1 (aN), aN.type()); Otherwise apply the same to a2, ... aN arguments. Remember that every extract uses dynamic_cast for a hierarchy with multiple inheritance. Even for small N it can be expensive. Though some optimization can be made IMHO. 2. Code bloat caused by generation of class hierarchy for every holded type. This hierarchy is central to implementation and cannot be changed to something else (but number of virtual functions can be minimized). The only way is to teach users minimalizm in the library usage. 3. Integration with other libraries such as Serialization, variant and visitor libraries. Best regards, Alexander Nasonov mailbox: alnsn server: mail.ru ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost