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 //class LayoutData 00020 00021 /// Data that maintains a one-to-one mapping of T to the boxes in a BoxLayout 00022 /** 00023 A collection of Box-oriented objects. The arrangement of the T objects 00024 is given by the underlying BoxLayout object. LayoutData does not attempt 00025 to prevent users from manipulating the template class T to become out of 00026 synch with the boxes in the BoxLayout. Caveat emptor. 00027 00028 Non-local (off-processor access) to a LayoutData index is an error. You 00029 can assure that access to the data stored in a LayoutData is local to your 00030 processor by using the DataIterator object for indexing. 00031 00032 Data in a LayoutData CANNOT be communicated to other processors using 00033 the API presented in LevelData. 00034 00035 class T must provide the following methods: 00036 <PRE> 00037 { 00038 T() 00039 } 00040 </PRE> 00041 00042 This class is useful for processor-local data that needs to be indexable 00043 along with a BoxLayoutData. Auxillary data objects, etc. 00044 */ 00045 template<class T> class LayoutData 00046 { 00047 public: 00048 /// 00049 LayoutData(); 00050 00051 /// 00052 /** 00053 constructor. allocates a T object for every box in the BoxLayout a_dp 00054 using the T null constructor. a_dp must be closed. 00055 */ 00056 LayoutData(const BoxLayout& a_dp); 00057 00058 /// 00059 virtual ~LayoutData(); 00060 00061 /// 00062 /** 00063 constructor. allocates a T object for every box in the BoxLayout a_dp 00064 using the T null constructor. a_dp must be closed. previously stored 00065 T objects are removed 00066 */ 00067 virtual void define(const BoxLayout& a_dp); 00068 00069 // this approach, of using the iterator itself for indexing is my own 00070 // brilliance. This way you don't need all the crappy [Const][Dependent] 00071 // Iterators. It also forces all data access to be done through the 00072 // DataIterator, which will know how to talk to KeLP (or other parallel 00073 // architectures, like multithreading, etc). 00074 00075 /// 00076 DataIterator dataIterator() const; 00077 00078 TimedDataIterator timedDataIterator() const; 00079 00080 /// const accessor function 00081 const T& operator [] (const DataIndex& a_index) const; 00082 00083 /// const accessor function 00084 /** 00085 Returns member for which DataIterator is currently indexed to. 00086 Equivalent to layout[a_iterator()] 00087 */ 00088 const T& operator [] (const DataIterator& a_iterator) const; 00089 00090 /// non-const accessor function 00091 T& operator [] (const DataIndex& a_index); 00092 00093 /// non-const accessor function 00094 T& operator [] (const DataIterator& a_iterator); 00095 00096 /// 00097 Box box(const DataIndex& a_index) const; 00098 00099 Box box(const DataIterator& a_iterator) const; 00100 00101 // not really a protection mechanism, since a user can always 00102 // perform a shallow copy of the BoxLayout, and be free to manipulate 00103 // the data in the object. If you wish to have an actual copy 00104 // of the BoxLayout, then you need to invoke the clone() method. 00105 00106 /// 00107 const BoxLayout& boxLayout() const 00108 { 00109 return m_boxLayout; 00110 } 00111 00112 00113 protected: 00114 00115 // for BoxLayout::define(const LayoutData<Box>& a_newLayout) 00116 friend class BoxLayout; 00117 00118 BoxLayout m_boxLayout; 00119 00120 // this used to be std::vector<T>, and I could let vector handle 00121 // destruction for me, but vector.resize() absolutely demands that 00122 // I provide a copy constructor for T. People get uncomfortable when 00123 // I make them provide me with copy constructors. 00124 Vector<T*> m_vector; 00125 00126 // thinking about making this class self-documenting to a greater degree 00127 // and having the component names also be kept in the class and carried 00128 // around through various transformations..... 00129 // vector<string> m_componentNames; 00130 00131 bool m_callDelete; 00132 00133 00134 private: 00135 // disallow copy constructors and assignment operators 00136 // to avoid very hard-to-find performance problems 00137 LayoutData<T>& operator= (const LayoutData<T>& a_rhs); 00138 LayoutData(const LayoutData& a_rhs); 00139 00140 // handy usage function, tied to the implementation of this class 00141 // as a vector<T*>. Assumes that m_comps and m_boxLayout have already 00142 // been initialized correctly. Sets the correct size for the data 00143 // vector, deletes the extra T objects if m_vector is to shorten, and 00144 // performs either construction or define on the remaining T objects. 00145 void allocate(); 00146 }; 00147 00148 //====================== inline functions =========================== 00149 // not literally a .H file, but just an experiment in having useable, 00150 // readable headers, while having the dependeny system work properly. 00151 // Since LayoutData.H now depends on LayoutDataI.H, then changing either 00152 // should cause all code that includes LayoutData.H to be recompiled. 00153 // This way people can just read the interface in this file. 00154 // Implementation is put in the *I.H file. 00155 00156 #include "NamespaceFooter.H" 00157 #include "LayoutDataI.H" 00158 00159 #endif