value.cc
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         // 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                 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 


typelib
Author(s): Sylvain Joyeux/sylvain.joyeux@m4x.org
autogenerated on Sat Jun 8 2019 18:49:22