$search
00001 #include "value.hh" 00002 00003 #include "typevisitor.hh" 00004 00005 namespace Typelib 00006 { 00007 class ValueVisitor::TypeDispatch : public TypeVisitor 00008 { 00009 friend class ValueVisitor; 00010 00011 // The dispatching stack 00012 std::list<uint8_t*> m_stack; 00013 00014 // The ValueVisitor object 00015 ValueVisitor& m_visitor; 00016 00017 template<typename T8, typename T16, typename T32, typename T64> 00018 bool integer_cast(uint8_t* value, Type const& t) 00019 { 00020 switch(t.getSize()) 00021 { 00022 case 1: return m_visitor.visit_(*reinterpret_cast<T8*>(value)); 00023 case 2: return m_visitor.visit_(*reinterpret_cast<T16*>(value)); 00024 case 4: return m_visitor.visit_(*reinterpret_cast<T32*>(value)); 00025 case 8: return m_visitor.visit_(*reinterpret_cast<T64*>(value)); 00026 default: 00027 throw UnsupportedType(t, "unsupported integer size"); 00028 }; 00029 } 00030 00031 protected: 00032 virtual bool visit_ (Numeric const& type) 00033 { 00034 uint8_t* value(m_stack.back()); 00035 switch(type.getNumericCategory()) 00036 { 00037 case Numeric::SInt: 00038 return integer_cast<int8_t, int16_t, int32_t, int64_t>(value, type); 00039 case Numeric::UInt: 00040 return integer_cast<uint8_t, uint16_t, uint32_t, uint64_t>(value, type); 00041 case Numeric::Float: 00042 switch(type.getSize()) 00043 { 00044 case sizeof(float): return m_visitor.visit_(*reinterpret_cast<float*>(value)); 00045 case sizeof(double): return m_visitor.visit_(*reinterpret_cast<double*>(value)); 00046 } 00047 } 00048 throw UnsupportedType(type, "unsupported numeric category"); 00049 } 00050 00051 virtual bool visit_ (Enum const& type) 00052 { 00053 Enum::integral_type& v = *reinterpret_cast<Enum::integral_type*>(m_stack.back()); 00054 return m_visitor.visit_(v, type); 00055 } 00056 00057 virtual bool visit_ (Container const& type) 00058 { 00059 Value v(m_stack.back(), type); 00060 return m_visitor.visit_(v, type); 00061 } 00062 00063 virtual bool visit_ (Pointer const& type) 00064 { 00065 Value v(m_stack.back(), type); 00066 m_stack.push_back( *reinterpret_cast<uint8_t**>(m_stack.back()) ); 00067 bool ret = m_visitor.visit_(v, type); 00068 m_stack.pop_back(); 00069 return ret; 00070 } 00071 virtual bool visit_ (Array const& type) 00072 { 00073 Value v(m_stack.back(), type); 00074 return m_visitor.visit_(v, type); 00075 } 00076 00077 virtual bool visit_ (Compound const& type) 00078 { 00079 Value v(m_stack.back(), type); 00080 return m_visitor.visit_(v, type); 00081 } 00082 00083 virtual bool visit_ (OpaqueType const& type) 00084 { 00085 Value v(m_stack.back(), type); 00086 return m_visitor.visit_(v, type); 00087 } 00088 00089 virtual bool visit_ (Compound const& type, Field const& field) 00090 { 00091 m_stack.push_back( m_stack.back() + field.getOffset() ); 00092 bool ret = m_visitor.visit_(Value(m_stack.back(), field.getType()), type, field); 00093 m_stack.pop_back(); 00094 return ret; 00095 } 00096 00097 public: 00098 TypeDispatch(ValueVisitor& visitor) 00099 : m_visitor(visitor) { } 00100 00101 void apply(Value value) 00102 { 00103 m_stack.clear(); 00104 m_stack.push_back( reinterpret_cast<uint8_t*>(value.getData())); 00105 TypeVisitor::apply(value.getType()); 00106 m_stack.pop_back(); 00107 } 00108 00109 }; 00110 00111 bool ValueVisitor::visit_(Value const& v, Pointer const& t) 00112 { return m_dispatcher->TypeVisitor::visit_(t); } 00113 bool ValueVisitor::visit_(Value const& v, Array const& a) 00114 { 00115 uint8_t* base = static_cast<uint8_t*>(v.getData()); 00116 m_dispatcher->m_stack.push_back(base); 00117 uint8_t*& element = m_dispatcher->m_stack.back(); 00118 00119 Type const& array_type(a.getIndirection()); 00120 for (size_t i = 0; i < a.getDimension(); ++i) 00121 { 00122 element = base + array_type.getSize() * i; 00123 if (! m_dispatcher->TypeVisitor::visit_(array_type)) 00124 break; 00125 } 00126 00127 m_dispatcher->m_stack.pop_back(); 00128 return true; 00129 } 00130 bool ValueVisitor::visit_(Value const& v, Container const& c) 00131 { return c.visit(v.getData(), *this); } 00132 bool ValueVisitor::visit_(Value const&, Compound const& c) 00133 { return m_dispatcher->TypeVisitor::visit_(c); } 00134 bool ValueVisitor::visit_(Value const&, Compound const& c, Field const& f) 00135 { return m_dispatcher->TypeVisitor::visit_(c, f); } 00136 bool ValueVisitor::visit_(Enum::integral_type&, Enum const& e) 00137 { return m_dispatcher->TypeVisitor::visit_(e); } 00138 bool ValueVisitor::visit_(Value const& v, OpaqueType const& t) 00139 { return true; } 00140 void ValueVisitor::dispatch(Value v) 00141 { 00142 m_dispatcher->m_stack.push_back(reinterpret_cast<uint8_t*>(v.getData())); 00143 m_dispatcher->TypeVisitor::visit_(v.getType()); 00144 m_dispatcher->m_stack.pop_back(); 00145 } 00146 00147 } 00148 00149 namespace Typelib 00150 { 00151 ValueVisitor::ValueVisitor(bool defval) 00152 : m_defval(defval), m_dispatcher(new TypeDispatch(*this)) 00153 { 00154 } 00155 ValueVisitor::~ValueVisitor() 00156 { 00157 delete m_dispatcher; 00158 } 00159 void ValueVisitor::apply(Value v) 00160 { 00161 m_dispatcher->apply(v); 00162 } 00163 00164 } 00165