diff --git a/Optional b/Optional index 717f86cc..c386acbd 160000 --- a/Optional +++ b/Optional @@ -1 +1 @@ -Subproject commit 717f86cc20e5602d1c5b7a380b1b68a4a85d0653 +Subproject commit c386acbdf2d6ae368de7cba55801b06d362bdaac diff --git a/sol/in_place.hpp b/sol/in_place.hpp new file mode 100644 index 00000000..2410fb96 --- /dev/null +++ b/sol/in_place.hpp @@ -0,0 +1,50 @@ +// The MIT License (MIT) + +// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#ifndef SOL_IN_PLACE_HPP +#define SOL_IN_PLACE_HPP + +namespace sol { + + namespace detail { + struct in_place_of {}; + template + struct in_place_of_i {}; + template + struct in_place_of_t {}; + } // detail + + struct in_place_tag { struct init {}; constexpr in_place_tag(init) {} in_place_tag() = delete; }; + constexpr inline in_place_tag in_place(detail::in_place_of) { return in_place_tag(in_place_tag::init()); } + template + constexpr inline in_place_tag in_place(detail::in_place_of_t) { return in_place_tag(in_place_tag::init()); } + template + constexpr inline in_place_tag in_place(detail::in_place_of_i) { return in_place_tag(in_place_tag::init()); } + + using in_place_t = in_place_tag(&)(detail::in_place_of); + template + using in_place_type_t = in_place_tag(&)(detail::in_place_of_t); + template + using in_place_index_t = in_place_tag(&)(detail::in_place_of_i); + +} // sol + +#endif // SOL_IN_PLACE_HPP diff --git a/sol/optional.hpp b/sol/optional.hpp index 74b3bae3..ee88f129 100644 --- a/sol/optional.hpp +++ b/sol/optional.hpp @@ -24,6 +24,7 @@ #if defined(SOL_USE_BOOST) #include +#include "../sol/in_place.hpp" #else #include "../Optional/optional.hpp" #endif // Boost vs. Better optional @@ -35,33 +36,8 @@ namespace sol { using optional = boost::optional; using nullopt_t = boost::none_t; const nullopt_t nullopt = boost::none; - - namespace detail { - struct in_place_of {}; - } // detail - - struct in_place_tag { struct init {}; constexpr in_place_tag(init) {} in_place_tag() = delete; }; - constexpr inline in_place_tag in_place(detail::in_place_of) { return in_place_tag(in_place_tag::init()); } - using in_place_t = in_place_tag(&)(detail::in_place_of); #endif // Boost vs. Better optional - namespace detail { - template - struct in_place_of_i {}; - template - struct in_place_of_t {}; - } - - template - constexpr inline in_place_tag in_place(detail::in_place_of_t) { return in_place_tag(in_place_tag::init()); } - template - constexpr inline in_place_tag in_place(detail::in_place_of_i) { return in_place_tag(in_place_tag::init()); } - - template - using in_place_type_t = in_place_tag(&)(detail::in_place_of_t); - template - using in_place_index_t = in_place_tag(&)(detail::in_place_of_i); - } // sol #endif // SOL_OPTIONAL_HPP diff --git a/sol/stack_get.hpp b/sol/stack_get.hpp index 266518cf..b346ffe2 100644 --- a/sol/stack_get.hpp +++ b/sol/stack_get.hpp @@ -77,6 +77,54 @@ namespace sol { } }; + template + struct getter, meta::neg>, meta::neg, std::is_base_of>>>::value>> { + static T get(lua_State* L, int index, record& tracking) { + typedef typename T::value_type V; + tracking.use(1); + + T arr; + index = lua_absindex(L, index); + lua_pushnil(L); + while (lua_next(L, index) != 0) { + int isint = 0; + lua_Integer li = lua_tointegerx(L, -2, &isint); + if (isint == 0) { + lua_pop(L, 1); + continue; + } + std::size_t i = static_cast(li); + arr.push_back(stack::get(L, -1)); + lua_pop(L, 1); + } + return arr; + } + }; + + template + struct getter, meta::has_key_value_pair, meta::neg, std::is_base_of>>>::value>> { + static T get(lua_State* L, int index, record& tracking) { + typedef typename T::value_type P; + typedef typename P::first_type K; + typedef typename P::second_type V; + tracking.use(1); + + T associative; + index = lua_absindex(L, index); + lua_pushnil(L); + while (lua_next(L, index) != 0) { + decltype(auto) key = stack::check_get(L, -1); + if (!key) { + lua_pop(L, 1); + continue; + } + arr.emplace(std::forward(key), stack::get(L, -1)); + lua_pop(L, 1); + } + return associative; + } + }; + template struct getter::value || std::is_base_of::value>> { static T get(lua_State* L, int index, record& tracking) {