Intrepid
/usr/src/RPM/BUILD/trilinos-11.12.1/packages/intrepid/src/Shared/MiniTensor/Intrepid_MiniTensor_Storage.h
00001 // @HEADER
00002 // ************************************************************************
00003 //
00004 //                           Intrepid Package
00005 //                 Copyright (2007) 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: Alejandro Mota (amota@sandia.gov)
00038 //
00039 // ************************************************************************
00040 // @HEADER
00041 
00042 #if !defined(Intrepid_MiniTensor_Storage_h)
00043 #define Intrepid_MiniTensor_Storage_h
00044 
00045 #include "Intrepid_MiniTensor_Definitions.h"
00046 
00047 namespace Intrepid {
00048 
00050 template <Index N, Index C>
00051 struct dimension_const {
00052   static Index const value = C;
00053 };
00054 
00055 template <Index C>
00056 struct dimension_const<DYNAMIC, C> {
00057   static Index const value = DYNAMIC;
00058 };
00059 
00061 template <Index D>
00062 struct check_static {
00063   static Index const
00064   maximum_dimension = static_cast<Index>(std::numeric_limits<Index>::digits);
00065 
00066   STATIC_ASSERT(D < maximum_dimension, dimension_too_large);
00067   static Index const value = D;
00068 };
00069 
00070 template <typename Store>
00071 inline
00072 void
00073 check_dynamic(Index const dimension)
00074 {
00075   Index const
00076   maximum_dimension = static_cast<Index>(std::numeric_limits<Index>::digits);
00077 
00078   assert(Store::IS_DYNAMIC == true);
00079 
00080   if (dimension > maximum_dimension) {
00081     std::cerr << "ERROR: " << __PRETTY_FUNCTION__;
00082     std::cerr << std::endl;
00083     std::cerr << "Requested dimension (" << dimension;
00084     std::cerr << ") exceeds maximum allowed: " << maximum_dimension;
00085     std::cerr << std::endl;
00086     exit(1);
00087   }
00088 }
00089 
00091 template <Index D, Index O>
00092 struct dimension_power {
00093   static Index const value = 0;
00094 };
00095 
00096 template <Index D>
00097 struct dimension_power<D, 1> {
00098   static Index const value = D;
00099 };
00100 
00101 template <Index D>
00102 struct dimension_power<D, 2> {
00103   static Index const value = D * D;
00104 };
00105 
00106 template <Index D>
00107 struct dimension_power<D, 3> {
00108   static Index const value = D * D * D;
00109 };
00110 
00111 template <Index D>
00112 struct dimension_power<D, 4> {
00113   static Index const value = D * D * D * D;
00114 };
00115 
00117 template <Index N>
00118 struct dimension_square {
00119   static Index const value = 0;
00120 };
00121 
00122 template <>
00123 struct dimension_square<DYNAMIC> {
00124   static Index const value = DYNAMIC;
00125 };
00126 
00127 template <>
00128 struct dimension_square<1> {
00129   static Index const value = 1;
00130 };
00131 
00132 template <>
00133 struct dimension_square<2> {
00134   static Index const value = 4;
00135 };
00136 
00137 template <>
00138 struct dimension_square<3> {
00139   static Index const value = 9;
00140 };
00141 
00142 template <>
00143 struct dimension_square<4> {
00144   static Index const value = 16;
00145 };
00146 
00150 template <Index N>
00151 struct dimension_sqrt {
00152   static Index const value = 0;
00153 };
00154 
00155 template <>
00156 struct dimension_sqrt<DYNAMIC> {
00157   static Index const value = DYNAMIC;
00158 };
00159 
00160 template <>
00161 struct dimension_sqrt<1> {
00162   static Index const value = 1;
00163 };
00164 
00165 template <>
00166 struct dimension_sqrt<4> {
00167   static Index const value = 2;
00168 };
00169 
00170 template <>
00171 struct dimension_sqrt<9> {
00172   static Index const value = 3;
00173 };
00174 
00175 template <>
00176 struct dimension_sqrt<16> {
00177   static Index const value = 4;
00178 };
00179 
00181 template <Index N, Index P>
00182 struct dimension_add {
00183   static Index const value = N + P;
00184 };
00185 
00186 template <Index P>
00187 struct dimension_add<DYNAMIC, P> {
00188   static Index const value = DYNAMIC;
00189 };
00190 
00191 template <Index N, Index P>
00192 struct dimension_subtract {
00193   static Index const value = N - P;
00194 };
00195 
00196 template <Index P>
00197 struct dimension_subtract<DYNAMIC, P> {
00198   static Index const value = DYNAMIC;
00199 };
00200 
00204 template<typename T, Index N>
00205 class Storage
00206 {
00207 public:
00208   typedef T value_type;
00209   typedef T * pointer_type;
00210   typedef T & reference_type;
00211   typedef T const * const_pointer_type;
00212   typedef T const & const_reference_type;
00213 
00214   static
00215   bool const
00216   IS_STATIC = true;
00217 
00218   static
00219   bool const
00220   IS_DYNAMIC = false;
00221 
00222   Storage() {}
00223 
00224   explicit
00225   Storage(Index const number_entries) {resize(number_entries);}
00226 
00227   ~Storage() {}
00228 
00229   T const &
00230   operator[](Index const i) const
00231   {assert(i < N); return storage_[i];}
00232 
00233   T &
00234   operator[](Index const i)
00235   {assert(i < N); return storage_[i];}
00236 
00237   Index
00238   size() const {return N;}
00239 
00240   void
00241   resize(Index const number_entries) {assert(number_entries == N);}
00242 
00243   void
00244   clear() {}
00245 
00246   pointer_type
00247   get_pointer() {return &storage_[0];}
00248 
00249   const_pointer_type
00250   get_const_pointer() const {return &storage_[0];}
00251 
00252 private:
00253 
00254   Storage(Storage<T, N> const & s);
00255 
00256   Storage<T, N> &
00257   operator=(Storage<T, N> const & s);
00258 
00259   T
00260   storage_[N];
00261 
00262 };
00263 
00267 template<typename T>
00268 class Storage<T, DYNAMIC>
00269 {
00270 public:
00271   typedef T value_type;
00272   typedef T * pointer_type;
00273   typedef T & reference_type;
00274   typedef T const * const_pointer_type;
00275   typedef T const & const_reference_type;
00276 
00277   static
00278   bool const
00279   IS_DYNAMIC = true;
00280 
00281   static
00282   bool const
00283   IS_STATIC = false;
00284 
00285   Storage() : storage_(NULL), size_(0) {}
00286 
00287   explicit
00288   Storage(Index const number_entries) : storage_(NULL), size_(0)
00289   {resize(number_entries);}
00290 
00291   ~Storage() {clear();}
00292 
00293   T const &
00294   operator[](Index const i) const
00295   {assert(i < size()); return storage_[i];}
00296 
00297   T &
00298   operator[](Index const i)
00299   {assert(i < size()); return storage_[i];}
00300 
00301   Index
00302   size() const
00303   {return size_;}
00304 
00305   void
00306   resize(Index const number_entries)
00307   {
00308     if (number_entries != size_) {
00309       clear(); storage_ = new T[number_entries]; size_ = number_entries;
00310     }
00311   }
00312 
00313   void
00314   clear()
00315   {
00316     if (storage_ != NULL) {
00317       delete [] storage_; storage_ = NULL; size_ = 0;
00318     }
00319   }
00320 
00321   pointer_type
00322   get_pointer() {return storage_;}
00323 
00324   const_pointer_type
00325   get_const_pointer() const {return storage_;}
00326 
00327 private:
00328 
00329   Storage(Storage<T, DYNAMIC> const & s);
00330 
00331   Storage<T, DYNAMIC> &
00332   operator=(Storage<T, DYNAMIC> const & s);
00333 
00334   T *
00335   storage_;
00336 
00337   Index
00338   size_;
00339 };
00340 
00341 } // namespace Intrepid
00342 
00343 #include "Intrepid_MiniTensor_Storage.i.h"
00344 
00345 #endif // Intrepid_MiniTensor_Storage_h