[multi_index] index based on case-insensitive strings
struct employee { std::string name; }; typedef multi_index_container< employee, indexed_by< hashed_unique<member<employee, std::string, &employee::name> >
mi;
If I want to change the index to make it case-insensitive I have to write my own key extractor, right? Would the following code then be correct (it is based on boost::multi_index::member)? template<class Class, std::string Class::*PtrToMember> struct caseinsensitive_string { typedef std::string result_type; template<typename ChainedPtr> std::string operator()(const ChainedPtr& x) const { return operator()(*x); } std::string operator()(const Class& x) const { return boost::algorithm::to_lower_copy(x.*PtrToMember); } std::string operator()(Class& x) const { return boost::algorithm::to_lower_copy(x.*PtrToMember); } std::string operator()(const boost::reference_wrapper<const Class>& x) const { return operator()(x.get()); } std::string operator()(const boost::reference_wrapper<Class> x) const { return operator()(x.get()); } }; With the following typedef I get a container which does not change the name of an employee (I want to retain the name without making it lower- or uppercase) but refuses items with the same case-insensitive name? typedef multi_index_container< employee, indexed_by< hashed_unique<caseinsensitive_string<employee, &employee::name> >
mi2;
Boris
Boris ha escrito:
struct employee { std::string name; };
typedef multi_index_container< employee, indexed_by< hashed_unique<member<employee, std::string, &employee::name> >
mi;
If I want to change the index to make it case-insensitive I have to write my own key extractor, right? Would the following code then be correct (it is based on boost::multi_index::member)?
[...] Yep, it is correct, though possibly a little overkill; you could use a simpler key extractor for the task at hand, like this: struct employee_case_insensitive_name_extractor { typedef std::string result_type; std::string operator()(const employee& x) const { return boost::algorithm::to_lower_copy(x.name); } };
With the following typedef I get a container which does not change the name of an employee (I want to retain the name without making it lower- or uppercase) but refuses items with the same case-insensitive name?
typedef multi_index_container< employee, indexed_by< hashed_unique<caseinsensitive_string<employee, &employee::name> >
mi2;
Well, you just have to try in order to find out :) Looks pretty much like it'll do what you want. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
On Fri, 23 Feb 2007 11:24:35 +0200, Joaquín Mª López Muñoz <joaquin@tid.es> wrote:
[...]Yep, it is correct, though possibly a little overkill; you could use a simpler key extractor for the task at hand, like this:
struct employee_case_insensitive_name_extractor { typedef std::string result_type;
std::string operator()(const employee& x) const { return boost::algorithm::to_lower_copy(x.name); } };
If the existing key extractors had a fourth template parameter to accept an unary function object I think it would be a bit easier to create user-defined key extractors? Imagine a (simplified) member defintion like this: template<class Class,typename Type,Type Class::*PtrToMember,typename Functor> struct member { typedef Type result_type; Type& operator()(const Class& x)const { return Functor(x.*PtrToMember); } }; Now I could create my multi_index_container like this: typedef multi_index_container< employee, indexed_by< hashed_unique<member<employee, std::string, &employee::name, boost::algorithm::to_lower_copy> >
mi2;
Do I miss anything? If not please regard this as a proposal to improve Boost.Multi-index. :) Boris
After some playing around I got now this code to compile (based on boost::multi_index::detail::const_member_base): template<class Class,typename Type,Type Class::*PtrToMember,Type (*func)(const Type&)> struct my_member { typedef Type result_type; template<typename ChainedPtr> Type& operator()(const ChainedPtr& x)const { return operator()(*x); } Type operator()(const Class& x)const { return func(x.*PtrToMember); } Type& operator()(const reference_wrapper<const Class>& x)const { return operator()(x.get()); } Type& operator()(const reference_wrapper<Class> x,int=0)const { return operator()(x.get()); } }; std::string test(const std::string &s) { return boost::algorithm::to_lower_copy(s); } typedef multi_index_container< employee, indexed_by< hashed_unique< my_member<employee, std::string, &employee::name, &test> >
mi;
mi employees; I don't know if it can be more generalized or if it is of any help for anybody else except me. But now I don't have the time to play around some more with key extractors unfortunately. :) Boris
Boris ha escrito: [...]
If the existing key extractors had a fourth template parameter to accept an unary function object I think it would be a bit easier to create user-defined key extractors? Imagine a (simplified) member defintion like this:
template<class Class,typename Type,Type Class::*PtrToMember,typename Functor> struct member { typedef Type result_type;
Type& operator()(const Class& x)const { return Functor(x.*PtrToMember); } };
Now I could create my multi_index_container like this:
typedef multi_index_container< employee, indexed_by< hashed_unique<member<employee, std::string, &employee::name, boost::algorithm::to_lower_copy> >
mi2;
Do I miss anything?
Alas, yes. You can't provide boost::algorithm::to_lower_copy as the fourth parameter of member<> since it is a function template and member<> expects a type --you'd have to wrap the function up into a user-defined functor class.
If not please regard this as a proposal to improve Boost.Multi-index. :)
Your suggestion is appealing at first sight, but I'm not inclined to implement it. I could go and try to provide some facilities to cascade key extractors, but in the end one reaches a point where the possible benefits are outweighed by the clumsy syntax, only to avoid defining very simple custom key extractors. And no framework can conver all the cases, as you have experienced in your previous example. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
participants (2)
-
Boris
-
Joaquín Mª López Muñoz