Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ShEval.hpp

00001 #ifndef SHEVAL_HPP 
00002 #define SHEVAL_HPP
00003 
00004 #include <vector>
00005 #include <map>
00006 #include "ShHashMap.hpp"
00007 #include "ShStatement.hpp"
00008 #include "ShVariant.hpp"
00009 #include "ShOperation.hpp"
00010 #include "ShRefCount.hpp"
00011 #include "ShInterval.hpp"
00012 #include "ShHalf.hpp"
00013 
00014 namespace SH {
00015 
00039 // forward declarations
00040 //class ShVariant;
00041 class ShEvalOp;
00042 //typedef ShPointer<ShVariant> ShVariant*;
00043 //typedef ShPointer<const ShVariant> const ShVariant*;
00044 
00045 struct 
00046 SH_DLLEXPORT
00047 ShEvalOpInfo: public ShStatementInfo {
00048   ShOperation m_op;
00049 
00050   const ShEvalOp* m_evalOp;
00051 
00052   // type indices of the destination and sources
00053   // These are set to a valid value type except when the src/dest is not
00054   // used for m_op 
00055   ShValueType m_dest;
00056   ShValueType m_src[3]; 
00057 
00058   ShEvalOpInfo(ShOperation op, const ShEvalOp* evalOp, ShValueType dest, 
00059       ShValueType src0, ShValueType src1, ShValueType src2);
00060 
00061   ShStatementInfo* clone() const;
00062 
00063   std::string encode() const;
00064 };
00065 
00066 class 
00067 SH_DLLEXPORT
00068 ShEval {
00069   public:
00078     void operator()(ShOperation op, ShVariant* dest,
00079         const ShVariant* a, const ShVariant* b, const ShVariant* c) const;
00080 
00082     void addOp(ShOperation op, const ShEvalOp* evalOp, ShValueType dest, 
00083         ShValueType src0, ShValueType src1 = SH_VALUETYPE_END, 
00084         ShValueType src2 = SH_VALUETYPE_END); 
00085 
00090     const ShEvalOpInfo* getEvalOpInfo(ShOperation op, ShValueType dest,
00091         ShValueType src0, ShValueType src1 = SH_VALUETYPE_END, 
00092         ShValueType src2 = SH_VALUETYPE_END) const;
00093 
00095     std::string availableOps() const;
00096 
00097     static ShEval* instance();
00098 
00099   private:
00100     ShEval();
00101 
00102 
00103     typedef std::list<ShEvalOpInfo> OpInfoList;
00104     typedef OpInfoList OpInfoMap[SH_OPERATION_END];
00105     OpInfoMap m_evalOpMap; 
00106 
00107     typedef ShPairPairHashMap<ShOperation, ShValueType, ShValueType, ShValueType, const ShEvalOpInfo*> EvalOpCache;
00108     mutable EvalOpCache  m_evalOpCache;
00109 
00110     static ShEval* m_instance;
00111 };
00112 
00113 class 
00114 SH_DLLEXPORT
00115 ShEvalOp {
00116   public:
00117     virtual ~ShEvalOp();
00118 
00119     // Wraps an operation where at least dest and a are non-null.
00120     virtual void operator()(ShVariant* dest, const ShVariant* a, 
00121         const ShVariant* b, const ShVariant* c) const = 0;
00122 };
00123 
00124 // The strategy for defining ops is to use separate classes to hold
00125 // and register operations for different categories of types.
00126 //
00127 // Each of these "concrete" evaluation evalOps must implement
00128 // 1) the virtual void ShEvalOp::operator()(...)
00129 //    This is used to evaluate ShVariables
00130 //
00131 // 2) Functions 
00132 //    template<ShOperation S>
00133 //    static void unaryOp(ShDataVariant<T1> &dest, const ShDataVariant<T2> &src);
00134 //
00135 //    and similarly for binary, ternary ops 
00136 //    (for most ops, only T1 = T2 is supported directly,
00137 //    but for range arithmetic ops, some args may be in a range arithmetic
00138 //    type and other args might not)
00139 //
00140 //    These can be specialized to implement specific ops,
00141 //    and thus used directly for computation on data from
00142 //    ShGenerics without going through ANY layers of virtual 
00143 //    function calls.
00144 
00148 template<ShOperation S, typename T>
00149 struct ShRegularOp: public ShEvalOp {
00150   void operator()(ShVariant* dest, const ShVariant* a, 
00151       const ShVariant* b, const ShVariant* c) const; 
00152 };
00153 
00154 // If functions could be partially specialized, then wouldn't need
00155 // to wrap this in a class.
00156 
00157 // TODO might want to break this down into a few more subclasses to handle
00158 // 1) special float/double cmath functions (for C built in types)
00159 // 2) other special functions (sgn, rcp, rsq, etc.) that C types don't have
00160 // OR, use helper functions 
00161 template<ShOperation S, typename T>
00162 struct ShConcreteRegularOp {
00163   typedef ShDataVariant<T, SH_HOST> Variant;
00164   typedef Variant* DataPtr; 
00165   typedef const Variant* DataCPtr; 
00166 
00167   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0);
00168 };
00169 
00171 // has little code snippets for functions like sgn, rcp, rsq, etc.
00172 // that are not built-in cmath functions.
00173 //
00174 //TODO - not all the functions make sense on integer types...may
00175 //want to not declare the ones that don't make sense...
00176 template<ShOperation S, typename T>
00177 struct ShConcreteCTypeOp {
00178   typedef ShDataVariant<T, SH_HOST> Variant;
00179   typedef Variant* DataPtr; 
00180   typedef const Variant* DataCPtr; 
00181 
00182   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0);
00183 };
00184 
00185 template<ShOperation S, typename T>
00186 struct ShRegularOpChooser {
00187   typedef ShConcreteRegularOp<S, T> Op;
00188 };
00189 
00190 #define SHOPC_CTYPE_OP(T)\
00191 template<ShOperation S>\
00192 struct ShRegularOpChooser<S, T> {\
00193   typedef ShConcreteCTypeOp<S, T> Op;\
00194 };
00195 
00196 SHOPC_CTYPE_OP(double);
00197 SHOPC_CTYPE_OP(float);
00198 SHOPC_CTYPE_OP(ShHalf);
00199 SHOPC_CTYPE_OP(int);
00200 
00204 template<ShOperation S, typename T1, typename T2>
00205 struct ShIntervalOp: public ShEvalOp {
00206   void operator()(ShVariant* dest, const ShVariant* a, 
00207       const ShVariant* b, const ShVariant* c) const; 
00208 };
00209 
00210 template<ShOperation S, typename T1, typename T2>
00211 struct ShConcreteIntervalOp{
00212   static void doop(ShDataVariant<T1, SH_HOST> &dest, 
00213       const ShDataVariant<T2, SH_HOST> &a);
00214       
00215 };
00216 
00217 
00218 // initializes the regular Ops for a floating point type T
00219 // with ShOpEvalOp<OP, T> objects
00220 template<typename T>
00221 void _shInitFloatOps();
00222 
00223 // initializes the regular Ops for an integer type T
00224 // (a subset of the floating point ones)
00225 template<typename T>
00226 void _shInitIntOps();
00227 
00228 // initializes the interval ops for a type T and ShInterval<T>
00229 template<typename T, typename IntervalT>
00230 void _shInitIntervalOps();
00231 
00232 
00233 }
00234 
00235 #include "ShEvalImpl.hpp"
00236 #include "ShConcreteRegularOpImpl.hpp"
00237 #include "ShConcreteCTypeOpImpl.hpp"
00238 #include "ShConcreteIntervalOpImpl.hpp"
00239 //#include "ShIntervalEvalImpl.hpp"
00240 
00241 #endif

Generated on Mon Jan 24 18:36:31 2005 for Sh by  doxygen 1.4.1