Re: [boost] [multi-index] key_value

Hello Tal, ----- Mensaje original ----- De: Tal Agmon <tal.boost@gmail.com> Fecha: Domingo, Agosto 20, 2006 6:20 pm Asunto: [boost] [multi-index] key_value
Hi,
I am happy to work with multi_index library up till now I am able to operate successfully a 5 indices with my cranky msvc 6.5 comiler at work.
Remarkable, given the unstability of that old compiler.
I do have a naive question
Is it possible to retreive all key values from an N index_type container? and how can I do it?
I don't understand the question. What do you mean by "key value" and by "an N index_type container"? In case the following is somewhat related to your problem, here's how one can produce the key part of each element of a given key-based index (uncompiled, expect typos.) // multi_index_t is some multi-index container. multi_index_t m; ... // index N-th is key-based (for instance, ordered.) typedef nth_index<multi_index_t,N>::type index_t; const index_t& i=get<N>(m); for(index_t::const_iterator it=i.begin();it!=i.end();++it){ std::cout<<i.key_extractor()(*it)<<std::endl; } This code uses the member function key_extractor(), which returns a copy of the internal key extractor, to extract the key part of a given element. In case your question is not addressed by the snippet above, I'd appreciate if you could explain it a little more clearly, possibly stating what your final goal is. Thank you for using Boost.MultiIndex, Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

Hi Joaquin, Sorry for the lack of info in my previous quote. I appreicate your affort to promptly help me. What I have is a non_unique which I carry to get all the keys.( I don't care about the elements) My guess is that key_extractor() returns a key_form_element, is quite redundant in my case. Regards Tal On 8/21/06, JOAQUIN LOPEZ MU?Z <joaquin@tid.es> wrote:
Hello Tal,
----- Mensaje original ----- De: Tal Agmon <tal.boost@gmail.com> Fecha: Domingo, Agosto 20, 2006 6:20 pm Asunto: [boost] [multi-index] key_value
Hi,
I am happy to work with multi_index library up till now I am able to operate successfully a 5 indices with my cranky msvc 6.5 comiler at work.
Remarkable, given the unstability of that old compiler.
I do have a naive question
Is it possible to retreive all key values from an N index_type container? and how can I do it?
I don't understand the question. What do you mean by "key value" and by "an N index_type container"? In case the following is somewhat related to your problem, here's how one can produce the key part of each element of a given key-based index (uncompiled, expect typos.)
// multi_index_t is some multi-index container. multi_index_t m; ...
// index N-th is key-based (for instance, ordered.) typedef nth_index<multi_index_t,N>::type index_t; const index_t& i=get<N>(m); for(index_t::const_iterator it=i.begin();it!=i.end();++it){ std::cout<<i.key_extractor()(*it)<<std::endl; }
This code uses the member function key_extractor(), which returns a copy of the internal key extractor, to extract the key part of a given element.
In case your question is not addressed by the snippet above, I'd appreciate if you could explain it a little more clearly, possibly stating what your final goal is.
Thank you for using Boost.MultiIndex,
Joaquín M López Muñoz Telefónica, Investigación y Desarrollo _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Tal Agmon ha escrito:
Hi Joaquin,
Sorry for the lack of info in my previous quote. I appreicate your affort to promptly help me.
What I have is a non_unique which I carry to get all the keys.( I don't care about the elements)
My guess is that key_extractor() returns a key_form_element, is quite redundant in my case.
Hello again. Still I'm having difficulties with understanding your question, but let me try my hand: are you looking for a way to produce all *different* key values contained by an index? If so, something like the following would do: for(index_t::const_iterator it=i.begin();it!=i.end();){ // note: no ++it // output the key std::cout<<i.key_extractor()(*it)<<std::endl; // jump to the next different key value it=i.upper_bound(i.key_extractor()(*it)); } Now, is this what you were asking about?
Regards Tal
Best, Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

Still I'm having difficulties with understanding your question, but let me try my hand
Your are good! :) I should knock myself for not sending you a snippet code below you can fiind a "small" example with only 2 indices ******** BEGIN CODE ******** typedef int handle; typedef int group_id; struct NodeBase:boost::enable_shared_from_this<NodeBase> { virtual ~NodeBase(){} virtual group_id memberOf()const=0; virtual handle getHandle()const=0; }; struct NodeType:NodeBase { NodeType(handle h,group_id gid):h(h),gid(gid){} virtual group_id memberOf()const{return gid;} virtual handle getHandle()const{return h;} private: group_id gid; handle h; }; struct NodeBaseHandleExtractor { typedef handle result_type; result_type operator()(const boost::shared_ptr<NodeBase>& x) { return x->getHandle(); } }; struct NodeBaseGroupIdExtractor { typedef group_id result_type; result_type operator()(const boost::shared_ptr<NodeBase>& x) { return x->memberOf(); } }; typedef boost::multi_index::multi_index_container< boost::shared_ptr<NodeBase>, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< NodeBaseHandleExtractor
, boost::multi_index::ordered_non_unique<
NodeBaseGroupIdExtractor
NodePtrSet;
int main() { NodePtrSet ns; typedef boost::shared_ptr<NodeBase> element_type; ns.insert(element_type(new NodeType(0,10))); // 0 = id, 10 = group_id ns.insert(element_type(new NodeType(1,10))); ns.insert(element_type(new NodeType(2,20))); // Now lets say I want to get a list of unique group_id values. // so I should get {10,20} event thought I have 3 elements //if i use the following for(index_t::const_iterator it=i.begin();it!=i.end();){ // note: no ++it // output the key std::cout<<i.key_extractor()(*it)<<std::endl; // jump to the next different key value ( which is great btw) it=i.upper_bound(i.key_extractor()(*it)); } //Note that the for loop still iterates 3 times and not 2 times. // Meaning that the results of the key_extractor()(*it) key_value are {10,10,20} // My goal is to get back just {10,20} and not {10,10,20} //assuming that in this non_unique_index container the key (group_id) is at least unique even though 10 points to 2 elements. return 0; } I hope I made my point this time. Regards Tal Agmon On 8/21/06, Joaquín Mª López Muñoz <joaquin@tid.es> wrote:
Tal Agmon ha escrito:
Hi Joaquin,
Sorry for the lack of info in my previous quote. I appreicate your affort to promptly help me.
What I have is a non_unique which I carry to get all the keys.( I don't care about the elements)
My guess is that key_extractor() returns a key_form_element, is quite redundant in my case.
Hello again.
Still I'm having difficulties with understanding your question, but let me try my hand: are you looking for a way to produce all *different* key values contained by an index? If so, something like the following would do:
for(index_t::const_iterator it=i.begin();it!=i.end();){ // note: no ++it // output the key std::cout<<i.key_extractor()(*it)<<std::endl;
// jump to the next different key value it=i.upper_bound(i.key_extractor()(*it)); }
Now, is this what you were asking about?
Regards Tal
Best,
Joaquín M López Muñoz Telefónica, Investigación y Desarrollo _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Tal Agmon ha escrito:
Still I'm having difficulties with understanding your question, but let me try my hand
Your are good! :) I should knock myself for not sending you a snippet code
below you can fiind a "small" example with only 2 indices
[...]
// Now lets say I want to get a list of unique group_id values. // so I should get {10,20} event thought I have 3 elements
//if i use the following [...] //Note that the for loop still iterates 3 times and not 2 times. // Meaning that the results of the key_extractor()(*it) key_value are {10,10,20} // My goal is to get back just {10,20} and not {10,10,20}
[...]
I hope I made my point this time.
Yep, now it is much clearer, thanks. I've taken your snippet and filled in a few bits (missing includes, missing typedef and declaration for index_t and i, the key extractors' operator()'s were not const) and everything seems to be working, both on GCC 3.2 and MSVC 6.5, the output is 10 20 like you require. I don't know how you're observing the loop iterating thrice, here it does two steps as it should. Please check the attached file to see if this solves your needs. Best, Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

Joaquin, It works !
From some reason the point I made In the latter code shows this strange results But then when I tried this sample on another non_unique_index the results was correct. then I had to figure out what the ...
the cure was to rebuild the project (...or maybe a coffee break for me and my computer). Other than that I appreciate your efforts and you can ignore my previous post I should be getting a new compiler which will be more friendly pretty soon. Regards, On 8/21/06, Tal Agmon <tal.boost@gmail.com> wrote:
Still I'm having difficulties with understanding your question, but let me try my hand
Your are good! :) I should knock myself for not sending you a snippet code
below you can fiind a "small" example with only 2 indices
******** BEGIN CODE ********
typedef int handle; typedef int group_id;
struct NodeBase:boost::enable_shared_from_this<NodeBase> {
virtual ~NodeBase(){}
virtual group_id memberOf()const=0; virtual handle getHandle()const=0; };
struct NodeType:NodeBase { NodeType(handle h,group_id gid):h(h),gid(gid){}
virtual group_id memberOf()const{return gid;} virtual handle getHandle()const{return h;}
private: group_id gid; handle h; };
struct NodeBaseHandleExtractor { typedef handle result_type; result_type operator()(const boost::shared_ptr<NodeBase>& x) { return x->getHandle(); } };
struct NodeBaseGroupIdExtractor { typedef group_id result_type; result_type operator()(const boost::shared_ptr<NodeBase>& x) { return x->memberOf();
} };
typedef boost::multi_index::multi_index_container< boost::shared_ptr<NodeBase>, boost::multi_index::indexed_by< boost::multi_index::ordered_unique<
NodeBaseHandleExtractor
, boost::multi_index::ordered_non_unique<
NodeBaseGroupIdExtractor
NodePtrSet;
int main() { NodePtrSet ns;
typedef boost::shared_ptr<NodeBase> element_type;
ns.insert(element_type(new NodeType(0,10))); // 0 = id, 10 = group_id ns.insert(element_type(new NodeType(1,10))); ns.insert(element_type(new NodeType(2,20)));
// Now lets say I want to get a list of unique group_id values. // so I should get {10,20} event thought I have 3 elements
//if i use the following for(index_t::const_iterator it=i.begin();it!=i.end();){ // note: no ++it // output the key
std::cout<<i.key_extractor()(*it)<<std::endl;
// jump to the next different key value ( which is great btw) it=i.upper_bound(i.key_extractor()(*it)); }
//Note that the for loop still iterates 3 times and not 2 times. // Meaning that the results of the key_extractor()(*it) key_value are {10,10,20}
// My goal is to get back just {10,20} and not {10,10,20} //assuming that in this non_unique_index container the key (group_id) is at least unique even though 10 points to 2 elements.
return 0; }
I hope I made my point this time.
Regards Tal Agmon
On 8/21/06, Joaquín Mª López Muñoz <joaquin@tid.es> wrote:
Tal Agmon ha escrito:
Hi Joaquin,
Sorry for the lack of info in my previous quote. I appreicate your affort to promptly help me.
What I have is a non_unique which I carry to get all the keys.( I don't care about the elements)
My guess is that key_extractor() returns a key_form_element, is quite redundant in my case.
Hello again.
Still I'm having difficulties with understanding your question, but let me try my hand: are you looking for a way to produce all *different* key values contained by an index? If so, something like the following would do:
for(index_t::const_iterator it=i.begin();it!=i.end();){ // note: no ++it // output the key std::cout<<i.key_extractor()(*it)<<std::endl;
// jump to the next different key value it=i.upper_bound(i.key_extractor()(*it)); }
Now, is this what you were asking about?
Regards Tal
Best,
Joaquín M López Muñoz Telefónica, Investigación y Desarrollo _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (3)
-
JOAQUIN LOPEZ MU?Z
-
Joaquín Mª López Muñoz
-
Tal Agmon