OpenSceneGraph/include/osgIntrospection/ExtendedTypeInfo
2007-02-13 09:33:35 +00:00

124 lines
4.4 KiB
C++

/* -*-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 <typeinfo>
#include <string>
#include <osgIntrospection/type_traits>
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 <typename T>
osgIntrospection::ExtendedTypeInfo
extended_typeid(T)
{
return osgIntrospection::ExtendedTypeInfo(typeid(T),
is_reference<T>::value,
is_const_reference<T>::value);
}
/// extended_typeid works like typeid, but returns an ExtendedTypeInfo. This
/// version operates on types, which must be specified as a template parameter.
template <typename T>
osgIntrospection::ExtendedTypeInfo
extended_typeid()
{
return osgIntrospection::ExtendedTypeInfo(typeid(T),
is_reference<T>::value,
is_const_reference<T>::value);
}
#endif