/usr/include/BALL/COMMON/rtti.h is in libball1.4-dev 1.4.1+20111206-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | // -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
#ifndef BALL_COMMON_RTTI_H
#define BALL_COMMON_RTTI_H
#ifndef BALL_CONFIG_CONFIG_H
# include <BALL/CONFIG/config.h>
#endif
#ifndef BALL_COMMON_H
# include <BALL/common.h>
#endif
#include <string>
#include <typeinfo>
using std::string;
namespace BALL
{
# ifdef __GNUC__
// EGCS produces a nearly unreadable name mangling that requires
// further interpretation
namespace GNUDemangling
{
BALL_EXPORT string demangle(string s);
}
# endif
/** Returns a unique name for a class.
This name contains no blanks. It is usually derived by substituting all
blanks in the name (as returned by RTTI::getName()) with underscores ("_").
In the case of <tt>gcc</tt>, however a name demangling decodes the string first.
This function is needed for object persistence.
@param t the <tt>type_info</tt> structure as returned by <tt>typeid</tt>
@return string the coverted class name
\ingroup Common
*/
BALL_EXPORT string streamClassName(const std::type_info& t);
/** Simplified RunTime Type Identification.
ANSI C++ provides support for runtime type identification (RTTI). However, the support
is very basic. The template functions of the RTTI namespace provide a more
readable support for RTTI. It defines
predicates such as \link BALL::RTTI::isKindOf isKindOf \endlink that simplify tests on the hereditary relationship of
different objects. \par
To use the RTTI template functions, parametrize it with the type you are interested in.
For example, to find out whether a given molecule is a protein, the following code
can be used: \par
\code
Molecule& m =...;
...
if (RTTI::isKindOf<Protein>(m))
{
// perform some protein specific operations
} else {
// this is only a molecule...
}
\endcode
\ingroup Common
*/
namespace RTTI
{
/** Return a reference to a static default instance of the corresponding class.
This method is basically intended to provide a default object for certain operations
that require an instance of a certain class without really using this instance.
It is mainly used inside the RTTI class.
*/
template <typename T>
const T& getDefault()
{
static T t;
return t;
}
/** Return a void pointer to a new instance of the class.
Use this method to provide an easy factory for objects of a certain class.
The main use of this function lies in object persistence. The \link PersistenceManager PersistenceManager \endlink
needs a function for the dynamic creation of objects.
*/
template <typename T>
void* getNew()
{
return static_cast<void*>(new T);
}
/** Return the name of the class.
This method returns the name of the class as given by <tt>typeid(\<class instance\>.name())</tt>.
No additional name demangling and whitespace substitution are performed.
*/
template <typename T>
const char* getName()
{
return typeid(T).name();
}
/** Return a void pointer that is unique for each class.
*/
template <typename T>
void* getClassID()
{
static char dummy;
return (void*)&dummy;
}
/** Return the demangled class name.
The class name is demangled (as far as possible) and in the
resulting string blanks are substituted by underscores, so the
name can be read from a stream as one string.
The typical usage is something like
\code
String class_name = RTTI::getStreamName<Residue>();
...
\endcode
*/
template <typename T>
const char* getStreamName()
{
// define portable names for the portable
// types (some platforms use Size, some unsigned int,
// SUN CC even unsigned for the Size type)
if ((typeid(T) == typeid(Size))
|| (typeid(T) == typeid(Position))
|| (typeid(T) == typeid(HashIndex))
|| (typeid(T) == typeid(Property))
|| (typeid(T) == typeid(Handle)))
{
return "BALL::Size";
}
if ((typeid(T) == typeid(Index))
|| (typeid(T) == typeid(ErrorCode))
|| (typeid(T) == typeid(Distance)))
{
return "BALL::Index";
}
if (typeid(T) == typeid(::std::string))
{
return "::std::string";
}
if (typeid(T) == typeid(LongSize))
{
return "BALL::LongSize";
}
if (typeid(T) == typeid(bool))
{
return "bool";
}
if (typeid(T) == typeid(float))
{
return "float";
}
if (typeid(T) == typeid(char))
{
return "char";
}
if (typeid(T) == typeid(unsigned char))
{
return "unsigned_char";
}
if (typeid(T) == typeid(double))
{
return "double";
}
static string s("");
static bool is_set = false;
if (!is_set)
{
is_set = true;
s = streamClassName(typeid(T));
}
return s.c_str();
}
/** Return true if <tt>u</tt> is a kind of T.
If <tt>u</tt> is an instance of a class derived from T,
this predicate returns true: \par
\code
Protein p;
// return true, since Protein is derived from Molecule
bool is_molecule = RTTI::isKindOf<Molecule>(p);
\endcode
*/
template <typename T, typename U>
bool isKindOf(const U& u)
{
return (0 != dynamic_cast<const T*>(&u));
}
/** Cast an object to a specialized class.
<b>Example:</b> \par
\code
Composite* composite = ...;
...
// check whether the composite is also an atom
if (RTTI::isKindOf<Atom>(composite))
{
// perform some atom specific actions
Atom* atom = RTTI::castTo<Atom>(*composite);
...
atom->setCharge(0);
...
}
\endcode
*/
template <typename T, typename U>
T* castTo(const U& u)
{
return const_cast<T*>(dynamic_cast<const T*>(&u));
}
/** Return <b>true</b> if a given object is an instance of a given class.
If <tt>u</tt> is an instance of <tt>T</tt>, this predicate returns <b>true</b>.
If <tt>u</tt> is an instance of a class that is derived from <tt>T</tt> or
a base class of <tt>T</tt>, it returns false.
*/
template <typename T, typename U>
bool isInstanceOf(const U& u)
{
return (typeid(u) == typeid(T));
}
} // namespace RTTI
} // namespace BALL
#endif // BALL_COMMON_RTTI_H
|