/[escript]/trunk/escript/src/Data.cpp
ViewVC logotype

Diff of /trunk/escript/src/Data.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 94 by jgs, Wed Oct 27 00:45:54 2004 UTC revision 97 by jgs, Tue Dec 14 05:39:33 2004 UTC
# Line 38  Line 38 
38  #include "escript/Data/DataAlgorithm.h"  #include "escript/Data/DataAlgorithm.h"
39  #include "escript/Data/FunctionSpaceFactory.h"  #include "escript/Data/FunctionSpaceFactory.h"
40  #include "escript/Data/AbstractContinuousDomain.h"  #include "escript/Data/AbstractContinuousDomain.h"
41    #include "escript/Data/UnaryFuncs.h"
42    
43  using namespace std;  using namespace std;
44  using namespace boost::python;  using namespace boost::python;
# Line 49  Data::Data() Line 50  Data::Data()
50    //    //
51    // Default data is type DataEmpty    // Default data is type DataEmpty
52    DataAbstract* temp=new DataEmpty();    DataAbstract* temp=new DataEmpty();
53    m_data=shared_ptr<DataAbstract>(temp);    shared_ptr<DataAbstract> temp_data(temp);
54      m_data=temp_data;
55  }  }
56    
57  Data::Data(double value,  Data::Data(double value,
# Line 75  Data::Data(double value, Line 77  Data::Data(double value,
77    initialise(temp.getView(),what,expanded);    initialise(temp.getView(),what,expanded);
78  }  }
79    
80  Data::Data(const Data& inData):  Data::Data(const Data& inData)
   m_data(inData.m_data)  
81  {  {
82      m_data=inData.m_data;
83  }  }
84    
85  Data::Data(const Data& inData,  Data::Data(const Data& inData,
86             const DataArrayView::RegionType& region)             const DataArrayView::RegionType& region)
87  {  {
88    //    //
89    // Create data which is a subset(slice) of another Data    // Create Data which is a slice of another Data
90    DataAbstract* tmp=inData.m_data->getSlice(region);    DataAbstract* tmp = inData.m_data->getSlice(region);
91    m_data=shared_ptr<DataAbstract>(tmp);    shared_ptr<DataAbstract> temp_data(tmp);
92      m_data=temp_data;
93  }  }
94    
95  Data::Data(const Data& inData,  Data::Data(const Data& inData,
# Line 117  Data::Data(const DataTagged::TagListType Line 120  Data::Data(const DataTagged::TagListType
120             bool expanded)             bool expanded)
121  {  {
122    DataAbstract* temp=new DataTagged(tagKeys,values,defaultValue,what);    DataAbstract* temp=new DataTagged(tagKeys,values,defaultValue,what);
123    m_data=shared_ptr<DataAbstract>(temp);    shared_ptr<DataAbstract> temp_data(temp);
124      m_data=temp_data;
125    if (expanded) {    if (expanded) {
126      expand();      expand();
127    }    }
# Line 212  Data::copy(const Data& other) Line 216  Data::copy(const Data& other)
216        //        //
217        // Construct a DataExpanded copy        // Construct a DataExpanded copy
218        DataAbstract* newData=new DataExpanded(*temp);        DataAbstract* newData=new DataExpanded(*temp);
219        m_data=shared_ptr<DataAbstract>(newData);        shared_ptr<DataAbstract> temp_data(newData);
220          m_data=temp_data;
221        return;        return;
222      }      }
223    }    }
# Line 220  Data::copy(const Data& other) Line 225  Data::copy(const Data& other)
225      DataTagged* temp=dynamic_cast<DataTagged*>(other.m_data.get());      DataTagged* temp=dynamic_cast<DataTagged*>(other.m_data.get());
226      if (temp!=0) {      if (temp!=0) {
227        //        //
228        // Construct a DataTaggeded copy        // Construct a DataTagged copy
229        DataAbstract* newData=new DataTagged(*temp);        DataAbstract* newData=new DataTagged(*temp);
230        m_data=shared_ptr<DataAbstract>(newData);        shared_ptr<DataAbstract> temp_data(newData);
231          m_data=temp_data;
232        return;        return;
233      }      }
234    }    }
# Line 232  Data::copy(const Data& other) Line 238  Data::copy(const Data& other)
238        //        //
239        // Construct a DataConstant copy        // Construct a DataConstant copy
240        DataAbstract* newData=new DataConstant(*temp);        DataAbstract* newData=new DataConstant(*temp);
241        m_data=shared_ptr<DataAbstract>(newData);        shared_ptr<DataAbstract> temp_data(newData);
242          m_data=temp_data;
243          return;
244        }
245      }
246      {
247        DataEmpty* temp=dynamic_cast<DataEmpty*>(other.m_data.get());
248        if (temp!=0) {
249          //
250          // Construct a DataEmpty copy
251          DataAbstract* newData=new DataEmpty();
252          shared_ptr<DataAbstract> temp_data(newData);
253          m_data=temp_data;
254        return;        return;
255      }      }
256    }    }
# Line 284  Data::isConstant() const Line 302  Data::isConstant() const
302    return (temp!=0);    return (temp!=0);
303  }  }
304    
 Data  
 Data::getSlice(const DataArrayView::RegionType& region) const  
 {  
   return Data(*this,region);  
 }  
   
 void  
 Data::setSlice(const Data& value,  
                const DataArrayView::RegionType& region)  
 {  
   m_data->setSlice(value.m_data.get(), region);  
 }  
   
305  void  void
306  Data::expand()  Data::expand()
307  {  {
308    if (isConstant()) {    if (isConstant()) {
309      DataConstant* tempDataConst=dynamic_cast<DataConstant*>(m_data.get());      DataConstant* tempDataConst=dynamic_cast<DataConstant*>(m_data.get());
310      DataAbstract* temp=new DataExpanded(*tempDataConst);      DataAbstract* temp=new DataExpanded(*tempDataConst);
311      m_data=shared_ptr<DataAbstract>(temp);      shared_ptr<DataAbstract> temp_data(temp);
312        m_data=temp_data;
313    } else if (isTagged()) {    } else if (isTagged()) {
314      DataTagged* tempDataTag=dynamic_cast<DataTagged*>(m_data.get());      DataTagged* tempDataTag=dynamic_cast<DataTagged*>(m_data.get());
315      DataAbstract* temp=new DataExpanded(*tempDataTag);      DataAbstract* temp=new DataExpanded(*tempDataTag);
316      m_data=shared_ptr<DataAbstract>(temp);      shared_ptr<DataAbstract> temp_data(temp);
317        m_data=temp_data;
318    } else if (isExpanded()) {    } else if (isExpanded()) {
319      //      //
320      // do nothing      // do nothing
# Line 319  Data::expand() Line 326  Data::expand()
326  }  }
327    
328  void  void
 Data::reshapeDataPoint(const DataArrayView::ShapeType& shape)  
 {  
   m_data->reshapeDataPoint(shape);  
 }  
   
 void  
329  Data::tag()  Data::tag()
330  {  {
331    if (isConstant()) {    if (isConstant()) {
332      DataConstant* tempDataConst=dynamic_cast<DataConstant*>(m_data.get());      DataConstant* tempDataConst=dynamic_cast<DataConstant*>(m_data.get());
333      DataAbstract* temp=new DataTagged(*tempDataConst);      DataAbstract* temp=new DataTagged(*tempDataConst);
334      m_data=shared_ptr<DataAbstract>(temp);      shared_ptr<DataAbstract> temp_data(temp);
335        m_data=temp_data;
336    } else if (isTagged()) {    } else if (isTagged()) {
337      // do nothing      // do nothing
338    } else if (isExpanded()) {    } else if (isExpanded()) {
# Line 342  Data::tag() Line 344  Data::tag()
344    }    }
345  }  }
346    
347    void
348    Data::reshapeDataPoint(const DataArrayView::ShapeType& shape)
349    {
350      m_data->reshapeDataPoint(shape);
351    }
352    
353  Data  Data
354  Data::wherePositive() const  Data::wherePositive() const
355  {  {
# Line 349  Data::wherePositive() const Line 357  Data::wherePositive() const
357  }  }
358    
359  Data  Data
360    Data::whereNegative() const
361    {
362      return escript::unaryOp(*this,bind2nd(less<double>(),0.0));
363    }
364    
365    Data
366  Data::whereNonNegative() const  Data::whereNonNegative() const
367  {  {
368    return escript::unaryOp(*this,bind2nd(greater_equal<double>(),0.0));    return escript::unaryOp(*this,bind2nd(greater_equal<double>(),0.0));
369  }  }
370    
371  Data  Data
372  Data::whereNegative() const  Data::whereNonPositive() const
373  {  {
374    return escript::unaryOp(*this,bind2nd(less<double>(),0.0));    return escript::unaryOp(*this,bind2nd(less_equal<double>(),0.0));
375  }  }
376    
377  Data  Data
# Line 367  Data::whereZero() const Line 381  Data::whereZero() const
381  }  }
382    
383  Data  Data
384    Data::whereNonZero() const
385    {
386      return escript::unaryOp(*this,bind2nd(not_equal_to<double>(),0.0));
387    }
388    
389    Data
390  Data::interpolate(const FunctionSpace& functionspace) const  Data::interpolate(const FunctionSpace& functionspace) const
391  {  {
392    return Data(*this,functionspace);    return Data(*this,functionspace);
# Line 523  double Line 543  double
543  Data::Lsup() const  Data::Lsup() const
544  {  {
545    //    //
546    // set the initial absolute maximum value to min possible    // set the initial absolute maximum value to zero
547    return algorithm(DataAlgorithmAdapter<AbsMax>(numeric_limits<double>::min()));    return algorithm(DataAlgorithmAdapter<AbsMax>(0));
548  }  }
549    
550  double  double
551  Data::sup() const  Data::sup() const
552  {  {
553    //    //
554    // set the initial maximum value to min possible    // set the initial maximum value to min possible double
555    return algorithm(DataAlgorithmAdapter<FMax>(numeric_limits<double>::min()));    return algorithm(DataAlgorithmAdapter<FMax>(numeric_limits<double>::min()));
556  }  }
557    
# Line 539  double Line 559  double
559  Data::inf() const  Data::inf() const
560  {  {
561    //    //
562    // set the initial minimum value to max possible    // set the initial minimum value to max possible double
563    return algorithm(DataAlgorithmAdapter<FMin>(numeric_limits<double>::max()));    return algorithm(DataAlgorithmAdapter<FMin>(numeric_limits<double>::max()));
564  }  }
565    
566  Data& Data::operator+=(const Data& right)  Data
567    Data::maxval() const
568    {
569      // not implemented - will use dp_algorithm
570      return (*this);
571    }
572    
573    Data
574    Data::minval() const
575    {
576      // not implemented - will use dp_algorithm
577      return (*this);
578    }
579    
580    Data
581    Data::length() const
582    {
583      // not implemented - will use dp_algorithm
584      return (*this);
585    }
586    
587    Data
588    Data::trace() const
589    {
590      // not implemented - will use dp_algorithm
591      return (*this);
592    }
593    
594    Data
595    Data::transpose(int axis) const
596    {
597      // not implemented
598      return (*this);
599    }
600    
601    Data
602    Data::sign() const
603    {
604      return escript::unaryOp(*this,escript::fsign);
605    }
606    
607    Data
608    Data::abs() const
609    {
610      return escript::unaryOp(*this,(Data::UnaryDFunPtr)::fabs);
611    }
612    
613    Data
614    Data::neg() const
615    {
616      return escript::unaryOp(*this,negate<double>());
617    }
618    
619    Data
620    Data::pos() const
621    {
622      return (*this);
623    }
624    
625    Data
626    Data::exp() const
627    {
628      return escript::unaryOp(*this,(Data::UnaryDFunPtr)::exp);
629    }
630    
631    Data
632    Data::sqrt() const
633    {
634      return escript::unaryOp(*this,(Data::UnaryDFunPtr)::sqrt);
635    }
636    
637    Data&
638    Data::operator+=(const Data& right)
639  {  {
640    binaryOp(right,plus<double>());    binaryOp(right,plus<double>());
641    return (*this);    return (*this);
642  }  }
643    
644  Data& Data::operator+=(const boost::python::object& right)  Data&
645    Data::operator+=(const boost::python::object& right)
646  {  {
647    binaryOp(right,plus<double>());    binaryOp(right,plus<double>());
648    return (*this);    return (*this);
649  }  }
650    
651  Data& Data::operator-=(const Data& right)  Data&
652    Data::operator-=(const Data& right)
653  {  {
654    binaryOp(right,minus<double>());    binaryOp(right,minus<double>());
655    return (*this);    return (*this);
656  }  }
657    
658  Data& Data::operator-=(const boost::python::object& right)  Data&
659    Data::operator-=(const boost::python::object& right)
660  {  {
661    binaryOp(right,minus<double>());    binaryOp(right,minus<double>());
662    return (*this);    return (*this);
663  }  }
664    
665  Data& Data::operator*=(const Data& right)  Data&
666    Data::operator*=(const Data& right)
667  {  {
668    binaryOp(right,multiplies<double>());    binaryOp(right,multiplies<double>());
669    return (*this);    return (*this);
670  }  }
671    
672  Data& Data::operator*=(const boost::python::object& right)  Data&
673    Data::operator*=(const boost::python::object& right)
674  {  {
675    binaryOp(right,multiplies<double>());    binaryOp(right,multiplies<double>());
676    return (*this);    return (*this);
677  }  }
678    
679  Data& Data::operator/=(const Data& right)  Data&
680    Data::operator/=(const Data& right)
681  {  {
682    binaryOp(right,divides<double>());    binaryOp(right,divides<double>());
683    return (*this);    return (*this);
684  }  }
685    
686  Data& Data::operator/=(const boost::python::object& right)  Data&
687    Data::operator/=(const boost::python::object& right)
688  {  {
689    binaryOp(right,divides<double>());    binaryOp(right,divides<double>());
690    return (*this);    return (*this);
691  }  }
692    
693  Data Data::powO(const boost::python::object& right) const  Data
694    Data::powO(const boost::python::object& right) const
695  {  {
696    Data result;    Data result;
697    result.copy(*this);    result.copy(*this);
# Line 599  Data Data::powO(const boost::python::obj Line 699  Data Data::powO(const boost::python::obj
699    return result;    return result;
700  }  }
701    
702  Data Data::powD(const Data& right) const  Data
703    Data::powD(const Data& right) const
704  {  {
705    Data result;    Data result;
706    result.copy(*this);    result.copy(*this);
# Line 609  Data Data::powD(const Data& right) const Line 710  Data Data::powD(const Data& right) const
710    
711  //  //
712  // NOTE: It is essential to specify the namepsace this operator belongs to  // NOTE: It is essential to specify the namepsace this operator belongs to
713  Data escript::operator+(const Data& left, const Data& right)  Data
714    escript::operator+(const Data& left, const Data& right)
715  {  {
716    Data result;    Data result;
717    //    //
# Line 621  Data escript::operator+(const Data& left Line 723  Data escript::operator+(const Data& left
723    
724  //  //
725  // NOTE: It is essential to specify the namepsace this operator belongs to  // NOTE: It is essential to specify the namepsace this operator belongs to
726  Data escript::operator-(const Data& left, const Data& right)  Data
727    escript::operator-(const Data& left, const Data& right)
728  {  {
729    Data result;    Data result;
730    //    //
# Line 633  Data escript::operator-(const Data& left Line 736  Data escript::operator-(const Data& left
736    
737  //  //
738  // NOTE: It is essential to specify the namepsace this operator belongs to  // NOTE: It is essential to specify the namepsace this operator belongs to
739  Data escript::operator*(const Data& left, const Data& right)  Data
740    escript::operator*(const Data& left, const Data& right)
741  {  {
742    Data result;    Data result;
743    //    //
# Line 645  Data escript::operator*(const Data& left Line 749  Data escript::operator*(const Data& left
749    
750  //  //
751  // NOTE: It is essential to specify the namepsace this operator belongs to  // NOTE: It is essential to specify the namepsace this operator belongs to
752  Data escript::operator/(const Data& left, const Data& right)  Data
753    escript::operator/(const Data& left, const Data& right)
754  {  {
755    Data result;    Data result;
756    //    //
# Line 657  Data escript::operator/(const Data& left Line 762  Data escript::operator/(const Data& left
762    
763  //  //
764  // NOTE: It is essential to specify the namepsace this operator belongs to  // NOTE: It is essential to specify the namepsace this operator belongs to
765  Data escript::operator+(const Data& left, const boost::python::object& right)  Data
766    escript::operator+(const Data& left, const boost::python::object& right)
767  {  {
768    //    //
769    // Convert to DataArray format if possible    // Convert to DataArray format if possible
# Line 672  Data escript::operator+(const Data& left Line 778  Data escript::operator+(const Data& left
778    
779  //  //
780  // NOTE: It is essential to specify the namepsace this operator belongs to  // NOTE: It is essential to specify the namepsace this operator belongs to
781  Data escript::operator-(const Data& left, const boost::python::object& right)  Data
782    escript::operator-(const Data& left, const boost::python::object& right)
783  {  {
784    //    //
785    // Convert to DataArray format if possible    // Convert to DataArray format if possible
# Line 687  Data escript::operator-(const Data& left Line 794  Data escript::operator-(const Data& left
794    
795  //  //
796  // NOTE: It is essential to specify the namepsace this operator belongs to  // NOTE: It is essential to specify the namepsace this operator belongs to
797  Data escript::operator*(const Data& left, const boost::python::object& right)  Data
798    escript::operator*(const Data& left, const boost::python::object& right)
799  {  {
800    //    //
801    // Convert to DataArray format if possible    // Convert to DataArray format if possible
# Line 702  Data escript::operator*(const Data& left Line 810  Data escript::operator*(const Data& left
810    
811  //  //
812  // NOTE: It is essential to specify the namepsace this operator belongs to  // NOTE: It is essential to specify the namepsace this operator belongs to
813  Data escript::operator/(const Data& left, const boost::python::object& right)  Data
814    escript::operator/(const Data& left, const boost::python::object& right)
815  {  {
816    //    //
817    // Convert to DataArray format if possible    // Convert to DataArray format if possible
# Line 717  Data escript::operator/(const Data& left Line 826  Data escript::operator/(const Data& left
826    
827  //  //
828  // NOTE: It is essential to specify the namepsace this operator belongs to  // NOTE: It is essential to specify the namepsace this operator belongs to
829  Data escript::operator+(const boost::python::object& left, const Data& right)  Data
830    escript::operator+(const boost::python::object& left, const Data& right)
831  {  {
832    //    //
833    // Construct the result using the given value and the other parameters    // Construct the result using the given value and the other parameters
# Line 729  Data escript::operator+(const boost::pyt Line 839  Data escript::operator+(const boost::pyt
839    
840  //  //
841  // NOTE: It is essential to specify the namepsace this operator belongs to  // NOTE: It is essential to specify the namepsace this operator belongs to
842  Data escript::operator-(const boost::python::object& left, const Data& right)  Data
843    escript::operator-(const boost::python::object& left, const Data& right)
844  {  {
845    //    //
846    // Construct the result using the given value and the other parameters    // Construct the result using the given value and the other parameters
# Line 741  Data escript::operator-(const boost::pyt Line 852  Data escript::operator-(const boost::pyt
852    
853  //  //
854  // NOTE: It is essential to specify the namepsace this operator belongs to  // NOTE: It is essential to specify the namepsace this operator belongs to
855  Data escript::operator*(const boost::python::object& left, const Data& right)  Data
856    escript::operator*(const boost::python::object& left, const Data& right)
857  {  {
858    //    //
859    // Construct the result using the given value and the other parameters    // Construct the result using the given value and the other parameters
# Line 753  Data escript::operator*(const boost::pyt Line 865  Data escript::operator*(const boost::pyt
865    
866  //  //
867  // NOTE: It is essential to specify the namepsace this operator belongs to  // NOTE: It is essential to specify the namepsace this operator belongs to
868  Data escript::operator/(const boost::python::object& left, const Data& right)  Data
869    escript::operator/(const boost::python::object& left, const Data& right)
870  {  {
871    //    //
872    // Construct the result using the given value and the other parameters    // Construct the result using the given value and the other parameters
# Line 765  Data escript::operator/(const boost::pyt Line 878  Data escript::operator/(const boost::pyt
878    
879  //  //
880  // NOTE: It is essential to specify the namepsace this operator belongs to  // NOTE: It is essential to specify the namepsace this operator belongs to
881  bool escript::operator==(const Data& left, const Data& right)  //bool escript::operator==(const Data& left, const Data& right)
882  {  //{
883    /*  //  /*
884    NB: this operator does very little at this point, and isn't to  //  NB: this operator does very little at this point, and isn't to
885    be relied on. Requires further implementation.  //  be relied on. Requires further implementation.
886    */  //  */
887    //
888    bool ret;  //  bool ret;
889    //
890    if (left.isEmpty()) {  //  if (left.isEmpty()) {
891      if(!right.isEmpty()) {  //    if(!right.isEmpty()) {
892        ret = false;  //      ret = false;
893      } else {  //    } else {
894        ret = true;  //      ret = true;
895      }  //    }
896    }  //  }
897    //
898    //  if (left.isConstant()) {
899    //    if(!right.isConstant()) {
900    //      ret = false;
901    //    } else {
902    //      ret = true;
903    //    }
904    // }
905    //
906    //  if (left.isTagged()) {
907    //   if(!right.isTagged()) {
908    //      ret = false;
909    //    } else {
910    //      ret = true;
911    //    }
912    //  }
913    //
914    //  if (left.isExpanded()) {
915    //    if(!right.isExpanded()) {
916    //      ret = false;
917    //    } else {
918    //      ret = true;
919    //    }
920    //  }
921    //
922    //  return ret;
923    //}
924    
925    if (left.isConstant()) {  Data
926      if(!right.isConstant()) {  Data::getItem(const boost::python::object& key) const
927        ret = false;  {
928      } else {    const DataArrayView& view=getPointDataView();
       ret = true;  
     }  
   }  
929    
930    if (left.isTagged()) {    DataArrayView::RegionType slice_region=view.getSliceRegion(key);
     if(!right.isTagged()) {  
       ret = false;  
     } else {  
       ret = true;  
     }  
   }  
931    
932    if (left.isExpanded()) {    if (slice_region.size()!=view.getRank()) {
933      if(!right.isExpanded()) {      throw DataException("Error - slice size does not match Data rank.");
       ret = false;  
     } else {  
       ret = true;  
     }  
934    }    }
935    
936    return ret;    return getSlice(slice_region);
937  }  }
938    
939  Data  Data
940  Data::getItem(const boost::python::object& key) const  Data::getSlice(const DataArrayView::RegionType& region) const
941  {  {
942     const DataArrayView& view=getPointDataView();    return Data(*this,region);
    DataArrayView::RegionType slice_region=view.getSliceRegion(key);  
    if (slice_region.size()!=view.getRank()) {  
      throw DataException("Error - slice size does not match Data rank.");  
      return Data();  
    }  
    //  
    // Create a new Data which is a slice of this one  
    return getSlice(slice_region);  
943  }  }
944    
945  void  void
946  Data::setItem(const boost::python::object& key,  Data::setItemO(const boost::python::object& key,
947                const Data& value)                 const boost::python::object& value)
948    {
949      Data tempData(value,getFunctionSpace());
950      setItemD(key,tempData);
951    }
952    
953    void
954    Data::setItemD(const boost::python::object& key,
955                   const Data& value)
956  {  {
957    const DataArrayView& view=getPointDataView();    const DataArrayView& view=getPointDataView();
958    DataArrayView::RegionType slice_region=view.getSliceRegion(key);    DataArrayView::RegionType slice_region=view.getSliceRegion(key);
959    if (slice_region.size()!=view.getRank()) {    if (slice_region.size()!=view.getRank()) {
960      throw DataException("Error - slice size does not match Data rank.");      throw DataException("Error - slice size does not match Data rank.");
961    }    }
   typeMatch(value);  
962    setSlice(value,slice_region);    setSlice(value,slice_region);
963  }  }
964    
965  void  void
966  Data::typeMatch(const Data& right)  Data::setSlice(const Data& value,
967                   const DataArrayView::RegionType& region)
968    {
969      Data tempValue(value);
970      typeMatchLeft(tempValue);
971      typeMatchRight(tempValue);
972      m_data->setSlice(tempValue.m_data.get(),region);
973    }
974    
975    void
976    Data::typeMatchLeft(Data& right) const
977    {
978      if (isExpanded()){
979        right.expand();
980      } else if (isTagged()) {
981        if (right.isConstant()) {
982          right.tag();
983        }
984      }
985    }
986    
987    void
988    Data::typeMatchRight(const Data& right)
989  {  {
   //  
   // match the type of this to the RHS  
990    if (isTagged()) {    if (isTagged()) {
991      if (right.isExpanded()) {      if (right.isExpanded()) {
       //  
       // if the right hand side is expanded so must this  
992        expand();        expand();
993      }      }
994    } else if (isConstant()) {    } else if (isConstant()) {
995      if (right.isExpanded()) {      if (right.isExpanded()) {
       //  
       // if the right hand side is expanded so must this  
996        expand();        expand();
997      } else if (right.isTagged()) {      } else if (right.isTagged()) {
       //  
       // if the right hand side is tagged so must this  
998        tag();        tag();
999      }      }
1000    }    }

Legend:
Removed from v.94  
changed lines
  Added in v.97

  ViewVC Help
Powered by ViewVC 1.1.26