Go to the documentation of this file.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
00012 std::list<uint8_t*> m_stack;
00013
00014
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