Fundamental Vector Reduction/Transformation Operator (RTOp) Interfaces Version of the Day
RTOpPack_Types.hpp
00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 // RTOp: Interfaces and Support Software for Vector Reduction Transformation
00005 //       Operations
00006 //                Copyright (2006) Sandia Corporation
00007 // 
00008 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00009 // license for use of this work by or on behalf of the U.S. Government.
00010 // 
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 
00039 // 
00040 // ***********************************************************************
00041 // @HEADER
00042 
00043 
00044 #ifndef RTOPPACK_TYPES_HPP
00045 #define RTOPPACK_TYPES_HPP
00046 
00047 
00048 #include "RTOp_ConfigDefs.hpp"
00049 #include "Teuchos_Array.hpp"
00050 #include "Teuchos_RCP.hpp"
00051 #include "Teuchos_ArrayRCP.hpp"
00052 #include "Teuchos_Range1D.hpp"
00053 #include "Teuchos_ScalarTraits.hpp"
00054 #include "Teuchos_TypeNameTraits.hpp"
00055 #include "Teuchos_Assert.hpp"
00056 #include "Teuchos_implicit_cast.hpp"
00057 #include "Teuchos_FancyOStream.hpp"
00058 
00059 
00060 namespace RTOpPack {
00061 
00062 
00063 //
00064 // Basic types
00065 //
00066 
00068 typedef Teuchos_Ordinal Ordinal;
00070 using Teuchos::Ptr;
00072 using Teuchos::RCP;
00074 using Teuchos::ArrayRCP;
00076 using Teuchos::ArrayView;
00078 using Teuchos::Array;
00080 using Teuchos::Range1D;
00082 using Teuchos::ScalarTraits;
00084 using Teuchos::TypeNameTraits;
00086 using Teuchos::FancyOStream;
00087 
00089 typedef Teuchos_Ordinal index_type;
00091 typedef char  char_type;
00092 
00093 
00094 //
00095 // Exceptions
00096 //
00097 
00098 
00100 class UnknownError : public std::logic_error
00101 {public: UnknownError(const std::string& what_arg) : std::logic_error(what_arg) {}};
00103 class InvalidUsage : public std::logic_error
00104 {public: InvalidUsage(const std::string& what_arg) : std::logic_error(what_arg) {}};
00106 class InvalidNumVecs : public std::logic_error
00107 {public: InvalidNumVecs(const std::string& what_arg) : std::logic_error(what_arg) {}};
00109 class InvalidNumTargVecs : public std::logic_error
00110 {public: InvalidNumTargVecs(const std::string& what_arg) : std::logic_error(what_arg) {}};
00112 class IncompatibleVecs : public std::logic_error
00113 {public: IncompatibleVecs(const std::string& what_arg) : std::logic_error(what_arg) {}};
00115 class IncompatibleReductObj : public std::logic_error
00116 {public: IncompatibleReductObj(const std::string& what_arg) : std::logic_error(what_arg) {}};
00117 
00118 
00119 //
00120 // VectorBase subviews
00121 //
00122 
00123 
00143 template<class Scalar>
00144 class ConstSubVectorView {
00145 public:
00147   ConstSubVectorView() : globalOffset_(0), subDim_(0), stride_(0) {}
00149   ConstSubVectorView(const ArrayRCP<const Scalar> &values_in)
00150     :globalOffset_(0), subDim_(0), stride_(0)
00151     { initialize(0, values_in.size(), values_in, 1); }
00153   ConstSubVectorView(Ordinal globalOffset_in, Ordinal subDim_in,
00154     const ArrayRCP<const Scalar> &values_in, ptrdiff_t stride_in)
00155     :globalOffset_(0), subDim_(0), stride_(0)
00156     { initialize(globalOffset_in, subDim_in, values_in, stride_in); }
00158   ConstSubVectorView( const ConstSubVectorView<Scalar>& sv )
00159     :globalOffset_(sv.globalOffset()), subDim_(sv.subDim()),
00160      values_(sv.values()), stride_(sv.stride()) 
00161     {}
00163   void initialize(Ordinal globalOffset_in, Ordinal subDim_in,
00164     const ArrayRCP<const Scalar> &values_in, ptrdiff_t stride_in)
00165     {
00166 #ifdef TEUCHOS_DEBUG
00167       TEUCHOS_ASSERT(globalOffset_in >= 0);
00168       if (!is_null(values_in)) {
00169         TEUCHOS_ASSERT(subDim_in >= 0);
00170         TEUCHOS_ASSERT(stride_in != 0);
00171         TEUCHOS_ASSERT(
00172           subDim_in*std::abs(Teuchos::as<int>(stride_in)) - 1 <= values_in.upperOffset());
00173         TEUCHOS_ASSERT(values_in.lowerOffset() <= 0);
00174       }
00175       else {
00176         TEUCHOS_ASSERT(subDim_in==0);
00177       }
00178 #endif
00179       globalOffset_=globalOffset_in;
00180       subDim_=subDim_in;
00181       values_=values_in;
00182       stride_=stride_in;
00183     }
00185   void uninitialize()
00186     { globalOffset_ = 0; subDim_=0; values_ = Teuchos::null; stride_ = 0; }
00188   void setGlobalOffset(Ordinal globalOffset_in)
00189     {
00190 #ifdef TEUCHOS_DEBUG
00191       TEUCHOS_ASSERT(globalOffset_in >= 0);
00192 #endif
00193       globalOffset_ = globalOffset_in;
00194     } 
00196   Ordinal globalOffset() const { return globalOffset_; }
00198   Ordinal subDim() const { return subDim_; }
00200   const ArrayRCP<const Scalar>  values() const { return values_; }
00202   ptrdiff_t stride() const { return stride_; }
00205   const Scalar& operator[](Ordinal i) const
00206     {
00207 #ifdef TEUCHOS_DEBUG
00208       TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE(i, 0, subDim_);
00209 #endif
00210       return valuesBegin()[stride_*i];
00211     }
00214   const Scalar& operator()(Ordinal i) const { return (*this)[i]; }
00215 private:
00216   Ordinal globalOffset_;
00217   Ordinal subDim_;
00218   ArrayRCP<const Scalar> values_;
00219   ptrdiff_t stride_;
00220   const typename ArrayRCP<const Scalar>::iterator valuesBegin() const
00221     {
00222       if (stride_ > 0)
00223         return values_.begin();
00224       return values_.begin() + (subDim_*std::abs(Teuchos::as<int>(stride_)) - 1);
00225     } 
00226 public:
00227 };
00228 
00229 
00246 template<class Scalar>
00247 class SubVectorView : public ConstSubVectorView<Scalar> {
00248 public:
00250   SubVectorView() {}
00252   SubVectorView(const ArrayRCP<Scalar> &values_in)
00253     :ConstSubVectorView<Scalar>(values_in)
00254     {}
00256   SubVectorView(Ordinal globalOffset_in, Ordinal subDim_in,
00257     const ArrayRCP<Scalar> &values_in, ptrdiff_t stride_in)
00258     :ConstSubVectorView<Scalar>(globalOffset_in, subDim_in, values_in, stride_in)
00259     {}
00261   SubVectorView(Ordinal subDim_in)
00262     :ConstSubVectorView<Scalar>(0, subDim_in, Teuchos::arcp<Scalar>(subDim_in), 1)
00263     {}
00265   SubVectorView(const SubVectorView<Scalar> & sv)
00266     :ConstSubVectorView<Scalar>(sv)
00267     {}
00269   void initialize(Ordinal globalOffset_in, Ordinal subDim_in,
00270     const ArrayRCP<Scalar> &values_in, ptrdiff_t stride_in)
00271     { ConstSubVectorView<Scalar>::initialize(globalOffset_in, subDim_in, values_in, stride_in); }
00273   const ArrayRCP<Scalar> values() const
00274     { return Teuchos::arcp_const_cast<Scalar>(ConstSubVectorView<Scalar>::values());  }
00277   Scalar& operator[](Ordinal i) const
00278     { return const_cast<Scalar&>(ConstSubVectorView<Scalar>::operator[](i)); }
00281   Scalar& operator()(Ordinal i) const { return (*this)[i]; }
00282 public:
00283 };
00284 
00285 
00287 template<class Scalar>
00288 void assign_entries( const Ptr<const SubVectorView<Scalar> > &msv,
00289   const ConstSubVectorView<Scalar> &sv )
00290 {
00291 #ifdef TEUCHOS_DEBUG
00292   TEUCHOS_ASSERT_EQUALITY(msv->subDim(), sv.subDim());
00293 #endif
00294   for( int i = 0; i < sv.subDim(); ++i ) {
00295     (*msv)(i) = sv(i);
00296   }
00297 }
00298 
00299 
00304 template<class Scalar>
00305 std::ostream& operator<<(std::ostream &out, const ConstSubVectorView<Scalar> &sv)
00306 {
00307   out
00308     << "{"
00309     << "globalOffset="<<sv.globalOffset()
00310     << ",subDim="<<sv.subDim()
00311     << ",values="<<sv.values()
00312     << ",stride="<<sv.stride()
00313     << "}";
00314   return out;
00315 }
00316 
00317 
00318 //
00319 // MultiVectorBase subviews
00320 //
00321 
00322 
00344 template<class Scalar>
00345 class ConstSubMultiVectorView {
00346 public:
00348   ConstSubMultiVectorView()
00349     :globalOffset_(0), subDim_(0), colOffset_(0), numSubCols_(0),
00350      leadingDim_(0)
00351     {}
00353   ConstSubMultiVectorView(
00354     Ordinal globalOffset_in, Ordinal subDim_in,
00355     Ordinal colOffset_in, Ordinal numSubCols_in,
00356     const ArrayRCP<const Scalar> &values_in, Ordinal leadingDim_in
00357     )
00358     :globalOffset_(0), subDim_(0), colOffset_(0), numSubCols_(0),
00359      leadingDim_(0)
00360     {
00361       initialize(globalOffset_in, subDim_in, colOffset_in, numSubCols_in, values_in,
00362         leadingDim_in);
00363     }
00365   ConstSubMultiVectorView( const ConstSubMultiVectorView<Scalar>& smv )
00366     :globalOffset_(smv.globalOffset()), subDim_(smv.subDim()),
00367      colOffset_(smv.colOffset()), numSubCols_(smv.numSubCols()),
00368      values_(smv.values()), leadingDim_(smv.leadingDim())
00369     {}
00371   void initialize(
00372     Ordinal globalOffset_in, Ordinal subDim_in,
00373     Ordinal colOffset_in, Ordinal numSubCols_in,
00374     const ArrayRCP<const Scalar> &values_in, Ordinal leadingDim_in
00375     )
00376     {
00377 #ifdef TEUCHOS_DEBUG
00378       TEUCHOS_ASSERT(globalOffset_in >= 0);
00379       TEUCHOS_ASSERT(colOffset_in >= 0);
00380       if (!is_null(values_in)) {
00381         TEUCHOS_ASSERT(subDim_in >= 0);
00382         TEUCHOS_ASSERT(leadingDim_in >= subDim_in);
00383         TEUCHOS_ASSERT(numSubCols_in*leadingDim_in - 1 <= values_in.upperOffset());
00384         TEUCHOS_ASSERT(values_in.lowerOffset() <= 0);
00385       }
00386       else {
00387         TEUCHOS_ASSERT(subDim_in == 0);
00388       }
00389 #endif
00390       globalOffset_=globalOffset_in;
00391       subDim_=subDim_in;
00392       colOffset_=colOffset_in;
00393       numSubCols_=numSubCols_in;
00394       values_=values_in;
00395       leadingDim_=leadingDim_in;
00396     }
00398   void uninitialize()
00399     {
00400       globalOffset_ = 0; subDim_=0; colOffset_=0, numSubCols_=0;
00401       values_=Teuchos::null; leadingDim_=0;
00402     }
00404   void setGlobalOffset(Ordinal globalOffset_in)
00405     {
00406 #ifdef TEUCHOS_DEBUG
00407       TEUCHOS_ASSERT(globalOffset_in >= 0);
00408 #endif
00409       globalOffset_ = globalOffset_in;
00410     } 
00412   Ordinal globalOffset() const { return globalOffset_; }
00414   Ordinal subDim() const { return subDim_; }
00416   Ordinal colOffset() const { return colOffset_; }
00418   Ordinal numSubCols() const { return numSubCols_; }
00420   const ArrayRCP<const Scalar> values() const { return values_; }
00422   Ordinal leadingDim() const { return leadingDim_; }
00426   const Scalar& operator()(Ordinal i, Ordinal j) const
00427     {
00428 #ifdef TEUCHOS_DEBUG
00429       TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE(i, 0, subDim_);
00430       TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE(j, 0, numSubCols_ );
00431 #endif
00432       return values_[ i + leadingDim_*j ];
00433     }
00437   ConstSubVectorView<Scalar> col( const Ordinal j ) const
00438     {
00439 #ifdef TEUCHOS_DEBUG
00440       TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE(j, 0, numSubCols_ );
00441 #endif
00442       return ConstSubVectorView<Scalar>(
00443         globalOffset(), subDim(), values().persistingView(j*leadingDim(),subDim()), 1 );
00444     }
00445 private:
00446   Ordinal globalOffset_;
00447   Ordinal subDim_;
00448   Ordinal colOffset_;
00449   Ordinal numSubCols_;
00450   ArrayRCP<const Scalar> values_;
00451   Ordinal leadingDim_;
00452 public:
00453 };
00454 
00455 
00472 template<class Scalar>
00473 class SubMultiVectorView : public ConstSubMultiVectorView<Scalar> {
00474 public:
00476   SubMultiVectorView() {}
00478   SubMultiVectorView(
00479     Ordinal numRows_in, Ordinal numCols_in
00480     )
00481     :ConstSubMultiVectorView<Scalar>(0, numRows_in, 0, numCols_in,
00482       Teuchos::arcp<Scalar>(numRows_in*numCols_in), numRows_in)
00483     {}
00485   SubMultiVectorView(
00486     Ordinal globalOffset_in, Ordinal subDim_in,
00487     Ordinal colOffset_in, Ordinal numSubCols_in,
00488     const ArrayRCP<Scalar> &values_in, Ordinal leadingDim_in
00489     )
00490     :ConstSubMultiVectorView<Scalar>(globalOffset_in, subDim_in,
00491       colOffset_in, numSubCols_in, values_in, leadingDim_in)
00492     {}
00494   SubMultiVectorView( const SubMultiVectorView<Scalar> & smv)
00495     :ConstSubMultiVectorView<Scalar>(smv)
00496     {}
00498  void initialize(
00499    Ordinal globalOffset_in, Ordinal subDim_in,
00500    Ordinal colOffset_in, Ordinal numSubCols_in,
00501    const ArrayRCP<Scalar> &values_in, Ordinal leadingDim_in
00502    )
00503    {
00504      ConstSubMultiVectorView<Scalar>::initialize(globalOffset_in,
00505        subDim_in, colOffset_in, numSubCols_in, values_in, leadingDim_in);
00506    }
00508   const ArrayRCP<Scalar> values() const
00509     {
00510       return Teuchos::arcp_const_cast<Scalar>(
00511         ConstSubMultiVectorView<Scalar>::values());
00512     }
00516   Scalar& operator()(Ordinal i, Ordinal j) const
00517     { return const_cast<Scalar&>(ConstSubMultiVectorView<Scalar>::operator()(i,j)); }
00521   SubVectorView<Scalar> col( const Ordinal j ) const
00522     {
00523 #ifdef TEUCHOS_DEBUG
00524       TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE(j, 0, this->numSubCols());
00525 #endif
00526       return SubVectorView<Scalar>(this->globalOffset(), this->subDim(),
00527         values().persistingView(j*this->leadingDim(),this->subDim()), 1);
00528     }
00529 public:
00530 };
00531 
00532 
00534 template<class Scalar>
00535 void assign_entries( const Ptr<const SubMultiVectorView<Scalar> > &msmv,
00536   const ConstSubMultiVectorView<Scalar> &smv )
00537 {
00538 #ifdef TEUCHOS_DEBUG
00539   TEUCHOS_ASSERT_EQUALITY(msmv->subDim(), smv.subDim());
00540   TEUCHOS_ASSERT_EQUALITY(msmv->numSubCols(), smv.numSubCols());
00541 #endif
00542   for( Ordinal j = 0; j < smv.numSubCols(); ++j ) {
00543     for( Ordinal i = 0; i < smv.subDim(); ++i ) {
00544       (*msmv)(i,j) = smv(i,j);
00545     }
00546   }
00547 }
00548 
00549 
00550 //
00551 // Primitive Type Traits
00552 //
00553 
00554 
00565 template <class Scalar, class ConcreteObj>
00566 class PrimitiveTypeTraits {
00567 public:
00569   typedef Scalar primitiveType;
00571   static int numPrimitiveObjs()
00572     { return Scalar::this_type_is_missing_a_specialization(); }
00574   static int numIndexObjs()
00575     { return Scalar::this_type_is_missing_a_specialization(); }
00577   static int numCharObjs()
00578     { return Scalar::this_type_is_missing_a_specialization(); }
00580   static void extractPrimitiveObjs(
00581     const Scalar &obj,
00582     const ArrayView<primitiveType> &primitiveObjs,
00583     const ArrayView<index_type> &indexObjs,
00584     const ArrayView<char> &charObjs
00585     )
00586     {
00587       Scalar::this_type_is_missing_a_specialization(obj);
00588     }
00590   static void loadPrimitiveObjs(
00591     const ArrayView<const primitiveType> &primitiveObjs,
00592     const ArrayView<const index_type> &indexObjs,
00593     const ArrayView<const char> &charObjs,
00594     const Ptr<Scalar> &obj
00595     )
00596     {
00597       *obj = Scalar::this_type_is_missing_a_specialization();
00598     }
00599 };
00600 
00601 
00602 
00606 template <class Scalar>
00607 class PrimitiveTypeTraits<Scalar, Scalar> {
00608 public:
00610   typedef Scalar primitiveType;
00612   static int numPrimitiveObjs() { return 1; }
00614   static int numIndexObjs() { return 0; }
00616   static int numCharObjs() { return 0; }
00618   static void extractPrimitiveObjs(
00619     const Scalar &obj,
00620     const ArrayView<primitiveType> &primitiveObjs,
00621     const ArrayView<index_type> &indexObjs,
00622     const ArrayView<char> &charObjs
00623     )
00624     {
00625       assertInput(primitiveObjs, indexObjs, charObjs);
00626       primitiveObjs[0] = obj;
00627     }
00629   static void loadPrimitiveObjs(
00630     const ArrayView<const primitiveType> &primitiveObjs,
00631     const ArrayView<const index_type> &indexObjs,
00632     const ArrayView<const char> &charObjs,
00633     const Ptr<Scalar> &obj
00634     )
00635     {
00636       assertInput(primitiveObjs, indexObjs, charObjs);
00637       *obj = primitiveObjs[0];
00638     }
00639 private:
00640   static void assertInput(
00641     const ArrayView<const primitiveType> &primitiveObjs,
00642     const ArrayView<const index_type> &indexObjs,
00643     const ArrayView<const char> &charObjs
00644     )
00645     {
00646 #ifdef TEUCHOS_DEBUG
00647       TEUCHOS_TEST_FOR_EXCEPT( primitiveObjs.size()!=1 || indexObjs.size()!=0
00648         || charObjs.size()!=0 );
00649 #endif
00650     }
00651 };
00652 
00653 
00655 template <class Scalar>
00656 class PrimitiveTypeTraits<Scalar, index_type> {
00657 public:
00659   typedef PrimitiveTypeTraits<Scalar,Scalar> ScalarPrimitiveTypeTraits;
00661   typedef typename ScalarPrimitiveTypeTraits::primitiveType primitiveType;
00663   static int numPrimitiveObjs() { return 0; }
00665   static int numIndexObjs() { return 1; }
00667   static int numCharObjs() { return 0; }
00669   static void extractPrimitiveObjs(
00670     const index_type &obj,
00671     const ArrayView<primitiveType> &primitiveObjs,
00672     const ArrayView<index_type> &indexObjs,
00673     const ArrayView<char> &charObjs
00674     )
00675     {
00676       assertInput(primitiveObjs, indexObjs, charObjs);
00677       indexObjs[0] = obj;
00678     }
00680   static void loadPrimitiveObjs(
00681     const ArrayView<const primitiveType> &primitiveObjs,
00682     const ArrayView<const index_type> &indexObjs,
00683     const ArrayView<const char> &charObjs,
00684     const Ptr<index_type> &obj
00685     )
00686     {
00687       assertInput(primitiveObjs, indexObjs, charObjs);
00688       *obj = indexObjs[0];
00689     }
00690 private:
00691   static void assertInput(
00692     const ArrayView<const primitiveType> &primitiveObjs,
00693     const ArrayView<const index_type> &indexObjs,
00694     const ArrayView<const char> &charObjs
00695     )
00696     {
00697 #ifdef TEUCHOS_DEBUG
00698       TEUCHOS_TEST_FOR_EXCEPT( primitiveObjs.size()!=0 || indexObjs.size()!=1
00699         || charObjs.size()!=0 );
00700 #endif
00701     }
00702 };
00703 
00704 
00705 #if defined(HAVE_COMPLEX) && defined(HAVE_TEUCHOS_COMPLEX)
00706 
00707 
00711 template <class Scalar>
00712 class PrimitiveTypeTraits<std::complex<Scalar>, std::complex<Scalar> > {
00713 public:
00715   typedef PrimitiveTypeTraits<Scalar,Scalar> ScalarPrimitiveTypeTraits;
00717   typedef typename ScalarPrimitiveTypeTraits::primitiveType primitiveType;
00719   static int numPrimitiveObjs()
00720     { return 2*ScalarPrimitiveTypeTraits::numPrimitiveObjs(); }
00722   static int numIndexObjs() { return 0; }
00724   static int numCharObjs() { return 0; }
00726   static void extractPrimitiveObjs(
00727     const std::complex<Scalar> &obj,
00728     const ArrayView<primitiveType> &primitiveObjs,
00729     const ArrayView<index_type> &indexObjs,
00730     const ArrayView<char> &charObjs
00731     )
00732     {
00733       using Teuchos::null;
00734       const int numScalarPrimitiveObjs =
00735         ScalarPrimitiveTypeTraits::numPrimitiveObjs();
00736       assertInput(primitiveObjs, indexObjs, charObjs);
00737       ScalarPrimitiveTypeTraits::extractPrimitiveObjs(
00738         obj.real(), primitiveObjs(0,numScalarPrimitiveObjs), null, null );
00739       ScalarPrimitiveTypeTraits::extractPrimitiveObjs(
00740         obj.imag(), primitiveObjs(numScalarPrimitiveObjs,numScalarPrimitiveObjs), null, null );
00741     }
00743   static void loadPrimitiveObjs(
00744     const ArrayView<const primitiveType> &primitiveObjs,
00745     const ArrayView<const index_type> &indexObjs,
00746     const ArrayView<const char> &charObjs,
00747     const Ptr<std::complex<Scalar> > &obj
00748     )
00749     {
00750       using Teuchos::null;
00751       using Teuchos::outArg;
00752       assertInput(primitiveObjs, indexObjs, charObjs);
00753       const int numScalarPrimitiveObjs =
00754         ScalarPrimitiveTypeTraits::numPrimitiveObjs();
00755       Scalar real, imag;
00756       ScalarPrimitiveTypeTraits::loadPrimitiveObjs(
00757         primitiveObjs(0,numScalarPrimitiveObjs), null, null,
00758         outArg(real) );
00759       ScalarPrimitiveTypeTraits::loadPrimitiveObjs(
00760         primitiveObjs(numScalarPrimitiveObjs,numScalarPrimitiveObjs), null, null,
00761         outArg(imag) );
00762       *obj = std::complex<Scalar>( real, imag );
00763     }
00764 private:
00765   static void assertInput(
00766     const ArrayView<const primitiveType> &primitiveObjs,
00767     const ArrayView<const index_type> &indexObjs,
00768     const ArrayView<const char> &charObjs
00769     )
00770     {
00771 #ifdef TEUCHOS_DEBUG
00772       TEUCHOS_TEST_FOR_EXCEPT(
00773         primitiveObjs.size()!=2*ScalarPrimitiveTypeTraits::numPrimitiveObjs()
00774         || indexObjs.size()!=0
00775         || charObjs.size()!=0 );
00776 #endif
00777     }
00778 };
00779 
00780 
00784 template <class Scalar>
00785 class PrimitiveTypeTraits<std::complex<Scalar>, Scalar> {
00786 public:
00788   typedef PrimitiveTypeTraits<Scalar,Scalar> ScalarPrimitiveTypeTraits;
00790   typedef typename ScalarPrimitiveTypeTraits::primitiveType primitiveType;
00792   static int numPrimitiveObjs()
00793     { return ScalarPrimitiveTypeTraits::numPrimitiveObjs(); }
00795   static int numIndexObjs() { return 0; }
00797   static int numCharObjs() { return 0; }
00799   static void extractPrimitiveObjs(
00800     const Scalar &obj,
00801     const ArrayView<primitiveType> &primitiveObjs,
00802     const ArrayView<index_type> &indexObjs,
00803     const ArrayView<char> &charObjs
00804     )
00805     {
00806       using Teuchos::null;
00807       assertInput(primitiveObjs, indexObjs, charObjs);
00808       ScalarPrimitiveTypeTraits::extractPrimitiveObjs(
00809         obj, primitiveObjs, null, null );
00810     }
00812   static void loadPrimitiveObjs(
00813     const ArrayView<const primitiveType> &primitiveObjs,
00814     const ArrayView<const index_type> &indexObjs,
00815     const ArrayView<const char> &charObjs,
00816     const Ptr<Scalar > &obj
00817     )
00818     {
00819       using Teuchos::null;
00820       assertInput(primitiveObjs, indexObjs, charObjs);
00821       ScalarPrimitiveTypeTraits::loadPrimitiveObjs(
00822         primitiveObjs, null, null, obj );
00823     }
00824 private:
00825   static void assertInput(
00826     const ArrayView<const primitiveType> &primitiveObjs,
00827     const ArrayView<const index_type> &indexObjs,
00828     const ArrayView<const char> &charObjs
00829     )
00830     {
00831 #ifdef TEUCHOS_DEBUG
00832       TEUCHOS_TEST_FOR_EXCEPT(
00833         primitiveObjs.size()!=ScalarPrimitiveTypeTraits::numPrimitiveObjs()
00834         || indexObjs.size()!=0
00835         || charObjs.size()!=0 );
00836 #endif
00837     }
00838 };
00839 
00840 
00841 #endif // defined(HAVE_COMPLEX) && defined(HAVE_TEUCHOS_COMPLEX)
00842 
00843 
00844 
00845 //
00846 // Forward declaration for templated types
00847 //
00848 
00849 
00851 template<class Scalar>  class RTOpT;
00852 
00853 
00854 } // namespace RTOpPack
00855 
00856 
00857 #endif // RTOPPACK_TYPES_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends