Looping typedefs - PullRequest
       2

Looping typedefs

2 голосов
/ 21 сентября 2011

У меня есть скучная функция, которую я хочу запустить, я хочу перебрать ее, чтобы сэкономить это время (у меня есть все данные), но для этого требуются типы.Есть ли способ сделать массив типов, или есть что-то комплиментное время, чтобы сделать это?(Если это помогает, у меня есть 3 типа и я хочу запустить метод со всеми типами для всех типов).

fprintf(stdout, "Testing UTF-32...\n");
testUTF<uint32_t, uint32_t>(&testEncs[0], &testEncs[0]);
testUTF<uint32_t, uint16_t>(&testEncs[0], &testEncs[1]);
testUTF<uint32_t, uint8_t> (&testEncs[0], &testEncs[2]);

fprintf(stdout, "Testing UTF-16...\n");
testUTF<uint16_t, uint32_t>(&testEncs[1], &testEncs[0]);
testUTF<uint16_t, uint16_t>(&testEncs[1], &testEncs[1]);
testUTF<uint16_t, uint8_t> (&testEncs[1], &testEncs[2]);

fprintf(stdout, "Testing UTF-8...\n");
testUTF<uint8_t,  uint32_t>(&testEncs[2], &testEncs[0]);
testUTF<uint8_t,  uint16_t>(&testEncs[2], &testEncs[1]);
testUTF<uint8_t,  uint8_t> (&testEncs[2], &testEncs[2]);

Ответы [ 4 ]

7 голосов
/ 21 сентября 2011
template <int I> struct UType;
template <> struct UType<0> { typedef uint32_t Type; };
template <> struct UType<1> { typedef uint16_t Type; };
template <> struct UType<2> { typedef uint8_t Type; };
static const int n_types = 3;

template <int A,int B>
struct Test {
  typedef typename UType<A>::Type AType;
  typedef typename UType<B>::Type BType;
  static void test()
  {
    testUTF<AType,BType>(&testEncs[A],&testEncs[B]);
    Test<A,B+1>::test();
  }
};

template <int A>
struct Test<A,n_types> {
  static void test() { Test<A+1,0>::test(); }
};

template <>
struct Test<n_types,0> {
  static void test() { }
};

void testAll()
{
  Test<0,0>::test();
}
1 голос
/ 21 сентября 2011

Вы можете вызывать тесты рекурсивно. (Это не то, на что похожи ваши тесты, но это можно сделать так же)

template<typename Next, typename Impl>
struct Tester
{
    template<typename FwdIter>
    static void Test(FwdIter first, FwdIter last)
    {
        for(FwdIter it = first;it != last; ++it)
            Impl::TestImpl(*first, *it);
        Next::Test(first, last);
    }
};

struct EndTest
{
    template<typename FwdIter>
    static void Test(FwdIter first, FwdIter last) { }
};

template<typename Next>
struct TestA : Tester<Next, TestA<Next>>
{
    static void TestImpl(int a, int b)
    {
        std::cout << "A" << a << b <<"\n";
    }
};

template<typename Next>
struct TestB : Tester<Next, TestB<Next>>
{
    static void TestImpl(int a, int b)
    {
        std::cout << "B" << a << b <<"\n";
    }
};

int main()
{
    TestA<TestB<EndTest>> test;
    std::array<int, 3> values = {1, 2, 3};
    test.Test(values.begin(), values.end());
    return 0;
}
0 голосов
/ 21 сентября 2011

Еще один инструмент для просмотра списка типов (мне нравятся классы типов):

#include <stdint.h>
#include <typeinfo>
#include <iostream>

// typeclass

/*
 * Concept:
 *   struct typedseq_traits<T>
 *   {
 *      enum { is_empty = 0 };
 *      static SomeType head(const T &);
 *      static TailTypes tail(const T &); // typedseq_traits<TailTypes>
 *   }
 */

template<class T>
struct typedseq_traits;


template<class T, class F, int is_empty>
struct typedseq_foreach_step;

template<class T, class F>
struct typedseq_foreach_step<T,F,1>
{
    static void walk(F &func, const T &seq)
    {}
};

template<class T, class F>
struct typedseq_foreach_step<T,F,0>
{
    static void walk(F &func, const T &seq)
    {
        func(typedseq_traits<T>::head(seq));
        typedseq_foreach(func, typedseq_traits<T>::tail(seq));
    }
};


template<class T, class F>
void typedseq_foreach(F &func, const T &seq)
{
    typedseq_foreach_step<T,F,typedseq_traits<T>::is_empty>::walk(func, seq);
}

// instances

struct typelist_empty {};

template<class H, class T>
struct typelist_cons {};

template<>
struct typedseq_traits<typelist_empty>
{
    enum { is_empty = 1 };
};

template<class H, class T>
struct typedseq_traits<typelist_cons<H,T> >
{
    enum { is_empty = 0 };
    static H head(const typelist_cons<H,T> &seq) { return H(); }
    static T tail(const typelist_cons<H,T> &seq) { return T(); }
};

// usage

typedef typelist_cons<uint8_t, typelist_cons<uint16_t, typelist_cons<uint32_t, typelist_empty> > > mylist;

template<class T1>
struct func2
{
    template<class T2>
    void operator()(T2)
    {
        std::cerr << typeid(T1).name() << ", " << typeid(T2).name() << std::endl;
    }
};

struct func1
{
    template<class T1>
    void operator()(T1)
    {
        func2<T1> f;
        typedseq_foreach(f, mylist());
    }
};

int main()
{
    func1 f;
    typedseq_foreach(f, mylist());
}
0 голосов
/ 21 сентября 2011

Один из способов сделать это - написать другую программу (на вашем любимом языке) для генерации кода C ++, необходимого для этого тестирования.Вы можете встроить этот генератор кода в свою систему сборки или просто запустить его один раз и сохранить выходной код C ++.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...