Skip to content

Instantly share code, notes, and snippets.

@slipher
Last active April 5, 2020 02:57
Show Gist options
  • Save slipher/855c9be0634b9cb17cf680856baf697e to your computer and use it in GitHub Desktop.
Save slipher/855c9be0634b9cb17cf680856baf697e to your computer and use it in GitHub Desktop.
template<typename DST, typename SRC, typename X, typename A>
struct make_property_chain_I_1 {
static void ExportThunk(const Callback<void(DST)> &self, SRC value) {
PropertyImpl<SRC, DST>::Export(value, self);
}
static void Export(const X &self, const Callback<void(DST)> &returnz) {
A::Get::thunk_(self, ConstReferenceCaller<Callback<void(DST)>, void(SRC), ExportThunk>(returnz));
}
static void Import(X &self, DST value) {
SRC out;
PropertyImpl<SRC, DST>::Import(out, value);
A::Set::thunk_(self, out);
}
};
template<class I_Outer, class I_Inner>
Property<detail::propertyimpl_other<I_Outer>> make_property_chain(detail::propertyimpl_self<I_Inner> &it) {
using DST = detail::propertyimpl_other<I_Outer>;
using SRC = detail::propertyimpl_self<I_Outer>;
using X = detail::propertyimpl_self<I_Inner>;
using A = property_impl<I_Inner>;
using I = make_property_chain_I_1<DST, SRC, X, A>;
return make_property<PropertyAdaptor<X, DST, I>>(it);
}
template<typename DST, typename SRC, typename A>
struct make_property_chain_I_2 {
static void ExportThunk(const Callback<void(DST)> &self, SRC value) {
PropertyImpl<SRC, DST>::Export(value, self);
}
static void Export(const Callback<void(DST)> &returnz) {
A::Get::thunk_(nullptr, ConstReferenceCaller<Callback<void(DST)>, void(SRC), ExportThunk>(returnz));
}
static void Import(DST value) {
SRC out;
PropertyImpl<SRC, DST>::Import(out, value);
A::Set::thunk_(nullptr, out);
}
};
template<class I_Outer, class I_Inner>
Property<detail::propertyimpl_other<I_Outer>> make_property_chain() {
using DST = detail::propertyimpl_other<I_Outer>;
using SRC = detail::propertyimpl_self<I_Outer>;
using A = property_impl_free<I_Inner>;
using I = make_property_chain_I_2<DST, SRC, A>;
return make_property<PropertyAdaptorFree<DST, I>>();
}
template<class Widget, class Self, class T, class native>
struct AddDataCustom_Wrapper {
static void Export(const native &self, const Callback<void(T)> &returnz) {
native *p = &const_cast<native &>(self);
auto widget = Self::from(p);
Widget::Get::thunk_(widget, returnz);
}
static void Import(native &self, T value) {
native *p = &self;
auto widget = Self::from(p);
Widget::Set::thunk_(widget, value);
}
};
template<class Widget>
void AddDataCustom(DialogDataList &self, typename Widget::Type widget, Property<typename Widget::Other> const &property) {
using Self = typename Widget::Type;
using T = typename Widget::Other;
using native = typename std::remove_pointer<typename Self::native>::type;
using Wrapper = AddDataCustom_Wrapper<Widget, Self, T, native>;
self.push_back(new CallbackDialogData<typename Widget::Other>(
make_property<PropertyAdaptor<native, T, Wrapper>>(*static_cast<native *>(widget)),
property
));
}
template<class T, class U = std::enable_if<!std::is_function<T>::value>::type>
inline const void *convertToOpaque(const T *t) {
return t;
}
template<class T>
struct ConvertFromOpaque<const T *> {
static const T *apply(void *p) {
return static_cast<const T *>(p);
}
};
template<class T, class U = std::enable_if<!std::is_function<T>::value>::type>
template<class T>
inline void *convertToOpaque(T *t) {
return t;
}
template<class T>
struct ConvertFromOpaque<T *> {
static T *apply(void *p) {
return static_cast<T *>(p);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment