This shortcut tutorial will show you all basic information to use RTTR.
Class declaration
Suppose you have a class called node which you want to introspect with RTTR.
#include <rttr/type>
namespace ns_3d
{
class node
{
public:
node(std::string name, node* parent = nullptr);
virtual ~node();
void set_name(const std::string& name);
const std::string& get_name() const;
std::vector<node*> get_children() const;
void set_visible(bool visible, bool cascade = true);
virtual void render();
private:
node* m_parent;
std::string m_name;
std::vector<node*> m_children;
};
}
#define RTTR_REGISTRATION_FRIEND
Place this macro inside a class, when you need to reflect properties, methods or constructors which a...
Definition registration.h:793
#define RTTR_ENABLE(...)
This macro is necessary in order to retrieve type information about the inheritance graph of a class.
Definition rttr_enable.h:85
The standard include file of rttr is: <rttr/type>
Remark the two added macros: RTTR_ENABLE() and RTTR_REGISTRATION_FRIEND. They are optional.
However, when you use class hierarchies you should add to every class: RTTR_ENABLE().
When you want to reflect private data of a class, add: RTTR_REGISTRATION_FRIEND.
Registration
Now comes the registration part, this is usually done in the corresponding source file.
#include <rttr/registration>
{
using namespace ns_3d;
(
)
.property("name", &node::get_name, &node::set_name)
(
metadata(
"TOOL_TIP",
"Set the name of node.")
)
.property_readonly("children", &node::get_children)
.method("set_visible", &node::set_visible)
(
)
.
method(
"render", &node::render)
;
}
The method class provides several meta information about a method and can be invoked.
Definition method.h:121
The property class provides several meta information about a property and gives read/write access to ...
Definition property.h:117
The class_ is used to register classes to RTTR.
Definition registration.h:130
bind< detail::ctor, Class_Type, acc_level, Args... > constructor(acc_level level=acc_level())
Register a constructor for this class type with or without arguments.
static const detail::private_access private_access
This variable can be used to specify during registration of a class member the access level: private.
Definition registration.h:434
Definition access_levels.h:34
detail::default_args< TArgs... > default_arguments(TArgs &&...args)
The default_arguments function should be used add default arguments, for constructors or a methods du...
detail::metadata metadata(variant key, variant value)
The metadata function can be used to add additional meta data information during the registration pro...
detail::parameter_names< detail::decay_t< TArgs >... > parameter_names(TArgs &&...args)
The parameter_names function should be used add human-readable names of the parameters,...
#define RTTR_REGISTRATION
Use this macro to automatically register your reflection information to RTTR before main is called.
Definition registration.h:745
static const detail::as_std_shared_ptr as_std_shared_ptr
The as_std_shared_ptr policy will create an instance of a class through std::make_shared<T>.
Definition policy.h:271
The standard include file for registration types in rttr is: <rttr/registration>
Include this file only when you want to register something. The registration class is here the entry point. This registration process creates internally wrapper classes, which store for example function pointers or object pointers of the specific class. For these pointers you have to provide the data manually.
Yeah, and that's it. Now you can use RTTR to retrieve this information.
Basic usage
#include <rttr/type>
#include <iostream>
int main(int argc, char *argv[])
{
prop.
set_value(var, std::string(
"A New Name"));
std::cout << prop.get_value(var).to_string() << "\n";
std::cout << "MetaData TOOL_TIP: " << prop.get_metadata("TOOL_TIP").to_string() << "\n";
std::cout << std::boolalpha <<
"invoke of method 'set_visible' was successfully: " << ret.
is_valid() <<
"\n\n";
std::cout << "'node' properties:" << "\n";
{
std::cout << " name: " << prop.get_name() << "\n";
std::cout << " type: " << prop.get_type().get_name() << "\n";
}
std::cout << "\n";
std::cout << "'node' methods:" << "\n";
{
std::cout <<
" name: " << meth.
get_name();
{
std::cout << " param " << info.get_index() << ": name: "<< info.get_name() << "\n";
}
}
return 0;
}
string_view get_name() const noexcept
Returns the name of this method.
string_view get_signature() const noexcept
Returns the signature of this method as readable string.
array_range< parameter_info > get_parameter_infos() const noexcept
Returns an ordered range of parameter_info objects, which matches the signature of the method.
variant invoke(instance object) const
Invokes the method represented by the current instance object.
bool set_value(instance object, argument arg) const
Set the property of the given instance object to the given value arg.
The type class holds the type information for any arbitrary object.
Definition type.h:171
string_view get_name() const noexcept
Returns the unique and human-readable name of the type.
method get_method(string_view name) const noexcept
Returns a method with the name name.
array_range< property > get_properties() const noexcept
Returns a range of all registered public properties for this type and all its base classes.
static type get_by_name(string_view name) noexcept
Returns the type object with the given name name.
array_range< method > get_methods() const noexcept
Returns a range of all registered public methods for this type and all its base classes.
variant create(std::vector< argument > args=std::vector< argument >()) const
Creates an instance of the current type, with the given arguments args for the constructor.
property get_property(string_view name) const noexcept
Returns a property with the name name.
The variant class allows to store data of any type and convert between these types transparently.
Definition variant.h:198
type get_type() const
Returns the type object of underlying data.
bool is_valid() const
Returns true if this variant is valid, that means the variant is holding some data.
Remark, that there is actual no include of node.h. See the output below:
Output
class std::shared_ptr<class ns_3d::node>
A New Name
MetaData TOOL_TIP: Set the name of node.
invoke of method 'set_visible' was successfully: true
'node' properties:
name: name
type: std::string
name: parent
type: ns_3d::node*
name: children
type: class std::vector<class ns_3d::node *,class std::allocator<class ns_3d::node *> >
'node' methods:
name: set_visible signature: set_visible( bool, bool )
param 0: name: visible
param 1: name: cascade
name: render signature: render( )
Derived classes
Suppose you create now from node a derived class called mesh.
#include <rttr/type>
class mesh : public node
{
public:
static std::shared_ptr<mesh> create_mesh(std::string file_name);
virtual void render();
enum class render_mode
{
POINTS,
WIREFRAME,
SOLID
};
void set_render_mode(render_mode mode);
render_mode get_render_mode() const;
private:
mesh(std::string name, node* parent = nullptr);
};
Now you put in RTTR_ENABLE() the name of the base class, in this case: node.
Registration part
{
using namespace ns_3d;
.property("render_mode", &mesh::get_render_mode, &mesh::set_render_mode)
.enumeration<mesh::render_mode>("ns_3d::render_mode")
(
value(
"POINTS", mesh::render_mode::POINTS),
value(
"WIREFRAME", mesh::render_mode::WIREFRAME),
value(
"SOLID", mesh::render_mode::SOLID)
);
}
detail::enum_data< Enum_Type > value(string_view, Enum_Type value)
The value function should be used to add a mapping from enum name to value during the registration pr...
Remark that it is not necessary to register again the render() method.
Basic Usage
#include <rttr/type>
#include <iostream>
#include "mesh.h"
int main(int argc, char *argv[])
{
std::shared_ptr<ns_3d::node> obj = ns_3d::mesh::create_mesh("House.obj");
std::cout <<
type::get(obj).get_name() <<
"\n";
std::cout <<
type::get(obj).get_wrapped_type().get_name() <<
"\n";
std::cout <<
type::get(*obj.get()).get_name() <<
"\n";
std::cout << "\n";
std::cout << "'mesh' properties:" << "\n";
{
std::cout << " name: " << prop.get_name() << "\n";
std::cout << " type: " << prop.get_type().get_name() << "\n";
}
bool ret = prop.set_value(obj, ns_3d::mesh::render_mode::SOLID);
std::cout << "\n";
std::shared_ptr<ns_3d::mesh> obj_derived = std::dynamic_pointer_cast<ns_3d::mesh>(obj);
std::cout << std::boolalpha <<
"invoke of method 'render' was successfully: " << var.
is_valid() <<
"\n";
}
type get_declaring_type() const noexcept
Returns the class that declares this method.
static type get() noexcept
Returns a type object for the given template type T.
See the output below:
Output
class std::shared_ptr<class ns_3d::node>
ns_3d::node*
ns_3d::mesh
'mesh' properties:
name: name
type: std::string
name: parent
type: ns_3d::node*
name: children
type: class std::vector<class ns_3d::node *,class std::allocator<class ns_3d::node *> >
name: render_mode
type: ns_3d::render_mode
ns_3d::node
invoke of method 'render' was successfully: true
That's it.
However, in order to see all the possibilities of RTTR, it is recommend to go through the in-depth tutorial: Start Tutorial