small library proposal -- rebind template args and function pointer types

Hello Boost Members, I have written a small library of meta-functions that allow rebinding of template arguments and function pointer return/argument types. I am posting in an attempt to guage interest and hopefully receive pointers on the library proposal process. The library provides the following meta-functions: rebind<int index, class rebind_type, class source_type> -- rebind template arguments rebind_func_arg<int index, class rebind_type, class func_type> -- rebind argument type of func/method ptr rebind_func_return<class rebind_type, class func_type> -- rebind return type of func/method ptr rebind_method_class<class rebind_type, class func_type> -- rebind class portion of method ptr // --- rebind<> example ------------------------------------------------ template <class A, class B, class C> class foo { }; typedef foo<int, int, int> source_type; typedef rebind<1, char, source_type>::type rebound_type; // rebound_type equates to foo<int, char, int> // --- rebind_func_arg<> example --------------------------------------- typedef int (*func_ptr)(int); typedef rebind_func_arg<0, char, func_ptr>::type rebound_type // rebound_type equates to int (*)(char) // rebind_func_args also works with pointer-to-method types // --- rebind_func_return<> example ------------------------------------ typedef int (*func_ptr)(int); typedef rebind_func_return<char, func_ptr>::type rebound_type // rebound_type equates to char (*)(int) // rebind_func_return also works with pointer-to-method types // --- rebind_method_class<class rebind_type, class func_type> --------- typedef int (foo::*method_ptr)(int); typedef rebind_method_class<bar, method_ptr>::type rebound_type; // rebound_type equates to int (bar::*)(int); -- end examples -- I have tested the code using MSVC 7.1 and GCC 3.3.2-1. Please let me know if this library would be useful to any of you, or otherwise any reason why it is not required or, of course any tips/suggestions/questions that you might have. Kind Regards, James Harris.

From: "James Harris" <james.harris@icecave.com.au>
rebind_method_class<class rebind_type, class func_type> -- rebind class portion of method ptr
[snip]
Please let me know if this library would be useful to any of you, or otherwise any reason why it is not required or, of course any tips/suggestions/questions that you might have.
I can't say that I've run across the need for such a library. Note that C++ doesn't have methods; they are called member functions. rebind_method_class is misnamed. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

Hi James, is it possible to have a look inside ? Rebinding template arguments sounds interesting (although I find the order of the parameters a bit strange). I could imagine cases where this is useful (for example making a std::{container}<type> a std::{container}< proxy<type> >). Jonathan Turkanis wrote a small lib for decomposing and synthesizing member function / function types, which covers the function part of your library. [ see http://thread.gmane.org/gmane.comp.lib.boost.devel/111645 ] I am currently working on some internal refinement of this, so I am curious to see how you implemented the function part. ( If it inspires my code your work will be acknowledged, of course. ) As I said in the thread referenced above I don't really know any real world applications for the synthesis part of it - same thing with the function part of your library. Regards, Tobias

"James Harris" <james.harris@icecave.com.au> wrote in message news:clvhdd$3rp$1@sea.gmane.org...
Hello Boost Members,
I have written a small library of meta-functions that allow rebinding of template arguments <snip> I am posting in an attempt to guage interest and hopefully receive pointers on the library proposal process.
The library provides the following meta-functions:
rebind<int index, class rebind_type, class source_type> -- rebind template arguments
To be MPL-friendly, it should be template<typename N, typename rebind_type, typename source_type> struct rebind; <snip>
template <class A, class B, class C> class foo { };
typedef foo<int, int, int> source_type; typedef rebind<1, char, source_type>::type rebound_type; // rebound_type equates to foo<int, char, int>
On two occassions recently I found myself implementing a template-argument-rebinding facility and wished for a generic solution. Unfortunately, I just looked at my two use cases and found that the metafunction you describe would not be much help. Let me describe these cases, to give you an idea of the problems which a generic rebind facility should IMO be able to solve. --- 1) In my yet-to-be documented or posted "Format Lite" library -- a lightweight alternative to Reece Dunne's recently reviewed Output Formatting library -- I use class template specializations as CSS-type selectors to indicate the set of classes which should receive a given formatting. E.g., cout << punctuate< vector<string> >("[", ",", "]") << punctuate< vector<_> >("{", ",", "}"); The above code tells std::cout to format vectors of strings with square brackets but all other vectors with curly brackets. I wanted to treat vector<_> and vector<_, _> as equlivalent, so I wrote a metafunction rebind which takes a template specialization T<P1, ..., Pn> and returns T<_, ..., _>. Using your library, I would need to use an mpl iteration construct to implement this templa te, and would also need to discover the arity of T (using mpl::aux::template_arity). A much more efficient and straightforward solution is to use a sequence of partial specializations, one for each arity. The moral is that rebind should be able to rebind several template arguments at once. 2) For another yet-to-be posted library, I implemented a generic facility for chaining user-defined policies to avoid increased instance size resulting from multiple inheritance. (See http://www.boost.org/libs/utility/operators.htm#chaining http://www.cuj.com/documents/s=8890/cujexp0310alexandr/alexandr.htm ) The convention is that user-defined policies should be templates whose last argument position is reserved for another policy, from which the user-defined policy should derive. Now, given two policies P1 and P2, we can combine them as follows: (i) if P1 is not a template instance (shame on the user!), return a policy which derives indirectly from both P1 and P2. (ii) if P1 is a template specialization of the form T<Arg1, ...., Arg(n-1), empty_base>, return T<Arg1, ...., Arg(n-1), P2> (iii) otherwise, if P1 is a template specialization of the form T<Arg1, ...., Argn>, return T< Arg1, ..., combine<Argn, P2> > Again, this is fairly straightforward to implement as a sequence of partial specializations (two for each arity, this time), but your metafunction doesn't help much. --- I'm not sure there is a general solution to problems like the above, but I'd be interested to see If you can come up with one.
I have tested the code using MSVC 7.1 and GCC 3.3.2-1.
Have you tested it with templates that have default template arguments? GCC notoriously will allow std::vector<char> to match the partial specialization template<template<typename> class T, typename P> struct foo< T<P> > { /* ... */ }; despite the fact that std::vector is a binary template.
Kind Regards, James Harris.
Jonathan
participants (4)
-
James Harris
-
Jonathan Turkanis
-
Rob Stewart
-
Tobias Schwinger