00001 #ifdef CH_LANG_CC 00002 /* 00003 * _______ __ 00004 * / ___/ / ___ __ _ / / ___ 00005 * / /__/ _ \/ _ \/ V \/ _ \/ _ \ 00006 * \___/_//_/\___/_/_/_/_.__/\___/ 00007 * Please refer to Copyright.txt, in Chombo's root directory. 00008 */ 00009 #endif 00010 00011 #ifndef _LAYOUTDATA_H_ 00012 #define _LAYOUTDATA_H_ 00013 00014 #include "BoxLayout.H" 00015 #include "DataIterator.H" 00016 #include "TimedDataIterator.H" 00017 #include "NamespaceHeader.H" 00018 00019 00020 //class LayoutData 00021 00023 00046 template<class T> class LayoutData 00047 { 00048 public: 00050 LayoutData(); 00051 00053 00057 LayoutData(const BoxLayout& a_dp); 00058 00060 virtual ~LayoutData(); 00061 00063 00068 virtual void define(const BoxLayout& a_dp); 00069 00070 // this approach, of using the iterator itself for indexing is my own 00071 // brilliance. This way you don't need all the crappy [Const][Dependent] 00072 // Iterators. It also forces all data access to be done through the 00073 // DataIterator, which will know how to talk to KeLP (or other parallel 00074 // architectures, like multithreading, etc). 00075 00077 DataIterator dataIterator() const; 00078 00079 TimedDataIterator timedDataIterator() const; 00080 00082 const T& operator [] (const DataIndex& a_index) const; 00083 00085 00089 const T& operator [] (const DataIterator& a_iterator) const; 00090 00092 T& operator [] (const DataIndex& a_index); 00093 00095 T& operator [] (const DataIterator& a_iterator); 00096 00098 Box box(const DataIndex& a_index) const; 00099 00100 Box box(const DataIterator& a_iterator) const; 00101 00102 // not really a protection mechanism, since a user can always 00103 // perform a shallow copy of the BoxLayout, and be free to manipulate 00104 // the data in the object. If you wish to have an actual copy 00105 // of the BoxLayout, then you need to invoke the clone() method. 00106 00108 const BoxLayout& boxLayout() const 00109 { 00110 return m_boxLayout; 00111 } 00112 00113 00114 protected: 00115 00116 BoxLayout m_boxLayout; 00117 00118 // this used to be std::vector<T>, and I could let vector handle 00119 // destruction for me, but vector.resize() absolutely demands that 00120 // I provide a copy constructor for T. People get uncomfortable when 00121 // I make them provide me with copy constructors. 00122 Vector<T*> m_vector; 00123 00124 // thinking about making this class self-documenting to a greater degree 00125 // and having the component names also be kept in the class and carried 00126 // around through various transformations..... 00127 // vector<string> m_componentNames; 00128 00129 bool m_callDelete; 00130 00131 00132 private: 00133 // disallow copy constructors and assignment operators 00134 // to avoid very hard-to-find performance problems 00135 LayoutData<T>& operator= (const LayoutData<T>& a_rhs); 00136 LayoutData(const LayoutData& a_rhs); 00137 00138 // handy usage function, tied to the implementation of this class 00139 // as a vector<T*>. Assumes that m_comps and m_boxLayout have already 00140 // been initialized correctly. Sets the correct size for the data 00141 // vector, deletes the extra T objects if m_vector is to shorten, and 00142 // performs either construction or define on the remaining T objects. 00143 void allocate(); 00144 }; 00145 00146 //====================== inline functions =========================== 00147 // not literally a .H file, but just an experiment in having useable, 00148 // readable headers, while having the dependeny system work properly. 00149 // Since LayoutData.H now depends on LayoutDataI.H, then changing either 00150 // should cause all code that includes LayoutData.H to be recompiled. 00151 // This way people can just read the interface in this file. 00152 // Implementation is put in the *I.H file. 00153 00154 #include "NamespaceFooter.H" 00155 #include "LayoutDataI.H" 00156 00157 #endif