diff --git a/include/sol/optional_implementation.hpp b/include/sol/optional_implementation.hpp index d321abce..e5398966 100644 --- a/include/sol/optional_implementation.hpp +++ b/include/sol/optional_implementation.hpp @@ -1396,14 +1396,14 @@ namespace sol { /// \returns the stored value if there is one, otherwise returns `u` /// \group value_or template - constexpr T& value_or(U&& u) const& { + constexpr T value_or(U&& u) const& { static_assert(std::is_copy_constructible::value && std::is_convertible::value, "T must be copy constructible and convertible from U"); return has_value() ? **this : static_cast(std::forward(u)); } /// \group value_or template - SOL_TL_OPTIONAL_11_CONSTEXPR T& value_or(U&& u) && { + SOL_TL_OPTIONAL_11_CONSTEXPR T value_or(U&& u) && { static_assert(std::is_move_constructible::value && std::is_convertible::value, "T must be move constructible and convertible from U"); return has_value() ? **this : static_cast(std::forward(u)); } @@ -2240,16 +2240,9 @@ namespace sol { /// \returns the stored value if there is one, otherwise returns `u` /// \group value_or template - constexpr T& value_or(U&& u) const& { - static_assert(std::is_copy_constructible::value && std::is_convertible::value, "T must be copy constructible and convertible from U"); - return has_value() ? **this : static_cast(std::forward(u)); - } - - /// \group value_or - template - SOL_TL_OPTIONAL_11_CONSTEXPR T& value_or(U&& u) && { - static_assert(std::is_move_constructible::value && std::is_convertible::value, "T must be move constructible and convertible from U"); - return has_value() ? **this : static_cast(std::forward(u)); + constexpr T& value_or(U&& u) const { + static_assert(std::is_convertible::value, "T must be convertible from U"); + return has_value() ? const_cast(**this) : static_cast(std::forward(u)); } /// Destroys the stored value if one exists, making the optional empty diff --git a/single/include/sol/forward.hpp b/single/include/sol/forward.hpp index be28ee97..19af118a 100644 --- a/single/include/sol/forward.hpp +++ b/single/include/sol/forward.hpp @@ -20,8 +20,8 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // This file was generated with a script. -// Generated 2019-03-29 03:22:11.311923 UTC -// This header was generated with sol v3.0.1-beta2 (revision 7218151) +// Generated 2019-03-31 03:30:36.689278 UTC +// This header was generated with sol v3.0.1-beta2 (revision 6017f63) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP diff --git a/single/include/sol/sol.hpp b/single/include/sol/sol.hpp index 44f3e315..0014dd69 100644 --- a/single/include/sol/sol.hpp +++ b/single/include/sol/sol.hpp @@ -20,8 +20,8 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // This file was generated with a script. -// Generated 2019-03-29 03:22:11.072530 UTC -// This header was generated with sol v3.0.1-beta2 (revision 7218151) +// Generated 2019-03-31 03:30:35.378291 UTC +// This header was generated with sol v3.0.1-beta2 (revision 6017f63) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_HPP @@ -4945,14 +4945,14 @@ namespace sol { /// \returns the stored value if there is one, otherwise returns `u` /// \group value_or template - constexpr T& value_or(U&& u) const& { + constexpr T value_or(U&& u) const& { static_assert(std::is_copy_constructible::value && std::is_convertible::value, "T must be copy constructible and convertible from U"); return has_value() ? **this : static_cast(std::forward(u)); } /// \group value_or template - SOL_TL_OPTIONAL_11_CONSTEXPR T& value_or(U&& u) && { + SOL_TL_OPTIONAL_11_CONSTEXPR T value_or(U&& u) && { static_assert(std::is_move_constructible::value && std::is_convertible::value, "T must be move constructible and convertible from U"); return has_value() ? **this : static_cast(std::forward(u)); } @@ -5785,16 +5785,9 @@ namespace sol { /// \returns the stored value if there is one, otherwise returns `u` /// \group value_or template - constexpr T& value_or(U&& u) const& { - static_assert(std::is_copy_constructible::value && std::is_convertible::value, "T must be copy constructible and convertible from U"); - return has_value() ? **this : static_cast(std::forward(u)); - } - - /// \group value_or - template - SOL_TL_OPTIONAL_11_CONSTEXPR T& value_or(U&& u) && { - static_assert(std::is_move_constructible::value && std::is_convertible::value, "T must be move constructible and convertible from U"); - return has_value() ? **this : static_cast(std::forward(u)); + constexpr T& value_or(U&& u) const { + static_assert(std::is_convertible::value, "T must be convertible from U"); + return has_value() ? const_cast(**this) : static_cast(std::forward(u)); } /// Destroys the stored value if one exists, making the optional empty diff --git a/tests/runtime_tests/source/utility.cpp b/tests/runtime_tests/source/utility.cpp index 7026214c..8c69ba96 100644 --- a/tests/runtime_tests/source/utility.cpp +++ b/tests/runtime_tests/source/utility.cpp @@ -34,6 +34,10 @@ #include #endif // C++17 +struct optional_ref_t { + int x = 0; +}; + std::mutex basic_init_require_mutex; void basic_initialization_and_lib_open() { @@ -114,18 +118,37 @@ TEST_CASE("utility/optional-conversion", "test that regular optional will proper lua.new_usertype("vars"); - lua["test"] = [](sol::optional x) { - return static_cast(x); - }; + lua["test"] = [](sol::optional x) { return static_cast(x); }; const auto result = lua.safe_script(R"( assert(test(vars:new())) assert(not test(3)) assert(not test(nil)) - )", sol::script_pass_on_error); + )", + sol::script_pass_on_error); REQUIRE(result.valid()); } +TEST_CASE("utility/optional-value-or", "test that regular optional will properly handle value_or") { + sol::optional str; + auto x = str.value_or("!"); + + sol::optional un; + auto y = un.value_or(64); + + optional_ref_t def_custom; + sol::optional custom; + auto z = custom.value_or(def_custom); + const auto& z_ref = custom.value_or(def_custom); + + REQUIRE(x == "!"); + + REQUIRE(y == 64); + + REQUIRE(&def_custom == &z_ref); + REQUIRE(&z != &def_custom); +} + TEST_CASE("utility/std optional", "test that shit optional can be round-tripped") { #ifdef SOL_CXX17_FEATURES SECTION("okay") {