// Copyright 2019 Microsoft Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef WEAK_SINGLE_THREADED_ITERABLE_H_ #define WEAK_SINGLE_THREADED_ITERABLE_H_ #include #include namespace Microsoft { namespace AI { namespace MachineLearning { namespace Details { template struct weak_single_threaded_iterable : public Microsoft::WRL::RuntimeClass< Microsoft::WRL::RuntimeClassFlags, ABI::Windows::Foundation::Collections::IIterable> { private: const T* m_p_begin; const T* m_p_end; public: HRESULT RuntimeClassInitialize(_In_ const T* p_begin, _In_ const T* p_end) { m_p_begin = p_begin; m_p_end = p_end; return S_OK; } virtual HRESULT STDMETHODCALLTYPE First( _Outptr_result_maybenull_ ABI::Windows::Foundation::Collections::IIterator** first) { if (first == nullptr) { return E_POINTER; } Microsoft::WRL::ComPtr iterator; auto hr = Microsoft::WRL::MakeAndInitialize( &iterator, this); if (FAILED(hr)) { return hr; } return iterator.CopyTo(first); } HRESULT Size(unsigned* p_size) { if (p_size == nullptr) { return E_POINTER; } *p_size = static_cast(m_p_end - m_p_begin); return S_OK; } HRESULT At(unsigned index, _Out_ T* p_current) { if (p_current == nullptr) { return E_POINTER; } *p_current = *(m_p_begin + index); return S_OK; } HRESULT Has(unsigned index, _Out_ boolean* p_has_current) { if (p_has_current == nullptr) { return E_POINTER; } unsigned size; auto hr = Size(&size); if (FAILED(hr)) { return hr; } *p_has_current = index < size; return S_OK; } struct weak_single_threaded_iterator : public Microsoft::WRL::RuntimeClass< Microsoft::WRL::RuntimeClassFlags, ABI::Windows::Foundation::Collections::IIterator> { private: Microsoft::WRL::ComPtr m_weak_single_threaded_iterable; unsigned m_current = 0; public: HRESULT RuntimeClassInitialize( _In_ weak_single_threaded_iterable* p_weak_single_threaded_iterable) { m_weak_single_threaded_iterable = p_weak_single_threaded_iterable; return S_OK; } virtual /* propget */ HRESULT STDMETHODCALLTYPE get_Current(_Out_ T* current) { return m_weak_single_threaded_iterable->At(m_current, current); } virtual /* propget */ HRESULT STDMETHODCALLTYPE get_HasCurrent(_Out_ boolean* hasCurrent) { return m_weak_single_threaded_iterable->Has(m_current, hasCurrent); } virtual HRESULT STDMETHODCALLTYPE MoveNext(_Out_ boolean* hasCurrent) { if (SUCCEEDED( m_weak_single_threaded_iterable->Has(m_current, hasCurrent)) && *hasCurrent) { m_current++; return m_weak_single_threaded_iterable->Has(m_current, hasCurrent); } return S_OK; } }; }; }}}} // namespace Microsoft::AI::MachineLearning::Details #endif // WEAK_SINGLE_THREADED_ITERABLE_H_