Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE) 00002 // 00003 // This file is part of Olena. 00004 // 00005 // Olena is free software: you can redistribute it and/or modify it under 00006 // the terms of the GNU General Public License as published by the Free 00007 // Software Foundation, version 2 of the License. 00008 // 00009 // Olena is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00016 // 00017 // As a special exception, you may use this file as part of a free 00018 // software project without restriction. Specifically, if other files 00019 // instantiate templates or use macros or inline functions from this 00020 // file, or you compile this file and link it with other files to produce 00021 // an executable, this file does not by itself cause the resulting 00022 // executable to be covered by the GNU General Public License. This 00023 // exception does not however invalidate any other reasons why the 00024 // executable file might be covered by the GNU General Public License. 00025 00026 #ifndef MLN_CORE_INTERNAL_EXACT_HH 00027 # define MLN_CORE_INTERNAL_EXACT_HH 00028 00032 00033 00034 00036 namespace mln 00037 { 00038 00039 template <typename T> 00040 struct Object; 00041 00042 } // End of namespace mln 00043 00044 00045 namespace mln 00046 { 00047 00048 namespace internal 00049 { 00050 00051 typedef char yes_; 00052 struct no_ { char dummy[2]; }; 00053 00054 template <typename T> 00055 struct make_ 00056 { 00057 static T* ptr(); 00058 }; 00059 00060 template <unsigned id, typename T> 00061 struct exact_ret_; 00062 00063 template <typename T> 00064 struct exact_ret_< 1, T > 00065 { 00066 typedef typename T::exact_t ret; 00067 }; 00068 00069 template <typename T> 00070 struct exact_ret_< 2, T > 00071 { 00072 typedef T ret; 00073 }; 00074 00075 template <typename E> 00076 yes_ exact_selector_(Object<E>*); 00077 00078 no_ exact_selector_(void*); 00079 00080 template <typename E, typename T> 00081 E* exact_run_(Object<E>* t, T*); 00082 00083 template <typename T> 00084 T* exact_run_(void*, T* t); 00085 00086 template <typename T> 00087 struct exact_ 00088 { 00089 enum { id = sizeof(exact_selector_(make_<T>::ptr())) }; 00090 typedef exact_ret_<id, T> helper; 00091 typedef typename helper::ret ret; 00092 static ret* run(T* t) 00093 { 00094 return exact_run_(t, t); 00095 } 00096 }; 00097 00098 template <typename T> 00099 struct exact_<const T> 00100 { 00101 enum { id = sizeof(exact_selector_(make_<T>::ptr())) }; 00102 typedef exact_ret_<id, T> helper; 00103 typedef const typename helper::ret ret; 00104 static ret* run(const T* t) 00105 { 00106 return exact_run_((T*)t, (T*)t); 00107 } 00108 }; 00109 00110 00111 # ifndef MLN_INCLUDE_ONLY 00112 00113 template <typename T> 00114 inline 00115 T* 00116 make_<T>::ptr() // This piece of code is defined to prevent an ICE from g++-2.95. 00117 { 00118 T* tmp; 00119 return tmp; 00120 } 00121 00122 template <typename E, typename T> 00123 inline 00124 E* exact_run_(Object<E>* t, T*) 00125 { 00126 return (E*)(void*)t; 00127 } 00128 00129 template <typename T> 00130 inline 00131 T* exact_run_(void*, T* t) 00132 { 00133 return t; 00134 } 00135 00136 # endif // ! MLN_INCLUDE_ONLY 00137 00138 } // end of namespace mln::internal 00139 00140 } // end of namespace mln 00141 00142 # include <mln/core/concept/object.hh> 00143 00144 #endif // ! MLN_CORE_INTERNAL_EXACT_HH