diff --git a/include/fastgltf/types.hpp b/include/fastgltf/types.hpp index c39d008ab..d257969ba 100644 --- a/include/fastgltf/types.hpp +++ b/include/fastgltf/types.hpp @@ -1020,6 +1020,19 @@ namespace fastgltf { static constexpr auto missing_value = static_cast(std::numeric_limits>::max()); }; + FASTGLTF_EXPORT template + class OptionalWithFlagValue; + + /** + * A type alias which checks if there is a specialization of OptionalFlagValue for T and "switches" + * between fastgltf::OptionalWithFlagValue and std::optional. + */ + FASTGLTF_EXPORT template + using Optional = std::conditional_t< + !std::is_same_v::missing_value)>>, + OptionalWithFlagValue, + std::optional>; + /** * A custom optional class for fastgltf, * which uses so-called "flag values" which are specific values of T that will never be present as an actual value. @@ -1030,7 +1043,7 @@ namespace fastgltf { * If no specialization for T of OptionalFlagValue is provided, a static assert will be triggered. * In those cases, use std::optional or fastgltf::Optional instead. */ - FASTGLTF_EXPORT template + template class OptionalWithFlagValue final { static_assert(!std::is_same_v::missing_value)>>, "OptionalWithFlagValue can only be used when there is an appropriate specialization of OptionalFlagValue."); @@ -1170,31 +1183,67 @@ namespace fastgltf { } template - [[nodiscard]] OptionalWithFlagValue and_then(F&& func)& { + [[nodiscard]] auto and_then(F&& func)& { + using U = std::remove_cv_t>>; + if (!has_value()) + return U(); + return std::invoke(std::forward(func), **this); + } + + template + [[nodiscard]] auto and_then(F&& func) const& { + using U = std::remove_cv_t>>; + if (!has_value()) + return U(); + return std::invoke(std::forward(func), **this); + } + + template + [[nodiscard]] auto and_then(F&& func)&& { + using U = std::remove_cv_t>>; + if (!has_value()) + return U(); + return std::invoke(std::forward(func), std::move(**this)); + } + + template + [[nodiscard]] auto and_then(F&& func) const&& { + using U = std::remove_cv_t>>; + if (!has_value()) + return U(); + return std::invoke(std::forward(func), std::move(**this)); + } + + template + [[nodiscard]] auto transform(F&& func)& { + using U = std::remove_cv_t>; if (!has_value()) - return std::nullopt; - return func(value()); + return Optional(); + return Optional(std::invoke(std::forward(func), **this)); } template - [[nodiscard]] OptionalWithFlagValue and_then(F&& func)&& { + [[nodiscard]] auto transform(F&& func) const& { + using U = std::remove_cv_t>; if (!has_value()) - return std::nullopt; - return func(std::move(value())); + return Optional(); + return Optional(std::invoke(std::forward(func), **this)); } template - [[nodiscard]] OptionalWithFlagValue transform(F&& func)& { + [[nodiscard]] auto transform(F&& func)&& { + using U = std::remove_cv_t>; if (!has_value()) - return std::nullopt; - return OptionalWithFlagValue(func(value())); + return Optional(); + return Optional(std::invoke(std::forward(func), std::move(**this))); } template - [[nodiscard]] OptionalWithFlagValue transform(F&& func)&& { + [[nodiscard]] auto transform(F&& func) const&& { + using U = std::remove_cv_t>; if (!has_value()) - return std::nullopt; - return OptionalWithFlagValue(func(std::move(value()))); + return Optional(); + return Optional(std::invoke(std::forward(func), std::move(**this))); } template @@ -1305,15 +1354,6 @@ namespace fastgltf { return opt.has_value() && *opt >= value; } - /** - * A type alias which checks if there is a specialization of OptionalFlagValue for T and "switches" - * between fastgltf::OptionalWithFlagValue and std::optional. - */ - FASTGLTF_EXPORT template - using Optional = std::conditional_t< - !std::is_same_v::missing_value)>>, - OptionalWithFlagValue, - std::optional>; #pragma endregion #pragma region Structs