@@ -3053,6 +3053,56 @@ struct luaw::pusher<luaw::function_tag> {
3053
3053
}
3054
3054
};
3055
3055
3056
+ // class_tag: push as an user defined custom class type.
3057
+ // Only works on class type or it's pointer.
3058
+ // Push class as full userdata, push pointer to class as light userdata.
3059
+ template <>
3060
+ struct luaw ::pusher<luaw::class_tag> {
3061
+ static const size_t size = 1 ;
3062
+
3063
+ template <typename Y>
3064
+ static int push (luaw& l, Y&& v) {
3065
+ using SolidY = std::remove_reference_t <Y>;
3066
+ static_assert (std::is_class<std::remove_pointer_t <SolidY>>::value,
3067
+ " Only class or it's pointer" );
3068
+ __push<SolidY>(l, std::forward<Y>(v), std::is_pointer<SolidY>{});
3069
+ return 1 ;
3070
+ }
3071
+
3072
+ // Construct TargetT by Y at the moment of creating userdata.
3073
+ template <typename TargetT, typename Y>
3074
+ static std::enable_if_t <!std::is_same<TargetT, Y>::value &&
3075
+ !std::is_reference<TargetT>::value,
3076
+ int >
3077
+ push (luaw& l, Y&& v) {
3078
+ static_assert (std::is_class<std::remove_pointer_t <TargetT>>::value,
3079
+ " Only class or it's pointer" );
3080
+ static_assert (std::is_convertible<Y, TargetT>::value,
3081
+ " Y should convertible to TargetT" );
3082
+ __push<TargetT>(l, std::forward<Y>(v), std::is_pointer<TargetT>{});
3083
+ return 1 ;
3084
+ }
3085
+
3086
+ private:
3087
+ // TargetT is pointer type
3088
+ template <typename TargetT, typename Y>
3089
+ static void __push (luaw& l, Y&& v, std::true_type) {
3090
+ l.pushlightuserdata (reinterpret_cast <void *>(
3091
+ const_cast <std::remove_cv_t <std::remove_pointer_t <TargetT>>*>(v)));
3092
+ luaw::metatable_factory<TargetT>::push_shared_metatable (l);
3093
+ l.setmetatable (-2 );
3094
+ }
3095
+
3096
+ // TargetT is not pointer type
3097
+ template <typename TargetT, typename Y>
3098
+ static void __push (luaw& l, Y&& v, std::false_type) {
3099
+ void * p = l.newuserdata (sizeof (TargetT));
3100
+ new (p) TargetT (std::forward<Y>(v)); // construct TargetT by Y
3101
+ luaw::metatable_factory<TargetT>::push_shared_metatable (l);
3102
+ l.setmetatable (-2 );
3103
+ }
3104
+ };
3105
+
3056
3106
// primary pusher. guess whether it may be a lambda, push as function if true,
3057
3107
// otherwise push as an user defined custom object.
3058
3108
template <typename T, typename >
@@ -3066,41 +3116,44 @@ struct luaw::pusher {
3066
3116
3067
3117
template <typename Y>
3068
3118
static int push (luaw& l, Y&& v) {
3069
- static_assert (std::is_convertible<std::decay_t <Y>, T>::value,
3070
- " Y should convertible to T" );
3119
+ static_assert (std::is_same<std::decay_t <Y>, T>::value,
3120
+ " DecayY should same to T" );
3121
+ using SolidY = std::remove_reference_t <Y>;
3071
3122
3072
3123
// Guess whether it may be a lambda object, if it is, then push as a
3073
3124
// function, otherwise push as custom class.
3074
- return __push (l, std::forward<Y>(v), luaw_detail::decay_maybe_lambda<Y>{});
3125
+ return __push<SolidY>(
3126
+ l, std::forward<Y>(v), luaw_detail::decay_maybe_lambda<Y>{});
3127
+ }
3128
+
3129
+ // Construct TargetT by Y at the moment of creating userdata.
3130
+ template <typename TargetT, typename Y>
3131
+ static std::enable_if_t <!std::is_same<TargetT, Y>::value &&
3132
+ !std::is_reference<TargetT>::value,
3133
+ int >
3134
+ push (luaw& l, Y&& v) {
3135
+ static_assert (std::is_class<TargetT>::value &&
3136
+ std::is_same<std::remove_cv_t <TargetT>, T>::value,
3137
+ " TargetT should be class T or cv- qualified T" );
3138
+ static_assert (std::is_convertible<Y, TargetT>::value,
3139
+ " Y should convertible to TargetT" );
3140
+ __push<TargetT>(
3141
+ l, std::forward<Y>(v), luaw_detail::decay_maybe_lambda<Y>{});
3142
+ return 1 ;
3075
3143
}
3076
3144
3077
3145
private:
3078
3146
// Push as a function.
3079
- template <typename Y>
3147
+ template <typename _Nouse, typename Y>
3080
3148
static int __push (luaw& l, Y&& v, std::true_type) {
3081
3149
return luaw::pusher<luaw::function_tag>::push (l, std::forward<Y>(v));
3082
3150
}
3083
3151
3084
3152
// Push as a full userdata.
3085
- template <typename Y>
3153
+ template <typename TargetT, typename Y>
3086
3154
static int __push (luaw& l, Y&& v, std::false_type) {
3087
- using SolidY = std::remove_reference_t <Y>;
3088
- using T0 = T;
3089
- using T1 = std::
3090
- conditional_t <std::is_const<SolidY>::value, std::add_const_t <T0>, T0>;
3091
- using T2 = std::conditional_t <std::is_volatile<SolidY>::value,
3092
- std::add_volatile_t <T1>,
3093
- T1>;
3094
- static_assert (std::is_same<T, std::decay_t <Y>>::value
3095
- ? std::is_same<T2, SolidY>::value
3096
- : true ,
3097
- " Never happen" );
3098
-
3099
- void * p = l.newuserdata (sizeof (T2));
3100
- new (p) T2 (std::forward<Y>(v)); // construct T by Y
3101
- luaw::metatable_factory<T2>::push_shared_metatable (l);
3102
- l.setmetatable (-2 );
3103
- return 1 ;
3155
+ return luaw::pusher<luaw::class_tag>::template push<TargetT>(
3156
+ l, std::forward<Y>(v));
3104
3157
}
3105
3158
};
3106
3159
@@ -3223,43 +3276,6 @@ struct luaw::pusher<
3223
3276
}
3224
3277
};
3225
3278
3226
- // class_tag: push as an user defined custom class type.
3227
- // only work on type class or pointer to class.
3228
- template <>
3229
- struct luaw ::pusher<luaw::class_tag> {
3230
- static const size_t size = 1 ;
3231
-
3232
- template <typename Y>
3233
- static int push (luaw& l, Y&& v) {
3234
- using SolidY = std::remove_reference_t <Y>;
3235
- static_assert (std::is_class<std::remove_pointer_t <SolidY>>::value,
3236
- " Only class or it's pointer" );
3237
-
3238
- __push<SolidY, Y>(l, std::forward<Y>(v), std::is_pointer<SolidY>{});
3239
-
3240
- return 1 ;
3241
- }
3242
-
3243
- private:
3244
- // SolidY is pointer type
3245
- template <typename SolidY, typename Y>
3246
- static void __push (luaw& l, Y&& v, std::true_type) {
3247
- l.pushlightuserdata (reinterpret_cast <void *>(
3248
- const_cast <std::remove_cv_t <std::remove_pointer_t <SolidY>>*>(v)));
3249
- luaw::metatable_factory<SolidY>::push_shared_metatable (l);
3250
- l.setmetatable (-2 );
3251
- }
3252
-
3253
- // SolidY is not pointer type
3254
- template <typename SolidY, typename Y>
3255
- static void __push (luaw& l, Y&& v, std::false_type) {
3256
- void * p = l.newuserdata (sizeof (SolidY));
3257
- new (p) SolidY (std::forward<Y>(v));
3258
- luaw::metatable_factory<SolidY>::push_shared_metatable (l);
3259
- l.setmetatable (-2 );
3260
- }
3261
- };
3262
-
3263
3279
// newtable_tag: push a new empty table
3264
3280
template <>
3265
3281
struct luaw ::pusher<luaw::newtable_tag> {
0 commit comments