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             }
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 


typelib
Author(s): Sylvain Joyeux/sylvain.joyeux@m4x.org
autogenerated on Mon Sep 14 2015 15:08:18