OpenSceneGraph/include/osgIntrospection/variant_cast

99 lines
3.7 KiB
Plaintext
Raw Normal View History

2006-07-18 23:21:48 +08:00
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2005-04-29 18:06:50 +08:00
*
* 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.
*/
//osgIntrospection - Copyright (C) 2005 Marco Jez
#ifndef OSGINTROSPECTION_VARIANT_CAST_
#define OSGINTROSPECTION_VARIANT_CAST_
#include <osgIntrospection/Value>
#include <osgIntrospection/ReaderWriter>
#include <sstream>
namespace osgIntrospection
{
2005-03-14 17:28:31 +08:00
/// Tries to convert an instance of Value to an object of type T.
/// If T is a plain type or a pointer type (either const or non-const),
/// and it matches the type of the value contained in v, then the actual
/// value of type T is returned. If T is a [const] reference type, and
/// its base (non reference) type matches the internal value's type,
/// then a [const] reference to the internal value is returned.
/// If none of the above conditions are met, a conversion is attempted
/// as described in Value::convert() and then variant_cast is called again
/// with the converted value as parameter.
/// If the conversion can't be completed, an exception is thrown.
/// Conversions that attempt to make a const pointer non-const will fail.
template<typename T> T variant_cast(const Value& v)
2005-03-14 17:28:31 +08:00
{
// return value
Value::Instance<T> *i = dynamic_cast<Value::Instance<T> *>(v._inbox->inst_);
if (i) return i->_data;
2005-03-14 17:28:31 +08:00
// return reference to value
i = dynamic_cast<Value::Instance<T> *>(v._inbox->_ref_inst);
if (i) return i->_data;
2005-03-14 17:28:31 +08:00
// return const reference to value
i = dynamic_cast<Value::Instance<T> *>(v._inbox->_const_ref_inst);
if (i) return i->_data;
2005-03-14 17:28:31 +08:00
// try to convert v to type T and restart
return variant_cast<T>(v.convertTo(typeof(T)));
}
/// Returns true if the Value passed as parameter can't be casted to
/// the specified type without a (potentially slow) conversion.
/// Returns false otherwise.
template<typename T> bool requires_conversion(const Value& v)
{
// direct value
Value::Instance<T> *i = dynamic_cast<Value::Instance<T> *>(v._inbox->inst_);
if (i) return false;
// reference to value
i = dynamic_cast<Value::Instance<T> *>(v._inbox->_ref_inst);
if (i) return false;
// const reference to value
i = dynamic_cast<Value::Instance<T> *>(v._inbox->_const_ref_inst);
if (i) return false;
return true;
}
2005-03-14 17:28:31 +08:00
/// Returns a typed pointer to the data contained in a Value
/// instance. If the value's type is not identical to type T,
/// a null pointer is returned.
template<typename T> T* extract_raw_data(Value& v)
2005-03-14 17:28:31 +08:00
{
Value::Instance<T>* i = dynamic_cast<Value::Instance<T> *>(v._inbox->inst_);
if (i) return &i->_data;
2005-03-14 17:28:31 +08:00
return 0;
}
/// Returns a typed pointer to the data contained in a const Value
/// instance. If the value's type is not identical to type T, a
/// null pointer is returned.
template<typename T> const T* extract_raw_data(const Value& v)
2005-03-14 17:28:31 +08:00
{
Value::Instance<T>* i = dynamic_cast<Value::Instance<T> *>(v._inbox->inst_);
if (i) return &i->_data;
2005-03-14 17:28:31 +08:00
return 0;
}
}
#endif