XdmfItem.hpp 20.6 KB
Newer Older
Kenneth Leiter's avatar
Kenneth Leiter committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*****************************************************************************/
/*                                    XDMF                                   */
/*                       eXtensible Data Model and Format                    */
/*                                                                           */
/*  Id : XdmfItem.hpp                                                        */
/*                                                                           */
/*  Author:                                                                  */
/*     Kenneth Leiter                                                        */
/*     kenneth.leiter@arl.army.mil                                           */
/*     US Army Research Laboratory                                           */
/*     Aberdeen Proving Ground, MD                                           */
/*                                                                           */
/*     Copyright @ 2011 US Army Research Laboratory                          */
/*     All Rights Reserved                                                   */
/*     See Copyright.txt for details                                         */
/*                                                                           */
/*     This software is distributed WITHOUT ANY WARRANTY; without            */
/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
/*     for more information.                                                 */
/*                                                                           */
/*****************************************************************************/

24 25 26
#ifndef XDMFITEM_HPP_
#define XDMFITEM_HPP_

27
// Forward Declarations
28
class XdmfCoreReader;
29
class XdmfInformation;
30 31 32
class XdmfVisitor;

// Includes
33
#include <loki/Visitor.h>
34
#include <map>
35
#include <string>
36
#include <vector>
37
#include "XdmfCore.hpp"
38
#include "XdmfSharedPtr.hpp"
39

40 41
// Macro that allows children XdmfItems to be attached to a parent XdmfItem.
// -- For Header File
42
#define XDMF_CHILDREN(ParentClass, ChildClass, ChildName, SearchName)         \
43 44 45
                                                                              \
public:                                                                       \
                                                                              \
46 47 48 49 50 51 52 53 54 55 56 57 58 59
  /** Get a ChildClass attached to this item by index.<br>
      Example of use:<br>
      C++<br>
      //Assume that exampleItem is a shared pointer to the ParentClass object<br>
      //Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br>
      unsigned int getIndex = 0;<br>
      shared_ptr<XdmfInformation> exampleChild = exampleItem->getInformation(getIndex);<br>
      Python<br>
      '''<br>
      Assume that exampleItem is a shared pointer to the ParentClass object<br>
      Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br>
      '''<br>
      getIndex = 0<br>
      exampleChild = exampleItem.getInformation(getIndex)<br>
60 61 62
      @return requested ChildClass. If no ChildClass##s exist at the index,
      a NULL pointer is returned.
  */                                                                          \
63
  virtual shared_ptr<ChildClass>                                              \
64 65
  get##ChildName(const unsigned int index);                                   \
                                                                              \
66 67 68 69 70 71 72
  /** Get a ChildClass attached to this item by index (const version).<br>
      Example of use:<br>
      C++<br>
      //Assume that exampleItem is a shared pointer to the ParentClass object<br>
      //Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br>
      unsigned int getIndex = 0;<br>
      shared_ptr<const XdmfInformation> exampleChildConst = exampleItem->getInformation(getIndex);<br>
73
      Python: does not support a constant version of this function
74 75 76 77
      @param index of the ChildClass to retrieve.
      @return requested ChildClass. If no ChildClass##s exist at the index, a
      NULL pointer is returned.
  */                                                                          \
78
  virtual shared_ptr<const ChildClass>                                        \
79 80
  get##ChildName(const unsigned int index) const;                             \
                                                                              \
81 82 83 84 85 86 87 88 89 90 91 92 93 94
  /** Get a ChildClass attached to this item by SearchName.<br>
      Example of use:<br>
      C++<br>
      //Assume that exampleItem is a shared pointer to the ParentClass object<br>
      //Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br>
      std::string findingInfo = "Find this";<br>
      shared_ptr<XdmfInformation> exampleStringChild = exampleItem->getInformation(findingInfo);<br>
      Python<br>
      '''<br>
      Assume that exampleItem is a shared pointer to the ParentClass object<br>
      Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br>
      '''<br>
      findingInfo = "Find this"<br>
      exampleStringChild = exampleItem.getInformation(findingInfo)<br>
95 96 97 98
      @param SearchName of the ChildClass to retrieve.
      @return requested ChildClass. If no ChildClass##s are found with the
      correct SearchName, a NULL pointer is returned.
  */                                                                          \
99
  virtual shared_ptr<ChildClass>                                              \
100 101
  get##ChildName(const std::string & SearchName);                             \
                                                                              \
102 103 104 105 106 107 108
  /** Get a ChildClass attached to this item by SearchName (const version).<br>
      Example of use:<br>
      C++<br>
      //Assume that exampleItem is a shared pointer to the ParentClass object<br>
      //Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br>
      std::string findingInfo = "Find this";<br>
      shared_ptr<const XdmfInformation> exampleStringChildConst = exampleItem->getInformation(findingInfo);<br>
109
      Python: does not support a constant version of this function
110 111 112 113
      @param SearchName of the ChildClass to retrieve.
      @return requested ChildClass  If no ChildClass##s are found with the
      correct SearchName, a NULL pointer is returned.
  */                                                                          \
114
  virtual shared_ptr<const ChildClass>                                        \
115 116
  get##ChildName(const std::string & SearchName) const;                       \
                                                                              \
117 118 119 120 121 122 123 124 125 126 127 128
  /** Get the number of ChildClass##s attached to this item.<br>
      Example of use:<br>
      C++<br>
      //Assume that exampleItem is a shared pointer to the ParentClass object<br>
      //Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br>
      unsigned int exampleSize = exampleItem->getNumberInformations();<br>
      Python<br>
      '''<br>
      Assume that exampleItem is a shared pointer to the ParentClass object<br>
      Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br>
      '''<br>
      exampleSize = exampleItem.getNumberInformations()<br>
129 130 131 132
      @return number of ChildClass##s attached to this item.
  */                                                                          \
  virtual unsigned int getNumber##ChildName##s() const;                       \
                                                                              \
133 134 135 136 137 138 139 140 141 142
  /** Insert a ChildClass into to this item.<br>
      Example of use:<br>
      C++<br>
      shared_ptr<XdmfInformation> exampleItem = XdmfInformation::New("Parent", "This is a parent information");<br>
      shared_ptr<XdmfInformation> addChild = XdmfInformation::New("Child", "This is a child information");<br>
      exampleItem->insert(addChild);<br>
      Python<br>
      exampleItem = XdmfInformation.New("Parent", "This is a parent information")<br>
      addChild = XdmfInformation.New("Child", "This is a child information")<br>
      exampleItem.insert(addChild)<br>
143 144
      @param ChildName to attach to this item.
  */                                                                          \
145
  virtual void insert(const shared_ptr<ChildClass> ChildName);                \
146
                                                                              \
147
  /** Remove a ChildClass from this item by index. If no object exists
148 149 150 151 152 153 154 155 156 157 158 159
      at the index, nothing is removed.<br>
      Example of use:<br>
      C++<br>
      //Assume that exampleItem is a shared pointer to the ParentClass object<br>
      //Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br>
      unsigned int removeIndex = 0;<br>
      exampleItem->removeInformation(removeIndex);<br>
      Python<br>
      '''<br>
      Assume that exampleItem is a shared pointer to the ParentClass object<br>
      Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br>
      '''<br>
160
      removeIndex = 0<br>
161
      exampleItem.removeInformation(removeIndex)
162 163 164 165 166
      @param index of the ChildClass to remove.
  */                                                                          \
  virtual void remove##ChildName(const unsigned int index);                   \
                                                                              \
  /** Remove a ChildClass from this item by SearchName. If no ChildClass##s
167 168 169 170 171 172 173 174 175 176 177 178 179 180
      have the correct SearchName, nothing is removed.<br>
      Example of use:<br>
      C++<br>
      //Assume that exampleItem is a shared pointer to the ParentClass object<br>
      //Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br>
      std::string removeInfo = "Remove this";<br>
      exampleItem->removeInformation(removeInfo);<br>
      Python<br>
      '''<br>
      Assume that exampleItem is a shared pointer to the ParentClass object<br>
      Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br>
      '''<br>
      removeInfo = "Remove this"<br>
      exampleItem.removeInformation(removeInfo)<br>
181 182 183 184 185 186
      @param SearchName of the ChildClass to remove.
  */                                                                          \
  virtual void remove##ChildName(const std::string & SearchName);             \
                                                                              \
protected :                                                                   \
                                                                              \
187
  std::vector<shared_ptr<ChildClass> > m##ChildName##s;                       \
188 189 190 191 192 193
                                                                              \
public :

// Macro that allows children XdmfItems to be attached to a parent XdmfItem.
// -- For Implementation File
#define XDMF_CHILDREN_IMPLEMENTATION(ParentClass,                             \
194 195 196
                                     ChildClass,                              \
                                     ChildName,                               \
                                     SearchName)                              \
197
                                                                              \
198
  shared_ptr<ChildClass>                                                      \
199 200 201 202 203 204
  ParentClass::get##ChildName(const unsigned int index)                       \
  {                                                                           \
    return boost::const_pointer_cast<ChildClass>                              \
      (static_cast<const ParentClass &>(*this).get##ChildName(index));        \
  }                                                                           \
                                                                              \
205
  shared_ptr<const ChildClass>                                                \
206 207 208 209 210
  ParentClass::get##ChildName(const unsigned int index) const                 \
  {                                                                           \
    if(index < m##ChildName##s.size()) {                                      \
      return m##ChildName##s[index];                                          \
    }                                                                         \
211
    return shared_ptr<ChildClass>();                                          \
212 213
  }                                                                           \
                                                                              \
214
  shared_ptr<ChildClass>                                                      \
215 216 217 218 219 220
  ParentClass::get##ChildName(const std::string & SearchName)                 \
  {                                                                           \
    return boost::const_pointer_cast<ChildClass>                              \
      (static_cast<const ParentClass &>(*this).get##ChildName(SearchName));   \
  }                                                                           \
                                                                              \
221
  shared_ptr<const ChildClass>                                                \
222 223
  ParentClass::get##ChildName(const std::string & SearchName) const           \
  {                                                                           \
224
    for(std::vector<shared_ptr<ChildClass> >::const_iterator iter =           \
225 226 227 228 229 230 231
          m##ChildName##s.begin();                                            \
        iter != m##ChildName##s.end();                                        \
        ++iter) {                                                             \
      if((*iter)->get##SearchName().compare(SearchName) == 0) {               \
        return *iter;                                                         \
      }                                                                       \
    }                                                                         \
232
    return shared_ptr<ChildClass>();                                          \
233 234 235 236 237 238 239 240 241
  }                                                                           \
                                                                              \
  unsigned int                                                                \
  ParentClass::getNumber##ChildName##s() const                                \
  {                                                                           \
    return m##ChildName##s.size();                                            \
  }                                                                           \
                                                                              \
  void                                                                        \
242
  ParentClass::insert(const shared_ptr<ChildClass> ChildName)                 \
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
  {                                                                           \
    m##ChildName##s.push_back(ChildName);                                     \
  }                                                                           \
                                                                              \
  void                                                                        \
  ParentClass::remove##ChildName(const unsigned int index)                    \
  {                                                                           \
    if(index < m##ChildName##s.size()) {                                      \
      m##ChildName##s.erase(m##ChildName##s.begin() + index);                 \
    }                                                                         \
  }                                                                           \
                                                                              \
  void                                                                        \
  ParentClass::remove##ChildName(const std::string & SearchName)              \
  {                                                                           \
258
    for(std::vector<shared_ptr<ChildClass> >::iterator iter =                 \
259 260 261 262 263 264 265 266 267
          m##ChildName##s.begin();                                            \
        iter != m##ChildName##s.end();                                        \
        ++iter) {                                                             \
        if((*iter)->get##SearchName().compare(SearchName) == 0) {             \
          m##ChildName##s.erase(iter);                                        \
          return;                                                             \
        }                                                                     \
    }                                                                         \
  }
268

269
/**
270 271
 * @brief Base class of any object that is able to be added to an Xdmf
 * structure.
272
 *
273 274 275
 * XdmfItem is an abstract base class. An XdmfItem is a structure that
 * can be visited and traversed by an XdmfVisitor and have its
 * contents written to an Xdmf file.
276
 */
277
class XDMFCORE_EXPORT XdmfItem : public Loki::BaseVisitable<void> {
278

279
public:
280

281
  virtual ~XdmfItem() = 0;
282

283 284
  LOKI_DEFINE_VISITABLE_BASE()
  XDMF_CHILDREN(XdmfItem, XdmfInformation, Information, Key)
285
  friend class XdmfCoreReader;
286

287
  /**
288 289
   * Get the tag for this item.  This is equivalent to tags in XML
   * parlance.
290
   *
291 292 293 294
   * Example of use:
   *
   * C++
   *
295
   * @dontinclude ExampleXdmfItem.cpp
296 297 298 299
   * @skipline //#initialization
   * @until //#initialization
   * @skipline //#getItemTag
   * @until //#getItemTag
300 301 302
   *
   * Python
   *
303
   * @dontinclude XdmfExampleItem.py
304 305 306 307
   * @skipline #//initialization
   * @until #//initialization
   * @skipline #//getItemTag
   * @until #//getItemTag
308
   *
309
   * @return    The tag for this XdmfItem.
310 311
   */
  virtual std::string getItemTag() const = 0;
312

313
  /**
314 315
   * Get the key/value property pairs for this item. These are
   * equivalent to attributes in XML parlance.
316
   *
317 318 319 320
   * Example of use:
   *
   * C++
   *
321
   * @dontinclude ExampleXdmfItem.cpp
322 323 324 325
   * @skipline //#initialization
   * @until //#initialization
   * @skipline //#getItemProperties
   * @until //#getItemProperties
326 327 328
   *
   * Python
   *
329
   * @dontinclude XdmfExampleItem.py
330 331 332 333
   * @skipline #//initialization
   * @until #//initialization
   * @skipline #//getItemProperties
   * @until #//getItemProperties
334
   *
335
   * @return    A map of key/value properties associated with this XdmfItem.
336 337
   */
  virtual std::map<std::string, std::string> getItemProperties() const = 0;
338

339 340 341
  /**
   * Traverse this item by passing the visitor to child items.
   *
342 343 344 345
   * Example of use:
   *
   * C++
   *
346
   * @dontinclude ExampleXdmfItem.cpp
347 348 349 350
   * @skipline //#initialization
   * @until //#initialization
   * @skipline //#traverse
   * @until //#traverse
351 352 353
   *
   * Python
   *
354
   * @dontinclude XdmfExampleItem.py
355 356 357 358
   * @skipline #//initialization
   * @until #//initialization
   * @skipline #//traverse
   * @until #//traverse
359
   *
360
   * @param     visitor         The visitor to pass to child items.
361
   */
362
  virtual void traverse(const shared_ptr<XdmfBaseVisitor> visitor);
363

364
protected:
365

366
  XdmfItem();
367

368
  /**
369 370 371
   * Populates an item using a map of key/value property pairs and a
   * vector of its child items. This is used to support generic
   * reading of XdmfItems from disk.
372 373 374 375 376 377 378 379 380
   *
   * @param itemProperties a map of key/value properties associated with
   * this item.
   * @param childItems a vector of child items to be added to this item.
   * @param reader the current XdmfCoreReader being used to populate Xdmf
   * structures.
   */
  virtual void
  populateItem(const std::map<std::string, std::string> & itemProperties,
381
               const std::vector<shared_ptr<XdmfItem > > & childItems,
382
               const XdmfCoreReader * const reader);
383

384
private:
385

386 387
  XdmfItem(const XdmfItem &);  // Not implemented.
  void operator=(const XdmfItem &);  // Not implemented.
388

389 390
};

391
#ifdef _WIN32
392 393
XDMFCORE_TEMPLATE
template class XDMFCORE_EXPORT
394
std::allocator<shared_ptr<XdmfItem> >;
395
XDMFCORE_TEMPLATE template class XDMFCORE_EXPORT
396 397
std::vector<shared_ptr<XdmfItem>, 
            std::allocator<shared_ptr<XdmfItem> > >;
398
XDMFCORE_TEMPLATE template class XDMFCORE_EXPORT
399
std::allocator<shared_ptr<XdmfInformation> >;
400
XDMFCORE_TEMPLATE template class XDMFCORE_EXPORT
401 402
std::vector<shared_ptr<XdmfInformation>, 
            std::allocator<shared_ptr<XdmfInformation> > >;
403
XDMFCORE_TEMPLATE template class XDMFCORE_EXPORT
404
shared_ptr<Loki::BaseVisitor>;
405 406
XDMFCORE_TEMPLATE template class XDMFCORE_EXPORT
Loki::BaseVisitable<void, false>;
407 408
#endif

409
#endif /* XDMFITEM_HPP_ */