]> git.mxchange.org Git - simgear.git/blob - simgear/misc/props.hxx
- changed getAttribute to avoid MSVC compiler warning
[simgear.git] / simgear / misc / props.hxx
1 /**
2  * \file props.hxx
3  * Interface definition for a property list.
4  * Started Fall 2000 by David Megginson, david@megginson.com
5  * This code is released into the Public Domain.
6  *
7  * See props.html for documentation [replace with URL when available].
8  *
9  * $Id$
10  */
11
12 #ifndef __PROPS_HXX
13 #define __PROPS_HXX
14
15 #include <simgear/compiler.h>
16
17 #include <stdio.h>
18
19 #include STL_STRING
20 #include <vector>
21 #include STL_IOSTREAM
22
23 SG_USING_STD(string);
24 SG_USING_STD(vector);
25 #if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
26 SG_USING_STD(istream);
27 SG_USING_STD(ostream);
28 #endif
29
30 #ifdef NONE
31 #pragma warn A sloppy coder has defined NONE as a macro!
32 #undef NONE
33 #endif
34
35 #ifdef ALIAS
36 #pragma warn A sloppy coder has defined ALIAS as a macro!
37 #undef ALIAS
38 #endif
39
40 #ifdef UNSPECIFIED
41 #pragma warn A sloppy coder has defined UNSPECIFIED as a macro!
42 #undef UNSPECIFIED
43 #endif
44
45 #ifdef BOOL
46 #pragma warn A sloppy coder has defined BOOL as a macro!
47 #undef BOOL
48 #endif
49
50 #ifdef INT
51 #pragma warn A sloppy coder has defined INT as a macro!
52 #undef INT
53 #endif
54
55 #ifdef LONG
56 #pragma warn A sloppy coder has defined LONG as a macro!
57 #undef LONG
58 #endif
59
60 #ifdef FLOAT
61 #pragma warn A sloppy coder has defined FLOAT as a macro!
62 #undef FLOAT
63 #endif
64
65 #ifdef DOUBLE
66 #pragma warn A sloppy coder has defined DOUBLE as a macro!
67 #undef DOUBLE
68 #endif
69
70 #ifdef STRING
71 #pragma warn A sloppy coder has defined STRING as a macro!
72 #undef STRING
73 #endif
74
75
76 \f
77 ////////////////////////////////////////////////////////////////////////
78 // A raw value.
79 //
80 // This is the mechanism that information-providing routines can
81 // use to link their own values to the property manager.  Any
82 // SGValue can be tied to a raw value and then untied again.
83 ////////////////////////////////////////////////////////////////////////
84
85
86 /**
87  * Abstract base class for a raw value.
88  *
89  * The property manager is implemented in three layers.  The {@link
90  * SGPropertyNode} is the highest and most abstract layer,
91  * representing * an LValue/RValue pair: it * records the position
92  * of the property in the property tree and * contains facilities
93  * for navigation to other nodes.  Each node * may contain an {@link
94  * SGValue}, which is guaranteed persistent: the * {@link SGValue}
95  * will not change during a session, even if the * property is bound
96  * and unbound multiple times.  The SGValue is the * abstraction of
97  * an RValue: it allows for conversion among all of the different
98  * types, and can be bound to external pointers, functions, methods,
99  * or other data sources.  Every SGValue contains an SGRawValue of
100  * a specific type.  The SGRawValue (this class) may change frequently
101  * during a session as a value is retyped or bound and unbound to
102  * various data source, but the abstract SGValue layer insulates
103  * the application from those changes.  The raw value contains no
104  * facilities for data binding or for type conversion: it is simply
105  * the abstraction of a primitive data type (or a compound data
106  * type, in the case of a string).
107  *
108  * The SGValue class always keeps a *copy* of a raw value, not the
109  * original one passed to it; if you override a derived class but do
110  * not replace the {@link #clone} method, strange things will happen.
111  *
112  * All raw values must implement {@link #getValue}, {@link #setValue},
113  * and {@link #clone} for the appropriate type.
114  *
115  * @see SGValue
116  * @see SGPropertyNode */
117 template <class T>
118 class SGRawValue
119 {
120 public:
121
122   /**
123    * The default underlying value for this type.
124    *
125    * Every raw value has a default; the default is false for a
126    * boolean, 0 for the various numeric values, and "" for a string.
127    * If additional types of raw values are added in the future, they
128    * may need different kinds of default values (such as epoch for a
129    * date type).  The default value is used when creating new values.
130    */
131   static const T DefaultValue;  // Default for this kind of raw value.
132
133
134   /**
135    * Constructor.
136    *
137    * Use the default value for this type.
138    */
139   SGRawValue () {}
140
141
142   /**
143    * Destructor.
144    */
145   virtual ~SGRawValue () {}
146
147
148   /**
149    * Return the underlying value.
150    *
151    * @return The actual value for the property.
152    * @see #setValue
153    */
154   virtual T getValue () const = 0;
155
156
157   /**
158    * Assign a new underlying value.
159    *
160    * If the new value cannot be set (because this is a read-only
161    * raw value, or because the new value is not acceptable for
162    * some reason) this method returns false and leaves the original
163    * value unchanged.
164    *
165    * @param value The actual value for the property.
166    * @return true if the value was set successfully, false otherwise.
167    * @see #getValue
168    */
169   virtual bool setValue (T value) = 0;
170
171
172   /**
173    * Create a new deep copy of this raw value.
174    *
175    * The copy will contain its own version of the underlying value
176    * as well.
177    *
178    * @return A deep copy of the current object.
179    */
180   virtual SGRawValue * clone () const = 0;
181 };
182
183
184 /**
185  * An unbound raw value, stored internally.
186  *
187  * Instances of this class are created automatically, by default,
188  * by the SGValue class; ordinarily the application should not
189  * need to touch it.
190  */
191 template <class T>
192 class SGRawValueInternal : public SGRawValue<T>
193 {
194 public:
195
196   /**
197    * Default constructor.
198    *
199    * Initialize with the default value for this type.
200    */
201   SGRawValueInternal () {}
202
203   /**
204    * Explicit value constructor.
205    *
206    * Initialize with the underlying value provided.
207    *
208    * @param value The initial value for this property.
209    */
210   SGRawValueInternal (T value) : _value(value) {}
211
212   /**
213    * Destructor.
214    */
215   virtual ~SGRawValueInternal () {}
216
217   /**
218    * Get the underlying value.
219    */
220   virtual T getValue () const { return _value; }
221
222   /**
223    * Set the underlying value.
224    */
225   virtual bool setValue (T value) { _value = value; return true; }
226
227   /**
228    * Create a deep copy of this raw value.
229    */
230   virtual SGRawValue<T> * clone () const {
231     return new SGRawValueInternal<T>(_value);
232   }
233
234 private:
235   T _value;
236 };
237
238
239 /**
240  * A raw value bound to a pointer.
241  *
242  * This is the most efficient way to tie an external value, but also
243  * the most dangerous, because there is no way for the supplier to
244  * perform bounds checking and derived calculations except by polling
245  * the variable to see if it has changed.  There is no default
246  * constructor, because this class would be meaningless without a
247  * pointer.
248  */
249 template <class T>
250 class SGRawValuePointer : public SGRawValue<T>
251 {
252 public:
253
254   /**
255    * Explicit pointer constructor.
256    *
257    * Create a new raw value bound to the value of the variable
258    * referenced by the pointer.
259    *
260    * @param ptr The pointer to the variable to which this raw value
261    * will be bound.
262    */
263   SGRawValuePointer (T * ptr) : _ptr(ptr) {}
264
265   /**
266    * Destructor.
267    */
268   virtual ~SGRawValuePointer () {}
269
270   /**
271    * Get the underlying value.
272    *
273    * This method will dereference the pointer and return the
274    * variable's value.
275    */
276   virtual T getValue () const { return *_ptr; }
277
278   /**
279    * Set the underlying value.
280    *
281    * This method will dereference the pointer and change the
282    * variable's value.
283    */
284   virtual bool setValue (T value) { *_ptr = value; return true; }
285
286   /**
287    * Create a copy of this raw value.
288    *
289    * The copy will use the same external pointer as the original.
290    */
291   virtual SGRawValue<T> * clone () const {
292     return new SGRawValuePointer<T>(_ptr);
293   }
294
295 private:
296   T * _ptr;
297 };
298
299
300 /**
301  * A value managed through static functions.
302  *
303  * A read-only value will not have a setter; a write-only value will
304  * not have a getter.
305  */
306 template <class T>
307 class SGRawValueFunctions : public SGRawValue<T>
308 {
309 public:
310
311   /**
312    * The template type of a static getter function.
313    */
314   typedef T (*getter_t)();
315
316   /**
317    * The template type of a static setter function.
318    */
319   typedef void (*setter_t)(T);
320
321   /**
322    * Explicit constructor.
323    *
324    * Create a new raw value bound to the getter and setter supplied.
325    *
326    * @param getter A static function for getting a value, or 0
327    * to read-disable the value.
328    * @param setter A static function for setting a value, or 0
329    * to write-disable the value.
330    */
331   SGRawValueFunctions (getter_t getter = 0, setter_t setter = 0)
332     : _getter(getter), _setter(setter) {}
333
334   /**
335    * Destructor.
336    */
337   virtual ~SGRawValueFunctions () {}
338
339   /**
340    * Get the underlying value.
341    *
342    * This method will invoke the getter function to get a value.
343    * If no getter function was supplied, this method will always
344    * return the default value for the type.
345    */
346   virtual T getValue () const {
347     if (_getter) return (*_getter)();
348     else return SGRawValue<T>::DefaultValue;
349   }
350
351   /**
352    * Set the underlying value.
353    *
354    * This method will invoke the setter function to change the
355    * underlying value.  If no setter function was supplied, this
356    * method will return false.
357    */
358   virtual bool setValue (T value) {
359     if (_setter) { (*_setter)(value); return true; }
360     else return false;
361   }
362
363   /**
364    * Create a copy of this raw value, bound to the same functions.
365    */
366   virtual SGRawValue<T> * clone () const {
367     return new SGRawValueFunctions<T>(_getter,_setter);
368   }
369
370 private:
371   getter_t _getter;
372   setter_t _setter;
373 };
374
375
376 /**
377  * An indexed value bound to static functions.
378  *
379  * A read-only value will not have a setter; a write-only value will
380  * not have a getter.  An indexed value is useful for binding one
381  * of a list of possible values (such as multiple engines for a
382  * plane).  The index is hard-coded at creation time.
383  */
384 template <class T>
385 class SGRawValueFunctionsIndexed : public SGRawValue<T>
386 {
387 public:
388   typedef T (*getter_t)(int);
389   typedef void (*setter_t)(int,T);
390   SGRawValueFunctionsIndexed (int index, getter_t getter = 0, setter_t setter = 0)
391     : _index(index), _getter(getter), _setter(setter) {}
392   virtual ~SGRawValueFunctionsIndexed () {}
393   virtual T getValue () const {
394     if (_getter) return (*_getter)(_index);
395     else return SGRawValue<T>::DefaultValue;
396   }
397   virtual bool setValue (T value) {
398     if (_setter) { (*_setter)(_index, value); return true; }
399     else return false;
400   }
401   virtual SGRawValue<T> * clone () const {
402     return new SGRawValueFunctionsIndexed<T>(_index, _getter, _setter);
403   }
404 private:
405   int _index;
406   getter_t _getter;
407   setter_t _setter;
408 };
409
410
411 /**
412  * A value managed through an object and access methods.
413  *
414  * A read-only value will not have a setter; a write-only value will
415  * not have a getter.
416  */
417 template <class C, class T>
418 class SGRawValueMethods : public SGRawValue<T>
419 {
420 public:
421   typedef T (C::*getter_t)() const;
422   typedef void (C::*setter_t)(T);
423   SGRawValueMethods (C &obj, getter_t getter = 0, setter_t setter = 0)
424     : _obj(obj), _getter(getter), _setter(setter) {}
425   virtual ~SGRawValueMethods () {}
426   virtual T getValue () const {
427     if (_getter) { return (_obj.*_getter)(); }
428     else { return SGRawValue<T>::DefaultValue; }
429   }
430   virtual bool setValue (T value) {
431     if (_setter) { (_obj.*_setter)(value); return true; }
432     else return false;
433   }
434   virtual SGRawValue<T> * clone () const {
435     return new SGRawValueMethods<C,T>(_obj, _getter, _setter);
436   }
437 private:
438   C &_obj;
439   getter_t _getter;
440   setter_t _setter;
441 };
442
443
444 /**
445  * An indexed value managed through an object and access methods.
446  *
447  * A read-only value will not have a setter; a write-only value will
448  * not have a getter.
449  */
450 template <class C, class T>
451 class SGRawValueMethodsIndexed : public SGRawValue<T>
452 {
453 public:
454   typedef T (C::*getter_t)(int) const;
455   typedef void (C::*setter_t)(int, T);
456   SGRawValueMethodsIndexed (C &obj, int index,
457                      getter_t getter = 0, setter_t setter = 0)
458     : _obj(obj), _index(index), _getter(getter), _setter(setter) {}
459   virtual ~SGRawValueMethodsIndexed () {}
460   virtual T getValue () const {
461     if (_getter) { return (_obj.*_getter)(_index); }
462     else { return SGRawValue<T>::DefaultValue; }
463   }
464   virtual bool setValue (T value) {
465     if (_setter) { (_obj.*_setter)(_index, value); return true; }
466     else return false;
467   }
468   virtual SGRawValue<T> * clone () const {
469     return new SGRawValueMethodsIndexed<C,T>(_obj, _index, _getter, _setter);
470   }
471 private:
472   C &_obj;
473   int _index;
474   getter_t _getter;
475   setter_t _setter;
476 };
477
478
479 \f
480 /**
481  * A node in a property tree.
482  */
483 class SGPropertyNode
484 {
485
486 public:
487
488
489   /**
490    * Property value types.
491    */
492   enum Type {
493     NONE,
494     ALIAS,
495     BOOL,
496     INT,
497     LONG,
498     FLOAT,
499     DOUBLE,
500     STRING,
501     UNSPECIFIED
502   };
503
504
505   /**
506    * Access mode attributes.
507    *
508    * <p>The ARCHIVE attribute is strictly advisory, and controls
509    * whether the property should normally be saved and restored.</p>
510    */
511   enum Attribute {
512     READ = 1,
513     WRITE = 2,
514     ARCHIVE = 4
515   };
516
517
518   /**
519    * Default constructor.
520    */
521   SGPropertyNode ();
522
523
524   /**
525    * Copy constructor.
526    */
527   SGPropertyNode (const SGPropertyNode &node);
528
529
530   /**
531    * Destructor.
532    */
533   virtual ~SGPropertyNode ();
534
535
536
537   //
538   // Basic properties.
539   //
540
541   /**
542    * Test whether this node contains a primitive leaf value.
543    */
544   bool hasValue () const { return (_type != NONE); }
545
546
547   /**
548    * Get the node's simple (XML) name.
549    */
550   const string &getName () const { return _name; }
551
552
553   /**
554    * Get the node's integer index.
555    */
556   const int getIndex () const { return _index; }
557
558
559   /**
560    * Get a non-const pointer to the node's parent.
561    */
562   SGPropertyNode * getParent () { return _parent; }
563
564
565   /**
566    * Get a const pointer to the node's parent.
567    */
568   const SGPropertyNode * getParent () const { return _parent; }
569
570
571   //
572   // Children.
573   //
574
575
576   /**
577    * Get the number of child nodes.
578    */
579   const int nChildren () const { return _children.size(); }
580
581
582   /**
583    * Get a child node by position (*NOT* index).
584    */
585   SGPropertyNode * getChild (int position);
586
587
588   /**
589    * Get a const child node by position (*NOT* index).
590    */
591   const SGPropertyNode * getChild (int position) const;
592
593
594   /**
595    * Get a child node by name and index.
596    */
597   SGPropertyNode * getChild (const string &name, int index = 0,
598                              bool create = false);
599
600
601   /**
602    * Get a const child node by name and index.
603    */
604   const SGPropertyNode * getChild (const string &name, int index = 0) const;
605
606
607   /**
608    * Get a vector of all children with the specified name.
609    */
610   vector<SGPropertyNode *> getChildren (const string &name);
611
612
613   /**
614    * Get a vector all all children (const) with the specified name.
615    */
616   vector<const SGPropertyNode *> getChildren (const string &name) const;
617
618
619   //
620   // Alias support.
621   //
622
623
624   /**
625    * Alias this node's leaf value to another's.
626    */
627   bool alias (SGPropertyNode * target);
628
629
630   /**
631    * Alias this node's leaf value to another's by relative path.
632    */
633   bool alias (const string &path);
634
635
636   /**
637    * Remove any alias for this node.
638    */
639   bool unalias ();
640
641
642   /**
643    * Test whether the node's leaf value is aliased to another's.
644    */
645   bool isAlias () const { return (_type == ALIAS); }
646
647
648   /**
649    * Get a non-const pointer to the current alias target, if any.
650    */
651   SGPropertyNode * getAliasTarget ();
652
653
654   /**
655    * Get a const pointer to the current alias target, if any.
656    */
657   const SGPropertyNode * getAliasTarget () const;
658
659
660   //
661   // Path information.
662   //
663
664
665   /**
666    * Get the path to this node from the root.
667    */
668   string getPath (bool simplify = false) const;
669
670
671   /**
672    * Get a pointer to the root node.
673    */
674   SGPropertyNode * getRootNode ();
675
676
677   /**
678    * Get a const pointer to the root node.
679    */
680   const SGPropertyNode * getRootNode () const;
681
682
683   /**
684    * Get a pointer to another node by relative path.
685    */
686   SGPropertyNode * getNode (const string &relative_path, bool create = false);
687
688
689   /**
690    * Get a const pointer to another node by relative path.
691    */
692   const SGPropertyNode * getNode (const string &relative_path) const;
693
694
695   //
696   // Access Mode.
697   //
698
699   /**
700    * Check a single mode attribute for the property node.
701    */
702   bool getAttribute (Attribute attr) const { return ((_attr & attr) != 0); }
703
704
705   /**
706    * Set a single mode attribute for the property node.
707    */
708   void setAttribute (Attribute attr, bool state) {
709     (state ? _attr |= attr : _attr &= ~attr);
710   }
711
712
713   /**
714    * Get all of the mode attributes for the property node.
715    */
716   int getAttributes () const { return _attr; }
717
718
719   /**
720    * Set all of the mode attributes for the property node.
721    */
722   void setAttributes (int attr) { _attr = attr; }
723   
724
725   //
726   // Leaf Value (primitive).
727   //
728
729
730   /**
731    * Get the type of leaf value, if any, for this node.
732    */
733   Type getType () const;
734
735
736   /**
737    * Get a bool value for this node.
738    */
739   bool getBoolValue () const;
740
741
742   /**
743    * Get an int value for this node.
744    */
745   int getIntValue () const;
746
747
748   /**
749    * Get a long int value for this node.
750    */
751   long getLongValue () const;
752
753
754   /**
755    * Get a float value for this node.
756    */
757   float getFloatValue () const;
758
759
760   /**
761    * Get a double value for this node.
762    */
763   double getDoubleValue () const;
764
765
766   /**
767    * Get a string value for this node.
768    */
769   string getStringValue () const;
770
771
772
773   /**
774    * Set a bool value for this node.
775    */
776   bool setBoolValue (bool value);
777
778
779   /**
780    * Set an int value for this node.
781    */
782   bool setIntValue (int value);
783
784
785   /**
786    * Set a long int value for this node.
787    */
788   bool setLongValue (long value);
789
790
791   /**
792    * Set a float value for this node.
793    */
794   bool setFloatValue (float value);
795
796
797   /**
798    * Set a double value for this node.
799    */
800   bool setDoubleValue (double value);
801
802
803   /**
804    * Set a string value for this node.
805    */
806   bool setStringValue (string value);
807
808
809   /**
810    * Set a value of unspecified type for this node.
811    */
812   bool setUnspecifiedValue (string value);
813
814
815   //
816   // Data binding.
817   //
818
819
820   /**
821    * Test whether this node is bound to an external data source.
822    */
823   bool isTied () const { return _tied; }
824
825
826   /**
827    * Bind this node to an external bool source.
828    */
829   bool tie (const SGRawValue<bool> &rawValue, bool useDefault = true);
830
831
832   /**
833    * Bind this node to an external int source.
834    */
835   bool tie (const SGRawValue<int> &rawValue, bool useDefault = true);
836
837
838   /**
839    * Bind this node to an external long int source.
840    */
841   bool tie (const SGRawValue<long> &rawValue, bool useDefault = true);
842
843
844   /**
845    * Bind this node to an external float source.
846    */
847   bool tie (const SGRawValue<float> &rawValue, bool useDefault = true);
848
849
850   /**
851    * Bind this node to an external double source.
852    */
853   bool tie (const SGRawValue<double> &rawValue, bool useDefault = true);
854
855
856   /**
857    * Bind this node to an external string source.
858    */
859   bool tie (const SGRawValue<string> &rawValue, bool useDefault = true);
860
861
862   /**
863    * Unbind this node from any external data source.
864    */
865   bool untie ();
866
867
868   //
869   // Convenience methods using paths.
870   // TODO: add attribute methods
871   //
872
873
874   /**
875    * Get another node's type.
876    */
877   Type getType (const string &relative_path) const;
878
879
880   /**
881    * Test whether another node has a leaf value.
882    */
883   bool hasValue (const string &relative_path) const;
884
885
886   /**
887    * Get another node's value as a bool.
888    */
889   bool getBoolValue (const string &relative_path,
890                      bool defaultValue = false) const;
891
892
893   /**
894    * Get another node's value as an int.
895    */
896   int getIntValue (const string &relative_path,
897                    int defaultValue = 0) const;
898
899
900   /**
901    * Get another node's value as a long int.
902    */
903   long getLongValue (const string &relative_path,
904                      long defaultValue = 0L) const;
905
906
907   /**
908    * Get another node's value as a float.
909    */
910   float getFloatValue (const string &relative_path,
911                        float defaultValue = 0.0) const;
912
913
914   /**
915    * Get another node's value as a double.
916    */
917   double getDoubleValue (const string &relative_path,
918                          double defaultValue = 0.0L) const;
919
920
921   /**
922    * Get another node's value as a string.
923    */
924   string getStringValue (const string &relative_path,
925                          string defaultValue = "") const;
926
927
928   /**
929    * Set another node's value as a bool.
930    */
931   bool setBoolValue (const string &relative_path, bool value);
932
933
934   /**
935    * Set another node's value as an int.
936    */
937   bool setIntValue (const string &relative_path, int value);
938
939
940   /**
941    * Set another node's value as a long int.
942    */
943   bool setLongValue (const string &relative_path, long value);
944
945
946   /**
947    * Set another node's value as a float.
948    */
949   bool setFloatValue (const string &relative_path, float value);
950
951
952   /**
953    * Set another node's value as a double.
954    */
955   bool setDoubleValue (const string &relative_path, double value);
956
957
958   /**
959    * Set another node's value as a string.
960    */
961   bool setStringValue (const string &relative_path, string value);
962
963
964   /**
965    * Set another node's value with no specified type.
966    */
967   bool setUnspecifiedValue (const string &relative_path, string value);
968
969
970   /**
971    * Test whether another node is bound to an external data source.
972    */
973   bool isTied (const string &relative_path) const;
974
975
976   /**
977    * Bind another node to an external bool source.
978    */
979   bool tie (const string &relative_path, const SGRawValue<bool> &rawValue,
980             bool useDefault = true);
981
982
983   /**
984    * Bind another node to an external int source.
985    */
986   bool tie (const string &relative_path, const SGRawValue<int> &rawValue,
987             bool useDefault = true);
988
989
990   /**
991    * Bind another node to an external long int source.
992    */
993   bool tie (const string &relative_path, const SGRawValue<long> &rawValue,
994             bool useDefault = true);
995
996
997   /**
998    * Bind another node to an external float source.
999    */
1000   bool tie (const string &relative_path, const SGRawValue<float> &rawValue,
1001             bool useDefault = true);
1002
1003
1004   /**
1005    * Bind another node to an external double source.
1006    */
1007   bool tie (const string &relative_path, const SGRawValue<double> &rawValue,
1008             bool useDefault = true);
1009
1010
1011   /**
1012    * Bind another node to an external string source.
1013    */
1014   bool tie (const string &relative_path, const SGRawValue<string> &rawValue,
1015             bool useDefault = true);
1016
1017
1018   /**
1019    * Unbind another node from any external data source.
1020    */
1021   bool untie (const string &relative_path);
1022
1023
1024 protected:
1025
1026
1027   /**
1028    * Protected constructor for making new nodes on demand.
1029    */
1030   SGPropertyNode (const string &name, int index, SGPropertyNode * parent);
1031
1032
1033 private:
1034
1035
1036   /**
1037    * Clear any existing value and set the type to NONE.
1038    */
1039   void clear_value ();
1040
1041   string _name;
1042   int _index;
1043   SGPropertyNode * _parent;
1044   vector<SGPropertyNode *> _children;
1045
1046
1047   Type _type;
1048   bool _tied;
1049   int _attr;
1050
1051                                 // The right kind of pointer...
1052   union {
1053     SGPropertyNode * alias;
1054     SGRawValue<bool> * bool_val;
1055     SGRawValue<int> * int_val;
1056     SGRawValue<long> * long_val;
1057     SGRawValue<float> * float_val;
1058     SGRawValue<double> * double_val;
1059     SGRawValue<string> * string_val;
1060   } _value;
1061
1062
1063 };
1064
1065
1066 \f
1067 ////////////////////////////////////////////////////////////////////////
1068 // I/O functions.
1069 ////////////////////////////////////////////////////////////////////////
1070
1071
1072 /**
1073  * Read properties from an XML input stream.
1074  */
1075 void readProperties (istream &input, SGPropertyNode * start_node,
1076                      const string &base = "");
1077
1078
1079 /**
1080  * Read properties from an XML file.
1081  */
1082 void readProperties (const string &file, SGPropertyNode * start_node);
1083
1084
1085 /**
1086  * Write properties to an XML output stream.
1087  */
1088 void writeProperties (ostream &output, const SGPropertyNode * start_node);
1089
1090
1091 /**
1092  * Write properties to an XML file.
1093  */
1094 void writeProperties (const string &file, const SGPropertyNode * start_node);
1095
1096
1097 /**
1098  * Copy properties from one node to another.
1099  */
1100 bool copyProperties (const SGPropertyNode *in, SGPropertyNode *out);
1101
1102
1103 #endif // __PROPS_HXX
1104
1105 // end of props.hxx