]> git.mxchange.org Git - simgear.git/blob - simgear/structure/SGExpression.hxx
Revert the check fro std::isnan() and isnan()
[simgear.git] / simgear / structure / SGExpression.hxx
1 /* -*-c++-*-
2  *
3  * Copyright (C) 2006-2007 Mathias Froehlich 
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18  * MA 02110-1301, USA.
19  *
20  */
21
22 #ifndef _SG_EXPRESSION_HXX
23 #define _SG_EXPRESSION_HXX 1
24
25 #include <string>
26 #include <vector>
27 #include <functional>
28 #include <set>
29 #include <string>
30
31 #include <simgear/props/condition.hxx>
32 #include <simgear/props/props.hxx>
33 #include <simgear/math/interpolater.hxx>
34 #include <simgear/math/SGMath.hxx>
35 #include <simgear/scene/model/persparam.hxx>
36 #include <simgear/structure/exception.hxx>
37 #include <simgear/structure/Singleton.hxx>
38
39 /// Expression tree implementation.
40
41 namespace simgear
42 {
43   namespace expression
44   {
45     enum Type {
46       BOOL = 0,
47       INT,
48       FLOAT,
49       DOUBLE
50     };
51     template<typename T> struct TypeTraits;
52     template<> struct TypeTraits<bool> {
53       static const Type typeTag = BOOL;
54     };
55     template<> struct TypeTraits<int> {
56       static const Type typeTag = INT;
57     };
58     template<> struct TypeTraits<float> {
59       static const Type typeTag = FLOAT;
60     };
61     template<> struct TypeTraits<double> {
62       static const Type typeTag = DOUBLE;
63     };
64
65     struct Value
66     {
67       Type typeTag;
68       union {
69         bool boolVal;
70         int intVal;
71         float floatVal;
72         double doubleVal;
73       } val;
74
75       Value() : typeTag(DOUBLE)
76       {
77         val.doubleVal = 0.0;
78       }
79
80       Value(bool val_) : typeTag(BOOL)
81       {
82         val.boolVal = val_;
83       }
84
85       Value(int val_) : typeTag(INT)
86       {
87         val.intVal = val_;
88       }
89
90       Value(float val_) : typeTag(FLOAT)
91       {
92         val.floatVal = val_;
93       }
94
95       Value(double val_) : typeTag(DOUBLE)
96       {
97         val.doubleVal = val_;
98       }
99
100     };
101
102     class Binding;
103   }
104
105   class Expression : public SGReferenced
106   {
107   public:
108     virtual ~Expression() {}
109     virtual expression::Type getType() const = 0;
110   };
111
112   const expression::Value eval(const Expression* exp,
113                                const expression::Binding* binding = 0);
114
115 }
116
117 template<typename T>
118 class SGExpression : public simgear::Expression {
119 public:
120   virtual ~SGExpression() {}
121   typedef T result_type;
122   typedef T operand_type;
123   virtual void eval(T&, const simgear::expression::Binding*) const = 0;
124
125   T getValue(const simgear::expression::Binding* binding = 0) const
126   { T value; eval(value, binding); return value; }
127
128   double getDoubleValue(const simgear::expression::Binding* binding = 0) const
129   { T value; eval(value, binding); return value; }
130
131   virtual bool isConst() const { return false; }
132   virtual SGExpression* simplify();
133   virtual simgear::expression::Type getType() const
134   {
135     return simgear::expression::TypeTraits<T>::typeTag;
136   }
137   virtual simgear::expression::Type getOperandType() const
138   {
139     return simgear::expression::TypeTraits<T>::typeTag;
140   }
141   virtual void collectDependentProperties(std::set<const SGPropertyNode*>& props) const
142   { }
143 };
144
145 /// Constant value expression
146 template<typename T>
147 class SGConstExpression : public SGExpression<T> {
148 public:
149   SGConstExpression(const T& value = T()) : _value(value)
150   { }
151   void setValue(const T& value)
152   { _value = value; }
153   const T& getValue(const simgear::expression::Binding* binding = 0) const
154   { return _value; }
155   virtual void eval(T& value, const simgear::expression::Binding*) const
156   { value = _value; }
157   virtual bool isConst() const { return true; }
158 private:
159   T _value;
160 };
161
162 template<typename T>
163 SGExpression<T>*
164 SGExpression<T>::simplify()
165 {
166   if (isConst())
167     return new SGConstExpression<T>(getValue());
168   return this;
169 }
170
171 template<typename T>
172 class SGUnaryExpression : public SGExpression<T> {
173 public:
174   const SGExpression<T>* getOperand() const
175   { return _expression; }
176   SGExpression<T>* getOperand()
177   { return _expression; }
178   void setOperand(SGExpression<T>* expression)
179   {
180     if (!expression)
181       expression = new SGConstExpression<T>(T());
182     _expression = expression;
183   }
184   virtual bool isConst() const
185   { return getOperand()->isConst(); }
186   virtual SGExpression<T>* simplify()
187   {
188     _expression = _expression->simplify();
189     return SGExpression<T>::simplify();
190   }
191   
192   virtual void collectDependentProperties(std::set<const SGPropertyNode*>& props) const
193     { _expression->collectDependentProperties(props); }  
194 protected:
195   SGUnaryExpression(SGExpression<T>* expression = 0)
196   { setOperand(expression); }
197
198 private:
199   SGSharedPtr<SGExpression<T> > _expression;
200 };
201
202 template<typename T>
203 class SGBinaryExpression : public SGExpression<T> {
204 public:
205   const SGExpression<T>* getOperand(size_t i) const
206   { return _expressions[i]; }
207   SGExpression<T>* getOperand(size_t i)
208   { return _expressions[i]; }
209   void setOperand(size_t i, SGExpression<T>* expression)
210   {
211     if (!expression)
212       expression = new SGConstExpression<T>(T());
213     if (2 <= i)
214       i = 0;
215     _expressions[i] = expression;
216   }
217
218   virtual bool isConst() const
219   { return getOperand(0)->isConst() && getOperand(1)->isConst(); }
220   virtual SGExpression<T>* simplify()
221   {
222     _expressions[0] = _expressions[0]->simplify();
223     _expressions[1] = _expressions[1]->simplify();
224     return SGExpression<T>::simplify();
225   }
226
227   virtual void collectDependentProperties(std::set<const SGPropertyNode*>& props) const
228   {
229     _expressions[0]->collectDependentProperties(props);
230     _expressions[1]->collectDependentProperties(props); 
231   } 
232   
233 protected:
234   SGBinaryExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
235   { setOperand(0, expr0); setOperand(1, expr1); }
236   
237 private:
238   SGSharedPtr<SGExpression<T> > _expressions[2];
239 };
240
241 template<typename T>
242 class SGNaryExpression : public SGExpression<T> {
243 public:
244   size_t getNumOperands() const
245   { return _expressions.size(); }
246   const SGExpression<T>* getOperand(size_t i) const
247   { return _expressions[i]; }
248   SGExpression<T>* getOperand(size_t i)
249   { return _expressions[i]; }
250   size_t addOperand(SGExpression<T>* expression)
251   {
252     if (!expression)
253       return ~size_t(0);
254     _expressions.push_back(expression);
255     return _expressions.size() - 1;
256   }
257
258   template<typename Iter>
259   void addOperands(Iter begin, Iter end)
260   {
261     for (Iter iter = begin; iter != end; ++iter)
262       {
263         addOperand(static_cast< ::SGExpression<T>*>(*iter));
264       }
265   }
266
267   virtual bool isConst() const
268   {
269     for (size_t i = 0; i < _expressions.size(); ++i)
270       if (!_expressions[i]->isConst())
271         return false;
272     return true;
273   }
274   virtual SGExpression<T>* simplify()
275   {
276     for (size_t i = 0; i < _expressions.size(); ++i)
277       _expressions[i] = _expressions[i]->simplify();
278     return SGExpression<T>::simplify();
279   }
280
281   virtual void collectDependentProperties(std::set<const SGPropertyNode*>& props) const
282   {
283     for (size_t i = 0; i < _expressions.size(); ++i)
284       _expressions[i]->collectDependentProperties(props);
285   } 
286 protected:
287   SGNaryExpression()
288   { }
289   SGNaryExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
290   { addOperand(expr0); addOperand(expr1); }
291   
292 private:
293   std::vector<SGSharedPtr<SGExpression<T> > > _expressions;
294 };
295
296
297
298
299 template<typename T>
300 class SGPropertyExpression : public SGExpression<T> {
301 public:
302   SGPropertyExpression(const SGPropertyNode* prop) : _prop(prop)
303   { }
304   void setPropertyNode(const SGPropertyNode* prop)
305   { _prop = prop; }
306   virtual void eval(T& value, const simgear::expression::Binding*) const
307   { doEval(value); }
308   
309   virtual void collectDependentProperties(std::set<const SGPropertyNode*>& props) const
310     { props.insert(_prop.get()); }
311 private:
312   void doEval(float& value) const
313   { if (_prop) value = _prop->getFloatValue(); }
314   void doEval(double& value) const
315   { if (_prop) value = _prop->getDoubleValue(); }
316   void doEval(int& value) const
317   { if (_prop) value = _prop->getIntValue(); }
318   void doEval(long& value) const
319   { if (_prop) value = _prop->getLongValue(); }
320   void doEval(bool& value) const
321   { if (_prop) value = _prop->getBoolValue(); }
322   SGSharedPtr<const SGPropertyNode> _prop;
323 };
324
325 template<typename T>
326 class SGAbsExpression : public SGUnaryExpression<T> {
327 public:
328   SGAbsExpression(SGExpression<T>* expr = 0)
329     : SGUnaryExpression<T>(expr)
330   { }
331
332   virtual void eval(T& value, const simgear::expression::Binding* b) const
333   { value = getOperand()->getValue(b); if (value <= 0) value = -value; }
334
335   using SGUnaryExpression<T>::getOperand;
336 };
337
338 template<typename T>
339 class SGACosExpression : public SGUnaryExpression<T> {
340 public:
341   SGACosExpression(SGExpression<T>* expr = 0)
342     : SGUnaryExpression<T>(expr)
343   { }
344
345   virtual void eval(T& value, const simgear::expression::Binding* b) const
346   { value = acos((double)SGMisc<T>::clip(getOperand()->getValue(b), -1, 1)); }
347
348   using SGUnaryExpression<T>::getOperand;
349 };
350
351 template<typename T>
352 class SGASinExpression : public SGUnaryExpression<T> {
353 public:
354   SGASinExpression(SGExpression<T>* expr = 0)
355     : SGUnaryExpression<T>(expr)
356   { }
357
358   virtual void eval(T& value, const simgear::expression::Binding* b) const
359   { value = asin((double)SGMisc<T>::clip(getOperand()->getValue(b), -1, 1)); }
360
361   using SGUnaryExpression<T>::getOperand;
362 };
363
364 template<typename T>
365 class SGATanExpression : public SGUnaryExpression<T> {
366 public:
367   SGATanExpression(SGExpression<T>* expr = 0)
368     : SGUnaryExpression<T>(expr)
369   { }
370
371   virtual void eval(T& value, const simgear::expression::Binding* b) const
372   { value = atan(getOperand()->getDoubleValue(b)); }
373
374   using SGUnaryExpression<T>::getOperand;
375 };
376
377 template<typename T>
378 class SGCeilExpression : public SGUnaryExpression<T> {
379 public:
380   SGCeilExpression(SGExpression<T>* expr = 0)
381     : SGUnaryExpression<T>(expr)
382   { }
383
384   virtual void eval(T& value, const simgear::expression::Binding* b) const
385   { value = ceil(getOperand()->getDoubleValue(b)); }
386
387   using SGUnaryExpression<T>::getOperand;
388 };
389
390 template<typename T>
391 class SGCosExpression : public SGUnaryExpression<T> {
392 public:
393   SGCosExpression(SGExpression<T>* expr = 0)
394     : SGUnaryExpression<T>(expr)
395   { }
396
397   virtual void eval(T& value, const simgear::expression::Binding* b) const
398   { value = cos(getOperand()->getDoubleValue(b)); }
399
400   using SGUnaryExpression<T>::getOperand;
401 };
402
403 template<typename T>
404 class SGCoshExpression : public SGUnaryExpression<T> {
405 public:
406   SGCoshExpression(SGExpression<T>* expr = 0)
407     : SGUnaryExpression<T>(expr)
408   { }
409
410   virtual void eval(T& value, const simgear::expression::Binding* b) const
411   { value = cosh(getOperand()->getDoubleValue(b)); }
412
413   using SGUnaryExpression<T>::getOperand;
414 };
415
416 template<typename T>
417 class SGExpExpression : public SGUnaryExpression<T> {
418 public:
419   SGExpExpression(SGExpression<T>* expr = 0)
420     : SGUnaryExpression<T>(expr)
421   { }
422
423   virtual void eval(T& value, const simgear::expression::Binding* b) const
424   { value = exp(getOperand()->getDoubleValue(b)); }
425
426   using SGUnaryExpression<T>::getOperand;
427 };
428
429 template<typename T>
430 class SGFloorExpression : public SGUnaryExpression<T> {
431 public:
432   SGFloorExpression(SGExpression<T>* expr = 0)
433     : SGUnaryExpression<T>(expr)
434   { }
435
436   virtual void eval(T& value, const simgear::expression::Binding* b) const
437   { value = floor(getOperand()->getDoubleValue(b)); }
438
439   using SGUnaryExpression<T>::getOperand;
440 };
441
442 template<typename T>
443 class SGLogExpression : public SGUnaryExpression<T> {
444 public:
445   SGLogExpression(SGExpression<T>* expr = 0)
446     : SGUnaryExpression<T>(expr)
447   { }
448
449   virtual void eval(T& value, const simgear::expression::Binding* b) const
450   { value = log(getOperand()->getDoubleValue(b)); }
451
452   using SGUnaryExpression<T>::getOperand;
453 };
454
455 template<typename T>
456 class SGLog10Expression : public SGUnaryExpression<T> {
457 public:
458   SGLog10Expression(SGExpression<T>* expr = 0)
459     : SGUnaryExpression<T>(expr)
460   { }
461
462   virtual void eval(T& value, const simgear::expression::Binding* b) const
463   { value = log10(getOperand()->getDoubleValue(b)); }
464
465   using SGUnaryExpression<T>::getOperand;
466 };
467
468 template<typename T>
469 class SGSinExpression : public SGUnaryExpression<T> {
470 public:
471   SGSinExpression(SGExpression<T>* expr = 0)
472     : SGUnaryExpression<T>(expr)
473   { }
474
475   virtual void eval(T& value, const simgear::expression::Binding* b) const
476   { value = sin(getOperand()->getDoubleValue(b)); }
477
478   using SGUnaryExpression<T>::getOperand;
479 };
480
481 template<typename T>
482 class SGSinhExpression : public SGUnaryExpression<T> {
483 public:
484   SGSinhExpression(SGExpression<T>* expr = 0)
485     : SGUnaryExpression<T>(expr)
486   { }
487
488   virtual void eval(T& value, const simgear::expression::Binding* b) const
489   { value = sinh(getOperand()->getDoubleValue(b)); }
490
491   using SGUnaryExpression<T>::getOperand;
492 };
493
494 template<typename T>
495 class SGSqrExpression : public SGUnaryExpression<T> {
496 public:
497   SGSqrExpression(SGExpression<T>* expr = 0)
498     : SGUnaryExpression<T>(expr)
499   { }
500
501   virtual void eval(T& value, const simgear::expression::Binding* b) const
502   { value = getOperand()->getValue(b); value = value*value; }
503
504   using SGUnaryExpression<T>::getOperand;
505 };
506
507 template<typename T>
508 class SGSqrtExpression : public SGUnaryExpression<T> {
509 public:
510   SGSqrtExpression(SGExpression<T>* expr = 0)
511     : SGUnaryExpression<T>(expr)
512   { }
513
514   virtual void eval(T& value, const simgear::expression::Binding* b) const
515   { value = sqrt(getOperand()->getDoubleValue(b)); }
516
517   using SGUnaryExpression<T>::getOperand;
518 };
519
520 template<typename T>
521 class SGTanExpression : public SGUnaryExpression<T> {
522 public:
523   SGTanExpression(SGExpression<T>* expr = 0)
524     : SGUnaryExpression<T>(expr)
525   { }
526
527   virtual void eval(T& value, const simgear::expression::Binding* b) const
528   { value = tan(getOperand()->getDoubleValue(b)); }
529
530   using SGUnaryExpression<T>::getOperand;
531 };
532
533 template<typename T>
534 class SGTanhExpression : public SGUnaryExpression<T> {
535 public:
536   SGTanhExpression(SGExpression<T>* expr = 0)
537     : SGUnaryExpression<T>(expr)
538   { }
539
540   virtual void eval(T& value, const simgear::expression::Binding* b) const
541   { value = tanh(getOperand()->getDoubleValue(b)); }
542
543   using SGUnaryExpression<T>::getOperand;
544 };
545
546 template<typename T>
547 class SGScaleExpression : public SGUnaryExpression<T> {
548 public:
549   SGScaleExpression(SGExpression<T>* expr = 0, const T& scale = T(1))
550     : SGUnaryExpression<T>(expr), _scale(scale)
551   { }
552   void setScale(const T& scale)
553   { _scale = scale; }
554   const T& getScale() const
555   { return _scale; }
556
557   virtual void eval(T& value, const simgear::expression::Binding* b) const
558   { value = _scale * getOperand()->getValue(b); }
559
560   virtual SGExpression<T>* simplify()
561   {
562     if (_scale == 1)
563       return getOperand()->simplify();
564     return SGUnaryExpression<T>::simplify();
565   }
566
567   using SGUnaryExpression<T>::getOperand;
568 private:
569   T _scale;
570 };
571
572 template<typename T>
573 class SGBiasExpression : public SGUnaryExpression<T> {
574 public:
575   SGBiasExpression(SGExpression<T>* expr = 0, const T& bias = T(0))
576     : SGUnaryExpression<T>(expr), _bias(bias)
577   { }
578
579   void setBias(const T& bias)
580   { _bias = bias; }
581   const T& getBias() const
582   { return _bias; }
583
584   virtual void eval(T& value, const simgear::expression::Binding* b) const
585   { value = _bias + getOperand()->getValue(b); }
586
587   virtual SGExpression<T>* simplify()
588   {
589     if (_bias == 0)
590       return getOperand()->simplify();
591     return SGUnaryExpression<T>::simplify();
592   }
593
594   using SGUnaryExpression<T>::getOperand;
595 private:
596   T _bias;
597 };
598
599 template<typename T>
600 class SGInterpTableExpression : public SGUnaryExpression<T> {
601 public:
602   SGInterpTableExpression(SGExpression<T>* expr,
603                           const SGInterpTable* interpTable) :
604     SGUnaryExpression<T>(expr),
605     _interpTable(interpTable)
606   { }
607
608   virtual void eval(T& value, const simgear::expression::Binding* b) const
609   {
610     if (_interpTable)
611       value = _interpTable->interpolate(getOperand()->getValue(b));
612   }
613
614   using SGUnaryExpression<T>::getOperand;
615 private:
616   SGSharedPtr<SGInterpTable const> _interpTable;
617 };
618
619 template<typename T>
620 class SGClipExpression : public SGUnaryExpression<T> {
621 public:
622   SGClipExpression(SGExpression<T>* expr)
623     : SGUnaryExpression<T>(expr),
624       _clipMin(SGMisc<T>::min(-SGLimits<T>::max(), SGLimits<T>::min())),
625       _clipMax(SGLimits<T>::max())
626   { }
627   SGClipExpression(SGExpression<T>* expr,
628                    const T& clipMin, const T& clipMax)
629     : SGUnaryExpression<T>(expr),
630       _clipMin(clipMin),
631       _clipMax(clipMax)
632   { }
633
634   void setClipMin(const T& clipMin)
635   { _clipMin = clipMin; }
636   const T& getClipMin() const
637   { return _clipMin; }
638
639   void setClipMax(const T& clipMax)
640   { _clipMax = clipMax; }
641   const T& getClipMax() const
642   { return _clipMax; }
643
644   virtual void eval(T& value, const simgear::expression::Binding* b) const
645   {
646     value = SGMisc<T>::clip(getOperand()->getValue(b), _clipMin, _clipMax);
647   }
648
649   virtual SGExpression<T>* simplify()
650   {
651     if (_clipMin <= SGMisc<T>::min(-SGLimits<T>::max(), SGLimits<T>::min()) &&
652         _clipMax >= SGLimits<T>::max())
653       return getOperand()->simplify();
654     return SGUnaryExpression<T>::simplify();
655   }
656
657   using SGUnaryExpression<T>::getOperand;
658 private:
659   T _clipMin;
660   T _clipMax;
661 };
662
663 template<typename T>
664 class SGStepExpression : public SGUnaryExpression<T> {
665 public:
666   SGStepExpression(SGExpression<T>* expr = 0,
667                    const T& step = T(1), const T& scroll = T(0))
668     : SGUnaryExpression<T>(expr), _step(step), _scroll(scroll)
669   { }
670
671   void setStep(const T& step)
672   { _step = step; }
673   const T& getStep() const
674   { return _step; }
675
676   void setScroll(const T& scroll)
677   { _scroll = scroll; }
678   const T& getScroll() const
679   { return _scroll; }
680
681   virtual void eval(T& value, const simgear::expression::Binding* b) const
682   { value = apply_mods(getOperand()->getValue(b)); }
683
684   using SGUnaryExpression<T>::getOperand;
685
686 private:
687   T apply_mods(T property) const
688   {
689     if( _step <= SGLimits<T>::min() ) return property;
690
691     // apply stepping of input value
692     T modprop = floor(property/_step)*_step;
693
694     // calculate scroll amount (for odometer like movement)
695     T remainder = property <= SGLimits<T>::min() ? -fmod(property,_step) : (_step - fmod(property,_step));
696     if( remainder > SGLimits<T>::min() && remainder < _scroll )
697       modprop += (_scroll - remainder) / _scroll * _step;
698
699     return modprop;
700   }
701
702   T _step;
703   T _scroll;
704 };
705
706 template<typename T>
707 class SGEnableExpression : public SGUnaryExpression<T> {
708 public:
709   SGEnableExpression(SGExpression<T>* expr = 0,
710                      SGCondition* enable = 0,
711                      const T& disabledValue = T(0))
712     : SGUnaryExpression<T>(expr),
713       _enable(enable),
714       _disabledValue(disabledValue)
715   { }
716
717   const T& getDisabledValue() const
718   { return _disabledValue; }
719   void setDisabledValue(const T& disabledValue)
720   { _disabledValue = disabledValue; }
721
722   virtual void eval(T& value, const simgear::expression::Binding* b) const
723   {
724     if (_enable->test())
725       value = getOperand()->getValue(b);
726     else
727       value = _disabledValue;
728   }
729
730   virtual SGExpression<T>* simplify()
731   {
732     if (!_enable)
733       return getOperand()->simplify();
734     return SGUnaryExpression<T>::simplify();
735   }
736   
737   virtual void collectDependentProperties(std::set<const SGPropertyNode*>& props) const
738   {
739     SGUnaryExpression<T>::collectDependentProperties(props);
740     _enable->collectDependentProperties(props);
741   }
742
743   using SGUnaryExpression<T>::getOperand;
744 private:
745   SGSharedPtr<SGCondition> _enable;
746   T _disabledValue;
747 };
748
749 template<typename T>
750 class SGAtan2Expression : public SGBinaryExpression<T> {
751 public:
752   SGAtan2Expression(SGExpression<T>* expr0, SGExpression<T>* expr1)
753     : SGBinaryExpression<T>(expr0, expr1)
754   { }
755   virtual void eval(T& value, const simgear::expression::Binding* b) const
756   { value = atan2(getOperand(0)->getDoubleValue(b), getOperand(1)->getDoubleValue(b)); }
757   using SGBinaryExpression<T>::getOperand;
758 };
759
760 template<typename T>
761 class SGDivExpression : public SGBinaryExpression<T> {
762 public:
763   SGDivExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
764     : SGBinaryExpression<T>(expr0, expr1)
765   { }
766   virtual void eval(T& value, const simgear::expression::Binding* b) const
767   { value = getOperand(0)->getValue(b) / getOperand(1)->getValue(b); }
768   using SGBinaryExpression<T>::getOperand;
769 };
770
771 template<typename T>
772 class SGModExpression : public SGBinaryExpression<T> {
773 public:
774   SGModExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
775     : SGBinaryExpression<T>(expr0, expr1)
776   { }
777   virtual void eval(T& value, const simgear::expression::Binding* b) const
778   { value = mod(getOperand(0)->getValue(b), getOperand(1)->getValue(b)); }
779   using SGBinaryExpression<T>::getOperand;
780 private:
781   int mod(const int& v0, const int& v1) const
782   { return v0 % v1; }
783   float mod(const float& v0, const float& v1) const
784   { return fmod(v0, v1); }
785   double mod(const double& v0, const double& v1) const
786   { return fmod(v0, v1); }
787 };
788
789 template<typename T>
790 class SGPowExpression : public SGBinaryExpression<T> {
791 public:
792   SGPowExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
793     : SGBinaryExpression<T>(expr0, expr1)
794   { }
795   virtual void eval(T& value, const simgear::expression::Binding* b) const
796   { value = pow(getOperand(0)->getDoubleValue(b), getOperand(1)->getDoubleValue(b)); }
797   using SGBinaryExpression<T>::getOperand;
798 };
799
800 template<typename T>
801 class SGSumExpression : public SGNaryExpression<T> {
802 public:
803   SGSumExpression()
804   { }
805   SGSumExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
806     : SGNaryExpression<T>(expr0, expr1)
807   { }
808   virtual void eval(T& value, const simgear::expression::Binding* b) const
809   {
810     value = T(0);
811     size_t sz = SGNaryExpression<T>::getNumOperands();
812     for (size_t i = 0; i < sz; ++i)
813       value += getOperand(i)->getValue(b);
814   }
815   using SGNaryExpression<T>::getValue;
816   using SGNaryExpression<T>::getOperand;
817 };
818
819 template<typename T>
820 class SGDifferenceExpression : public SGNaryExpression<T> {
821 public:
822   SGDifferenceExpression()
823   { }
824   SGDifferenceExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
825     : SGNaryExpression<T>(expr0, expr1)
826   { }
827   virtual void eval(T& value, const simgear::expression::Binding* b) const
828   {
829     value = getOperand(0)->getValue(b);
830     size_t sz = SGNaryExpression<T>::getNumOperands();
831     for (size_t i = 1; i < sz; ++i)
832       value -= getOperand(i)->getValue(b);
833   }
834   using SGNaryExpression<T>::getValue;
835   using SGNaryExpression<T>::getOperand;
836 };
837
838 template<typename T>
839 class SGProductExpression : public SGNaryExpression<T> {
840 public:
841   SGProductExpression()
842   { }
843   SGProductExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
844     : SGNaryExpression<T>(expr0, expr1)
845   { }
846   virtual void eval(T& value, const simgear::expression::Binding* b) const
847   {
848     value = T(1);
849     size_t sz = SGNaryExpression<T>::getNumOperands();
850     for (size_t i = 0; i < sz; ++i)
851       value *= getOperand(i)->getValue(b);
852   }
853   using SGNaryExpression<T>::getValue;
854   using SGNaryExpression<T>::getOperand;
855 };
856
857 template<typename T>
858 class SGMinExpression : public SGNaryExpression<T> {
859 public:
860   SGMinExpression()
861   { }
862   SGMinExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
863     : SGNaryExpression<T>(expr0, expr1)
864   { }
865   virtual void eval(T& value, const simgear::expression::Binding* b) const
866   {
867     size_t sz = SGNaryExpression<T>::getNumOperands();
868     if (sz < 1)
869       return;
870     
871     value = getOperand(0)->getValue(b);
872     for (size_t i = 1; i < sz; ++i)
873       value = SGMisc<T>::min(value, getOperand(i)->getValue(b));
874   }
875   using SGNaryExpression<T>::getOperand;
876 };
877
878 template<typename T>
879 class SGMaxExpression : public SGNaryExpression<T> {
880 public:
881   SGMaxExpression()
882   { }
883   SGMaxExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
884     : SGNaryExpression<T>(expr0, expr1)
885   { }
886   virtual void eval(T& value, const simgear::expression::Binding* b) const
887   {
888     size_t sz = SGNaryExpression<T>::getNumOperands();
889     if (sz < 1)
890       return;
891     
892     value = getOperand(0)->getValue(b);
893     for (size_t i = 1; i < sz; ++i)
894       value = SGMisc<T>::max(value, getOperand(i)->getValue(b));
895   }
896   using SGNaryExpression<T>::getOperand;
897 };
898
899 typedef SGExpression<int> SGExpressioni;
900 typedef SGExpression<float> SGExpressionf;
901 typedef SGExpression<double> SGExpressiond;
902 typedef SGExpression<bool> SGExpressionb;
903
904 typedef SGSharedPtr<SGExpressioni> SGExpressioni_ref;
905 typedef SGSharedPtr<SGExpressionf> SGExpressionf_ref;
906 typedef SGSharedPtr<SGExpressiond> SGExpressiond_ref;
907 typedef SGSharedPtr<SGExpressionb> SGExpressionb_ref;
908
909 /**
910  * Global function to make an expression out of properties.
911
912   <clip>
913     <clipMin>0</clipMin>
914     <clipMax>79</clipMax>
915     <abs>
916       <sum>
917         <rad2deg>
918           <property>sim/model/whatever-rad</property>
919         </rad2deg>
920         <property>sim/model/someother-deg</property>
921         <value>-90</value>
922       </sum>
923     </abs>
924   <clip>
925
926 will evaluate to an expression:
927
928 SGMisc<T>::clip(abs(deg2rad*sim/model/whatever-rad + sim/model/someother-deg - 90), clipMin, clipMax);
929
930  */
931 SGExpression<int>*
932 SGReadIntExpression(SGPropertyNode *inputRoot,
933                     const SGPropertyNode *configNode);
934
935 SGExpression<float>*
936 SGReadFloatExpression(SGPropertyNode *inputRoot,
937                       const SGPropertyNode *configNode);
938
939 SGExpression<double>*
940 SGReadDoubleExpression(SGPropertyNode *inputRoot,
941                        const SGPropertyNode *configNode);
942
943 SGExpression<bool>*
944 SGReadBoolExpression(SGPropertyNode *inputRoot,
945                      const SGPropertyNode *configNode);
946
947 namespace simgear
948 {
949   namespace expression
950   {
951   struct ParseError : public sg_exception
952   {
953       ParseError(const std::string& message = std::string())
954           : sg_exception(message) {}
955   };
956     
957   // Support for binding variables around an expression.
958   class Binding
959   {
960   public:
961       virtual ~Binding() {}
962       const virtual Value* getBindings() const = 0;
963       virtual Value* getBindings() = 0;
964   };
965
966   class VariableLengthBinding : public Binding
967   {
968   public:
969       const Value* getBindings() const
970       {
971           if (_bindings.empty())
972               return 0;
973           else
974               return &_bindings[0];
975       }
976       Value* getBindings()
977       {
978           if (_bindings.empty())
979               return 0;
980           else
981               return &_bindings[0];
982       }
983       std::vector<Value> _bindings;
984   };
985
986   template<int Size> class FixedLengthBinding : public Binding
987   {
988   public:
989       Value* getBindings()
990       {
991           return &_bindings[0];
992       }
993       const Value* getBindings() const
994       {
995           return &_bindings[0];
996       }
997       Value _bindings[Size];
998   };
999
1000   struct VariableBinding
1001   {
1002       VariableBinding() : type(expression::DOUBLE), location(-1) {}
1003
1004       VariableBinding(const std::string& name_, expression::Type type_,
1005                       int location_)
1006           : name(name_), type(type_), location(location_)
1007       {
1008       }
1009       std::string name;
1010       expression::Type type;
1011       int location;
1012   };
1013
1014   class BindingLayout
1015   {
1016   public:
1017       size_t addBinding(const std::string& name, expression::Type type);
1018       bool findBinding(const std::string& name, VariableBinding& result) const;
1019       std::vector<VariableBinding> bindings;
1020   };
1021
1022   class Parser {
1023   public:
1024       typedef Expression* (*exp_parser)(const SGPropertyNode* exp,
1025                                         Parser* parser);
1026       void addParser(const std::string& name, exp_parser parser)
1027       {
1028           getParserMap().insert(std::make_pair(name, parser));
1029       }
1030       Expression* read(const SGPropertyNode* exp)
1031       {
1032           ParserMap& map = getParserMap();
1033           ParserMap::iterator itr = map.find(exp->getName());
1034           if (itr == map.end())
1035               throw ParseError(std::string("unknown expression ") + exp->getName());
1036           exp_parser parser = itr->second;
1037           return (*parser)(exp, this);
1038       }
1039       // XXX vector of SGSharedPtr?
1040       bool readChildren(const SGPropertyNode* exp,
1041                         std::vector<Expression*>& result);
1042       /**
1043        * Function that parses a property tree, producing an expression.
1044        */
1045       typedef std::map<const std::string, exp_parser> ParserMap;
1046       virtual ParserMap& getParserMap() = 0;
1047       /**
1048        * After an expression is parsed, the binding layout may contain
1049        * references that need to be bound during evaluation.
1050        */
1051       BindingLayout& getBindingLayout() { return _bindingLayout; }
1052   protected:
1053       BindingLayout _bindingLayout;
1054   };
1055
1056   class ExpressionParser : public Parser
1057   {
1058   public:
1059       ParserMap& getParserMap()
1060       {
1061           return ParserMapSingleton::instance()->_parserTable;
1062       }
1063       static void addExpParser(const std::string&, exp_parser);
1064   protected:
1065       struct ParserMapSingleton : public simgear::Singleton<ParserMapSingleton>
1066       {
1067           ParserMap _parserTable;
1068       };
1069   };
1070
1071   /**
1072    * Constructor for registering parser functions.
1073    */
1074   struct ExpParserRegistrar
1075   {
1076       ExpParserRegistrar(const std::string& token, Parser::exp_parser parser)
1077       {
1078           ExpressionParser::addExpParser(token, parser);
1079       }
1080   };
1081
1082   }
1083
1084   /**
1085    * Access a variable definition. Use a location from a BindingLayout.
1086    */
1087   template<typename T>
1088   class VariableExpression : public ::SGExpression<T> {
1089   public:
1090     VariableExpression(int location) : _location(location) {}
1091     virtual ~VariableExpression() {}
1092     virtual void eval(T& value, const simgear::expression::Binding* b) const
1093     {
1094       const expression::Value* values = b->getBindings();
1095       value = *reinterpret_cast<const T *>(&values[_location].val);
1096     }
1097   protected:
1098     int _location;
1099
1100   };
1101
1102   /**
1103    * An n-ary expression where the types of the argument aren't the
1104    * same as the return type.
1105    */
1106   template<typename T, typename OpType>
1107   class GeneralNaryExpression : public ::SGExpression<T> {
1108   public:
1109     typedef OpType operand_type;
1110     size_t getNumOperands() const
1111     { return _expressions.size(); }
1112     const ::SGExpression<OpType>* getOperand(size_t i) const
1113     { return _expressions[i]; }
1114     ::SGExpression<OpType>* getOperand(size_t i)
1115     { return _expressions[i]; }
1116     size_t addOperand(::SGExpression<OpType>* expression)
1117     {
1118       if (!expression)
1119         return ~size_t(0);
1120       _expressions.push_back(expression);
1121       return _expressions.size() - 1;
1122     }
1123     
1124     template<typename Iter>
1125     void addOperands(Iter begin, Iter end)
1126     {
1127       for (Iter iter = begin; iter != end; ++iter)
1128         {
1129           addOperand(static_cast< ::SGExpression<OpType>*>(*iter));
1130         }
1131     }
1132     
1133     virtual bool isConst() const
1134     {
1135       for (size_t i = 0; i < _expressions.size(); ++i)
1136         if (!_expressions[i]->isConst())
1137           return false;
1138       return true;
1139     }
1140     virtual ::SGExpression<T>* simplify()
1141     {
1142       for (size_t i = 0; i < _expressions.size(); ++i)
1143         _expressions[i] = _expressions[i]->simplify();
1144       return SGExpression<T>::simplify();
1145     }
1146
1147     simgear::expression::Type getOperandType() const
1148     {
1149       return simgear::expression::TypeTraits<OpType>::typeTag;
1150     }
1151     
1152   protected:
1153     GeneralNaryExpression()
1154     { }
1155     GeneralNaryExpression(::SGExpression<OpType>* expr0,
1156                           ::SGExpression<OpType>* expr1)
1157     { addOperand(expr0); addOperand(expr1); }
1158
1159     std::vector<SGSharedPtr<SGExpression<OpType> > > _expressions;
1160   };
1161
1162   /**
1163    * A predicate that wraps, for example the STL template predicate
1164    * expressions like std::equal_to.
1165    */
1166   template<typename OpType, template<typename PredOp> class Pred>
1167   class PredicateExpression : public GeneralNaryExpression<bool, OpType> {
1168   public:
1169     PredicateExpression()
1170     {
1171     }
1172     PredicateExpression(::SGExpression<OpType>* expr0,
1173                         ::SGExpression<OpType>* expr1)
1174       : GeneralNaryExpression<bool, OpType>(expr0, expr1)
1175     {
1176     }
1177     virtual void eval(bool& value, const simgear::expression::Binding* b) const
1178     {
1179       size_t sz = this->getNumOperands();
1180       if (sz != 2)
1181         return;
1182       value = _pred(this->getOperand(0)->getValue(b),
1183                     this->getOperand(1)->getValue(b));
1184     }
1185   protected:
1186     Pred<OpType> _pred;
1187   };
1188
1189   template<template<typename OT> class Pred, typename OpType>
1190   PredicateExpression<OpType, Pred>*
1191   makePredicate(SGExpression<OpType>* op1, SGExpression<OpType>* op2)
1192   {
1193     return new PredicateExpression<OpType, Pred>(op1, op2);
1194   }
1195   
1196   template<typename OpType>
1197   class EqualToExpression : public PredicateExpression<OpType, std::equal_to>
1198   {
1199   public:
1200     EqualToExpression() {}
1201     EqualToExpression(::SGExpression<OpType>* expr0,
1202                       ::SGExpression<OpType>* expr1)
1203       : PredicateExpression<OpType, std::equal_to>(expr0, expr1)
1204     {
1205     }
1206   };
1207
1208   template<typename OpType>
1209   class LessExpression : public PredicateExpression<OpType, std::less>
1210   {
1211   public:
1212     LessExpression() {}
1213     LessExpression(::SGExpression<OpType>* expr0, ::SGExpression<OpType>* expr1)
1214       : PredicateExpression<OpType, std::less>(expr0, expr1)
1215     {
1216     }
1217   };
1218
1219   template<typename OpType>
1220   class LessEqualExpression
1221     : public PredicateExpression<OpType, std::less_equal>
1222   {
1223   public:
1224     LessEqualExpression() {}
1225     LessEqualExpression(::SGExpression<OpType>* expr0,
1226                         ::SGExpression<OpType>* expr1)
1227       : PredicateExpression<OpType, std::less_equal>(expr0, expr1)
1228     {
1229     }
1230   };
1231
1232   class NotExpression : public ::SGUnaryExpression<bool>
1233   {
1234   public:
1235     NotExpression(::SGExpression<bool>* expr = 0)
1236       : ::SGUnaryExpression<bool>(expr)
1237     {
1238     }
1239     void eval(bool& value, const expression::Binding* b) const
1240     {
1241       value = !getOperand()->getValue(b);
1242     }
1243   };
1244
1245   class OrExpression : public ::SGNaryExpression<bool>
1246   {
1247   public:
1248     void eval(bool& value, const expression::Binding* b) const
1249     {
1250       value = false;
1251       for (int i = 0; i < (int)getNumOperands(); ++i) {
1252         value = value || getOperand(i)->getValue(b);
1253         if (value)
1254           return;
1255       }
1256     }
1257   };
1258
1259   class AndExpression : public ::SGNaryExpression<bool>
1260   {
1261   public:
1262     void eval(bool& value, const expression::Binding* b) const
1263     {
1264       value = true;
1265       for (int i = 0; i < (int)getNumOperands(); ++i) {
1266         value = value && getOperand(i)->getValue(b);
1267         if (!value)
1268           return;
1269       }
1270     }
1271   };
1272
1273   /**
1274    * Convert an operand from OpType to T.
1275    */
1276   template<typename T, typename OpType>
1277   class ConvertExpression : public GeneralNaryExpression<T, OpType>
1278   {
1279   public:
1280     ConvertExpression() {}
1281     ConvertExpression(::SGExpression<OpType>* expr0)
1282     {
1283       this->addOperand(expr0);
1284     }
1285     virtual void eval(T& value, const simgear::expression::Binding* b) const
1286     {
1287       typename ConvertExpression::operand_type result;
1288       this->_expressions.at(0)->eval(result, b);
1289       value = result;
1290     }
1291   };
1292 }
1293 #endif // _SG_EXPRESSION_HXX