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 default:
00048 throw UnsupportedType(type, "unsupported numeric category");
00049 }
00050 }
00051
00052 virtual bool visit_ (Enum const& type)
00053 {
00054 Enum::integral_type& v = *reinterpret_cast<Enum::integral_type*>(m_stack.back());
00055 return m_visitor.visit_(v, type);
00056 }
00057
00058 virtual bool visit_ (Container const& type)
00059 {
00060 Value v(m_stack.back(), type);
00061 return m_visitor.visit_(v, type);
00062 }
00063
00064 virtual bool visit_ (Pointer const& type)
00065 {
00066 Value v(m_stack.back(), type);
00067 m_stack.push_back( *reinterpret_cast<uint8_t**>(m_stack.back()) );
00068 bool ret = m_visitor.visit_(v, type);
00069 m_stack.pop_back();
00070 return ret;
00071 }
00072 virtual bool visit_ (Array const& type)
00073 {
00074 Value v(m_stack.back(), type);
00075 return m_visitor.visit_(v, type);
00076 }
00077
00078 virtual bool visit_ (Compound const& type)
00079 {
00080 Value v(m_stack.back(), type);
00081 return m_visitor.visit_(v, type);
00082 }
00083
00084 virtual bool visit_ (OpaqueType const& type)
00085 {
00086 Value v(m_stack.back(), type);
00087 return m_visitor.visit_(v, type);
00088 }
00089
00090 virtual bool visit_ (Compound const& type, Field const& field)
00091 {
00092 m_stack.push_back( m_stack.back() + field.getOffset() );
00093 bool ret = m_visitor.visit_(Value(m_stack.back(), field.getType()), type, field);
00094 m_stack.pop_back();
00095 return ret;
00096 }
00097
00098 public:
00099 TypeDispatch(ValueVisitor& visitor)
00100 : m_visitor(visitor) { }
00101
00102 void apply(Value value)
00103 {
00104 m_stack.clear();
00105 m_stack.push_back( reinterpret_cast<uint8_t*>(value.getData()));
00106 TypeVisitor::apply(value.getType());
00107 m_stack.pop_back();
00108 }
00109
00110 };
00111
00112 bool ValueVisitor::visit_(Value const& v, Pointer const& t)
00113 { return m_dispatcher->TypeVisitor::visit_(t); }
00114 bool ValueVisitor::visit_(Value const& v, Array const& a)
00115 {
00116 uint8_t* base = static_cast<uint8_t*>(v.getData());
00117 m_dispatcher->m_stack.push_back(base);
00118 uint8_t*& element = m_dispatcher->m_stack.back();
00119
00120 Type const& array_type(a.getIndirection());
00121 for (size_t i = 0; i < a.getDimension(); ++i)
00122 {
00123 element = base + array_type.getSize() * i;
00124 if (! m_dispatcher->TypeVisitor::visit_(array_type))
00125 break;
00126 }
00127
00128 m_dispatcher->m_stack.pop_back();
00129 return true;
00130 }
00131 bool ValueVisitor::visit_(Value const& v, Container const& c)
00132 { return c.visit(v.getData(), *this); }
00133 bool ValueVisitor::visit_(Value const&, Compound const& c)
00134 { return m_dispatcher->TypeVisitor::visit_(c); }
00135 bool ValueVisitor::visit_(Value const&, Compound const& c, Field const& f)
00136 { return m_dispatcher->TypeVisitor::visit_(c, f); }
00137 bool ValueVisitor::visit_(Enum::integral_type&, Enum const& e)
00138 { return m_dispatcher->TypeVisitor::visit_(e); }
00139 bool ValueVisitor::visit_(Value const& v, OpaqueType const& t)
00140 { return true; }
00141 void ValueVisitor::dispatch(Value v)
00142 {
00143 m_dispatcher->m_stack.push_back(reinterpret_cast<uint8_t*>(v.getData()));
00144 m_dispatcher->TypeVisitor::visit_(v.getType());
00145 m_dispatcher->m_stack.pop_back();
00146 }
00147
00148 }
00149
00150 namespace Typelib
00151 {
00152 ValueVisitor::ValueVisitor(bool defval)
00153 : m_defval(defval), m_dispatcher(new TypeDispatch(*this))
00154 {
00155 }
00156 ValueVisitor::~ValueVisitor()
00157 {
00158 delete m_dispatcher;
00159 }
00160 void ValueVisitor::apply(Value v)
00161 {
00162 m_dispatcher->apply(v);
00163 }
00164
00165 }
00166