microsoft / xlang

MIT License
877 stars 103 forks source link

single_threaded_vector does not work in versions above 190211 #291

Closed kingofthebongo2008 closed 5 years ago

kingofthebongo2008 commented 5 years ago

One needs to import this code from the windows sdk in order to make it compile

namespace winrt::impl { template <typename D, typename T> struct produce<D, wfc::IIterator> : produce_base<D, wfc::IIterator> { int32_t WINRT_CALL get_Current(arg_out current) noexcept final { try { clear_abi(current); typename D::abi_guard guard(this->shim()); *current = detach_from(this->shim().Current()); return error_ok; } catch (...) { return to_hresult(); } }

    int32_t WINRT_CALL get_HasCurrent(bool* hasCurrent) noexcept final
    {
        try
        {
            typename D::abi_guard guard(this->shim());
            *hasCurrent = this->shim().HasCurrent();
            return error_ok;
        }
        catch (...) { return to_hresult(); }
    }

    int32_t WINRT_CALL MoveNext(bool* hasCurrent) noexcept final
    {
        try
        {
            typename D::abi_guard guard(this->shim());
            *hasCurrent = this->shim().MoveNext();
            return error_ok;
        }
        catch (...) { return to_hresult(); }
    }

    int32_t WINRT_CALL GetMany(uint32_t capacity, arg_out<T> value, uint32_t* actual) noexcept final
    {
        try
        {
            clear_abi(value);
            typename D::abi_guard guard(this->shim());
            *actual = this->shim().GetMany(array_view<T>(reinterpret_cast<T*>(value), reinterpret_cast<T*>(value) + capacity));
            return error_ok;
        }
        catch (...) { return to_hresult(); }
    }
};

template <typename D, typename T> struct produce<D, wfc::IIterable<T>> : produce_base<D, wfc::IIterable<T>>
{
    int32_t WINRT_CALL First(void** first) noexcept final
    {
        try
        {
            *first = nullptr;
            typename D::abi_guard guard(this->shim());
            *first = detach_from<wfc::IIterator<T>>(this->shim().First());
            return error_ok;
        }
        catch (...) { return to_hresult(); }
    }
};

template <typename D, typename T> struct produce<D, wfc::IVectorView<T>> : produce_base<D, wfc::IVectorView<T>>
{
    int32_t WINRT_CALL GetAt(uint32_t index, arg_out<T> item) noexcept final
    {
        try
        {
            clear_abi(item);
            typename D::abi_guard guard(this->shim());
            *item = detach_from<T>(this->shim().GetAt(index));
            return error_ok;
        }
        catch (...) { return to_hresult(); }
    }

    int32_t WINRT_CALL get_Size(uint32_t* size) noexcept final
    {
        try
        {
            typename D::abi_guard guard(this->shim());
            *size = this->shim().Size();
            return error_ok;
        }
        catch (...) { return to_hresult(); }
    }

    int32_t WINRT_CALL IndexOf(arg_in<T> value, uint32_t* index, bool* found) noexcept final
    {
        try
        {
            typename D::abi_guard guard(this->shim());
            *found = this->shim().IndexOf(*reinterpret_cast<T const*>(&value), *index);
            return error_ok;
        }
        catch (...) { return to_hresult(); }
    }

    int32_t WINRT_CALL GetMany(uint32_t startIndex, uint32_t capacity, arg_out<T> value, uint32_t* actual) noexcept final
    {
        try
        {
            clear_abi(value);
            typename D::abi_guard guard(this->shim());
            *actual = this->shim().GetMany(startIndex, array_view<T>(reinterpret_cast<T*>(value), reinterpret_cast<T*>(value) + capacity));
            return error_ok;
        }
        catch (...) { return to_hresult(); }
    }
};

template <typename D, typename T> struct produce<D, wfc::IVector<T>> : produce_base<D, wfc::IVector<T>>
{
    int32_t WINRT_CALL GetAt(uint32_t index, arg_out<T> item) noexcept final
    {
        try
        {
            clear_abi(item);
            typename D::abi_guard guard(this->shim());
            *item = detach_from<T>(this->shim().GetAt(index));
            return error_ok;
        }
        catch (...) { return to_hresult(); }
    }

    int32_t WINRT_CALL get_Size(uint32_t* size) noexcept final
    {
        try
        {
            typename D::abi_guard guard(this->shim());
            *size = this->shim().Size();
            return error_ok;
        }
        catch (...) { return to_hresult(); }
    }

    int32_t WINRT_CALL GetView(void** view) noexcept final
    {
        try
        {
            *view = nullptr;
            typename D::abi_guard guard(this->shim());
            *view = detach_from<wfc::IVectorView<T>>(this->shim().GetView());
            return error_ok;
        }
        catch (...) { return to_hresult(); }
    }

    int32_t WINRT_CALL IndexOf(arg_in<T> value, uint32_t* index, bool* found) noexcept final
    {
        try
        {
            typename D::abi_guard guard(this->shim());
            *found = this->shim().IndexOf(*reinterpret_cast<T const*>(&value), *index);
            return error_ok;
        }
        catch (...) { return to_hresult(); }
    }

    int32_t WINRT_CALL SetAt(uint32_t index, arg_in<T> item) noexcept final
    {
        try
        {
            typename D::abi_guard guard(this->shim());
            this->shim().SetAt(index, *reinterpret_cast<T const*>(&item));
            return error_ok;
        }
        catch (...) { return to_hresult(); }
    }

    int32_t WINRT_CALL InsertAt(uint32_t index, arg_in<T> item) noexcept final
    {
        try
        {
            typename D::abi_guard guard(this->shim());
            this->shim().InsertAt(index, *reinterpret_cast<T const*>(&item));
            return error_ok;
        }
        catch (...) { return to_hresult(); }
    }

    int32_t WINRT_CALL RemoveAt(uint32_t index) noexcept final
    {
        try
        {
            typename D::abi_guard guard(this->shim());
            this->shim().RemoveAt(index);
            return error_ok;
        }
        catch (...) { return to_hresult(); }
    }

    int32_t WINRT_CALL Append(arg_in<T> item) noexcept final
    {
        try
        {
            typename D::abi_guard guard(this->shim());
            this->shim().Append(*reinterpret_cast<T const*>(&item));
            return error_ok;
        }
        catch (...) { return to_hresult(); }
    }

    int32_t WINRT_CALL RemoveAtEnd() noexcept final
    {
        try
        {
            typename D::abi_guard guard(this->shim());
            this->shim().RemoveAtEnd();
            return error_ok;
        }
        catch (...) { return to_hresult(); }
    }

    int32_t WINRT_CALL Clear() noexcept final
    {
        try
        {
            typename D::abi_guard guard(this->shim());
            this->shim().Clear();
            return error_ok;
        }
        catch (...) { return to_hresult(); }
    }

    int32_t WINRT_CALL GetMany(uint32_t startIndex, uint32_t capacity, arg_out<T> value, uint32_t* actual) noexcept final
    {
        try
        {
            clear_abi(value);
            typename D::abi_guard guard(this->shim());
            *actual = this->shim().GetMany(startIndex, array_view<T>(reinterpret_cast<T*>(value), reinterpret_cast<T*>(value) + capacity));
            return error_ok;
        }
        catch (...) { return to_hresult(); }
    }

    int32_t WINRT_CALL ReplaceAll(uint32_t count, arg_out<T> item) noexcept final
    {
        try
        {
            typename D::abi_guard guard(this->shim());
            this->shim().ReplaceAll(array_view<T const>(reinterpret_cast<T const*>(item), reinterpret_cast<T const*>(item) + count));
            return error_ok;
        }
        catch (...) { return to_hresult(); }
    }
};

template <typename T, typename Container>
struct input_vector final :
    implements<input_vector<T, Container>, wfc::IVector<T>, wfc::IVectorView<T>, wfc::IIterable<T>>,
    vector_base<input_vector<T, Container>, T>
{
    static_assert(std::is_same_v<Container, std::remove_reference_t<Container>>, "Must be constructed with rvalue.");

    explicit input_vector1(Container&& values) : m_values(std::forward<Container>(values))
    {
    }

    auto& get_container() noexcept
    {
        return m_values;
    }

    auto& get_container() const noexcept
    {
        return m_values;
    }

private:

    Container m_values;
};

}

kennykerr commented 5 years ago

As of C++/WinRT 2.0, you need to include winrt/Windows.Foundation.Collections.h in order to use winrt::single_threaded_vector because this function implements collection interfaces that are defined in this namespace header. I'm working on an update to make the compiler error more understandable, but simply including this header should fix the problem.

kingofthebongo2008 commented 5 years ago

Thank you, I have figured this out. I guess you can close the issue.

On Mon, 8 Apr 2019 at 05:56, Kenny Kerr notifications@github.com wrote:

As of C++/WinRT 2.0, you need to include winrt/Windows.Foundation.Collections.h in order to use winrt::single_threaded_vector because this function implements collection interfaces that are defined in this namespace header. I'm working on an update to make the compiler error more understandable, but simply including this header should fix the problem.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Microsoft/xlang/issues/291#issuecomment-480666097, or mute the thread https://github.com/notifications/unsubscribe-auth/ABF5cbD3gEqMllOnZnPCypKG5jlo3mT5ks5veq_WgaJpZM4cgl2a .