Re: [boost] Re: Interest in multiindex_set?(again)

2003-07-12 Thread JOAQUIN LOPEZ MU?Z
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)

2003-07-12 Thread Fernando Cacciola
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++

2003-07-12 Thread Beman Dawes
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

2003-07-12 Thread Aleksey Gurtovoy
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++

2003-07-12 Thread David Abrahams
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

2003-07-12 Thread David Abrahams
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)

2003-07-12 Thread JOAQUIN LOPEZ MU?Z
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++

2003-07-12 Thread David Abrahams
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

2003-07-12 Thread Aleksey Gurtovoy
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?

2003-07-12 Thread Brian McNamara
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 ...]

2003-07-12 Thread Beman Dawes
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

2003-07-12 Thread Drazen DOTLIC
 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

2003-07-12 Thread Daniel Frey
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?

2003-07-12 Thread Andy Sawyer
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)

2003-07-12 Thread Jeremy Maitin-Shepard
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

2003-07-12 Thread David Abrahams
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++

2003-07-12 Thread David Abrahams
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

2003-07-12 Thread Joel de Guzman
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

2003-07-12 Thread Larry Evans
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++

2003-07-12 Thread Beman Dawes
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++

2003-07-12 Thread Joel de Guzman
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

2003-07-12 Thread Jeremy Maitin-Shepard
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++

2003-07-12 Thread David Abrahams
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)

2003-07-12 Thread Daryle Walker
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

2003-07-12 Thread Daryle Walker
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