views:

210

answers:

1

Hi Could anyone give me a sample program to "Create an ApplyRemoveConst template that constructs a new typelist with remove_const applied to each element"

For example:

typedef TYPELIST_3(A, const B, B) TL;
typedef ApplyRemoveConst<TL>::Result TL2;
// TL2 is the same as TYPELIST_3(A, B, B)


//Typelist Definition:

template<class T, class U>
struct Typelist
{
    typedef T Head;
    typedef U Tail;
    // Lets us a print a typelist
    inline static ostream &print(ostream &os) {
        return printInternal(os, "[");
    }
    inline static ostream &printInternal(ostream &os, string delimiter) {
        os << delimiter << typeid(Head).name();
        return Tail::printInternal(os, ", ");
    }
private:
    Typelist(); // Cannot create!
};

#define TYPELIST_1(T1)  Typelist<T1, NullType>
#define TYPELIST_2(T1, T2) Typelist<T1, TYPELIST_1(T2)>
#define TYPELIST_3(T1, T2, T3) Typelist<T1, TYPELIST_2(T2, T3)>

// Null type definition 

class NullType{
public:
    // NullType ends a typelist (just like NULL ends a C string)
    inline static ostream &printInternal(ostream &os, string delimiter) {
        return os << "]";
    }
};
+4  A: 

I think what you want is something like this:

template <typename, template <typename> class>
struct transform;

template <template <typename> class Func>
struct transform<NullType, Func>
{
    typedef NullType type; // nothing to do
};

template <typename T, typename U, template <typename> class Func>
struct transform<Typelist<T, U>, Func>
{
    typedef typename Func<T>::type Head; // apply to head
    typedef typename transform<U, Func>::type Tail; // tail is transformed tail

    typedef Typelist<Head, Tail> type; // put together
};

This applies something recursively. It makes a new list, by applying to the head, then taking everything else as the tail, applied. That in turn applies the head, and so on, until a NullType is reached in which we just get NullType.

Then you just need a meta-functor:

template <typename T>
struct remove_const
{
    typedef T type;
};

template <typename T>
struct remove_const<const T>
{
    typedef T type;
};

Then put them together:

typedef TYPELIST_3(A, const B, B) TL;
typedef transform<TL, remove_const>::type TL2;
// TL2 is the same as TYPELIST_3(A, B, B)

It should be noted I haven't tried any of this.

GMan
@GMan: doesn't your `apply` need it's second (`Func`) arg to be a template template parameter?
Mike Dinsdale
Hi How do I format my question such that it can be displayed in a better way ?
Eternal Learner
@Srinivasa: there's a guide [Here](http://stackoverflow.com/editing-help)
Mike Dinsdale
@Mike: Yes, sorry for slow reply. (Deadline in 30!) On second look, the code is disastrous. :) This time around should work. @Srinivasa: Check out your post, which I've edited. You need 4 spaces before code; the easiest way do that is to highlight it and click the 1010 button.
GMan
+1 Yep, this seems to work fine now... one small issue: the name `apply` might be a bit confusing, as this isn't what `apply` normally means in functional languages, or (so far as I can understand it ;)), `boost::mpl::apply` - mind you, `map` would be worse!
Mike Dinsdale
`transform` should be a suitable name.
Georg Fritzsche
@GMan: Your deadline is in 30 _what_? Minutes or decades? `:)`
sbi
@sbi: Heh, I thought that might annoy someone. :P Around here we just ramble off numbers and assume they're minutes. It annoys me too (units!?!) but then I end up doing it.
GMan