XdmfItem.hpp 19.3 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 46
                                                                              \
public:                                                                       \
                                                                              \
  /** Get a ChildClass attached to this item by index.
47 48 49 50 51 52 53 54 55 56 57
      Example of use:
      C++
      unsigned int getIndex = 0;
      //Assume that exampleItem is a shared pointer to an ParentClass object
      shared_ptr<ChildClass> exampleChild = exampleItem->get##ChildName(getIndex);
      Python
      getIndex = 0;
      '''
      Assume that exampleItem is a shared pointer to an ParentClass object
      '''
      exampleChild = exampleItem.get##ChildName(getIndex)
58 59 60 61
      @param index of the ChildClass to retrieve.
      @return requested ChildClass. If no ChildClass##s exist at the index,
      a NULL pointer is returned.
  */                                                                          \
62
  virtual shared_ptr<ChildClass>                                              \
63 64 65
  get##ChildName(const unsigned int index);                                   \
                                                                              \
  /** Get a ChildClass attached to this item by index (const version).
66 67 68 69 70 71
      Example of use:
      C++
      unsigned int getIndex = 0;
      //Assume that exampleItem is a shared pointer to an ParentClass object
      shared_ptr<const ChildClass> exampleChild = exampleItem->get##ChildName(getIndex);
      Python: does not support a constant version of this function
72 73 74 75
      @param index of the ChildClass to retrieve.
      @return requested ChildClass. If no ChildClass##s exist at the index, a
      NULL pointer is returned.
  */                                                                          \
76
  virtual shared_ptr<const ChildClass>                                        \
77 78 79
  get##ChildName(const unsigned int index) const;                             \
                                                                              \
  /** Get a ChildClass attached to this item by SearchName.
80 81 82 83 84 85 86 87 88 89 90
      Example of use:
      C++
      std::string finding##SearchName = "Find this";
      //Assume that exampleItem is a shared pointer to an ParentClass object
      shared_ptr<ChildClass> exampleChild = exampleItem->get##ChildName(finding##SearchName);
      Python
      finding##SearchName = "Find this"
      '''
      Assume that exampleItem is a shared pointer to an ParentClass object
      '''
      exampleChild = exampleItem.get##ChildName(finding##SearchName)
91 92 93 94
      @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.
  */                                                                          \
95
  virtual shared_ptr<ChildClass>                                              \
96 97 98
  get##ChildName(const std::string & SearchName);                             \
                                                                              \
  /** Get a ChildClass attached to this item by SearchName (const version).
99 100 101 102 103 104
      Example of use:
      C++
      std::string finding##SearchName = "Find this";
      //Assume that exampleItem is a shared pointer to an ParentClass object
      shared_ptr<const ChildClass> exampleChild = exampleItem->get##ChildName(finding##SearchName);
      Python: does not support a constant version of this function
105 106 107 108
      @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.
  */                                                                          \
109
  virtual shared_ptr<const ChildClass>                                        \
110 111 112
  get##ChildName(const std::string & SearchName) const;                       \
                                                                              \
  /** Get the number of ChildClass##s attached to this item.
113 114 115 116 117 118 119 120 121
      Example of use:
      C++
      //Assume that exampleItem is a shared pointer to an ParentClass object
      unsigned int exampleSize = exampleItem->getNumber##ChildName##s();
      Python
      '''
      Assume that exampleItem is a shared pointer to an ParentClass object
      '''
      exampleSize = exampleItem.getNumber##ChildName##s()
122 123 124 125 126
      @return number of ChildClass##s attached to this item.
  */                                                                          \
  virtual unsigned int getNumber##ChildName##s() const;                       \
                                                                              \
  /** Insert a ChildClass into to this item.
127 128 129 130 131 132 133 134 135 136 137
      Example of use:
      C++
      //Assume that exampleChild is a shared pointer to an ChildClass object
      //Assume that exampleItem is a shared pointer to an ParentClass object
      exampleItem->insert(exampleChild);
      Python
      '''
      Assume that exampleChild is a shared pointer to an ChildClass object
      Assume that exampleItem is a shared pointer to an ParentClass object
      '''
      exampleItem.insert(exampleChild)
138 139
      @param ChildName to attach to this item.
  */                                                                          \
140
  virtual void insert(const shared_ptr<ChildClass> ChildName);                \
141 142 143
                                                                              \
  /** Remove a ChildClass from this item by index. If no ChildClass##s exist
      at the index, nothing is removed.
144 145 146 147 148 149 150 151 152 153 154
      Example of use:
      C++
      //Assume that exampleItem is a shared pointer to an ParentClass object
      unsigned int removeIndex = 0;
      exampleItem->remove##ChildName(removeIndex);
      Python
      '''
      Assume that exampleItem is a shared pointer to an ParentClass object
      '''
      removeIndex = 0
      exampleItem.remove##ChildName(removeIndex)
155 156 157 158 159 160
      @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
      have the correct SearchName, nothing is removed.
161 162 163 164 165 166 167 168 169 170 171
      Example of use:
      C++
      //Assume that exampleItem is a shared pointer to an ParentClass object
      unsigned int remove##SearchName = "Remove this";
      exampleItem->remove##ChildName(remove##SearchName);
      Python
      '''
      Assume that exampleItem is a shared pointer to an ParentClass object
      '''
      remove##SearchName = "Remove this"
      exampleItem.remove##ChildName(remove##SearchName)
172 173 174 175 176 177
      @param SearchName of the ChildClass to remove.
  */                                                                          \
  virtual void remove##ChildName(const std::string & SearchName);             \
                                                                              \
protected :                                                                   \
                                                                              \
178
  std::vector<shared_ptr<ChildClass> > m##ChildName##s;                       \
179 180 181 182 183 184
                                                                              \
public :

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

260
/**
261 262
 * @brief Base class of any object that is able to be added to an Xdmf
 * structure.
263
 *
264 265 266
 * 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.
267
 */
268
class XDMFCORE_EXPORT XdmfItem : public Loki::BaseVisitable<void> {
269

270
public:
271

272
  virtual ~XdmfItem() = 0;
273

274
  LOKI_DEFINE_VISITABLE_BASE();
275
  XDMF_CHILDREN(XdmfItem, XdmfInformation, Information, Key);
276
  friend class XdmfCoreReader;
277

278
  /**
279 280
   * Get the tag for this item.  This is equivalent to tags in XML
   * parlance.
281
   *
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297
   * Example of use:
   *
   * C++
   *
   * //Using a shared pointer to an XdmfDomain object as an example
   * shared_ptr<XdmfDomain> exampleItem = XdmfDomain::New();
   * std::string exampleTag = exampleItem->getItemTag();
   *
   * Python
   *
   * '''
   * Using a shared pointer to an XdmfDomain object as an example
   * '''
   * exampleItem = XdmfDomain.New()
   * exampleTag = exampleItem.getItemTag()
   *
298 299 300
   * @return the tag for this XdmfItem.
   */
  virtual std::string getItemTag() const = 0;
301

302
  /**
303 304
   * Get the key/value property pairs for this item. These are
   * equivalent to attributes in XML parlance.
305
   *
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321
   * Example of use:
   *
   * C++
   *
   * //Using a shared pointer to an XdmfDomain object as an example
   * shared_ptr<XdmfDomain> exampleItem = XdmfDomain::New();
   * std::map<std::string, std::string> propertyMap = exampleItem->getItemProperties();
   *
   * Python
   *
   * '''
   * Using a shared pointer to an XdmfDomain object as an example
   * '''
   * exampleItem = XdmfDomain.New()
   * propertyMap = exampleItem.getItemProperties()
   *
322 323 324
   * @return a map of key/value properties associated with this XdmfItem.
   */
  virtual std::map<std::string, std::string> getItemProperties() const = 0;
325

326 327 328
  /**
   * Traverse this item by passing the visitor to child items.
   *
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348
   * Example of use:
   *
   * C++
   *
   * //Using a shared pointer to an XdmfDomain object as an example
   * shared_ptr<XdmfDomain> exampleItem = XdmfDomain::New();
   * std::string writePath = "file path here";
   * shared_ptr<XdmfWriter> exampleWriter = XdmfWriter::New(writepath);
   * exampleItem->traverse(exampleWriter);
   *
   * Python
   *
   * '''
   * Using a shared pointer to an XdmfDomain object as an example
   * '''
   * exampleItem = XdmfDomain.New()
   * writePath = "file path here"
   * exampleWriter = XdmfWriter.New(writepath)
   * exampleItem.traverse(exampleWriter)
   *
349 350
   * @param visitor the visitor to pass to child items.
   */
351
  virtual void traverse(const shared_ptr<XdmfBaseVisitor> visitor);
352

353
protected:
354

355
  XdmfItem();
356

357
  /**
358 359 360
   * 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.
361 362 363 364 365 366 367 368 369
   *
   * @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,
370
               const std::vector<shared_ptr<XdmfItem > > & childItems,
371
               const XdmfCoreReader * const reader);
372

373
private:
374

375 376
  XdmfItem(const XdmfItem &);  // Not implemented.
  void operator=(const XdmfItem &);  // Not implemented.
377

378 379
};

380
#ifdef _WIN32
381 382
XDMFCORE_TEMPLATE
template class XDMFCORE_EXPORT
383
std::allocator<shared_ptr<XdmfItem> >;
384
XDMFCORE_TEMPLATE template class XDMFCORE_EXPORT
385 386
std::vector<shared_ptr<XdmfItem>, 
            std::allocator<shared_ptr<XdmfItem> > >;
387
XDMFCORE_TEMPLATE template class XDMFCORE_EXPORT
388
std::allocator<shared_ptr<XdmfInformation> >;
389
XDMFCORE_TEMPLATE template class XDMFCORE_EXPORT
390 391
std::vector<shared_ptr<XdmfInformation>, 
            std::allocator<shared_ptr<XdmfInformation> > >;
392
XDMFCORE_TEMPLATE template class XDMFCORE_EXPORT
393
shared_ptr<Loki::BaseVisitor>;
394 395
XDMFCORE_TEMPLATE template class XDMFCORE_EXPORT
Loki::BaseVisitable<void, false>;
396 397
#endif

398
#endif /* XDMFITEM_HPP_ */