Disable all code related to libXp
[oweals/cde.git] / cde / programs / dtinfo / DtMmdb / StyleSheet / FeatureValue.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 // $TOG: FeatureValue.C /main/6 1998/04/17 11:49:16 mgreess $
24 #include "StyleSheetExceptions.h"
25 #include "SymTab.h"
26 #include "Feature.h"
27 #include "FeatureValue.h"
28 #include "Expression.h"
29 #include "Debug.h"
30 #include <utility/funcs.h>
31 #include <ctype.h>
32
33 #include <string.h>
34
35 /* cloning */
36 FeatureValue *
37 FeatureValueInt::clone() const
38 {
39   return new FeatureValueInt(*this);
40 }
41 FeatureValue *
42 FeatureValueReal::clone() const
43 {
44   return new FeatureValueReal(*this);
45 }
46 FeatureValue *
47 FeatureValueString::clone() const
48 {
49   return new FeatureValueString(*this);
50 }
51 FeatureValue *
52 FeatureValueSymbol::clone() const
53 {
54   return new FeatureValueSymbol(*this);
55 }
56 FeatureValue *
57 FeatureValueExpression::clone() const
58 {
59   return new FeatureValueExpression(*this);
60 }
61 FeatureValue *
62 FeatureValueFeatureSet::clone() const
63 {
64   return new FeatureValueFeatureSet(*this);
65 }
66 FeatureValue *
67 FeatureValueDimension::clone() const
68 {
69   return new FeatureValueDimension(*this);
70 }
71
72 // copy constructors
73
74 /* -------- Int -------- */
75
76 FeatureValueInt::FeatureValueInt(const FeatureValueInt &object)
77 : FeatureValue(integer), f_value(object.f_value)
78 {
79 }
80
81 /* -------- real -------- */
82 FeatureValueReal::FeatureValueReal(const FeatureValueReal &object)
83 : FeatureValue(real), f_value(object.f_value)
84 {
85 }
86
87 /* -------- String -------- */
88 FeatureValueString::FeatureValueString(const FeatureValueString &object)
89 : FeatureValue(string), f_value(object.f_value)
90 {
91 }
92
93
94 /* -------- Symbol -------- */
95 FeatureValueSymbol::FeatureValueSymbol(const FeatureValueSymbol &object)
96 : FeatureValue(symbol), f_value(object.f_value)
97 {
98 }
99
100 /* -------- Expression -------- */
101 FeatureValueExpression::FeatureValueExpression(const FeatureValueExpression &object)
102 : FeatureValue(expression), f_value(new Expression(*object.f_value))
103 {
104 }
105 FeatureValueExpression::FeatureValueExpression(Expression *e)
106 : FeatureValue(expression), f_value(e)
107 {
108 }
109
110 /* -------- Feature Set -------- */
111 FeatureValueFeatureSet::FeatureValueFeatureSet(FeatureSet *fs)
112 : FeatureValue(featureset), f_value(fs)
113 {
114 }
115
116 FeatureValueFeatureSet::FeatureValueFeatureSet(const FeatureValueFeatureSet &object)
117 : FeatureValue(featureset), f_value(new FeatureSet(*object.f_value))
118 {
119 }
120
121
122 FeatureValueDimension::FeatureValueDimension(const FeatureValueDimension& object)
123 : FeatureValue(dimension),
124   f_cachedValue(object.f_cachedValue),
125   f_unit(object.f_unit)
126 {
127    f_value = (object.f_value == 0) ? 0 : object.f_value -> clone();
128 }
129
130
131 // /////////////////////////////////////////////////////////////////////////
132 // Destructors
133 // /////////////////////////////////////////////////////////////////////////
134
135 FeatureValue::~FeatureValue()
136 {
137 }
138
139
140 FeatureValueString::~FeatureValueString()
141 {
142 }
143
144 FeatureValueExpression::~FeatureValueExpression()
145 {
146   delete f_value ;
147 }
148
149 FeatureValueFeatureSet::~FeatureValueFeatureSet()
150 {
151   delete f_value;
152 }
153
154 FeatureValueDimension::~FeatureValueDimension()
155 {
156   delete f_value;
157 }
158
159 /*
160   // operators 
161   virtual FeatureValue *operator+(FeatureValue&);
162   virtual FeatureValue *operator-(FeatureValue&);
163   virtual FeatureValue *operator*(FeatureValue&);
164   virtual FeatureValue *operator/(FeatureValue&);
165   */
166
167 FeatureValue *
168 FeatureValue::operator+(const FeatureValue &) const
169 {
170   // if we are here, then we did not override this function, and therefore
171   // cannot properly respond, so we use zero as our value
172   throw(CASTBEEXCEPT badEvaluationException());
173   return 0 ;
174 };
175
176 FeatureValue *
177 FeatureValue::operator-(const FeatureValue &) const
178 {
179   // if we are here, then we did not override this function, and therefore
180   // cannot properly respond, so we use zero as our value
181   throw (CASTBEEXCEPT badEvaluationException());
182   return 0 ;
183 };
184
185 FeatureValue *
186 FeatureValue::operator*(const FeatureValue &) const
187 {
188   // if we are here, then we did not override this function, and therefore
189   // cannot properly respond, so we use zero as our value
190   throw(CASTBEEXCEPT badEvaluationException());
191   return 0 ;
192 };
193
194 FeatureValue *
195 FeatureValue::operator/(const FeatureValue &) const
196 {
197   throw(CASTBEEXCEPT badEvaluationException());
198   return 0;
199 };
200
201 FeatureValue *
202 FeatureValue::operator+(const int)  const
203 {
204   throw(CASTBEEXCEPT badEvaluationException());
205   return 0;
206 }
207 FeatureValue *
208 FeatureValue::operator-(const int)  const
209 {
210   throw(CASTBEEXCEPT badEvaluationException());
211   return 0;
212 }
213
214 FeatureValue *
215 FeatureValue::operator*(const int)  const
216 {
217   throw(CASTBEEXCEPT badEvaluationException());
218   return 0;
219 }
220
221 FeatureValue *
222 FeatureValue::operator/(const int)  const
223 {
224   throw(CASTBEEXCEPT badEvaluationException());
225   return 0;
226 }
227
228 FeatureValue *
229 FeatureValue::operator+(const float)  const
230 {
231   throw(CASTBEEXCEPT badEvaluationException());
232   return 0;
233 }
234
235
236 FeatureValue *
237 FeatureValue::operator-(const float)  const
238 {
239   throw(CASTBEEXCEPT badEvaluationException());
240   return 0;
241 }
242 FeatureValue *
243 FeatureValue::operator*(const float)  const
244 {
245   throw(CASTBEEXCEPT badEvaluationException());
246   return 0;
247 }
248
249 FeatureValue *
250 FeatureValue::operator/(const float)  const
251 {
252   throw(CASTBEEXCEPT badEvaluationException());
253   return 0;
254 }
255
256
257 FeatureValue*
258 FeatureValue::operator+(const FeatureValueInt&) const
259 {
260   throw(CASTBEEXCEPT badEvaluationException());
261   return 0;
262 }
263
264 FeatureValue*
265 FeatureValue::operator-(const FeatureValueInt&) const
266 {
267   throw(CASTBEEXCEPT badEvaluationException());
268   return 0;
269 }
270
271 FeatureValue*
272 FeatureValue::operator*(const FeatureValueInt&) const
273 {
274   throw(CASTBEEXCEPT badEvaluationException());
275   return 0;
276 }
277
278 FeatureValue*
279 FeatureValue::operator/(const FeatureValueInt&) const
280 {
281   throw(CASTBEEXCEPT badEvaluationException());
282   return 0;
283 }
284
285
286 FeatureValue*
287 FeatureValue::operator+(const FeatureValueReal&) const
288 {
289   throw(CASTBEEXCEPT badEvaluationException());
290   return 0;
291 }
292
293 FeatureValue*
294 FeatureValue::operator-(const FeatureValueReal&) const
295 {
296   throw(CASTBEEXCEPT badEvaluationException());
297   return 0;
298 }
299
300 FeatureValue*
301 FeatureValue::operator*(const FeatureValueReal&) const
302 {
303   throw(CASTBEEXCEPT badEvaluationException());
304   return 0;
305 }
306
307 FeatureValue*
308 FeatureValue::operator/(const FeatureValueReal&) const
309 {
310   throw(CASTBEEXCEPT badEvaluationException());
311   return 0;
312 }
313
314
315 FeatureValue*
316 FeatureValue::operator+(const FeatureValueDimension&) const
317 {
318   throw(CASTBEEXCEPT badEvaluationException());
319   return 0;
320 }
321
322 FeatureValue*
323 FeatureValue::operator-(const FeatureValueDimension&) const
324 {
325   throw(CASTBEEXCEPT badEvaluationException());
326   return 0;
327 }
328
329 FeatureValue*
330 FeatureValue::operator*(const FeatureValueDimension&) const
331 {
332   throw(CASTBEEXCEPT badEvaluationException());
333   return 0;
334 }
335
336 FeatureValue*
337 FeatureValue::operator/(const FeatureValueDimension&) const
338 {
339   throw(CASTBEEXCEPT badEvaluationException());
340   return 0;
341 }
342
343
344 FeatureValue*
345 FeatureValue::operator+(const FeatureValueExpression&) const
346 {
347   throw(CASTBEEXCEPT badEvaluationException());
348   return 0;
349 }
350
351 FeatureValue*
352 FeatureValue::operator-(const FeatureValueExpression&) const
353 {
354   throw(CASTBEEXCEPT badEvaluationException());
355   return 0;
356 }
357
358 FeatureValue*
359 FeatureValue::operator*(const FeatureValueExpression&) const
360 {
361   throw(CASTBEEXCEPT badEvaluationException());
362   return 0;
363 }
364
365 FeatureValue*
366 FeatureValue::operator/(const FeatureValueExpression&) const
367 {
368   throw(CASTBEEXCEPT badEvaluationException());
369   return 0;
370 }
371
372
373 // /////////////////////////////////////////////////////////////////////////
374 // operators for FeatureValueInt
375 // /////////////////////////////////////////////////////////////////////////
376
377 FeatureValue *
378 FeatureValueInt::operator+(const FeatureValue &value) const
379 {
380   return value + f_value ;
381 }
382
383 FeatureValue *
384 FeatureValueInt::operator-(const FeatureValue &value) const
385 {
386   return value.rsub(f_value) ;
387 }
388
389 FeatureValue *
390 FeatureValueInt::operator*(const FeatureValue &value) const
391 {
392   return value * f_value ;
393 }
394
395 FeatureValue *
396 FeatureValueInt::operator/(const FeatureValue &value) const
397 {
398   return value.rdiv(f_value);
399 }
400
401 // now comes the ability to do actual operations because all types are know
402
403 FeatureValue*
404 FeatureValueInt::operator+(const int i) const
405 {
406   return new FeatureValueInt(f_value + i);
407 }
408
409 FeatureValue*
410 FeatureValueInt::operator-(const int i) const 
411 {
412   return new FeatureValueInt(f_value - i);
413 }
414
415 FeatureValue*
416 FeatureValueInt::operator*(const int i) const
417 {
418   return new FeatureValueInt(f_value * i);
419 }
420
421 FeatureValue*
422 FeatureValueInt::operator/(const int i) const
423 {
424   return new FeatureValueReal((float)f_value / (float)i);
425 }
426
427
428 // /////////////////////////////////////////////////////////////////////////
429 // Printing
430 // /////////////////////////////////////////////////////////////////////////
431
432 // output operator, uses virtual function print
433 ostream & operator << (ostream &o, const FeatureValue &f)
434 {
435   return f.print(o);
436 }
437
438 ostream  &
439 FeatureValueReal::print(ostream &o) const
440 {
441   return o << f_value ; 
442 }
443 ostream &
444 FeatureValueInt::print(ostream &o) const
445 {
446   return o << f_value ; 
447 }
448 ostream &
449 FeatureValueString::print(ostream &o) const
450 {
451   return o << '"' << f_value << '"'; 
452 }
453 ostream &
454 FeatureValueSymbol::print(ostream &o) const
455 {
456   return o << f_value ; 
457 }
458 ostream &
459 FeatureValueExpression::print(ostream &o) const
460 {
461   return o << *f_value ; 
462 }
463 ostream &
464 FeatureValueFeatureSet::print(ostream &o) const
465 {
466   return o << *f_value ; 
467 }
468
469
470 // /////////////////////////////////////////////////////////////////////////
471 // Casting
472 // /////////////////////////////////////////////////////////////////////////
473
474 FeatureValue::operator const FeatureSet *() const
475 {
476   throw(CASTBCEXCEPT badCastException());
477   return 0 ;
478 }
479
480 FeatureValueFeatureSet::operator const FeatureSet *() const
481 {
482   return f_value ;
483 }
484
485 FeatureValue::operator float() const
486 {
487   throw(CASTBCEXCEPT badCastException());
488   return 0;
489 }
490 FeatureValue::operator int() const
491 {
492   throw(CASTBCEXCEPT badCastException());
493   return 0;
494 }
495 FeatureValue::operator const char *() const
496 {
497   throw(CASTBCEXCEPT badCastException());
498   return 0;
499 }
500
501 FeatureValueReal::operator int() const
502 {
503   return (int)f_value ;
504 }
505
506 FeatureValueReal::operator float() const
507 {
508   return f_value ;
509 }
510
511 FeatureValue *
512 FeatureValueString::operator+(const FeatureValue& x) const 
513 {
514    if ( x.type() != string )
515      return FeatureValue::operator+(x);
516    else {
517      const char* str1 = *this;
518      const char* str2 = x;
519
520      int len1 = f_value.length();
521      int len2 = ((FeatureValueString*)&x) -> f_value.length();
522
523      char* newString = new char[len1 + len2 + 1];
524
525      int i;
526      for ( i=0; i<len1; i++ )
527         newString[i] = str1[i];
528        
529      for ( i=0; i<len2; i++ )
530         newString[i+len1] = str2[i];
531        
532      newString[len1+len2] = 0;
533
534      FeatureValueString *z = new FeatureValueString(newString);
535      delete newString;
536
537      return z;
538    }
539 }
540
541 FeatureValue *
542 FeatureValueString::operator+(const FeatureValueInt& x) const 
543 {
544    return FeatureValue::operator+(x);
545 }
546
547 FeatureValue *
548 FeatureValueString::operator+(const FeatureValueReal& x) const 
549 {
550    return FeatureValue::operator+(x);
551 }
552
553 FeatureValue *
554 FeatureValueString::operator+(const FeatureValueDimension& x) const 
555 {
556    return FeatureValue::operator+(x);
557 }
558
559 FeatureValue *
560 FeatureValueString::operator+(const FeatureValueExpression& expr) const 
561 {
562    FeatureValue *x = 0;
563    FeatureValue *y = 0;
564    mtry
565     {
566       x = expr.evaluate();
567       y = operator+(*x);
568       delete x;
569       return y;
570     }
571    mcatch_any()
572     {
573       delete x;
574       rethrow;
575     }
576    end_try ;
577 }
578 FeatureValue *
579 FeatureValueString::operator+(const int i) const 
580 {
581    return FeatureValue::operator+(i);
582 }
583
584 FeatureValue *
585 FeatureValueString::operator+(const float f) const 
586 {
587    return FeatureValue::operator+(f);
588 }
589
590 FeatureValueString::operator const char *() const
591 {
592   return f_value ;
593 }
594
595 FeatureValueSymbol::operator const char *() const
596 {
597   return strdup(f_value.name()) ;
598 }
599
600 FeatureValueInt::operator const char *() const
601 {
602   throw(CASTBCEXCEPT badCastException()) ;
603   return 0;
604 }
605
606 FeatureValueExpression::operator const char *() const
607 {
608   throw(CASTBCEXCEPT badCastException()) ;
609   return 0;
610 }
611
612 FeatureValueDimension::operator int ()  const
613 {
614   if ( f_cachedValue != -1 )
615     return (int)f_cachedValue;
616
617   if ( f_value == 0 )
618      throw(CASTBEEXCEPT badEvaluationException()) ;
619
620   FeatureValue *intermediate = f_value->doConvert(f_unit);
621   int i = *intermediate ;
622   delete intermediate ;
623   return i ;
624 }
625
626 FeatureValueDimension::operator float()  const
627 {
628   if ( f_cachedValue != -1 )
629     return f_cachedValue;
630
631   if ( f_value == 0 )
632      throw(CASTBEEXCEPT badEvaluationException()) ;
633
634   FeatureValue *intermediate = f_value->doConvert(f_unit);
635   float f = *intermediate ;
636   delete intermediate ;
637   return f ;
638 }
639
640 FeatureValueDimension::operator const char *() const 
641 {
642   throw(CASTBCEXCEPT badCastException()) ;
643   return 0;
644 }
645
646 // /////////////////////////////////////////////////////////////////////////
647 // Evaluate
648 // /////////////////////////////////////////////////////////////////////////
649
650 FeatureValue *
651 FeatureValue::evaluate() const
652 {
653    return clone();
654 }
655
656 FeatureValue *
657 FeatureValueFeatureSet::evaluate() const
658 {
659 #ifdef TK
660   FeatureSet* fs = new FeatureSet;
661   return new FeatureValueFeatureSet(f_value->evaluate(fs)); 
662 #else
663   return new FeatureValueFeatureSet(f_value->evaluate());
664 #endif
665 }
666
667 FeatureValue *
668 FeatureValueExpression::evaluate() const
669 {
670   return f_value->evaluate();
671 }
672
673 // /////////////////////////////////////////////////////////////////////////
674 // more math for Expression
675 // /////////////////////////////////////////////////////////////////////////
676
677 FeatureValue *
678 FeatureValueExpression::operator/(const FeatureValue &f) const
679 {
680   // Need parameters for evaluate 
681   FeatureValue *eval = evaluate();
682   FeatureValue *rval = (*eval) / f ;
683   delete eval ;
684   return rval ;
685 }
686
687 FeatureValue *
688 FeatureValueExpression::operator*(const FeatureValue &f) const
689 {
690   // Need parameters for evaluate 
691   FeatureValue *eval = evaluate();
692   FeatureValue *rval = (*eval) * f ;
693   delete eval ;
694   return rval ;
695 }
696 FeatureValue *
697 FeatureValueExpression::operator-(const FeatureValue &f) const
698 {
699   // Need parameters for evaluate 
700   FeatureValue *eval = evaluate();
701   FeatureValue *rval = (*eval) - f ;
702   delete eval ;
703   return rval ;
704 }
705 FeatureValue *
706 FeatureValueExpression::operator+(const FeatureValue &f) const
707 {
708   // Need parameters for evaluate 
709   FeatureValue *eval = evaluate();
710   FeatureValue *rval = (*eval) + f ;
711   delete eval ;
712   return rval ;
713 }
714
715 FeatureValue *
716 FeatureValueExpression::operator/(const float f) const
717 {
718   // need values for evaluate 
719   FeatureValue *eval = evaluate();
720   FeatureValue *rval = (*eval) / f ;
721   delete eval ;
722   return rval ;
723 }
724 FeatureValue *
725 FeatureValueExpression::operator*(const float f) const
726 {
727   // need values for evaluate 
728   FeatureValue *eval = evaluate();
729   FeatureValue *rval = (*eval) * f ;
730   delete eval ;
731   return rval ;
732 }
733 FeatureValue *
734 FeatureValueExpression::operator-(const float f) const
735 {
736   // need values for evaluate 
737   FeatureValue *eval = evaluate();
738   FeatureValue *rval = (*eval) - f ;
739   delete eval ;
740   return rval ;
741 }
742 FeatureValue *
743 FeatureValueExpression::operator+(const float f) const
744 {
745   // need values for evaluate 
746   FeatureValue *eval = evaluate();
747   FeatureValue *rval = (*eval) + f ;
748   delete eval ;
749   return rval ;
750 }
751
752
753 FeatureValue *
754 FeatureValueExpression::operator/(const int f) const
755 {
756   // need values for evaluate 
757   FeatureValue *eval = evaluate();
758   FeatureValue *rval = (*eval) / f ;
759   delete eval ;
760   return rval ;
761 }
762 FeatureValue *
763 FeatureValueExpression::operator*(const int f) const
764 {
765   // need values for evaluate 
766   FeatureValue *eval = evaluate();
767   FeatureValue *rval = (*eval) * f ;
768   delete eval ;
769   return rval ;
770 }
771 FeatureValue *
772 FeatureValueExpression::operator-(const int f) const
773 {
774   // need values for evaluate 
775   FeatureValue *eval = evaluate();
776   FeatureValue *rval = (*eval) - f ;
777   delete eval ;
778   return rval ;
779 }
780 FeatureValue *
781 FeatureValueExpression::operator+(const int f) const
782 {
783   // need values for evaluate 
784   FeatureValue *eval = evaluate();
785   FeatureValue *rval = (*eval) + f ;
786   delete eval ;
787   return rval ;
788 }
789
790 FeatureValue *
791 FeatureValueInt::operator/(const float f) const
792 {
793   return new FeatureValueReal(f_value / f);
794 }
795 FeatureValue *
796 FeatureValueInt::operator*(const float f) const
797 {
798   return new FeatureValueReal(f_value * f);
799 }
800
801 FeatureValue *
802 FeatureValueInt::operator-(const float f) const
803 {
804   return new FeatureValueReal(f_value - f);
805 }
806
807 FeatureValue*
808 FeatureValueInt::operator+(const float f) const
809 {
810   return new FeatureValueReal(f_value + f);
811 }
812
813 FeatureValueReal::operator const char*(void) const
814 {
815   throw(CASTBEEXCEPT badEvaluationException());
816   return 0;
817 }
818
819 FeatureValueString::operator int(void) const
820 {
821 #ifdef old_code
822   throw(CASTBEEXCEPT badEvaluationException());
823   return 0;
824 #else
825   return atoi (f_value);
826 #endif
827 }
828
829 FeatureValueString::operator float(void) const
830 {
831   throw(CASTBEEXCEPT badEvaluationException());
832   return 0;
833 }
834
835 FeatureValueSymbol::operator int(void) const
836 {
837   throw(CASTBEEXCEPT badEvaluationException());
838   return 0;
839 }
840
841 FeatureValueSymbol::operator float(void) const
842 {
843   throw(CASTBEEXCEPT badEvaluationException());
844   return 0;
845 }
846
847 FeatureValue*
848 FeatureValueReal::operator/(const FeatureValue &f) const
849 {
850   return f.rdiv(f_value);
851 }
852
853 FeatureValue*
854 FeatureValueReal::operator*(const FeatureValue &f) const
855 {
856   return f * f_value ;
857 }
858 FeatureValue*
859 FeatureValueReal::operator-(const FeatureValue &f) const
860 {
861   return f.rsub(f_value);
862 }
863 FeatureValue*
864 FeatureValueReal::operator+(const FeatureValue &f) const
865 {
866   return f + f_value ;
867 }
868
869
870 FeatureValueExpression::operator int(void) const
871 {
872   FeatureValue *eval = evaluate();
873   int i = (int)(*eval);
874   delete eval;
875   return i;
876 }
877
878 FeatureValueExpression::operator float(void) const
879 {
880   FeatureValue *eval = evaluate();
881   float f = (float)(*eval);
882   delete eval;
883   return f;
884 }
885
886 FeatureValue *
887 FeatureValueReal::operator/(const float f) const
888 {
889   return  new FeatureValueReal(f_value / f);
890 }
891 FeatureValue *
892 FeatureValueReal::operator*(const float f) const
893 {
894   return  new FeatureValueReal(f_value * f);
895 }
896 FeatureValue *
897 FeatureValueReal::operator-(const float f) const
898 {
899   return  new FeatureValueReal(f_value - f);
900 }
901 FeatureValue *
902 FeatureValueReal::operator+(const float f) const
903 {
904   return  new FeatureValueReal(f_value + f);
905 }
906
907 FeatureValue*
908 FeatureValueReal::operator/(const int i) const
909 {
910   return new FeatureValueReal(f_value / (float) i);
911 }
912 FeatureValue*
913 FeatureValueReal::operator*(const int i) const
914 {
915   return new FeatureValueReal(f_value * (float) i);
916 }
917 FeatureValue*
918 FeatureValueReal::operator-(const int i) const
919 {
920   return new FeatureValueReal(f_value - (float) i);
921 }
922 FeatureValue*
923 FeatureValueReal::operator+(const int i) const
924 {
925   return new FeatureValueReal(f_value + (float) i);
926 }
927
928 FeatureValueInt::operator int(void) const
929 {
930   return f_value  ;
931 }
932
933 FeatureValueInt::operator float(void) const
934 {
935   return f_value ;
936 }
937
938
939 // /////////////////////////////////////////////////////////////////////////
940 // operator ==
941 // /////////////////////////////////////////////////////////////////////////
942
943 unsigned int
944 FeatureValue::operator==(const FeatureValue &) const 
945 {
946   // false unless overridden by derived objects
947   return 0 ;
948 }
949 unsigned int
950 FeatureValue::operator==(const FeatureValueInt &) const 
951 {
952   return 0 ;
953 }
954 unsigned int
955 FeatureValue::operator==(const FeatureValueReal &) const
956 {
957   return 0 ;
958 }
959 unsigned int
960 FeatureValue::operator==(const FeatureValueString &) const
961 {
962   return 0 ;
963 }
964 unsigned int
965 FeatureValue::operator==(const FeatureValueSymbol &) const
966 {
967   return 0 ;
968 }
969
970
971 unsigned int
972 FeatureValueInt::operator==(const FeatureValue &f) const
973 {
974   return f == *this ;
975 }
976
977 unsigned int
978 FeatureValueInt::operator==(const FeatureValueInt &f) const
979 {
980   return f.f_value == f_value ;
981 }
982 unsigned int
983 FeatureValueInt::operator==(const FeatureValueReal &) const
984 {
985   return 0 ;
986 }
987 unsigned int
988 FeatureValueInt::operator==(const FeatureValueString &) const
989 {
990   return 0 ;
991 }
992 unsigned int
993 FeatureValueInt::operator==(const FeatureValueSymbol &) const
994 {
995   return 0 ;
996 }
997
998
999 unsigned int
1000 FeatureValueReal::operator==(const FeatureValue &f) const
1001 {
1002   return f == *this ;
1003 }
1004
1005 unsigned int
1006 FeatureValueReal::operator==(const FeatureValueReal &f) const
1007 {
1008   return f.f_value == f_value ;
1009 }
1010 unsigned int
1011 FeatureValueReal::operator==(const FeatureValueInt &) const
1012 {
1013   return 0 ;
1014 }
1015 unsigned int
1016 FeatureValueReal::operator==(const FeatureValueString &) const
1017 {
1018   return 0 ;
1019 }
1020 unsigned int
1021 FeatureValueReal::operator==(const FeatureValueSymbol &) const
1022 {
1023   return 0 ;
1024 }
1025
1026 unsigned int
1027 FeatureValueSymbol::operator==(const FeatureValue &f) const
1028 {
1029   return f == *this ;
1030 }
1031 unsigned int
1032 FeatureValueSymbol::operator==(const FeatureValueSymbol &f) const
1033 {
1034   return f.f_value == f_value ;
1035 }
1036 unsigned int
1037 FeatureValueSymbol::operator==(const FeatureValueInt &) const
1038 {
1039   return 0 ;
1040 }
1041 unsigned int
1042 FeatureValueSymbol::operator==(const FeatureValueReal &) const
1043 {
1044   return 0 ;
1045 }
1046 unsigned int
1047 FeatureValueSymbol::operator==(const FeatureValueString &) const
1048 {
1049   return 0 ;
1050 }
1051
1052 unsigned int
1053 FeatureValueString::operator==(const FeatureValue &f) const
1054 {
1055   return f == *this ;
1056 }
1057 unsigned int
1058 FeatureValueString::operator==(const FeatureValueString &f) const
1059 {
1060   return !f_value.compareTo(f.f_value, CC_String::exact);
1061 }
1062 unsigned int
1063 FeatureValueString::operator==(const FeatureValueInt &) const
1064 {
1065   return 0 ;
1066 }
1067 unsigned int
1068 FeatureValueString::operator==(const FeatureValueReal &) const
1069 {
1070   return 0 ;
1071 }
1072 unsigned int
1073 FeatureValueString::operator==(const FeatureValueSymbol &) const
1074 {
1075   return 0 ;
1076 }
1077
1078 // /////////////////////////////////////////////////////////////////////////
1079 // merge
1080 // /////////////////////////////////////////////////////////////////////////
1081
1082
1083 FeatureValue *
1084 FeatureValue::merge(const FeatureValue &f)
1085 {
1086   return f.clone();
1087 }
1088
1089 FeatureValue *
1090 FeatureValueFeatureSet::merge(const FeatureValue &f)
1091 {
1092   if (f.type() == featureset)
1093     return new FeatureValueFeatureSet(new FeatureSet(*f_value, 
1094                                                      *((FeatureValueFeatureSet*)&f)->f_value));
1095   else
1096     return f.clone() ;
1097 }
1098
1099 static float dimensionConversionTable[] = {72, 12, 1, 72/2.54};
1100
1101 static float
1102 convert(float y,
1103         FeatureValue::Unit dimensionOfy,
1104         FeatureValue::Unit dimensionOfReturn
1105         )
1106 {
1107    if ( dimensionOfy == FeatureValue::NONE ||
1108         dimensionOfReturn == FeatureValue::NONE ||
1109         dimensionOfy == dimensionOfReturn
1110       )
1111      return y;
1112
1113 // handle PIXEL case here.
1114
1115
1116 // handle INCH, PICA, POINT and CM cases here
1117
1118 //debug(cerr, y);
1119 //debug(cerr, dimensionConversionTable[dimensionOfy]);
1120 //debug(cerr, dimensionConversionTable[dimensionOfReturn]);
1121
1122    return y *
1123           dimensionConversionTable[dimensionOfy] /
1124           dimensionConversionTable[dimensionOfReturn];
1125 }
1126
1127
1128 float
1129 FeatureValueDimension::convert(float y,
1130                                Unit dimensionOfy,
1131                                Unit dimensionOfReturn
1132                               )
1133 {
1134    return ::convert(y, dimensionOfy, dimensionOfReturn);
1135 }
1136
1137 FeatureValue *FeatureValueDimension::operator/(const FeatureValue& fv) const
1138 {
1139   return fv.rdiv(*this);
1140 }
1141
1142 FeatureValue *FeatureValueDimension::operator*(const FeatureValue& fv) const
1143 {
1144   return fv * *this ;
1145 }
1146
1147 FeatureValue *FeatureValueDimension::operator-(const FeatureValue& fv) const
1148 {
1149   return fv.rsub(*this);
1150 }
1151
1152 FeatureValue *FeatureValueDimension::operator+(const FeatureValue& fv) const
1153 {
1154   return fv + *this ;
1155 }
1156
1157 FeatureValue *FeatureValueDimension::operator/(const float x) const
1158 {
1159   FeatureValue *intermediate = *f_value / x;
1160   FeatureValue *result = intermediate->convertTo(f_unit);
1161   delete  intermediate;
1162   return result ;
1163 }
1164
1165 FeatureValue *FeatureValueDimension::operator*(const float x) const
1166 {
1167   FeatureValue *intermediate = *f_value * x ;
1168   FeatureValue *result = intermediate->convertTo(f_unit);
1169   delete intermediate ;
1170   return result ;
1171 }
1172
1173 FeatureValue *FeatureValueDimension::operator-(const float x) const
1174 {
1175   FeatureValue *intermediate = *f_value - x;
1176   FeatureValue *result = intermediate->convertTo(f_unit);
1177   delete intermediate;
1178   return result ;
1179 }
1180
1181 FeatureValue *FeatureValueDimension::operator+(const float x) const
1182 {
1183   FeatureValue *intermediate = *f_value + x;
1184   FeatureValue *result = intermediate->convertTo(f_unit);
1185   delete intermediate;
1186   return result ;
1187 }
1188
1189 FeatureValue *FeatureValueDimension::operator/(const int x) const
1190 {
1191   FeatureValue *intermediate = *f_value / x ;
1192   FeatureValue *result = intermediate->convertTo(f_unit);
1193   delete intermediate;
1194   return result ;
1195 }
1196
1197 FeatureValue *FeatureValueDimension::operator*(const int x) const
1198 {
1199   FeatureValue *intermediate = *f_value * x ;
1200   FeatureValue *result = intermediate->convertTo(f_unit);
1201   delete intermediate;
1202   return result ;
1203 }
1204
1205 FeatureValue *FeatureValueDimension::operator-(const int x) const
1206 {
1207   FeatureValue *intermediate = *f_value - x ;
1208   FeatureValue *result = intermediate->convertTo(f_unit);
1209   delete intermediate ;
1210   return result ;
1211 }
1212
1213 FeatureValue *FeatureValueDimension::operator+(const int x) const
1214 {
1215   FeatureValue *intermediate = *f_value + x ;
1216   FeatureValue *result = intermediate->convertTo(f_unit);
1217   delete intermediate ;
1218   return result ;
1219 }
1220
1221 ostream& FeatureValueDimension::print(ostream& out) const
1222 {
1223   out << '<' ;
1224   if ( f_value == 0 )
1225     if ( f_cachedValue != -1 )
1226       out << f_cachedValue << " ";
1227     else
1228       throw(CASTBEEXCEPT badEvaluationException());
1229   else
1230      out << *f_value << " ";
1231
1232   switch ( f_unit )
1233     {
1234     case INCH:
1235       out << "inch";
1236       break;
1237     case PICA:
1238       out << "pica";
1239       break;
1240     case POINT:
1241       out << "point";
1242       break;
1243     case CM:
1244       out << "cm";
1245       break;
1246     case PIXEL:
1247       out << "pixel";
1248       break;
1249     default:
1250       throw(CASTBEEXCEPT badEvaluationException());
1251     }
1252   out << '>' ;
1253   return out ;
1254 }
1255
1256 FeatureValueDimension::FeatureValueDimension(float f, const char* u)
1257 : FeatureValue(dimension), f_value(0), 
1258   f_cachedValue(f)
1259 {
1260   f_unit = convertToUnit(u);
1261 }
1262
1263 FeatureValueDimension::FeatureValueDimension(FeatureValue *value, Unit unit)
1264 : FeatureValue(dimension),
1265   f_value(value), 
1266   f_cachedValue(-1),
1267   f_unit(unit)
1268 {
1269 }
1270
1271 FeatureValueDimension::FeatureValueDimension(FeatureValue* f, const char* u)
1272 : FeatureValue(dimension), f_value(f), f_cachedValue(-1)
1273 {
1274   f_unit = convertToUnit(u);
1275 }
1276
1277 FeatureValue::Unit 
1278 FeatureValueDimension::convertToUnit(const char* u)
1279 {
1280    Unit x;
1281    if ( strcasecmp(u, "inch") == 0 || strcasecmp(u, "in") == 0 )
1282        x=INCH;
1283    else
1284    if ( strcasecmp(u, "cm") == 0 )
1285       x=CM;
1286    else
1287    if ( strcasecmp(u, "pica") == 0 || strcasecmp(u, "pc") == 0 )
1288       x=PICA;
1289    else
1290    if ( strcasecmp(u, "point") == 0 || strcasecmp(u, "pt") == 0 )
1291       x=POINT;
1292    else
1293    if ( strcasecmp(u, "pixel") == 0 )
1294       x=PIXEL;
1295    else {
1296      throw(CASTBEEXCEPT badEvaluationException());
1297    }
1298    return x;
1299 }
1300
1301 float FeatureValueDimension::getValue(Unit u)
1302 {
1303    return convert(float(*this), f_unit, u);
1304 }
1305
1306 // real
1307
1308 FeatureValue*
1309 FeatureValueReal::operator+(const FeatureValueInt &value) const
1310 {
1311   return value + f_value ;
1312 }
1313
1314 FeatureValue*
1315 FeatureValueReal::operator-(const FeatureValueInt &value) const
1316 {
1317   return new FeatureValueReal(f_value - (int)value);
1318 }
1319
1320 FeatureValue*
1321 FeatureValueReal::operator*(const FeatureValueInt &value) const
1322 {
1323   return value * f_value ;
1324 }
1325
1326 FeatureValue*
1327 FeatureValueReal::operator/(const FeatureValueInt &value) const
1328 {
1329   return value.rdiv(f_value);
1330 }
1331
1332
1333 FeatureValue*
1334 FeatureValueReal::operator+(const FeatureValueReal &value) const
1335 {
1336   return value + f_value ;
1337 }
1338
1339 FeatureValue*
1340 FeatureValueReal::operator-(const FeatureValueReal &value) const
1341 {
1342   return new FeatureValueReal(f_value - value.f_value) ;
1343 }
1344
1345 FeatureValue*
1346 FeatureValueReal::operator*(const FeatureValueReal &value) const
1347 {
1348   return value * f_value ;
1349 }
1350
1351 FeatureValue*
1352 FeatureValueReal::operator/(const FeatureValueReal &value) const
1353 {
1354   return value.rdiv(f_value);
1355 }
1356
1357
1358 FeatureValue*
1359 FeatureValueReal::operator+(const FeatureValueDimension &value) const
1360 {
1361   return value + f_value ;
1362 }
1363
1364 FeatureValue*
1365 FeatureValueReal::operator-(const FeatureValueDimension &value) const
1366 {
1367   return value.rsub(f_value);
1368 }
1369
1370 FeatureValue*
1371 FeatureValueReal::operator*(const FeatureValueDimension &value) const
1372 {
1373   return value * f_value ;
1374 }
1375
1376 FeatureValue*
1377 FeatureValueReal::operator/(const FeatureValueDimension &value) const
1378 {
1379   return value.rdiv(f_value);
1380 }
1381
1382
1383 FeatureValue*
1384 FeatureValueReal::operator+(const FeatureValueExpression &value) const
1385 {
1386   FeatureValue *eval = value.evaluate();
1387   FeatureValue *return_val = *eval + f_value ;
1388   delete eval ;
1389   return return_val ;
1390 }
1391
1392 FeatureValue*
1393 FeatureValueReal::operator-(const FeatureValueExpression &value) const
1394 {
1395   FeatureValue *eval   = value.evaluate();
1396   FeatureValue *result = eval->rsub( f_value );
1397   delete eval;
1398   return result ;
1399 }
1400
1401 FeatureValue*
1402 FeatureValueReal::operator*(const FeatureValueExpression &value) const
1403 {
1404   FeatureValue *eval = value.evaluate();
1405   FeatureValue *return_val = *eval * f_value ;
1406   delete eval ;
1407   return return_val ;
1408 }
1409
1410 FeatureValue*
1411 FeatureValueReal::operator/(const FeatureValueExpression &value) const
1412 {
1413   FeatureValue *eval   = value.evaluate();
1414   FeatureValue *result = eval->rdiv(f_value) ;
1415   delete eval;
1416   return result ;
1417 }
1418
1419
1420 // int
1421 FeatureValue*
1422 FeatureValueInt::operator+(const FeatureValueInt &value) const
1423 {
1424   return value + f_value ;
1425 }
1426
1427 FeatureValue*
1428 FeatureValueInt::operator-(const FeatureValueInt &value) const
1429 {
1430   return value.rsub(f_value);
1431 }
1432
1433 FeatureValue*
1434 FeatureValueInt::operator*(const FeatureValueInt &value) const
1435 {
1436   return value * f_value ;
1437 }
1438
1439 FeatureValue*
1440 FeatureValueInt::operator/(const FeatureValueInt &value) const
1441 {
1442   return value.rdiv(f_value);
1443 }
1444
1445
1446 FeatureValue*
1447 FeatureValueInt::operator+(const FeatureValueReal &value) const
1448 {
1449   return value + f_value ;
1450 }
1451
1452 FeatureValue*
1453 FeatureValueInt::operator-(const FeatureValueReal &value) const
1454 {
1455   return value.rsub(f_value);
1456 }
1457
1458 FeatureValue*
1459 FeatureValueInt::operator*(const FeatureValueReal &value) const
1460 {
1461   return value * f_value ;
1462 }
1463
1464 FeatureValue*
1465 FeatureValueInt::operator/(const FeatureValueReal &value) const
1466 {
1467   return value.rdiv(f_value);
1468 }
1469
1470
1471 FeatureValue*
1472 FeatureValueInt::operator+(const FeatureValueDimension &value) const
1473 {
1474   return value + f_value ;
1475 }
1476
1477 FeatureValue*
1478 FeatureValueInt::operator-(const FeatureValueDimension &value) const
1479 {
1480   return value.rsub(f_value);
1481 }
1482
1483 FeatureValue*
1484 FeatureValueInt::operator*(const FeatureValueDimension &value) const
1485 {
1486   return value * f_value ;
1487 }
1488
1489 FeatureValue*
1490 FeatureValueInt::operator/(const FeatureValueDimension &value) const
1491 {
1492   return value.rdiv(f_value);
1493 }
1494
1495
1496 FeatureValue*
1497 FeatureValueInt::operator+(const FeatureValueExpression &value) const
1498 {
1499   FeatureValue *eval = value.evaluate();
1500   FeatureValue *return_val = *eval + f_value ;
1501   delete eval;
1502   return return_val ;
1503 }
1504
1505 FeatureValue*
1506 FeatureValueInt::operator-(const FeatureValueExpression &value) const
1507 {
1508   FeatureValue *eval   = value.evaluate();
1509   FeatureValue *result = eval->rsub(f_value) ;
1510   delete eval;
1511   return result;
1512 }
1513
1514 FeatureValue*
1515 FeatureValueInt::operator*(const FeatureValueExpression &value) const
1516 {
1517   FeatureValue *eval = value.evaluate();
1518   FeatureValue *return_val = *eval * f_value ;
1519   delete eval;
1520   return return_val ;
1521 }
1522
1523 FeatureValue*
1524 FeatureValueInt::operator/(const FeatureValueExpression &value) const
1525 {
1526   FeatureValue *eval = value.evaluate();
1527   FeatureValue *result = eval->rdiv(f_value) ;
1528   delete eval;
1529   return result ;
1530 }
1531
1532 // expression
1533 FeatureValue*
1534 FeatureValueExpression::operator+(const FeatureValueInt &value) const
1535 {
1536   FeatureValue *eval = evaluate();
1537   FeatureValue *return_val = *eval + value ;
1538   delete eval ;
1539   return return_val ;
1540 }
1541
1542 FeatureValue*
1543 FeatureValueExpression::operator-(const FeatureValueInt &value) const
1544 {
1545   FeatureValue *eval = evaluate();
1546   FeatureValue *return_val = *eval - value ;
1547   delete eval ;
1548   return return_val ;
1549 }
1550
1551 FeatureValue*
1552 FeatureValueExpression::operator*(const FeatureValueInt &value) const
1553 {
1554   FeatureValue *eval = evaluate();
1555   FeatureValue *return_val = *eval * value ;
1556   delete eval ;
1557   return return_val ;
1558 }
1559
1560 FeatureValue*
1561 FeatureValueExpression::operator/(const FeatureValueInt &value) const
1562 {
1563   FeatureValue *eval = evaluate();
1564   FeatureValue *return_val = *eval / value ;
1565   delete eval ;
1566   return return_val ;
1567 }
1568
1569
1570 FeatureValue*
1571 FeatureValueExpression::operator+(const FeatureValueReal &value) const
1572 {
1573   FeatureValue *eval = evaluate();
1574   FeatureValue *return_val = *eval + value ;
1575   delete eval ;
1576   return return_val ;
1577 }
1578
1579 FeatureValue*
1580 FeatureValueExpression::operator-(const FeatureValueReal &value) const
1581 {
1582   FeatureValue *eval = evaluate();
1583   FeatureValue *return_val = *eval - value ;
1584   delete eval ;
1585   return return_val ;
1586 }
1587
1588 FeatureValue*
1589 FeatureValueExpression::operator*(const FeatureValueReal &value) const
1590 {
1591   FeatureValue *eval = evaluate();
1592   FeatureValue *return_val = *eval * value ;
1593   delete eval ;
1594   return return_val ;
1595 }
1596
1597 FeatureValue*
1598 FeatureValueExpression::operator/(const FeatureValueReal &value) const
1599 {
1600   FeatureValue *eval = evaluate();
1601   FeatureValue *return_val = *eval / value ;
1602   delete eval ;
1603   return return_val ;
1604 }
1605
1606
1607 FeatureValue*
1608 FeatureValueExpression::operator+(const FeatureValueDimension &value) const
1609 {
1610   FeatureValue *eval = evaluate();
1611   FeatureValue *return_val = *eval + value ;
1612   delete eval ;
1613   return return_val ;
1614 }
1615
1616 FeatureValue*
1617 FeatureValueExpression::operator-(const FeatureValueDimension &value) const
1618 {
1619   FeatureValue *eval = evaluate();
1620   FeatureValue *return_val = *eval - value ;
1621   delete eval ;
1622   return return_val ;
1623 }
1624
1625 FeatureValue*
1626 FeatureValueExpression::operator*(const FeatureValueDimension &value) const
1627 {
1628   FeatureValue *eval = evaluate();
1629   FeatureValue *return_val = *eval * value ;
1630   delete eval ;
1631   return return_val ;
1632 }
1633
1634 FeatureValue*
1635 FeatureValueExpression::operator/(const FeatureValueDimension &value) const
1636 {
1637   FeatureValue *eval = evaluate();
1638   FeatureValue *return_val = *eval / value ;
1639   delete eval ;
1640   return return_val ;
1641 }
1642
1643
1644 FeatureValue*
1645 FeatureValueExpression::operator+(const FeatureValueExpression &value) const
1646 {
1647   FeatureValue *eval = evaluate();
1648   FeatureValue *return_val = *eval + value ;
1649   delete eval ;
1650   return return_val ;
1651 }
1652
1653 FeatureValue*
1654 FeatureValueExpression::operator-(const FeatureValueExpression &value) const
1655 {
1656   FeatureValue *eval = evaluate();
1657   FeatureValue *return_val = *eval - value ;
1658   delete eval ;
1659   return return_val ;
1660 }
1661
1662 FeatureValue*
1663 FeatureValueExpression::operator*(const FeatureValueExpression &value) const
1664 {
1665   FeatureValue *eval = evaluate();
1666   FeatureValue *return_val = *eval * value ;
1667   delete eval ;
1668   return return_val ;
1669 }
1670
1671 FeatureValue*
1672 FeatureValueExpression::operator/(const FeatureValueExpression &value) const
1673 {
1674   FeatureValue *eval = evaluate();
1675   FeatureValue *return_val = *eval / value ;
1676   delete eval ;
1677   return return_val ;
1678 }
1679
1680
1681 // dimension
1682 FeatureValue*
1683 FeatureValueDimension::operator+(const FeatureValueInt &value) const
1684 {
1685   FeatureValue *intermediate =  *f_value + value ;
1686   FeatureValue *result = intermediate->convertTo(f_unit);
1687   delete intermediate;
1688   return result ;
1689 }
1690
1691 FeatureValue*
1692 FeatureValueDimension::operator-(const FeatureValueInt &value) const
1693 {
1694   FeatureValue *intermediate =  *f_value - value ;
1695   FeatureValue *result = intermediate->convertTo(f_unit);
1696   delete intermediate;
1697   return result ;
1698 }
1699
1700 FeatureValue*
1701 FeatureValueDimension::operator*(const FeatureValueInt &value) const
1702 {
1703   FeatureValue *intermediate =  *f_value * value;
1704   FeatureValue *result = intermediate->convertTo(f_unit);
1705   delete intermediate;
1706   return result ;
1707 }
1708
1709 FeatureValue*
1710 FeatureValueDimension::operator/(const FeatureValueInt &value) const
1711 {
1712   FeatureValue *intermediate =  *f_value / value;
1713   FeatureValue *result = intermediate->convertTo(f_unit);
1714   delete intermediate;
1715   return result ;
1716 }
1717
1718
1719 FeatureValue*
1720 FeatureValueDimension::operator+(const FeatureValueReal &value) const
1721 {
1722   FeatureValue *intermediate =  *f_value + value;
1723   FeatureValue *result = intermediate->convertTo(f_unit);
1724   delete intermediate;
1725   return result ;
1726 }
1727
1728 FeatureValue*
1729 FeatureValueDimension::operator-(const FeatureValueReal &value) const
1730 {
1731   FeatureValue *intermediate =  *f_value - value;
1732   FeatureValue *result = intermediate->convertTo(f_unit);
1733   delete intermediate;
1734   return result ;
1735 }
1736
1737 FeatureValue*
1738 FeatureValueDimension::operator*(const FeatureValueReal &value) const
1739 {
1740   FeatureValue *intermediate =  *f_value * value;
1741   FeatureValue *result = intermediate->convertTo(f_unit);
1742   delete intermediate;
1743   return result ;
1744 }
1745
1746 FeatureValue*
1747 FeatureValueDimension::operator/(const FeatureValueReal &value) const
1748 {
1749   FeatureValue *intermediate =  *f_value / value;
1750   FeatureValue *result = intermediate->convertTo(f_unit);
1751   delete intermediate;
1752   return result ;
1753 }
1754
1755
1756 FeatureValue*
1757 FeatureValueDimension::operator+(const FeatureValueDimension &value) const
1758 {
1759   FeatureValue *i1 = value.doConvert(f_unit);
1760   FeatureValue *i2 = f_value->doConvert(f_unit);
1761   FeatureValue *i3 = *i1 + *i2 ;
1762   delete i2 ;
1763   delete i1 ;
1764   return new FeatureValueDimension(i3, f_unit) ;
1765 }
1766
1767 FeatureValue*
1768 FeatureValueDimension::operator-(const FeatureValueDimension &value) const
1769 {
1770   FeatureValue *intermediate =  *f_value - value;
1771   FeatureValue *result = intermediate->convertTo(f_unit);
1772   delete intermediate;
1773   return result ;
1774 }
1775
1776 FeatureValue*
1777 FeatureValueDimension::operator*(const FeatureValueDimension &value) const
1778 {
1779   FeatureValue *intermediate =  *f_value * value;
1780   FeatureValue *result = intermediate->convertTo(f_unit);
1781   delete intermediate;
1782   return result ;
1783 }
1784
1785 FeatureValue*
1786 FeatureValueDimension::operator/(const FeatureValueDimension &value) const
1787 {
1788   FeatureValue *intermediate =  *f_value / value;
1789   FeatureValue *result = intermediate->convertTo(f_unit);
1790   delete intermediate;
1791   return result ;
1792 }
1793
1794
1795 FeatureValue*
1796 FeatureValueDimension::operator+(const FeatureValueExpression &value) const
1797 {
1798   FeatureValue *intermediate =  *f_value + value;
1799   FeatureValue *result = intermediate->convertTo(f_unit);
1800   delete intermediate;
1801   return result ;
1802 }
1803
1804 FeatureValue*
1805 FeatureValueDimension::operator-(const FeatureValueExpression &value) const
1806 {
1807   FeatureValue *intermediate =  *f_value - value;
1808   FeatureValue *result = intermediate->convertTo(f_unit);
1809   delete intermediate;
1810   return result ;
1811 }
1812
1813 FeatureValue*
1814 FeatureValueDimension::operator*(const FeatureValueExpression &value) const
1815 {
1816   FeatureValue *intermediate =  *f_value * value;
1817   FeatureValue *result = intermediate->convertTo(f_unit);
1818   delete intermediate;
1819   return result ;
1820 }
1821
1822 FeatureValue*
1823 FeatureValueDimension::operator/(const FeatureValueExpression &value) const
1824 {
1825   FeatureValue *intermediate =  *f_value / value;
1826   FeatureValue *result = intermediate->convertTo(f_unit);
1827   delete intermediate;
1828   return result ;
1829 }
1830
1831
1832 /* -------- rdiv, rsub -------- */
1833
1834 FeatureValue *
1835 FeatureValue::rdiv(const FeatureValue &) const
1836 {
1837   throw(CASTBEEXCEPT badEvaluationException());
1838   return 0 ;
1839 }
1840 FeatureValue *
1841 FeatureValue::rsub(const FeatureValue &) const
1842 {
1843   throw(CASTBEEXCEPT badEvaluationException());
1844   return 0 ;
1845 }
1846 FeatureValue *
1847 FeatureValue::rdiv(const FeatureValueInt &) const
1848 {
1849   throw(CASTBEEXCEPT badEvaluationException());
1850   return 0 ;
1851 }
1852 FeatureValue *
1853 FeatureValue::rsub(const FeatureValueInt &) const
1854 {
1855   throw(CASTBEEXCEPT badEvaluationException());
1856   return 0 ;
1857 }
1858 FeatureValue *
1859 FeatureValue::rdiv(const FeatureValueReal &) const
1860 {
1861   throw(CASTBEEXCEPT badEvaluationException());
1862   return 0 ;
1863 }
1864 FeatureValue *
1865 FeatureValue::rsub(const FeatureValueReal &) const
1866 {
1867   throw(CASTBEEXCEPT badEvaluationException());
1868   return 0 ;
1869 }
1870 FeatureValue *
1871 FeatureValue::rdiv(const FeatureValueExpression &) const
1872 {
1873   throw(CASTBEEXCEPT badEvaluationException());
1874   return 0 ;
1875 }
1876 FeatureValue *
1877 FeatureValue::rsub(const FeatureValueExpression &) const
1878 {
1879   throw(CASTBEEXCEPT badEvaluationException());
1880   return 0 ;
1881 }
1882 FeatureValue *
1883 FeatureValue::rdiv(const FeatureValueDimension &) const
1884 {
1885   throw(CASTBEEXCEPT badEvaluationException());
1886   return 0 ;
1887 }
1888 FeatureValue *
1889 FeatureValue::rsub(const FeatureValueDimension &) const
1890 {
1891   throw(CASTBEEXCEPT badEvaluationException());
1892   return 0 ;
1893 }
1894 FeatureValue *
1895 FeatureValue::rdiv(const int) const
1896 {
1897   throw(CASTBEEXCEPT badEvaluationException());
1898   return 0 ;
1899 }
1900 FeatureValue *
1901 FeatureValue::rsub(const int) const
1902 {
1903   throw(CASTBEEXCEPT badEvaluationException());
1904   return 0;
1905 }
1906 FeatureValue *
1907 FeatureValue::rdiv(const float) const
1908 {
1909   throw(CASTBEEXCEPT badEvaluationException());
1910   return 0;
1911 }
1912 FeatureValue *
1913 FeatureValue::rsub(const float) const
1914 {
1915   throw(CASTBEEXCEPT badEvaluationException());
1916   return 0 ;
1917 }
1918
1919 /* --------  FeatureValueInt rdiv, rsub -------- */
1920
1921 FeatureValue *
1922 FeatureValueInt::rdiv(const FeatureValue &f) const
1923 {
1924   return f / f_value;
1925 }
1926 FeatureValue *
1927 FeatureValueInt::rsub(const FeatureValue &f) const
1928 {
1929   return f - f_value ;
1930 }
1931 FeatureValue *
1932 FeatureValueInt::rdiv(const FeatureValueInt &i) const
1933 {
1934   return i / f_value ;
1935 }
1936 FeatureValue *
1937 FeatureValueInt::rsub(const FeatureValueInt &i) const
1938 {
1939   return i - f_value ;
1940 }
1941 FeatureValue *
1942 FeatureValueInt::rdiv(const FeatureValueReal &r) const
1943 {
1944   return r / f_value ;
1945 }
1946 FeatureValue *
1947 FeatureValueInt::rsub(const FeatureValueReal &r) const
1948 {
1949   return r - f_value ;
1950 }
1951 FeatureValue *
1952 FeatureValueInt::rdiv(const FeatureValueExpression &e) const
1953 {
1954   return e / f_value ;
1955 }
1956 FeatureValue *
1957 FeatureValueInt::rsub(const FeatureValueExpression &e) const
1958 {
1959   return e - f_value ;
1960 }
1961 FeatureValue *
1962 FeatureValueInt::rdiv(const FeatureValueDimension &d) const
1963 {
1964   return d / f_value ;
1965 }
1966 FeatureValue *
1967 FeatureValueInt::rsub(const FeatureValueDimension &d) const
1968 {
1969   return d - f_value ;
1970 }
1971 FeatureValue *
1972 FeatureValueInt::rdiv(const int i) const
1973 {
1974   return new FeatureValueInt(i / f_value);
1975 }
1976 FeatureValue *
1977 FeatureValueInt::rsub(const int i) const
1978 {
1979   return new FeatureValueInt(i - f_value);
1980 }
1981 FeatureValue *
1982 FeatureValueInt::rdiv(const float f) const
1983 {
1984   return new FeatureValueReal(f / f_value);
1985 }
1986 FeatureValue *
1987 FeatureValueInt::rsub(const float f) const
1988 {
1989   return new FeatureValueReal(f - f_value);
1990 }
1991 /* --------  FeatureValueReal rdiv, rsub -------- */
1992 FeatureValue *
1993 FeatureValueReal::rdiv(const FeatureValue &f) const
1994 {
1995   return f / f_value ;
1996 }
1997 FeatureValue *
1998 FeatureValueReal::rsub(const FeatureValue &f) const
1999 {
2000   return f - f_value ;
2001 }
2002 FeatureValue *
2003 FeatureValueReal::rdiv(const FeatureValueInt &i) const
2004 {
2005   return i / f_value ;
2006 }
2007 FeatureValue *
2008 FeatureValueReal::rsub(const FeatureValueInt &i) const
2009 {
2010   return i - f_value ;
2011 }
2012 FeatureValue *
2013 FeatureValueReal::rdiv(const FeatureValueReal &r) const
2014 {
2015   return r / f_value ;
2016 }
2017 FeatureValue *
2018 FeatureValueReal::rsub(const FeatureValueReal &r) const
2019 {
2020   return r - f_value ;
2021 }
2022 FeatureValue *
2023 FeatureValueReal::rdiv(const FeatureValueExpression &e) const
2024 {
2025   return e / f_value ;
2026 }
2027 FeatureValue *
2028 FeatureValueReal::rsub(const FeatureValueExpression &e) const
2029 {
2030   return e - f_value ;
2031 }
2032 FeatureValue *
2033 FeatureValueReal::rdiv(const FeatureValueDimension &d) const
2034 {
2035   return d / f_value ;
2036 }
2037 FeatureValue *
2038 FeatureValueReal::rsub(const FeatureValueDimension &d) const
2039 {
2040   return d - f_value ;
2041 }
2042 FeatureValue *
2043 FeatureValueReal::rdiv(const int i) const
2044 {
2045   return new FeatureValueReal(i / f_value);
2046 }
2047 FeatureValue *
2048 FeatureValueReal::rsub(const int i) const
2049 {
2050   return new FeatureValueReal(i - f_value);
2051 }
2052 FeatureValue *
2053 FeatureValueReal::rdiv(const float f) const
2054 {
2055   return new FeatureValueReal(f / f_value);
2056 }
2057 FeatureValue *
2058 FeatureValueReal::rsub(const float f) const
2059 {
2060   return new FeatureValueReal(f - f_value);
2061 }
2062 /* -------- FeatureValueExpression rdiv, rsub -------- */
2063
2064 FeatureValue *
2065 FeatureValueExpression::rdiv(const FeatureValue &f) const
2066 {
2067   return f / *this ;
2068 }
2069 FeatureValue *
2070 FeatureValueExpression::rsub(const FeatureValue &f) const
2071 {
2072   return f - *this ;
2073 }
2074 FeatureValue *
2075 FeatureValueExpression::rdiv(const FeatureValueInt &i) const
2076 {
2077   return i / *this ;
2078 }
2079 FeatureValue *
2080 FeatureValueExpression::rsub(const FeatureValueInt &i) const
2081 {
2082   return i - *this ;
2083 }
2084 FeatureValue *
2085 FeatureValueExpression::rdiv(const FeatureValueReal &r) const
2086 {
2087   return r / *this ;
2088 }
2089 FeatureValue *
2090 FeatureValueExpression::rsub(const FeatureValueReal &r) const
2091 {
2092   return r - *this ;
2093 }
2094 FeatureValue *
2095 FeatureValueExpression::rdiv(const FeatureValueExpression &e) const
2096 {
2097   return e / *this ;
2098 }
2099 FeatureValue *
2100 FeatureValueExpression::rsub(const FeatureValueExpression &e) const
2101 {
2102   return e - *this ;
2103 }
2104 FeatureValue *
2105 FeatureValueExpression::rdiv(const FeatureValueDimension &d) const
2106 {
2107   return d / *this ;
2108 }
2109 FeatureValue *
2110 FeatureValueExpression::rsub(const FeatureValueDimension &d) const
2111 {
2112   return d - *this ;
2113 }
2114 FeatureValue *
2115 FeatureValueExpression::rdiv(const int i) const
2116 {
2117   FeatureValue *e = evaluate();
2118   FeatureValue *intermediate = e->rdiv(i);
2119   delete e ;
2120   return intermediate;
2121 }
2122 FeatureValue *
2123 FeatureValueExpression::rsub(const int i) const
2124 {
2125   FeatureValue *e = evaluate();
2126   FeatureValue *intermediate = e->rsub(i);
2127   delete e ;
2128   return intermediate;
2129 }
2130 FeatureValue *
2131 FeatureValueExpression::rdiv(const float f) const
2132 {
2133   FeatureValue *e = evaluate();
2134   FeatureValue *intermediate = e->rdiv(f);
2135   delete e ;
2136   return intermediate;
2137 }
2138 FeatureValue *
2139 FeatureValueExpression::rsub(const float f) const
2140 {
2141   FeatureValue *e = evaluate();
2142   FeatureValue *intermediate = e->rsub(f);
2143   delete e ;
2144   return intermediate;
2145 }
2146 /* -------- FeatureValueDimension rdiv, rsub -------- */
2147 FeatureValue *
2148 FeatureValueDimension::rdiv(const FeatureValue &f) const
2149 {
2150   return f / *this ;
2151 }
2152 FeatureValue *
2153 FeatureValueDimension::rsub(const FeatureValue &f) const
2154 {
2155   return f - *this ;
2156 }
2157 FeatureValue *
2158 FeatureValueDimension::rdiv(const FeatureValueInt &i) const
2159 {
2160   return i / *this ;
2161 }
2162 FeatureValue *
2163 FeatureValueDimension::rsub(const FeatureValueInt &i) const
2164 {
2165   return i - *this ;
2166 }
2167 FeatureValue *
2168 FeatureValueDimension::rdiv(const FeatureValueReal &r) const
2169 {
2170   return r / *this ;
2171 }
2172 FeatureValue *
2173 FeatureValueDimension::rsub(const FeatureValueReal &r) const
2174 {
2175   return r - *this ;
2176 }
2177 FeatureValue *
2178 FeatureValueDimension::rdiv(const FeatureValueExpression &e) const
2179 {
2180   return e / *this ;
2181 }
2182 FeatureValue *
2183 FeatureValueDimension::rsub(const FeatureValueExpression &e) const
2184 {
2185   return e - *this ;
2186 }
2187 FeatureValue *
2188 FeatureValueDimension::rdiv(const FeatureValueDimension &d) const
2189 {
2190   return d / *this ;
2191 }
2192 FeatureValue *
2193 FeatureValueDimension::rsub(const FeatureValueDimension &d) const
2194 {
2195   return d - *this ;
2196 }
2197 FeatureValue *
2198 FeatureValueDimension::rdiv(const int i) const
2199 {
2200   // rdiv the value then convert result to our unit type 
2201   FeatureValue *intermediate = f_value->rdiv(i);
2202   FeatureValue *result = intermediate->convertTo(f_unit);
2203   delete intermediate;
2204   return result;
2205 }
2206
2207 FeatureValue *
2208 FeatureValueDimension::rsub(const int i) const
2209 {
2210   FeatureValue *intermediate = f_value->rsub(i);
2211   FeatureValue *result = intermediate->convertTo(f_unit);
2212   delete intermediate;
2213   return result;
2214 }
2215 FeatureValue *
2216 FeatureValueDimension::rdiv(const float f) const
2217 {
2218   FeatureValue *intermediate = f_value->rdiv(f);
2219   FeatureValue *result = intermediate->convertTo(f_unit);
2220   delete intermediate;
2221   return result;
2222 }
2223 FeatureValue *
2224 FeatureValueDimension::rsub(const float f) const
2225 {
2226   FeatureValue *intermediate = f_value->rsub(f);
2227   FeatureValue *result = intermediate->convertTo(f_unit);
2228   delete intermediate;
2229   return result;
2230 }
2231
2232 /* -------- convert To -------- */
2233
2234 FeatureValue *
2235 FeatureValue::convertTo(Unit ) const
2236 {
2237   throw(CASTBEEXCEPT badEvaluationException());
2238   return 0 ;
2239 }
2240
2241 FeatureValue *
2242 FeatureValueInt::convertTo(Unit unit) const
2243 {
2244   return new FeatureValueDimension(new FeatureValueInt(*this), unit);
2245 }
2246
2247 FeatureValue *
2248 FeatureValueReal::convertTo(Unit unit) const
2249 {
2250   return new FeatureValueDimension(new FeatureValueReal(*this), unit);
2251 }
2252
2253 FeatureValue *
2254 FeatureValueDimension::convertTo(Unit unit) const
2255 {
2256   if (f_unit == unit)
2257     return new FeatureValueDimension(*this);
2258   
2259   // convert our value to new unit type 
2260   return new FeatureValueDimension(f_value->convertTo(f_unit, unit),
2261                                    unit);
2262 }
2263
2264 FeatureValue *
2265 FeatureValue::convertTo(Unit, Unit) const
2266 {
2267   throw(CASTBEEXCEPT badEvaluationException());
2268   return 0 ;
2269 }
2270
2271 FeatureValue *
2272 FeatureValueReal::convertTo(Unit old_unit,
2273                             Unit new_unit) const
2274 {
2275   return new FeatureValueReal(convert(f_value,old_unit, new_unit));
2276 }
2277 FeatureValue *
2278 FeatureValueInt::convertTo(Unit old_unit,
2279                            Unit new_unit) const
2280 {
2281   return new FeatureValueReal(convert(f_value,old_unit, new_unit));
2282 }
2283
2284 FeatureValue*
2285 FeatureValueDimension::convertTo(Unit old_unit,
2286                                  Unit new_unit) const
2287 {
2288   FeatureValue *intermediate = f_value->convertTo(old_unit, f_unit);
2289   FeatureValue *result = intermediate->convertTo(new_unit);
2290   delete intermediate; 
2291   return result ;
2292 }
2293
2294 /* -------- FeatureValueDimension::evaluate -------- */
2295
2296 FeatureValue *
2297 FeatureValueDimension::evaluate() const
2298 {
2299   FeatureValue *intermediate = f_value->evaluate();
2300   FeatureValue *result = intermediate->convertTo(f_unit);
2301   delete intermediate;
2302
2303   return result ;
2304 }
2305
2306 FeatureValue *
2307 FeatureValue::doConvert(Unit) const
2308 {
2309   throw(CASTBEEXCEPT badEvaluationException());
2310   return 0 ;
2311 };
2312
2313 FeatureValue *
2314 FeatureValueReal::doConvert(Unit) const
2315 {
2316   return new FeatureValueReal(*this);
2317 }
2318
2319 FeatureValue *
2320 FeatureValueInt::doConvert(Unit) const
2321 {
2322   return new FeatureValueInt(*this);
2323 }
2324
2325 FeatureValue*
2326 FeatureValueDimension::doConvert(Unit unit) const
2327 {
2328   if (unit == f_unit)
2329     return f_value->doConvert(unit);
2330
2331   return f_value->convertTo(f_unit, unit);
2332 }
2333
2334 ///////////////////////////////////////////////////
2335 // FeatureValueArray
2336 ///////////////////////////////////////////////////
2337
2338 FeatureValueArray::FeatureValueArray(const char* nm, int size) :
2339    FeatureValue(array), pointer_vector<FeatureValue>(size, 0), f_name(strdup(nm))
2340 {
2341 }
2342
2343 FeatureValueArray::FeatureValueArray(const FeatureValueArray& x) :
2344    FeatureValue(array), pointer_vector<FeatureValue>(x.length(), 0),
2345    f_name(strdup(x.f_name))
2346 {
2347    mtry
2348     {
2349       for ( unsigned int i=0; i<length(); i++ )
2350          (*this)[i] = x[i] -> clone();
2351       return;
2352     }
2353    mcatch_any()
2354     {
2355       for ( unsigned int i=0; i<length(); i++ )
2356          delete (*this)[i];
2357       rethrow;
2358     }
2359    end_try ;
2360 }
2361
2362 FeatureValueArray::~FeatureValueArray()
2363 {
2364    for ( unsigned int i=0; i<length(); i++ )
2365      delete (*this)[i];
2366
2367    delete f_name;
2368 }
2369
2370 FeatureValue *
2371 FeatureValueArray::evaluate() const
2372 {
2373   FeatureValueArray *result = new FeatureValueArray(f_name, length());
2374
2375   mtry
2376     {
2377       for ( unsigned int i=0; i<length(); i++ ) {
2378         (*result)[i] = (*this)[i] -> evaluate();
2379       }
2380       return result;
2381     }
2382    mcatch_any()
2383     {
2384       delete result;
2385       rethrow;
2386     }
2387    end_try ;
2388 }
2389
2390 ostream& 
2391 FeatureValueArray::print(ostream& out) const
2392 {
2393    out << f_name << "[\n";
2394
2395    for ( unsigned int i=0; i<length(); i++ ) {
2396
2397      if ( (*this)[i] == 0 ) {
2398         MESSAGE(cerr, form("%d is a null slot", i));
2399         continue;
2400      }
2401
2402      out << "\t" << *((*this)[i]) << "\n";
2403    }
2404
2405    out << "]" << endl;
2406    return out;
2407 }
2408
2409