Skip to content

Commit

Permalink
Support pointer of pointers.
Browse files Browse the repository at this point in the history
  • Loading branch information
cfis committed Nov 16, 2024
1 parent ee283ba commit bacc7bc
Showing 1 changed file with 79 additions and 0 deletions.
79 changes: 79 additions & 0 deletions rice/Data_Object.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,52 @@ namespace Rice::detail
Return* returnInfo_ = nullptr;
};

template <typename T>
class To_Ruby<T**>
{
public:
To_Ruby() = default;

explicit To_Ruby(Return* returnInfo) : returnInfo_(returnInfo)
{
}

VALUE convert(T** data)
{
if (data)
{
// Note that T could be a pointer or reference to a base class while data is in fact a
// child class. Lookup the correct type so we return an instance of the correct Ruby class
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType(*data);
bool isOwner = this->returnInfo_ && this->returnInfo_->isOwner();
return detail::wrap(rubyTypeInfo.first, rubyTypeInfo.second, data, isOwner);
}
else
{
return Qnil;
}
}

VALUE convert(const T** data)
{
if (data)
{
// Note that T could be a pointer or reference to a base class while data is in fact a
// child class. Lookup the correct type so we return an instance of the correct Ruby class
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType(*data);
bool isOwner = this->returnInfo_ && this->returnInfo_->isOwner();
return detail::wrap(rubyTypeInfo.first, rubyTypeInfo.second, data, isOwner);
}
else
{
return Qnil;
}
}

private:
Return* returnInfo_ = nullptr;
};

template<typename T>
class To_Ruby<Data_Object<T>>
{
Expand Down Expand Up @@ -471,6 +517,39 @@ namespace Rice::detail
}
};

template<typename T>
class From_Ruby<T**>
{
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
"Data_Object cannot be used with fundamental types");
public:
Convertible is_convertible(VALUE value)
{
switch (rb_type(value))
{
case RUBY_T_DATA:
return Data_Type<T>::is_descendant(value) ? Convertible::Exact : Convertible::None;
break;
default:
return Convertible::None;
}
}

T** convert(VALUE value)
{
using Intrinsic_T = intrinsic_type<T>;

if (value == Qnil)
{
return nullptr;
}
else
{
return detail::unwrap<Intrinsic_T*>(value, Data_Type<T>::ruby_data_type());
}
}
};

template<typename T>
class From_Ruby<Data_Object<T>>
{
Expand Down

0 comments on commit bacc7bc

Please sign in to comment.