I'm trying to redesign functions for dynamic_any. Currenly, I have this: struct less : function_vv<bool> { template<typename T> bool operator()(const T & a, const T & b) const { return a < b; } };
Two trailing 'v' in function_vv are indicators that less accepts two arguments by value or const reference. First change I'm going to make is to remove these trailing letters and to introduce more natural syntax (idea is taken from Boost.Function): struct less : function<bool (const arg &, const arg &)> { template<typename Arg> bool operator()(const Arg & a, const Arg & b) const { return a < b; } }; The 'arg' is a placeholder for pseudo-template parameter. Compare it with Arg defined in less::operator() and with less::operator() signature. This change doesn't solve other problem: using of a 'call' function: using namespace boost; using namespace boost::dynamic_any; any<mpl::list<less> > a, b; bool result = call(less(), a, b); // here is a problem I would like it to be: any<mpl::list<less> > a, b; bool result = less()(a, b); // much better Curiously recurring pattern suits fine here. Let the class template 'function' to accept end function (less in our case). Call operator that takes two 'any' values can be implemented inside the 'function' (constness of arguments leaved apart for simplicity): template<class EndFunction, typename Signarure> struct function { template<class OperationLlist> typename function_result<OperationList, EndFunction>::type operator()(any<OperationList> & a, any<OperationList> & b) { // implementation } // implementation }; But it will be hidden by the call operator defined in EndFunction. EndFunction::operator() should be renamed: struct less : function<less, bool (const arg &, const arg &)> { // note the name template<typename Arg> bool call(const Arg & a, const Arg & b) const { return a < b; } }; Additionally, two types of control are desired: 1) Control over real types of arguments. It is a limitation of dynamic_any library that arguments must be converted to _one_ type before a call. But they can be of different types. Problem can be easily solved by adding additional arguments to the 'call' member-function: template<typename Arg> bool less::call(const Arg & a, const std::type_info & ta, const Arg & b, const std::type_info & tb) const { return a < b; } 2) Controlled behavior when the call cannot be made. I propose to make it over 'nocall' member-function. Default handler can be implemented inside the 'function' as a single throw statement. Those users who wish other behavior can override 'nocall'. As a summary I can demonstrate less function that compares first by type and then by value: struct less : function<less, bool (const arg &, const arg &)> { template<typename Arg> bool call(const Arg & a, const std::type_info & ta, const Arg & b, const std::type_info & tb) const { return (ta == tb) ? (a < b) : ta.before(tb); } template<typename OperationList> bool nocall(const any<OperationList> & ta, const any<OperationList> & tb) const { return a.type().before(b.type()); } }; // Example: typedef any<mpl::list<less> > any_less; std::vector<any_less> v = get_it(); std::sort(v.begin(), v.end(), less()); How do you like it? Best regards, Alexander Nasonov mailbox: alnsn server: mail.ru _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost