00001 #ifndef __TYPELIB_TYPEMODEL_HH__
00002 #define __TYPELIB_TYPEMODEL_HH__
00003
00004 #include <string>
00005 #include <list>
00006 #include <map>
00007 #include <set>
00008 #include <boost/tuple/tuple.hpp>
00009
00010 #include "typename.hh"
00011
00012 namespace Typelib
00013 {
00014 class Registry;
00015
00017 class Type
00018 {
00019 public:
00020
00021 enum Category
00022 {
00023 NullType = 0,
00024 Array ,
00025 Pointer,
00026 Numeric,
00027 Enum ,
00028 Compound,
00029 Opaque,
00030 Container
00031 };
00032 static const int ValidCategories = Compound + 1;
00033
00034 private:
00035 std::string m_name;
00036
00037 size_t m_size;
00038 Category m_category;
00039
00041 static bool isValidIdentifier(const std::string& identifier);
00042
00043 protected:
00044 typedef std::map<Type const*, Type const*> RecursionStack;
00045
00046
00047 Type(const std::string& name, size_t size, Category category);
00048
00049 public:
00050 virtual ~Type();
00051
00054 void setName (const std::string& name);
00059 void setSize (size_t size);
00061 std::string getName() const;
00063 std::string getBasename() const;
00065 std::string getNamespace() const;
00067 size_t getSize() const;
00069 Category getCategory() const;
00071 bool isNull() const;
00072
00074 virtual std::set<Type const*> dependsOn() const = 0;
00075
00076 bool operator == (Type const& with) const;
00077 bool operator != (Type const& with) const;
00078
00083 bool isSame(Type const& other) const;
00084
00089 Type const& merge(Registry& registry) const;
00090
00091 virtual Type const& merge(Registry& registry, RecursionStack& stack) const;
00092
00093 protected:
00094 virtual bool do_isSame(Type const& other, std::map<Type const*, Type const*>& stack) const;
00095
00096 bool rec_isSame(Type const& left, Type const& right, RecursionStack& stack) const;
00097
00098
00099 Type const* try_merge(Registry& registry, RecursionStack& stack) const;
00105 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const = 0;
00106 };
00107
00108 class NullType : public Type
00109 {
00110 public:
00111 NullType(std::string const& name) : Type(name, 0, Type::NullType ) {}
00112 virtual std::set<Type const*> dependsOn() const { return std::set<Type const*>(); }
00113
00114 private:
00115 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const { return new NullType(*this); }
00116 };
00117
00122 class OpaqueType : public Type
00123 {
00124 public:
00125 OpaqueType(std::string const& name, size_t size) : Type(name, size, Type::Opaque) {}
00126 virtual std::set<Type const*> dependsOn() const { return std::set<Type const*>(); }
00127 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const { return new OpaqueType(*this); }
00128 };
00129
00131 class Numeric : public Type
00132 {
00133 public:
00134 enum NumericCategory
00135 {
00136 SInt = Type::ValidCategories,
00137 UInt,
00138 Float
00139 };
00140 static const int ValidCategories = Float + 1;
00141
00143 NumericCategory getNumericCategory() const;
00144
00145 public:
00147 Numeric(const std::string& name, size_t size, NumericCategory category);
00148
00149 virtual std::set<Type const*> dependsOn() const { return std::set<Type const*>(); }
00150
00151 private:
00152 virtual bool do_isSame(Type const& other, RecursionStack& stack) const;
00153 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const;
00154 NumericCategory m_category;
00155 };
00156
00158 class Enum : public Type
00159 {
00160 public:
00161 typedef int integral_type;
00162 typedef std::map<std::string, int> ValueMap;
00163
00164 class AlreadyExists {};
00165 class SymbolNotFound {};
00166 class ValueNotFound {};
00167
00168 Enum(const std::string& name, Enum::integral_type initial_value = 0);
00170 void add(std::string const& name, int value);
00173 integral_type get(std::string const& name) const;
00176 std::string get(integral_type value) const;
00177
00179 std::list<std::string> names() const;
00181 ValueMap const& values() const;
00182
00183 virtual std::set<Type const*> dependsOn() const { return std::set<Type const*>(); }
00184
00187 Enum::integral_type getNextValue() const;
00188
00189 private:
00190 virtual bool do_isSame(Type const& other, RecursionStack& stack) const;
00191 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const;
00192 integral_type m_last_value;
00193 ValueMap m_values;
00194 };
00195
00197 class Field
00198 {
00199 friend class Compound;
00200
00201 std::string m_name;
00202 const Type& m_type;
00203 size_t m_offset;
00204
00205 protected:
00206 void setOffset(size_t offset);
00207
00208 public:
00209 Field(const std::string& name, Type const& base_type);
00210
00212 std::string getName() const;
00214 const Type& getType() const;
00217 size_t getOffset() const;
00218
00219 bool operator == (Field const& field) const;
00220 };
00221
00224 class Compound : public Type
00225 {
00226 public:
00227 typedef std::list<Field> FieldList;
00228
00229 public:
00230 Compound(std::string const& name);
00231
00233 FieldList const& getFields() const;
00236 Field const* getField(const std::string& name) const;
00238 void addField(const Field& field, size_t offset);
00240 void addField(const std::string& name, const Type& type, size_t offset);
00241
00242 virtual std::set<Type const*> dependsOn() const;
00243
00244 private:
00245 virtual bool do_isSame(Type const& other, RecursionStack& stack) const;
00246 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const;
00247 FieldList m_fields;
00248 };
00249
00251 class Indirect : public Type
00252 {
00253 public:
00254 static const int ValidIDs = Type::Pointer | Type::Array;
00255
00256 public:
00257
00258 Indirect(std::string const& name, size_t size, Category category, Type const& on);
00259 Type const& getIndirection() const;
00260 virtual std::set<Type const*> dependsOn() const;
00261
00262 virtual Type const& merge(Registry& registry, RecursionStack& stack) const;
00263
00264 protected:
00265 virtual bool do_isSame(Type const& other, RecursionStack& stack) const;
00266
00267 private:
00268 Type const& m_indirection;
00269 };
00270
00274 class Array : public Indirect
00275 {
00276 public:
00277
00278 Array(Type const& of, size_t dimension);
00279 size_t getDimension() const;
00280 static std::string getArrayName(std::string const& base, size_t new_dim);
00281
00282 private:
00283 virtual bool do_isSame(Type const& other, RecursionStack& stack) const;
00284 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const;
00285 size_t m_dimension;
00286 };
00287
00289 class Pointer : public Indirect
00290 {
00291 public:
00292 Pointer(Type const& on);
00293 static std::string getPointerName(std::string const& base);
00294
00295 private:
00296 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const;
00297 };
00298
00299 struct UnknownContainer : public std::runtime_error
00300 {
00301 UnknownContainer(std::string const& name)
00302 : std::runtime_error("unknown container " + name) {}
00303 };
00304
00305 class ValueVisitor;
00306 class Value;
00307
00309 class Container : public Indirect
00310 {
00311 std::string m_kind;
00312
00313
00314 protected:
00315 struct DeleteIfPredicate
00316 {
00317 virtual bool should_delete(Value const& v) = 0;
00318 };
00319
00320 virtual void delete_if_impl(void* ptr, DeleteIfPredicate& pred) const = 0;
00321
00322 private:
00323 template<typename Pred>
00324 struct PredicateWrapper : public DeleteIfPredicate
00325 {
00326 Pred pred;
00327
00328 PredicateWrapper(Pred pred)
00329 : pred(pred) {}
00330
00331 virtual bool should_delete(Value const& v)
00332 {
00333 return pred(v);
00334 };
00335 };
00336
00337
00338 public:
00339 typedef std::vector<size_t> MarshalOps;
00340
00341 Container(std::string const& kind, std::string const& name, size_t size, Type const& of);
00342
00343 std::string kind() const;
00344 virtual void init(void* ptr) const = 0;
00345 virtual void destroy(void* ptr) const = 0;
00346 virtual bool visit(void* ptr, ValueVisitor& visitor) const = 0;
00347
00350 virtual void insert(void* ptr, Value v) const = 0;
00351
00356 virtual bool erase(void* ptr, Value v) const = 0;
00357
00363 virtual bool compare(void* ptr, void* other) const = 0;
00364
00368 virtual void copy(void* dst, void* src) const = 0;
00369
00370 template<typename Pred>
00371 void delete_if(void* ptr, Pred pred) const
00372 {
00373 PredicateWrapper<Pred> predicate(pred);
00374 delete_if_impl(ptr, predicate);
00375 }
00376
00377 virtual size_t getElementCount(void* ptr) const = 0;
00378
00396 virtual MarshalOps::const_iterator dump(
00397 void* container_ptr, size_t element_count,
00398 std::vector<uint8_t>& buffer,
00399 MarshalOps::const_iterator const begin, MarshalOps::const_iterator const end) const = 0;
00400
00417 virtual boost::tuple<size_t, MarshalOps::const_iterator> load(
00418 void* container_ptr, size_t element_count,
00419 std::vector<uint8_t> const& buffer, size_t in_offset,
00420 MarshalOps::const_iterator const begin, MarshalOps::const_iterator const end) const = 0;
00421
00422 typedef Container const& (*ContainerFactory)(Registry& r, std::list<Type const*> const& base_type);
00423 typedef std::map<std::string, ContainerFactory> AvailableContainers;
00424
00425 static AvailableContainers availableContainers();
00426 static void registerContainer(std::string const& name, ContainerFactory factory);
00427 static Container const& createContainer(Registry& r, std::string const& name, Type const& on);
00428 static Container const& createContainer(Registry& r, std::string const& name, std::list<Type const*> const& on);
00429
00430 protected:
00431 virtual bool do_isSame(Type const& other, RecursionStack& stack) const;
00432 virtual ContainerFactory getFactory() const = 0;
00433 Type* do_merge(Registry& registry, RecursionStack& stack) const;
00434
00435 private:
00436 static AvailableContainers* s_available_containers;
00437 };
00438
00439 struct TypeException : public std::runtime_error
00440 {
00441 TypeException(std::string const& msg) : std::runtime_error(msg) { }
00442 };
00443
00444 struct BadCategory : public TypeException
00445 {
00446 Type::Category const found;
00447 int const expected;
00448
00449 BadCategory(Type::Category found, int expected);
00450 };
00451
00452 struct NullTypeFound : public TypeException
00453 {
00454 NullTypeFound();
00455 };
00456 };
00457
00458 #endif
00459