Chombo + EB  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  /** Returns the number of values associated with nth occurence of
2908  name (prepended with the prefix) in the table. n == -1 implies
2909  the last occurence.
2910  */
2911  int countval (const char* name,
2912  int n = -1) const;
2913 
2914  ///
2915  /** Returns the number of times the given name (prepended with
2916  prefix) appears in the table.
2917  */
2918  int countname (const char* name) const;
2919 
2920  ///
2921  /** Returns the number of times the given name (prepended with
2922  prefix) appears in the table.
2923  */
2924  int countname (const std::string& name) const;
2925 
2926  ///
2927  /**
2928  * Accessor for private method that adds parameters
2929  * to the global table (SWS-Tech-X Research)
2930  * e.g. parmParseObj.addEntries("tst_value = 2")
2931  */
2932  void addEntries (const std::string& strEntry)
2933  {
2934  int len = (int)strEntry.size() + 1;
2935  bldTable(strEntry.c_str(), len, table);
2936  }
2937 
2938  ///
2939  /**
2940  * Append input parameter pairs to ParmParse
2941  *
2942  * 1. convert value to string
2943  * 2. construct string line syntax for ParmParse
2944  * 3. use special public method in ParmParse.H
2945  *
2946  * @param varName parameter string name
2947  * @param varVal numerical value type
2948  */
2949  template <typename TYPE>
2950  void setVal (const std::string& varName, TYPE varVal)
2951  {
2952  std::string valStr =
2953  static_cast<std::ostringstream*>( &(std::ostringstream() << varVal) )->str();
2954  std::string inEntry = varName + " = " + valStr;
2955  addEntries(inEntry);
2956  }
2957 
2958  ///
2959  /**
2960  * Append input parameter pairs to ParmParse
2961  *
2962  * 1. convert value to string
2963  * 2. construct string line syntax for ParmParse
2964  * 3. use special public method in ParmParse.H
2965  *
2966  * @param varName parameter string name
2967  * @param varVal string value type
2968  */
2969  void setStr (const std::string& varName, std::string varVal)
2970  {
2971  std::string inEntry = varName + " = " + varVal;
2972  addEntries(inEntry);
2973  }
2974 
2975  ///
2976  /**
2977  Write the contents of the table in ASCII to the ostream.
2978  */
2979  void dumpTable (std::ostream& os) const;
2980 
2981  /// access single object
2982  /** Get the ival'th value of last occurrence of the requested name.
2983  If successful, the value is converted to an int and stored
2984  in reference ref. If the name does not exist or
2985  ival'th value does not exist, or if the printed representation
2986  of the value cannot be converted to an int, an error message is
2987  output and the program halts. Note that ival == 0 is the first
2988  value in the list.
2989  */
2990  void get (const char* name,
2991  int& ref,
2992  int ival=0) const;
2993 
2994  ///
2995  /** Get the ival'th value of last occurrence of the
2996  requested name. If successful, the value is converted
2997  to an int and stored in reference ref. Returns 1 if
2998  successful. Returns 0 if the name does not exist. If
2999  ival'th value does not exist, or if the printed
3000  representation of the value cannot be converted to an
3001  int, an error message is output and the program halts.
3002  Note that ival == 0 is the first value in the list.
3003  */
3004  int query (const char* name,
3005  int& ref,
3006  int ival=0) const;
3007 
3008  /// access single object
3009  /** Get the ival'th value of last occurrence of the requested name.
3010  If successful, the value is converted to a n unsigned long and stored
3011  in reference ref. If the name does not exist or
3012  ival'th value does not exist, or if the printed representation
3013  of the value cannot be converted to an int, an error message is
3014  output and the program halts. Note that ival == 0 is the first
3015  value in the list.
3016  */
3017  void get (const char* name,
3018  unsigned long& ref,
3019  int ival=0) const;
3020 
3021  ///
3022  /** Get the ival'th value of last occurrence of the
3023  requested name. If successful, the value is converted
3024  to an unsigned long and stored in reference ref. Returns 1 if
3025  successful. Returns 0 if the name does not exist. If
3026  ival'th value does not exist, or if the printed
3027  representation of the value cannot be converted to an
3028  int, an error message is output and the program halts.
3029  Note that ival == 0 is the first value in the list.
3030  */
3031  int query (const char* name,
3032  unsigned long& ref,
3033  int ival=0) const;
3034 
3035  ///
3036  /** Get the ival'th value of last occurrence of the requested name.
3037  If successful, the value is converted to a float and stored
3038  in reference ref. If the name does not exist or
3039  ival'th value does not exist, or if the printed representation
3040  of the value cannot be converted to a float, an error message is
3041  output and the program halts. Note that ival == 0 is the first
3042  value in the list.
3043  */
3044  void get (const char* name,
3045  float& ref,
3046  int ival=0) const;
3047 
3048  ///
3049  /** Get the ival'th value of last occurrence of the
3050  requested name. If successful, the value is converted
3051  to a float and stored in reference ref. Returns 1 if
3052  successful. Returns 0 if the name does not exist. If
3053  ival'th value does not exist, or if the printed
3054  representation of the value cannot be converted to a float,
3055  an error message is output and the program halts.
3056  Note that ival == 0 is the first value in the list.
3057  */
3058  int query (const char* name,
3059  float& ref,
3060  int ival=0) const;
3061 
3062  ///
3063  /** Get the ival'th value of last occurrence of the requested name.
3064  If successful, the value is converted to a double and stored
3065  in reference ref. If the name does not exist or
3066  ival'th value does not exist, or if the printed representation
3067  of the value cannot be converted to a double, an error message is
3068  output and the program halts. Note that ival == 0 is the first
3069  value in the list.
3070  */
3071  void get (const char* name,
3072  double& ref,
3073  int ival=0) const;
3074 
3075  ///
3076  /** Get the ival'th value of last occurrence of the
3077  requested name. If successful, the value is converted
3078  to a double and stored in reference ref. Returns 1 if
3079  successful. Returns 0 if the name does not exist. If
3080  ival'th value does not exist, or if the printed
3081  representation of the value cannot be converted to a double,
3082  an error message is output and the program halts.
3083  Note that ival == 0 is the first value in the list.
3084  */
3085  int query (const char* name,
3086  double& ref,
3087  int ival=0) const;
3088 
3089  ///Get the ival'th value of last occurrence of the requested name.
3090  /** Get the ival'th value of last occurrence of the requested name.
3091  If successful, the value is converted to a string and stored
3092  in reference ref. If the name does not exist or
3093  ival'th value does not exist, or if the printed representation
3094  of the value cannot be converted to a string, an error message is
3095  output and the program halts. Note that ival == 0 is the first
3096  value in the list.
3097  */
3098  void get (const char* name,
3099  std::string& ref,
3100  int ival=0) const;
3101 
3102  ///Get the ival'th value of last occurrence of the requested name.
3103  /** Get the ival'th value of last occurrence of the
3104  requested name. If successful, the value is converted
3105  to a string and stored in reference ref. Returns 1 if
3106  successful. Returns 0 if the name does not exist. If
3107  ival'th value does not exist, or if the printed
3108  representation of the value cannot be converted to a string,
3109  an error message is output and the program halts.
3110  Note that ival == 0 is the first value in the list.
3111  */
3112  int query (const char* name,
3113  std::string& ref,
3114  int ival=0) const;
3115 
3116  /// Get the ival'th value of last occurrence of the requested name.
3117  /** Get the ival'th value of last occurrence of the requested name.
3118  If successful, the value is converted to a bool and stored
3119  in reference ref. If the name does not exist or
3120  ival'th value does not exist, or if the printed representation
3121  of the value cannot be converted to a bool, an error message is
3122  output and the program halts. Valid representations of bool
3123  are "true" and "false" (case is ignored), and numeric values
3124  1 (=true) and 0 (=false). Note that ival == 0 is the first
3125  value in the list.
3126  */
3127  void get (const char* name,
3128  bool& ref,
3129  int ival=0) const;
3130 
3131  ///Get the ival'th value of last occurrence of the requested name.
3132  /** Get the ival'th value of last occurrence of the
3133  requested name. If successful, the value is converted
3134  to a bool and stored in reference ref. Returns 1 if
3135  successful. Returns 0 if the name does not exist. If
3136  ival'th value does not exist, or if the printed
3137  representation of the value cannot be converted to a bool,
3138  an error message is output and the program halts.
3139  Valid representations of bool are "true" and "false"
3140  (case is ignored), and numeric values 1 (=true) and 0 (=false).
3141  Note that ival == 0 is the first value in the list.
3142  */
3143  int query (const char* name,
3144  bool& ref,
3145  int ival=0) const;
3146 
3147  /// access an array of objects
3148  /** Gets a std::vector<int> of num_val values from last
3149  occurrence of given name. If successful, the values
3150  are converted to an int and stored in the
3151  std::vector<int> object ref. ref is resized (if
3152  necessary) to hold num_val values. The value in the
3153  list indexed by start_ix is copied into
3154  std::vector<int>[0], std::vector<int>[1] holds
3155  start_ix+1, etc. If there are fewer than start_ix +
3156  num_val values associated with the last occurrence, or
3157  if some of the values cannot be converted to an int, an
3158  error message is reported and the program halts.
3159  */
3160  void getarr (const char* name,
3161  Vector<int>& ref,
3162  int start_ix,
3163  int num_val) const;
3164 
3165  /// access an array of objects
3166  /** Gets a std::vector<int> of num_val values from last
3167  occurrence of given name. If successful, the values
3168  are converted to an int and stored in the
3169  std::vector<int> object ref. ref is resized (if
3170  necessary) to hold num_val values. The value in the
3171  list indexed by start_ix is copied into
3172  std::vector<int>[0], std::vector<int>[1] holds
3173  start_ix+1, etc. If there are fewer than start_ix +
3174  num_val values associated with the last occurrence, or
3175  if some of the values cannot be converted to an int, an
3176  error message is reported and the program halts.
3177  */
3178  void getarr (const char* name,
3179  std::vector<int>& ref,
3180  int start_ix,
3181  int num_val) const;
3182 
3183  /// access an array of objects
3184  /** Gets a std::vector<int> of num_val values from last
3185  occurrence of given name. If successful, the values
3186  are converted to an int and stored in the
3187  std::vector<int> object ref. ref is resized (if
3188  necessary) to hold num_val values. The value in the
3189  list indexed by start_ix is copied into
3190  std::vector<int>[0], std::vector<int>[1] holds
3191  start_ix+1, etc. Returns 0 if the name does not
3192  exist. If there are fewer than start_ix + num_val
3193  values associated with the last occurrence, or if some
3194  of the values cannot be converted to an int, an error
3195  message is reported and the program halts.
3196  */
3197  int queryarr (const char* name,
3198  Vector<int>& ref,
3199  int start_ix,
3200  int num_val) const;
3201 
3202  /// access an array of objects
3203  /** Gets a std::vector<int> of num_val values from last
3204  occurrence of given name. If successful, the values
3205  are converted to an int and stored in the
3206  std::vector<int> object ref. ref is resized (if
3207  necessary) to hold num_val values. The value in the
3208  list indexed by start_ix is copied into
3209  std::vector<int>[0], std::vector<int>[1] holds
3210  start_ix+1, etc. Returns 0 if the name does not
3211  exist. If there are fewer than start_ix + num_val
3212  values associated with the last occurrence, or if some
3213  of the values cannot be converted to an int, an error
3214  message is reported and the program halts.
3215  */
3216  int queryarr (const char* name,
3217  std::vector<int>& ref,
3218  int start_ix,
3219  int num_val) const;
3220 
3221  /// access an array of objects
3222  /** Gets a std::vector<unsigned long> of num_val values from last
3223  occurrence of given name. If successful, the values
3224  are converted to an int and stored in the
3225  std::vector<unsigned long> object ref. ref is resized (if
3226  necessary) to hold num_val values. The value in the
3227  list indexed by start_ix is copied into
3228  std::vector<unsigned long>[0], std::vector<unsigned long>[1] holds
3229  start_ix+1, etc. If there are fewer than start_ix +
3230  num_val values associated with the last occurrence, or
3231  if some of the values cannot be converted to an unsigned long, an
3232  error message is reported and the program halts.
3233  */
3234  void getarr (const char* name,
3235  Vector<unsigned long>& ref,
3236  int start_ix,
3237  int num_val) const;
3238 
3239  /// access an array of objects
3240  /** Gets a std::vector<unsigned long> of num_val values from last
3241  occurrence of given name. If successful, the values
3242  are converted to an unsigned long and stored in the
3243  std::vector<unsigned long> object ref. ref is resized (if
3244  necessary) to hold num_val values. The value in the
3245  list indexed by start_ix is copied into
3246  std::vector<unsigned long>[0], std::vector<unsigned long>[1] holds
3247  start_ix+1, etc. If there are fewer than start_ix +
3248  num_val values associated with the last occurrence, or
3249  if some of the values cannot be converted to an unsigned long, an
3250  error message is reported and the program halts.
3251  */
3252  void getarr (const char* name,
3253  std::vector<unsigned long>& ref,
3254  int start_ix,
3255  int num_val) const;
3256 
3257  /// access an array of objects
3258  /** Gets a std::vector<unsigned long> of num_val values from last
3259  occurrence of given name. If successful, the values
3260  are converted to an unsigned long and stored in the
3261  std::vector<unsigned long> object ref. ref is resized (if
3262  necessary) to hold num_val values. The value in the
3263  list indexed by start_ix is copied into
3264  std::vector<unsigned long>[0], std::vector<unsigned long>[1] holds
3265  start_ix+1, etc. Returns 0 if the name does not
3266  exist. If there are fewer than start_ix + num_val
3267  values associated with the last occurrence, or if some
3268  of the values cannot be converted to an unsigned long, an error
3269  message is reported and the program halts.
3270  */
3271  int queryarr (const char* name,
3272  Vector<unsigned long>& ref,
3273  int start_ix,
3274  int num_val) const;
3275 
3276  /// access an array of objects
3277  /** Gets a std::vector<unsigned long> of num_val values from last
3278  occurrence of given name. If successful, the values
3279  are converted to an unsigned long and stored in the
3280  std::vector<unsigned long> object ref. ref is resized (if
3281  necessary) to hold num_val values. The value in the
3282  list indexed by start_ix is copied into
3283  std::vector<unsigned long>[0], std::vector<unsigned long>[1] holds
3284  start_ix+1, etc. Returns 0 if the name does not
3285  exist. If there are fewer than start_ix + num_val
3286  values associated with the last occurrence, or if some
3287  of the values cannot be converted to an unsigned long, an error
3288  message is reported and the program halts.
3289  */
3290  int queryarr (const char* name,
3291  std::vector<unsigned long>& ref,
3292  int start_ix,
3293  int num_val) const;
3294 
3295  /// access an array
3296  /** Gets a std::vector<float> of num_val values from last
3297  occurrence of given name. If successful, the values
3298  are converted to a float and stored in the
3299  std::vector<float> object ref. ref is resized (if
3300  necessary) to hold num_val values. The value in the
3301  list indexed by start_ix is copied into
3302  std::vector<float>[0], std::vector<float>[1] holds
3303  start_ix+1, etc. If there are fewer than start_ix +
3304  num_val values associated with the last occurrence, or
3305  if some of the values cannot be converted to a float, an
3306  error message is reported and the program halts.
3307  */
3308  void getarr (const char* name,
3309  Vector<float>& ref,
3310  int start_ix,
3311  int num_val) const;
3312 
3313  /// access an array
3314  /** Gets a std::vector<float> of num_val values from last
3315  occurrence of given name. If successful, the values
3316  are converted to a float and stored in the
3317  std::vector<float> object ref. ref is resized (if
3318  necessary) to hold num_val values. The value in the
3319  list indexed by start_ix is copied into
3320  std::vector<float>[0], std::vector<float>[1] holds
3321  start_ix+1, etc. If there are fewer than start_ix +
3322  num_val values associated with the last occurrence, or
3323  if some of the values cannot be converted to a float, an
3324  error message is reported and the program halts.
3325  */
3326  void getarr (const char* name,
3327  std::vector<float>& ref,
3328  int start_ix,
3329  int num_val) const;
3330 
3331  ///
3332  /** Gets a std::vector<float> of num_val values from last
3333  occurrence of given name. If successful, the values
3334  are converted to a float and stored in the
3335  std::vector<float> object ref. ref is resized (if
3336  necessary) to hold num_val values. The value in the
3337  list indexed by start_ix is copied into
3338  std::vector<float>[0], std::vector<float>[1] holds
3339  start_ix+1, etc. Returns 0 if the name does not
3340  exist. If there are fewer than start_ix + num_val
3341  values associated with the last occurrence, or if some
3342  of the values cannot be converted to a float, an error
3343  message is reported and the program halts.
3344  */
3345  int queryarr (const char* name,
3346  Vector<float>& ref,
3347  int start_ix,
3348  int num_val) const;
3349 
3350  ///
3351  /** Gets a std::vector<float> of num_val values from last
3352  occurrence of given name. If successful, the values
3353  are converted to a float and stored in the
3354  std::vector<float> object ref. ref is resized (if
3355  necessary) to hold num_val values. The value in the
3356  list indexed by start_ix is copied into
3357  std::vector<float>[0], std::vector<float>[1] holds
3358  start_ix+1, etc. Returns 0 if the name does not
3359  exist. If there are fewer than start_ix + num_val
3360  values associated with the last occurrence, or if some
3361  of the values cannot be converted to a float, an error
3362  message is reported and the program halts.
3363  */
3364  int queryarr (const char* name,
3365  std::vector<float>& ref,
3366  int start_ix,
3367  int num_val) const;
3368 
3369  ///
3370  /** Gets a std::vector<double> of num_val values from last
3371  occurrence of given name. If successful, the values
3372  are converted to a double and stored in the
3373  std::vector<double> object ref. ref is resized (if
3374  necessary) to hold num_val values. The value in the
3375  list indexed by start_ix is copied into
3376  std::vector<double>[0], std::vector<double>[1] holds
3377  start_ix+1, etc. If there are fewer than start_ix +
3378  num_val values associated with the last occurrence, or
3379  if some of the values cannot be converted to a double, an
3380  error message is reported and the program halts.
3381  */
3382  void getarr (const char* name,
3383  Vector<double>& ref,
3384  int start_ix,
3385  int num_val) const;
3386 
3387  ///
3388  /** Gets a std::vector<double> of num_val values from last
3389  occurrence of given name. If successful, the values
3390  are converted to a double and stored in the
3391  std::vector<double> object ref. ref is resized (if
3392  necessary) to hold num_val values. The value in the
3393  list indexed by start_ix is copied into
3394  std::vector<double>[0], std::vector<double>[1] holds
3395  start_ix+1, etc. If there are fewer than start_ix +
3396  num_val values associated with the last occurrence, or
3397  if some of the values cannot be converted to a double, an
3398  error message is reported and the program halts.
3399  */
3400  void getarr (const char* name,
3401  std::vector<double>& ref,
3402  int start_ix,
3403  int num_val) const;
3404 
3405  ///
3406  /** Gets a std::vector<double> of num_val values from last
3407  occurrence of given name. If successful, the values
3408  are converted to a double and stored in the
3409  std::vector<double> object ref. ref is resized (if
3410  necessary) to hold num_val values. The value in the
3411  list indexed by start_ix is copied into
3412  std::vector<double>[0], std::vector<double>[1] holds
3413  start_ix+1, etc. Returns 0 if the name does not
3414  exist. If there are fewer than start_ix + num_val
3415  values associated with the last occurrence, or if some
3416  of the values cannot be converted to a double, an error
3417  message is reported and the program halts.
3418  */
3419  int queryarr (const char* name,
3420  Vector<double>& ref,
3421  int start_ix,
3422  int num_val) const;
3423 
3424  ///
3425  /** Gets a std::vector<double> of num_val values from last
3426  occurrence of given name. If successful, the values
3427  are converted to a double and stored in the
3428  std::vector<double> object ref. ref is resized (if
3429  necessary) to hold num_val values. The value in the
3430  list indexed by start_ix is copied into
3431  std::vector<double>[0], std::vector<double>[1] holds
3432  start_ix+1, etc. Returns 0 if the name does not
3433  exist. If there are fewer than start_ix + num_val
3434  values associated with the last occurrence, or if some
3435  of the values cannot be converted to a double, an error
3436  message is reported and the program halts.
3437  */
3438  int queryarr (const char* name,
3439  std::vector<double>& ref,
3440  int start_ix,
3441  int num_val) const;
3442 
3443  ///
3444  /** Gets a std::vector<string> of num_val values from last
3445  occurrence of given name. If successful, the values
3446  are converted to a string and stored in the
3447  std::vector<string> object ref. ref is resized (if
3448  necessary) to hold num_val values. The value in the
3449  list indexed by start_ix is copied into
3450  std::vector<string>[0], std::vector<string>[1] holds
3451  start_ix+1, etc. If there are fewer than start_ix +
3452  num_val values associated with the last occurrence, or
3453  if some of the values cannot be converted to a string, an
3454  error message is reported and the program halts.
3455  */
3456  void getarr (const char* name,
3457  Vector<std::string>& ref,
3458  int start_ix,
3459  int num_val) const;
3460 
3461  ///
3462  /** Gets a std::vector<string> of num_val values from last
3463  occurrence of given name. If successful, the values
3464  are converted to a string and stored in the
3465  std::vector<string> object ref. ref is resized (if
3466  necessary) to hold num_val values. The value in the
3467  list indexed by start_ix is copied into
3468  std::vector<string>[0], std::vector<string>[1] holds
3469  start_ix+1, etc. If there are fewer than start_ix +
3470  num_val values associated with the last occurrence, or
3471  if some of the values cannot be converted to a string, an
3472  error message is reported and the program halts.
3473  */
3474  void getarr (const char* name,
3475  std::vector<std::string>& ref,
3476  int start_ix,
3477  int num_val) const;
3478 
3479  ///
3480  /** Gets a std::vector<string> of num_val values from last
3481  occurrence of given name. If successful, the values
3482  are converted to a string and stored in the
3483  std::vector<string> object ref. ref is resized (if
3484  necessary) to hold num_val values. The value in the
3485  list indexed by start_ix is copied into
3486  std::vector<string>[0], std::vector<string>[1] holds
3487  start_ix+1, etc. Returns 0 if the name does not
3488  exist. If there are fewer than start_ix + num_val
3489  values associated with the last occurrence, or if some
3490  of the values cannot be converted to a string, an error
3491  message is reported and the program halts.
3492  */
3493  int queryarr (const char* name,
3494  Vector<std::string>& ref,
3495  int start_ix,
3496  int num_val) const;
3497 
3498  ///
3499  /** Gets a std::vector<string> of num_val values from last
3500  occurrence of given name. If successful, the values
3501  are converted to a string and stored in the
3502  std::vector<string> object ref. ref is resized (if
3503  necessary) to hold num_val values. The value in the
3504  list indexed by start_ix is copied into
3505  std::vector<string>[0], std::vector<string>[1] holds
3506  start_ix+1, etc. Returns 0 if the name does not
3507  exist. If there are fewer than start_ix + num_val
3508  values associated with the last occurrence, or if some
3509  of the values cannot be converted to a string, an error
3510  message is reported and the program halts.
3511  */
3512  int queryarr (const char* name,
3513  std::vector<std::string>& ref,
3514  int start_ix,
3515  int num_val) const;
3516 
3517 ///
3518  /** Gets a std::vector<bool> of num_val values from last
3519  occurrence of given name. If successful, the values
3520  are converted to a bool and stored in the
3521  std::vector<bool> object ref. ref is resized (if
3522  necessary) to hold num_val values. The value in the
3523  list indexed by start_ix is copied into
3524  std::vector<bool>[0], std::vector<bool>[1] holds
3525  start_ix+1, etc. If there are fewer than start_ix +
3526  num_val values associated with the last occurrence, or
3527  if some of the values cannot be converted to a bool, an
3528  error message is reported and the program halts.
3529  */
3530  void getarr (const char* name,
3531  Vector<bool>& ref,
3532  int start_ix,
3533  int num_val) const;
3534 
3535  ///
3536  /** Gets a std::vector<bool> of num_val values from last
3537  occurrence of given name. If successful, the values
3538  are converted to a bool and stored in the
3539  std::vector<bool> object ref. ref is resized (if
3540  necessary) to hold num_val values. The value in the
3541  list indexed by start_ix is copied into
3542  std::vector<bool>[0], std::vector<bool>[1] holds
3543  start_ix+1, etc. If there are fewer than start_ix +
3544  num_val values associated with the last occurrence, or
3545  if some of the values cannot be converted to a bool, an
3546  error message is reported and the program halts.
3547  */
3548  void getarr (const char* name,
3549  std::vector<bool>& ref,
3550  int start_ix,
3551  int num_val) const;
3552 
3553  ///
3554  /** Gets a std::vector<bool> of num_val values from last
3555  occurrence of given name. If successful, the values
3556  are converted to a bool and stored in the
3557  std::vector<bool> object ref. ref is resized (if
3558  necessary) to hold num_val values. The value in the
3559  list indexed by start_ix is copied into
3560  std::vector<bool>[0], std::vector<bool>[1] holds
3561  start_ix+1, etc. Returns 0 if the name does not
3562  exist. If there are fewer than start_ix + num_val
3563  values associated with the last occurrence, or if some
3564  of the values cannot be converted to a bool, an error
3565  message is reported and the program halts.
3566  */
3567  int queryarr (const char* name,
3568  Vector<bool>& ref,
3569  int start_ix,
3570  int num_val) const;
3571 
3572  ///
3573  /** Gets a std::vector<bool> of num_val values from last
3574  occurrence of given name. If successful, the values
3575  are converted to a bool and stored in the
3576  std::vector<bool> object ref. ref is resized (if
3577  necessary) to hold num_val values. The value in the
3578  list indexed by start_ix is copied into
3579  std::vector<bool>[0], std::vector<bool>[1] holds
3580  start_ix+1, etc. Returns 0 if the name does not
3581  exist. If there are fewer than start_ix + num_val
3582  values associated with the last occurrence, or if some
3583  of the values cannot be converted to a bool, an error
3584  message is reported and the program halts.
3585  */
3586  int queryarr (const char* name,
3587  std::vector<bool>& ref,
3588  int start_ix,
3589  int num_val) const;
3590 
3591  /// return prefix
3592  inline const char* prefix() const
3593  {
3594  return thePrefix.c_str();
3595  }
3596 
3597 #ifndef DOXYGEN
3598  //
3599  // This should be protected, but cfront-derived compilers complain :-(
3600  //
3601  enum PPType
3602  {
3603  ppDefn,
3604  ppOption,
3605  ppInt,
3606  ppUnsignedLong,
3607  ppFloat,
3608  ppDouble,
3609  ppString,
3610  ppBool,
3611  ppEQ_sign,
3612  ppEOF
3613  };
3614 
3615 
3616 protected:
3617  //
3618  // Table of entries common to all objects.
3619  //
3620  static PP_List<PP_entry*> table;
3621  //
3622  // Command line arguments.
3623  //
3624  static int xargc;
3625  static char** xargv;
3626  //
3627  // Keep track of number of ParmParse objects out there.
3628  //
3629  static int num_obj;
3630  //
3631  // Parses string and builds table.
3632  //
3633  void bldTable (const char* str,
3634  int lenstr,
3635  PP_List<PP_entry*>& tab);
3636  //
3637  // Add defn to table, check for file inclusion.
3638  //
3639  void addDefn (PP_String& def,
3640  PP_List<PP_String>& val,
3641  PP_List<PP_entry*>& tab);
3642  //
3643  // Reads file into string then parses it with call to bldTable.
3644  //
3645  void read_file (const char* fname,
3646  PP_List<PP_entry*>& tab);
3647  //
3648  // Lexical analyser called by bldTable.
3649  //
3650  PPType getToken (const char*,
3651  int&,
3652  int,
3653  char*);
3654  //
3655  // Reclaims memory used in table.
3656  //
3657  void rmTable ();
3658  //
3659  // Prefix used in keyword search.
3660  //
3661  PP_String thePrefix;
3662  //
3663  // Used by constructor to build table.
3664  //
3665  void ppinit (const char* parfile);
3666  //
3667  // Find n'th occurence of name in table.
3668  //
3669  const PP_entry* ppindex (int n,
3670  const char* name) const;
3671  //
3672  // Get ival_th value of k_th occurence of given name.
3673  // If k_th occurence does not exist or ival_th value does
3674  // not exist or if ival_type does not match with type, an
3675  // error message is reported and the program halts.
3676  // If successful, value is stored in ptr.
3677  // same as above but searches for last occurence of name.
3678  //
3679  void getval (const char* name,
3680  const PPType type,
3681  void* ptr,
3682  int ival,
3683  int k=-1) const;
3684 public:
3685  //
3686  // Get an array of values.
3687  //
3688  void getarr (const char* name,
3689  const PPType type,
3690  void* ptr,
3691  int start_ix,
3692  int num_val,
3693  int k=-1) const;
3694  int queryval (const char* name,
3695  const PPType type,
3696  void* ptr,
3697  int ival,
3698  int k=-1) const;
3699  int queryarr (const char* name,
3700  const PPType type,
3701  void* ptr,
3702  int start_ix,
3703  int num_val,
3704  int k=-1) const;
3705 
3706 private:
3707  bool isInteger (const PP_String& str, int& val) const;
3708  bool isUnsigned(const PP_String& str, unsigned long& val) const;
3709  int isDouble (const PP_String& str, double& val) const;
3710  bool isBool (const PP_String& str, bool& val) const;
3711 
3712 #endif /* DOXYGEN ENDIF */
3713 
3714 };
3715 
3716 #ifndef DOXYGEN
3717 class PP_entry
3718 {
3719 private:
3720  friend class ParmParse;
3721  PP_entry()
3722  {}
3723 
3724  PP_entry (PP_String& name,
3725  ParmParse::PPType typ,
3726  PP_List<PP_String>& vals);
3727 
3728  ~PP_entry()
3729  {}
3730 
3731  PP_String defname;
3732  ParmParse::PPType deftype;
3733  PP_Array<PP_String> val;
3734 
3735  void dump (std::ostream& os) const;
3736 };
3737 #endif //doxygen
3738 
3739 //
3740 // Inlines.
3741 //
3742 
3743 inline
3744 int
3746  int n) const
3747 {
3748  //
3749  // First find n'th occurance of name in table.
3750  //
3751  const PP_entry* def = ppindex(n,name);
3752  return def == 0 ? 0 : def->val.length();
3753 }
3754 
3755 inline
3756 void
3757 ParmParse::get (const char* name,
3758  int& ptr,
3759  int ival) const
3760 {
3761  getval(name,ppInt,&ptr,ival,-1);
3762 }
3763 
3764 inline
3765 int
3766 ParmParse::query (const char* name,
3767  int& ptr,
3768  int ival) const
3769 {
3770  return queryval(name,ppInt,&ptr,ival,-1);
3771 }
3772 
3773 inline
3774 void
3775 ParmParse::get (const char* name,
3776  unsigned long& ptr,
3777  int ival) const
3778 {
3779  getval(name,ppUnsignedLong,&ptr,ival,-1);
3780 }
3781 
3782 inline
3783 int
3784 ParmParse::query (const char* name,
3785  unsigned long& ptr,
3786  int ival) const
3787 {
3788  return queryval(name,ppUnsignedLong,&ptr,ival,-1);
3789 }
3790 
3791 inline
3792 void
3793 ParmParse::get (const char* name,
3794  float& ptr,
3795  int ival) const
3796 {
3797  getval(name,ppFloat,&ptr,ival,-1);
3798 }
3799 
3800 inline
3801 int
3802 ParmParse::query (const char* name,
3803  float& ptr,
3804  int ival) const
3805 {
3806  return queryval(name,ppFloat,&ptr,ival,-1);
3807 }
3808 
3809 inline
3810 void
3811 ParmParse::get (const char* name,
3812  double& ptr,
3813  int ival) const
3814 {
3815  getval(name,ppDouble,&ptr,ival,-1);
3816 }
3817 
3818 inline
3819 int
3820 ParmParse::query (const char* name,
3821  double& ptr,
3822  int ival) const
3823 {
3824  return queryval(name,ppDouble,&ptr,ival,-1);
3825 }
3826 
3827 inline
3828 void
3829 ParmParse::get (const char* name,
3830  std::string& ptr,
3831  int ival) const
3832 {
3833  PP_String pp_string;
3834  getval(name,ppString,&pp_string,ival,-1);
3835  ptr = pp_string.c_str();
3836 }
3837 
3838 inline
3839 int
3840 ParmParse::query (const char* name,
3841  std::string& ptr,
3842  int ival) const
3843 {
3844  PP_String pp_string;
3845  int status = queryval(name,ppString,&pp_string,ival,-1);
3846  if (status != 0)
3847  ptr = pp_string.c_str();
3848  return status;
3849 }
3850 
3851 inline
3852 void
3853 ParmParse::get(const char* name,
3854  bool& ptr,
3855  int ival) const
3856 {
3857  getval(name,ppBool,&ptr,ival,-1);
3858 }
3859 
3860 inline
3861 int
3862 ParmParse::query (const char* name,
3863  bool& ptr,
3864  int ival) const
3865 {
3866  return queryval(name,ppBool,&ptr,ival,-1);
3867 }
3868 
3869 inline
3870 void
3872  std::vector<int>& ptr,
3873  int start_ix,
3874  int num_val) const
3875 {
3876  if (ptr.size() < num_val)
3877  ptr.resize(num_val);
3878  int* c_array = new int[num_val];
3879  getarr(name,ppInt,c_array,start_ix,num_val,-1);
3880  for (int i = 0; i < num_val; ++i)
3881  {
3882  ptr[i] = c_array[i];
3883  }
3884  delete[] c_array;
3885 }
3886 
3887 inline
3888 void
3890  Vector<int>& ptr,
3891  int start_ix,
3892  int num_val) const
3893 {
3894  if (ptr.size() < num_val)
3895  ptr.resize(num_val);
3896  int* c_array = new int[num_val];
3897  getarr(name,ppInt,c_array,start_ix,num_val,-1);
3898  for (int i = 0; i < num_val; ++i)
3899  {
3900  ptr[i] = c_array[i];
3901  }
3902  delete[] c_array;
3903 }
3904 
3905 inline
3906 int
3908  std::vector<int>& ptr,
3909  int start_ix,
3910  int num_val) const
3911 {
3912  if (ptr.size() < num_val)
3913  ptr.resize(num_val);
3914  int* c_array = new int[num_val];
3915  int status = queryarr(name,ppInt,c_array,start_ix,num_val,-1);
3916  if (status != 0 )
3917  {
3918  for (int i = 0; i < num_val; ++i)
3919  {
3920  ptr[i] = c_array[i];
3921  }
3922  }
3923  delete [] c_array;
3924  return status;
3925 }
3926 
3927 inline
3928 int
3930  Vector<int>& ptr,
3931  int start_ix,
3932  int num_val) const
3933 {
3934  if (ptr.size() < num_val)
3935  ptr.resize(num_val);
3936  int* c_array = new int[num_val];
3937  int status = queryarr(name,ppInt,c_array,start_ix,num_val,-1);
3938  if (status != 0 )
3939  {
3940  for (int i = 0; i < num_val; ++i)
3941  {
3942  ptr[i] = c_array[i];
3943  }
3944  }
3945  return status;
3946 }
3947 
3948 inline
3949 void
3951  std::vector<float>& ptr,
3952  int start_ix,
3953  int num_val) const
3954 {
3955  if (ptr.size() < num_val)
3956  ptr.resize(num_val);
3957  float* c_array = new float[num_val];
3958  getarr(name,ppFloat,c_array,start_ix,num_val,-1);
3959  for (int i = 0; i < num_val; ++i)
3960  {
3961  ptr[i] = c_array[i];
3962  }
3963  delete[] c_array;
3964 }
3965 
3966 inline
3967 void
3969  Vector<float>& ptr,
3970  int start_ix,
3971  int num_val) const
3972 {
3973  if (ptr.size() < num_val)
3974  ptr.resize(num_val);
3975  float* c_array = new float[num_val];
3976  getarr(name,ppFloat,c_array,start_ix,num_val,-1);
3977  for (int i = 0; i < num_val; ++i)
3978  {
3979  ptr[i] = c_array[i];
3980  }
3981  delete[] c_array;
3982 }
3983 
3984 inline
3985 int
3987  std::vector<float>& ptr,
3988  int start_ix,
3989  int num_val) const
3990 {
3991  if (ptr.size() < num_val)
3992  ptr.resize(num_val);
3993  float* c_array = new float[num_val];
3994  int status = queryarr(name,ppFloat,c_array,start_ix,num_val,-1);
3995  if (status != 0)
3996  {
3997  for (int i = 0; i < num_val; ++i)
3998  {
3999  ptr[i] = c_array[i];
4000  }
4001  }
4002  delete[] c_array;
4003  return status;
4004 }
4005 
4006 inline
4007 int
4009  Vector<float>& ptr,
4010  int start_ix,
4011  int num_val) const
4012 {
4013  if (ptr.size() < num_val)
4014  ptr.resize(num_val);
4015  float* c_array = new float[num_val];
4016  int status = queryarr(name,ppFloat,c_array,start_ix,num_val,-1);
4017  if (status != 0)
4018  {
4019  for (int i = 0; i < num_val; ++i)
4020  {
4021  ptr[i] = c_array[i];
4022  }
4023  }
4024  delete[] c_array;
4025  return status;
4026 }
4027 
4028 inline
4029 void
4031  std::vector<double>& ptr,
4032  int start_ix,
4033  int num_val) const
4034 {
4035  if (ptr.size() < num_val)
4036  ptr.resize(num_val);
4037  double* c_array = new double[num_val];
4038  int status = queryarr(name,ppDouble,c_array,start_ix,num_val,-1);
4039  if (status == 0)
4040  {
4041  cerr << "ParmParse::getarr(): "
4042  << name
4043  << " not found in table" << endl;
4044  dumpTable(cerr);
4045  MayDay::Abort();
4046  }
4047  for (int i = 0; i < num_val; ++i)
4048  {
4049  ptr[i] = c_array[i];
4050  }
4051  delete[] c_array;
4052 }
4053 
4054 inline
4055 void
4057  Vector<double>& ptr,
4058  int start_ix,
4059  int num_val) const
4060 {
4061  if (ptr.size() < num_val)
4062  ptr.resize(num_val);
4063  double* c_array = new double[num_val];
4064  int status = queryarr(name,ppDouble,c_array,start_ix,num_val,-1);
4065  if (status == 0)
4066  {
4067  cerr << "ParmParse::getarr(): "
4068  << name
4069  << " not found in table" << endl;
4070  dumpTable(cerr);
4071  MayDay::Abort();
4072  }
4073  for (int i = 0; i < num_val; ++i)
4074  {
4075  ptr[i] = c_array[i];
4076  }
4077  delete[] c_array;
4078 }
4079 
4080 inline
4081 int
4083  std::vector<double>& ptr,
4084  int start_ix,
4085  int num_val) const
4086 {
4087  if (ptr.size() < num_val)
4088  ptr.resize(num_val);
4089  double* c_array = new double[num_val];
4090  int status = queryarr(name,ppDouble,c_array,start_ix,num_val,-1);
4091  if (status != 0)
4092  {
4093  for (int i = 0; i < num_val; ++i)
4094  {
4095  ptr[i] = c_array[i];
4096  }
4097  }
4098  delete[] c_array;
4099  return status;
4100 }
4101 
4102 inline
4103 int
4105  Vector<double>& ptr,
4106  int start_ix,
4107  int num_val) const
4108 {
4109  if (ptr.size() < num_val)
4110  ptr.resize(num_val);
4111  double* c_array = new double[num_val];
4112  int status = queryarr(name,ppDouble,c_array,start_ix,num_val,-1);
4113  if (status != 0)
4114  {
4115  for (int i = 0; i < num_val; ++i)
4116  {
4117  ptr[i] = c_array[i];
4118  }
4119  }
4120  delete[] c_array;
4121  return status;
4122 }
4123 
4124 inline
4125 void
4127  std::vector<std::string>& ptr,
4128  int start_ix,
4129  int num_val) const
4130 {
4131  if (ptr.size() < num_val)
4132  ptr.resize(num_val);
4133  PP_String* c_array = new PP_String[num_val];
4134  getarr(name,ppString,c_array,start_ix,num_val,-1);
4135  for (int i = 0; i < num_val; ++i)
4136  {
4137  ptr[i] = c_array[i].c_str();
4138  }
4139  delete[] c_array;
4140 }
4141 
4142 inline
4143 void
4145  Vector<std::string>& ptr,
4146  int start_ix,
4147  int num_val) const
4148 {
4149  if (ptr.size() < num_val)
4150  ptr.resize(num_val);
4151  PP_String* c_array = new PP_String[num_val];
4152  getarr(name,ppString,c_array,start_ix,num_val,-1);
4153  for (int i = 0; i < num_val; ++i)
4154  {
4155  ptr[i] = c_array[i].c_str();
4156  }
4157  delete[] c_array;
4158 }
4159 
4160 inline
4161 int
4163  std::vector<std::string>& ptr,
4164  int start_ix,
4165  int num_val) const
4166 {
4167  if (ptr.size() < num_val)
4168  ptr.resize(num_val);
4169  PP_String* c_array = new PP_String[num_val];
4170  int status = queryarr(name,ppString,c_array,start_ix,num_val,-1);
4171  if (status != 0)
4172  {
4173  for (int i = 0; i < num_val; ++i)
4174  {
4175  ptr[i] = c_array[i].c_str();
4176  }
4177  }
4178  delete[] c_array;
4179  return status;
4180 }
4181 
4182 inline
4183 int
4185  Vector<std::string>& ptr,
4186  int start_ix,
4187  int num_val) const
4188 {
4189  if (ptr.size() < num_val)
4190  ptr.resize(num_val);
4191  PP_String* c_array = new PP_String[num_val];
4192  int status = queryarr(name,ppString,c_array,start_ix,num_val,-1);
4193  if (status != 0)
4194  {
4195  for (int i = 0; i < num_val; ++i)
4196  {
4197  ptr[i] = c_array[i].c_str();
4198  }
4199  }
4200  delete[] c_array;
4201  return status;
4202 }
4203 
4204 // ----------------------------------------
4205 inline
4206 void
4208  std::vector<bool>& ptr,
4209  int start_ix,
4210  int num_val) const
4211 {
4212  if (ptr.size() < num_val)
4213  ptr.resize(num_val);
4214  bool* c_array = new bool[num_val];
4215  getarr(name,ppBool,c_array,start_ix,num_val,-1);
4216  for (int i = 0; i < num_val; ++i)
4217  {
4218  ptr[i] = c_array[i];
4219  }
4220  delete[] c_array;
4221 }
4222 
4223 inline
4224 int
4226  std::vector<bool>& ptr,
4227  int start_ix,
4228  int num_val) const
4229 {
4230  if (ptr.size() < num_val)
4231  ptr.resize(num_val);
4232  bool* c_array = new bool[num_val];
4233  int status = queryarr(name,ppBool,c_array,start_ix,num_val,-1);
4234  if (status != 0 )
4235  {
4236  for (int i = 0; i < num_val; ++i)
4237  {
4238  ptr[i] = c_array[i];
4239  }
4240  }
4241  delete [] c_array;
4242  return status;
4243 }
4244 
4245 // ---------------------------------------
4246 
4247 inline
4248 bool
4249 ParmParse::isInteger (const PP_String& str,
4250  int& val) const
4251 {
4252  //
4253  // Start token scan.
4254  //
4255  char* endp = 0;
4256  val = (int) strtol(str.c_str(), &endp, 10);
4257  return *endp == 0;
4258 }
4259 
4260 inline
4261 bool
4262 ParmParse::isUnsigned (const PP_String& str,
4263  unsigned long & val) const
4264 {
4265  char* endp = 0;
4266  val = strtoul(str.c_str(), &endp, 10);
4267  return *endp == 0;
4268 }
4269 
4270 inline
4271 int
4272 ParmParse::isDouble (const PP_String& str,
4273  double& val) const
4274 {
4275  char* endp = 0;
4276  val = std::strtod(str.c_str(), &endp);
4277  return *endp == 0;
4278 }
4279 
4280 inline
4281 bool
4282 ParmParse::isBool (const PP_String& str,
4283  bool& val) const
4284 {
4285  PP_String str_lc( str );
4286  str_lc.toLower();
4287  if ( str_lc == "true" || str_lc == "1" )
4288  {
4289  return val = true ;
4290  }
4291  else if ( str_lc == "false" || str_lc == "0" )
4292  {
4293  val = false ;
4294  return true ;
4295  }
4296  else
4297  {
4298  return false ;
4299  }
4300 }
4301 
4302 inline
4303 int
4304 ParmParse::countname (const std::string& name) const
4305 {
4306  return countname(name.c_str());
4307 }
4308 
4309 #include "BaseNamespaceFooter.H"
4310 #endif /*CH_PARMPARSE_H*/
friend class PP_entry
Definition: ParmParse.H:2851
int countname(const char *name) const
#define CH_assert(cond)
Definition: CHArray.H:37
void setStr(const std::string &varName, std::string varVal)
Definition: ParmParse.H:2969
void define(int argc, char **argv, const char *prefix=0, const char *parfile=0)
Initialize after calling the default constructor.
int isEmpty(const box2d *)
int countval(const char *name, int n=-1) const
Definition: ParmParse.H:3745
Parse Parameters From Command Line and Input Files.
Definition: ParmParse.H:2849
void dumpTable(std::ostream &os) const
void resize(unsigned int isize)
Definition: Vector.H:346
int query(const char *name, int &ref, int ival=0) const
Definition: ParmParse.H:3766
std::ostream & operator<<(std::ostream &a_os, const IndexTM< T, N > &a_iv)
void get(const char *name, int &ref, int ival=0) const
access single object
Definition: ParmParse.H:3757
C::self_type operator+(const C &, const C &)
Definition: GenericArithmeticI.H:120
const char * name(const FArrayBox &a_dummySpecializationArg)
Definition: CH_HDF5.H:864
std::istream & operator>>(std::istream &a_os, IndexTM< T, N > &a_iv)
bool operator<(const FaceIndex &f1, const FaceIndex &f2)
Definition: FaceIndex.H:212
ParmParse(int argc, char **argv, const char *prefix=0, const char *parfile=0)
bool contains(const char *name) const
int queryarr(const char *name, Vector< int > &ref, int start_ix, int num_val) const
access an array of objects
Definition: ParmParse.H:3929
void setVal(const std::string &varName, TYPE varVal)
Definition: ParmParse.H:2950
void const char const int const int const int * K
Definition: Lapack.H:83
void getarr(const char *name, Vector< int > &ref, int start_ix, int num_val) const
access an array of objects
Definition: ParmParse.H:3889
T Min(const T &a_a, const T &a_b)
Definition: Misc.H:26
size_t size() const
Definition: Vector.H:192
C::self_type operator*(const C &, const C &)
Definition: GenericArithmeticI.H:128
void addEntries(const std::string &strEntry)
Definition: ParmParse.H:2932
const char * prefix() const
return prefix
Definition: ParmParse.H:3592
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).