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   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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Wed Apr 13 09:57:28 2011 for Teuchos Package Browser (Single Doxygen Collection) by  doxygen 1.6.3