PlayaHandle.hpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                 Playa: Programmable Linear Algebra
00005 //                 Copyright 2012 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
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 Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
00041 
00042 #ifndef PLAYA_HANDLE_HPP
00043 #define PLAYA_HANDLE_HPP
00044 
00045 #include "PlayaDefs.hpp"
00046 #include "PlayaOut.hpp"
00047 #include "PlayaPrintable.hpp"
00048 #include "Teuchos_Describable.hpp"
00049 #include "PlayaHandleable.hpp"
00050 #include "PlayaExceptions.hpp"
00051 #include "PlayaObjectWithVerbosity.hpp"
00052 #include "Teuchos_RefCountPtr.hpp"
00053 #include "Teuchos_TypeNameTraits.hpp"
00054 
00055 
00056  /** \def This helper macro defines boilerplate constructors for classes deriving
00057   * from Handle.
00058   *
00059   * If class MyHandle is a handle to a type MyType, simply 
00060   * put
00061   * \code
00062   * HANDLE_CTORS(MyHandle, MyType);
00063   * \endcode
00064   * in the class declaration of MyHandle and the macro will create 
00065   * an empty ctor, a ctor from a smart ptr, and a ctor from a raw pointer. 
00066   * The macro will also create appropriate doxygen for the handle ctors */
00067 #define HANDLE_CTORS(handle, contents) \
00068   /** Empty ctor */ \
00069 handle() : Playa::Handle<contents >() {;} \
00070   /** Construct a #handle with a raw pointer to a #contents */ \
00071   handle(Playa::Handleable<contents >* rawPtr) : Playa::Handle<contents >(rawPtr) {;} \
00072   /** Construct a #handle with a smart pointer to a #contents */ \
00073   handle(const Teuchos::RCP<contents >& smartPtr) : Playa::Handle<contents >(smartPtr){;}
00074 
00075 
00076 
00077 namespace Playa
00078 {
00079 using Teuchos::RCP;
00080 using Teuchos::rcp;
00081 
00082 
00083 /** This traits class is used to extract the non-const version of
00084  * a template argument. The generic case returns the template argument. */
00085 template <class X>
00086 class ConstHandleTraits
00087 {
00088 public:
00089   typedef X NonconstType;
00090 };
00091 
00092 /** Specialization of CHT to types "const X". The nonconst type can
00093  * be extracted from the template argument. This lets us figure out
00094  * type X when the handle is to a "const X" */
00095 template <class X>
00096 class ConstHandleTraits<const X>
00097 {
00098 public:
00099   typedef X NonconstType;
00100 };
00101 
00102 
00103 
00104 /**
00105  * Class Playa::Handle provides a general implementation
00106  * of the common features of reference-counted handles.
00107  */
00108 template <class PointerType>
00109 class Handle 
00110 {
00111 public:
00112   /** Empty ctor  */
00113   Handle() : ptr_() {;}
00114 
00115   /** Construct from a smart pointer */
00116   Handle(const RCP<PointerType>& _ptr) : ptr_(_ptr) {;}
00117 
00118   /** Construct from a raw pointer to a Handleable.  */
00119   Handle(Handleable<PointerType>* rawPtr) : ptr_(rawPtr->getRcp()) {;}
00120 
00121   /** Read-only access to the underlying smart pointer. */
00122   const RCP<PointerType>& ptr() const {return ptr_;}
00123 
00124   /** Read-write access to the underlying smart pointer. */
00125   RCP<PointerType>& ptr() {return ptr_;}
00126 
00127   /** 
00128    * Print to a stream. This tries to use, in order, the 
00129    * Printable, Describable, and fallback forms of output. 
00130    */
00131   void print(std::ostream& os) const ;
00132 
00133 
00134   /** 
00135    * Return a short descriptive std::string using the Describable interface.
00136    * If the contents of the handle cannot be 
00137    * downcasted or crosscasted to a Describable*, an exception
00138    * will be thrown. 
00139    */
00140   std::string description() const ;
00141 
00142   /** Write a fallback description to be used in objects that are
00143    * neither named, printable, or describable */
00144   std::string fallbackDescription() const ;
00145 
00146   /** Return the verbosity */
00147   int verb() const ;
00148 
00149   /** Set the verbosity */
00150   void setVerb(int v);
00151 
00152 private:
00153   RCP<PointerType> ptr_;
00154 };
00155 
00156 /* implementation of print() */
00157 template <class PointerType> inline 
00158 void Handle<PointerType>::print(std::ostream& os) const 
00159 {
00160   const Printable* p = dynamic_cast<const Printable*>(ptr_.get());
00161   const Describable* d = dynamic_cast<const Describable*>(ptr_.get());
00162 
00163   if (p!=0) p->print(os);
00164   else if (d!=0) os << d->description();
00165   else os << fallbackDescription();
00166 }
00167 
00168 /* implementation of description() */
00169 template <class PointerType> inline
00170 std::string Handle<PointerType>::description() const 
00171 {
00172   const Describable* d = dynamic_cast<const Describable*>(ptr_.get());
00173   TeuchosOStringStream oss;
00174 
00175   if (d!=0) oss << d->description();
00176   else oss << fallbackDescription();
00177 
00178   return oss.str();
00179 }
00180 
00181 template <class PointerType> inline
00182 std::string Handle<PointerType>::fallbackDescription() const
00183 {
00184   typedef typename ConstHandleTraits<PointerType>::NonconstType NC;
00185   TeuchosOStringStream oss;
00186 
00187   oss << "Handle[" << TypeNameTraits<NC>::name()
00188       << ", ptr=" << ptr_.get() << "]";
00189   return oss.str();
00190 }
00191 
00192 
00193 
00194 /* implementation of verb() */
00195 template <class PointerType> inline
00196 int Handle<PointerType>::verb() const 
00197 {
00198   const ObjectWithVerbosity* v 
00199     = dynamic_cast<const ObjectWithVerbosity*>(ptr_.get());
00200   if (v) return v->verb();
00201   return 0;
00202 }
00203 
00204 
00205 /* implementation of verb() */
00206 template <class PointerType> inline
00207 void Handle<PointerType>::setVerb(int verbosity) 
00208 {
00209   ObjectWithVerbosity* v 
00210     = dynamic_cast<ObjectWithVerbosity*>(ptr_.get());
00211   if (v) v->setVerb(verbosity);
00212   TEUCHOS_TEST_FOR_EXCEPTION(v==0, RuntimeError, 
00213     "attempt to set verbosity on a handle that doesn't wrap "
00214     "an ObjectWithVerbosity subtype");
00215 }
00216 
00217 template <class PointerType> inline
00218 std::ostream& operator<<(std::ostream& os, const Playa::Handle<PointerType>& h)
00219 {
00220   h.print(os);
00221   return os;
00222 }
00223 
00224 }
00225 
00226 #define STREAM_OUT(handleType) \
00227                         inline std::ostream& operator<<(std::ostream& os, const handleType& h) \
00228                         {h.print(os); return os;}
00229 
00230 
00231 
00232 #endif
00233 

Site Contact