Skip to content

Commit 8a213f6

Browse files
committed
Update README
1 parent 1b54209 commit 8a213f6

File tree

3 files changed

+76
-39
lines changed

3 files changed

+76
-39
lines changed

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33

44
## Currently Unreleased - TBD
55

6-
* Add static assertion to explicitly forbid using reference type as return type
7-
or argument type in `luaw::function`.
6+
* Add static assertion to explicitly forbid using non-const lvalue reference
7+
as argument or using any reference as return for `luaw::function`.
88
* Add new class `subluaw`, and add method `luaw::make_subluaw`.
99
* add method `luaw::function::unref`, `luaw::function::ref_id` etc.
1010
* Add method `luavalueref::setglobal`, `luavalueref::unref` etc.

README.md

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,9 @@ l.set("co", co); // set const instance by copy
954954
l.set("co", std::move(co)); // set const instance by move
955955
// or
956956
l.set("co", std::add_const_t<Obj>{}); // set const instance by move
957+
// or
958+
l.set<const Obj>("co", o); // copy non-const "o" to a const instance
959+
957960
// The variable "co" is const, it can access all registered members variables
958961
// and registered const member functins of Obj.
959962
```
@@ -1903,24 +1906,27 @@ if (f.failed()) {
19031906

19041907
#### 3.3 Type of argument and return
19051908

1906-
Do not support using C++ reference type as function's argument or return type.
1907-
1908-
If using reference as argument, it will make a copy of the referenced
1909-
argument into Lua, won't implicitly take its address, meaning that it
1910-
will not share the same object in Lua with that in C++, and this
1911-
behaves differently with that in C++. This may confuse users, so
1912-
explicitly forbid it.
1909+
##### Argument
19131910

1914-
Directly using the underlying type if you want to make a copy of the
1915-
argument into Lua.
1911+
Do not support non-const lvalue reference as luaw::function's argument.
1912+
1913+
If using this kind of reference, it will make a copy of the referenced
1914+
argument into Lua, won't implicitly take its address, meaning that it
1915+
will not share the same object in Lua with C++.
1916+
And this behaves differently with that in C++. This may confuse users,
1917+
so explicitly forbid it.
19161918

1917-
Or if you want to share the same argument objects in Lua with C++,
1919+
If you want to share the same argument objects in Lua with C++,
19181920
so you can modify them in Lua, you can use raw pointer type if there is
19191921
only one kind of raw pointer type in all arguments, or use smart
1920-
pointer type or `luaw::ptrw` type, and these are safer and more reassuring.
1922+
pointer type or `peacalm::luaw::ptrw` type, and these two are safer and
1923+
more reassuring.
1924+
1925+
##### Return
19211926

19221927
Since we cannot make C++ reference type of reference to values in Lua,
1923-
so using C++ reference type as return type is also forbidden.
1928+
so using any C++ reference type as return type is forbidden.
1929+
19241930
To get a reference of a Lua value, can use type
19251931
[`luaw::luavalueref`](https://github.com/peacalm/cpp-luaw?tab=readme-ov-file#9-reference-of-lua-values-in-c).
19261932

@@ -3173,38 +3179,50 @@ int main() {
31733179
##### Set const instances to Lua
31743180
31753181
Const property of an instance in C++ will be perfectly transfered to Lua using
3176-
"set" method.
3182+
`set` method (if `Hint` was not provided).
3183+
3184+
Or explicitly provide a const type as `Hint` then `set` will construct a const
3185+
instance by a given value, which must be convertible to type `Hint`.
3186+
31773187
31783188
Example:
31793189
31803190
```C++
3191+
3192+
// ==== Set const instance:
31813193
const Obj co;
31823194
l.set("co", co); // set const instance by copy
31833195
// or
31843196
l.set("co", std::move(co)); // set const instance by move
31853197
// or
31863198
l.set("co", std::add_const_t<Obj>{}); // set const instance by move
31873199
// or
3200+
l.set<const Obj>("co", Obj{}); // copy non-const instance to be a const instance
3201+
3202+
// ==== Set raw pointer of const instance:
31883203
const Obj co2;
31893204
// set low-level const pointer to be a lightuserdata which is also const
3190-
l.set("co", &co2);
3191-
// The variable "co" (set by any method above) is const in Lua,
3192-
// it can access all registered member variables (but can't modify) and
3193-
// registered const member functins of Obj.
3205+
l.set("cop", &co2);
31943206
3195-
3196-
// Set underlying const instance using smart pointer.
3207+
// ==== Set underlying const instance using smart pointer:
31973208
// "sco" is not const, by it's underlying object is const,
31983209
// so it behaves same as "co":
31993210
auto sco = std::make_shared<const Obj>();
32003211
l.set("sco", sco); // by copy
32013212
l.set("sco", std::move(sco)); // by move
32023213
l.set("sco", std::make_shared<const Obj>()); // by move
3203-
// or
3214+
3215+
// ==== Set raw pointer of smart pointer:
32043216
auto sco2 = std::make_shared<const Obj>();
3205-
l.set("sco", &sco2); // set as lightuserdata, also underlying const
3217+
l.set("scop", &sco2); // set as lightuserdata, also underlying const
3218+
32063219
```
32073220

3221+
The variables set by methods above can read all registered member variables
3222+
and call registered const member functins of `Obj`.
3223+
But can't modify member variables and can't call non-const member functions.
3224+
3225+
32083226
#### 5.10 Get instances from Lua
32093227

32103228
Use "get" method, we can get an instance or a pointer of an instance from Lua.

include/peacalm/luaw.h

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3931,7 +3931,8 @@ struct luaw::convertor<luaw::placeholder_tag> {
39313931

39323932
namespace luaw_detail {
39333933

3934-
// Has any reference type in a std::tuple
3934+
// Whether the type T is a std::tuple and has element of reference type.
3935+
39353936
template <typename T>
39363937
struct tuple_has_ref : std::false_type {};
39373938

@@ -3945,31 +3946,47 @@ struct tuple_has_ref<std::tuple<T, Ts...>>
39453946
template <>
39463947
struct tuple_has_ref<std::tuple<>> : std::false_type {};
39473948

3948-
// Has any reference type in Ts
3949+
// Whether the type T is a std::tuple and has element of non-const lvalue
3950+
// reference type.
3951+
3952+
template <typename T>
3953+
struct tuple_has_non_const_lvalue_ref : std::false_type {};
3954+
3955+
template <typename T, typename... Ts>
3956+
struct tuple_has_non_const_lvalue_ref<std::tuple<T, Ts...>>
3957+
: public std::integral_constant<
3958+
bool,
3959+
(std::is_lvalue_reference<T>::value &&
3960+
!std::is_const<std::remove_reference_t<T>>::value) ||
3961+
tuple_has_non_const_lvalue_ref<std::tuple<Ts...>>::value> {};
3962+
3963+
template <>
3964+
struct tuple_has_non_const_lvalue_ref<std::tuple<>> : std::false_type {};
3965+
3966+
// Whether have any non-const lvalue reference type in Ts
39493967
template <typename... Ts>
3950-
struct has_ref : public tuple_has_ref<std::tuple<Ts...>> {};
3968+
struct has_non_const_lvalue_ref
3969+
: public tuple_has_non_const_lvalue_ref<std::tuple<Ts...>> {};
39513970

39523971
} // namespace luaw_detail
39533972

39543973
template <typename Return, typename... Args>
39553974
class luaw::function<Return(Args...)> {
39563975
static_assert(
3957-
!luaw_detail::has_ref<Args...>::value,
3958-
"Do not support reference type as luaw::function's argument. "
3976+
!luaw_detail::has_non_const_lvalue_ref<Args...>::value,
3977+
"Do not support non-const lvalue reference as luaw::function's argument. "
39593978
""
3960-
"If using reference as argument, it will make a copy of the referenced "
3979+
"If using this kind of reference, it will make a copy of the referenced "
39613980
"argument into Lua, won't implicitly take its address, meaning that it "
3962-
"will not share the same object in Lua with that in C++, and this "
3963-
"behaves differently with that in C++. This may confuse users, so "
3964-
"explicitly forbid it. "
3981+
"will not share the same object in Lua with C++. "
3982+
"And this behaves differently with that in C++. This may confuse users, "
3983+
"so explicitly forbid it. "
39653984
""
3966-
"Directly using the underlying type if you want to make a copy of the "
3967-
"argument into Lua. "
3968-
"Or if you want to share the same argument objects in Lua with C++, "
3985+
"If you want to share the same argument objects in Lua with C++, "
39693986
"so you can modify them in Lua, you can use raw pointer type if there is "
39703987
"only one kind of raw pointer type in all arguments, or use smart "
3971-
"pointer type or peacalm::luaw::ptrw type, and these are safer and more "
3972-
"reassuring.");
3988+
"pointer type or peacalm::luaw::ptrw type, and these two are safer and "
3989+
"more reassuring.");
39733990
static_assert(!std::is_reference<Return>::value &&
39743991
!luaw_detail::tuple_has_ref<Return>::value,
39753992
"Do not support reference type as luaw::function's result. "
@@ -4090,7 +4107,7 @@ class luaw::function<Return(Args...)> {
40904107
return luaw::pusher_for_return<std::decay_t<Return>>::size;
40914108
}
40924109

4093-
Return operator()(const Args&... args) const {
4110+
Return operator()(Args... args) const {
40944111
// reset all states first
40954112
function_failed_ = false;
40964113
function_exists_ = false;
@@ -4127,7 +4144,9 @@ class luaw::function<Return(Args...)> {
41274144
function_exists_ = true;
41284145
}
41294146

4130-
int narg = push_args(l, args...);
4147+
// push args by copy or move
4148+
int narg = push_args(l, std::forward<Args>(args)...);
4149+
41314150
int pcall_ret = l.pcall(narg, LUA_MULTRET, 0);
41324151
PEACALM_LUAW_ASSERT(l.gettop() >= sz);
41334152

0 commit comments

Comments
 (0)