From 264d69e0c9653d9e9ad6680dcbc70c6c9d60a34a Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 13 Feb 2007 09:33:35 +0000 Subject: [PATCH] From Mike Wittman, support for reference parameters --- include/osgIntrospection/ExtendedTypeInfo | 123 ++++++++++++++++++++++ include/osgIntrospection/type_traits | 63 +++++++++++ src/osgIntrospection/Reflector.cpp | 11 ++ 3 files changed, 197 insertions(+) create mode 100644 include/osgIntrospection/ExtendedTypeInfo create mode 100644 include/osgIntrospection/type_traits create mode 100644 src/osgIntrospection/Reflector.cpp diff --git a/include/osgIntrospection/ExtendedTypeInfo b/include/osgIntrospection/ExtendedTypeInfo new file mode 100644 index 000000000..000fd69b4 --- /dev/null +++ b/include/osgIntrospection/ExtendedTypeInfo @@ -0,0 +1,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 +#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 diff --git a/include/osgIntrospection/type_traits b/include/osgIntrospection/type_traits new file mode 100644 index 000000000..e4eb26ad5 --- /dev/null +++ b/include/osgIntrospection/type_traits @@ -0,0 +1,63 @@ +/* -*-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_TYPE_TRAITS_ +#define OSGINTROSPECTION_TYPE_TRAITS_ + + +/// is_reference is a compile-time template predicate to determine if a +/// type is a reference type. +template +struct is_reference +{ + static const bool value = false; +}; + +template +struct is_reference +{ + static const bool value = true; +}; + + +/// is_const_reference is a compile-time template predicate to determine +/// if a type is a const reference type. +template +struct is_const_reference +{ + static const bool value = false; +}; + +template +struct is_const_reference +{ + static const bool value = true; +}; + + +/// remove_pointer is a compile-time template type mapper that produces +/// the input type, but with any pointer modifier removed. +template +struct remove_pointer +{ + typedef T type; +}; + +template +struct remove_pointer +{ + typedef T type; +}; + + +#endif diff --git a/src/osgIntrospection/Reflector.cpp b/src/osgIntrospection/Reflector.cpp new file mode 100644 index 000000000..a133d9423 --- /dev/null +++ b/src/osgIntrospection/Reflector.cpp @@ -0,0 +1,11 @@ +#include + +namespace osgIntrospection +{ + template<> + void Reflector::init_reference_types() + { + // Avoid trying to register void & / const void &, which are + // illegal types. + } +}