|
Teuchos Package Browser (Single Doxygen Collection) Version of the Day
|
00001 // @HEADER 00002 // *********************************************************************** 00003 // 00004 // Teuchos: Common Tools Package 00005 // Copyright (2004) Sandia Corporation 00006 // 00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00008 // license for use of this work by or on behalf of the U.S. Government. 00009 // 00010 // This library is free software; you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as 00012 // published by the Free Software Foundation; either version 2.1 of the 00013 // License, or (at your option) any later version. 00014 // 00015 // This library is distributed in the hope that it will be useful, but 00016 // WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 // Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public 00021 // License along with this library; if not, write to the Free Software 00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00023 // USA 00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00025 // 00026 // *********************************************************************** 00027 // @HEADER 00028 00029 #ifndef TEUCHOS_TEST_CLASSES_HPP 00030 #define TEUCHOS_TEST_CLASSES_HPP 00031 00032 00033 #include "Teuchos_RCP.hpp" 00034 00035 00036 // Return constants from class functions 00037 const int A_g_return = 1; 00038 const int A_f_return = 2; 00039 const int B1_g_return = 3; 00040 const int B1_f_return = 4; 00041 const int B2_g_return = 5; 00042 const int B2_f_return = 6; 00043 const int C_g_return = 7; 00044 const int C_f_return = 8; 00045 const int D_g_return = 9; 00046 const int D_f_return = 10; 00047 const int E_g_return = 11; 00048 const int E_f_return = 12; 00049 00050 00051 /* 00052 00053 Polymorphic multiple inheritance example 00054 00055 ----- 00056 | A | 00057 ----- 00058 /|\ 00059 | 00060 ------------ 00061 | | 00062 ----- ------ 00063 | B1 | | B2 | 00064 ----- ------ 00065 /|\ /|\ 00066 | | 00067 ------------ 00068 | 00069 ----- 00070 | C | 00071 ----- 00072 00073 */ 00074 00075 00076 class C; 00077 00078 00079 class A { 00080 int A_g_, A_f_; 00081 public: 00082 A() : A_g_(A_g_return), A_f_(A_f_return) {} 00083 virtual ~A(); // See below 00084 virtual int A_g() { return A_g_; } 00085 virtual int A_f() const { return A_f_; } 00086 int call_C_f(); 00087 private: 00088 Teuchos::RCP<C> c_; 00089 public: 00090 void set_C(const Teuchos::RCP<C> &c ) { c_ = c; } 00091 }; 00092 00093 00094 class B1 : virtual public A { 00095 int B1_g_, B1_f_; 00096 public: 00097 B1() : B1_g_(B1_g_return), B1_f_(B1_f_return) {} 00098 ~B1() { B1_g_ = -1; B1_f_ = -1; } 00099 virtual int B1_g() { return B1_g_; } 00100 virtual int B1_f() const { return B1_f_; } 00101 }; 00102 00103 00104 class B2 : virtual public A { 00105 int B2_g_, B2_f_; 00106 public: 00107 B2() : B2_g_(B2_g_return), B2_f_(B2_f_return) {} 00108 ~B2() { B2_g_ = -1; B2_f_ = -1; } 00109 virtual int B2_g() { return B2_g_; } 00110 virtual int B2_f() const { return B2_f_; } 00111 }; 00112 00113 00114 class C : virtual public B1, virtual public B2 00115 { 00116 int C_g_, C_f_; 00117 public: 00118 C() : C_g_(C_g_return), C_f_(C_f_return), call_A_on_delete_(false) 00119 { 00120 A_g_on_delete_ = -2; 00121 } 00122 ~C() 00123 { 00124 C_g_ = -1; C_f_ = -1; 00125 if (call_A_on_delete_) { 00126 // VERY BAD THING TO DO! 00127 A_g_on_delete_ = call_A_g(); 00128 // NOTE: If a_ is a weak pointer and the underlying 'A' object has 00129 // already been deleted, then this destructor will throw an exception. 00130 // This is *never* a good thing to do in production code. However, I 00131 // am allowing this destructor to throw an exception so I can write a 00132 // unit test to detect this. 00133 } 00134 } 00135 virtual int C_g() { return C_g_; } 00136 virtual int C_f() const { return C_f_; } 00137 void call_A_on_delete(bool call_A_on_delete_in) 00138 { call_A_on_delete_ = call_A_on_delete_in; } 00139 int call_A_g() { return a_->A_g(); } 00140 static int get_A_g_on_delete() { return A_g_on_delete_; } 00141 private: 00142 Teuchos::RCP<A> a_; 00143 bool call_A_on_delete_; 00144 static int A_g_on_delete_; 00145 public: 00146 void set_A(const Teuchos::RCP<A> &a ) { a_ = a; } 00147 Teuchos::RCP<A> get_A() { return a_; } 00148 }; 00149 00150 00151 // Need to put these here if we have circular references 00152 00153 inline 00154 A::~A() { A_g_ = -1; A_f_ = -1; } 00155 00156 00157 inline 00158 int A::call_C_f() { return c_->C_f(); } 00159 00160 00161 class Get_A_f_return { 00162 const A *a_; 00163 int *a_f_return_; 00164 Get_A_f_return(); 00165 public: 00166 Get_A_f_return( const A *a, int *a_f_return ) : a_(a), a_f_return_(a_f_return) {} 00167 ~Get_A_f_return() { *a_f_return_ = a_->A_f(); } 00168 }; 00169 00170 00171 void deallocA(A* ptr); 00172 00173 00174 void deallocHandleA(A** handle); 00175 00176 00177 /* 00178 00179 Non-polymophic classes hiearchy examlpe 00180 00181 ----- 00182 | D | 00183 ----- 00184 /|\ 00185 | 00186 ----- 00187 | E | 00188 ----- 00189 00190 */ 00191 00192 00193 class D 00194 { 00195 int D_g_, D_f_; 00196 public: 00197 D() : D_g_(D_g_return), D_f_(D_f_return) {} 00198 int D_g() { return D_g_; } 00199 int D_f() const { return D_f_; } 00200 }; 00201 00202 00203 class E : public D 00204 { 00205 int E_g_, E_f_; 00206 public: 00207 E() : E_g_(E_g_return), E_f_(E_f_return) {} 00208 int E_g() { return E_g_; } 00209 int E_f() const { return E_f_; } 00210 }; 00211 00212 00213 /* 00214 00215 Typedef to pointer for undefined struct as an opaque object type without a 00216 specialization of TypeNameTraits. 00217 00218 This simulates what happens with a lot of MPI implementations. 00219 00220 */ 00221 00222 struct UndefinedType; // Forward declared but never defined! 00223 typedef UndefinedType* Opaque_handle; 00224 const Opaque_handle OPAQUE_HANDLE_NULL = 0; 00225 Opaque_handle createOpaque(); 00226 const int getOpaqueValue_return = 5; 00227 int getOpaqueValue( Opaque_handle opaque ); 00228 void destroyOpaque( Opaque_handle * opaque ); 00229 00230 00231 /* 00232 00233 Typedef to pointer for an undefiend struct as an opaque object type out a 00234 specialization of TypeNameTraits of the actually type. 00235 00236 This allows it to be stored in an RCP object itself. 00237 00238 */ 00239 00240 struct UndefinedType2; // Forward declared but never defined! 00241 typedef UndefinedType2* Opaque2_handle; 00242 const Opaque2_handle OPAQUE2_HANDLE_NULL = 0; 00243 Opaque2_handle createOpaque2(); 00244 const int getOpaque2Value_return = 8; 00245 int getOpaque2Value( Opaque2_handle opaque ); 00246 void destroyOpaque2( Opaque2_handle * opaque ); 00247 00248 00249 namespace Teuchos { 00250 00251 00252 // Here we define the traits for the underlying type itself. 00253 template<> 00254 class TypeNameTraits<UndefinedType2> { 00255 public: 00256 static std::string name() { return "UndefinedType2"; } 00257 static std::string concreteName(const UndefinedType2&) 00258 { return name(); } 00259 }; 00260 00261 00262 } // namespace Teuchos 00263 00264 00265 /* 00266 00267 Typedef to pointer for an undefiend struct as an opaque object type out a 00268 specialization of TypeNameTraits of the actually type. 00269 00270 This allows handles to the type be used with Array, ArrayRCP, and ArrayView. 00271 However, this type can *not* be used with RCP since it does not define a 00272 TypeNameTraits specialization for the underlying undefined type. 00273 00274 This simulates what can happen with MPI implementations. 00275 00276 */ 00277 00278 struct UndefinedType3; // Forward declared but never defined! 00279 typedef UndefinedType3* Opaque3_handle; 00280 const Opaque3_handle OPAQUE3_HANDLE_NULL = 0; 00281 00282 00283 namespace Teuchos { 00284 00285 // Here we only define the traits class for the handle type and we don't even 00286 // need to worry about what the underlying type is (unless we already have a 00287 // speicalization defined for it). 00288 template<> 00289 class TypeNameTraits<Opaque3_handle> { 00290 public: 00291 static std::string name() { return "Opaque3_handle"; } 00292 static std::string concreteName(Opaque3_handle) 00293 { return name(); } 00294 }; 00295 00296 00297 } // namespace Teuchos 00298 00299 00300 #endif // TEUCHOS_TEST_CLASSES_HPP
1.7.4