TestClasses.hpp

Go to the documentation of this file.
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 };
00148 
00149 
00150 // Need to put these here if we have circular references
00151 
00152 inline
00153 A::~A() { A_g_ = -1; A_f_ = -1; }
00154 
00155 
00156 inline
00157 int A::call_C_f() { return c_->C_f(); }
00158 
00159 
00160 class Get_A_f_return {
00161   const A *a_;
00162   int *a_f_return_;
00163   Get_A_f_return();
00164 public:
00165   Get_A_f_return( const A *a, int *a_f_return ) : a_(a), a_f_return_(a_f_return) {}
00166   ~Get_A_f_return() { *a_f_return_ = a_->A_f(); }
00167 };
00168 
00169 
00170 void deallocA(A* ptr);
00171 
00172 
00173 void deallocHandleA(A** handle);
00174 
00175 
00176 /*
00177 
00178  Non-polymophic classes hiearchy examlpe
00179 
00180             -----
00181            |  D  |
00182             -----
00183              /|\
00184               | 
00185             -----
00186            |  E  |
00187             -----
00188 
00189 */
00190 
00191 
00192 class D 
00193 {
00194   int D_g_, D_f_;
00195 public:
00196   D() : D_g_(D_g_return), D_f_(D_f_return) {}
00197   int D_g() { return D_g_; }
00198   int D_f() const { return D_f_; }
00199 };
00200 
00201 
00202 class E : public D
00203 {
00204   int E_g_, E_f_;
00205 public:
00206   E() : E_g_(E_g_return), E_f_(E_f_return) {}
00207   int E_g() { return E_g_; }
00208   int E_f() const { return E_f_; }
00209 };
00210 
00211 
00212 /*
00213 
00214 Typedef to pointer for undefined struct as an opaque object type without a
00215 specialization of TypeNameTraits.
00216 
00217 This simulates what happens with a lot of MPI implementations.
00218 
00219 */
00220 
00221 struct UndefinedType; // Forward declared but never defined!
00222 typedef UndefinedType* Opaque_handle;
00223 const Opaque_handle OPAQUE_HANDLE_NULL = 0;
00224 Opaque_handle createOpaque();
00225 const int getOpaqueValue_return = 5;
00226 int getOpaqueValue( Opaque_handle opaque );
00227 void destroyOpaque( Opaque_handle * opaque );
00228 
00229 
00230 /*
00231 
00232 Typedef to pointer for an undefiend struct as an opaque object type out a
00233 specialization of TypeNameTraits of the actually type.
00234 
00235 This allows it to be stored in an RCP object itself.
00236 
00237 */
00238 
00239 struct UndefinedType2; // Forward declared but never defined!
00240 typedef UndefinedType2* Opaque2_handle;
00241 const Opaque2_handle OPAQUE2_HANDLE_NULL = 0;
00242 Opaque2_handle createOpaque2();
00243 const int getOpaque2Value_return = 8;
00244 int getOpaque2Value( Opaque2_handle opaque );
00245 void destroyOpaque2( Opaque2_handle * opaque );
00246 
00247 
00248 namespace Teuchos {
00249 
00250 
00251 // Here we define the traits for the underlying type itself.
00252 template<>
00253 class TypeNameTraits<UndefinedType2> {
00254 public:
00255   static std::string name() { return "UndefinedType2"; }
00256   static std::string concreteName(const UndefinedType2&)
00257     { return name(); }
00258 };
00259 
00260 
00261 } // namespace Teuchos
00262 
00263 
00264 /*
00265 
00266 Typedef to pointer for an undefiend struct as an opaque object type out a
00267 specialization of TypeNameTraits of the actually type.
00268 
00269 This allows handles to the type be used with Array, ArrayRCP, and ArrayView.
00270 However, this type can *not* be used with RCP since it does not define a
00271 TypeNameTraits specialization for the underlying undefined type.
00272 
00273 This simulates what can happen with MPI implementations.
00274 
00275 */
00276 
00277 struct UndefinedType3; // Forward declared but never defined!
00278 typedef UndefinedType3* Opaque3_handle;
00279 const Opaque3_handle OPAQUE3_HANDLE_NULL = 0;
00280 
00281 
00282 namespace Teuchos {
00283 
00284 // Here we only define the traits class for the handle type and we don't even
00285 // need to worry about what the underlying type is (unless we already have a
00286 // speicalization defined for it).
00287 template<>
00288 class TypeNameTraits<Opaque3_handle> {
00289 public:
00290   static std::string name() { return "Opaque3_handle"; }
00291   static std::string concreteName(Opaque3_handle)
00292     { return name(); }
00293 };
00294 
00295 
00296 } // namespace Teuchos
00297 
00298 
00299 #endif // TEUCHOS_TEST_CLASSES_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Tue Oct 20 10:13:59 2009 for Teuchos Package Browser (Single Doxygen Collection) by  doxygen 1.6.1