/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ #ifndef OSGINTROSPECTION_EXTENDEDTYPEINFO_ #define OSGINTROSPECTION_EXTENDEDTYPEINFO_ #include #include #include namespace osgIntrospection { /// This class is a wrapper for std::type_info that also records whether /// a type is a reference or const reference. It permits osgIntrospection /// to make use of reference information that is ignored by typeid(), and /// to generate reference types based on it. The ExtendedTypeInfo for a /// class can be produced via the extended_typeid() functions, analogous /// to typeid(). /// class ExtendedTypeInfo { public: ExtendedTypeInfo(const std::type_info &ti, bool isReference, bool isConstReference) : _ti(&ti), _is_reference(isReference), _is_const_reference(isConstReference) { } /// Orders ExtendedTypeInfo based first on std::type_info, then on /// reference, then on const reference. Note that we can't rely on /// default pointer comparison for std::type_info because it is not /// guaranteed that &typeid(T) always returns the same pointer for a /// given T (thanks Andrew Koenig). bool operator<(const ExtendedTypeInfo &other) const { if (_ti->before(*other._ti)) return true; else if (other._ti->before(*_ti)) return false; else if (_is_reference < other._is_reference) return true; else if (other._is_reference < _is_reference) return false; else return _is_const_reference < other._is_const_reference; } /// Returns true if *this and other are the same type. bool operator==(const ExtendedTypeInfo &other) const { return (*_ti == *other._ti && _is_reference == other._is_reference && _is_const_reference == other._is_const_reference); } /// Gets the std::type_info object for this type. const std::type_info &getStdTypeInfo() const { return *_ti; } /// Returns true if this type is a reference or const reference. bool isReference() const { return _is_reference; } /// Returns true if this type is a const reference. bool isConstReference() const { return _is_const_reference; } /// Returns the name of this type, based on the std::type_info name. std::string name() const { if (_is_const_reference) return std::string("const ") + _ti->name() + " &"; else if (_is_reference) return std::string(_ti->name()) + " &"; else return _ti->name(); } private: const std::type_info *_ti; bool _is_reference; bool _is_const_reference; }; } /// extended_typeid works like typeid, but returns an ExtendedTypeInfo. This /// version operates on expressions. template osgIntrospection::ExtendedTypeInfo extended_typeid(T) { return osgIntrospection::ExtendedTypeInfo(typeid(T), is_reference::value, is_const_reference::value); } /// extended_typeid works like typeid, but returns an ExtendedTypeInfo. This /// version operates on types, which must be specified as a template parameter. template osgIntrospection::ExtendedTypeInfo extended_typeid() { return osgIntrospection::ExtendedTypeInfo(typeid(T), is_reference::value, is_const_reference::value); } #endif