sigx++ 2.0.1
signal_traits.h
Go to the documentation of this file.
00001 #ifndef _SIGX_SIGNAL_TYPE_TRAIT_HPP_
00002 #define _SIGX_SIGNAL_TYPE_TRAIT_HPP_
00003 
00004 /*
00005  * Copyright 2005 Klaus Triendl
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Library General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Library General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Library General Public
00018  * License along with this library; if not, write to the Free 
00019  * Software Foundation, 51 Franklin Street, Fifth Floor, 
00020  * Boston, MA 02110-1301, USA.
00021  */
00022 
00023 #include <sigc++/signal_base.h>
00024 #include <glibmm/signalproxy.h>
00025 
00026 
00027 namespace sigx
00028 {
00029 
00030     namespace internal
00031     {
00032 
00033 struct derivation_helper
00034 {
00035     typedef char sm;
00036     struct middle {
00037         char memory[32];
00038     };
00039     struct big {
00040         char memory[64];
00041     };
00042 
00043     enum Type
00044     {
00045         NOBASE = sizeof(sm), 
00046         BASE1 = sizeof(middle), 
00047         BASE2 = sizeof(big)
00048     };
00049 };
00050 
00059 template<typename T_derived, typename T_base1, typename T_base2>
00060 struct is_derived_from
00061 {
00062 private:
00063 #ifndef SIGC_SELF_REFERENCE_IN_MEMBER_INITIALIZATION
00064 
00065     //Certain compilers, notably GCC 3.2, require these functions to be inside an inner class.
00066     struct internal_class
00067     {
00068         static derivation_helper::sm is_base_class_(...);
00069         static derivation_helper::middle is_base_class_(typename sigc::type_trait<T_base1>::pointer);
00070         static derivation_helper::big is_base_class_(typename sigc::type_trait<T_base2>::pointer);
00071     };
00072 
00073 public:
00074     static const int value =
00075         sizeof(internal_class::is_base_class_(reinterpret_cast<typename sigc::type_trait<T_derived>::pointer>(0)));
00076 
00077 #else //SIGC_SELF_REFERENCE_IN_MEMBER_INITIALIZATION
00078 
00079     //The AIX xlC compiler does not like these 2 functions being in the inner class.
00080     //It says "The incomplete type "test" must not be used as a qualifier.
00081     //It does not seem necessary anyway. murrayc.
00082     static derivation_helper::sm is_base_class_(...);
00083     static derivation_helper::middle is_base_class_(typename sigc::type_trait<T_base1>::pointer);
00084     static derivation_helper::big is_base_class_(typename sigc::type_trait<T_base2>::pointer);
00085 
00086 public:
00087     static const int value =
00088         sizeof(is_base_class_(reinterpret_cast<typename sigc::type_trait<T_derived>::pointer>(0)));
00089 
00090 #endif //SIGC_SELF_REFERENCE_IN_MEMBER_INITIALIZATION
00091 
00092     void avoid_gcc3_warning_(); //Not implemented. g++ 3.3.5 (but not 3.3.4, and not 3.4) warn that there are no public methods, even though there is a public variable.
00093 };
00094 
00095 
00096 enum signal_group
00097 {
00098     SIGGROUP_IRRELEVANT, 
00099     SIGGROUP_SIGC, 
00100     SIGGROUP_GLIB_PROXY
00101 };
00102 
00103 
00109 template<typename T_signal, int I_oneof = is_derived_from<T_signal, sigc::signal_base, Glib::SignalProxyNormal>::value>
00110 struct signal_type_trait
00111 {
00112     static const signal_group type = SIGGROUP_IRRELEVANT;
00113 };
00114 
00117 template<typename T_signal>
00118 struct signal_type_trait<T_signal, derivation_helper::BASE1>
00119 {
00120     static const signal_group type = SIGGROUP_SIGC;
00121 };
00122 
00125 template<typename T_signal>
00126 struct signal_type_trait<T_signal, derivation_helper::BASE2>
00127 {
00128     static const signal_group type = SIGGROUP_GLIB_PROXY;
00129 };
00130 
00131 
00132     } // namespace internal
00133 
00134 } // namespace sigx
00135 
00136 
00137 #endif // end file guard