00001 // Copyright (C) 2007, 2008, 2009 EPITA Research and Development 00002 // Laboratory (LRDE) 00003 // 00004 // This file is part of Olena. 00005 // 00006 // Olena is free software: you can redistribute it and/or modify it under 00007 // the terms of the GNU General Public License as published by the Free 00008 // Software Foundation, version 2 of the License. 00009 // 00010 // Olena is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00017 // 00018 // As a special exception, you may use this file as part of a free 00019 // software project without restriction. Specifically, if other files 00020 // instantiate templates or use macros or inline functions from this 00021 // file, or you compile this file and link it with other files to produce 00022 // an executable, this file does not by itself cause the resulting 00023 // executable to be covered by the GNU General Public License. This 00024 // exception does not however invalidate any other reasons why the 00025 // executable file might be covered by the GNU General Public License. 00026 00027 #include <typeinfo> 00028 #include <mln/core/routine/exact.hh> 00029 00030 00031 00032 struct test : mln::Object< test > 00033 { 00034 }; 00035 00036 00037 namespace mln 00038 { 00039 00040 template <typename E> 00041 struct Base : Object<E> 00042 { 00043 void m() 00044 { 00045 int** i = exact(this)->m_impl(); 00046 (void) i; 00047 } 00048 void m() const 00049 { 00050 int* i = exact(this)->m_impl(); 00051 (void) i; 00052 } 00053 }; 00054 00055 struct concrete : Base< concrete > 00056 { 00057 int** m_impl() { return 0; } 00058 int* m_impl() const { return 0; } 00059 }; 00060 00061 } 00062 00063 00064 int main() 00065 { 00066 using namespace mln; 00067 00068 { 00069 00070 concrete c; 00071 Base<concrete>& b = c; 00072 b.m(); 00073 const Base<concrete>& bb = c; 00074 bb.m(); 00075 00076 } 00077 00078 00079 // ----------------------------------- 00080 00081 // test t; 00082 // Object<test>& t_ = t; 00083 // mln_assertion(typeid(exact(t_)).name() == typeid(exact(t)).name()); 00084 00085 // { 00086 // int i; 00087 // exact(i); // `int' from `float' 00088 // exact(&i); // `int *' from `const double' 00089 // } 00090 // { 00091 // const int j = 0; 00092 // exact(j); // `int' from `const double' 00093 // exact(&j); // `const int *' from `const double 00094 // } 00095 00096 // { 00097 // int i; 00098 // int& j = i; 00099 // exact(j); // `int' from `float' 00100 // exact(&j); // `int *' from `const double' 00101 // } 00102 // { 00103 // int i; 00104 // const int& j = i; 00105 // exact(j); // `int' from `const double' 00106 // exact(&j); // `const int *' from `const double' 00107 // } 00108 00109 // { 00110 // int* i; 00111 // exact(i); // `int *' from `float' 00112 // exact(*i); // `int' from `float' 00113 // int *const j = 0; 00114 // exact(j); // `int *' from `const double' 00115 // exact(*j); `int' from `float' 00116 // } 00117 00118 // { 00119 // const int* i; 00120 // exact(i); // `const int *' from `float' 00121 // exact(*i); // `int' from `const double' 00122 // const int *const j = 0; 00123 // exact(j); // `const int *' from `const double' 00124 // exact(*j); `int' from `const double' 00125 // } 00126 00127 00128 // ----------------------------------- 00129 00130 00131 // { 00132 // int i; 00133 // exact(&i); // `int *' from `const double' 00134 // } 00135 // { 00136 // const int j = 0; 00137 // exact(j); // `int' from `const double' 00138 // exact(&j); // `const int *' from `const double 00139 // } 00140 00141 // { 00142 // int i; 00143 // int& j = i; 00144 // exact(&j); // `int *' from `const double' 00145 // } 00146 // { 00147 // int i; 00148 // const int& j = i; 00149 // exact(j); // `int' from `const double' 00150 // exact(&j); // `const int *' from `const double' 00151 // } 00152 00153 // { 00154 // int *const j = 0; 00155 // exact(j); // `int *' from `const double' 00156 // } 00157 00158 // { 00159 // const int* i; 00160 // exact(*i); // `int' from `const double' 00161 // const int *const j = 0; 00162 // exact(j); // `const int *' from `const double' 00163 // exact(*j); // `int' from `const double' 00164 // } 00165 00166 00167 // ----------------------------------- 00168 00169 00170 // { 00171 // int* i; 00172 // exact(i); 00173 // } 00174 00175 // { 00176 // int i; 00177 // exact(i); // `int' from `float' 00178 // } 00179 00180 // { 00181 // int i; 00182 // int& j = i; 00183 // exact(j); // `int' from `float' 00184 // } 00185 00186 // { 00187 // int* i; 00188 // exact(i); // `int *' from `float' 00189 // exact(*i); // `int' from `float' 00190 // int *const j = 0; 00191 // exact(*j); // `int' from `float' 00192 // } 00193 00194 // { 00195 // const int* i; 00196 // exact(i); // `const int *' from `float' 00197 // } 00198 00199 }