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 <vector>
00009 #include <stdint.h>
00010 #include <stdexcept>
00011
00012 namespace Typelib
00013 {
00014 namespace ValueOps
00015 {
00016
00017
00018 struct OutputStream;
00019 struct InputStream;
00020 }
00021
00022 class Registry;
00023
00025 class Type
00026 {
00027 public:
00028
00029 enum Category
00030 {
00031 NullType = 0,
00032 Array ,
00033 Pointer,
00034 Numeric,
00035 Enum ,
00036 Compound,
00037 Opaque,
00038 Container
00039 };
00040 static const int ValidCategories = Compound + 1;
00041
00042 private:
00043 std::string m_name;
00044
00045 size_t m_size;
00046 Category m_category;
00047
00049 static bool isValidIdentifier(const std::string& identifier);
00050
00051 protected:
00052
00053
00054 Type(const std::string& name, size_t size, Category category);
00055
00056 public:
00057 virtual ~Type();
00058
00061 void setName (const std::string& name);
00066 void setSize (size_t size);
00068 std::string getName() const;
00070 std::string getBasename() const;
00072 std::string getNamespace() const;
00074 size_t getSize() const;
00076 Category getCategory() const;
00078 bool isNull() const;
00079
00085 virtual std::set<Type const*> dependsOn() const = 0;
00086
00093 virtual void modifiedDependencyAliases(Registry& registry) const;
00094
00095 bool operator == (Type const& with) const;
00096 bool operator != (Type const& with) const;
00097
00102 bool isSame(Type const& other) const;
00103
00107 bool canCastTo(Type const& to) const;
00108
00113 Type const& merge(Registry& registry) const;
00114
00116 typedef std::map<Type const*, Type const*> RecursionStack;
00117
00124 virtual Type const& merge(Registry& registry, RecursionStack& stack) const;
00125
00134 virtual bool resize(Registry& registry, std::map<std::string, std::pair<size_t, size_t> >& new_sizes);
00135
00138 virtual unsigned int getTrailingPadding() const;
00139
00140 protected:
00159 virtual bool do_compare(Type const& other, bool equality, std::map<Type const*, Type const*>& stack) const;
00160
00166 bool rec_compare(Type const& left, Type const& right, bool equality, RecursionStack& stack) const;
00167
00175 Type const* try_merge(Registry& registry, RecursionStack& stack) const;
00176
00184 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const = 0;
00185
00187 virtual bool do_resize(Registry& into, std::map<std::string, std::pair<size_t, size_t> >& new_sizes);
00188 };
00189
00190 class NullType : public Type
00191 {
00192 public:
00193 NullType(std::string const& name) : Type(name, 0, Type::NullType ) {}
00194 virtual std::set<Type const*> dependsOn() const { return std::set<Type const*>(); }
00195
00196 private:
00197 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const { return new NullType(*this); }
00198 };
00199
00204 class OpaqueType : public Type
00205 {
00206 public:
00207 OpaqueType(std::string const& name, size_t size) : Type(name, size, Type::Opaque) {}
00208 virtual std::set<Type const*> dependsOn() const { return std::set<Type const*>(); }
00209 virtual bool do_compare(Type const& other, bool equality, std::map<Type const*, Type const*>& stack) const;
00210 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const { return new OpaqueType(*this); }
00211 };
00212
00214 class Numeric : public Type
00215 {
00216 public:
00217 enum NumericCategory
00218 {
00219 SInt = Type::ValidCategories,
00220 UInt,
00221 Float
00222 };
00223 static const int ValidCategories = Float + 1;
00224
00226 NumericCategory getNumericCategory() const;
00227
00228 public:
00230 Numeric(const std::string& name, size_t size, NumericCategory category);
00231
00232 virtual std::set<Type const*> dependsOn() const { return std::set<Type const*>(); }
00233
00234 private:
00235 virtual bool do_compare(Type const& other, bool equality, RecursionStack& stack) const;
00236 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const;
00237 NumericCategory m_category;
00238 };
00239
00241 class Enum : public Type
00242 {
00243 public:
00244 typedef int integral_type;
00245 typedef std::map<std::string, int> ValueMap;
00246
00247 class AlreadyExists : public std::runtime_error
00248 {
00249 public:
00250 AlreadyExists(Type const& type, std::string const& name);
00251 };
00252 class SymbolNotFound : public std::runtime_error
00253 {
00254 public:
00255 SymbolNotFound(Type const& type, std::string const& name);
00256 };
00257 class ValueNotFound : public std::runtime_error
00258 {
00259 public:
00260 ValueNotFound(Type const& type, int value);
00261 };
00262
00263 Enum(const std::string& name, Enum::integral_type initial_value = 0);
00265 void add(std::string const& name, int value);
00268 integral_type get(std::string const& name) const;
00271 std::string get(integral_type value) const;
00272
00274 std::list<std::string> names() const;
00276 ValueMap const& values() const;
00277
00278 virtual std::set<Type const*> dependsOn() const { return std::set<Type const*>(); }
00279
00282 Enum::integral_type getNextValue() const;
00283
00284 private:
00285 virtual bool do_compare(Type const& other, bool equality, RecursionStack& stack) const;
00286 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const;
00287 integral_type m_last_value;
00288 ValueMap m_values;
00289 };
00290
00292 class Field
00293 {
00294 friend class Compound;
00295
00296 std::string m_name;
00297 const Type& m_type;
00298 size_t m_offset;
00299
00300 protected:
00301 void setOffset(size_t offset);
00302
00303 public:
00304 Field(const std::string& name, Type const& base_type);
00305
00307 std::string getName() const;
00309 const Type& getType() const;
00312 size_t getOffset() const;
00313
00314 bool operator == (Field const& field) const;
00315 };
00316
00319 class Compound : public Type
00320 {
00321 public:
00322 typedef std::list<Field> FieldList;
00323
00324 public:
00325 Compound(std::string const& name);
00326
00328 FieldList const& getFields() const;
00331 Field const* getField(const std::string& name) const;
00333 void addField(const Field& field, size_t offset);
00335 void addField(const std::string& name, const Type& type, size_t offset);
00336
00339 unsigned int getTrailingPadding() const;
00340
00341 virtual std::set<Type const*> dependsOn() const;
00342
00343 private:
00344 virtual bool do_compare(Type const& other, bool equality, RecursionStack& stack) const;
00345 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const;
00346 bool do_resize(Registry& registry, std::map<std::string, std::pair<size_t, size_t> >& new_sizes);
00347 FieldList m_fields;
00348 };
00349
00351 class Indirect : public Type
00352 {
00353 public:
00354 static const int ValidIDs = Type::Pointer | Type::Array;
00355
00356 public:
00357
00358 Indirect(std::string const& name, size_t size, Category category, Type const& on);
00359
00360 void modifiedDependencyAliases(Registry& registry) const;
00361
00362 Type const& getIndirection() const;
00363 virtual std::set<Type const*> dependsOn() const;
00364
00365 virtual Type const& merge(Registry& registry, RecursionStack& stack) const;
00366
00367 protected:
00368 virtual bool do_compare(Type const& other, bool equality, RecursionStack& stack) const;
00369 virtual bool do_resize(Registry& registry, std::map<std::string, std::pair<size_t, size_t> >& new_sizes);
00370
00377 virtual std::string getIndirectTypeName(std::string const& inside_name) const = 0;
00378
00379 private:
00380 Type const& m_indirection;
00381 };
00382
00386 class Array : public Indirect
00387 {
00388 public:
00389
00390 Array(Type const& of, size_t dimension);
00391 size_t getDimension() const;
00392 static std::string getArrayName(std::string const& base, size_t new_dim);
00393
00394 protected:
00395 virtual std::string getIndirectTypeName(std::string const& inside_name) const;
00396
00397 private:
00398 virtual bool do_compare(Type const& other, bool equality, RecursionStack& stack) const;
00399 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const;
00400 virtual bool do_resize(Registry& into, std::map<std::string, std::pair<size_t, size_t> >& new_sizes);
00401 size_t m_dimension;
00402 };
00403
00405 class Pointer : public Indirect
00406 {
00407 public:
00408 Pointer(Type const& on);
00409 static std::string getPointerName(std::string const& base);
00410
00411 protected:
00412 virtual std::string getIndirectTypeName(std::string const& inside_name) const;
00413
00414 private:
00415 virtual Type* do_merge(Registry& registry, RecursionStack& stack) const;
00416 };
00417
00418 struct UnknownContainer : public std::runtime_error
00419 {
00420 UnknownContainer(std::string const& name)
00421 : std::runtime_error("unknown container " + name) {}
00422 };
00423
00424 class ValueVisitor;
00425 class Value;
00426
00428 class Container : public Indirect
00429 {
00430 std::string m_kind;
00431
00432
00433 protected:
00434 struct DeleteIfPredicate
00435 {
00436 virtual bool should_delete(Value const& v) = 0;
00437 };
00438
00439 virtual void delete_if_impl(void* ptr, DeleteIfPredicate& pred) const = 0;
00440
00441 private:
00442 template<typename Pred>
00443 struct PredicateWrapper : public DeleteIfPredicate
00444 {
00445 Pred pred;
00446
00447 PredicateWrapper(Pred pred)
00448 : pred(pred) {}
00449
00450 virtual bool should_delete(Value const& v)
00451 {
00452 return pred(v);
00453 };
00454 };
00455
00456
00457 public:
00458 typedef std::vector<size_t> MarshalOps;
00459
00460 Container(std::string const& kind, std::string const& name, size_t size, Type const& of);
00461
00462 std::string kind() const;
00463 virtual void init(void* ptr) const = 0;
00464 virtual void destroy(void* ptr) const = 0;
00465 virtual bool visit(void* ptr, ValueVisitor& visitor) const = 0;
00466
00472 virtual bool isRandomAccess() const;
00473
00482 virtual Typelib::Value getElement(void* ptr, int idx) const;
00483
00492 virtual void setElement(void* ptr, int idx, Typelib::Value value) const;
00493
00496 virtual void clear(void* ptr) const = 0;
00497
00500 virtual void push(void* ptr, Value v) const = 0;
00501
00506 virtual bool erase(void* ptr, Value v) const = 0;
00507
00513 virtual bool compare(void* ptr, void* other) const = 0;
00514
00518 virtual void copy(void* dst, void* src) const = 0;
00519
00524 virtual long getNaturalSize() const = 0;
00525
00526 template<typename Pred>
00527 void delete_if(void* ptr, Pred pred) const
00528 {
00529 PredicateWrapper<Pred> predicate(pred);
00530 delete_if_impl(ptr, predicate);
00531 }
00532
00533 virtual size_t getElementCount(void const* ptr) const = 0;
00534
00552 virtual MarshalOps::const_iterator dump(
00553 void const* container_ptr, size_t element_count,
00554 ValueOps::OutputStream& stream,
00555 MarshalOps::const_iterator const begin, MarshalOps::const_iterator const end) const = 0;
00556
00573 virtual MarshalOps::const_iterator load(
00574 void* container_ptr, size_t element_count,
00575 ValueOps::InputStream& stream,
00576 MarshalOps::const_iterator const begin, MarshalOps::const_iterator const end) const = 0;
00577
00578 typedef Container const& (*ContainerFactory)(Registry& r, std::list<Type const*> const& base_type);
00579 typedef std::map<std::string, ContainerFactory> AvailableContainers;
00580
00581 static AvailableContainers availableContainers();
00582 static void registerContainer(std::string const& name, ContainerFactory factory);
00583 static Container const& createContainer(Registry& r, std::string const& name, Type const& on);
00584 static Container const& createContainer(Registry& r, std::string const& name, std::list<Type const*> const& on);
00585
00586 protected:
00587 virtual bool do_compare(Type const& other, bool equality, RecursionStack& stack) const;
00588 virtual ContainerFactory getFactory() const = 0;
00589 Type* do_merge(Registry& registry, RecursionStack& stack) const;
00590
00591 private:
00592 static AvailableContainers* s_available_containers;
00593 };
00594
00595 struct TypeException : public std::runtime_error
00596 {
00597 TypeException(std::string const& msg) : std::runtime_error(msg) { }
00598 };
00599
00600 struct BadCategory : public TypeException
00601 {
00602 Type::Category const found;
00603 int const expected;
00604
00605 BadCategory(Type::Category found, int expected);
00606 };
00607
00608 struct NullTypeFound : public TypeException
00609 {
00610 NullTypeFound();
00611 };
00612 };
00613
00614 #endif
00615