Chombo + EB + MF  3.2
ParmParse.H
Go to the documentation of this file.
1 #ifdef CH_LANG_CC
2 /*
3  * _______ __
4  * / ___/ / ___ __ _ / / ___
5  * / /__/ _ \/ _ \/ V \/ _ \/ _ \
6  * \___/_//_/\___/_/_/_/_.__/\___/
7  * Please refer to Copyright.txt, in Chombo's root directory.
8  */
9 #endif
10 
11 #ifndef _PARMPARSE_H_
12 #define _PARMPARSE_H_
13 
14 /*
15  DISCLAIMER:
16  This is ugly because it consists of four files from boxlib
17  concatenated together and munged hopelessly. This was done
18  (1) to greatly reduce the size of the API of boxlib
19  (2) to avoid the godawful task of rewriting parmparse
20  (3) to avoid cluttering the global namespace
21  We deeply apologize.
22 
23  Any class that begins with PP_ is a convenience
24  and will not be in any way supported by anyone at ANAG.
25 */
26 
27 #include <iostream>
28 #include <iomanip>
29 #include <cstdlib>
30 #include <cstring>
31 #include <vector>
32 #include <string>
33 #include <sstream>
34 
35 #include "CH_assert.H"
36 #include "MayDay.H"
37 #include "Misc.H"
38 #include "Vector.H"
39 #include "BaseNamespaceHeader.H"
40 using std::cout;
41 using std::cerr;
42 using std::endl;
43 //#include <aString.H>
44 
45 //#include <Pointers.H>
46 
47 //#include <UseCount.H>
48 
49 //
50 //@Man:
51 //@Memo: A Class Encapsulating Reference Counts for ParmParse
52 /*@Doc:
53 
54 This class encapsulates reference counts.
55 
56 This is a convenience class for ParmParse
57 and will not be in any way supported by anyone at ANAG.
58 */
59 #ifndef DOXYGEN
60 class PP_UseCount
61 {
62 public:
63  //
64  ///: Construct a PP_UseCount initialized to one.
65  //
66  PP_UseCount ();
67  //
68  ///: The copy constructor -- bumps reference count.
69  //
70  PP_UseCount (const PP_UseCount& rhs);
71 
72  /**: The assignment operator. Increments the reference count on
73  rhs, decrements the reference count on this, and then makes
74  this and rhs point to the same reference count.
75  */
76  PP_UseCount& operator= (const PP_UseCount& rhs);
77  //
78  ///: The destructor -- decrements the reference count.
79  //
80  ~PP_UseCount ();
81  //
82  ///: The PP_UseCount is unique if the reference count == 1.
83  //
84  bool unique () const;
85  //
86  ///: Returns the reference count.
87  //
88  int linkCount () const;
89 
90 private:
91  //
92  // A pointer to the reference count.
93  //
94  unsigned int* cnt;
95  //
96  // Decrement the reference count and delete the reference
97  // counter if there are no more references.
98  //
99  void decrement ();
100 };
101 
102 //
103 // Inlines.
104 //
105 
106 inline
107 PP_UseCount::PP_UseCount ()
108  :
109  cnt(new unsigned int(1))
110 {
111 }
112 
113 inline
114 PP_UseCount::PP_UseCount (const PP_UseCount& rhs)
115  :
116  cnt(rhs.cnt)
117 {
118  ++*cnt;
119 }
120 
121 inline
122 bool
123 PP_UseCount::unique () const
124 {
125  return *cnt == 1;
126 }
127 
128 inline
129 void
130 PP_UseCount::decrement ()
131 {
132  if (unique())
133  {
134  delete cnt;
135  cnt = 0;
136  }
137  else
138  --*cnt;
139 }
140 
141 inline
142 PP_UseCount&
143 PP_UseCount::operator= (const PP_UseCount& rhs)
144 {
145  ++*rhs.cnt;
146  decrement();
147  cnt = rhs.cnt;
148  return *this;
149 }
150 
151 inline
152 PP_UseCount::~PP_UseCount ()
153 {
154  decrement();
155 }
156 
157 inline
158 int
159 PP_UseCount::linkCount () const
160 {
161  return *cnt;
162 }
163 
164 ///: A Smart Pointer for Intrinsic or User-Defined Types for ParmParse
165 /**
166 
167 The template class PP_CpPtr<T> provides a simple wrapper around a pointer
168 to type T (T*) that builds a copy of the pointed-to object when copied
169 from one PP_CpPtr<T> to another. This is in contrast to a reference-counted
170 pointer class that would maintain one pointed-to object with a reference
171 count indicating the number of references. Hence we call this a
172 "copied" smart pointer class. It is intended for use with any type
173 type T, including the intrinsic types. This class does not supply
174 an operator->(), as such an operator on intrinsic types has only recently
175 become a part of the C++ language, and many compilers do not yet implement
176 it.
177 
178 This is a convenience class for ParmParse
179 and will not be in any way supported by anyone at ANAG.
180 */
181 
182 template <class T>
183 class PP_CpPtr
184 {
185 public:
186  //
187  ///: The default constructor. The wrapped pointer is null.
188  //
189  PP_CpPtr ();
190  //
191  ///: Construct a PP_CpPtr<T> setting the wrapped pointer to rhs.
192  //
193  /*explicit*/ PP_CpPtr (T* rhs);
194  //
195  ///: The destructor. Deletes the wrapped pointer.
196  //
197  ~PP_CpPtr ();
198 
199  /**: The copy constructor. If the pointer wrapped by rhs is null,
200  the wrapped pointer is null here as well. Otherwise,
201  the contained pointer here is set to a new'd copy of that
202  wrapped by rhs, with the two pointed-to values being identical.
203  This assumes that type T has a well-defined and accessible copy
204  constructor. T must also be a concrete type, not a abstract
205  type.
206  */
207  PP_CpPtr (const PP_CpPtr<T>& rhs);
208 
209  /**: Sets the wrapped pointer to rhs. Deletes the previously
210  wrapped pointer.
211  */
212  PP_CpPtr<T>& operator= (T* rhs);
213 
214  /**: The copy assignment operator. If the pointer wrapped by rhs
215  is null, the wrapped pointer is null here as well. Otherwise,
216  the contained pointer here is set to a new'd copy of that
217  wrapped by rhs, with the two pointed-to values being identical.
218  This assumes that type T has a well-defined and accessible copy
219  constructor. T must also be a concrete type, not a abstract
220  type.
221  */
222  PP_CpPtr<T>& operator= (const PP_CpPtr<T>& rhs);
223 
224  /**: Returns a reference to the value pointed to by the wrapped
225  pointer; i.e. dereferencing this PP_CpPtr<T>, returns the
226  dereferenced wrapped pointer. It is an error if the wrapped
227  pointer is null.
228  */
229  T& operator* () const;
230  //
231  ///: Returns true if the wrapped pointer null.
232  //
233  bool isNull () const;
234  //
235  ///: Sets the wrapped pointer to null and returns the previous value.
236  //
237  T* release ();
238  //
239  ///: Are the two pointers (not the values to which they point) equal?
240  //
241  bool operator== (const PP_CpPtr<T>& rhs) const;
242  //
243  ///: Are the two pointers not equal?
244  //
245  bool operator!= (const PP_CpPtr<T>& rhs) const;
246 
247 protected:
248  T* ptr;
249 };
250 
251 /// A Smart Pointer for User-Defined Types for ParmParse
252 /**
253 
254 The template class PP_CpClassPtr<T> is derived from PP_CpPtr<T>. It provides a
255 simple wrapper around a pointer to type T (a T*) that "does the right thing"
256 when copied from one PP_CpPtr<T> to another. The type T MUST be a user-defined
257 type, not an intrinsic type. Given this restriction, we can supply
258 an operator->().
259 
260 This is a convenience class for ParmParse
261 and will not be in any way supported by anyone at ANAG.
262 */
263 
264 template<class T>
265 class PP_CpClassPtr :
266  public PP_CpPtr<T>
267 {
268 public:
269  //
270  ///: The default constructor. The wrapped pointer is null.
271  //
272  PP_CpClassPtr ();
273  //
274  ///: Construct a PP_CpPtr<T> setting the wrapped pointer to rhs.
275  //
276  /*explicit*/ PP_CpClassPtr (T* rhs);
277 
278  /**: The copy constructor. If the pointer wrapped by rhs is null,
279  the wrapped pointer is null here as well. Otherwise,
280  the contained pointer here is set to a new'd copy of that
281  wrapped by rhs, with the two pointed-to values being identical.
282  This assumes that type T has a well-defined and accessible copy
283  constructor. T must also be a concrete type, not a abstract
284  type.
285  */
286  PP_CpClassPtr (const PP_CpClassPtr<T>& rhs);
287 
288  /**: Sets the wrapped pointer to rhs. Deletes the previously
289  wrapped pointer.
290  */
291  PP_CpClassPtr<T>& operator= (T* rhs);
292 
293  /**: The copy assignment operator. If the pointer wrapped by rhs
294  is null, the wrapped pointer is null here as well. Otherwise,
295  the contained pointer here is set to a new'd copy of that
296  wrapped by rhs, with the two pointed-to values being identical.
297  This assumes that type T has a well-defined and accessible copy
298  constructor. T must also be a concrete type, not a abstract
299  type.
300  */
301  PP_CpClassPtr<T>& operator= (const PP_CpClassPtr<T>& rhs);
302  //
303  ///: Applies operator-> to the wrapped pointer.
304  //
305  T* operator-> () const;
306 };
307 
308 /// A Reference Counted Smart Pointer for Intrinsic or User-Defined Types for ParmParse
309 /**
310 
311 The template class PP_LnPtr<T> provides a reference counted wrapper around a
312 pointer to type T (a T*). This "smart" pointer is intended for use with
313 any type type T, including the intrinsic types. For this reason, we do
314 not supply an operator->(), as such an operator on intrinsic types has only
315 recently become a part of the C++ language and many compilers do not yet
316 implement it.
317 
318 This is a convenience class for ParmParse
319 and will not be in any way supported by anyone at ANAG.
320 */
321 
322 template<class T>
323 class PP_LnPtr
324 {
325 public:
326  //
327  ///: The default constructor. The wrapped pointer is null.
328  //
329  PP_LnPtr ();
330  //
331  ///: Construct a PP_LnPtr<T> setting the wrapped pointer to rhs.
332  //
333  /*explicit*/ PP_LnPtr (T* rhs);
334 
335  /**: The copy assignment operator. The contained pointer is set
336  to the one wrapped by rhs. The reference count is decremented
337  on this object and the reference count is incremented for
338  the newly wrapped pointer.
339  */
340  PP_LnPtr<T>& operator= (const PP_LnPtr<T>& rhs);
341 
342  /**: Sets the wrapped pointer to rhs. Decrements the count
343  on the previously wrapped pointer and deletes it if there
344  was only one reference.
345  */
346  PP_LnPtr<T>& operator= (T* rhs)
347  {
348  //
349  // This is inlined here as OCC won't have it any other way :-(
350  //
351  if (unique())
352  delete ptr;
353  ptr = rhs;
354  ucnt = PP_UseCount();
355  return *this;
356  }
357 
358  /**: The destructor -- decrements the reference count and deletes
359  the wrapped pointer if there is only one reference.
360  */
361  ~PP_LnPtr ();
362  //
363  ///: Returns true if only one reference to the wrapped pointer.
364  //
365  bool unique () const;
366  //
367  ///: Returns the number of references to the wrapped pointer.
368  //
369  int linkCount () const;
370 
371  /**: Returns a reference to the value pointed to by the wrapped
372  pointer; i.e. dereferencing this PP_LnPtr<T>, returns the
373  dereferenced wrapped pointer. It is an error if the wrapped
374  pointer is null.
375  */
376  T& operator* () const;
377  //
378  ///: Returns true if the wrapped pointer is null.
379  //
380  bool isNull () const;
381  //
382  ///: Are the two pointers (not the values to which they point) equal?
383  //
384  bool operator== (const PP_LnPtr<T>& rhs) const;
385  //
386  ///: Are the two pointers not equal?
387  //
388  bool operator!= (const PP_LnPtr<T>& rhs) const;
389 
390 protected:
391  T* ptr;
392 
393 private:
394  PP_UseCount ucnt;
395 };
396 
397 /// A Smart Reference Counted Pointer for User-Defined Types for ParmParse
398 /**
399 
400 The template class PP_LnClassPtr<T> is derived from PP_LnPtr<T>. It provides a
401 reference counted wrapper around a pointer to type T (a T*). The type T
402 MUST be a user-defined type, not an intrinsic type. Given this
403 restriction, we can supply an operator->().
404 
405 This is a convenience class for ParmParse
406 and will not be in any way supported by anyone at ANAG.
407 */
408 
409 template<class T>
410 class PP_LnClassPtr
411  : public PP_LnPtr<T>
412 {
413 public:
414  //
415  ///: The default constructor. The wrapped pointer is null.
416  //
417  PP_LnClassPtr ();
418  //
419  ///: Construct a PP_LnPtr<T> setting the wrapped pointer to rhs.
420  //
421  /*explicit*/ PP_LnClassPtr (T* rhs);
422 
423  /**: The copy assignment operator. The contained pointer is set
424  to the one wrapped by rhs. The reference count is decremented
425  on this object and the reference count is incremented for
426  the newly wrapped pointer.
427  */
428  PP_LnClassPtr<T>& operator= (const PP_LnClassPtr<T>& rhs);
429 
430  /**: Sets the wrapped pointer to rhs. Decrements the count
431  on the previously wrapped pointer and deletes it if there
432  was only one reference.
433  */
434  PP_LnClassPtr<T>& operator= (T* rhs);
435  //
436  ///: Applies operator-> to the wrapped pointer.
437  //
438  T* operator->() const;
439 };
440 
441 //
442 // Inlines.
443 //
444 
445 template <class T>
446 inline
447 PP_CpPtr<T>::PP_CpPtr ()
448  :
449  ptr(0)
450 {
451 }
452 
453 template <class T>
454 inline
455 PP_CpPtr<T>::PP_CpPtr(T* rhs)
456  :
457  ptr(rhs)
458 {
459 }
460 
461 template <class T>
462 inline
463 PP_CpPtr<T>::~PP_CpPtr()
464 {
465  delete ptr;
466 }
467 
468 template <class T>
469 inline
470 bool
471 PP_CpPtr<T>::isNull () const
472 {
473  return ptr == 0;
474 }
475 
476 template <class T>
477 inline
478 PP_CpPtr<T>::PP_CpPtr (const PP_CpPtr<T>& rhs)
479 {
480  ptr = rhs.isNull() ? 0 : new T(*rhs.ptr);
481 }
482 
483 template <class T>
484 inline
485 PP_CpPtr<T>&
486 PP_CpPtr<T>::operator= (const PP_CpPtr<T>& rhs)
487 {
488  if (!(ptr == rhs.ptr))
489  {
490  delete ptr;
491  ptr = rhs.isNull() ? 0 : new T(*rhs.ptr);
492  }
493  return *this;
494 }
495 
496 template <class T>
497 inline
498 PP_CpPtr<T>&
499 PP_CpPtr<T>::operator= (T* rhs)
500 {
501  delete ptr;
502  ptr = rhs;
503  return *this;
504 }
505 
506 template <class T>
507 inline
508 T&
510 {
511  CH_assert(ptr != 0);
512  return *ptr;
513 }
514 
515 template <class T>
516 inline
517 T*
518 PP_CpPtr<T>::release ()
519 {
520  T* old = ptr;
521  ptr = 0;
522  return old;
523 }
524 
525 template <class T>
526 inline
527 bool
528 PP_CpPtr<T>::operator== (const PP_CpPtr<T>& rhs) const
529 {
530  return ptr == rhs.ptr;
531 }
532 
533 template <class T>
534 inline
535 bool
536 PP_CpPtr<T>::operator!= (const PP_CpPtr<T>& rhs) const
537 {
538  return ptr != rhs.ptr;
539 }
540 
541 template <class T>
542 inline
543 PP_CpClassPtr<T>::PP_CpClassPtr ()
544  :
545  PP_CpPtr<T>()
546 {
547 }
548 
549 template <class T>
550 inline
551 PP_CpClassPtr<T>::PP_CpClassPtr (T* rhs)
552  :
553  PP_CpPtr<T>(rhs)
554 {
555 }
556 
557 template <class T>
558 inline
559 PP_CpClassPtr<T>::PP_CpClassPtr (const PP_CpClassPtr<T>& rhs)
560  :
561  PP_CpPtr<T>(rhs)
562 {
563 }
564 
565 template <class T>
566 inline
567 PP_CpClassPtr<T>&
568 PP_CpClassPtr<T>::operator= (T* rhs)
569 {
570  PP_CpPtr<T>::operator= (rhs);
571  return *this;
572 }
573 
574 template <class T>
575 inline
576 PP_CpClassPtr<T>&
577 PP_CpClassPtr<T>::operator= (const PP_CpClassPtr<T>& rhs)
578 {
579  PP_CpPtr<T>::operator= (rhs);
580  return *this;
581 }
582 
583 template <class T>
584 inline
585 T*
586 PP_CpClassPtr<T>::operator-> () const
587 {
588  return this->ptr;
589 }
590 
591 template <class T>
592 inline
593 PP_LnPtr<T>::PP_LnPtr ()
594  :
595  ptr(0)
596 {
597 }
598 
599 template <class T>
600 inline
601 PP_LnPtr<T>::PP_LnPtr(T* rhs)
602  :
603  ptr(rhs)
604 {
605 }
606 
607 template <class T>
608 inline
609 bool
610 PP_LnPtr<T>::unique () const
611 {
612  return ucnt.unique();
613 }
614 
615 template <class T>
616 inline
617 PP_LnPtr<T>::~PP_LnPtr ()
618 {
619  if (ucnt.unique())
620  delete ptr;
621 }
622 
623 template <class T>
624 inline
625 PP_LnPtr<T>&
626 PP_LnPtr<T>::operator= (const PP_LnPtr<T>& rhs)
627 {
628  if (ptr != rhs.ptr)
629  {
630  if (unique())
631  delete ptr;
632  ptr = rhs.ptr;
633  ucnt = rhs.ucnt;
634  }
635  return *this;
636 }
637 
638 template <class T>
639 inline
640 int
641 PP_LnPtr<T>::linkCount () const
642 {
643  return ucnt.linkCount();
644 }
645 
646 template <class T>
647 inline
648 T&
650 {
651  CH_assert(ptr != 0);
652  return *ptr;
653 }
654 
655 template <class T>
656 inline
657 bool
658 PP_LnPtr<T>::isNull () const
659 {
660  return ptr == 0;
661 }
662 
663 template <class T>
664 inline
665 bool
666 PP_LnPtr<T>::operator== (const PP_LnPtr<T>& rhs) const
667 {
668  return ptr == rhs.ptr;
669 }
670 
671 template <class T>
672 inline
673 bool
674 PP_LnPtr<T>::operator!= (const PP_LnPtr<T>& rhs) const
675 {
676  return ptr != rhs.ptr;
677 }
678 
679 template <class T>
680 inline
681 PP_LnClassPtr<T>::PP_LnClassPtr ()
682 {
683 }
684 
685 template <class T>
686 inline
687 PP_LnClassPtr<T>::PP_LnClassPtr (T* rhs)
688  :
689  PP_LnPtr<T>(rhs)
690 {
691 }
692 
693 template <class T>
694 inline
695 PP_LnClassPtr<T>&
696 PP_LnClassPtr<T>::operator= (const PP_LnClassPtr<T>& rhs)
697 {
698  PP_LnPtr<T>::operator=(rhs);
699  return *this;
700 }
701 
702 template <class T>
703 inline
704 PP_LnClassPtr<T>&
705 PP_LnClassPtr<T>::operator= (T* rhs)
706 {
707  PP_LnPtr<T>::operator=(rhs);
708  return *this;
709 }
710 
711 template <class T>
712 inline
713 T*
714 PP_LnClassPtr<T>::operator->() const
715 {
716  return this->ptr;
717 }
718 
719 //
720 // Helper class for class PP_String.
721 //
722 
723 class PP_StringRep
724 {
725  friend class PP_String;
726  char* s;
727  int bufferlength;
728 public:
729  /*explicit*/ PP_StringRep (int _len = 0);
730  ~PP_StringRep ();
731  //
732  // Resized the buffer and copies the contents of old buffer to new one.
733  //
734  void resize (int n);
735 };
736 
737 //
738 // PP_StringRep inlines.
739 //
740 
741 inline
742 PP_StringRep::PP_StringRep (int _len)
743 {
744  bufferlength = _len;
745  s = new char [bufferlength];
746 }
747 
748 inline
749 PP_StringRep::~PP_StringRep ()
750 {
751  delete [] s;
752  s = 0;
753 }
754 
755 /// A String Class for ParmParse
756 /**
757 
758 The class PP_String is used to store and manipulate character strings. It
759 has an efficient underlying storage mechanism and some useful string
760 manipulation operations.
761 
762 The PP_String class is implemented using a character array and reference
763 count. Two PP_Strings may reference the same underlying character array with
764 a reference count of two. When an PP_String copy constructor or copy
765 operator is applied the reference count on the underlying character array
766 is incremented but the actual string is not copied. That is, copying an
767 PP_String is an inexpensive operation. When an PP_String is destructed, the
768 reference count is decremented. The underlying character array is deleted
769 only when the reference count goes to zero. Any operator that modifies an
770 PP_String will make its own copy of the character array before the
771 modification, unless it's the sole owner of the character array in the
772 PP_String.
773 
774 This is a convenience class for ParmParse
775 and will not be in any way supported by anyone at ANAG.
776 
777 */
778 
779 class PP_String
780 {
781 public:
782  //
783  ///: Constructs an empty string.
784  //
785  PP_String ();
786 
787  /**: Constructs an PP_String containing the single character c.
788  If c is the null character then this will be the empty string.
789  */
790  /*explicit*/ PP_String (char c);
791 
792  /**: Constructs an empty PP_String but allocates enough space to hold
793  a character string of length len. This may be useful when
794  reading in very long lines with the `getline' function; i.e.
795  it may be slightly more efficient to allocate a very large
796  PP_String once and then use `getline' than to use `getline'
797  on an empty string. In general though, you won't notice any
798  difference and you really shouldn't use this constructor.
799  */
800  /*explicit*/ PP_String (int len);
801 
802  /**: Constructs an PP_String initialized to the character string s.
803  It is an error is `s' is the null string.
804  */
805  PP_String (const char* s);
806  //
807  ///: The copy constructor.
808  //
809  PP_String (const PP_String& rhs);
810  //
811  ///: The assignment operator
812  //
813  PP_String& operator= (const PP_String& rhs);
814 
815  /**: Catenate PP_String right onto end of this PP_String. Return a
816  reference to self to allow for operator chaining.
817  */
818  PP_String& operator+= (const PP_String& right);
819 
820  /**: Catenate character string right onto end of this PP_String.
821  Returns a reference to self to allow for operator chaining.
822  It is an error is `right' is the null string.
823  */
824  PP_String& operator+= (const char* right);
825 
826  /**: Catenate character c onto end of this PP_String.
827  Returns a reference to self to allow for operator chaining.
828  This does nothing if c is the null character.
829  */
830  PP_String& operator+= (char c);
831 
832  /**: Converts all characters in this PP_String to upper case.
833  Returns a reference to self to allow for operator chaining.
834  */
835  PP_String& toUpper ();
836 
837  /**: Converts all characters in this PP_String to lower case.
838  Returns a reference to self to allow for operator chaining.
839  */
840  PP_String& toLower ();
841 
842  /**: Read the next line from the input stream strm and store it
843  as the value of the string. The delimiter for a line of text
844  is the newline character. The newline is extracted from the
845  istream, but it is NOT stored in the PP_String. There is no
846  limit to the length of string that can be extracted.
847  */
848  std::istream& getline (std::istream& strm);
849 
850  /**: Returns the number of characters stored in this PP_String.
851  This does not include the terminating null character.
852  */
853  int length () const;
854 
855  //
856  ///: Returns true if this is the null string.
857  //
858  bool isNull () const;
859 
860  /**: Returns a reference to the kth character in the string. An
861  error occurs if k < 0 or k >= length().
862  */
863  char& operator [] (int k);
864 
865  /**: Returns kth character in the string. An error occurs
866  if k < 0 or k >= length().
867  */
868  char operator[] (int k) const;
869 
870  /**: Convert an PP_String to a const char *. This allows an PP_String
871  to be used in any context where a const char* type is needed.
872  */
873  const char* c_str () const;
874 
875  /**: Returns the value of the string as a double. In the case
876  when the string is empty or when the initial characters
877  in the string are strictly alphabetic characters, this
878  returns zero. It's equivalent to `atof(c_str())'.
879  */
880  double toDouble () const;
881 
882  /**: Returns the value of the string as a integer. In the case
883  when the string is empty or when the initial characters
884  in the string are strictly alphabetic characters, this
885  returns zero. It's equivalent to `atoi(c_str())'.
886  */
887  int toInteger () const;
888 
889  /**: Returns the value of the string as a long. In the case
890  when the string is empty or when the initial characters
891  in the string are strictly alphabetic characters, this
892  returns zero. It's equivalent to `atol(c_str())'.
893  */
894  long toLong () const;
895  //
896  ///: Write to an ostream in ASCII format.
897  //
898  friend std::ostream& operator<< (std::ostream& os,
899  const PP_String& str);
900 
901  /**: Read a whitespace delimited string from an istream.
902  This function discards leading whitespace and then reads
903  in non-whitespace character until the next whitespace
904  character or end-of-file. Note that there is no limit,
905  on the length of the character that can be read in, except
906  that dictated by the resources of the machine.
907  Note also that operator>> and operator<< are not completely
908  symmetrical in the case where operator<< writes out a
909  string that contains whitespace. If you're trying to
910  read in a string that contains whitespace, you might
911  want to use getline() instead.
912  */
913  friend std::istream& operator>> (std::istream& is,
914  PP_String& str);
915 
916 protected:
917  void copyModify ();
918 
919 private:
920  PP_LnClassPtr<PP_StringRep> p;
921  int len;
922 
923  //
924  // None of the following functions need to be friends. I've made
925  // them friends solely so they'll show up nicely in the HTML documentaion
926  // spewed out by doc++.
927  //
928 
929  //
930  // Is left lexically less than right?
931  //
932  friend inline bool operator< (const PP_String& left,
933  const PP_String& right);
934  //
935  // Is left lexically less than or equal to right?
936  //
937  friend inline bool operator<= (const PP_String& left,
938  const PP_String& right);
939  //
940  // Is left not equal to right?
941  //
942  friend inline bool operator!= (const PP_String& left,
943  const PP_String& right);
944  //
945  // Is left equal to right?
946  //
947  friend inline bool operator== (const PP_String& left,
948  const PP_String& right);
949  //
950  // Is left lexically greater than or equal to right?
951  //
952  friend inline bool operator>= (const PP_String& left,
953  const PP_String& right);
954  //
955  // Is left lexically greater than right?
956  //
957  friend inline bool operator> (const PP_String& left,
958  const PP_String& right);
959  //
960  // Is left lexically less than right?
961  //
962  friend inline bool operator< (const PP_String& left,
963  const char* right);
964  //
965  // Is left lexically less than or equal to right?
966  //
967  friend inline bool operator<= (const PP_String& left,
968  const char* right);
969  //
970  // Is left not equal to right?
971  //
972  friend inline bool operator!= (const PP_String& left,
973  const char* right);
974  //
975  // Is left equal to right?
976  //
977  friend inline bool operator== (const PP_String& left,
978  const char* right);
979  //
980  // Is left lexically greater than or equal to right?
981  //
982  friend inline bool operator>= (const PP_String& left,
983  const char* right);
984  //
985  // Is left lexically greater than right?
986  //
987  friend inline bool operator> (const PP_String& left,
988  const char* right);
989  //
990  // Is left lexically less than right?
991  //
992  friend inline bool operator< (const char* left,
993  const PP_String& right);
994  //
995  // Is left lexically less than or equal to right?
996  //
997  friend inline bool operator<= (const char* left,
998  const PP_String& right);
999  //
1000  // Is left not equal to right?
1001  //
1002  friend inline bool operator!= (const char* left,
1003  const PP_String& right);
1004  //
1005  // Is left equal to right?
1006  //
1007  friend inline bool operator== (const char* left,
1008  const PP_String& right);
1009  //
1010  // Is left lexically greater than or equal to right?
1011  //
1012  friend inline bool operator>= (const char* left,
1013  const PP_String& right);
1014  //
1015  // Is left lexically greater than right?
1016  //
1017  friend inline bool operator> (const char* left,
1018  const PP_String& right);
1019 };
1020 
1021 //
1022 // PP_String inlines.
1023 //
1024 
1025 inline
1026 bool
1027 PP_String::isNull () const
1028 {
1029  return len == 0;
1030 }
1031 
1032 inline
1033 int
1034 PP_String::length () const
1035 {
1036  return len;
1037 }
1038 
1039 inline
1040 double
1041 PP_String::toDouble () const
1042 {
1043  return len == 0 ? 0 : std::atof(p->s);
1044 }
1045 
1046 inline
1047 int
1048 PP_String::toInteger () const
1049 {
1050  return len == 0 ? 0 : atoi(p->s);
1051 }
1052 
1053 inline
1054 long
1055 PP_String::toLong () const
1056 {
1057  return len == 0 ? 0 : atol(p->s);
1058 }
1059 
1060 inline
1061 const char*
1062 PP_String::c_str () const
1063 {
1064  return p->s;
1065 }
1066 
1067 inline
1068 char
1069 PP_String::operator[] (int index) const
1070 {
1071  CH_assert(index >=0 && index < len);
1072  return p->s[index];
1073 }
1074 
1075 inline
1076 PP_String
1077 operator+ (const PP_String& left,
1078  const PP_String& right)
1079 {
1080  PP_String result(left);
1081  return result += right;
1082 }
1083 
1084 inline
1085 bool
1086 operator< (const PP_String& left,
1087  const PP_String& right)
1088 {
1089  return ::strcmp(left.c_str(), right.c_str()) < 0;
1090 }
1091 
1092 inline
1093 bool
1094 operator<= (const PP_String& left,
1095  const PP_String& right)
1096 {
1097  return ::strcmp(left.c_str(), right.c_str()) <= 0;
1098 }
1099 
1100 inline
1101 bool
1102 operator!= (const PP_String& left,
1103  const PP_String& right)
1104 {
1105  return ::strcmp(left.c_str(), right.c_str()) != 0;
1106 }
1107 
1108 inline
1109 bool
1110 operator== (const PP_String& left,
1111  const PP_String& right)
1112 {
1113  return ::strcmp(left.c_str(), right.c_str()) == 0;
1114 }
1115 
1116 inline
1117 bool
1118 operator>= (const PP_String& left,
1119  const PP_String& right)
1120 {
1121  return ::strcmp(left.c_str(), right.c_str()) >= 0;
1122 }
1123 
1124 inline
1125 bool
1126 operator> (const PP_String& left,
1127  const PP_String& right)
1128 {
1129  return ::strcmp(left.c_str(), right.c_str()) > 0;
1130 }
1131 
1132 inline
1133 bool
1134 operator< (const PP_String& left,
1135  const char* right)
1136 {
1137  return ::strcmp(left.c_str(), right) < 0;
1138 }
1139 
1140 inline
1141 bool
1142 operator<= (const PP_String& left,
1143  const char* right)
1144 {
1145  return ::strcmp(left.c_str(), right) <= 0;
1146 }
1147 
1148 inline
1149 bool
1150 operator!= (const PP_String& left,
1151  const char* right)
1152 {
1153  return ::strcmp(left.c_str(), right) != 0;
1154 }
1155 
1156 inline
1157 bool
1158 operator== (const PP_String& left,
1159  const char* right)
1160 {
1161  return ::strcmp(left.c_str(), right) == 0;
1162 }
1163 
1164 inline
1165 bool
1166 operator>= (const PP_String& left,
1167  const char* right)
1168 {
1169  return ::strcmp(left.c_str(), right) >= 0;
1170 }
1171 
1172 inline
1173 bool
1174 operator> (const PP_String& left,
1175  const char* right)
1176 {
1177  return ::strcmp(left.c_str(), right) > 0;
1178 }
1179 
1180 inline
1181 bool
1182 operator< (const char* left,
1183  const PP_String& right)
1184 {
1185  return ::strcmp(left, right.c_str()) < 0;
1186 }
1187 
1188 inline
1189 bool
1190 operator<= (const char* left,
1191  const PP_String& right)
1192 {
1193  return ::strcmp(left, right.c_str()) <= 0;
1194 }
1195 
1196 inline
1197 bool
1198 operator!= (const char* left,
1199  const PP_String& right)
1200 {
1201  return ::strcmp(left, right.c_str()) != 0;
1202 }
1203 
1204 inline
1205 bool
1206 operator== (const char* left,
1207  const PP_String& right)
1208 {
1209  return ::strcmp(left, right.c_str()) == 0;
1210 }
1211 
1212 inline
1213 bool
1214 operator>= (const char* left,
1215  const PP_String& right)
1216 {
1217  return ::strcmp(left, right.c_str()) >= 0;
1218 }
1219 
1220 inline
1221 bool
1222 operator> (const char* left,
1223  const PP_String& right)
1224 {
1225  return ::strcmp(left, right.c_str()) > 0;
1226 }
1227 
1228 //#include <List.H>
1229 
1230 template <class T> class PP_ListLink;
1231 template <class T> class PP_ListIterator;
1232 template <class T> class PP_List;
1233 
1234 template <class T>
1235 class PP_ListLink
1236 {
1237 private:
1238  friend class PP_List<T>;
1239  friend class PP_ListIterator<T>;
1240 
1241  PP_ListLink (const T& _val,
1242  PP_ListLink<T>* _pre,
1243  PP_ListLink<T>* _suc)
1244  :
1245  val(_val),
1246  pre(_pre),
1247  suc(_suc)
1248  {}
1249 
1250 private:
1251  T val;
1252  PP_ListLink<T>* pre;
1253  PP_ListLink<T>* suc;
1254 };
1255 
1256 ///Iterate over a List for ParmParse
1257 /**
1258 
1259 The class PP_ListIterator<T> is an iterator over class PP_List<T>.
1260 
1261 This class does NOT provide a default constructor or an assignment operator.
1262 
1263 This is a convenience class for ParmParse
1264 and will not be in any way supported by anyone at ANAG.
1265 */
1266 
1267 template <class T>
1268 class PP_ListIterator
1269 {
1270 public:
1271  //
1272  ///: Construct a PP_ListIterator<T> to first element of aList.
1273  //
1274  /*explicit*/ PP_ListIterator (const PP_List<T>& aList);
1275  //
1276  ///: The copy constructor.
1277  //
1278  PP_ListIterator (const PP_ListIterator<T>& rhs);
1279 
1280  /**: Reset this PP_ListIterator<T> to point to the first element
1281  in the PP_List<T>.
1282  */
1283  void rewind ();
1284 
1285  /**: Return a constant reference to the object in the PP_List<T>
1286  currently pointed to by this PP_ListIterator<T>.
1287  */
1288  const T& operator() () const;
1289 
1290  /**: Return a constant reference to the object in the PP_List<T>
1291  currently pointed to by this PP_ListIterator<T>.
1292  */
1293  const T& operator* () const;
1294 
1295  /**: This is a conversion operator that makes the iterator look
1296  like a pointer. This operator makes it easy to check if the
1297  iterator is pointing to an element on the PP_List<T>. If the
1298  iterator has been moved off the PP_List<T> or if the PP_List<T> is
1299  empty, this conversion returns the NULL pointer.
1300  */
1301  operator void* ();
1302 
1303  /**: Returns true if PP_ListIterator<T> doesn't point to any
1304  element on the PP_List<T>.
1305  */
1306  bool operator! () const;
1307 
1308  /**: Return a constant reference to the object in the PP_List<T>
1309  currently pointed to by the iterator.
1310  */
1311  const T& value () const;
1312 
1313  /**: This is the prefix auto-increment operator. It advances the
1314  PP_ListIterator<T> to point to the next element on the PP_List<T>.
1315  It then returns a reference to itself to allow for chaining
1316  with other operators.
1317  */
1318  PP_ListIterator<T>& operator++ ();
1319 
1320  /**: This is the prefix auto-decrement operator. It moves the
1321  PP_ListIterator<T> to point to the previous element on the
1322  PP_List<T>. It then returns a reference to itself to allow for
1323  chaining with other operators.
1324  */
1325  PP_ListIterator<T>& operator-- ();
1326 
1327  /**: This is the postfix auto-decrement operator. It moves the
1328  PP_ListIterator<T> to point to the previous element on the
1329  PP_List<T>. It then returns a PP_ListIterator<T> that points to
1330  the old element to allow for chaining with other operators.
1331 
1332  */
1333  PP_ListIterator<T> operator-- (int);
1334 
1335  /**: This is the postfix auto-increment operator. It advances the
1336  PP_ListIterator<T> to point to the next element on the PP_List<T>.
1337  It then returns a PP_ListIterator<T> that points to the old
1338  element to allow for chaining with other operators.
1339  */
1340  PP_ListIterator<T> operator++ (int);
1341 
1342  /**: Do the two PP_ListIterator<T>s point to the same PP_List<T> and
1343  the same element within the PP_List<T>?
1344  */
1345  bool operator== (const PP_ListIterator<T>&) const;
1346  //
1347  ///: Are the PP_ListIterator<T>s not equal?
1348  //
1349  bool operator!= (const PP_ListIterator<T>&) const;
1350 
1351 protected:
1352  //
1353  // Construct a PP_ListIterator<T> to a PP_List<T> and object in that PP_List<T>.
1354  //
1355  PP_ListIterator (const PP_List<T>& _list,
1356  PP_ListLink<T>* _p);
1357  //
1358  // A reference to the PP_List<T> to which we point.
1359  //
1360  const PP_List<T>& list;
1361  //
1362  // A pointer to the element in the PP_List<T> to which we point.
1363  //
1364  PP_ListLink<T>* p;
1365 
1366 private:
1367  friend class PP_List<T>;
1368  //
1369  // These are disallowed.
1370  //
1371  PP_ListIterator ();
1372  PP_ListIterator<T>& operator= (const PP_ListIterator<T>&);
1373 };
1374 
1375 /// A Doubly-Linked List for ParmParse
1376 /**
1377 
1378 The PP_List<T> class is a template class that implements a doubly-linked list
1379 of objects. A PP_List<T> is a useful container class when the number of
1380 objects in the collection is not known ahead of time. A PP_List<T> can
1381 contain an arbitrary number of elements; operations such as insertion,
1382 deletion, and catenation are easily implemented and inexpensive.
1383 
1384 The only difficulty when defining a list class is devising a mechanism to
1385 access the elements. In an array, an element is accessed using an
1386 integer index. Since the elements in a PP_List<T> are ordered by position,
1387 we could define an integer indexing operation that walks along the
1388 PP_List<T> links from the beginning until the numbered element is found.
1389 Unfortunately, this would be very inefficient when accessing elements near
1390 the end of a long list. Another solution is to allow user access to the
1391 individual link objects that contain the element as well as the forward and
1392 backward pointers. This is not a satisfactory solution since it allows
1393 user access to the internal representation of the class. The solution
1394 chosen is to define a PP_ListIterator<T> template class.
1395 
1396 Think of a PP_ListIterator<T> as a pointer to an object in the PP_List<T>. You
1397 can access the element currently pointed to by the iterator, move the
1398 iterator forward and backward through the PP_List<T>, and use it as a
1399 mechanism to define where elements should be inserted and deleted. If the
1400 iterator is moved off the end of the list it behaves as a null pointer.
1401 
1402 This is a concrete class, not a polymorphic one.
1403 
1404 This is a convenience class for ParmParse
1405 and will not be in any way supported by anyone at ANAG.
1406 */
1407 
1408 template <class T>
1409 class PP_List
1410 {
1411 public:
1412  //
1413  ///: Construct an empty PP_List<T>.
1414  //
1415  PP_List ();
1416  //
1417  ///: The copy constructor.
1418  //
1419  PP_List (const PP_List<T>& rhs);
1420  //
1421  ///: The assignment operator.
1422  //
1423  PP_List<T>& operator= (const PP_List<T>& rhs);
1424  //
1425  ///: The destructor.
1426  //
1427  ~PP_List();
1428  //
1429  ///: Adds a copy of the value to the beginning of the PP_List<T>.
1430  //
1431  void prepend (const T& value);
1432  //
1433  ///: Adds a copy of the value to the end of the PP_List<T>.
1434  //
1435  void append (const T& value);
1436  //
1437  ///: Adds a copy of the value to the end of the PP_List<T>.
1438  //
1439  void add (const T& value);
1440  //
1441  ///: Appends a copy of all items in PP_List<T> src to this PP_List<T>.
1442  //
1443  void join (const PP_List<T>& src);
1444 
1445  /**: Appends a copy of all items in PP_List<T> src to this PP_List<T>.
1446  This differs from join() in that it unlinks the objects from
1447  the PP_List<T> src and glues them to the end of this PP_List<T>,
1448  leaving PP_List<T> src empty. This is more efficient that
1449  join() if src is no longer needed.
1450  */
1451  void catenate (PP_List<T>& src);
1452  //
1453  ///: Removes all objects from the PP_List<T>.
1454  //
1455  void clear ();
1456  //
1457  ///: Returns a reference to the first element in the PP_List<T>.
1458  //
1459  T& firstElement () const;
1460  //
1461  ///: Returns a reference to the last element in the PP_List<T>.
1462  //
1463  T& lastElement () const;
1464 
1465  /**: Returns true if the PP_List<T> contains an object identical
1466  to value. Type T must have an operator==() defined, or
1467  be an intrinsic type.
1468  */
1469  bool includes (const T& value) const;
1470 
1471  /**: Returns true if the this and rhs are memberwise equal;
1472  i.e. the two lists are the same size and each of the
1473  elements in the list compare equal. Type T must have an
1474  operator==() defined, or be an intrinsic type.
1475  */
1476  bool operator== (const PP_List<T>& rhs) const;
1477  //
1478  ///: Returns true if the this and rhs are not equal.
1479  //
1480  bool operator!= (const PP_List<T>& rhs) const;
1481  //
1482  ///: Returns true if the PP_List<T> is empty.
1483  //
1484  bool isEmpty () const;
1485  //
1486  ///: Returns true if the PP_List<T> is not empty.
1487  //
1488  bool isNotEmpty () const;
1489  //
1490  ///: Returns the number of objects in the PP_List<T>.
1491  //
1492  int length () const;
1493  //
1494  ///: Removes the first element in the PP_List<T>.
1495  //
1496  void removeFirst ();
1497  //
1498  ///: Removes the last element in the PP_List<T>.
1499  //
1500  void removeLast ();
1501  //
1502  ///: Returns reference to object pointed to by the PP_ListIterator<T>.
1503  //
1504  const T& operator[] (const PP_ListIterator<T>& li) const;
1505  //
1506  ///: Returns reference to object pointed to by the PP_ListIterator<T>.
1507  //
1508  T& operator[] (const PP_ListIterator<T>& li);
1509  //
1510  ///: Removes all objects in the PP_List<T> equal to value.
1511  //
1512  void remove (const T& value);
1513 
1514  /**: Removes all objects in the PP_List<T> equal to any of the
1515  values in lst.
1516  */
1517  void remove (const PP_List<T>& lst);
1518  //
1519  ///: Removes the object pointed to by the PP_ListIterator<T>.
1520  //
1521  void remove (PP_ListIterator<T>& lit);
1522  //
1523  ///: Replace the value pointed to by the PP_ListIterator<T> by val.
1524  //
1525  void replace (PP_ListIterator<T>& li,
1526  const T& val);
1527 
1528  /**: Insert val into PP_List<T> after the object pointed to by
1529  PP_ListIterator<T>.
1530  */
1531  void addAfter (PP_ListIterator<T>& lit,
1532  const T& val);
1533 
1534  /**: Insert val into PP_List<T> before the object pointed to by
1535  PP_ListIterator<T>.
1536  */
1537  void addBefore (PP_ListIterator<T>& lit,
1538  const T& val);
1539  //
1540  ///: Returns a PP_ListIterator<T> to the first object in this PP_List<T>.
1541  //
1542  PP_ListIterator<T> first () const;
1543  //
1544  ///: Returns a PP_ListIterator<T> to the last object in this PP_List<T>.
1545  //
1546  PP_ListIterator<T> last () const;
1547 
1548 protected:
1549  //
1550  // A helper function for removing nodes.
1551  //
1552  void remove (PP_ListLink<T> *ln);
1553  //
1554  // A helper function for adding nodes.
1555  //
1556  PP_ListLink<T>* addBefore (PP_ListLink<T>* ln,
1557  const T& val);
1558  //
1559  // A helper function for adding nodes.
1560  //
1561  PP_ListLink<T>* addAfter (PP_ListLink<T>* ln,
1562  const T& val);
1563  //
1564  // The head of the list.
1565  //
1566  PP_ListLink<T>* head;
1567  //
1568  // The tail of the list.
1569  //
1570  PP_ListLink<T>* tail;
1571  //
1572  // Our good and trusted friend.
1573  //
1574  friend class PP_ListIterator<T>;
1575 };
1576 
1577 //
1578 // Inlines.
1579 //
1580 
1581 //
1582 // The ListIterator stuff.
1583 //
1584 
1585 template <class T>
1586 inline
1587 PP_ListIterator<T>::PP_ListIterator (const PP_List<T>& _list,
1588  PP_ListLink<T>* _p)
1589  :
1590  list(_list),
1591  p(_p)
1592 {
1593 }
1594 
1595 template <class T>
1596 inline
1597 PP_ListIterator<T>::PP_ListIterator (const PP_List<T>& aList)
1598  :
1599  list(aList)
1600 {
1601  p = list.head;
1602 }
1603 
1604 template <class T>
1605 inline
1606 PP_ListIterator<T>::PP_ListIterator (const PP_ListIterator<T>& li)
1607  :
1608  list(li.list),
1609  p(li.p)
1610 {
1611 }
1612 
1613 template <class T>
1614 inline
1615 void
1616 PP_ListIterator<T>::rewind ()
1617 {
1618  p = list.head;
1619 }
1620 
1621 template <class T>
1622 inline
1623 const T&
1624 PP_ListIterator<T>::operator() () const
1625 {
1626  CH_assert(p != 0);
1627  return p->val;
1628 }
1629 
1630 template <class T>
1631 inline
1632 const T&
1634 {
1635  CH_assert(p != 0);
1636  return p->val;
1637 }
1638 
1639 template <class T>
1640 inline
1641 PP_ListIterator<T>::operator void* ()
1642 {
1643  return p != 0 ? this : 0;
1644 }
1645 
1646 template <class T>
1647 inline
1648 bool
1649 PP_ListIterator<T>::operator! () const
1650 {
1651  return p == 0 ? true : false;
1652 }
1653 
1654 template <class T>
1655 inline
1656 const T&
1657 PP_ListIterator<T>::value () const
1658 {
1659  CH_assert(p != 0);
1660  return p->val;
1661 }
1662 
1663 template <class T>
1664 inline
1665 PP_ListIterator<T>&
1666 PP_ListIterator<T>::operator++ ()
1667 {
1668  if (p)
1669  p = p->suc;
1670  return *this;
1671 }
1672 
1673 template <class T>
1674 inline
1675 PP_ListIterator<T>&
1676 PP_ListIterator<T>::operator-- ()
1677 {
1678  if (p)
1679  p = p->pre;
1680  return *this;
1681 }
1682 
1683 template <class T>
1684 inline
1685 PP_ListIterator<T>
1686 PP_ListIterator<T>::operator++ (int)
1687 {
1688  const PP_ListIterator<T> li = *this;
1689  ++(*this);
1690  return li;
1691 }
1692 
1693 template <class T>
1694 inline
1695 PP_ListIterator<T>
1696 PP_ListIterator<T>::operator-- (int)
1697 {
1698  const PP_ListIterator<T> li = *this;
1699  --(*this);
1700  return li;
1701 }
1702 
1703 template <class T>
1704 inline
1705 bool
1706 PP_ListIterator<T>::operator== (const PP_ListIterator<T>& _li) const
1707 {
1708  return (&list == &_li.list && p == _li.p) ? true : false;
1709 }
1710 
1711 template <class T>
1712 inline
1713 bool
1714 PP_ListIterator<T>::operator!= (const PP_ListIterator<T>& _li) const
1715 {
1716  return ! PP_ListIterator<T>::operator==(_li);
1717 }
1718 
1719 //
1720 // List stuff.
1721 //
1722 
1723 template <class T>
1724 inline
1725 PP_List<T>::PP_List ()
1726  :
1727  head(0),
1728  tail(0)
1729 {
1730 }
1731 
1732 template <class T>
1733 inline
1734 PP_List<T>::~PP_List ()
1735 {
1736  clear();
1737 }
1738 
1739 template <class T>
1740 inline
1741 void
1742 PP_List<T>::prepend (const T& value)
1743 {
1744  addBefore(head, value);
1745 }
1746 
1747 template <class T>
1748 inline
1749 void
1750 PP_List<T>::append (const T& value)
1751 {
1752  addAfter(tail, value);
1753 }
1754 
1755 template <class T>
1756 inline
1757 T&
1758 PP_List<T>::firstElement () const
1759 {
1760  CH_assert(head != 0);
1761  return head->val;
1762 }
1763 
1764 template <class T>
1765 inline
1766 T&
1767 PP_List<T>::lastElement () const
1768 {
1769  CH_assert(tail != 0);
1770  return tail->val;
1771 }
1772 
1773 template <class T>
1774 inline
1775 bool
1776 PP_List<T>::isEmpty () const
1777 {
1778  return head == 0 && tail == 0;
1779 }
1780 
1781 template <class T>
1782 inline
1783 bool
1784 PP_List<T>::isNotEmpty () const
1785 {
1786  return !isEmpty();
1787 }
1788 
1789 template <class T>
1790 inline
1791 void
1792 PP_List<T>::removeFirst ()
1793 {
1794  remove(head);
1795 }
1796 
1797 template <class T>
1798 inline
1799 void
1800 PP_List<T>::removeLast ()
1801 {
1802  remove(tail);
1803 }
1804 
1805 template <class T>
1806 inline
1807 const T&
1808 PP_List<T>::operator[] (const PP_ListIterator<T>& li) const
1809 {
1810  CH_assert(li.p != 0);
1811  return li.p->val;
1812 }
1813 
1814 template <class T>
1815 inline
1816 T&
1817 PP_List<T>::operator[] (const PP_ListIterator<T>& li)
1818 {
1819  CH_assert(li.p != 0);
1820  return li.p->val;
1821 }
1822 
1823 template <class T>
1824 inline
1825 void
1826 PP_List<T>::replace (PP_ListIterator<T>& li,
1827  const T& _val)
1828 {
1829  CH_assert(li.p != 0);
1830  li.p->val = _val;
1831 }
1832 
1833 template <class T>
1834 inline
1835 void
1836 PP_List<T>::addAfter (PP_ListIterator<T>& lit,
1837  const T& val)
1838 {
1839  addAfter(lit.p, val);
1840 }
1841 
1842 template <class T>
1843 inline
1844 void
1845 PP_List<T>::addBefore (PP_ListIterator<T>& lit,
1846  const T& val)
1847 {
1848  addBefore(lit.p, val);
1849 }
1850 
1851 template <class T>
1852 inline
1853 PP_ListIterator<T>
1854 PP_List<T>::first () const
1855 {
1856  return PP_ListIterator<T>(*this,head);
1857 }
1858 
1859 template <class T>
1860 inline
1861 PP_ListIterator<T>
1862 PP_List<T>::last () const
1863 {
1864  return PP_ListIterator<T>(*this,tail);
1865 }
1866 
1867 //
1868 // List members
1869 //
1870 
1871 template <class T>
1872 inline
1873 PP_List<T>::PP_List (const PP_List<T>& source)
1874  :
1875  head(0),
1876  tail(0)
1877 {
1878  if (source.isEmpty())
1879  tail = head = 0;
1880  else
1881  for (PP_ListIterator<T> li(source); li; ++li)
1882  append(li());
1883 }
1884 
1885 //
1886 // This isn't inlined as it's declared virtual.
1887 //
1888 
1889 template <class T>
1890 inline void
1891 PP_List<T>::add (const T& value)
1892 {
1893  append(value);
1894 }
1895 
1896 template <class T>
1897 inline
1898 int
1899 PP_List<T>::length () const
1900 {
1901  int len = 0;
1902  for (PP_ListIterator<T> li(*this); li; ++li)
1903  len++;
1904  return len;
1905 }
1906 
1907 template <class T>
1908 inline
1909 PP_List<T>&
1910 PP_List<T>::operator= (const PP_List<T>& source)
1911 {
1912  if (!(this == &source))
1913  {
1914  clear();
1915  for (PP_ListIterator<T> li(source); li; ++li)
1916  append(li());
1917  }
1918  return *this;
1919 }
1920 
1921 template <class T>
1922 inline PP_ListLink<T> *
1923 PP_List<T>::addBefore (PP_ListLink<T>* ln,
1924  const T& val)
1925 {
1926  CH_assert(ln != 0 || head == 0);
1927 
1928  PP_ListLink<T>* newlink;
1929 
1930  if (ln == head)
1931  {
1932  head = newlink = new PP_ListLink<T>(val, 0, head);
1933 
1934  if (tail == 0)
1935  tail = head;
1936  else
1937  head->suc->pre = newlink;
1938  }
1939  else
1940  {
1941  newlink = new PP_ListLink<T>(val, ln->pre, ln);
1942 
1943  ln->pre->suc = newlink;
1944  ln->pre = newlink;
1945  }
1946 
1947  return newlink;
1948 }
1949 
1950 template <class T>
1951 inline
1952 PP_ListLink<T>*
1953 PP_List<T>::addAfter (PP_ListLink<T>* ln,
1954  const T& val)
1955 {
1956  CH_assert(ln != 0 || tail == 0);
1957 
1958  PP_ListLink<T>* newlink;
1959 
1960  // trying this here to satisfy icc -O2 (ndk)
1961  // this worked for me -- but since we aren't actively using icc, i'll
1962  // leave it commented.
1963  //newlink = new PP_ListLink<T>(val,tail,0);
1964  //delete newlink;
1965 
1966  if (ln == tail)
1967  {
1968  tail = newlink = new PP_ListLink<T>(val,tail,0);
1969 
1970  if (head == 0)
1971  head = tail;
1972  else
1973  tail->pre->suc = newlink;
1974  }
1975  else
1976  {
1977  newlink = new PP_ListLink<T>(val, ln, ln->suc);
1978 
1979  ln->suc->pre = newlink;
1980  ln->suc = newlink;
1981  }
1982 
1983  return newlink;
1984 }
1985 
1986 template <class T>
1987 inline void
1988 PP_List<T>::join (const PP_List<T>& list2)
1989 {
1990  for (PP_ListIterator<T> li2(list2); li2; ++li2)
1991  append(li2());
1992 }
1993 
1994 template <class T>
1995 inline void
1996 PP_List<T>::catenate (PP_List<T>& list2)
1997 {
1998  if (list2.isEmpty())
1999  //
2000  // Do nothing.
2001  //
2002  ;
2003  else if (isEmpty())
2004  {
2005  head = list2.head;
2006  tail = list2.tail;
2007  list2.head = 0;
2008  list2.tail = 0;
2009  }
2010  else
2011  {
2012  tail->suc = list2.head;
2013  list2.head->pre = tail;
2014  tail = list2.tail;
2015  list2.head = 0;
2016  list2.tail = 0;
2017  }
2018 }
2019 
2020 template <class T>
2021 inline void
2022 PP_List<T>::clear ()
2023 {
2024  PP_ListLink<T>* next = 0;
2025 
2026  for (PP_ListLink<T>* p = head; p != 0; p = next)
2027  {
2028  next = p->suc;
2029  p->suc = 0;
2030  delete p;
2031  }
2032  tail = head = 0;
2033 }
2034 
2035 template <class T>
2036 inline bool
2037 PP_List<T>::includes (const T& v) const
2038 {
2039  bool rc = false;
2040  for (PP_ListIterator<T> li(*this); li && !rc; ++li)
2041  if (v == li())
2042  rc = true;
2043  return rc;
2044 }
2045 
2046 template<class T>
2047 inline bool
2048 PP_List<T>::operator== (const PP_List<T>& rhs) const
2049 {
2050  if (length() == rhs.length())
2051  {
2052  for (PP_ListIterator<T> li(*this), ri(rhs); li; ++li, ++ri)
2053  if (li() != ri())
2054  return false;
2055  return true;
2056  }
2057 
2058  return false;
2059 }
2060 
2061 template<class T>
2062 inline bool
2063 PP_List<T>::operator!= (const PP_List<T>& rhs) const
2064 {
2065  return !operator==(rhs);
2066 }
2067 
2068 template <class T>
2069 inline void
2070 PP_List<T>::remove (PP_ListIterator<T>& li)
2071 {
2072  PP_ListLink<T> *np = li.p->suc;
2073  remove(li.p);
2074  li.p = np;
2075 }
2076 
2077 template <class T>
2078 inline void
2079 PP_List<T>::remove (const T& _v)
2080 {
2081  for (PP_ListIterator<T> litr(*this); litr; ++litr)
2082  if (litr() == _v)
2083  remove(litr);
2084 }
2085 
2086 template <class T>
2087 inline void
2088 PP_List<T>::remove (const PP_List<T>& _lv)
2089 {
2090  for (PP_ListIterator<T> litr(_lv); litr; ++litr)
2091  remove(litr());
2092 }
2093 
2094 template <class T>
2095 inline void
2096 PP_List<T>::remove (PP_ListLink<T>* ln)
2097 {
2098  CH_assert(head !=0 && tail != 0);
2099 
2100  if (head == ln && tail == ln)
2101  head = tail = 0;
2102  else if (head == ln)
2103  {
2104  CH_assert(ln->pre == 0);
2105  head = ln->suc;
2106  head->pre = 0;
2107  }
2108  else if (tail == ln)
2109  {
2110  CH_assert(ln->suc == 0);
2111  tail = ln->pre;
2112  tail->suc = 0;
2113  }
2114  else
2115  {
2116  CH_assert(ln->suc != 0 && ln->pre != 0);
2117  ln->suc->pre = ln->pre;
2118  ln->pre->suc = ln->suc;
2119  }
2120  delete ln;
2121  ln = 0;
2122 }
2123 
2124 template <class T> class PP_Array;
2125 
2126 /// An Array of Objects of Type T for ParmParse
2127 /**
2128 
2129 This class implements an array of objects of the parameterized type
2130 T. In contrast with the predefined C++ array type, an `PP_Array<T>'
2131 object knows its length, can be dynamically resized, and provides
2132 automatic bounds checking. The bounds checking can be turned off by
2133 specifying the -DNDEBUG flag on the command line when compiling the
2134 BOXLIB library. The main reason for defining the PP_Array class is that
2135 it is used, either by composition or inheritance, to implement many of
2136 the other classes in the BOXLIB library.
2137 
2138 The `PP_Array<T>' class works by storing copies of the objects it
2139 contains. If the objects are large, such as `FARRAYBOX's it is
2140 probably better to use the `PArray' class which is an array class that
2141 stores pointers to the objects (avoiding expensive copies).
2142 The `PP_Array<T>' class destructs all objects in the array when it is
2143 itself destructed. If this is not the desired action, the `PArray' class
2144 should be used.
2145 
2146 In the PP_Array<T> class, there are two different concepts of size: the amount
2147 of space allocated, and the amount of space actually used. Obviously, the
2148 allocated space must be larger than the used space. We separate these two
2149 concepts to allow the user to optionally avoid memory allocation costs.
2150 Rather than construct and destroy a temporary PP_Array<T> many times, it may
2151 be less expensive to allocate it once with enough memory to handle all uses,
2152 and resize the PP_Array<T> for each particular use. See the member functions
2153 `reserve', `shrinkWrap', and `resize'.
2154 
2155 Note that care must be taken when deriving classes from `PP_Array<T>'. It is
2156 a concrete class, not a polymorphic one.
2157 
2158 This class does NOT provide an assignment operator for assigning an integer
2159 to an PP_Array<T>.
2160 
2161 This is a convenience class for ParmParse
2162 and will not be in any way supported by anyone at ANAG.
2163 */
2164 
2165 template <class T>
2166 class PP_Array
2167 {
2168 public:
2169  //
2170  ///: Constructs an `PP_Array<T>' with no elements
2171  //
2172  PP_Array ();
2173 
2174  /**: Constructs an `PP_Array<T>' of length len with the value of each
2175  element defined by the default constructor for `T'.
2176  */
2177  /*explicit*/ PP_Array (long len);
2178 
2179  /**: Constructs an `PP_Array<T>' of length len with the value of each
2180  elements given by initialvalue.
2181  */
2182  PP_Array (long len,
2183  const T& initialvalue);
2184 
2185  /**: Constructs an `PP_Array<T>' of length len in which the K'th
2186  value is a copy of vec[K].
2187  */
2188  PP_Array (const T* vec,
2189  long len);
2190  //
2191  ///: The copy constructor.
2192  //
2193  PP_Array (const PP_Array<T>& rhs);
2194 
2195  /**: This operator deletes the current `PP_Array<T>' and replaces it
2196  with a copy of rhs.
2197  */
2198  PP_Array<T>& operator= (const PP_Array<T>& rhs);
2199  //
2200  ///: Deletes the `PP_Array<T>' and all objects it contains.
2201  //
2202  ~PP_Array ();
2203 
2204  /**: Destructs each element in this `PP_Array<T>'. The resulting array
2205  has length zero.
2206  */
2207  void clear ();
2208  //
2209  ///: Returns true if this `PP_Array<T>' is not empty.
2210  //
2211  bool ready () const;
2212 
2213  /**: Reserve space for future expansion of memory. You still must
2214  `resize' to address the memory.
2215  */
2216  void reserve (long _truesize);
2217 
2218  /**: Shrink allocated memory to be just enough for elements in
2219  PP_Array. This is useful if you allocated a lot of memory to
2220  avoid memory allocation delays as you add elements. Once all
2221  the elements are added, you can reduce memory usage to
2222  the minimum by calling this function.
2223  */
2224  void shrinkWrap ();
2225 
2226  /**: This function changes the size of this `PP_Array<T>' to newlen
2227  while preserving the value of as many array elements as
2228  possible. If newlen is greater than the current length, the
2229  array is grown and the new elements have the value given by
2230  the default constructor for `T'. If newlen is less than the
2231  current length the array is cropped with the remaining
2232  elements retaining their original values.
2233  */
2234  void resize (long newlen);
2235 
2236  /**: This function changes the size of this `PP_Array<T>' to newlen
2237  while preserving the value of as many array elements as
2238  possible. If newlen is greater than the current length, the
2239  array is grown and the new elements have the value given by
2240  initialvalue. If newlen is less than the current length the
2241  array is cropped with the remaining elements retaining their
2242  original values.
2243  */
2244  void resize (long newlen,
2245  const T& initialvalue);
2246  //
2247  ///: Return number of elements in the array.
2248  //
2249  long length () const;
2250 
2251  /**: Return the maximum number of elements the array can hold
2252  without doing a `resize'.
2253  */
2254  long trueSize () const;
2255 
2256  /**: Returns a reference to the K'th element in this `PP_Array<T>'.
2257  The element can be modified through this reference. The
2258  result can be used as an L-value.
2259  */
2260  T& operator[] (long K);
2261  //
2262  ///: Same as above, except acts on const PP_Array's.
2263  //
2264  const T& operator[] (long K) const;
2265  //
2266  ///: Different syntax for operator[] (long i).
2267  //
2268  T& get (long i);
2269  //
2270  ///: Different syntax for const operator[] (long i).
2271  //
2272  const T& get (long i) const;
2273 
2274  /**: Returns pointer to vector of data. This function breaks object
2275  encapsulation and should only be used for interfacing to
2276  Fortran subroutines.
2277  */
2278  T* dataPtr ();
2279  //
2280  ///: Same as above for constant PP_Arrays.
2281  //
2282  const T* dataPtr () const;
2283  //
2284  ///: Changes the i'th element of this `PP_Array<T>' to elem.
2285  //
2286  void set (long i,
2287  const T& elem);
2288  //
2289  ///: This function swaps the i'th and j'th element of the PP_Array.
2290  //
2291  void swap (long i,
2292  long j);
2293  //
2294  ///: Test for equality.
2295  //
2296  bool operator== (const PP_Array<T>& rhs) const;
2297  //
2298  ///: Test for inequality.
2299  //
2300  bool operator!= (const PP_Array<T>& rhs) const;
2301 
2302 protected:
2303  //
2304  // The true size of the PP_Array.
2305  //
2306  long truesize;
2307  //
2308  // The number of elements in the PP_Array.
2309  //
2310  long nelem;
2311  //
2312  // The array itself.
2313  //
2314  T* vp;
2315 
2316 private:
2317  //
2318  // This is disallowed.
2319  //
2320  PP_Array<T>& operator= (int);
2321 };
2322 
2323 //
2324 // Inlines.
2325 //
2326 
2327 template <class T>
2328 inline
2329 PP_Array<T>::PP_Array ()
2330 {
2331  nelem = 0;
2332  vp = new T[1];
2333  truesize = 1;
2334 }
2335 
2336 template <class T>
2337 inline
2338 PP_Array<T>::PP_Array (long len)
2339 {
2340  CH_assert(len >= 0);
2341  nelem = len;
2342  vp = new T[len];
2343  truesize = nelem;
2344 }
2345 
2346 template <class T>
2347 inline
2348 void
2349 PP_Array<T>::clear ()
2350 {
2351  delete [] vp;
2352  vp = 0;
2353  nelem = 0;
2354  truesize = 0;
2355 }
2356 
2357 template <class T>
2358 inline
2359 PP_Array<T>::~PP_Array ()
2360 {
2361  clear();
2362 }
2363 
2364 template <class T>
2365 inline
2366 bool
2367 PP_Array<T>::ready () const
2368 {
2369  return vp != 0 && nelem != 0;
2370 }
2371 
2372 template <class T>
2373 inline
2374 long
2375 PP_Array<T>::length () const
2376 {
2377  return nelem;
2378 }
2379 
2380 template <class T>
2381 inline
2382 long
2383 PP_Array<T>::trueSize () const
2384 {
2385  return truesize;
2386 }
2387 
2388 template <class T>
2389 inline
2390 T&
2391 PP_Array<T>::operator[] (long i)
2392 {
2393  CH_assert(vp != 0);
2394  CH_assert(i >= 0 && i < nelem);
2395  return vp[i];
2396 }
2397 
2398 template <class T>
2399 inline
2400 const T&
2401 PP_Array<T>::operator[] (long i) const
2402 {
2403  CH_assert(vp != 0);
2404  CH_assert(i >= 0 && i < nelem);
2405  return vp[i];
2406 }
2407 
2408 template <class T>
2409 inline
2410 T&
2411 PP_Array<T>::get (long i)
2412 {
2413  CH_assert(vp != 0);
2414  CH_assert(i >= 0 && i < nelem);
2415  return vp[i];
2416 }
2417 
2418 template <class T>
2419 inline
2420 const T&
2421 PP_Array<T>::get (long i) const
2422 {
2423  CH_assert(vp != 0);
2424  CH_assert(i >= 0 && i < nelem);
2425  return vp[i];
2426 }
2427 
2428 template <class T>
2429 inline
2430 void
2431 PP_Array<T>::set (long i,
2432  const T& elem)
2433 {
2434  CH_assert(vp != 0);
2435  CH_assert(i >= 0 && i < nelem);
2436  vp[i] = elem;
2437 }
2438 
2439 template <class T>
2440 inline
2441 T*
2442 PP_Array<T>::dataPtr ()
2443 {
2444  return vp;
2445 }
2446 
2447 template <class T>
2448 inline
2449 const T*
2450 PP_Array<T>::dataPtr () const
2451 {
2452  return vp;
2453 }
2454 
2455 template <class T>
2456 inline
2457 void
2458 PP_Array<T>::swap (long i,
2459  long j)
2460 {
2461  CH_assert(i >= 0 && i < nelem);
2462  CH_assert(j >= 0 && j < nelem);
2463  T tmp = vp[i];
2464  vp[i] = vp[j];
2465  vp[j] = tmp;
2466 }
2467 
2468 template <class T>
2469 inline
2470 bool
2471 PP_Array<T>::operator!= (const PP_Array<T>& rhs) const
2472 {
2473  return !(operator==(rhs));
2474 }
2475 
2476 //
2477 // Non-inlined stuff.
2478 //
2479 
2480 template <class T>
2481 PP_Array<T>::PP_Array (long len,
2482  const T& initialValue)
2483 {
2484  CH_assert(len >= 0);
2485  nelem = len;
2486  vp = new T[len];
2487  truesize = nelem;
2488  for (long i = 0; i < nelem; ++i)
2489  vp[i] = initialValue;
2490 }
2491 
2492 template <class T>
2493 PP_Array<T>::PP_Array (const T* vec,
2494  long len)
2495 {
2496  CH_assert(len >= 0);
2497  nelem = len;
2498  vp = new T[len];
2499  truesize = nelem;
2500  for (long i = 0; i < nelem; ++i)
2501  vp[i] = vec[i];
2502 }
2503 
2504 template <class T>
2505 PP_Array<T>::PP_Array (const PP_Array<T>& a)
2506 {
2507  nelem = a.nelem;
2508  vp = new T[nelem];
2509  truesize = nelem;
2510  for (long i = 0; i < nelem; i++)
2511  vp[i] = a.vp[i];
2512 }
2513 
2514 template <class T>
2515 PP_Array<T>&
2516 PP_Array<T>::operator= (const PP_Array<T>& sa)
2517 {
2518  if (this != &sa)
2519  {
2520  clear();
2521  vp = new T[sa.nelem];
2522  nelem = sa.nelem;
2523  truesize = nelem;
2524  for (long i = 0; i < nelem; i++)
2525  vp[i] = sa.vp[i];
2526  }
2527  return *this;
2528 }
2529 
2530 template <class T>
2531 inline
2532 void
2533 PP_Array<T>::resize (long newlen)
2534 {
2535  if (newlen == nelem)
2536  return;
2537  if (newlen <= truesize)
2538  {
2539  nelem = newlen;
2540  return;
2541  }
2542  T* newvp = new T[newlen];
2543  long len = Min(newlen,nelem);
2544  for (long i = 0; i < len; i++)
2545  newvp[i] = vp[i];
2546  delete [] vp;
2547  vp = newvp;
2548  nelem = newlen;
2549  truesize = newlen;
2550 }
2551 
2552 template <class T>
2553 inline
2554 void PP_Array<T>::resize (long newlen,
2555  const T& initialValue)
2556 {
2557  if (newlen == nelem)
2558  return;
2559  if (newlen <= truesize)
2560  {
2561  for (long i = nelem; i < newlen; ++i)
2562  vp[i] = initialValue;
2563  nelem = newlen;
2564  return;
2565  }
2566  T* newvp = new T[newlen];
2567  long len = Min(newlen,nelem);
2568  long i;
2569  for (i = 0; i < len; i++)
2570  newvp[i] = vp[i];
2571  for (i = len; i < newlen; ++i)
2572  newvp[i] = initialValue;
2573  delete [] vp;
2574  vp = newvp;
2575  nelem = newlen;
2576  truesize = newlen;
2577 }
2578 
2579 template <class T>
2580 void
2581 PP_Array<T>::reserve (long _truesize)
2582 {
2583  if (_truesize > truesize)
2584  {
2585  T* newvp = new T[_truesize];
2586  for (long i = 0; i < nelem; i++)
2587  newvp[i] = vp[i];
2588  delete [] vp;
2589  vp = newvp;
2590  truesize = _truesize;
2591  }
2592 }
2593 
2594 template <class T>
2595 void
2596 PP_Array<T>::shrinkWrap ()
2597 {
2598  if (nelem != truesize)
2599  {
2600  T* newvp = new T[nelem];
2601  for (long i = 0; i < nelem; i++)
2602  newvp[i] = vp[i];
2603  delete [] vp;
2604  vp = newvp;
2605  truesize = nelem;
2606  }
2607 }
2608 
2609 template <class T>
2610 bool
2611 PP_Array<T>::operator== (const PP_Array<T>& rhs) const
2612 {
2613  if (length() != rhs.length())
2614  return false;
2615 
2616  for (long i = 0; i < length(); ++i)
2617  if (!((*this)[i] == rhs[i]))
2618  return false;
2619 
2620  return true;
2621 }
2622 
2623 // -----------------------------------------------------------------
2624 // ----------------------- COMMENTS -------------------------------
2625 // -----------------------------------------------------------------
2626 // The ParmParse class implements a simple database for the storage
2627 // and retrieval of command-line and input-file arguments. The
2628 // entries are stored in a static table in (name,value_list) pairs.
2629 //
2630 // The format of the input file is a series of OPTIONS and DEFINITIONS.
2631 //
2632 // An OPTION is an entry of the form: -<name> and has no associated list
2633 // of values. For example, the command line:
2634 // prog -verbose -no_opt
2635 // has two options: "verbose" and "no_opt".
2636 //
2637 // A DEFINITION is of the form <name> = <value> <value> ...
2638 // The equal sign is important since the list of values can span multiple
2639 // lines.
2640 //
2641 // Comments in an input file include all text from a '#' character to the
2642 // end of the line. Here is an example input file:
2643 //
2644 // -no_garbage # an OPTION
2645 // niter = 100 # niter is an integer
2646 // title = "Double Wammy" # example of a string with spaces
2647 // cell_size = 0.5 0.75 # cell spacing in each dimension
2648 // plot.var = Density 1 10 # a list of values
2649 // plot.var = Energy 5 12 # another list of values
2650 // bigarray = 1 2 3 4 5 6 7 8 # first part of array
2651 // 9 10 11 12 # continuation of bigarray
2652 // test = apple "boy blue" 10 20 30 40
2653 // FILE = prob_file # insert contents of this "prob_file" here
2654 //
2655 // The "FILE = <filename>" definition is special. Rather than just
2656 // adding this entry to the database, it reads the contents of <filename>
2657 // into the database.
2658 //
2659 // ParmParse stores all entries in a static table which is built the
2660 // first time a ParmParse object is constructed (usually in main()).
2661 // Subsequent invocations have access to this table.
2662 // A ParmParse constructor has an optional "prefix" argument that will
2663 // limit the searches to only those entries of the table with this prefix
2664 // in name. For example:
2665 // ParmParse pp("plot");
2666 // will find only those entries with name given by "plot.<string>".
2667 //
2668 // All values in the table are stored as strings. For example, the
2669 // values of "cell_size" in the above input file are stored as the
2670 // strings "0.5" and "0.75". These strings can be returned as either
2671 // string of numeric values by the query functions.
2672 // Character strings with spaces must be delimited by double quotes
2673 // in the input file but the quotes are stripped before they are entered
2674 // into the table. For example, 'title' in the above input file has a
2675 // single value, the string 'Double Wammy' (without the quotes).
2676 // Each value in the list associated with a definition can be referred to
2677 // by its index number. The index numbers start at 0 just like an array
2678 // in the C programming language. Consider the definition of "test" in
2679 // the above input file. The first value 'apple'is a string with index
2680 // 0. The second value 'boy blue' is a string with index 1. The
2681 // remaining four values are integers indexed 2, 3, 4, and 5.
2682 //
2683 // For a string value to represent an integer or float it must fit the
2684 // following regular experssion:
2685 // Sign ::= '+' | '-'
2686 // Digit ::= '0' | '1' | ... | '9'
2687 // Integer ::= [Sign]Digit+
2688 // Exp ::= ('e'|'E')Integer
2689 // Float ::= ( Integer[.Digit*][Exp] | [Integer].Digit+[Exp] )
2690 //
2691 // Where '+' indicates one or more occurences, '*' represents zero or
2692 // more occurences, '|' means one or the other and '[]' represents zero
2693 // or one occurence.
2694 //
2695 // Note that floats and doubles have the same string representation and
2696 // that the FORTRAN "double" exponent format is not supported.
2697 // That is, 1.0d+3 is not a valid representation of a floating point
2698 // number but that 1.0e+3 is acceptable.
2699 //
2700 // There are a host of functions allowing the user to query the database
2701 // and retrieve values. Here are some general rules about the names of
2702 // the member functions:
2703 //
2704 // * Functions with the string "get" in their names attempt to get a
2705 // value or an array of values from the table. They generate a
2706 // run-time error if they are not successful.
2707 //
2708 // * Functions with the string "query" in their names attempt to get a
2709 // value or an array of values from the table. They return the value 1
2710 // (true) if they are successful and 0 (false) if not.
2711 //
2712 // * Functions with the string "arr" in their names get an Array of
2713 // values from the given entry in the table. The array argument is
2714 // resized (if necessary) to hold all the values requested.
2715 //
2716 // * Functions without the string "arr" in their names get single
2717 // values from the given entry in the table.
2718 //
2719 // The following is a code sample showing how to use ParmParse:
2720 //
2721 // main(int argc, char **argv)
2722 // {
2723 // char* in_file_name = argv[1];
2724 // ParmParse pp(argc-2, argv+2, 0, in_file_name);
2725 //
2726 // // was the "-verbose" command line argument set?
2727 // int verbose = pp.contains("verbose");
2728 //
2729 // // Query table for value of "niter". If not in table
2730 // // then set to default value
2731 // if (!pp.query("niter",niter)) niter = 20;
2732 //
2733 // // read array of cell sizes if in table
2734 // std::vector<float> dx;
2735 // if (nx=pp.countval("cell_size")) {
2736 // // get nx values starting at index 0 and store in dx.
2737 // // dx is automatically resized here.
2738 // pp.getarr("cell_size",dx,0,nx);
2739 // }
2740 // }
2741 //
2742 // void do_graphics()
2743 // {
2744 // //
2745 // // Will only query entries with the "plot" prefix:
2746 // //
2747 // ParmParse pp("plot");
2748 // //
2749 // // Read all variables with "plot.var" keyword.
2750 // //
2751 // std::string var_name;
2752 // std::vector<int> range;
2753 // int num = pp.countname("var");
2754 // //
2755 // // Element 0 in list is a string.
2756 // //
2757 // pp.get("var",var_name,0);
2758 // //
2759 // // Elements 1 and 2 are integers.
2760 // // Note that "range" will be resized to hold 2 elements.
2761 // //
2762 // pp.getarr("var",range,1,2);
2763 // cout << "variable = " << var_name << "lo, hi = ",
2764 // << range[0] << " " << range[1] << endl;
2765 // }
2766 // -----------------------------------------------------------------
2767 // ----------------------- END COMMENTS ---------------------------
2768 // -----------------------------------------------------------------
2769 
2770 //
2771 // Forward reference to private class.
2772 //
2773 class PP_entry;
2774 
2775 #endif //for the doxygen thing
2776 
2777 /// Parse Parameters From Command Line and Input Files
2778 /**
2779 
2780 The ParmParse class is used to interpret parameters passed in to a program
2781 from the command line and an arbitrary collection of input files. The
2782 parameters are stored in static table that can be queried by any object
2783 of type ParmParse. A parameter can be either an "option" (usually
2784 specified on the command line) or a "definition". An option is of the form
2785 "-<name>" and is stored in the table without the hyphen. A definition is
2786 of the form "<name> = <value><value>...<value>". It is stored in the table
2787 as a name, value-list pair.
2788 
2789 In the following example, verbose and no_opt are stored in the table as
2790 options. niter is a definition with the single integer value 10; name is
2791 a definition with the string value "big code" and dx is a definition with
2792 the two floating point values 0.5 and 0.75.
2793 
2794 prog -verbose -no_opt niter = 10 name = "big code" dx = 0.5 0.75
2795 
2796 The ParmParse class has two constructors. The first is responsible for
2797 building the table and is usually called by the main routine of an
2798 application. It has arguments for the command line argc and argv parameters,
2799 as well as an optional filename argument for reading definitions from an
2800 input file. The table is built by reading the input file first (if it
2801 exists) with the command line arguments added to the end of the table.
2802 The order of a definition in the table is significant, so command line
2803 parameters can be used to override definitions in the input file. A
2804 definition of the explicit form: FILE=<filename> is not added to the table
2805 but is a directive to include the named file at that point in the table.
2806 
2807 The second constructor is generally used by other classes in the code. It
2808 permits access to the table via a large collection of query functions.
2809 Both constructors have an optional prefix argument that narrows the search
2810 to entries in the table with the same prefix. For example, let PlanR be a
2811 ParmParse object with code prefix "ope". PlanR.get("val",v) will look for
2812 an entry in the parameter list of the form: ope.val==<value>, and will
2813 reject all entries not starting with the correct code prefix.
2814 
2815 The query functions search the table for definition names that match a given
2816 string (and prefix) and return values from the corresponding value list.
2817 The values can be returned as ints, Array<int>s, floats, std::vector<float>s,
2818 doubles, std::vector<double>s, std::strings, or std::vector<std::sring>s. All values in the
2819 table are stored as PP_String objects, but if an int, float, or double is
2820 requested, the translation is done automatically. In the previous example,
2821 the value of niter could be returned as either an std::string, an int, a double,
2822 or a float. The values of dx can be returned as std::strings, floats, or
2823 doubles, but the value of name can be returned only as an std::string.
2824 
2825 Comments in an input file include all text from a `\#' character to the
2826 end of the line. Here is a sample input file:
2827 
2828 -no_garbage
2829 
2830 niter = 100
2831 
2832 title = "Double Wammy"
2833 
2834 cell_size = 0.5 0.75
2835 
2836 plot.var = Density 1 10
2837 
2838 plot.var = Energy 5 12
2839 
2840 bigarray = 1 2 3 4 5 6 7 8
2841 
2842 9 10 11 12
2843 
2844 test = apple "boy blue" 10 20 30 40
2845 
2846 FILE = prob_file
2847 */
2848 
2850 {
2851  friend class PP_entry;
2852 public:
2853 
2854  ///
2855  /** Construct an initial ParmParse object from the argc and argv
2856  passed in to main(). An error will be signalled if another
2857  ParmParse object currently exists. If parfile is specified,
2858  read the parameters in from that file first and then append
2859  those derived from argv to the table. If prefix is specified,
2860  load this string as the code prefix for this particular
2861  ParmParse object.
2862  */
2863  ParmParse (int argc,
2864  char** argv,
2865  const char* prefix = 0,
2866  const char* parfile = 0);
2867 
2868  /// Initialize after calling the default constructor.
2869  /** Same as the constructor with the same args.
2870  */
2871  void define (int argc,
2872  char** argv,
2873  const char* prefix = 0,
2874  const char* parfile = 0);
2875 
2876  /** Construct an additional ParmParse object sharing the same
2877  internal table as any other such objects in existence. If
2878  prefix is specified, load this string as the code prefix
2879  for this particular ParmParse object. If there are no other
2880  existing objects, this doesn't do anything, and define() must
2881  be called before the object can be used.
2882  */
2883  /*explicit*/ ParmParse (const char* prefix = 0);
2884 
2885  ///got sick of typing c_str()
2886  ParmParse(const std::string& a_string);
2887 
2888 
2889  /** The destructor. The internal static table will only be deleted
2890  if there are no other ParmParse objects in existence.
2891  */
2892  ~ParmParse();
2893 
2894  ///
2895  /**
2896  Returns true if name is in table.
2897  */
2898  bool contains (const char* name) const;
2899 
2900  ///
2901  /**
2902  Returns true if name is in table.
2903  */
2904  bool contains (const std::string& name) const;
2905 
2906 
2907  ///
2908  /**
2909  Returns true if name is part of an entry in table.
2910  (i.e. returns true if name = "name.this" and there
2911  is a "name.this.list")
2912  */
2913  bool looseContains (const char* name) const;
2914 
2915  ///
2916  /**
2917  Returns true if name is in table.
2918  */
2919  bool looseContains (const std::string& name) const;
2920 
2921 
2922  ///
2923  /** Returns the number of values associated with nth occurence of
2924  name (prepended with the prefix) in the table. n == -1 implies
2925  the last occurence.
2926  */
2927  int countval (const char* name,
2928  int n = -1) const;
2929 
2930  ///
2931  /** Returns the number of times the given name (prepended with
2932  prefix) appears in the table.
2933  */
2934  int countname (const char* name) const;
2935 
2936  ///
2937  /** Returns the number of times the given name (prepended with
2938  prefix) appears in the table.
2939  */
2940  int countname (const std::string& name) const;
2941 
2942  ///
2943  /**
2944  * Accessor for private method that adds parameters
2945  * to the global table (SWS-Tech-X Research)
2946  * e.g. parmParseObj.addEntries("tst_value = 2")
2947  */
2948  void addEntries (const std::string& strEntry)
2949  {
2950  int len = (int)strEntry.size() + 1;
2951  bldTable(strEntry.c_str(), len, table);
2952  }
2953 
2954  ///
2955  /**
2956  * Append input parameter pairs to ParmParse
2957  *
2958  * 1. convert value to string
2959  * 2. construct string line syntax for ParmParse
2960  * 3. use special public method in ParmParse.H
2961  *
2962  * @param varName parameter string name
2963  * @param varVal numerical value type
2964  */
2965  template <typename TYPE>
2966  void setVal (const std::string& varName, TYPE varVal)
2967  {
2968  std::string valStr =
2969  static_cast<std::ostringstream*>( &(std::ostringstream() << varVal) )->str();
2970  std::string inEntry = varName + " = " + valStr;
2971  addEntries(inEntry);
2972  }
2973 
2974  ///
2975  /**
2976  * Append input parameter pairs to ParmParse
2977  *
2978  * 1. convert value to string
2979  * 2. construct string line syntax for ParmParse
2980  * 3. use special public method in ParmParse.H
2981  *
2982  * @param varName parameter string name
2983  * @param varVal string value type
2984  */
2985  void setStr (const std::string& varName, std::string varVal)
2986  {
2987  std::string inEntry = varName + " = " + varVal;
2988  addEntries(inEntry);
2989  }
2990 
2991  ///
2992  /**
2993  Write the contents of the table in ASCII to the ostream.
2994  */
2995  void dumpTable (std::ostream& os) const;
2996 
2997  /// access single object
2998  /** Get the ival'th value of last occurrence of the requested name.
2999  If successful, the value is converted to an int and stored
3000  in reference ref. If the name does not exist or
3001  ival'th value does not exist, or if the printed representation
3002  of the value cannot be converted to an int, an error message is
3003  output and the program halts. Note that ival == 0 is the first
3004  value in the list.
3005  */
3006  void get (const char* name,
3007  int& ref,
3008  int ival=0) const;
3009 
3010  ///
3011  /** Get the ival'th value of last occurrence of the
3012  requested name. If successful, the value is converted
3013  to an int and stored in reference ref. Returns 1 if
3014  successful. Returns 0 if the name does not exist. If
3015  ival'th value does not exist, or if the printed
3016  representation of the value cannot be converted to an
3017  int, an error message is output and the program halts.
3018  Note that ival == 0 is the first value in the list.
3019  */
3020  int query (const char* name,
3021  int& ref,
3022  int ival=0) const;
3023 
3024  /// access single object
3025  /** Get the ival'th value of last occurrence of the requested name.
3026  If successful, the value is converted to a n unsigned long and stored
3027  in reference ref. If the name does not exist or
3028  ival'th value does not exist, or if the printed representation
3029  of the value cannot be converted to an int, an error message is
3030  output and the program halts. Note that ival == 0 is the first
3031  value in the list.
3032  */
3033  void get (const char* name,
3034  unsigned long& ref,
3035  int ival=0) const;
3036 
3037  ///
3038  /** Get the ival'th value of last occurrence of the
3039  requested name. If successful, the value is converted
3040  to an unsigned long and stored in reference ref. Returns 1 if
3041  successful. Returns 0 if the name does not exist. If
3042  ival'th value does not exist, or if the printed
3043  representation of the value cannot be converted to an
3044  int, an error message is output and the program halts.
3045  Note that ival == 0 is the first value in the list.
3046  */
3047  int query (const char* name,
3048  unsigned long& ref,
3049  int ival=0) const;
3050 
3051  ///
3052  /** Get the ival'th value of last occurrence of the requested name.
3053  If successful, the value is converted to a float and stored
3054  in reference ref. If the name does not exist or
3055  ival'th value does not exist, or if the printed representation
3056  of the value cannot be converted to a float, an error message is
3057  output and the program halts. Note that ival == 0 is the first
3058  value in the list.
3059  */
3060  void get (const char* name,
3061  float& ref,
3062  int ival=0) const;
3063 
3064  ///
3065  /** Get the ival'th value of last occurrence of the
3066  requested name. If successful, the value is converted
3067  to a float and stored in reference ref. Returns 1 if
3068  successful. Returns 0 if the name does not exist. If
3069  ival'th value does not exist, or if the printed
3070  representation of the value cannot be converted to a float,
3071  an error message is output and the program halts.
3072  Note that ival == 0 is the first value in the list.
3073  */
3074  int query (const char* name,
3075  float& ref,
3076  int ival=0) const;
3077 
3078  ///
3079  /** Get the ival'th value of last occurrence of the requested name.
3080  If successful, the value is converted to a double and stored
3081  in reference ref. If the name does not exist or
3082  ival'th value does not exist, or if the printed representation
3083  of the value cannot be converted to a double, an error message is
3084  output and the program halts. Note that ival == 0 is the first
3085  value in the list.
3086  */
3087  void get (const char* name,
3088  double& ref,
3089  int ival=0) const;
3090 
3091  ///
3092  /** Get the ival'th value of last occurrence of the
3093  requested name. If successful, the value is converted
3094  to a double and stored in reference ref. Returns 1 if
3095  successful. Returns 0 if the name does not exist. If
3096  ival'th value does not exist, or if the printed
3097  representation of the value cannot be converted to a double,
3098  an error message is output and the program halts.
3099  Note that ival == 0 is the first value in the list.
3100  */
3101  int query (const char* name,
3102  double& ref,
3103  int ival=0) const;
3104 
3105  ///Get the ival'th value of last occurrence of the requested name.
3106  /** Get the ival'th value of last occurrence of the requested name.
3107  If successful, the value is converted to a string and stored
3108  in reference ref. If the name does not exist or
3109  ival'th value does not exist, or if the printed representation
3110  of the value cannot be converted to a string, an error message is
3111  output and the program halts. Note that ival == 0 is the first
3112  value in the list.
3113  */
3114  void get (const char* name,
3115  std::string& ref,
3116  int ival=0) const;
3117 
3118  ///Get the ival'th value of last occurrence of the requested name.
3119  /** Get the ival'th value of last occurrence of the
3120  requested name. If successful, the value is converted
3121  to a string and stored in reference ref. Returns 1 if
3122  successful. Returns 0 if the name does not exist. If
3123  ival'th value does not exist, or if the printed
3124  representation of the value cannot be converted to a string,
3125  an error message is output and the program halts.
3126  Note that ival == 0 is the first value in the list.
3127  */
3128  int query (const char* name,
3129  std::string& ref,
3130  int ival=0) const;
3131 
3132  /// Get the ival'th value of last occurrence of the requested name.
3133  /** Get the ival'th value of last occurrence of the requested name.
3134  If successful, the value is converted to a bool and stored
3135  in reference ref. If the name does not exist or
3136  ival'th value does not exist, or if the printed representation
3137  of the value cannot be converted to a bool, an error message is
3138  output and the program halts. Valid representations of bool
3139  are "true" and "false" (case is ignored), and numeric values
3140  1 (=true) and 0 (=false). Note that ival == 0 is the first
3141  value in the list.
3142  */
3143  void get (const char* name,
3144  bool& ref,
3145  int ival=0) const;
3146 
3147  ///Get the ival'th value of last occurrence of the requested name.
3148  /** Get the ival'th value of last occurrence of the
3149  requested name. If successful, the value is converted
3150  to a bool and stored in reference ref. Returns 1 if
3151  successful. Returns 0 if the name does not exist. If
3152  ival'th value does not exist, or if the printed
3153  representation of the value cannot be converted to a bool,
3154  an error message is output and the program halts.
3155  Valid representations of bool are "true" and "false"
3156  (case is ignored), and numeric values 1 (=true) and 0 (=false).
3157  Note that ival == 0 is the first value in the list.
3158  */
3159  int query (const char* name,
3160  bool& ref,
3161  int ival=0) const;
3162 
3163  /// access an array of objects
3164  /** Gets a std::vector<int> of num_val values from last
3165  occurrence of given name. If successful, the values
3166  are converted to an int and stored in the
3167  std::vector<int> object ref. ref is resized (if
3168  necessary) to hold num_val values. The value in the
3169  list indexed by start_ix is copied into
3170  std::vector<int>[0], std::vector<int>[1] holds
3171  start_ix+1, etc. If there are fewer than start_ix +
3172  num_val values associated with the last occurrence, or
3173  if some of the values cannot be converted to an int, an
3174  error message is reported and the program halts.
3175  */
3176  void getarr (const char* name,
3177  Vector<int>& ref,
3178  int start_ix,
3179  int num_val) const;
3180 
3181  /// access an array of objects
3182  /** Gets a std::vector<int> of num_val values from last
3183  occurrence of given name. If successful, the values
3184  are converted to an int and stored in the
3185  std::vector<int> object ref. ref is resized (if
3186  necessary) to hold num_val values. The value in the
3187  list indexed by start_ix is copied into
3188  std::vector<int>[0], std::vector<int>[1] holds
3189  start_ix+1, etc. If there are fewer than start_ix +
3190  num_val values associated with the last occurrence, or
3191  if some of the values cannot be converted to an int, an
3192  error message is reported and the program halts.
3193  */
3194  void getarr (const char* name,
3195  std::vector<int>& ref,
3196  int start_ix,
3197  int num_val) const;
3198 
3199  /// access an array of objects
3200  /** Gets a std::vector<int> of num_val values from last
3201  occurrence of given name. If successful, the values
3202  are converted to an int and stored in the
3203  std::vector<int> object ref. ref is resized (if
3204  necessary) to hold num_val values. The value in the
3205  list indexed by start_ix is copied into
3206  std::vector<int>[0], std::vector<int>[1] holds
3207  start_ix+1, etc. Returns 0 if the name does not
3208  exist. If there are fewer than start_ix + num_val
3209  values associated with the last occurrence, or if some
3210  of the values cannot be converted to an int, an error
3211  message is reported and the program halts.
3212  */
3213  int queryarr (const char* name,
3214  Vector<int>& ref,
3215  int start_ix,
3216  int num_val) const;
3217 
3218  /// access an array of objects
3219  /** Gets a std::vector<int> of num_val values from last
3220  occurrence of given name. If successful, the values
3221  are converted to an int and stored in the
3222  std::vector<int> object ref. ref is resized (if
3223  necessary) to hold num_val values. The value in the
3224  list indexed by start_ix is copied into
3225  std::vector<int>[0], std::vector<int>[1] holds
3226  start_ix+1, etc. Returns 0 if the name does not
3227  exist. If there are fewer than start_ix + num_val
3228  values associated with the last occurrence, or if some
3229  of the values cannot be converted to an int, an error
3230  message is reported and the program halts.
3231  */
3232  int queryarr (const char* name,
3233  std::vector<int>& ref,
3234  int start_ix,
3235  int num_val) const;
3236 
3237  /// access an array of objects
3238  /** Gets a std::vector<unsigned long> of num_val values from last
3239  occurrence of given name. If successful, the values
3240  are converted to an int and stored in the
3241  std::vector<unsigned long> object ref. ref is resized (if
3242  necessary) to hold num_val values. The value in the
3243  list indexed by start_ix is copied into
3244  std::vector<unsigned long>[0], std::vector<unsigned long>[1] holds
3245  start_ix+1, etc. If there are fewer than start_ix +
3246  num_val values associated with the last occurrence, or
3247  if some of the values cannot be converted to an unsigned long, an
3248  error message is reported and the program halts.
3249  */
3250  void getarr (const char* name,
3251  Vector<unsigned long>& ref,
3252  int start_ix,
3253  int num_val) const;
3254 
3255  /// access an array of objects
3256  /** Gets a std::vector<unsigned long> of num_val values from last
3257  occurrence of given name. If successful, the values
3258  are converted to an unsigned long and stored in the
3259  std::vector<unsigned long> object ref. ref is resized (if
3260  necessary) to hold num_val values. The value in the
3261  list indexed by start_ix is copied into
3262  std::vector<unsigned long>[0], std::vector<unsigned long>[1] holds
3263  start_ix+1, etc. If there are fewer than start_ix +
3264  num_val values associated with the last occurrence, or
3265  if some of the values cannot be converted to an unsigned long, an
3266  error message is reported and the program halts.
3267  */
3268  void getarr (const char* name,
3269  std::vector<unsigned long>& ref,
3270  int start_ix,
3271  int num_val) const;
3272 
3273  /// access an array of objects
3274  /** Gets a std::vector<unsigned long> of num_val values from last
3275  occurrence of given name. If successful, the values
3276  are converted to an unsigned long and stored in the
3277  std::vector<unsigned long> object ref. ref is resized (if
3278  necessary) to hold num_val values. The value in the
3279  list indexed by start_ix is copied into
3280  std::vector<unsigned long>[0], std::vector<unsigned long>[1] holds
3281  start_ix+1, etc. Returns 0 if the name does not
3282  exist. If there are fewer than start_ix + num_val
3283  values associated with the last occurrence, or if some
3284  of the values cannot be converted to an unsigned long, an error
3285  message is reported and the program halts.
3286  */
3287  int queryarr (const char* name,
3288  Vector<unsigned long>& ref,
3289  int start_ix,
3290  int num_val) const;
3291 
3292  /// access an array of objects
3293  /** Gets a std::vector<unsigned long> of num_val values from last
3294  occurrence of given name. If successful, the values
3295  are converted to an unsigned long and stored in the
3296  std::vector<unsigned long> object ref. ref is resized (if
3297  necessary) to hold num_val values. The value in the
3298  list indexed by start_ix is copied into
3299  std::vector<unsigned long>[0], std::vector<unsigned long>[1] holds
3300  start_ix+1, etc. Returns 0 if the name does not
3301  exist. If there are fewer than start_ix + num_val
3302  values associated with the last occurrence, or if some
3303  of the values cannot be converted to an unsigned long, an error
3304  message is reported and the program halts.
3305  */
3306  int queryarr (const char* name,
3307  std::vector<unsigned long>& ref,
3308  int start_ix,
3309  int num_val) const;
3310 
3311  /// access an array
3312  /** Gets a std::vector<float> of num_val values from last
3313  occurrence of given name. If successful, the values
3314  are converted to a float and stored in the
3315  std::vector<float> object ref. ref is resized (if
3316  necessary) to hold num_val values. The value in the
3317  list indexed by start_ix is copied into
3318  std::vector<float>[0], std::vector<float>[1] holds
3319  start_ix+1, etc. If there are fewer than start_ix +
3320  num_val values associated with the last occurrence, or
3321  if some of the values cannot be converted to a float, an
3322  error message is reported and the program halts.
3323  */
3324  void getarr (const char* name,
3325  Vector<float>& ref,
3326  int start_ix,
3327  int num_val) const;
3328 
3329  /// access an array
3330  /** Gets a std::vector<float> of num_val values from last
3331  occurrence of given name. If successful, the values
3332  are converted to a float and stored in the
3333  std::vector<float> object ref. ref is resized (if
3334  necessary) to hold num_val values. The value in the
3335  list indexed by start_ix is copied into
3336  std::vector<float>[0], std::vector<float>[1] holds
3337  start_ix+1, etc. If there are fewer than start_ix +
3338  num_val values associated with the last occurrence, or
3339  if some of the values cannot be converted to a float, an
3340  error message is reported and the program halts.
3341  */
3342  void getarr (const char* name,
3343  std::vector<float>& ref,
3344  int start_ix,
3345  int num_val) const;
3346 
3347  ///
3348  /** Gets a std::vector<float> of num_val values from last
3349  occurrence of given name. If successful, the values
3350  are converted to a float and stored in the
3351  std::vector<float> object ref. ref is resized (if
3352  necessary) to hold num_val values. The value in the
3353  list indexed by start_ix is copied into
3354  std::vector<float>[0], std::vector<float>[1] holds
3355  start_ix+1, etc. Returns 0 if the name does not
3356  exist. If there are fewer than start_ix + num_val
3357  values associated with the last occurrence, or if some
3358  of the values cannot be converted to a float, an error
3359  message is reported and the program halts.
3360  */
3361  int queryarr (const char* name,
3362  Vector<float>& ref,
3363  int start_ix,
3364  int num_val) const;
3365 
3366  ///
3367  /** Gets a std::vector<float> of num_val values from last
3368  occurrence of given name. If successful, the values
3369  are converted to a float and stored in the
3370  std::vector<float> object ref. ref is resized (if
3371  necessary) to hold num_val values. The value in the
3372  list indexed by start_ix is copied into
3373  std::vector<float>[0], std::vector<float>[1] holds
3374  start_ix+1, etc. Returns 0 if the name does not
3375  exist. If there are fewer than start_ix + num_val
3376  values associated with the last occurrence, or if some
3377  of the values cannot be converted to a float, an error
3378  message is reported and the program halts.
3379  */
3380  int queryarr (const char* name,
3381  std::vector<float>& ref,
3382  int start_ix,
3383  int num_val) const;
3384 
3385  ///
3386  /** Gets a std::vector<double> of num_val values from last
3387  occurrence of given name. If successful, the values
3388  are converted to a double and stored in the
3389  std::vector<double> object ref. ref is resized (if
3390  necessary) to hold num_val values. The value in the
3391  list indexed by start_ix is copied into
3392  std::vector<double>[0], std::vector<double>[1] holds
3393  start_ix+1, etc. If there are fewer than start_ix +
3394  num_val values associated with the last occurrence, or
3395  if some of the values cannot be converted to a double, an
3396  error message is reported and the program halts.
3397  */
3398  void getarr (const char* name,
3399  Vector<double>& ref,
3400  int start_ix,
3401  int num_val) const;
3402 
3403  ///
3404  /** Gets a std::vector<double> of num_val values from last
3405  occurrence of given name. If successful, the values
3406  are converted to a double and stored in the
3407  std::vector<double> object ref. ref is resized (if
3408  necessary) to hold num_val values. The value in the
3409  list indexed by start_ix is copied into
3410  std::vector<double>[0], std::vector<double>[1] holds
3411  start_ix+1, etc. If there are fewer than start_ix +
3412  num_val values associated with the last occurrence, or
3413  if some of the values cannot be converted to a double, an
3414  error message is reported and the program halts.
3415  */
3416  void getarr (const char* name,
3417  std::vector<double>& ref,
3418  int start_ix,
3419  int num_val) const;
3420 
3421  ///
3422  /** Gets a std::vector<double> of num_val values from last
3423  occurrence of given name. If successful, the values
3424  are converted to a double and stored in the
3425  std::vector<double> object ref. ref is resized (if
3426  necessary) to hold num_val values. The value in the
3427  list indexed by start_ix is copied into
3428  std::vector<double>[0], std::vector<double>[1] holds
3429  start_ix+1, etc. Returns 0 if the name does not
3430  exist. If there are fewer than start_ix + num_val
3431  values associated with the last occurrence, or if some
3432  of the values cannot be converted to a double, an error
3433  message is reported and the program halts.
3434  */
3435  int queryarr (const char* name,
3436  Vector<double>& ref,
3437  int start_ix,
3438  int num_val) const;
3439 
3440  ///
3441  /** Gets a std::vector<double> of num_val values from last
3442  occurrence of given name. If successful, the values
3443  are converted to a double and stored in the
3444  std::vector<double> object ref. ref is resized (if
3445  necessary) to hold num_val values. The value in the
3446  list indexed by start_ix is copied into
3447  std::vector<double>[0], std::vector<double>[1] holds
3448  start_ix+1, etc. Returns 0 if the name does not
3449  exist. If there are fewer than start_ix + num_val
3450  values associated with the last occurrence, or if some
3451  of the values cannot be converted to a double, an error
3452  message is reported and the program halts.
3453  */
3454  int queryarr (const char* name,
3455  std::vector<double>& ref,
3456  int start_ix,
3457  int num_val) const;
3458 
3459  ///
3460  /** Gets a std::vector<string> of num_val values from last
3461  occurrence of given name. If successful, the values
3462  are converted to a string and stored in the
3463  std::vector<string> object ref. ref is resized (if
3464  necessary) to hold num_val values. The value in the
3465  list indexed by start_ix is copied into
3466  std::vector<string>[0], std::vector<string>[1] holds
3467  start_ix+1, etc. If there are fewer than start_ix +
3468  num_val values associated with the last occurrence, or
3469  if some of the values cannot be converted to a string, an
3470  error message is reported and the program halts.
3471  */
3472  void getarr (const char* name,
3473  Vector<std::string>& ref,
3474  int start_ix,
3475  int num_val) const;
3476 
3477  ///
3478  /** Gets a std::vector<string> of num_val values from last
3479  occurrence of given name. If successful, the values
3480  are converted to a string and stored in the
3481  std::vector<string> object ref. ref is resized (if
3482  necessary) to hold num_val values. The value in the
3483  list indexed by start_ix is copied into
3484  std::vector<string>[0], std::vector<string>[1] holds
3485  start_ix+1, etc. If there are fewer than start_ix +
3486  num_val values associated with the last occurrence, or
3487  if some of the values cannot be converted to a string, an
3488  error message is reported and the program halts.
3489  */
3490  void getarr (const char* name,
3491  std::vector<std::string>& ref,
3492  int start_ix,
3493  int num_val) const;
3494 
3495  ///
3496  /** Gets a std::vector<string> of num_val values from last
3497  occurrence of given name. If successful, the values
3498  are converted to a string and stored in the
3499  std::vector<string> object ref. ref is resized (if
3500  necessary) to hold num_val values. The value in the
3501  list indexed by start_ix is copied into
3502  std::vector<string>[0], std::vector<string>[1] holds
3503  start_ix+1, etc. Returns 0 if the name does not
3504  exist. If there are fewer than start_ix + num_val
3505  values associated with the last occurrence, or if some
3506  of the values cannot be converted to a string, an error
3507  message is reported and the program halts.
3508  */
3509  int queryarr (const char* name,
3510  Vector<std::string>& ref,
3511  int start_ix,
3512  int num_val) const;
3513 
3514  ///
3515  /** Gets a std::vector<string> of num_val values from last
3516  occurrence of given name. If successful, the values
3517  are converted to a string and stored in the
3518  std::vector<string> object ref. ref is resized (if
3519  necessary) to hold num_val values. The value in the
3520  list indexed by start_ix is copied into
3521  std::vector<string>[0], std::vector<string>[1] holds
3522  start_ix+1, etc. Returns 0 if the name does not
3523  exist. If there are fewer than start_ix + num_val
3524  values associated with the last occurrence, or if some
3525  of the values cannot be converted to a string, an error
3526  message is reported and the program halts.
3527  */
3528  int queryarr (const char* name,
3529  std::vector<std::string>& ref,
3530  int start_ix,
3531  int num_val) const;
3532 
3533 ///
3534  /** Gets a std::vector<bool> of num_val values from last
3535  occurrence of given name. If successful, the values
3536  are converted to a bool and stored in the
3537  std::vector<bool> object ref. ref is resized (if
3538  necessary) to hold num_val values. The value in the
3539  list indexed by start_ix is copied into
3540  std::vector<bool>[0], std::vector<bool>[1] holds
3541  start_ix+1, etc. If there are fewer than start_ix +
3542  num_val values associated with the last occurrence, or
3543  if some of the values cannot be converted to a bool, an
3544  error message is reported and the program halts.
3545  */
3546  void getarr (const char* name,
3547  Vector<bool>& ref,
3548  int start_ix,
3549  int num_val) const;
3550 
3551  ///
3552  /** Gets a std::vector<bool> of num_val values from last
3553  occurrence of given name. If successful, the values
3554  are converted to a bool and stored in the
3555  std::vector<bool> object ref. ref is resized (if
3556  necessary) to hold num_val values. The value in the
3557  list indexed by start_ix is copied into
3558  std::vector<bool>[0], std::vector<bool>[1] holds
3559  start_ix+1, etc. If there are fewer than start_ix +
3560  num_val values associated with the last occurrence, or
3561  if some of the values cannot be converted to a bool, an
3562  error message is reported and the program halts.
3563  */
3564  void getarr (const char* name,
3565  std::vector<bool>& ref,
3566  int start_ix,
3567  int num_val) const;
3568 
3569  ///
3570  /** Gets a std::vector<bool> of num_val values from last
3571  occurrence of given name. If successful, the values
3572  are converted to a bool and stored in the
3573  std::vector<bool> object ref. ref is resized (if
3574  necessary) to hold num_val values. The value in the
3575  list indexed by start_ix is copied into
3576  std::vector<bool>[0], std::vector<bool>[1] holds
3577  start_ix+1, etc. Returns 0 if the name does not
3578  exist. If there are fewer than start_ix + num_val
3579  values associated with the last occurrence, or if some
3580  of the values cannot be converted to a bool, an error
3581  message is reported and the program halts.
3582  */
3583  int queryarr (const char* name,
3584  Vector<bool>& ref,
3585  int start_ix,
3586  int num_val) const;
3587 
3588  ///
3589  /** Gets a std::vector<bool> of num_val values from last
3590  occurrence of given name. If successful, the values
3591  are converted to a bool and stored in the
3592  std::vector<bool> object ref. ref is resized (if
3593  necessary) to hold num_val values. The value in the
3594  list indexed by start_ix is copied into
3595  std::vector<bool>[0], std::vector<bool>[1] holds
3596  start_ix+1, etc. Returns 0 if the name does not
3597  exist. If there are fewer than start_ix + num_val
3598  values associated with the last occurrence, or if some
3599  of the values cannot be converted to a bool, an error
3600  message is reported and the program halts.
3601  */
3602  int queryarr (const char* name,
3603  std::vector<bool>& ref,
3604  int start_ix,
3605  int num_val) const;
3606 
3607  /// return prefix
3608  inline const char* prefix() const
3609  {
3610  return thePrefix.c_str();
3611  }
3612 
3613 #ifndef DOXYGEN
3614  //
3615  // This should be protected, but cfront-derived compilers complain :-(
3616  //
3617  enum PPType
3618  {
3619  ppDefn,
3620  ppOption,
3621  ppInt,
3622  ppUnsignedLong,
3623  ppFloat,
3624  ppDouble,
3625  ppString,
3626  ppBool,
3627  ppEQ_sign,
3628  ppEOF
3629  };
3630 
3631 
3632 protected:
3633  //
3634  // Table of entries common to all objects.
3635  //
3636  static PP_List<PP_entry*> table;
3637  //
3638  // Command line arguments.
3639  //
3640  static int xargc;
3641  static char** xargv;
3642  //
3643  // Keep track of number of ParmParse objects out there.
3644  //
3645  static int num_obj;
3646  //
3647  // Parses string and builds table.
3648  //
3649  void bldTable (const char* str,
3650  int lenstr,
3651  PP_List<PP_entry*>& tab);
3652  //
3653  // Add defn to table, check for file inclusion.
3654  //
3655  void addDefn (PP_String& def,
3656  PP_List<PP_String>& val,
3657  PP_List<PP_entry*>& tab);
3658  //
3659  // Reads file into string then parses it with call to bldTable.
3660  //
3661  void read_file (const char* fname,
3662  PP_List<PP_entry*>& tab);
3663  //
3664  // Lexical analyser called by bldTable.
3665  //
3666  PPType getToken (const char*,
3667  int&,
3668  int,
3669  char*);
3670  //
3671  // Reclaims memory used in table.
3672  //
3673  void rmTable ();
3674  //
3675  // Prefix used in keyword search.
3676  //
3677  PP_String thePrefix;
3678  //
3679  // Used by constructor to build table.
3680  //
3681  void ppinit (const char* parfile);
3682  //
3683  // Find n'th occurence of name in table.
3684  //
3685  const PP_entry* ppindex (int n,
3686  const char* name) const;
3687  //
3688  // Get ival_th value of k_th occurence of given name.
3689  // If k_th occurence does not exist or ival_th value does
3690  // not exist or if ival_type does not match with type, an
3691  // error message is reported and the program halts.
3692  // If successful, value is stored in ptr.
3693  // same as above but searches for last occurence of name.
3694  //
3695  void getval (const char* name,
3696  const PPType type,
3697  void* ptr,
3698  int ival,
3699  int k=-1) const;
3700 public:
3701  //
3702  // Get an array of values.
3703  //
3704  void getarr (const char* name,
3705  const PPType type,
3706  void* ptr,
3707  int start_ix,
3708  int num_val,
3709  int k=-1) const;
3710  int queryval (const char* name,
3711  const PPType type,
3712  void* ptr,
3713  int ival,
3714  int k=-1) const;
3715  int queryarr (const char* name,
3716  const PPType type,
3717  void* ptr,
3718  int start_ix,
3719  int num_val,
3720  int k=-1) const;
3721 
3722 private:
3723  bool isInteger (const PP_String& str, int& val) const;
3724  bool isUnsigned(const PP_String& str, unsigned long& val) const;
3725  int isDouble (const PP_String& str, double& val) const;
3726  bool isBool (const PP_String& str, bool& val) const;
3727 
3728 #endif /* DOXYGEN ENDIF */
3729 
3730 };
3731 
3732 #ifndef DOXYGEN
3733 class PP_entry
3734 {
3735 private:
3736  friend class ParmParse;
3737  PP_entry()
3738  {}
3739 
3740  PP_entry (PP_String& name,
3741  ParmParse::PPType typ,
3742  PP_List<PP_String>& vals);
3743 
3744  ~PP_entry()
3745  {}
3746 
3747  PP_String defname;
3748  ParmParse::PPType deftype;
3749  PP_Array<PP_String> val;
3750 
3751  void dump (std::ostream& os) const;
3752 };
3753 #endif //doxygen
3754 
3755 //
3756 // Inlines.
3757 //
3758 
3759 inline
3760 int
3762  int n) const
3763 {
3764  //
3765  // First find n'th occurance of name in table.
3766  //
3767  const PP_entry* def = ppindex(n,name);
3768  return def == 0 ? 0 : def->val.length();
3769 }
3770 
3771 inline
3772 void
3773 ParmParse::get (const char* name,
3774  int& ptr,
3775  int ival) const
3776 {
3777  getval(name,ppInt,&ptr,ival,-1);
3778 }
3779 
3780 inline
3781 int
3782 ParmParse::query (const char* name,
3783  int& ptr,
3784  int ival) const
3785 {
3786  return queryval(name,ppInt,&ptr,ival,-1);
3787 }
3788 
3789 inline
3790 void
3791 ParmParse::get (const char* name,
3792  unsigned long& ptr,
3793  int ival) const
3794 {
3795  getval(name,ppUnsignedLong,&ptr,ival,-1);
3796 }
3797 
3798 inline
3799 int
3800 ParmParse::query (const char* name,
3801  unsigned long& ptr,
3802  int ival) const
3803 {
3804  return queryval(name,ppUnsignedLong,&ptr,ival,-1);
3805 }
3806 
3807 inline
3808 void
3809 ParmParse::get (const char* name,
3810  float& ptr,
3811  int ival) const
3812 {
3813  getval(name,ppFloat,&ptr,ival,-1);
3814 }
3815 
3816 inline
3817 int
3818 ParmParse::query (const char* name,
3819  float& ptr,
3820  int ival) const
3821 {
3822  return queryval(name,ppFloat,&ptr,ival,-1);
3823 }
3824 
3825 inline
3826 void
3827 ParmParse::get (const char* name,
3828  double& ptr,
3829  int ival) const
3830 {
3831  getval(name,ppDouble,&ptr,ival,-1);
3832 }
3833 
3834 inline
3835 int
3836 ParmParse::query (const char* name,
3837  double& ptr,
3838  int ival) const
3839 {
3840  return queryval(name,ppDouble,&ptr,ival,-1);
3841 }
3842 
3843 inline
3844 void
3845 ParmParse::get (const char* name,
3846  std::string& ptr,
3847  int ival) const
3848 {
3849  PP_String pp_string;
3850  getval(name,ppString,&pp_string,ival,-1);
3851  ptr = pp_string.c_str();
3852 }
3853 
3854 inline
3855 int
3856 ParmParse::query (const char* name,
3857  std::string& ptr,
3858  int ival) const
3859 {
3860  PP_String pp_string;
3861  int status = queryval(name,ppString,&pp_string,ival,-1);
3862  if (status != 0)
3863  ptr = pp_string.c_str();
3864  return status;
3865 }
3866 
3867 inline
3868 void
3869 ParmParse::get(const char* name,
3870  bool& ptr,
3871  int ival) const
3872 {
3873  getval(name,ppBool,&ptr,ival,-1);
3874 }
3875 
3876 inline
3877 int
3878 ParmParse::query (const char* name,
3879  bool& ptr,
3880  int ival) const
3881 {
3882  return queryval(name,ppBool,&ptr,ival,-1);
3883 }
3884 
3885 inline
3886 void
3888  std::vector<int>& ptr,
3889  int start_ix,
3890  int num_val) const
3891 {
3892  if (ptr.size() < num_val)
3893  ptr.resize(num_val);
3894  int* c_array = new int[num_val];
3895  getarr(name,ppInt,c_array,start_ix,num_val,-1);
3896  for (int i = 0; i < num_val; ++i)
3897  {
3898  ptr[i] = c_array[i];
3899  }
3900  delete[] c_array;
3901 }
3902 
3903 inline
3904 void
3906  Vector<int>& ptr,
3907  int start_ix,
3908  int num_val) const
3909 {
3910  if (ptr.size() < num_val)
3911  ptr.resize(num_val);
3912  int* c_array = new int[num_val];
3913  getarr(name,ppInt,c_array,start_ix,num_val,-1);
3914  for (int i = 0; i < num_val; ++i)
3915  {
3916  ptr[i] = c_array[i];
3917  }
3918  delete[] c_array;
3919 }
3920 
3921 inline
3922 int
3924  std::vector<int>& ptr,
3925  int start_ix,
3926  int num_val) const
3927 {
3928  if (ptr.size() < num_val)
3929  ptr.resize(num_val);
3930  int* c_array = new int[num_val];
3931  int status = queryarr(name,ppInt,c_array,start_ix,num_val,-1);
3932  if (status != 0 )
3933  {
3934  for (int i = 0; i < num_val; ++i)
3935  {
3936  ptr[i] = c_array[i];
3937  }
3938  }
3939  delete [] c_array;
3940  return status;
3941 }
3942 
3943 inline
3944 int
3946  Vector<int>& ptr,
3947  int start_ix,
3948  int num_val) const
3949 {
3950  if (ptr.size() < num_val)
3951  ptr.resize(num_val);
3952  int* c_array = new int[num_val];
3953  int status = queryarr(name,ppInt,c_array,start_ix,num_val,-1);
3954  if (status != 0 )
3955  {
3956  for (int i = 0; i < num_val; ++i)
3957  {
3958  ptr[i] = c_array[i];
3959  }
3960  }
3961  delete [] c_array;
3962  return status;
3963 }
3964 
3965 inline
3966 void
3968  std::vector<float>& ptr,
3969  int start_ix,
3970  int num_val) const
3971 {
3972  if (ptr.size() < num_val)
3973  ptr.resize(num_val);
3974  float* c_array = new float[num_val];
3975  getarr(name,ppFloat,c_array,start_ix,num_val,-1);
3976  for (int i = 0; i < num_val; ++i)
3977  {
3978  ptr[i] = c_array[i];
3979  }
3980  delete[] c_array;
3981 }
3982 
3983 inline
3984 void
3986  Vector<float>& ptr,
3987  int start_ix,
3988  int num_val) const
3989 {
3990  if (ptr.size() < num_val)
3991  ptr.resize(num_val);
3992  float* c_array = new float[num_val];
3993  getarr(name,ppFloat,c_array,start_ix,num_val,-1);
3994  for (int i = 0; i < num_val; ++i)
3995  {
3996  ptr[i] = c_array[i];
3997  }
3998  delete[] c_array;
3999 }
4000 
4001 inline
4002 int
4004  std::vector<float>& ptr,
4005  int start_ix,
4006  int num_val) const
4007 {
4008  if (ptr.size() < num_val)
4009  ptr.resize(num_val);
4010  float* c_array = new float[num_val];
4011  int status = queryarr(name,ppFloat,c_array,start_ix,num_val,-1);
4012  if (status != 0)
4013  {
4014  for (int i = 0; i < num_val; ++i)
4015  {
4016  ptr[i] = c_array[i];
4017  }
4018  }
4019  delete[] c_array;
4020  return status;
4021 }
4022 
4023 inline
4024 int
4026  Vector<float>& ptr,
4027  int start_ix,
4028  int num_val) const
4029 {
4030  if (ptr.size() < num_val)
4031  ptr.resize(num_val);
4032  float* c_array = new float[num_val];
4033  int status = queryarr(name,ppFloat,c_array,start_ix,num_val,-1);
4034  if (status != 0)
4035  {
4036  for (int i = 0; i < num_val; ++i)
4037  {
4038  ptr[i] = c_array[i];
4039  }
4040  }
4041  delete[] c_array;
4042  return status;
4043 }
4044 
4045 inline
4046 void
4048  std::vector<double>& ptr,
4049  int start_ix,
4050  int num_val) const
4051 {
4052  if (ptr.size() < num_val)
4053  ptr.resize(num_val);
4054  double* c_array = new double[num_val];
4055  int status = queryarr(name,ppDouble,c_array,start_ix,num_val,-1);
4056  if (status == 0)
4057  {
4058  cerr << "ParmParse::getarr(): "
4059  << name
4060  << " not found in table" << endl;
4061  dumpTable(cerr);
4062  MayDay::Abort();
4063  }
4064  for (int i = 0; i < num_val; ++i)
4065  {
4066  ptr[i] = c_array[i];
4067  }
4068  delete[] c_array;
4069 }
4070 
4071 inline
4072 void
4074  Vector<double>& ptr,
4075  int start_ix,
4076  int num_val) const
4077 {
4078  if (ptr.size() < num_val)
4079  ptr.resize(num_val);
4080  double* c_array = new double[num_val];
4081  int status = queryarr(name,ppDouble,c_array,start_ix,num_val,-1);
4082  if (status == 0)
4083  {
4084  cerr << "ParmParse::getarr(): "
4085  << name
4086  << " not found in table" << endl;
4087  dumpTable(cerr);
4088  MayDay::Abort();
4089  }
4090  for (int i = 0; i < num_val; ++i)
4091  {
4092  ptr[i] = c_array[i];
4093  }
4094  delete[] c_array;
4095 }
4096 
4097 inline
4098 int
4100  std::vector<double>& ptr,
4101  int start_ix,
4102  int num_val) const
4103 {
4104  if (ptr.size() < num_val)
4105  ptr.resize(num_val);
4106  double* c_array = new double[num_val];
4107  int status = queryarr(name,ppDouble,c_array,start_ix,num_val,-1);
4108  if (status != 0)
4109  {
4110  for (int i = 0; i < num_val; ++i)
4111  {
4112  ptr[i] = c_array[i];
4113  }
4114  }
4115  delete[] c_array;
4116  return status;
4117 }
4118 
4119 inline
4120 int
4122  Vector<double>& ptr,
4123  int start_ix,
4124  int num_val) const
4125 {
4126  if (ptr.size() < num_val)
4127  ptr.resize(num_val);
4128  double* c_array = new double[num_val];
4129  int status = queryarr(name,ppDouble,c_array,start_ix,num_val,-1);
4130  if (status != 0)
4131  {
4132  for (int i = 0; i < num_val; ++i)
4133  {
4134  ptr[i] = c_array[i];
4135  }
4136  }
4137  delete[] c_array;
4138  return status;
4139 }
4140 
4141 inline
4142 void
4144  std::vector<std::string>& ptr,
4145  int start_ix,
4146  int num_val) const
4147 {
4148  if (ptr.size() < num_val)
4149  ptr.resize(num_val);
4150  PP_String* c_array = new PP_String[num_val];
4151  getarr(name,ppString,c_array,start_ix,num_val,-1);
4152  for (int i = 0; i < num_val; ++i)
4153  {
4154  ptr[i] = c_array[i].c_str();
4155  }
4156  delete[] c_array;
4157 }
4158 
4159 inline
4160 void
4162  Vector<std::string>& ptr,
4163  int start_ix,
4164  int num_val) const
4165 {
4166  if (ptr.size() < num_val)
4167  ptr.resize(num_val);
4168  PP_String* c_array = new PP_String[num_val];
4169  getarr(name,ppString,c_array,start_ix,num_val,-1);
4170  for (int i = 0; i < num_val; ++i)
4171  {
4172  ptr[i] = c_array[i].c_str();
4173  }
4174  delete[] c_array;
4175 }
4176 
4177 inline
4178 int
4180  std::vector<std::string>& ptr,
4181  int start_ix,
4182  int num_val) const
4183 {
4184  if (ptr.size() < num_val)
4185  ptr.resize(num_val);
4186  PP_String* c_array = new PP_String[num_val];
4187  int status = queryarr(name,ppString,c_array,start_ix,num_val,-1);
4188  if (status != 0)
4189  {
4190  for (int i = 0; i < num_val; ++i)
4191  {
4192  ptr[i] = c_array[i].c_str();
4193  }
4194  }
4195  delete[] c_array;
4196  return status;
4197 }
4198 
4199 inline
4200 int
4202  Vector<std::string>& ptr,
4203  int start_ix,
4204  int num_val) const
4205 {
4206  if (ptr.size() < num_val)
4207  ptr.resize(num_val);
4208  PP_String* c_array = new PP_String[num_val];
4209  int status = queryarr(name,ppString,c_array,start_ix,num_val,-1);
4210  if (status != 0)
4211  {
4212  for (int i = 0; i < num_val; ++i)
4213  {
4214  ptr[i] = c_array[i].c_str();
4215  }
4216  }
4217  delete[] c_array;
4218  return status;
4219 }
4220 
4221 // ----------------------------------------
4222 inline
4223 void
4225  std::vector<bool>& ptr,
4226  int start_ix,
4227  int num_val) const
4228 {
4229  if (ptr.size() < num_val)
4230  ptr.resize(num_val);
4231  bool* c_array = new bool[num_val];
4232  getarr(name,ppBool,c_array,start_ix,num_val,-1);
4233  for (int i = 0; i < num_val; ++i)
4234  {
4235  ptr[i] = c_array[i];
4236  }
4237  delete[] c_array;
4238 }
4239 
4240 inline
4241 int
4243  std::vector<bool>& ptr,
4244  int start_ix,
4245  int num_val) const
4246 {
4247  if (ptr.size() < num_val)
4248  ptr.resize(num_val);
4249  bool* c_array = new bool[num_val];
4250  int status = queryarr(name,ppBool,c_array,start_ix,num_val,-1);
4251  if (status != 0 )
4252  {
4253  for (int i = 0; i < num_val; ++i)
4254  {
4255  ptr[i] = c_array[i];
4256  }
4257  }
4258  delete [] c_array;
4259  return status;
4260 }
4261 
4262 // ---------------------------------------
4263 
4264 inline
4265 bool
4266 ParmParse::isInteger (const PP_String& str,
4267  int& val) const
4268 {
4269  //
4270  // Start token scan.
4271  //
4272  char* endp = 0;
4273  val = (int) strtol(str.c_str(), &endp, 10);
4274  return *endp == 0;
4275 }
4276 
4277 inline
4278 bool
4279 ParmParse::isUnsigned (const PP_String& str,
4280  unsigned long & val) const
4281 {
4282  char* endp = 0;
4283  val = strtoul(str.c_str(), &endp, 10);
4284  return *endp == 0;
4285 }
4286 
4287 inline
4288 int
4289 ParmParse::isDouble (const PP_String& str,
4290  double& val) const
4291 {
4292  char* endp = 0;
4293  val = std::strtod(str.c_str(), &endp);
4294  return *endp == 0;
4295 }
4296 
4297 inline
4298 bool
4299 ParmParse::isBool (const PP_String& str,
4300  bool& val) const
4301 {
4302  PP_String str_lc( str );
4303  str_lc.toLower();
4304  if ( str_lc == "true" || str_lc == "1" )
4305  {
4306  return val = true ;
4307  }
4308  else if ( str_lc == "false" || str_lc == "0" )
4309  {
4310  val = false ;
4311  return true ;
4312  }
4313  else
4314  {
4315  return false ;
4316  }
4317 }
4318 
4319 inline
4320 int
4321 ParmParse::countname (const std::string& name) const
4322 {
4323  return countname(name.c_str());
4324 }
4325 
4326 #include "BaseNamespaceFooter.H"
4327 #endif /*CH_PARMPARSE_H*/
friend class PP_entry
Definition: ParmParse.H:2851
int countval(const char *name, int n=-1) const
Definition: ParmParse.H:3761
#define CH_assert(cond)
Definition: CHArray.H:37
int countname(const char *name) const
int query(const char *name, int &ref, int ival=0) const
Definition: ParmParse.H:3782
void setStr(const std::string &varName, std::string varVal)
Definition: ParmParse.H:2985
int isEmpty(const box2d *)
Parse Parameters From Command Line and Input Files.
Definition: ParmParse.H:2849
void resize(unsigned int isize)
Definition: Vector.H:346
std::ostream & operator<<(std::ostream &a_os, const IndexTM< T, N > &a_iv)
C::self_type operator+(const C &, const C &)
Definition: GenericArithmeticI.H:120
const char * name(const FArrayBox &a_dummySpecializationArg)
Definition: CH_HDF5.H:907
std::istream & operator>>(std::istream &a_os, IndexTM< T, N > &a_iv)
bool operator<(const FaceIndex &f1, const FaceIndex &f2)
Definition: FaceIndex.H:212
size_t size() const
Definition: Vector.H:192
int queryarr(const char *name, Vector< int > &ref, int start_ix, int num_val) const
access an array of objects
Definition: ParmParse.H:3945
void get(const char *name, int &ref, int ival=0) const
access single object
Definition: ParmParse.H:3773
void setVal(const std::string &varName, TYPE varVal)
Definition: ParmParse.H:2966
void const char const int const int const int * K
Definition: Lapack.H:83
T Min(const T &a_a, const T &a_b)
Definition: Misc.H:26
C::self_type operator*(const C &, const C &)
Definition: GenericArithmeticI.H:128
const char * prefix() const
return prefix
Definition: ParmParse.H:3608
void addEntries(const std::string &strEntry)
Definition: ParmParse.H:2948
void dumpTable(std::ostream &os) const
void getarr(const char *name, Vector< int > &ref, int start_ix, int num_val) const
access an array of objects
Definition: ParmParse.H:3905
static void Abort(const char *const a_msg=m_nullString)
Print out message to cerr and exit via abort() (if serial) or MPI_Abort() (if parallel).