Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add value_or_cast<U> #49

Open
mgood7123 opened this issue Jul 21, 2021 · 0 comments
Open

add value_or_cast<U> #49

mgood7123 opened this issue Jul 21, 2021 · 0 comments

Comments

@mgood7123
Copy link

mgood7123 commented Jul 21, 2021

add support for value_or_cast

this is useful when using unsigned and signed types

tl::optional<size_t> x = get_PossibleVal();

example 1

// equivalent to:    float a = x.hasValue() ? *x : static_cast<size_t>(NAN);
// ERROR: size_t is unsigned type and will convert to size_t 0
// ERROR: resulting float is [value or 0] instead of [value or NAN]
float a = x.value_or<float>(NAN);

// equivalent to:    float b = x.hasValue() ? static_cast<float>(*x) : NAN;
// resulting float is value or NAN
float b = x.value_or_cast<float>(NAN);

example 2

// equivalent to:    float a = x.hasValue() ? *x : static_cast<size_t>(-1);
// ERROR: size_t is unsigned type and will convert to size_t 18446744073709551615
// ERROR: resulting float is [value or 1.8446744073709551615] instead of [value or -1]
float a = x.value_or<float>(-1);

// equivalent to:    float b = x.hasValue() ? static_cast<float>(*x) : -1;
// resulting float is value or -1
float b = x.value_or_cast<float>(-1);

new code

        /// Returns the stored value if there is one, otherwise returns `u`
        template <class U> constexpr U value_or_cast(U &&u) const & {
            static_assert(std::is_copy_constructible<U>::value &&
                          std::is_convertible<T, U>::value,
                          "U must be copy constructible and convertible from T");
            return has_value() ? static_cast<U>(**this) : std::forward<U>(u);
        }

        /// Returns the stored value if there is one, otherwise returns `u`
        template <class U> TL_OPTIONAL_11_CONSTEXPR U value_or_cast(U &&u) && {
            static_assert(std::is_move_constructible<U>::value &&
                          std::is_convertible<T, U>::value,
                          "U must be move constructible and convertible from T");
            return has_value() ? static_cast<U>(**this) : std::forward<U>(u);
        }
        /// Returns the stored value if there is one, otherwise returns `u`
        template <class U> constexpr U value_or_cast(U &&u) const & noexcept {
            static_assert(std::is_copy_constructible<U>::value &&
                          std::is_convertible<T, U>::value,
                          "U must be copy constructible and convertible from T");
            return has_value() ? static_cast<U>(**this) : std::forward<U>(u);
        }

        /// \group value_or_cast
        template <class U> TL_OPTIONAL_11_CONSTEXPR U value_or_cast(U &&u) && noexcept {
            static_assert(std::is_move_constructible<U>::value &&
                          std::is_convertible<T, U>::value,
                          "U must be move constructible and convertible from T");
            return has_value() ? static_cast<U>(**this) : std::forward<U>(u);
        }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant