SignatureInfo.h

См. документацию.
00001 /*
00002  * CntmLib - Подсчет ссылок, потоки, синхронизация, асинхронные процедуры, события
00003  * Copyright (c) 2005, Овсеевич Роман, CntmLib@mail.ru
00004  * _______________________________________________________________________________
00005  * Разрешено свободное использование, копирование, распространение, изменение
00006  * (изменение сведений об авторских правах запрещено). Запрещена продажа и
00007  * включение всей библиотеки или ее частей в другие библиотеки. В сведениях об
00008  * авторских правах на программу (или сведениях о программе, об авторах,
00009  * использованных средствах разработки и т.д.) должна быть указана информация
00010  * о библиотеке CntmLib, ее авторе и, возможно, сайте или email'е.
00011  * Библиотека поставляется "как есть", без каких-либо гарантий со стороны автора.
00012  */
00013 
00014 #ifndef CNTM_SIGNATUREINFO_H
00015 #define CNTM_SIGNATUREINFO_H
00016 #include <cstdlib>
00017 #include <boost/preprocessor/control/if.hpp>
00018 #include <boost/preprocessor/facilities/empty.hpp>
00019 #include <boost/preprocessor/repetition/enum.hpp>
00020 #include <boost/preprocessor/repetition/enum_params.hpp>
00021 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
00022 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
00023 #include <boost/preprocessor/repetition/repeat.hpp>
00024 
00025 namespace Cntm
00026 {
00027 
00028         /**
00029          * Данный модуль предоставляет средства для разбора сигнатур функций и методов: выделение типов параметров, типа возвращаемого значения, некоторые вспомогательные типы и статические методы.
00030          *
00031          * Для получения информации о сигнатуре используется шаблонная структура Cntm::SignatureInfo. В качестве параметра шаблона указывается сигнатура функции или метода, например: SignatureInfo<double (int, const string&, void*)> или SignatureInfo<double (Class1::*)(int, const string&, void*)>.
00032          *
00033          * Класс содержит статические константы:
00034          * int argsCount - кол-во аргументов;
00035          * bool isMethod - является ли сигнатура сигнатурой функции или сигнатурой метода.
00036          *
00037          * Класс содержит следующие типы (заданные через typedef):
00038          * FuncSign - сигнатура функции с заданными аргументами и возвращаемым значением (для метода и для функции);
00039          * FuncInfo - информация и сигнатуре функции (для метода и для функции);
00040          * ResType - тип результата метода или функции;
00041          * ArgType0, ... ArgTypeN - типы аргументов метода или функции (со спецификаторами const, volatile, ссылочные типы, если аргумент - ссылка);
00042          * ResultStoreType - typedef SignatureInfoResult < ResType > - специальный класс, инкапсулирующий результат метода (в т.ч. и void). Описание Cntm::SignatureInfoResult см. ниже;
00043          * StoreType0, ... ArgTypeN - типы значений аргументов метода или функции (типы, очищенные от const, volatile и ссылок, они пригодны для хранения значений аргументов или указателей на значения аргументов);
00044          * ClassType - тип класса (только для методов);
00045          * Pointer - указатель на метод или функцию с указанной сигнатурой.
00046          *
00047          * Класс содержит следующие вложенные структуры:
00048          *      template <typename ClassForMethodT> struct Method содержит тип Pointer, который является указателем на метод класса ClassForMethodT с текущей сигнатурой;
00049          * struct Args { StoreType0 arg0; ... ArgTypeN argN; } - структура используется для хранения значений всех аргументов метода или функции.
00050          *
00051          * Класс содержит следующие статические методы:
00052          * Result MethodCall(ClassForMethodT* Object, typename Method<ClassForMethodT>::Pointer Method, Args* Args) - данный метод используется для вызова метода Method с текущей сигнатурой объекта Object типа ClassForMethodT. Значения аргументов, которые будут переданы методу представлены структурой Args. Метод возвращает значение не ResType (которое м.б. и void), а Result, т.е. всегда возвращает какоето значение, тип Result имеет оператор приведение к типу ResType (если этот тип не void).
00053          *
00054          * Класс Cntm::SignatureResult (представленный в Cntm::SignatureInfo как Result) позволяет унифицировать работу с возвращаемыми значениями как типа void (ничего не возвращается) так и со всеми прочими типами. Для типов не void класс содержит конструктор копирования для типа возвращаемого значения метода или функции и оператор приведения к этому типу, для void ни конструктора, ни оператора нет. Класс содержит статический флаг noVoid, который содержит true для нормальных типов и false для void.
00055          */
00056         template <typename SignatureT>
00057         struct SignatureInfo
00058         {
00059         };
00060 
00061 
00062         template <typename ArgT>
00063         struct SignatureArgInfo
00064         {
00065                 typedef ArgT StoreType;
00066         };
00067 
00068         /** @deprecated */
00069         template <typename ArgT>
00070         struct SignatureArgInfo<ArgT&>
00071         {
00072                 /** @deprecated */
00073                 typedef ArgT StoreType;
00074         };
00075 
00076         /** @deprecated */
00077         template <typename ArgT>
00078         struct SignatureArgInfo<const ArgT&>
00079         {
00080                 /** @deprecated */
00081                 typedef ArgT StoreType;
00082         };
00083 
00084         /** @deprecated */
00085         template <typename ArgT>
00086         struct SignatureArgInfo<volatile ArgT&>
00087         {
00088                 /** @deprecated */
00089                 typedef ArgT StoreType;
00090         };
00091 
00092         /** @deprecated */
00093         template <typename ArgT>
00094         struct SignatureArgInfo<const volatile ArgT&>
00095         {
00096                 /** @deprecated */
00097                 typedef ArgT StoreType;
00098         };
00099 
00100 
00101         template <typename ResT>
00102         struct SignatureResult
00103         {
00104                 static const bool noVoid = true;
00105 
00106                 ResT res;
00107 
00108                 SignatureResult(const ResT& Src): res(Src) {}
00109 
00110                 operator ResT& () { return res; }
00111         };
00112 
00113         template <>
00114         struct SignatureResult<void>
00115         {
00116                 static const bool noVoid = false;
00117         };
00118 
00119 
00120 #define CNTM_SIGNATURES_MAX_ARGS 17
00121 
00122 #define CNTM_SIGNATURES_EMPTY
00123 
00124 // Макрос для определения типов ArgTypeN и StoreTypeN для одного параметра.
00125 #define CNTM_SIGNATURES_COMMON_INFO_ARG(z, n, _) \
00126                 typedef ArgT##n ArgType##n; \
00127                 typedef typename SignatureArgInfo < ArgT##n > ::StoreType StoreType##n;
00128 
00129 // Макрос для определения одного поля в структуре хранения аргументов Args.
00130 #define CNTM_SIGNATURES_COMMON_INFO_ARGS_ARG(z, n, _) \
00131                 StoreType##n arg##n;
00132 
00133 // Макрос для инициализации одного поля в конструкторе структуры хранения аргументов Args.
00134 #define CNTM_SIGNATURES_COMMON_INFO_ARGS_CTOR_ARG(z, n, _) \
00135                 arg##n(Arg##n)
00136 
00137 #define CNTM_SIGNATURES_COMMON_INFO_ARGS_CTOR_TEMPL0(z, n)
00138 
00139 #define CNTM_SIGNATURES_COMMON_INFO_ARGS_CTOR_TEMPL(z, n) \
00140                 BOOST_PP_IF(n, template <, CNTM_SIGNATURES_EMPTY) \
00141                 BOOST_PP_ENUM_PARAMS_Z(z, n, typename SrcArgT) \
00142                 BOOST_PP_IF(n, >, CNTM_SIGNATURES_EMPTY)
00143 
00144 // Макрос для определения общей информации для функций и методов о сигнатуре.
00145 #define CNTM_SIGNATURES_COMMON_INFO(z, n, _) \
00146                 static const int argsCount = n; \
00147                 typedef ResT (FuncSign)(BOOST_PP_ENUM_PARAMS_Z(z, n, ArgT)); \
00148                 typedef SignatureInfo < FuncSign > FuncInfo; \
00149                 typedef ResT ResType; \
00150                 typedef SignatureResult < ResT > ResultStoreType; \
00151                 BOOST_PP_REPEAT(n, CNTM_SIGNATURES_COMMON_INFO_ARG, CNTM_SIGNATURES_EMPTY) \
00152                 template < typename ClassForMethodT > \
00153                 struct Method \
00154                 { \
00155                         typedef ResT (ClassForMethodT::*Pointer)(BOOST_PP_ENUM_PARAMS_Z(z, n, ArgT)); \
00156                 }; \
00157                 struct Args \
00158                 { \
00159                         BOOST_PP_REPEAT_##z(n, CNTM_SIGNATURES_COMMON_INFO_ARGS_ARG, CNTM_SIGNATURES_EMPTY) \
00160                         CNTM_SIGNATURES_COMMON_INFO_ARGS_CTOR_TEMPL(z, n) \
00161                         Args(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, const SrcArgT, & Arg)) \
00162                         BOOST_PP_IF(n, :, CNTM_SIGNATURES_EMPTY) \
00163                         BOOST_PP_ENUM_##z(n, CNTM_SIGNATURES_COMMON_INFO_ARGS_CTOR_ARG, CNTM_SIGNATURES_EMPTY) {} \
00164                 }; \
00165         private: \
00166                 template < typename ClassForMethodT > \
00167                 static ResultStoreType MethodCallImpl(SignatureResult<void>* VoidCast, ClassForMethodT* Object, \
00168                         typename Method < ClassForMethodT > ::Pointer Method, Args* Args) \
00169                 { \
00170                         (Object->*Method)(BOOST_PP_ENUM_PARAMS_Z(z, n, Args->arg)); \
00171                         return ResultStoreType(); \
00172                 } \
00173                 template < typename MethodResT, typename ClassForMethodT > \
00174                 static ResultStoreType MethodCallImpl(SignatureResult<MethodResT>* NoVoidCast, ClassForMethodT* Object, \
00175                         typename Method < ClassForMethodT > ::Pointer Method, Args* Args) \
00176                 { \
00177                         return (Object->*Method)(BOOST_PP_ENUM_PARAMS_Z(z, n, Args->arg)); \
00178                 } \
00179         public: \
00180                 template < typename ClassForMethodT > \
00181                 static ResultStoreType MethodCall(ClassForMethodT* Object, \
00182                         typename Method < ClassForMethodT > ::Pointer Method, Args* Args) \
00183                 { \
00184                         return MethodCallImpl((SignatureResult<ResType>*)NULL, Object, Method, Args); \
00185                 } \
00186                 template < typename ClassForMethodT > \
00187                 static ResType MethodExec(ClassForMethodT* Object, \
00188                         typename Method < ClassForMethodT > ::Pointer Method, Args* Args) \
00189                 { \
00190                         return (Object->*Method)(BOOST_PP_ENUM_PARAMS_Z(z, n, Args->arg)); \
00191                 } \
00192                 static ResType FuncExec(FuncSign* Function, Args* Args) \
00193                 { \
00194                         return (*Function)(BOOST_PP_ENUM_PARAMS_Z(z, n, Args->arg)); \
00195                 }
00196 
00197 
00198 #define CNTM_SIGNATURES_FUNC_INFO(z, n, _) \
00199         template < typename ResT BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, typename ArgT) > \
00200         struct SignatureInfo < ResT (BOOST_PP_ENUM_PARAMS_Z(z, n, ArgT)) > \
00201         { \
00202                 CNTM_SIGNATURES_COMMON_INFO(z, n, CNTM_SIGNATURES_EMPTY) \
00203                 static const bool isMethod = false; \
00204                 struct ClassType {}; \
00205                 typedef FuncSign* Pointer; \
00206                 static ResType Exec(ClassType* Object, Pointer Procedure, Args* Args) \
00207                 { \
00208                         return FuncExec(Procedure, Args); \
00209                 } \
00210         };
00211 
00212 #define CNTM_SIGNATURES_PFUNC_INFO(z, n, _) \
00213         template < typename ResT BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, typename ArgT) > \
00214         struct SignatureInfo < ResT (*)(BOOST_PP_ENUM_PARAMS_Z(z, n, ArgT)) > \
00215         { \
00216                 CNTM_SIGNATURES_COMMON_INFO(z, n, CNTM_SIGNATURES_EMPTY) \
00217                 static const bool isMethod = false; \
00218                 struct ClassType {}; \
00219                 typedef FuncSign* Pointer; \
00220                 static ResType Exec(ClassType* Object, Pointer Procedure, Args* Args) \
00221                 { \
00222                         return FuncExec(Procedure, Args); \
00223                 } \
00224         };
00225 
00226 #define CNTM_SIGNATURES_METHOD_INFO(z, n, _) \
00227         template < typename ResT, typename ClassT BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, typename ArgT) > \
00228         struct SignatureInfo < ResT (ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(z, n, ArgT)) > \
00229         { \
00230                 CNTM_SIGNATURES_COMMON_INFO(z, n, CNTM_SIGNATURES_EMPTY) \
00231                 static const bool isMethod = true; \
00232                 typedef ClassT ClassType; \
00233                 typedef typename Method < ClassT > ::Pointer Pointer; \
00234                 static ResType Exec(ClassType* Object, Pointer Procedure, Args* Args) \
00235                 { \
00236                         return MethodExec(Object, Procedure, Args); \
00237                 } \
00238         };
00239 
00240         template <typename SignatureT>
00241         struct SignatureInfo;
00242 
00243         BOOST_PP_REPEAT(CNTM_SIGNATURES_MAX_ARGS, CNTM_SIGNATURES_FUNC_INFO, CNTM_SIGNATURES_EMPTY)
00244 
00245         BOOST_PP_REPEAT(CNTM_SIGNATURES_MAX_ARGS, CNTM_SIGNATURES_PFUNC_INFO, CNTM_SIGNATURES_EMPTY)
00246 
00247         BOOST_PP_REPEAT(CNTM_SIGNATURES_MAX_ARGS, CNTM_SIGNATURES_METHOD_INFO, CNTM_SIGNATURES_EMPTY)
00248 
00249 }
00250 
00251 /*
00252 Развертка макросов выглядит примерно так:
00253 template <typename ResT, typename ArgT1, typename ArgT2>
00254 struct SignatureInfo<ResT (ArgT1, ArgT2)>
00255 {
00256         static const int argsCount = 2;
00257         static const bool isMethod = false;
00258 
00259         typedef ResT ResType;
00260         typedef SignatureInfoResult<ResT> Result;
00261 
00262         typedef ArgT1 ArgType1;
00263         typedef ArgT2 ArgType2;
00264 
00265         typedef typename SignatureInfoArg < ArgT1 > ::StoreType StoreType1;
00266         typedef typename SignatureInfoArg < ArgT2 > ::StoreType StoreType2;
00267 
00268         typedef ResT (FuncSign)(ArgT1, ArgT2);
00269         typedef SignatureInfo<FuncSign> FuncInfo;
00270 
00271         template <typename ClassT>
00272         struct Method
00273         {
00274                 typedef ResT (ClassT::*Pointer)(ArgT1, ArgT2);
00275         };
00276 
00277         typedef FuncSign* Pointer;
00278 
00279         struct Args
00280         {
00281                 StoreType1 arg1;
00282                 StoreType2 arg2;
00283 
00284                 template <typename SrcArgT1, typename SrcArgT2>
00285                 Args(const SrcArgT1& Arg1, const SrcArgT2& Arg2): arg1(Arg1), arg2(Arg2) {}
00286         };
00287 
00288         template <typename MethodResT, typename ClassForMethodT>
00289         static Result MethodCallImpl(MethodResT* NoVoidCast, ClassForMethodT* Object,
00290                 typename Method<ClassForMethodT>::Pointer Method, Args* Args)
00291         {
00292                 return (Object->*Method)(Args->arg1, Args->arg2);
00293         }
00294 
00295         template <typename ClassForMethodT>
00296         static Result MethodCallImpl(void* VoidCast, ClassForMethodT* Object,
00297                 typename Method<ClassForMethodT>::Pointer Method, Args* Args)
00298         {
00299                 (Object->*Method)(Args->arg1, Args->arg2);
00300                 return Result();
00301         }
00302 
00303         template <typename ClassForMethodT>
00304         static Result MethodCall(ClassForMethodT* Object,
00305                 typename Method<ClassForMethodT>::Pointer Method, Args* Args)
00306         {
00307                 ResType* ResTypeVoidCheck;
00308                 return MethodCallImpl(ResTypeVoidCheck, Object, Method, Args);
00309         }
00310 };
00311 
00312 template <typename ResT, typename ClassT, typename ArgT1, typename ArgT2>
00313 struct SignatureInfo<ResT (ClassT::*)(ArgT1, ArgT2)>
00314 {
00315         static const int argsCount = 2;
00316 
00317         typedef ResT (FuncSign)(ArgT1, ArgT2);
00318         typedef SignatureInfo<FuncSign> FuncInfo;
00319         typedef ResT ResType;
00320         typedef SignatureInfoResult < ResT > Result;
00321         typedef ArgT1 ArgType1;
00322         typedef ArgT2 ArgType2;
00323         typedef typename SignatureInfoArg < ArgT1 > ::StoreType StoreType1;
00324         typedef typename SignatureInfoArg < ArgT2 > ::StoreType StoreType2;
00325 
00326         template <typename ClassForMethodT>
00327         struct Method
00328         {
00329                 typedef ResT (ClassForMethodT::*Pointer)(ArgT1, ArgT2);
00330         };
00331 
00332         struct Args
00333         {
00334                 StoreType1 arg1;
00335                 StoreType2 arg2;
00336 
00337                 template <typename SrcArgT1, typename SrcArgT2>
00338                 Args(const SrcArgT1& Arg1, const SrcArgT2& Arg2): arg1(Arg1), arg2(Arg2) {}
00339         };
00340 
00341         template <typename MethodResT, typename ClassForMethodT>
00342         static Result MethodCallImpl(MethodResT* NoVoidCast, ClassForMethodT* Object,
00343                 typename Method<ClassForMethodT>::Pointer Method, Args* Args)
00344         {
00345                 return (Object->*Method)(Args->arg1, Args->arg2);
00346         }
00347 
00348         template <typename ClassForMethodT>
00349         static Result MethodCallImpl(void* VoidCast, ClassForMethodT* Object,
00350                 typename Method<ClassForMethodT>::Pointer Method, Args* Args)
00351         {
00352                 (Object->*Method)(Args->arg1, Args->arg2);
00353                 return Result();
00354         }
00355 
00356         template <typename ClassForMethodT>
00357         static Result MethodCall(ClassForMethodT* Object,
00358                 typename Method<ClassForMethodT>::Pointer Method, Args* Args)
00359         {
00360                 ResType* ResTypeVoidCheck;
00361                 return MethodCallImpl(ResTypeVoidCheck, Object, Method, Args);
00362         }
00363 
00364 
00365         static const bool isMethod = true;
00366         typedef ClassT ClassType;
00367         typedef typename Method < ClassT > ::Pointer Pointer;
00368 };
00369 */
00370 
00371 #endif //CNTM_SIGNATUREINFO_H

SourceForge.net Logo
© Овсеевич Р.В. Документация по CntmLib 1.1.4 от 28 May 2008. Создано системой  doxygen 1.5.3