|
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 // Redistribution and use in source and binary forms, with or without 00011 // modification, are permitted provided that the following conditions are 00012 // met: 00013 // 00014 // 1. Redistributions of source code must retain the above copyright 00015 // notice, this list of conditions and the following disclaimer. 00016 // 00017 // 2. Redistributions in binary form must reproduce the above copyright 00018 // notice, this list of conditions and the following disclaimer in the 00019 // documentation and/or other materials provided with the distribution. 00020 // 00021 // 3. Neither the name of the Corporation nor the names of the 00022 // contributors may be used to endorse or promote products derived from 00023 // this software without specific prior written permission. 00024 // 00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00036 // 00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00038 // 00039 // *********************************************************************** 00040 // @HEADER 00041 00042 #ifndef TEUCHOS_TEST_CLASSES_HPP 00043 #define TEUCHOS_TEST_CLASSES_HPP 00044 00045 00046 #include "Teuchos_RCP.hpp" 00047 00048 00049 // Return constants from class functions 00050 const int A_g_return = 1; 00051 const int A_f_return = 2; 00052 const int B1_g_return = 3; 00053 const int B1_f_return = 4; 00054 const int B2_g_return = 5; 00055 const int B2_f_return = 6; 00056 const int C_g_return = 7; 00057 const int C_f_return = 8; 00058 const int D_g_return = 9; 00059 const int D_f_return = 10; 00060 const int E_g_return = 11; 00061 const int E_f_return = 12; 00062 00063 00064 /* 00065 00066 Polymorphic multiple inheritance example 00067 00068 ----- 00069 | A | 00070 ----- 00071 /|\ 00072 | 00073 ------------ 00074 | | 00075 ----- ------ 00076 | B1 | | B2 | 00077 ----- ------ 00078 /|\ /|\ 00079 | | 00080 ------------ 00081 | 00082 ----- 00083 | C | 00084 ----- 00085 00086 */ 00087 00088 00089 class C; 00090 00091 00092 class A { 00093 int A_g_, A_f_; 00094 public: 00095 A() : A_g_(A_g_return), A_f_(A_f_return) {} 00096 static Teuchos::RCP<A> create() { return Teuchos::rcp(new A); } 00097 virtual ~A(); // See below 00098 virtual int A_g() { return A_g_; } 00099 virtual int A_f() const { return A_f_; } 00100 int call_C_f(); 00101 private: 00102 Teuchos::RCP<C> c_; 00103 public: 00104 void set_C(const Teuchos::RCP<C> &c ) { c_ = c; } 00105 }; 00106 00107 00108 class B1 : virtual public A { 00109 int B1_g_, B1_f_; 00110 public: 00111 B1() : B1_g_(B1_g_return), B1_f_(B1_f_return) {} 00112 ~B1() { B1_g_ = -1; B1_f_ = -1; } 00113 static Teuchos::RCP<B1> create() { return Teuchos::rcp(new B1); } 00114 virtual int B1_g() { return B1_g_; } 00115 virtual int B1_f() const { return B1_f_; } 00116 }; 00117 00118 00119 class B2 : virtual public A { 00120 int B2_g_, B2_f_; 00121 public: 00122 B2() : B2_g_(B2_g_return), B2_f_(B2_f_return) {} 00123 static Teuchos::RCP<B2> create() { return Teuchos::rcp(new B2); } 00124 ~B2() { B2_g_ = -1; B2_f_ = -1; } 00125 virtual int B2_g() { return B2_g_; } 00126 virtual int B2_f() const { return B2_f_; } 00127 }; 00128 00129 00130 class C : virtual public B1, virtual public B2 00131 { 00132 int C_g_, C_f_; 00133 public: 00134 C() : C_g_(C_g_return), C_f_(C_f_return), call_A_on_delete_(false) 00135 { 00136 A_g_on_delete_ = -2; 00137 } 00138 static Teuchos::RCP<C> create() { return Teuchos::rcp(new C); } 00139 ~C() 00140 { 00141 C_g_ = -1; C_f_ = -1; 00142 if (call_A_on_delete_) { 00143 // VERY BAD THING TO DO! 00144 A_g_on_delete_ = call_A_g(); 00145 // NOTE: If a_ is a weak pointer and the underlying 'A' object has 00146 // already been deleted, then this destructor will throw an exception. 00147 // This is *never* a good thing to do in production code. However, I 00148 // am allowing this destructor to throw an exception so I can write a 00149 // unit test to detect this. 00150 } 00151 } 00152 virtual int C_g() { return C_g_; } 00153 virtual int C_f() const { return C_f_; } 00154 void call_A_on_delete(bool call_A_on_delete_in) 00155 { call_A_on_delete_ = call_A_on_delete_in; } 00156 int call_A_g() { return a_->A_g(); } 00157 static int get_A_g_on_delete() { return A_g_on_delete_; } 00158 private: 00159 Teuchos::RCP<A> a_; 00160 bool call_A_on_delete_; 00161 static int A_g_on_delete_; 00162 public: 00163 void set_A(const Teuchos::RCP<A> &a ) { a_ = a; } 00164 Teuchos::RCP<A> get_A() { return a_; } 00165 }; 00166 00167 00168 // Need to put these here if we have circular references 00169 00170 inline 00171 A::~A() { A_g_ = -1; A_f_ = -1; } 00172 00173 00174 inline 00175 int A::call_C_f() { return c_->C_f(); } 00176 00177 00178 class Get_A_f_return { 00179 const A *a_; 00180 int *a_f_return_; 00181 Get_A_f_return(); 00182 public: 00183 Get_A_f_return( const A *a, int *a_f_return ) : a_(a), a_f_return_(a_f_return) {} 00184 ~Get_A_f_return() { *a_f_return_ = a_->A_f(); } 00185 }; 00186 00187 00188 void deallocA(A* ptr); 00189 00190 00191 void deallocHandleA(A** handle); 00192 00193 00194 /* 00195 00196 Non-polymophic classes hiearchy examlpe 00197 00198 ----- 00199 | D | 00200 ----- 00201 /|\ 00202 | 00203 ----- 00204 | E | 00205 ----- 00206 00207 */ 00208 00209 00210 class D 00211 { 00212 int D_g_, D_f_; 00213 public: 00214 D() : D_g_(D_g_return), D_f_(D_f_return) {} 00215 int D_g() { return D_g_; } 00216 int D_f() const { return D_f_; } 00217 }; 00218 00219 00220 class E : public D 00221 { 00222 int E_g_, E_f_; 00223 public: 00224 E() : E_g_(E_g_return), E_f_(E_f_return) {} 00225 int E_g() { return E_g_; } 00226 int E_f() const { return E_f_; } 00227 }; 00228 00229 00230 /* 00231 00232 Typedef to pointer for undefined struct as an opaque object type without a 00233 specialization of TypeNameTraits. 00234 00235 This simulates what happens with a lot of MPI implementations. 00236 00237 */ 00238 00239 struct UndefinedType; // Forward declared but never defined! 00240 typedef UndefinedType* Opaque_handle; 00241 const Opaque_handle OPAQUE_HANDLE_NULL = 0; 00242 Opaque_handle createOpaque(); 00243 const int getOpaqueValue_return = 5; 00244 int getOpaqueValue( Opaque_handle opaque ); 00245 void destroyOpaque( Opaque_handle * opaque ); 00246 00247 00248 /* 00249 00250 Typedef to pointer for an undefiend struct as an opaque object type out a 00251 specialization of TypeNameTraits of the actually type. 00252 00253 This allows it to be stored in an RCP object itself. 00254 00255 */ 00256 00257 struct UndefinedType2; // Forward declared but never defined! 00258 typedef UndefinedType2* Opaque2_handle; 00259 const Opaque2_handle OPAQUE2_HANDLE_NULL = 0; 00260 Opaque2_handle createOpaque2(); 00261 const int getOpaque2Value_return = 8; 00262 int getOpaque2Value( Opaque2_handle opaque ); 00263 void destroyOpaque2( Opaque2_handle * opaque ); 00264 00265 00266 namespace Teuchos { 00267 00268 00269 // Here we define the traits for the underlying type itself. 00270 template<> 00271 class TypeNameTraits<UndefinedType2> { 00272 public: 00273 static std::string name() { return "UndefinedType2"; } 00274 static std::string concreteName(const UndefinedType2&) 00275 { return name(); } 00276 }; 00277 00278 00279 } // namespace Teuchos 00280 00281 00282 /* 00283 00284 Typedef to pointer for an undefiend struct as an opaque object type out a 00285 specialization of TypeNameTraits of the actually type. 00286 00287 This allows handles to the type be used with Array, ArrayRCP, and ArrayView. 00288 However, this type can *not* be used with RCP since it does not define a 00289 TypeNameTraits specialization for the underlying undefined type. 00290 00291 This simulates what can happen with MPI implementations. 00292 00293 */ 00294 00295 struct UndefinedType3; // Forward declared but never defined! 00296 typedef UndefinedType3* Opaque3_handle; 00297 const Opaque3_handle OPAQUE3_HANDLE_NULL = 0; 00298 00299 00300 namespace Teuchos { 00301 00302 // Here we only define the traits class for the handle type and we don't even 00303 // need to worry about what the underlying type is (unless we already have a 00304 // speicalization defined for it). 00305 template<> 00306 class TypeNameTraits<Opaque3_handle> { 00307 public: 00308 static std::string name() { return "Opaque3_handle"; } 00309 static std::string concreteName(Opaque3_handle) 00310 { return name(); } 00311 }; 00312 00313 00314 } // namespace Teuchos 00315 00316 00317 #endif // TEUCHOS_TEST_CLASSES_HPP
1.7.6.1