Re: [boost] Re: Interest in multiindex_set?(again)
Hi Fernando, - Mensaje Original - De: Fernando Cacciola [EMAIL PROTECTED] Fecha: Sbado, Julio 12, 2003 1:22 am Asunto: [boost] Re: Interest in multiindex_set?(again) Hi Joaqun, Unfortunately, I douldn't compile the code with BCC because it extensivelyuses non-type template parameters which are only partially supported on Borland. After having read the documentation and looked at the code again, I realize now that your class is really a database-like table but not an associativecontainer. In fact, it is not even a container. The problem is that you cannot traverse over _all_ the elements linerly.(See 23.1, Table 65) Yes you can, see below. I previously took for granted that it was a container so I asked about the _global_ arrangement of the elements. I think that you shoud add iterators to traverse over the entire table as if it were a Sequence. This is the basic requirement of a container. With dismay I realize how very poor my documentation skills are :) multiindex_set *is* a container in the sense you describe. Given a multiindex_set instantiation say my_mx_set witn N indices, each index provides a set-like interface with allows the user to traverse *all the elements* contained: my_mx_set mxs; ... my_mx_set::index_typen::type index_n= mxs.getn(); // n between 0 and the N-1 Now, index_n.begin() and index_n.end() let you enumerate *all* the elements in mxs, regardless of n; the difference is in the order they are enumerated, which depends on the comparison predicate associated with index #n. By convention, my_mx_set inherits the functionailty of index #0, that is my_mx_set::some_memfun(...); is the same as my_mx_set::index_type0::type::some_memfun(...); In particular, my_mx_set::begin() and my_mx_set::end() let you traverse through then entire set of elements contained, with the order induced by index #0. Does this ask your question? If not, please let me know and I'll be happy to explain it further. I'm most determined to eliminate this semantic barrier between both of us :) Also, may I suggest you download some distribution of g++ and play with the library a little. Maybe then things become clearer. Now, suppose that you can iterate over the all of the elements: what's the order in which elements will appear w.r.t the insertion sequence and the ordering implied by the indices? This is what I've asked you about the ordering and clustering invariants of the data structure. If, during a linear traversal (that is, iterating over all of the elementsas if it were a sequence), the elements will appear in an unspecified order, then the data structure is not an associative container (much less a set), so it should _definitely_ be called 'table' and not 'set'. I think I understand now why the term 'index'. It reseambles the filtering-key associated with the 'field' which designates a 'column' on a database table. However, if I'm not mistaken, the filtered-column itself,that is, the sequence of elements with such value in the correspondingfield, is not an 'index'. So the subsquence which is mapped to a given index shouln't be called index, I think. I would call it a 'cluster' as I suggested before. Since I can't play with the code I couldn't see how much of a set is each 'cluster'. Make sure to check with the requirements and document this clearly. Hopefully, this has been asked above. Again, please let me know otherwise so that I try to make myself clearer. Another thing I couldn't figure out is how to compose indices hierachically.That is, how to reproduce a typical SQL SELECT * ORDER BY X,Y,Z. Since you're modeling an indexed table, this functionality should be supported. This is an interesting subject to study, but as some others are already writing a relational framework I guess we should limit here to the basics of the container. SQL-like predicates can be built on top of it in the context of more ambitious libraries. I vote for a separate KeyExtraction because: (a) Key extraction and key comparison are conceptually orthogonal. (b) The orthogonality will be important in practice when users want to compare whith other predicates besides less_than and/or based on more than just data members. With your mixin approach, it would be more difficult to have an index based on a runtime expression (such as a hash value) combined with a comparison other than . The most usual situation for specification of an index (standard less_than comparison on some member of the element) is already covered by less_by. Furthermore, less_by accepts an additional template parameter for specifying a comparison predicate other than std::less. For instance less_byemployee,std::string,employee::name specifies an index based on less_than comparison of employee::name (a string). If you want to use some other comparison criterium on empoyee::name (for instance, case insensitive comparison), you can write
[boost] Re: Re: Interest in multiindex_set?(again)
Hi Joaquín, JOAQUIN LOPEZ MU?Z wrote: Hi Fernando, - Mensaje Original - De: Fernando Cacciola [EMAIL PROTECTED] Fecha: Sábado, Julio 12, 2003 1:22 am Asunto: [boost] Re: Interest in multiindex_set?(again) [snip] Now, index_n.begin() and index_n.end() let you enumerate *all* the elements in mxs, regardless of n; the difference is in the order they are enumerated, which depends on the comparison predicate associated with index #n. By convention, my_mx_set inherits the functionailty of index #0, that is my_mx_set::some_memfun(...); is the same as my_mx_set::index_type0::type::some_memfun(...); Ah! I see. Sorry about the confusion. In particular, my_mx_set::begin() and my_mx_set::end() let you traverse through then entire set of elements contained, with the order induced by index #0. Does this ask your question? Absolutely! If not, please let me know and I'll be happy to explain it further. I'm most determined to eliminate this semantic barrier between both of us :) Me too... I got it wrong from the start though :-) Also, may I suggest you download some distribution of g++ and play with the library a little. Maybe then things become clearer. Now, suppose that you can iterate over the all of the elements: what's the order in which elements will appear w.r.t the insertion sequence and the ordering implied by the indices? This is what I've asked you about the ordering and clustering invariants of the data structure. If, during a linear traversal (that is, iterating over all of the elementsas if it were a sequence), the elements will appear in an unspecified order, then the data structure is not an associative container (much less a set), so it should _definitely_ be called 'table' and not 'set'. I think I understand now why the term 'index'. It reseambles the filtering-key associated with the 'field' which designates a 'column' on a database table. However, if I'm not mistaken, the filtered-column itself,that is, the sequence of elements with such value in the correspondingfield, is not an 'index'. So the subsquence which is mapped to a given index shouln't be called index, I think. I would call it a 'cluster' as I suggested before. Since I can't play with the code I couldn't see how much of a set is each 'cluster'. Make sure to check with the requirements and document this clearly. Hopefully, this has been asked above. Again, please let me know otherwise so that I try to make myself clearer. It's OK. I guess I got it right this time. Another thing I couldn't figure out is how to compose indices hierachically.That is, how to reproduce a typical SQL SELECT * ORDER BY X,Y,Z. Since you're modeling an indexed table, this functionality should be supported. This is an interesting subject to study, but as some others are already writing a relational framework I guess we should limit here to the basics of the container. SQL-like predicates can be built on top of it in the context of more ambitious libraries. I see. If this functionality can be built on top of it, then I think it is OK not to support it explicitely. I vote for a separate KeyExtraction because: (a) Key extraction and key comparison are conceptually orthogonal. (b) The orthogonality will be important in practice when users want to compare whith other predicates besides less_than and/or based on more than just data members. With your mixin approach, it would be more difficult to have an index based on a runtime expression (such as a hash value) combined with a comparison other than . The most usual situation for specification of an index (standard less_than comparison on some member of the element) is already covered by less_by. Furthermore, less_by accepts an additional template parameter for specifying a comparison predicate other than std::less. For instance less_byemployee,std::string,employee::name specifies an index based on less_than comparison of employee::name (a string). If you want to use some other comparison criterium on empoyee::name (for instance, case insensitive comparison), you can write less_byemployee,std::string,employee::name,string_case_insensitive_compare Is this what you're referring to? Half of it. I see that I can use the precanned 'less-by' and specify a different comparison semantic (though in this case why is it named 'less_by' instead of 'order_by'), but I don't see how can I use it with something different than a data member as the key itself. On some applications, specially outside databases, the keys are given by runtime expressions and not just stored data members. If the users would have to end up writting their own predicates, the separaton will make that task a lot easier. Finally, I'm not entirely happy with the coallision response of 'modify' (or maybe I don't understand it). Is it ever possible to afford removing the colliding modified element? Imagine I change the Social Security
[boost] N1477 Single Pass Iterators and *r++
The old input iterator 24.1.1 had a requirement: *r++ returned type T, semantics {T tmp= *r; ++r; return tmp; } The new Single Pass Iterators in N1477 have no such requirement. That's fine with me - that requirement was a source of bugs in my code and violated the rule of least astonishment as far as I was concerned. But before I remove the test from the filesystem library that verifies the old input iterator semantics for directory_iterator, I'd like to verify that the omission of *r++ was a design decision rather than an oversight. The omission of special requirements for *r++ means that Readable and Single Pass = Input, as shown in the diagram, is not actually correct, unless I'm missing something. Thus perhaps it should be discussed in the paper. --Beman ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: mpl/loki
David Abrahams wrote: That's because void_ is for MPL internal use only; it's not a type you should manipulate While I agree that _some_ user needs for a special unique type a better handled by introducing a new one (otherwise you'll get yourself into situation like we have right now, only in your own code :), I don't agree that we should deny the occasional need for a special type in many simpler cases - like Drazen's one. It would just make user life unnecessary more complicated than it should be. Besides, 'void_' _is_ a public type: beginnon-sequence-type::type === void_ orderSet,non-existing-key::type === void_ and a couple of others I don't remember off hand :). (I think Aleksey doesn't believe me, but I'm about to prove it... wink). I don't _agree_ :). Observe the definition of identity (comments added for exposition purposes): templatetypename T = void_ struct identity { typedef T type; }; // identityvoid_ is a metafunction class which makes it efficient // to pass mpl::identity where a lambda expr/metafunction class is // expected. template struct identity void_ { template class T1, class T2 =void_, class T3 =void_, class T4 =void_, class T5 =void_ struct apply : identity T1 {}; }; // specialization of lambdaidentity for efficiency. template struct lambda identity void_ { typedef identity void_ type; }; IMO we should just stop using 'void_' for internal purposes and give it up to users :). Aleksey ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: N1477 Single Pass Iterators and *r++
Beman Dawes [EMAIL PROTECTED] writes: The old input iterator 24.1.1 had a requirement: *r++ returned type T, semantics {T tmp= *r; ++r; return tmp; } The new Single Pass Iterators in N1477 have no such requirement. That's because the requirement mixes access and traversal. That's fine with me - that requirement was a source of bugs in my code and violated the rule of least astonishment as far as I was concerned. But before I remove the test from the filesystem library that verifies the old input iterator semantics for directory_iterator, I'd like to verify that the omission of *r++ was a design decision rather than an oversight. The omission of special requirements for *r++ means that Readable and Single Pass = Input, as shown in the diagram, is not actually correct, unless I'm missing something. Thus perhaps it should be discussed in the paper. A single-pass iterator is required to support r++ (inherited from the incrementable iterator requirements), but I guess that we've unintentionally dropped the requiremnt for *r++ of readable single-pass iterator, by allowing incrementable iterators to return any type convertible to const X. I think it should require that the return type be X, the Assertion/Note/Precondition/Postcondition column should be labelled Operational Semantics and the lower right entry should be moved to the middle column. The same goes for the lower-right entry of each of the following two tables. I'm going to make those changes; if there are objections, please let me know ASAP. -- Dave Abrahams Boost Consulting www.boost-consulting.com ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: mpl/loki
Aleksey Gurtovoy [EMAIL PROTECTED] writes: IMO we should just stop using 'void_' for internal purposes and give it up to users :). I am still unsure about 'void_' being better than 'nil' or 'null' Users already have a type, 'void', which means void. There's no correspondence between void_ and void the way there is between bool_ and bool. -- Dave Abrahams Boost Consulting www.boost-consulting.com ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: Interest in multiindex_set?(again)
Hi again, - Mensaje Original - De: Fernando Cacciola [EMAIL PROTECTED] Fecha: Sbado, Julio 12, 2003 7:32 pm Asunto: [boost] Re: Re: Interest in multiindex_set?(again) [stuff about conceptual structure of multtindex_set deleted] OK, I'm glad we finally got to understand each other :) There's a problem with the name of the class. Others have expressed dislike for multtindex_set. Alternative candidates are indexed_set and indexed_table. I haven't decided yet for one, plus there's the problem of which namespace should this live in (regardless of whether it is promoted to namespace boost later). The alternatives so far are (name of the class/associated namespace) * multiindex_set/boost::multiindex * indexed_set/?? * indexed_table/?? * ??/boost::container (proposed by Daryle) boost::container I don't like because some of the associated small utility classes and functions (less_by, get, project) shouldn't really belong into a general-purpose namespace like container which is supposed to hold other contributions. Also, there's the additional problem that the class and the namespace shouldn't be named the same (it makes some compilers choke, this has been discussed in connection with Boost.Tuple). Suggestions in this area are most welcome. I vote for a separate KeyExtraction because: [...] Half of it. I see that I can use the precanned 'less-by' and specify a different comparison semantic (though in this case why is it named 'less_by' instead of 'order_by'), but I don't see how can I use it with something different than a data member as the key itself. On some applications, specially outside databases, the keys are given by runtime expressions and not just stored data members. If the users would have to end up writting their own predicates, the separaton will make that task a lot easier. At first I was strongly against key extraction, but now I got an idea that maybe we all can settle for. Following Beman's advice, I elminated the unique_indices parameter in favor of this type of specification: multiindex_set employee, tuple uniquestd::lessemployee , non_uniqueless_byemployee,std::string,employee::name , non_uniqueless_byemployee,int,employee::age employee_set; unique and non-unique accepts the comparison predicate as a template parameter. This is nicer in which it opens the way to other index implementations (hashed indices, for instance) in a seamless manner. Now, I see this new style lends itself more easily to a key extraction approach. Instead of accepting a comparison predicate, it can be changed to: uniqueKeyExtractor,Compare=std::lesstypename KeyExtractor::result_type where KeyExtractor is expected to behave as an std::unary_function and hence have a result_type nested typedef. If we drop less_by and provide a member utility class, instead of non_uniqueless_byemployee,std::string,employee::name we can have non_uniquememberemployee,std::string,employee::name and instead of non_uniqueless_byemployee,std::string,employee::name,string_case_insensitive_compare we can have non_uniquememberemployee,std::string,employee::name, string_case_insensitive_compare Basically, the two schemes are functionally equivalent, but the latter enforces the key-extraction approach, which seems to have been demanded by Boosters. Moreover, it accepts the kind of external key-extraction functions you were talking about. What do you think about it? [...] OK, this is the best we could think of, at least right now. Many times the user knows exactly what she's doing so that no collisionswill ever really ocurr. For example, if the modify does not change keys but other data. For this cases modify() is a big plus. The acutal user code could assertthe result of modify() so that a coallision is treated as postconditionviolation. Here you can even resort to const_casting just as you would with an std::set. modify is expected to be used mainly when you do not change unique keys but you change non-unique keys; in this case, modify will not fail, but internal reordering is necessary (which bans the use of const_casting). The documentation could express emphatically that if the modification changed keys, update() must be used, else, modify() can. A possibility is to protect modify() so that it can used but not accidentally.That is, we can prevent a user for just seeing modify() on the public interface and blindly and incorrectly use it. Simply putting it into a protected section is problematic because it requires the user to derive from the class, so something better should be used to protect such a method. ...but I don't know right know how to code this :-) but I'm sure there are patterns for this already. Maybe with an addtional 'Modifier' template parameter which the user supplies with a 'modify' wrapper, or something like that. I'll let you know if I think of something. Plase do so. Best regards,
[boost] Re: N1477 Single Pass Iterators and *r++
David Abrahams [EMAIL PROTECTED] writes: That's fine with me - that requirement was a source of bugs in my code and violated the rule of least astonishment as far as I was concerned. But before I remove the test from the filesystem library that verifies the old input iterator semantics for directory_iterator, I'd like to verify that the omission of *r++ was a design decision rather than an oversight. The omission of special requirements for *r++ means that Readable and Single Pass = Input, as shown in the diagram, is not actually correct, unless I'm missing something. Thus perhaps it should be discussed in the paper. A single-pass iterator is required to support r++ (inherited from the incrementable iterator requirements), but I guess that we've unintentionally dropped the requiremnt for *r++ of readable single-pass iterator, by allowing incrementable iterators to return any type convertible to const X. I think it should require that the return type be X, the Assertion/Note/Precondition/Postcondition column should be labelled Operational Semantics and the lower right entry should be moved to the middle column. The same goes for the lower-right entry of each of the following two tables. I'm going to make those changes; if there are objections, please let me know ASAP. Done. -- Dave Abrahams Boost Consulting www.boost-consulting.com ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: mpl/loki
David Abrahams wrote: Aleksey Gurtovoy [EMAIL PROTECTED] writes: IMO we should just stop using 'void_' for internal purposes and give it up to users :). I am still unsure about 'void_' being better than 'nil' or 'null' Users already have a type, 'void', which means void. ... in conventional run-time programs. Unfortunately, 'void' is not special for metaprograms, many of which have a need to routinely manipulate it along with all other built-in types. 'mpl::void_' addresses this issue. There's no correspondence between void_ and void the way there is between bool_ and bool. 'void_' in MPL plays a role very similar to a role of 'void' in the core language. So, conceptually, there is a correspondence. Personally, I appreciate the analogy, dislike 'null'/'nil'/etc. for the lack of such, and would like to keep the name. Aleksey ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: functors for taking apart std::pair?
On Sat, Jul 12, 2003 at 01:21:49PM +0100, Andy Sawyer wrote: There's a third form I've also found useful on occasion: struct selector1st { templatetypename Pair const typename Pair::first_type operator()( const Pair a ) const { return a.first; } }; Which has the advantage of not needing to specify _any_ type at the call site: for_each( map.begin(), map.end(), selector1st() ); And again, is not limited to use with std::pair. However, it's utility is limited by not inheriting from std::unary_function. If and when I get FC++ ( http://www.cc.gatech.edu/~yannis/fc++/ ) into Boost, FC++ has the same kind of selectors you've shown above (named fst and snd, as in Haskell). Whereas these function objects also cannot be used with STL algorithms requiring adaptables (for the reason you mention above), it can be used with the analogous algorithms in FC++, since the FC++ infrastructure enables return-type-deduction for template function objects. I've been working on boostifying FC++ this past week (adopting naming conventions, reusing Boost code, etc.) and will hopefully get a Boost-ful FC++ version up for review in the next two weeks or so. -- -Brian McNamara ([EMAIL PROTECTED]) ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Release criteria [was Warnings about derivation ...]
At 05:47 AM 7/12/2003, Daniel Frey wrote: PS: Would it make sense to have a boost bug bashing week or something to fix some more bugs/regressions? Or do we wait for users to complain and provide fixes? Until recently, figuring out which tests should pass for each compiler was difficult. Sometimes a problem was a compiler bug, sometimes a bug in boost code, and sometimes a configuration problem. That is changing. On Win32 we now have several compilers which are good enough that either all tests should pass, or all tests should pass except for a very few where the compiler supplier has acknowledged a compiler bug. So for the next release we can talk about explicit release criteria. Meeting those criteria will in effect be a boost bug bashing week. It may go on for a bit longer than that, however:-) But right now a lot of Boost developers are coping with interface changes in Boost.Random and iterator adaptors. We need to keep focused on those fixes until the dust starts to clear a bit. --Beman ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
RE: [boost] Re: mpl/loki
That's because void_ is for MPL internal use only; it's not a type you should manipulate (I think Aleksey doesn't believe me, but I'm about to prove it... wink). It's quite all right - my code does not use that other type, I just need a type. I could have just as well used my own class null_type {};, but mpl's void_ looked like good enough choice. Anyway, I want to use null or void in the name of the type just for readability of my code. Observe the definition of identity (comments added for exposition purposes): [snip] Well, what can I say - this is not visible from the header, as many things are wrapped in macros, so reading the code is much harder. Now that you've shown it the way it really is, I can see the problem. But since I didn't need void_ in the first place, all is good. Thanks, Drazen ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Warnings about derivation without explicit access control specified
Hello, I saw a lot of new regression runs on various platforms. One obvious question: Should we remove the outdated runs? Now for the real reason of this message: One compiler (the SGI MIPSpro) complains (with a warning) about: cc-1234 CC: WARNING File = /net/cci/maurer/boost/libs/utility/operators_test.cpp, Line = 52 Access control is not specified (private by default). : boost::operatorsWrapped1T The question is: Should we, for the sake of portability, support this warning by requesting an explicit access control specifier whenever we derive? Or is such a general coding guideline inappropriate because it's too common that people omit it? At least I do this often as I think that the default is obvious and although I don't have a good reason for it, I also have no reason against it. Comments? Regards, Daniel PS: Would it make sense to have a boost bug bashing week or something to fix some more bugs/regressions? Or do we wait for users to complain and provide fixes? ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: functors for taking apart std::pair?
Edward Diener writes: Andy Sawyer wrote: Marshall's first and second are slightly different to the HP versions: template class T1, class T2 struct first: std::unary_function std::pair T1, T2, T1 ... vs. templatetypename Pair struct select1st : std::unary_function Pair, typename Pair::first_type Yes, I see it now. Marshall's version seems a little more redundant since one has to specify both types while the HP version just has one specifying a single pair type. This is particularly useful when you're dealing with std::map: map_t some_map; ... for_each( some_map.begin(), some_map.end(), select2ndsome_map::value_type() ); Since you normally have the pair type trivially available at the call site. (Of course, you also have the first_type and second_type available). There's a third form I've also found useful on occasion: struct selector1st { templatetypename Pair const typename Pair::first_type operator()( const Pair a ) const { return a.first; } }; (selector2nd is left as an excercise for the reader :) Which has the advantage of not needing to specify _any_ type at the call site: for_each( map.begin(), map.end(), selector1st() ); And again, is not limited to use with std::pair. However, it's utility is limited by not inheriting from std::unary_function. I think these disappeared from the standard around the same time as project1st/project2nd? (or at least, didn't make it in at around the same time :) Yes, Austern's book also mentions project1st and project2nd. Indeed it does (I checked shortly after my last post :) I believe one can build an even more flexible function object which returns an object of any type among multiple types using the Boost Tuple implementation. Of course one would have to pass an index to such a function object, which makes it a little more complicated to use than the pair implementations being discussed. Or one could have tuple_select1st... through tuple_selectxxx function objects up to some arbitrary limit. Maybe Jaakko Jarvi can add such a function object to the Tuple library if others find it useful. It would certainly be a useful addition (IMO, at least), although I think many users would be happy with a version that works for std::pair (the common case, of course, being operations on the elements of std::map) Regards, Andy S. -- Light thinks it travels faster than anything but it is wrong. No matter how fast light travels it finds the darkness has always got there first, and is waiting for it. -- Terry Pratchett, Reaper Man ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Interest in multiindex_set?(again)
Fernando Cacciola wrote: JOAQUIN LOPEZ MU?Z wrote: [...] Another thing I couldn't figure out is how to compose indices hierachically.That is, how to reproduce a typical SQL SELECT * ORDER BY X,Y,Z. Since you're modeling an indexed table, this functionality should be supported. This is an interesting subject to study, but as some others are already writing a relational framework I guess we should limit here to the basics of the container. SQL-like predicates can be built on top of it in the context of more ambitious libraries. I see. If this functionality can be built on top of it, then I think it is OK not to support it explicitely. If the library supports key extraction, for example, the the key extractor could simply return a tuple of references to e.g. the X, Y, and Z members of the value. With the default std::less comparison predicate, this would provide the desired lexigraphical ordering. [...] The most usual situation for specification of an index (standard less_than comparison on some member of the element) is already covered by less_by. Furthermore, less_by accepts an additional template parameter for specifying a comparison predicate other than std::less. For instance less_byemployee,std::string,employee::name specifies an index based on less_than comparison of employee::name (a string). If you want to use some other comparison criterium on empoyee::name (for instance, case insensitive comparison), you can write less_byemployee,std::string,employee::name,string_case_insensitive_compare Is this what you're referring to? Half of it. I see that I can use the precanned 'less-by' and specify a different comparison semantic (though in this case why is it named 'less_by' instead of 'order_by'), but I don't see how can I use it with something different than a data member as the key itself. On some applications, specially outside databases, the keys are given by runtime expressions and not just stored data members. If the users would have to end up writting their own predicates, the separaton will make that task a lot easier. Effectively, less_by to some extent *is* separating key extraction from comparison. It would be implemented to a greater extent if the additional functor were provided that was a more generic version of less_by, where the first argument is the key extractor functor. However, there are certain advantages, as I have discussed in previous posts, to integrating this separation into the table class directly. [...] If you want restoring-on-collision, use update(). To sum it up: * update() does restore-on-collision, with the overhead of an element copy. * modify() does not incur an element copy, but on collision the modified element is erased. I don't think we have other options here. I've tried to model modify() following your request and those of others, and the approach is IMHO forced by design. Anyway, I'm open to new ideas. OK, this is the best we could think of, at least right now. Many times the user knows exactly what she's doing so that no collisions will ever really ocurr. For example, if the modify does not change keys but other data. For this cases modify() is a big plus. The acutal user code could assert the result of modify() so that a coallision is treated as postcondition violation. The documentation could express emphatically that if the modification changed keys, update() must be used, else, modify() can. If the keys are not modified, a modify method is not needed. The idea of the modify method is to fix ordering as needed as a result of changing a key. Additionally, versions of modify could be provided that allow the user to specify, either by index number or a index tag (see below), in which indices reordering might be required, thus saving the cost of determining that in other indices, which the user knows will not be modified, no reordering is required. This functionality is important for efficiency. Ideally, a convenient syntax could be devised for specifying that no reordering will be required as a result of a modify operation. The problem is that it seems that, for instance: modify(it, functor); // should mean reorder in all indices modify3(it, functor); // reorder only 3 modifyTagType(it, functor); // reorder only indices with TagType tag Possibly, the way to do that would be to specify a tag-type that is not used by any index. E.g. if void is unused, then: modifyvoid(it, functor); // no reordering required Instead of this syntax, the alternative is to make the iterators non-constant. This is inconsistent with standard library associative containers (although this is not really an associative container); it does, however, allow for the use of standard algorithms that require non-constant iterators (but which will not modify the elements such that reordering would be necessary) without an adaptor. If non-constant iterators are not provided, it seems it would be useful to provide a const_casting iterator
[boost] Re: mpl/loki
Aleksey Gurtovoy [EMAIL PROTECTED] writes: David Abrahams wrote: Aleksey Gurtovoy [EMAIL PROTECTED] writes: IMO we should just stop using 'void_' for internal purposes and give it up to users :). I am still unsure about 'void_' being better than 'nil' or 'null' Users already have a type, 'void', which means void. ... in conventional run-time programs. Unfortunately, 'void' is not special for metaprograms, many of which have a need to routinely manipulate it along with all other built-in types. 'mpl::void_' addresses this issue. There's no correspondence between void_ and void the way there is between bool_ and bool. 'void_' in MPL plays a role very similar to a role of 'void' in the core language. So, conceptually, there is a correspondence. But that's only true as long as void_ is being used for internal purposes. Once you give it up to users as you suggest, it loses that correspondence, and we'll have some other internal name which has that correspondence to void. Personally, I appreciate the analogy, dislike 'null'/'nil'/etc. for the lack of such, and would like to keep the name. Makes little sense to me, especially after the give up, but maybe that's just me. -- Dave Abrahams Boost Consulting www.boost-consulting.com ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: N1477 Single Pass Iterators and *r++
Beman Dawes [EMAIL PROTECTED] writes: At 04:17 PM 7/12/2003, David Abrahams wrote: A single-pass iterator is required to support r++ (inherited from the incrementable iterator requirements), but I guess that we've unintentionally dropped the requiremnt for *r++ of readable single-pass iterator, by allowing incrementable iterators to return any type convertible to const X. I think it should require that the return type be X, the Assertion/Note/Precondition/Postcondition column should be labelled Operational Semantics and the lower right entry should be moved to the middle column. The same goes for the lower-right entry of each of the following two tables. I'm going to make those changes; if there are objections, please let me know ASAP. Done. In the main CVS? iterator-categories.html is still dated several days ago. Or am I looking in the wrong place? I guess so. Why would I be editing a document in the multi_array lib? I don't understand it, but Ron Garcia seems to have a fondness for checking duplicates of information that is hosted elsewhere into his library's tree. The source for that paper is kept in libs/iterator/docs/new-iter-concepts.rst and I keep an HTML version up-to-date at http://www.boost-consulting.com/writing/new-iter-concepts.html. -- Dave Abrahams Boost Consulting www.boost-consulting.com ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: mpl/loki
David Abrahams [EMAIL PROTECTED] wrote: Aleksey Gurtovoy [EMAIL PROTECTED] writes: IMO we should just stop using 'void_' for internal purposes and give it up to users :). I am still unsure about 'void_' being better than 'nil' or 'null' Users already have a type, 'void', which means void. There's no correspondence between void_ and void the way there is between bool_ and bool. IMO, there is. For example, the new TR1 tuples implementation (it's feature complete and in the sandbox now BTW) uses void_ as it would a void tuple element. nil_t or something would do, but we'll need to convert this to void_ simply because MPL expects void_. Admittedly, the void_ is not part of its public API and the use should not care about it, *but* you have to consider that the tuple lib *IS* a client of MPL. As such, it needs the mpl_void_ as a *public* API. Another good example is Phoenix/LL. We are using void_ much as a void argument to something. Here now, there is a direct mapping to our C++ void. Again, the void_ is not part of Phoenix's public API but then again, it *is* a client of MPL. -- Joel de Guzman joel at boost-consulting.com http://www.boost-consulting.com http://spirit.sf.net ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: filtered/decorated streambufs
Larry Evans wrote: [snip] I'm trying to get synopsis to translate into Boost guideline form; however, I'm having trouble with getting comments properly attached to the declarations. As soon as that is done, I'll upload it. The comments are properly attached; however, the ASCII formatter only formats the declarations, not the actual definitions. Hence, the executable code is not formatted according to Boost's guideline form. Maybe I'll get around to tweaking synopsis to do this later. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: N1477 Single Pass Iterators and *r++
At 07:19 PM 7/12/2003, David Abrahams wrote: Beman Dawes [EMAIL PROTECTED] writes: At 04:17 PM 7/12/2003, David Abrahams wrote: A single-pass iterator is required to support r++ (inherited from the incrementable iterator requirements), but I guess that we've unintentionally dropped the requiremnt for *r++ of readable single-pass iterator, by allowing incrementable iterators to return any type convertible to const X. I think it should require that the return type be X, the Assertion/Note/Precondition/Postcondition column should be labelled Operational Semantics and the lower right entry should be moved to the middle column. The same goes for the lower-right entry of each of the following two tables. I'm going to make those changes; if there are objections, please let me know ASAP. Done. In the main CVS? iterator-categories.html is still dated several days ago. Or am I looking in the wrong place? I guess so. Why would I be editing a document in the multi_array lib? I was talking about boost-root/libs/iterator/doc/iterator-categories.html, committed July 7 by Joel. That is the document I was expecting to see updated. I don't understand it, but Ron Garcia seems to have a fondness for checking duplicates of information that is hosted elsewhere into his library's tree. The source for that paper is kept in libs/iterator/docs/new-iter-concepts.rst and I keep an HTML version up-to-date at http://www.boost-consulting.com/writing/new-iter-concepts.html. Ron added that last January. He wanted something in Boost releases to refer to, IIRC.. Wouldn't it be better to bring the Boost CVS libs/iterator/doc stuff up-to-date? Particularly since there is no index.html in libs/iterator pointing to other locations. --Beman ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: N1477 Single Pass Iterators and *r++
Beman Dawes [EMAIL PROTECTED] wrote: In the main CVS? iterator-categories.html is still dated several days ago. Or am I looking in the wrong place? I guess so. Why would I be editing a document in the multi_array lib? I was talking about boost-root/libs/iterator/doc/iterator-categories.html, committed July 7 by Joel. That is the document I was expecting to see updated. Wouldn't it be better to bring the Boost CVS libs/iterator/doc stuff up-to-date? Particularly since there is no index.html in libs/iterator pointing to other locations. This is really what I intend to do. However, I'm having some difficulties with my net connection right now. If anyone would be so kind to link in the docs, I would appreciate it very much. Regards, -- Joel de Guzman joel at boost-consulting.com http://www.boost-consulting.com http://spirit.sf.net ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Problem compiling boost.filesystem library
Matthias Troyer wrote: Dear Boosters, After a recent cvs update I can no longer compile the boost filesystem library: The filesystem library was broken by the update in the main CVS to the new iterator adapators library, and AFAIK the changes that are needed have yet to be completed. --- Jeremy Maitin-Shepard [EMAIL PROTECTED] ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: N1477 Single Pass Iterators and *r++
Joel de Guzman [EMAIL PROTECTED] writes: Beman Dawes [EMAIL PROTECTED] wrote: In the main CVS? iterator-categories.html is still dated several days ago. Or am I looking in the wrong place? I guess so. Why would I be editing a document in the multi_array lib? I was talking about boost-root/libs/iterator/doc/iterator-categories.html, committed July 7 by Joel. That is the document I was expecting to see updated. Oh, I never saw that. Joel, it's inconvenient to have the .html file with a different name from the .rst file. Is there any reason we can't change that so they're both named new-iter-concepts.xxx? -- Dave Abrahams Boost Consulting www.boost-consulting.com ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Interest in multiindex_set?(again)
On Saturday, July 12, 2003, at 9:21 PM, Joaquín M López Muñoz wrote: Hi again, - Mensaje Original - De: Fernando Cacciola [EMAIL PROTECTED] Fecha: Sábado, Julio 12, 2003 7:32 pm Asunto: [boost] Re: Re: Interest in multiindex_set?(again) [stuff about conceptual structure of multtindex_set deleted] OK, I'm glad we finally got to understand each other :) There's a problem with the name of the class. Others have expressed dislike for multtindex_set. Alternative candidates are indexed_set and indexed_table. I haven't decided yet for one, plus there's the problem of which namespace should this live in (regardless of whether it is promoted to namespace boost later). The alternatives so far are (name of the class/associated namespace) * multiindex_set/boost::multiindex * indexed_set/?? * indexed_table/?? * ??/boost::container (proposed by Daryle) boost::container I don't like because some of the associated small utility classes and functions (less_by, get, project) shouldn't really belong into a general-purpose namespace like container which is supposed to hold other contributions. Also, there's the additional problem that the class and the namespace shouldn't be named the same (it makes some compilers choke, this has been discussed in connection with Boost.Tuple). Suggestions in this area are most welcome. [TRUNCATE] If the small utility classes are sufficiently independent from your main classes, then put them in separate (possibly unrelated) namespaces. I don't we've ever reviewed a multi-domain package, though. Or we can review the utility parts separately, first. Daryle ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] About member extraction
In another thread, by Joaquín M López Muñoz, there is talk of a helper class like: // template class Class,typename Type, Type Class::*PtrToMember, typename Compare=std::lessType struct less_by { less_by(const Compare comp=Compare()):comp(comp){} bool operator()(const Class x,const Class y)const { return comp(x.*PtrToMember,y.*PtrToMember); } bool operator()(const Type x,const Class y)const { return comp(x,y.*PtrToMember); } bool operator()(const Class x,const Type y)const { return comp(x.*PtrToMember,y); } private: Compare comp; }; // [That was cut from the multindex trial code.] The author later decided to segregate the extraction from the comparison. No code has been given yet, but that class could be like: // template class Class,typename Type, Type Class::*PtrToMember struct member { Type const operator ()( Class const c ) const { return c.*PtrToMember; } Type operator ()( Class c ) const { return c.*PtrToMember; } }; // But doesn't the PtrToMember template parameter already imply the Type and Class parameters? So specifying all three would be redundant. Could we reduce it by: // template typename PtrToMember struct member_extractor { // Don't know if this is a real type-traits class BOOST_STATIC_ASSERT(is_pointer_data_memberPtrToMember::value); // The extractor traits classes aren't real (yet, maybe) typedef get_class_typePtrToMember argument_type; typedef get_member_typePtrToMember return_type; return_type const operator ()( argument_type const c ) const { return c.*PtrToMember; } return_type operator ()( argument_type c ) const { return c.*PtrToMember; } }; // Or we can simplify the type extraction, at the cost/gain of needing to specify the exact member at construction time by: // template class Class, typename Type class member_extractor { public: typedef Class argument_type; typedef Type return_type; typedef Type Class::* member_type; explicit member_extractor( member_type m ) : member_( m ) {} return_type const operator ()( argument_type const c ) const { return c.*member_; } return_type operator ()( argument_type c ) const { return c.*member_; } member_type get_member() const { return this-member_; } private: member_type member_; }; // Daryle ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost