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 }
00107
00108 };
00109
00110 bool ValueVisitor::visit_(Value const& v, Pointer const& t)
00111 { return m_dispatcher->TypeVisitor::visit_(t); }
00112 bool ValueVisitor::visit_(Value const& v, Array const& a)
00113 {
00114 uint8_t* base = static_cast<uint8_t*>(v.getData());
00115 m_dispatcher->m_stack.push_back(base);
00116 uint8_t*& element = m_dispatcher->m_stack.back();
00117
00118 Type const& array_type(a.getIndirection());
00119 for (size_t i = 0; i < a.getDimension(); ++i)
00120 {
00121 element = base + array_type.getSize() * i;
00122 if (! m_dispatcher->TypeVisitor::visit_(array_type))
00123 break;
00124 }
00125
00126 m_dispatcher->m_stack.pop_back();
00127 return true;
00128 }
00129 bool ValueVisitor::visit_(Value const& v, Container const& c)
00130 { return c.visit(v.getData(), *this); }
00131 bool ValueVisitor::visit_(Value const&, Compound const& c)
00132 { return m_dispatcher->TypeVisitor::visit_(c); }
00133 bool ValueVisitor::visit_(Value const&, Compound const& c, Field const& f)
00134 { return m_dispatcher->TypeVisitor::visit_(c, f); }
00135 bool ValueVisitor::visit_(Enum::integral_type&, Enum const& e)
00136 { return m_dispatcher->TypeVisitor::visit_(e); }
00137 bool ValueVisitor::visit_(Value const& v, OpaqueType const& t)
00138 { return true; }
00139 void ValueVisitor::dispatch(Value v)
00140 {
00141 m_dispatcher->m_stack.push_back(reinterpret_cast<uint8_t*>(v.getData()));
00142 m_dispatcher->TypeVisitor::visit_(v.getType());
00143 m_dispatcher->m_stack.pop_back();
00144 }
00145
00146 }
00147
00148 namespace Typelib
00149 {
00150 void ValueVisitor::apply(Value v)
00151 {
00152 TypeDispatch dispatcher(*this);
00153 m_dispatcher = &dispatcher;
00154 dispatcher.apply(v);
00155 m_dispatcher = 0;
00156 }
00157 }
00158