Refactored sol::stack::push to use sol::stack::pusher

This commit is contained in:
Rapptz 2014-06-01 01:03:27 -04:00
parent 76b1efe12e
commit 4cc402dc6e

View File

@ -120,28 +120,6 @@ inline auto get_helper(std::false_type, lua_State* L, int index = -1) -> decltyp
// T is a class // T is a class
return get(types<T>(), L, index); return get(types<T>(), L, index);
} }
template<typename T>
inline void push_unsigned(std::true_type, lua_State* L, T x) {
lua_pushunsigned(L, x);
}
template<typename T>
inline void push_unsigned(std::false_type, lua_State* L, T x) {
lua_pushinteger(L, x);
}
template<typename T>
inline void push_arithmetic(std::true_type, lua_State* L, T x) {
// T is an integral type
push_unsigned(std::is_unsigned<T>{}, L, x);
}
template<typename T>
inline void push_arithmetic(std::false_type, lua_State* L, T x) {
// T is an floating point type
lua_pushnumber(L, x);
}
} // detail } // detail
template<typename T, typename U = Unqualified<T>> template<typename T, typename U = Unqualified<T>>
@ -167,62 +145,100 @@ auto pop(lua_State* L) -> decltype(get<T>(L)) {
return r; return r;
} }
template<typename T, bool B = std::is_arithmetic<T>::value> template<typename T>
inline typename std::enable_if<B, void>::type push(lua_State* L, T arithmetic) { struct pusher;
detail::push_arithmetic(std::is_integral<T>{}, L, arithmetic);
}
template<typename T, bool B = !std::is_arithmetic<T>::value && template<typename T>
!std::is_same<Unqualified<T>, std::string>::value && struct pusher {
has_begin_end<T>::value> template<typename U = T, EnableIf<std::is_floating_point<U>> = 0>
inline typename std::enable_if<B, void>::type push(lua_State* L, const T& cont) { static void push(lua_State* L, const T& value) {
lua_pushnumber(L, value);
}
template<typename U = T, EnableIf<std::is_integral<U>, std::is_signed<U>> = 0>
static void push(lua_State* L, const T& value) {
lua_pushinteger(L, value);
}
template<typename U = T, EnableIf<std::is_integral<U>, std::is_unsigned<U>> = 0>
static void push(lua_State* L, const T& value) {
lua_pushunsigned(L, value);
}
template<typename U = T, EnableIf<has_begin_end<U>, Not<has_key_value_pair<U>>> = 0>
static void push(lua_State* L, const T& cont) {
lua_createtable(L, cont.size(), 0); lua_createtable(L, cont.size(), 0);
unsigned index = 1; unsigned index = 1;
for(auto&& i : cont) { for(auto&& i : cont) {
// push the index // push the index
push(L, index++); pusher<unsigned>::push(L, index++);
// push the value // push the value
push(L, i); pusher<Unqualified<decltype(i)>>::push(L, i);
// set the table // set the table
lua_settable(L, -3); lua_settable(L, -3);
} }
} }
};
inline void push(lua_State*, reference& ref) { template<>
ref.push(); struct pusher<bool> {
} static void push(lua_State* L, const bool& b) {
lua_pushboolean(L, b);
}
};
inline void push(lua_State* L, bool boolean) { template<>
lua_pushboolean(L, boolean); struct pusher<reference> {
} static void push(lua_State*, reference& r) {
r.push();
}
};
inline void push(lua_State* L, const nil_t&) { template<>
struct pusher<nil_t> {
static void push(lua_State* L, const nil_t&) {
lua_pushnil(L); lua_pushnil(L);
} }
};
inline void push(lua_State* L, lua_CFunction func) { template<>
struct pusher<lua_CFunction> {
static void push(lua_State* L, lua_CFunction func) {
lua_pushcfunction(L, func); lua_pushcfunction(L, func);
} }
};
inline void push(lua_State* L, lua_CFunction func, int n) { template<>
lua_pushcclosure(L, func, n); struct pusher<void*> {
} static void push(lua_State* L, void* userdata) {
inline void push(lua_State* L, void* userdata) {
lua_pushlightuserdata(L, userdata); lua_pushlightuserdata(L, userdata);
} }
};
template<>
struct pusher<const char*> {
static void push(lua_State* L, const char* str) {
lua_pushlstring(L, str, std::char_traits<char>::length(str));
}
};
template<size_t N> template<size_t N>
inline void push(lua_State* L, const char (&str)[N]) { struct pusher<char[N]> {
static void push(lua_State* L, const char (&str)[N]) {
lua_pushlstring(L, str, N - 1); lua_pushlstring(L, str, N - 1);
} }
};
inline void push(lua_State* L, const char* str) { template<>
lua_pushlstring(L, str, std::char_traits<char>::length(str)); struct pusher<std::string> {
} static void push(lua_State* L, const std::string& str) {
inline void push(lua_State* L, const std::string& str) {
lua_pushlstring(L, str.c_str(), str.size()); lua_pushlstring(L, str.c_str(), str.size());
}
};
template<typename T>
inline void push(lua_State* L, T&& t) {
pusher<Unqualified<T>>::push(L, std::forward<T>(t));
} }
template<typename T> template<typename T>
@ -237,8 +253,8 @@ inline void push_user(lua_State* L, T& userdata, const char* metatablekey) {
} }
template<typename T, size_t N> template<typename T, size_t N>
inline void push(lua_State* L, const std::array<T, N>& data) { inline void push_as_upvalues(lua_State* L, const std::array<T, N>& data) {
for (auto&& i : data) { for(auto&& i : data) {
push(L, i); push(L, i);
} }
} }
@ -254,7 +270,7 @@ inline int push_user(lua_State* L, T& item) {
data_t data{{}}; data_t data{{}};
std::memcpy(std::addressof(data[0]), std::addressof(item), itemsize); std::memcpy(std::addressof(data[0]), std::addressof(item), itemsize);
push(L, data); push_as_upvalues(L, data);
return data_t_count; return data_t_count;
} }
@ -294,14 +310,15 @@ inline auto rtl_pop(lua_State* L, F&& f, types<Args...> t, types<Head, Tail...>,
} // detail } // detail
template<typename... Args> template<typename... Args>
inline void push(lua_State* L, const std::tuple<Args...>& tuplen) { struct pusher<std::tuple<Args...>> {
static void push(lua_State* L, const std::tuple<Args...>& tuplen) {
detail::push_tuple(L, build_indices<sizeof...(Args)>(), tuplen); detail::push_tuple(L, build_indices<sizeof...(Args)>(), tuplen);
} }
template<typename... Args> static void push(lua_State* L, std::tuple<Args...>&& tuplen) {
inline void push(lua_State* L, std::tuple<Args...>&& tuplen) {
detail::push_tuple(L, build_indices<sizeof...(Args)>(), std::move(tuplen)); detail::push_tuple(L, build_indices<sizeof...(Args)>(), std::move(tuplen));
} }
};
template<typename T> template<typename T>
inline void push_reverse(lua_State* L, T&& item) { inline void push_reverse(lua_State* L, T&& item) {
@ -374,7 +391,6 @@ template <typename T>
struct get_return { struct get_return {
typedef decltype(get<T>(nullptr)) type; typedef decltype(get<T>(nullptr)) type;
}; };
} // stack } // stack
} // sol } // sol