這個(gè)設(shè)計(jì)主要是拿來保證跨組件的時(shí)候能盡可能的保護(hù)型別安全.
我今天晚上早些時(shí)候也往SoftArt里面提交了一個(gè)type to id的實(shí)現(xiàn),使用宏和特化機(jī)制
但是這個(gè)版本的一個(gè)很大的問題就在于用起來不是很方便,每注冊一個(gè)類需要2行代碼,而且都是
#define PARAM float
#include REGTYPE()
這樣的非常規(guī)的宏用法.
但是由于它是分類實(shí)現(xiàn)的,所以可以在里面補(bǔ)充一些額外的功能,比如自動(dòng)的具名常量的生成.
所以晚上回來的時(shí)候又用boost的mpl寫了一個(gè)原形,基本上是純模板的.注冊類只需要一行,但是宏實(shí)現(xiàn)版本中一些半自動(dòng)化的特點(diǎn)也損失的差不多了.
回頭還是要考慮用preprocessor結(jié)合MPL,看看能不能做到兩個(gè)特點(diǎn)兼?zhèn)?
mingw + gcc 4.2.1下通過
#include <iostream>
#include <boost/smart_ptr.hpp>

#include <boost/mpl/vector.hpp>
#include <boost/mpl/find.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/less.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/less_equal.hpp>

#include <boost/type_traits/is_same.hpp>

using namespace std;


struct empty
{};

#define BEGIN_REGISTER_TYPE() typedef boost::mpl::vector<empty
#define REGISTER_TYPE(type) ,type
#define END_REGISTER_TYPE() > typelst;

namespace shader_constant


{
BEGIN_REGISTER_TYPE()
REGISTER_TYPE(int)
REGISTER_TYPE(float)
REGISTER_TYPE(bool)
END_REGISTER_TYPE();

static const int size_of_typelst = boost::mpl::size<typelst>::value;
typedef boost::mpl::int_<size_of_typelst> size_of_typelst_t;

template<class T>

struct type2id
{
typedef typename boost::mpl::find<typelst, T>::type iter;
static const int id =
boost::mpl::if_<
boost::is_same<boost::mpl::end<typelst>::type, iter>,
boost::mpl::int_<0>,
typename iter::pos
>::type::value;
};

template<int id>

struct id2type
{
typedef boost::mpl::int_<id> int_id;
typedef boost::mpl::int_<0> int_0;

//type = (0 < id && id <= size) ? typelst[id] : empty;
typedef typename boost::mpl::if_<
boost::mpl::and_<
boost::mpl::less<int_0, int_id >,
boost::mpl::less_equal<int_id, boost::mpl::size<typelst>::type >
>,
typename boost::mpl::at<typelst, int_id>::type,
empty
>::type type;
};
}

using namespace shader_constant;

typedef void (*Assignments)(void* p1, void* p2);

template<class T>
void AssignImpl(void* p1, void* p2)


{
cout << typeid(T).name() << endl;
*(T*)p1 = *(T*)p2;
}

template <> void AssignImpl<empty>(void* p1, void* p2)


{
cout << "error type!" << endl;
}

Assignments assigns[size_of_typelst+1];

template <int i>
struct assigns_initializer


{
assigns_initializer<i-1> m;

assigns_initializer()
{
assigns[i] = &AssignImpl<typename id2type<i>::type >;
}
};

template <>
struct assigns_initializer<-1>


{

assigns_initializer()
{
}
};

static assigns_initializer<size_of_typelst> ai;

typedef double T;
int main()


{
T i1(T(0));
T i2(T(10));
assigns[type2id<T>::id](&i1, &i2);
cout << i1;
system("pause");
return 0;
}
