Teuchos Package Browser (Single Doxygen Collection) Version of the Day
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 // 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   virtual ~A(); // See below
00097   virtual int A_g() { return A_g_; }
00098   virtual int A_f() const { return A_f_; }
00099   int call_C_f();
00100 private:
00101   Teuchos::RCP<C> c_;
00102 public:
00103   void set_C(const Teuchos::RCP<C> &c ) { c_ = c; }
00104 };
00105 
00106 
00107 class B1 : virtual public A {
00108   int B1_g_, B1_f_;
00109 public:
00110   B1() : B1_g_(B1_g_return), B1_f_(B1_f_return) {}
00111   ~B1() { B1_g_ = -1; B1_f_ = -1; }
00112   virtual int B1_g() { return B1_g_; }
00113   virtual int B1_f() const { return B1_f_; }
00114 };
00115 
00116 
00117 class B2 : virtual public A {
00118   int B2_g_, B2_f_;
00119 public:
00120   B2() : B2_g_(B2_g_return), B2_f_(B2_f_return) {}
00121   ~B2() { B2_g_ = -1; B2_f_ = -1; }
00122   virtual int B2_g() { return B2_g_; }
00123   virtual int B2_f() const { return B2_f_; }
00124 };
00125 
00126 
00127 class C : virtual public B1, virtual public B2
00128 {
00129   int C_g_, C_f_;
00130 public:
00131   C() : C_g_(C_g_return), C_f_(C_f_return), call_A_on_delete_(false)
00132     {
00133       A_g_on_delete_ = -2;
00134     }
00135   ~C()
00136     {
00137       C_g_ = -1; C_f_ = -1;
00138       if (call_A_on_delete_) {
00139         // VERY BAD THING TO DO!
00140         A_g_on_delete_ = call_A_g();
00141         // NOTE: If a_ is a weak pointer and the underlying 'A' object has
00142         // already been deleted, then this destructor will throw an exception.
00143         // This is *never* a good thing to do in production code.  However, I
00144         // am allowing this destructor to throw an exception so I can write a
00145         // unit test to detect this.
00146       }
00147     }
00148   virtual int C_g() { return C_g_; }
00149   virtual int C_f() const { return C_f_; }
00150   void call_A_on_delete(bool call_A_on_delete_in)
00151     { call_A_on_delete_ = call_A_on_delete_in; }
00152   int call_A_g() { return a_->A_g(); }
00153   static int get_A_g_on_delete() { return A_g_on_delete_; }
00154 private:
00155   Teuchos::RCP<A> a_;
00156   bool call_A_on_delete_;
00157   static int A_g_on_delete_;
00158 public:
00159   void set_A(const Teuchos::RCP<A> &a ) { a_ = a; }
00160   Teuchos::RCP<A> get_A() { return a_; }
00161 };
00162 
00163 
00164 // Need to put these here if we have circular references
00165 
00166 inline
00167 A::~A() { A_g_ = -1; A_f_ = -1; }
00168 
00169 
00170 inline
00171 int A::call_C_f() { return c_->C_f(); }
00172 
00173 
00174 class Get_A_f_return {
00175   const A *a_;
00176   int *a_f_return_;
00177   Get_A_f_return();
00178 public:
00179   Get_A_f_return( const A *a, int *a_f_return ) : a_(a), a_f_return_(a_f_return) {}
00180   ~Get_A_f_return() { *a_f_return_ = a_->A_f(); }
00181 };
00182 
00183 
00184 void deallocA(A* ptr);
00185 
00186 
00187 void deallocHandleA(A** handle);
00188 
00189 
00190 /*
00191 
00192  Non-polymophic classes hiearchy examlpe
00193 
00194             -----
00195            |  D  |
00196             -----
00197              /|\
00198               | 
00199             -----
00200            |  E  |
00201             -----
00202 
00203 */
00204 
00205 
00206 class D 
00207 {
00208   int D_g_, D_f_;
00209 public:
00210   D() : D_g_(D_g_return), D_f_(D_f_return) {}
00211   int D_g() { return D_g_; }
00212   int D_f() const { return D_f_; }
00213 };
00214 
00215 
00216 class E : public D
00217 {
00218   int E_g_, E_f_;
00219 public:
00220   E() : E_g_(E_g_return), E_f_(E_f_return) {}
00221   int E_g() { return E_g_; }
00222   int E_f() const { return E_f_; }
00223 };
00224 
00225 
00226 /*
00227 
00228 Typedef to pointer for undefined struct as an opaque object type without a
00229 specialization of TypeNameTraits.
00230 
00231 This simulates what happens with a lot of MPI implementations.
00232 
00233 */
00234 
00235 struct UndefinedType; // Forward declared but never defined!
00236 typedef UndefinedType* Opaque_handle;
00237 const Opaque_handle OPAQUE_HANDLE_NULL = 0;
00238 Opaque_handle createOpaque();
00239 const int getOpaqueValue_return = 5;
00240 int getOpaqueValue( Opaque_handle opaque );
00241 void destroyOpaque( Opaque_handle * opaque );
00242 
00243 
00244 /*
00245 
00246 Typedef to pointer for an undefiend struct as an opaque object type out a
00247 specialization of TypeNameTraits of the actually type.
00248 
00249 This allows it to be stored in an RCP object itself.
00250 
00251 */
00252 
00253 struct UndefinedType2; // Forward declared but never defined!
00254 typedef UndefinedType2* Opaque2_handle;
00255 const Opaque2_handle OPAQUE2_HANDLE_NULL = 0;
00256 Opaque2_handle createOpaque2();
00257 const int getOpaque2Value_return = 8;
00258 int getOpaque2Value( Opaque2_handle opaque );
00259 void destroyOpaque2( Opaque2_handle * opaque );
00260 
00261 
00262 namespace Teuchos {
00263 
00264 
00265 // Here we define the traits for the underlying type itself.
00266 template<>
00267 class TypeNameTraits<UndefinedType2> {
00268 public:
00269   static std::string name() { return "UndefinedType2"; }
00270   static std::string concreteName(const UndefinedType2&)
00271     { return name(); }
00272 };
00273 
00274 
00275 } // namespace Teuchos
00276 
00277 
00278 /*
00279 
00280 Typedef to pointer for an undefiend struct as an opaque object type out a
00281 specialization of TypeNameTraits of the actually type.
00282 
00283 This allows handles to the type be used with Array, ArrayRCP, and ArrayView.
00284 However, this type can *not* be used with RCP since it does not define a
00285 TypeNameTraits specialization for the underlying undefined type.
00286 
00287 This simulates what can happen with MPI implementations.
00288 
00289 */
00290 
00291 struct UndefinedType3; // Forward declared but never defined!
00292 typedef UndefinedType3* Opaque3_handle;
00293 const Opaque3_handle OPAQUE3_HANDLE_NULL = 0;
00294 
00295 
00296 namespace Teuchos {
00297 
00298 // Here we only define the traits class for the handle type and we don't even
00299 // need to worry about what the underlying type is (unless we already have a
00300 // speicalization defined for it).
00301 template<>
00302 class TypeNameTraits<Opaque3_handle> {
00303 public:
00304   static std::string name() { return "Opaque3_handle"; }
00305   static std::string concreteName(Opaque3_handle)
00306     { return name(); }
00307 };
00308 
00309 
00310 } // namespace Teuchos
00311 
00312 
00313 #endif // TEUCHOS_TEST_CLASSES_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines