C++ 实现IDL原码研究

// asgard_test.cpp : Defines the entry point for the console application.
//


#include <Typelist.h>
#include <static_check.h>


#include <iostream>
#include <string>
#include <vector>
using namespace std;


class NullType
{
NullType ();
};


class IParameter
{
public:
virtual void print () const = 0;
};


class IMethod
{
protected:
std::vector <IParameter*> parameters;
};


template <class T>
struct in : public IParameter
{
typedef T OriginalType;
T value;
void setValue (T v){
value = v;
}
void print () const { 
cout << typeid(*this).name() << ": " << value << endl; 
}
};


template <class T>
struct out : public IParameter
{
typedef T OriginalType;
virtual void print () const {
cout << typeid(*this).name() << endl; 
}
};


template <class T>
struct inout : public IParameter
{
typedef T OriginalType;
T value;
void setValue (T v){
value = v;
}
virtual void print () const {
cout << typeid(*this).name() << ": " << value << endl; 
}
};


template <class T>
class InOutTypeTraits
{
Loki::CompileTimeError <false> Not_Supported_Type;
};


template <class T>
struct InOutTypeTraits < in<T> >
{
enum {isin=1, isout=0};
};


template <class T>
struct InOutTypeTraits < out<T> >
{
enum {isin=0, isout=1};
};


template <class T>
struct InOutTypeTraits < inout<T> >
{
enum {isin=1, isout=1};
};


template <>
struct InOutTypeTraits < NullType >
{
enum {isin=0, isout=0};
};


template <class T, int INDEX>
struct TypeReversedIndex
{
typedef T type;
enum {value = INDEX};
};


template <int CONDITION, class _THEN, class _ELSE>
struct If
{
typedef _THEN Result;
};


template <class _THEN, class _ELSE>
struct If <0, _THEN, _ELSE>
{
typedef _ELSE Result;
};


template < class T, int T_COUNT = Loki::TL::Length <T>::value >
struct InList
{
typedef typename If <
InOutTypeTraits <typename T::Head>::isin,
typename Loki::Typelist < TypeReversedIndex <typename T::Head, T_COUNT>, typename InList <typename T::Tail>::Result >, 
typename InList <typename T::Tail>::Result
>::Result Result;
};




template <class T>
struct InList < T, 0 >
{
typedef typename Loki::TL::MakeTypelist <>::Result Result;
};


template < class T, int T_COUNT = Loki::TL::Length <T>::value >
struct OutList
{
typedef typename If <
InOutTypeTraits <typename T::Head>::isout,
typename Loki::Typelist < TypeReversedIndex <typename T::Head, T_COUNT>, typename OutList <typename T::Tail>::Result >, 
typename OutList <typename T::Tail>::Result
>::Result Result;
};




template <class T>
struct OutList < T, 0 >
{
typedef typename Loki::TL::MakeTypelist <>::Result Result;
};


template <class T, int T_COUNT = Loki::TL::Length <T>::value >
struct FuncTypeTraits
{
Loki::CompileTimeError <false> Only_Use_Partial_Specialisation_Version;
};


template <class T>
struct FuncTypeTraits <T, 0>
{
typedef void(*Result)();
};


template <class T>
struct FuncTypeTraits <T, 1>
{
typedef void(*Result)(
typename Loki::TL::TypeAt <T, 0>::Result::OriginalType);
};


template <class T>
struct FuncTypeTraits <T, 2>
{
typedef void(*Result)(
typename Loki::TL::TypeAt <T, 0>::Result::OriginalType,
typename Loki::TL::TypeAt <T, 1>::Result::OriginalType);
};


template <class T>
struct FuncTypeTraits <T, 3>
{
typedef void(*Result)(
typename Loki::TL::TypeAt <T, 0>::Result::OriginalType,
typename Loki::TL::TypeAt <T, 1>::Result::OriginalType,
typename Loki::TL::TypeAt <T, 2>::Result::OriginalType);
};


template <class T>
struct FuncTypeTraits <T, 4>
{
typedef void(*Result)(
typename Loki::TL::TypeAt <T, 0>::Result::OriginalType,
typename Loki::TL::TypeAt <T, 1>::Result::OriginalType,
typename Loki::TL::TypeAt <T, 2>::Result::OriginalType,
typename Loki::TL::TypeAt <T, 3>::Result::OriginalType);
};


template <class T>
struct FuncTypeTraits <T, 5>
{
typedef void(*Result)(
typename Loki::TL::TypeAt <T, 0>::Result::OriginalType,
typename Loki::TL::TypeAt <T, 1>::Result::OriginalType,
typename Loki::TL::TypeAt <T, 2>::Result::OriginalType,
typename Loki::TL::TypeAt <T, 3>::Result::OriginalType,
typename Loki::TL::TypeAt <T, 4>::Result::OriginalType);
};


template <class TYPES,
class IN_TYPES = typename InList <TYPES>::Result,
int IN_COUNT = Loki::TL::Length <IN_TYPES>::value
>
struct Base
{
Loki::CompileTimeError <false> Only_Use_Partial_Specialisation_Version;
};


template <class TYPES, class IN_TYPES>
struct Base <TYPES, IN_TYPES, 0> : public IMethod
{
typedef typename FuncTypeTraits <TYPES>::Result FUNC_TYPE;


enum {TYPES_COUNT = typename Loki::TL::Length<TYPES>::value};


template <class FUNC_TYPE>
void async_call (FUNC_TYPE func = 0)
{
for (size_t i = 0; i < parameters.size(); i ++)
parameters[i]->print ();
}
};


template <class TYPES, class IN_TYPES>
struct Base <TYPES, IN_TYPES, 1> : public IMethod
{
typedef typename FuncTypeTraits <TYPES>::Result FUNC_TYPE;


enum {TYPES_COUNT = typename Loki::TL::Length<TYPES>::value};


void async_call (
typename Loki::TL::TypeAt <IN_TYPES, 0>::Result::type::OriginalType v0,
FUNC_TYPE func = 0)
{
((typename Loki::TL::TypeAt <IN_TYPES, 0>::Result::type*)
parameters[TYPES_COUNT - typename Loki::TL::TypeAt <IN_TYPES, 0>::Result::value])->setValue (v0);
for (size_t i = 0; i < parameters.size(); i ++)
parameters[i]->print ();
}
};


template <class TYPES, class IN_TYPES>
struct Base <TYPES, IN_TYPES, 2> : public IMethod
{
typedef typename FuncTypeTraits <TYPES>::Result FUNC_TYPE;


enum {TYPES_COUNT = typename Loki::TL::Length<TYPES>::value};


void async_call (
typename Loki::TL::TypeAt <IN_TYPES, 0>::Result::type::OriginalType v0, 
typename Loki::TL::TypeAt <IN_TYPES, 1>::Result::type::OriginalType v1,
FUNC_TYPE func = 0)
{
((typename Loki::TL::TypeAt <IN_TYPES, 0>::Result::type*)
parameters[TYPES_COUNT - typename Loki::TL::TypeAt <IN_TYPES, 0>::Result::value])->setValue (v0);
((typename Loki::TL::TypeAt <IN_TYPES, 1>::Result::type*)
parameters[TYPES_COUNT - typename Loki::TL::TypeAt <IN_TYPES, 1>::Result::value])->setValue (v1);
for (size_t i = 0; i < parameters.size(); i ++)
parameters[i]->print ();
}
};


template <class TYPES, class IN_TYPES>
struct Base <TYPES, IN_TYPES, 3> : public IMethod
{
typedef typename FuncTypeTraits <TYPES>::Result FUNC_TYPE;
typedef IN_TYPES type;


enum {TYPES_COUNT = typename Loki::TL::Length<TYPES>::value};


void async_call (
typename Loki::TL::TypeAt <IN_TYPES, 0>::Result::type::OriginalType v0, 
typename Loki::TL::TypeAt <IN_TYPES, 1>::Result::type::OriginalType v1, 
typename Loki::TL::TypeAt <IN_TYPES, 2>::Result::type::OriginalType v2, 
FUNC_TYPE func = 0)
{
((typename Loki::TL::TypeAt <IN_TYPES, 0>::Result::type*)
parameters[TYPES_COUNT - typename Loki::TL::TypeAt <IN_TYPES, 0>::Result::value])->setValue (v0);
((typename Loki::TL::TypeAt <IN_TYPES, 1>::Result::type*)
parameters[TYPES_COUNT - typename Loki::TL::TypeAt <IN_TYPES, 1>::Result::value])->setValue (v1);
((typename Loki::TL::TypeAt <IN_TYPES, 2>::Result::type*)
parameters[TYPES_COUNT - typename Loki::TL::TypeAt <IN_TYPES, 2>::Result::value])->setValue (v2);
for (size_t i = 0; i < parameters.size(); i ++)
parameters[i]->print ();
}
};


template <class TYPES, class IN_TYPES>
struct Base <TYPES, IN_TYPES, 4> : public IMethod
{
typedef typename FuncTypeTraits <TYPES>::Result FUNC_TYPE;


enum {TYPES_COUNT = typename Loki::TL::Length<TYPES>::value};


void async_call (
typename Loki::TL::TypeAt <IN_TYPES, 0>::Result::type::OriginalType v0, 
typename Loki::TL::TypeAt <IN_TYPES, 1>::Result::type::OriginalType v1, 
typename Loki::TL::TypeAt <IN_TYPES, 2>::Result::type::OriginalType v2, 
typename Loki::TL::TypeAt <IN_TYPES, 3>::Result::type::OriginalType v3,
FUNC_TYPE func = 0)
{
((typename Loki::TL::TypeAt <IN_TYPES, 0>::Result::type*)
parameters[TYPES_COUNT - typename Loki::TL::TypeAt <IN_TYPES, 0>::Result::value])->setValue (v0);
((typename Loki::TL::TypeAt <IN_TYPES, 1>::Result::type*)
parameters[TYPES_COUNT - typename Loki::TL::TypeAt <IN_TYPES, 1>::Result::value])->setValue (v1);
((typename Loki::TL::TypeAt <IN_TYPES, 2>::Result::type*)
parameters[TYPES_COUNT - typename Loki::TL::TypeAt <IN_TYPES, 2>::Result::value])->setValue (v2);
((typename Loki::TL::TypeAt <IN_TYPES, 3>::Result::type*)
parameters[TYPES_COUNT - typename Loki::TL::TypeAt <IN_TYPES, 3>::Result::value])->setValue (v3);
for (size_t i = 0; i < parameters.size(); i ++)
parameters[i]->print ();
}
};




template <class T>
struct Method
{
Loki::CompileTimeError <false> Only_Define_With_A_Function_Type;
};


template <class Ret>
struct Method <Ret()> : public Base < typename Loki::TL::MakeTypelist< out<Ret> >::Result >
{
out<Ret> ret;
Method ()
{
parameters.push_back (&ret);
}
};


template <>
struct Method <void()> : public Base < typename Loki::TL::MakeTypelist< >::Result >
{
};


template <class Ret, class A>
struct Method <Ret(A)> : public Base < typename Loki::TL::MakeTypelist< A, out<Ret> >::Result >
{
A a;
out<Ret> ret;
Method ()
{
parameters.push_back (&a);
parameters.push_back (&ret);
}
};


template <class A>
struct Method <void(A)> : public Base < typename Loki::TL::MakeTypelist< A >::Result >
{
A a;
Method ()
{
parameters.push_back (&a);
}
};


template <class Ret, class A, class B>
struct Method <Ret(A,B)> : public Base < typename Loki::TL::MakeTypelist< A,B,out<Ret> >::Result >
{
A a;
B b;
out<Ret> ret;
Method ()
{
parameters.push_back (&a);
parameters.push_back (&b);
parameters.push_back (&ret);
}
};


template <class A, class B>
struct Method <void(A,B)> : public Base < typename Loki::TL::MakeTypelist< A,B >::Result >
{
A a;
B b;
Method ()
{
parameters.push_back (&a);
parameters.push_back (&b);
}
};


template <class Ret, class A, class B, class C>
struct Method <Ret(A,B,C)> : public Base < typename Loki::TL::MakeTypelist< A,B,C,out<Ret> >::Result >
{
A a;
B b;
C c;
out<Ret> ret;
Method ()
{
parameters.push_back (&a);
parameters.push_back (&b);
parameters.push_back (&c);
parameters.push_back (&ret);
}
};


template <class A, class B, class C>
struct Method <void(A,B,C)> : public Base < typename Loki::TL::MakeTypelist< A,B,C >::Result >
{
A a;
B b;
C c;
Method ()
{
parameters.push_back (&a);
parameters.push_back (&b);
parameters.push_back (&c);
}
};


template <class Ret, class A, class B, class C, class D>
struct Method <Ret(A,B,C,D)> : public Base < typename Loki::TL::MakeTypelist< A,B,C,D,out<Ret> >::Result >
{
A a;
B b;
C c;
D d;
out<Ret> ret;
Method ()
{
parameters.push_back (&a);
parameters.push_back (&b);
parameters.push_back (&c);
parameters.push_back (&d);
parameters.push_back (&ret);
}
};


template <class A, class B, class C, class D>
struct Method <void(A,B,C,D)> : public Base < typename Loki::TL::MakeTypelist< A,B,C,D >::Result >
{
A a;
B b;
C c;
D d;
Method ()
{
parameters.push_back (&a);
parameters.push_back (&b);
parameters.push_back (&c);
parameters.push_back (&d);
}
};


template <class Ret, class A, class B, class C, class D, class E>
struct Method <Ret(A,B,C,D,E)> : public Base < typename Loki::TL::MakeTypelist< A,B,C,D,E,out<Ret> >::Result >
{
A a;
B b;
C c;
D d;
E e;
out<Ret> ret;
Method ()
{
parameters.push_back (&a);
parameters.push_back (&b);
parameters.push_back (&c);
parameters.push_back (&d);
parameters.push_back (&e);
parameters.push_back (&ret);
}
};




template <class A, class B, class C, class D, class E>
struct Method <void(A,B,C,D,E)> : public Base < typename Loki::TL::MakeTypelist< A,B,C,D,E >::Result >
{
A a;
B b;
C c;
D d;
E e;
Method ()
{
parameters.push_back (&a);
parameters.push_back (&b);
parameters.push_back (&c);
parameters.push_back (&d);
parameters.push_back (&e);
}
};


void test_func (int v0, char v1, string v2, short v3)
{
cout << "===========================================" << endl;
cout << "test_func(" << v0 << ", " << v1 << ", " << v2 << ", " << v3 << ")" << endl;
}


void test_func1 (int v0, char v1, short v2, string v3)
{
cout << "===========================================" << endl;
cout << "test_func1(" << v0 << ", " << v1 << ", " << v2 << ", " << v3 << ")" << endl;
}


int main()
{
{
Method < void(in<int>, in<char>, inout<string>, out<short>) > m;


m.async_call(3, 'a', "test");
cout << "===========================================" << endl;
m.async_call(3, 'a', "test", test_func);
cout << "===========================================" << endl;
}


{
Method <string(in<int>, out<char>, inout<short>)> m;
m.async_call(3, 4);
cout << "===========================================" << endl;
m.async_call(3, 4, test_func1);
cout << "===========================================" << endl;
}


return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值