It took a lott of work, but we finally have the right rankings for operator[] to work as intended with as minimal room for screwups as possible.

This should enable operator[] to work in all cases that it is to be expected, thanks to a lot of explicit conversions and some basic overload resolution ranking tricks (e.g., making some conversions a template).
We also need to remember that GCC expects `. template (function name)` in generic code, as it can parse things in a really dumb and silly manner.
This commit is contained in:
ThePhD 2013-12-21 22:00:28 -05:00
parent cfda1d34ba
commit 94c287810f
2 changed files with 31 additions and 26 deletions

View File

@ -64,35 +64,39 @@ public:
tbl.set( key, std::forward<U>( other ) ); tbl.set( key, std::forward<U>( other ) );
} }
operator nil_t ( ) { operator nil_t ( ) const {
return get<nil_t>( ); return get<nil_t>( );
} }
operator bool( ) { operator object( ) const {
return get<bool>( );
}
operator std::string( ) {
return get<std::string>( );
}
operator object( ) {
return get<object>( ); return get<object>( );
} }
operator function( ) { operator function( ) const {
return get<function>( ); return get<function>( );
} }
operator double( ) { operator std::string( ) const {
return get<std::string>( );
}
template <typename T = void>
operator bool( ) const {
return get<bool>( );
}
template <typename T = void>
operator double( ) const {
return get<double>( ); return get<double>( );
} }
operator float( ) { template <typename T = void>
operator float( ) const {
return get<float>( ); return get<float>( );
} }
operator int( ) { template <typename T = void>
operator int( ) const {
return get<int>( ); return get<int>( );
} }
@ -103,23 +107,23 @@ public:
}; };
template <typename Table, typename Key, typename T> template <typename Table, typename Key, typename T>
bool operator== ( T&& left, const proxy<Table, Key>& right ) { inline bool operator== ( T&& left, const proxy<Table, Key>& right ) {
return right.get<Decay<T>>( ) == left; return left == right.template get<Decay<T>>( );
} }
template <typename Table, typename Key, typename T> template <typename Table, typename Key, typename T>
bool operator== ( const proxy<Table, Key>& right, T&& left ) { inline bool operator== ( const proxy<Table, Key>& right, T&& left ) {
return right.get<Decay<T>>( ) == left; return right.template get<Decay<T>>( ) == left;
} }
template <typename Table, typename Key, typename T> template <typename Table, typename Key, typename T>
bool operator!= ( T&& left, const proxy<Table, Key>& right ) { inline bool operator!= ( T&& left, const proxy<Table, Key>& right ) {
return right.get<Decay<T>>( ) != left; return right.template get<Decay<T>>( ) != left;
} }
template <typename Table, typename Key, typename T> template <typename Table, typename Key, typename T>
bool operator!= ( const proxy<Table, Key>& right, T&& left ) { inline bool operator!= ( const proxy<Table, Key>& right, T&& left ) {
return right.get<Decay<T>>( ) != left; return right.template get<Decay<T>>( ) != left;
} }
} // sol } // sol

View File

@ -285,6 +285,7 @@ TEST_CASE("tables/operator[]", "Check if operator[] retrieval and setting works
REQUIRE(bar == "hello world"); REQUIRE(bar == "hello world");
REQUIRE(foo == 20); REQUIRE(foo == 20);
// test operator= for stringification // test operator= for stringification
// errors due to ambiguous operators
bar = lua["bar"]; bar = lua["bar"];
// basic setting // basic setting
@ -300,7 +301,7 @@ TEST_CASE("tables/operator[]", "Check if operator[] retrieval and setting works
REQUIRE_NOTHROW(lua.script("assert(test(10, 11, \"hello\") == 11)")); REQUIRE_NOTHROW(lua.script("assert(test(10, 11, \"hello\") == 11)"));
// function retrieval // function retrieval
sol::function test = lua["test"]; sol::function test = lua[ "test" ];
REQUIRE(test.call<int>(10, 11, "hello") == 11); REQUIRE(test.call<int>(10, 11, "hello") == 11);
// setting a lambda // setting a lambda
@ -311,15 +312,15 @@ TEST_CASE("tables/operator[]", "Check if operator[] retrieval and setting works
REQUIRE_NOTHROW(lua.script("assert(lamb(220) == 440)")); REQUIRE_NOTHROW(lua.script("assert(lamb(220) == 440)"));
// function retrieval of a lambda // function retrieval of a lambda
sol::function lamb = lua["lamb"]; sol::function lamb;// = lua[ "lamb" ];
REQUIRE(lamb.call<int>(220) == 440); REQUIRE(lamb.call<int>(220) == 440);
// test const table retrieval // test const table retrieval
auto assert1 = [](const sol::table& t) { auto assert1 = [](const sol::table& t) {
std::string a = t["foo"]; std::string a = t["foo"];
int b = t["bar"]; int b = t["bar"];
std::cout << a << ',' << b << '\n'; std::cout << a << ',' << b << '\n';
}; };
REQUIRE_NOTHROW(assert1(lua.global_table())); REQUIRE_NOTHROW(assert1(lua.global_table()));
} }