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   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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines