1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
/* -*-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
|