Go to the documentation of this file.00001 #ifndef TYPELIB_MEMORY_LAYOUT_HH
00002 #define TYPELIB_MEMORY_LAYOUT_HH
00003
00004 #include <stdexcept>
00005 #include <typelib/typevisitor.hh>
00006 #include <vector>
00007 #include <boost/static_assert.hpp>
00008
00009 namespace Typelib
00010 {
00013 struct NoLayout : public std::runtime_error
00014 {
00015 NoLayout(Type const& type, std::string const& reason)
00016 : std::runtime_error("there is no memory layout for type " + type.getName() + ": " + reason) { }
00017 };
00018
00022 struct UnknownLayoutBytecode : public std::runtime_error
00023 {
00024 UnknownLayoutBytecode() : std::runtime_error("found an unknown marshalling bytecode operation") { }
00025 };
00026
00027
00028
00029 BOOST_STATIC_ASSERT((sizeof(size_t) == sizeof(void*)));
00030
00031 typedef std::vector<size_t> MemoryLayout;
00032
00039 namespace MemLayout
00040 {
00048 enum Operations {
00049 FLAG_MEMCPY,
00050 FLAG_ARRAY,
00051 FLAG_CONTAINER,
00052 FLAG_SKIP,
00053 FLAG_END
00054 };
00055
00062 class Visitor : public TypeVisitor
00063 {
00064 private:
00065 MemoryLayout& ops;
00066 bool accept_pointers;
00067 bool accept_opaques;
00068 size_t current_op;
00069 size_t current_op_count;
00070 bool merge_skip_copy;
00071
00072 protected:
00073 void push_current_op();
00074 void skip(size_t count);
00075 void memcpy(size_t count);
00076 void add_generic_op(size_t op, size_t count);
00077 bool generic_visit(Type const& value);
00078 bool visit_ (Numeric const& type);
00079 bool visit_ (Enum const& type);
00080 bool visit_ (Array const& type);
00081 bool visit_ (Container const& type);
00082 bool visit_ (Compound const& type);
00083 bool visit_ (Pointer const& type);
00084 bool visit_ (OpaqueType const& type);
00085
00086 void merge_skips_and_copies();
00087
00088 public:
00089 Visitor(MemoryLayout& ops, bool accept_pointers = false, bool accept_opaques = false);
00090
00091 void apply(Type const& type, bool merge_skip_copy = true, bool remove_trailing_skips = true);
00092 };
00093
00100 MemoryLayout::const_iterator skip_block(
00101 MemoryLayout::const_iterator begin,
00102 MemoryLayout::const_iterator end);
00103 }
00104
00122 inline MemoryLayout layout_of(Type const& t, bool accept_pointers = false, bool accept_opaques = false, bool merge_skip_copy = true, bool remove_trailing_skips = true)
00123 {
00124 MemoryLayout ret;
00125 MemLayout::Visitor visitor(ret, accept_pointers, accept_opaques);
00126 visitor.apply(t, merge_skip_copy, remove_trailing_skips);
00127 return ret;
00128 }
00129 }
00130
00131 #endif
00132