rttr::wrapper_mapper< T > Struct Template Reference

The wrapper_mapper class is a class template to access different wrapper types via one common interface. More...

#include <wrapper_mapper.h>

Public Types

using type = T
 
using wrapped_type = typename wrapper_type::encapsulated_type
 

Static Public Member Functions

template<typename U >
static T< U > convert (const type &source, bool &ok)
 
static type create (const wrapped_type &value)
 
static wrapped_type get (const type &obj)
 

Detailed Description

template<typename T>
struct rttr::wrapper_mapper< T >

The wrapper_mapper class is a class template to access different wrapper types via one common interface.

A wrapper type is a class which encapsulate an instance of another type. This are for instance smart pointer classes, e.g. std::shared_ptr<T> or std::unique_ptr<T>. Out of the box, RTTR recognize following wrapper types:

  • std::shared_ptr<T>
  • std::reference_wrapper<T>
  • std::weak_ptr<T>
  • std::unique_ptr<T>

Custom wrapper types

In order to work with custom wrapper types, its required to specialize the class wrapper_mapper<T>. Therefore you have to provide two nested type aliases:

  1. using wrapped_type = typename T::encapsulated_type;
  2. using type = T

And three functions:

  1. static wrapped_type get(const T& obj);
  2. static T create(wrapped_type& obj); (Optional)
  3. static T<U> convert(const type& source, bool& ok); (Optional)
Remarks
The create() function is optional. When no one is provided, then it will be not possible to convert from the wrapped type to the wrapper class from inside a variant. The convert() function is also optional. When no one is provided, you cannot use the rttr::type::register_wrapper_converter_for_base_classes<T>() function. For the wrapper classes: std::shared_ptr<T> and std::reference_wrapper<T> default conversion functions are included.
See also
variant::convert()

Following code example illustrates how to add a specialization:

// custom_type.h
template<typename T>
class custom_type
{
public:
custom_type(T& obj) : m_data(std::addressof(obj)) {}
custom_type(T) : m_data(nullptr) {}
T& get_data() { return *m_value; }
private:
T* m_data;
};
// the best place for the specialization, is in the same header file like the type itself
namespace rttr
{
template<typename T>
struct wrapper_mapper<custom_type<T>>
{
using wrapped_type = decltype(std::declval<custom_type<T>>().get_data());
using type = custom_type<T>;
inline static wrapped_type get(const type& obj)
{
return obj.get_data();
}
inline static type create(const wrapped_type& value)
{
return custom_type<T>(value);
}
template<typename U>
inline static custom_type<U> convert(const type& source, bool& ok)
{
if (auto obj = rttr_cast<typename custom_type<U>::wrapped_type*>(&source.get_data()))
{
ok = true;
return custom_type<U>(*obj);
}
else
{
ok = false;
return custom_type<U>();
}
}
};
} // end namespace rttr
Remarks
It is very important that the type alias for wrapped_type is the actual return type of the getter function. Make also sure you put your specialization inside the namespace rttr. The best place for this code, is below the declaration of your wrapper type. When this is not possible, include your specialization code before registering your types to RTTR.

Member Typedef Documentation

template<typename T >
using rttr::wrapper_mapper< T >::type = T
template<typename T >
using rttr::wrapper_mapper< T >::wrapped_type = typename wrapper_type::encapsulated_type

Member Function Documentation

template<typename T >
template<typename U >
static T<U> rttr::wrapper_mapper< T >::convert ( const type source,
bool &  ok 
)
inlinestatic
template<typename T >
static type rttr::wrapper_mapper< T >::create ( const wrapped_type value)
inlinestatic
template<typename T >
static wrapped_type rttr::wrapper_mapper< T >::get ( const type obj)
inlinestatic

The documentation for this struct was generated from the following file: