Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- namespace ac
- {
- /// \class Class
- /// \brief Describes a class
- ///
- /// A simple class that describes another class.
- ///
- /// \author Miguel Martin
- class Class
- {
- public:
- explicit Class(const char* name = 0)
- : _name(name)
- {
- }
- /// \return The name of the class
- const char* getName() const
- {
- return _name;
- }
- /// Compares two class objects to see if they are equal
- /// \param c The class you wish to compare with
- /// \return true if the two classes are equal
- bool operator==(const Class& c) const
- {
- return (this == &c);
- }
- /// Compares two class objects to see if they are equal
- /// \param c The class you wish to compare with
- /// \return true if the two classes are not equal
- bool operator!=(const Class& c) const
- {
- return !operator==(c);
- }
- private:
- /// The name of the class
- const char* _name;
- };
- /// Converts something to a string
- # define AC_CONVERT_TO_STR(x) #x
- /// Marks a class as identifiable
- /// You must place this macro inside the class's defintion,
- /// if you wish to identfy a class
- ///
- /// For example:
- /// class Example
- /// {
- /// AC_IDENTFIABLE(Example)
- /// };
- # define AC_IDENTIFIABLE(x) \
- public:\
- static const ac::Class& GetClass() \
- { \
- static const ac::Class instance(AC_CONVERT_TO_STR(x)); \
- return instance; \
- } \
- \
- virtual const ac::Class& getClass() const \
- { \
- return GetClass(); \
- } \
- private:
- namespace util
- {
- /// \struct ClassGetter
- /// \brief A utility class that gets a class of an object
- ///
- /// This is used so that it can be overloaded with pointer types.
- ///
- /// \author Miguel Martin
- template <typename T>
- struct ClassGetter
- {
- public:
- static const Class& Get()
- {
- return T::GetClass();
- }
- static const Class& Get(const T* obj)
- {
- return obj->getClass();
- }
- };
- template <typename T>
- struct ClassGetter <T*>
- {
- public:
- static const Class& Get()
- {
- return T::GetClass();
- }
- static const Class& Get(const T* obj)
- {
- return obj->getClass();
- }
- };
- /// \note This may or may NOT work on every platform/compiler
- /// \param obj A pointer to an object with a v-table
- /// \return A pointer to the v-table of the object
- void* get_vtable(void *obj)
- {
- return *(reinterpret_cast<void **>(obj));
- }
- }
- /// Compares two objects and tells whether they are from the same class
- /// \param x The first object that you wish to compare with
- /// \param y The second object that you wish to compare with
- /// \return true if the two objects are of the same type
- template <typename X, typename Y>
- bool isSameType(const X& x, const Y& y)
- {
- return util::ClassGetter<X>::Get(x) == util::ClassGetter<Y>::Get(y);
- }
- /// Tells whether an object is a specific type
- /// \tparam Type The type of class that you wish to check that an object is
- /// \return true if the object is of the class Type
- template <class Type, class T>
- bool isType(const T& obj)
- {
- return util::ClassGetter<Type>::Get() == util::ClassGetter<T>::Get(obj);
- }
- /// Compares two polymorphic objects to tell whether they are equal types
- /// \note
- /// If you have two objects, that do NOT declare the macro AC_IDENTIFIABLE in
- /// their class defintion, then perhaps you would want to use this method.
- /// This may or may NOT work on every platform/compiler.
- /// \param obj1 The first object you wish to compare
- /// \param obj2 The second object you wish to compare
- /// \return true if the two objects are of the same type
- bool isSameType(void* obj1, void* obj2)
- {
- return util::get_vtable(obj1) == util::get_vtable(obj2);
- }
- }
- class Base
- {
- AC_IDENTIFIABLE(Base)
- };
- class Derived
- : public Base
- {
- AC_IDENTIFIABLE(Derived)
- };
- int main(int argc, char** argv)
- {
- using namespace ac;
- Base* obj1 = new Derived;
- Base* obj2 = new Derived;
- std::cout << std::boolalpha;
- std::cout << "void* casts: " << isSameType((void*)obj1, (void*)obj2) << '\n';
- std::cout << "is obj1 a Base ? " << isType<Base>(obj1) << '\n';
- std::cout << "is obj2 a Derived ? " << isType<Derived>(obj2) << '\n';
- std::cout << "are obj1 and obj2 from the same class? " << isSameType(obj1, obj2) << '\n';
- delete obj1;
- delete obj2;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement