// // Copyright (c) 2000-2003 Brian McNamara and Yannis Smaragdakis // // Permission to use, copy, modify, distribute and sell this software // and its documentation for any purpose is granted without fee, // provided that the above copyright notice and this permission notice // appear in all source code copies and supporting documentation. The // software is provided "as is" without any express or implied // warranty. #ifndef FCPP_SIGNATURE_DOT_H #define FCPP_SIGNATURE_DOT_H #include "config.h" #include #ifndef FCPP_NO_USE_NAMESPACE namespace fcpp { #endif ////////////////////////////////////////////////////////////////////// // Inheritance detection // Code based on Andrei Alexandrescu's article: // http://www.cuj.com/experts/1810/alexandr.html template struct ConversionHelper { typedef char Small; struct Big { char dummy[2]; }; static Small Test( const U* ); static Big Test(...); static const T* MakeT(); }; template struct Conversion { typedef ConversionHelper H; static const int lhs = sizeof(H::Test((T*) H::MakeT())); static const int rhs = sizeof(typename H::Small); static const bool exists = (lhs==rhs); static const bool sameType = false; }; template struct Conversion { static const bool exists = true; static const bool sameType = true; }; template struct Inherits { static const bool value = Conversion::exists && !Conversion::sameType; }; ////////////////////////////////////////////////////////////////////// // Here are the classes with "nested typedefs" which just help us use // our own type system; these classes are just inherited. // // Note that although the sigs support a large number of arguments, most // of the rest of the library only supports functions of 0-3 arguments. ////////////////////////////////////////////////////////////////////// // Handy helper 'nothing' class. struct Void {}; // This set names functoid arguments and results template struct FunType { typedef R ResultType; typedef A1 Arg1Type; typedef A2 Arg2Type; typedef A3 Arg3Type; typedef A4 Arg4Type; typedef A5 Arg5Type; typedef A6 Arg6Type; }; template struct FunType { typedef R ResultType; typedef A1 Arg1Type; typedef A2 Arg2Type; typedef A3 Arg3Type; typedef A4 Arg4Type; typedef A5 Arg5Type; }; template struct FunType { typedef R ResultType; typedef A1 Arg1Type; typedef A2 Arg2Type; typedef A3 Arg3Type; typedef A4 Arg4Type; }; template struct FunType { typedef R ResultType; typedef A1 Arg1Type; typedef A2 Arg2Type; typedef A3 Arg3Type; }; template struct FunType { typedef R ResultType; typedef A1 Arg1Type; typedef A2 Arg2Type; }; template struct FunType { typedef R ResultType; typedef A1 Arg1Type; }; template struct FunType { typedef R ResultType; }; ////////////////////////////////////////////////////////////////////// // Concrete versions ////////////////////////////////////////////////////////////////////// // This set is used for monomorphic direct functoids; the type names // are inherited as-is, and also a template-Sig is defined so that // monomorphic direct functoids can mix freely with polymorphic functoids // since the latter require a template-Sig member template < class A1, class A2 = Void, class A3 = Void, class A4 = Void, class A5 = Void, class A6 = Void, class R = Void > struct CFunType : public FunType { template struct Sig : public FunType {}; }; template struct CFunType : public FunType { template struct Sig : public FunType {}; }; template struct CFunType : public FunType { template struct Sig : public FunType {}; }; template struct CFunType : public FunType { template struct Sig : public FunType {}; }; template struct CFunType : public FunType, public std::binary_function { template struct Sig : public FunType {}; }; template struct CFunType : public FunType, public std::unary_function { template struct Sig : public FunType {}; }; struct CallableWithoutArguments {}; struct WrongNumberOfSigArgs {}; template struct CFunType : public CallableWithoutArguments, public FunType { template struct Sig : public FunType {}; template struct Sig : public FunType {}; }; ////////////////////////////////////////////////////////////////////// // Icky helpers ////////////////////////////////////////////////////////////////////// // These are strictly unnecessary, but they avoid a bug in the g++ // compiler and also make some things shorter to type. // RT means "return type of T when passed argument types " template struct RT { typedef typename T::template Sig::ResultType ResultType; typedef typename T::template Sig::Arg1Type Arg1Type; typedef typename T::template Sig::Arg2Type Arg2Type; typedef typename T::template Sig::Arg3Type Arg3Type; typedef typename T::template Sig::Arg4Type Arg4Type; typedef typename T::template Sig::Arg5Type Arg5Type; typedef typename T::template Sig::Arg6Type Arg6Type; }; template struct RT { typedef typename T::template Sig::ResultType ResultType; typedef typename T::template Sig::Arg1Type Arg1Type; typedef typename T::template Sig::Arg2Type Arg2Type; typedef typename T::template Sig::Arg3Type Arg3Type; typedef typename T::template Sig::Arg4Type Arg4Type; typedef typename T::template Sig::Arg5Type Arg5Type; }; template struct RT { typedef typename T::template Sig::ResultType ResultType; typedef typename T::template Sig::Arg1Type Arg1Type; typedef typename T::template Sig::Arg2Type Arg2Type; typedef typename T::template Sig::Arg3Type Arg3Type; typedef typename T::template Sig::Arg4Type Arg4Type; }; template struct RT { typedef typename T::template Sig::ResultType ResultType; typedef typename T::template Sig::Arg1Type Arg1Type; typedef typename T::template Sig::Arg2Type Arg2Type; typedef typename T::template Sig::Arg3Type Arg3Type; }; template struct RT { typedef typename T::template Sig::ResultType ResultType; typedef typename T::template Sig::Arg1Type Arg1Type; typedef typename T::template Sig::Arg2Type Arg2Type; }; template struct RT { typedef typename T::template Sig::ResultType ResultType; typedef typename T::template Sig::Arg1Type Arg1Type; }; template struct RT { typedef typename T::template Sig<>::ResultType ResultType; }; #ifndef FCPP_NO_USE_NAMESPACE } // end namespace fcpp #endif #endif