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