124 lines
4.4 KiB
Plaintext
124 lines
4.4 KiB
Plaintext
|
/* -*-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
|