I want to have a token structure that has start / end pairs for position, sentence and paragraph information. I also want participants to be available in different ways: as a start / end pair and individually. Given:
struct token { struct start_end { int start; int end; }; start_end pos; start_end sent; start_end para; typedef start_end token::*start_end_ptr; };
I can write a function, say distance() , which calculates the distance between any of the three start / end pairs, such as:
int distance( token const &i, token const &j, token::start_end_ptr mbr ) { return (j.*mbr).start - (i.*mbr).end; }
and name it like this:
token i, j; int d = distance( i, j, &token::pos );
which will return the distance from the pair pos . But I can also pass &token::sent or &token::para , and it does what I want. Therefore, the function is flexible.
However, now I also want to write a function, say max() , which calculates the maximum value for all pos.start or all pos.end or all sent.start , etc.
If I add:
typedef int token::start_end::*int_ptr;
I can write a function like:
int max( list<token> const &l, token::int_ptr p ) { int m = numeric_limits<int>::min(); for ( list<token>::const_iterator i = l.begin(); i != l.end(); ++i ) { int n = (*i).pos.*p;
and name it like this:
list<token> l; l.push_back( i ); l.push_back( j ); int m = max( l, &token::start_end::start );
However, as stated in the comment above, I do not want to hardcode the pos . I want the flexibility of the available start or end any of pos , sent or para to be passed as a parameter to max() .
I tried several things to get this to work (tried using unions, anonymous unions, etc.), but I can't come up with a data structure that allows flexibility in both ways when saving each value only once.
Any ideas how to arrange the token structure so that I can have what I want?
Attempted clarification
Given the structure of integer pairs, I want to be able to "slice" the data in two different ways:
- Passing a pointer to an element of a specific start / end pair, so that the called function works on any pair, not knowing which pair. The caller decides which pair.
- By passing a pointer to an element of a particular
int (i.e. only one int any pair), so the function being called works on any int , not knowing what int , or which pair said int from. The caller decides which int which pair.
Another example for the latter would be the summation of, say, total para.end or total sent.start .
Also, and what's important: for # 2 above, I would ideally want to pass only one member pointer to reduce the load on the caller. Therefore, I am trying to understand something using alliances.
For # 2, the structure will be optimally laid out like this:
struct token2 { int pos_start; int pos_end; int sent_start; int sent_end; int para_start; int para_end; };
The trick is token and token2 somehow superimposed on the union , but this is not obvious if / how to do it and still satisfy the available requirements.