/*** * collection.h - Windows Runtime Collection/Iterator Wrappers * * Copyright (c) Microsoft Corporation. All rights reserved. ****/ #pragma once #ifndef _COLLECTION_H_ #define _COLLECTION_H_ #ifndef RC_INVOKED #ifndef __cplusplus_winrt #error collection.h requires the /ZW compiler option. #endif #include <stddef.h> #include <algorithm> #include <array> #include <exception> #include <functional> #include <iterator> #include <map> #include <memory> #include <new> #include <type_traits> #include <unordered_map> #include <utility> #include <vector> #include <agile.h> #define _COLLECTION_ATTRIBUTES [::Platform::Metadata::RuntimeClassName] [::Windows::Foundation::Metadata::Default] #define _COLLECTION_TRANSLATE \ } catch (const ::std::bad_alloc&) { \ throw ref new OutOfMemoryException; \ } catch (const ::std::exception&) { \ throw ref new FailureException; \ } #ifndef _COLLECTION_WUXI #define _COLLECTION_WUXI 1 #endif #ifdef _WIN64 #pragma pack(push, 16) #else #pragma pack(push, 8) #endif #pragma warning(push, 4) #pragma warning(disable: 4451) // Usage of ref class 'Meow' inside this context can lead to invalid marshaling of object across contexts namespace Platform { namespace Collections { namespace Details { namespace WFC = ::Windows::Foundation::Collections; #if _COLLECTION_WUXI namespace WUXI = ::Windows::UI::Xaml::Interop; #endif // _COLLECTION_WUXI typedef ::Windows::Foundation::EventRegistrationToken Token; inline void ValidateBounds(bool b) { if (!b) { throw ref new OutOfBoundsException; } } inline void ValidateCounter(const ::std::shared_ptr<unsigned int>& ctr, unsigned int good_ctr) { if (*ctr != good_ctr) { throw ref new ChangedStateException; } } inline void ValidateSize(size_t n) { if (n > 0x7FFFFFFFUL) { throw ref new OutOfMemoryException; } } template <typename T> struct AlwaysFalse : public ::std::false_type { }; template <typename T> struct Wrap { typedef T type; }; template <typename T> struct Wrap<T^> : public ::std::conditional<__is_winrt_agile(T), T^, Agile<T^>> { }; template <typename T> inline const T& MakeWrap(const T& t) { return t; } template <typename T> inline typename ::std::enable_if<!__is_winrt_agile(T), Agile<T^>>::type MakeWrap(T^ const & t) { return Agile<T^>(t); } template <typename T> inline const T& Unwrap(const T& t) { return t; } template <typename T> inline T^ Unwrap(const Agile<T^>& a) { return a.Get(); } template <typename T, typename U> struct VectorEnableIf : public ::std::enable_if< ::std::is_same<T, U>::value || ::std::is_same<typename Wrap<T>::type, U>::value, void **> { }; template <typename X> inline void Init(::std::shared_ptr<unsigned int>& ctr, ::std::shared_ptr<X>& sp) { try { ctr = ::std::make_shared<unsigned int>(0); sp = ::std::make_shared<X>(); _COLLECTION_TRANSLATE } template <typename X, typename A> inline void Init(::std::shared_ptr<unsigned int>& ctr, ::std::shared_ptr<X>& sp, A&& a) { try { ctr = ::std::make_shared<unsigned int>(0); sp = ::std::make_shared<X>(::std::forward<A>(a)); ValidateSize(sp->size()); _COLLECTION_TRANSLATE } template <typename X, typename A, typename B> inline void Init(::std::shared_ptr<unsigned int>& ctr, ::std::shared_ptr<X>& sp, A&& a, B&& b) { try { ctr = ::std::make_shared<unsigned int>(0); sp = ::std::make_shared<X>(::std::forward<A>(a), ::std::forward<B>(b)); ValidateSize(sp->size()); _COLLECTION_TRANSLATE } template <typename X, typename A, typename B, typename C> inline void Init(::std::shared_ptr<unsigned int>& ctr, ::std::shared_ptr<X>& sp, A&& a, B&& b, C&& c) { try { ctr = ::std::make_shared<unsigned int>(0); sp = ::std::make_shared<X>(::std::forward<A>(a), ::std::forward<B>(b), ::std::forward<C>(c)); ValidateSize(sp->size()); _COLLECTION_TRANSLATE } template <typename X, typename A> inline void InitMoveVector(::std::shared_ptr<unsigned int>& ctr, ::std::shared_ptr<X>& sp, A&& a) { Init(ctr, sp, a.begin(), a.end()); } template <typename X> inline void InitMoveVector(::std::shared_ptr<unsigned int>& ctr, ::std::shared_ptr<X>& sp, X&& x) { Init(ctr, sp, ::std::move(x)); } template <typename K, typename V, typename M, typename InIt> inline void EmplaceWrappedRange(M& m, InIt first, InIt last) { for ( ; first != last; ++first) { ::std::pair<const K, V> p(*first); m.emplace(MakeWrap(p.first), MakeWrap(p.second)); } } template <typename K, typename V, typename X, typename A> inline void InitMoveMap(::std::shared_ptr<unsigned int>& ctr, ::std::shared_ptr<X>& sp, A&& a) { Init(ctr, sp, a.key_comp()); EmplaceWrappedRange<K, V>(*sp, a.begin(), a.end()); } template <typename K, typename V, typename X> inline void InitMoveMap(::std::shared_ptr<unsigned int>& ctr, ::std::shared_ptr<X>& sp, X&& x) { Init(ctr, sp, ::std::move(x)); } inline void IncrementCounter(::std::shared_ptr<unsigned int>& ctr) { if (++*ctr == static_cast<unsigned int>(-1)) { // Wraparound is imminent! Create a fresh counter. ctr = ::std::make_shared<unsigned int>(0); } } ref class VectorChangedEventArgs sealed : public _COLLECTION_ATTRIBUTES WFC::IVectorChangedEventArgs { internal: VectorChangedEventArgs(WFC::CollectionChange change, unsigned int index) : m_change(change), m_index(index) { } public: virtual property WFC::CollectionChange CollectionChange { virtual WFC::CollectionChange get() { return m_change; } } virtual property unsigned int Index { virtual unsigned int get() { if (m_change == WFC::CollectionChange::Reset) { throw ref new FailureException; } return m_index; } } private: WFC::CollectionChange m_change; unsigned int m_index; }; template <typename K> ref class MapChangedEventArgsReset sealed : public _COLLECTION_ATTRIBUTES WFC::IMapChangedEventArgs<K> { public: virtual property WFC::CollectionChange CollectionChange { virtual WFC::CollectionChange get() { return WFC::CollectionChange::Reset; } } virtual property K Key { virtual K get() { throw ref new FailureException; } } }; template <typename K> ref class MapChangedEventArgs sealed : public _COLLECTION_ATTRIBUTES WFC::IMapChangedEventArgs<K> { internal: MapChangedEventArgs(WFC::CollectionChange change, K key) : m_change(change), m_key(key) { } public: virtual property WFC::CollectionChange CollectionChange { virtual WFC::CollectionChange get() { return m_change; } } virtual property K Key { virtual K get() { return Unwrap(m_key); } } private: WFC::CollectionChange m_change; typename Wrap<K>::type m_key; }; template <typename T, typename E> inline bool VectorIndexOf(const ::std::vector<typename Wrap<T>::type>& v, T value, unsigned int * index) { auto pred = [&](const typename Wrap<T>::type& elem) { return E()(Unwrap(elem), value); }; *index = static_cast<unsigned int>(::std::find_if(v.begin(), v.end(), pred) - v.begin()); return *index < v.size(); } #if _COLLECTION_WUXI template <typename T> struct is_hat : public ::std::false_type { }; template <typename U> struct is_hat<U^> : public ::std::true_type { }; template <typename T, typename E> inline bool VectorBindableIndexOf(::std::false_type, const ::std::vector<typename Wrap<T>::type>& v, Object^ o, unsigned int * index) { IBox<T>^ ib = dynamic_cast<IBox<T>^>(o); if (ib) { return VectorIndexOf<T, E>(v, ib->Value, index); } else { *index = static_cast<unsigned int>(v.size()); return false; } } template <typename T, typename E> inline bool VectorBindableIndexOf(::std::true_type, const ::std::vector<typename Wrap<T>::type>& v, Object^ o, unsigned int * index) { T t = dynamic_cast<T>(o); if (!o || t) { return VectorIndexOf<T, E>(v, t, index); } else { *index = static_cast<unsigned int>(v.size()); return false; } } template <typename T, typename E> inline bool VectorBindableIndexOf(const ::std::vector<typename Wrap<T>::type>& v, Object^ o, unsigned int * index) { return VectorBindableIndexOf<T, E>(is_hat<T>(), v, o, index); } #endif // _COLLECTION_WUXI template <typename T> inline unsigned int VectorGetMany(const ::std::vector<typename Wrap<T>::type>& v, unsigned int startIndex, WriteOnlyArray<T>^ dest) { unsigned int capacity = dest->Length; unsigned int actual = static_cast<unsigned int>(v.size()) - startIndex; if (actual > capacity) { actual = capacity; } for (unsigned int i = 0; i < actual; ++i) { dest->set(i, Unwrap(v[startIndex + i])); } return actual; } template <typename T> ref class IteratorForVectorView sealed : public _COLLECTION_ATTRIBUTES WFC::IIterator<T> #if _COLLECTION_WUXI , public WUXI::IBindableIterator #endif // _COLLECTION_WUXI { private: typedef ::std::vector<typename Wrap<T>::type> WrappedVector; typedef WFC::IIterator<T> WFC_Base; #if _COLLECTION_WUXI typedef WUXI::IBindableIterator WUXI_Base; #endif // _COLLECTION_WUXI internal: IteratorForVectorView(const ::std::shared_ptr<unsigned int>& ctr, const ::std::shared_ptr<WrappedVector>& vec) : m_ctr(ctr), m_vec(vec), m_good_ctr(*ctr), m_index(0) { } public: virtual property T Current { virtual T get() = WFC_Base::Current::get { ValidateCounter(m_ctr, m_good_ctr); ValidateBounds(m_index < m_vec->size()); return Unwrap((*m_vec)[m_index]); } } virtual property bool HasCurrent { virtual bool get() { ValidateCounter(m_ctr, m_good_ctr); return m_index < m_vec->size(); } } virtual bool MoveNext() { ValidateCounter(m_ctr, m_good_ctr); ValidateBounds(m_index < m_vec->size()); ++m_index; return m_index < m_vec->size(); } virtual unsigned int GetMany(WriteOnlyArray<T>^ dest) { ValidateCounter(m_ctr, m_good_ctr); unsigned int actual = VectorGetMany(*m_vec, m_index, dest); m_index += actual; return actual; } private: #if _COLLECTION_WUXI virtual Object^ BindableCurrent() = WUXI_Base::Current::get { return Current; } #endif // _COLLECTION_WUXI ::std::shared_ptr<unsigned int> m_ctr; ::std::shared_ptr<WrappedVector> m_vec; unsigned int m_good_ctr; unsigned int m_index; }; } // namespace Details template <typename T, typename E = ::std::equal_to<T>, bool = __is_valid_winrt_type(T)> ref class Vector; template <typename T, typename E = ::std::equal_to<T>, bool = __is_valid_winrt_type(T)> ref class VectorView; template <typename T, typename E> ref class VectorView<T, E, false> { static_assert(Details::AlwaysFalse<T>::value, "Platform::Collections::VectorView<T, E> requires T to be a valid Windows Runtime type."); }; template <typename T, typename E, bool> ref class VectorView sealed : public _COLLECTION_ATTRIBUTES Details::WFC::IVectorView<T> #if _COLLECTION_WUXI , public Details::WUXI::IBindableVectorView #endif // _COLLECTION_WUXI { private: typedef ::std::vector<typename Details::Wrap<T>::type> WrappedVector; typedef Details::WFC::IVectorView<T> WFC_Base; #if _COLLECTION_WUXI typedef Details::WUXI::IBindableVectorView WUXI_Base; #endif // _COLLECTION_WUXI internal: VectorView() { Details::Init(m_ctr, m_vec); m_good_ctr = 0; } explicit VectorView(unsigned int size) { Details::Init(m_ctr, m_vec, size); m_good_ctr = 0; } VectorView(unsigned int size, T value) { Details::Init(m_ctr, m_vec, size, Details::MakeWrap(value)); m_good_ctr = 0; } template <typename U> explicit VectorView(const ::std::vector<U>& v, typename Details::VectorEnableIf<T, U>::type = nullptr) { Details::Init(m_ctr, m_vec, v.begin(), v.end()); m_good_ctr = 0; } template <typename U> explicit VectorView(::std::vector<U>&& v, typename Details::VectorEnableIf<T, U>::type = nullptr) { Details::InitMoveVector(m_ctr, m_vec, ::std::move(v)); m_good_ctr = 0; } VectorView(const T * ptr, unsigned int size) { Details::Init(m_ctr, m_vec, ptr, ptr + size); m_good_ctr = 0; } template <size_t N> explicit VectorView(const T (&arr)[N]) { Details::Init(m_ctr, m_vec, arr, arr + N); m_good_ctr = 0; } template <size_t N> explicit VectorView(const ::std::array<T, N>& a) { Details::Init(m_ctr, m_vec, a.begin(), a.end()); m_good_ctr = 0; } explicit VectorView(const Array<T>^ arr) { Details::Init(m_ctr, m_vec, arr->begin(), arr->end()); m_good_ctr = 0; } template <typename InIt> VectorView(InIt first, InIt last) { // SFINAE is unnecessary here. Details::Init(m_ctr, m_vec, first, last); m_good_ctr = 0; } VectorView(::std::initializer_list<T> il) { Details::Init(m_ctr, m_vec, il.begin(), il.end()); m_good_ctr = 0; } public: virtual Details::WFC::IIterator<T>^ First() = WFC_Base::First { Details::ValidateCounter(m_ctr, m_good_ctr); return ref new Details::IteratorForVectorView<T>(m_ctr, m_vec); } virtual T GetAt(unsigned int index) = WFC_Base::GetAt { Details::ValidateCounter(m_ctr, m_good_ctr); Details::ValidateBounds(index < m_vec->size()); return Details::Unwrap((*m_vec)[index]); } virtual property unsigned int Size { virtual unsigned int get() { Details::ValidateCounter(m_ctr, m_good_ctr); return static_cast<unsigned int>(m_vec->size()); } } virtual bool IndexOf(T value, unsigned int * index) = WFC_Base::IndexOf { *index = 0; Details::ValidateCounter(m_ctr, m_good_ctr); return Details::VectorIndexOf<T, E>(*m_vec, value, index); } virtual unsigned int GetMany(unsigned int startIndex, WriteOnlyArray<T>^ dest) { Details::ValidateCounter(m_ctr, m_good_ctr); Details::ValidateBounds(startIndex <= m_vec->size()); return Details::VectorGetMany(*m_vec, startIndex, dest); } private: friend ref class Vector<T, E>; VectorView(const ::std::shared_ptr<unsigned int>& ctr, const ::std::shared_ptr<WrappedVector>& vec) : m_ctr(ctr), m_vec(vec), m_good_ctr(*ctr) { } #if _COLLECTION_WUXI virtual Details::WUXI::IBindableIterator^ BindableFirst() = WUXI_Base::First { return safe_cast<Details::WUXI::IBindableIterator^>(First()); } virtual Object^ BindableGetAt(unsigned int index) = WUXI_Base::GetAt { return GetAt(index); } virtual bool BindableIndexOf(Object^ value, unsigned int * index) = WUXI_Base::IndexOf { *index = 0; Details::ValidateCounter(m_ctr, m_good_ctr); return Details::VectorBindableIndexOf<T, E>(*m_vec, value, index); } #endif // _COLLECTION_WUXI ::std::shared_ptr<unsigned int> m_ctr; ::std::shared_ptr<WrappedVector> m_vec; unsigned int m_good_ctr; }; template <typename T, typename E> ref class Vector<T, E, false> { static_assert(Details::AlwaysFalse<T>::value, "Platform::Collections::Vector<T, E> requires T to be a valid Windows Runtime type."); }; template <typename T, typename E, bool> ref class Vector sealed : public _COLLECTION_ATTRIBUTES Details::WFC::IObservableVector<T> #if _COLLECTION_WUXI , public Details::WUXI::IBindableObservableVector #endif // _COLLECTION_WUXI { private: typedef ::std::vector<typename Details::Wrap<T>::type> WrappedVector; typedef Details::WFC::IObservableVector<T> WFC_Base; typedef Details::WFC::VectorChangedEventHandler<T> WFC_Handler; #if _COLLECTION_WUXI typedef Details::WUXI::IBindableObservableVector WUXI_Base; typedef Details::WUXI::BindableVectorChangedEventHandler WUXI_Handler; #endif // _COLLECTION_WUXI internal: Vector() { Details::Init(m_ctr, m_vec); m_observed = false; } explicit Vector(unsigned int size) { Details::Init(m_ctr, m_vec, size); m_observed = false; } Vector(unsigned int size, T value) { Details::Init(m_ctr, m_vec, size, Details::MakeWrap(value)); m_observed = false; } template <typename U> explicit Vector(const ::std::vector<U>& v, typename Details::VectorEnableIf<T, U>::type = nullptr) { Details::Init(m_ctr, m_vec, v.begin(), v.end()); m_observed = false; } template <typename U> explicit Vector(::std::vector<U>&& v, typename Details::VectorEnableIf<T, U>::type = nullptr) { Details::InitMoveVector(m_ctr, m_vec, ::std::move(v)); m_observed = false; } Vector(const T * ptr, unsigned int size) { Details::Init(m_ctr, m_vec, ptr, ptr + size); m_observed = false; } template <size_t N> explicit Vector(const T (&arr)[N]) { Details::Init(m_ctr, m_vec, arr, arr + N); m_observed = false; } template <size_t N> explicit Vector(const ::std::array<T, N>& a) { Details::Init(m_ctr, m_vec, a.begin(), a.end()); m_observed = false; } explicit Vector(const Array<T>^ arr) { Details::Init(m_ctr, m_vec, arr->begin(), arr->end()); m_observed = false; } template <typename InIt> Vector(InIt first, InIt last) { // SFINAE is unnecessary here. Details::Init(m_ctr, m_vec, first, last); m_observed = false; } Vector(::std::initializer_list<T> il) { Details::Init(m_ctr, m_vec, il.begin(), il.end()); m_observed = false; } public: virtual Details::WFC::IIterator<T>^ First() = WFC_Base::First { return ref new Details::IteratorForVectorView<T>(m_ctr, m_vec); } virtual T GetAt(unsigned int index) = WFC_Base::GetAt { Details::ValidateBounds(index < m_vec->size()); return Details::Unwrap((*m_vec)[index]); } virtual property unsigned int Size { virtual unsigned int get() { return static_cast<unsigned int>(m_vec->size()); } } virtual bool IndexOf(T value, unsigned int * index) = WFC_Base::IndexOf { *index = 0; return Details::VectorIndexOf<T, E>(*m_vec, value, index); } virtual unsigned int GetMany(unsigned int startIndex, WriteOnlyArray<T>^ dest) { Details::ValidateBounds(startIndex <= m_vec->size()); return Details::VectorGetMany(*m_vec, startIndex, dest); } virtual Details::WFC::IVectorView<T>^ GetView() = WFC_Base::GetView { return ref new VectorView<T, E>(m_ctr, m_vec); } virtual void SetAt(unsigned int index, T item) = WFC_Base::SetAt { try { Details::IncrementCounter(m_ctr); Details::ValidateBounds(index < m_vec->size()); (*m_vec)[index] = item; NotifyChanged(index); _COLLECTION_TRANSLATE } virtual void InsertAt(unsigned int index, T item) = WFC_Base::InsertAt { try { Details::IncrementCounter(m_ctr); Details::ValidateBounds(index <= m_vec->size()); Details::ValidateSize(m_vec->size() + 1); Emplace(m_vec->begin() + index, item, ::std::is_same<T, bool>()); NotifyInserted(index); _COLLECTION_TRANSLATE } virtual void Append(T item) = WFC_Base::Append { try { Details::IncrementCounter(m_ctr); size_t n = m_vec->size(); Details::ValidateSize(n + 1); EmplaceBack(item, ::std::is_same<T, bool>()); NotifyInserted(static_cast<unsigned int>(n)); _COLLECTION_TRANSLATE } virtual void RemoveAt(unsigned int index) { try { Details::IncrementCounter(m_ctr); Details::ValidateBounds(index < m_vec->size()); m_vec->erase(m_vec->begin() + index); NotifyRemoved(index); _COLLECTION_TRANSLATE } virtual void RemoveAtEnd() { try { Details::IncrementCounter(m_ctr); Details::ValidateBounds(!m_vec->empty()); m_vec->pop_back(); NotifyRemoved(static_cast<unsigned int>(m_vec->size())); _COLLECTION_TRANSLATE } virtual void Clear() { try { Details::IncrementCounter(m_ctr); m_vec->clear(); NotifyReset(); _COLLECTION_TRANSLATE } virtual void ReplaceAll(const Array<T>^ arr) { try { Details::IncrementCounter(m_ctr); Details::ValidateSize(arr->Length); m_vec->assign(arr->begin(), arr->end()); NotifyReset(); _COLLECTION_TRANSLATE } virtual event WFC_Handler^ VectorChanged { virtual Details::Token add(WFC_Handler^ e) = WFC_Base::VectorChanged::add { m_observed = true; return m_wfc_event += e; } virtual void remove(Details::Token t) = WFC_Base::VectorChanged::remove { m_wfc_event -= t; } }; private: template <typename A, typename B> void Emplace(A&& a, B&& b, ::std::false_type) { m_vec->emplace(::std::forward<A>(a), ::std::forward<B>(b)); } template <typename A, typename B> void Emplace(A&& a, B&& b, ::std::true_type) { m_vec->insert(::std::forward<A>(a), ::std::forward<B>(b)); } template <typename A> void EmplaceBack(A&& a, ::std::false_type) { m_vec->emplace_back(::std::forward<A>(a)); } template <typename A> void EmplaceBack(A&& a, ::std::true_type) { m_vec->push_back(::std::forward<A>(a)); } void Notify(Details::WFC::CollectionChange change, unsigned int index) { if (m_observed) { auto args = ref new Details::VectorChangedEventArgs(change, index); m_wfc_event(this, args); #if _COLLECTION_WUXI m_wuxi_event(this, args); #endif // _COLLECTION_WUXI } } void NotifyReset() { Notify(Details::WFC::CollectionChange::Reset, 0); } void NotifyInserted(unsigned int index) { Notify(Details::WFC::CollectionChange::ItemInserted, index); } void NotifyRemoved(unsigned int index) { Notify(Details::WFC::CollectionChange::ItemRemoved, index); } void NotifyChanged(unsigned int index) { Notify(Details::WFC::CollectionChange::ItemChanged, index); } #if _COLLECTION_WUXI virtual Details::WUXI::IBindableIterator^ BindableFirst() = WUXI_Base::First { return safe_cast<Details::WUXI::IBindableIterator^>(First()); } virtual Object^ BindableGetAt(unsigned int index) = WUXI_Base::GetAt { return GetAt(index); } virtual bool BindableIndexOf(Object^ value, unsigned int * index) = WUXI_Base::IndexOf { *index = 0; return Details::VectorBindableIndexOf<T, E>(*m_vec, value, index); } virtual Details::WUXI::IBindableVectorView^ BindableGetView() = WUXI_Base::GetView { return safe_cast<Details::WUXI::IBindableVectorView^>(GetView()); } virtual void BindableSetAt(unsigned int index, Object^ item) = WUXI_Base::SetAt { SetAt(index, safe_cast<T>(item)); } virtual void BindableInsertAt(unsigned int index, Object^ item) = WUXI_Base::InsertAt { InsertAt(index, safe_cast<T>(item)); } virtual void BindableAppend(Object^ item) = WUXI_Base::Append { Append(safe_cast<T>(item)); } virtual Details::Token BindableEventAdd(WUXI_Handler^ e) = WUXI_Base::VectorChanged::add { m_observed = true; return m_wuxi_event += e; } virtual void BindableEventRemove(Details::Token t) = WUXI_Base::VectorChanged::remove { m_wuxi_event -= t; } #endif // _COLLECTION_WUXI ::std::shared_ptr<unsigned int> m_ctr; ::std::shared_ptr<WrappedVector> m_vec; bool m_observed; event WFC_Handler^ m_wfc_event; #if _COLLECTION_WUXI event WUXI_Handler^ m_wuxi_event; #endif // _COLLECTION_WUXI }; namespace Details { template <typename K, typename V> ref class KeyValuePair sealed : public _COLLECTION_ATTRIBUTES WFC::IKeyValuePair<K, V> { internal: KeyValuePair(const typename Wrap<K>::type& key, const typename Wrap<V>::type& value) : m_key(key), m_value(value) { } public: virtual property K Key { virtual K get() { return Unwrap(m_key); } } virtual property V Value { virtual V get() { return Unwrap(m_value); } } private: typename Wrap<K>::type m_key; typename Wrap<V>::type m_value; }; template <typename K, typename F, bool = ::std::is_same<typename Wrap<K>::type, K>::value> class WrapFunc { public: typedef F type; }; template <typename K, typename F> class WrapFunc<K, F, false> { public: typedef WrapFunc type; WrapFunc(const F& func) : m_func(func) { } size_t operator()(const Agile<K>& k) const { return m_func(k.Get()); } bool operator()(const Agile<K>& l, const Agile<K>& r) const { return m_func(l.Get(), r.Get()); } private: F m_func; }; template <typename K, typename V, typename C> struct WrapMap { typedef ::std::map<typename Wrap<K>::type, typename Wrap<V>::type, typename WrapFunc<K, C>::type> type; }; template <typename K, typename V, typename H, typename P> struct WrapUnorderedMap { typedef ::std::unordered_map<typename Wrap<K>::type, typename Wrap<V>::type, typename WrapFunc<K, H>::type, typename WrapFunc<K, P>::type> type; }; template <typename K, typename V, typename WrappedMap> ref class IteratorForAnyMapView sealed : public _COLLECTION_ATTRIBUTES WFC::IIterator<WFC::IKeyValuePair<K, V>^> { internal: IteratorForAnyMapView(const ::std::shared_ptr<unsigned int>& ctr, const ::std::shared_ptr<WrappedMap>& m) : m_ctr(ctr), m_map(m), m_good_ctr(*ctr), m_iter(m->begin()) { } public: virtual property WFC::IKeyValuePair<K, V>^ Current { virtual WFC::IKeyValuePair<K, V>^ get() { ValidateCounter(m_ctr, m_good_ctr); ValidateBounds(m_iter != m_map->end()); return ref new KeyValuePair<K, V>(m_iter->first, m_iter->second); } } virtual property bool HasCurrent { virtual bool get() { ValidateCounter(m_ctr, m_good_ctr); return m_iter != m_map->end(); } } virtual bool MoveNext() { ValidateCounter(m_ctr, m_good_ctr); ValidateBounds(m_iter != m_map->end()); ++m_iter; return m_iter != m_map->end(); } virtual unsigned int GetMany(WriteOnlyArray<WFC::IKeyValuePair<K, V>^>^ dest) { ValidateCounter(m_ctr, m_good_ctr); unsigned int capacity = dest->Length; unsigned int actual = 0; while (capacity > 0 && m_iter != m_map->end()) { dest->set(actual, ref new KeyValuePair<K, V>(m_iter->first, m_iter->second)); ++m_iter; --capacity; ++actual; } return actual; } private: ::std::shared_ptr<unsigned int> m_ctr; ::std::shared_ptr<WrappedMap> m_map; unsigned int m_good_ctr; typename WrappedMap::const_iterator m_iter; }; } // namespace Details template <typename K, typename V, typename C = ::std::less<K>, bool = __is_valid_winrt_type(K), bool = __is_valid_winrt_type(V)> ref class Map; template <typename K, typename V, typename C = ::std::less<K>, bool = __is_valid_winrt_type(K), bool = __is_valid_winrt_type(V)> ref class MapView; template <typename K, typename V, typename H = ::std::hash<K>, typename P = ::std::equal_to<K>, bool = __is_valid_winrt_type(K), bool = __is_valid_winrt_type(V)> ref class UnorderedMap; template <typename K, typename V, typename H = ::std::hash<K>, typename P = ::std::equal_to<K>, bool = __is_valid_winrt_type(K), bool = __is_valid_winrt_type(V)> ref class UnorderedMapView; template <typename K, typename V, typename C> ref class MapView<K, V, C, false, false> { static_assert(Details::AlwaysFalse<K>::value, "Platform::Collections::MapView<K, V, C> requires K and V to be valid Windows Runtime types."); }; template <typename K, typename V, typename C> ref class MapView<K, V, C, false, true> { static_assert(Details::AlwaysFalse<K>::value, "Platform::Collections::MapView<K, V, C> requires K to be a valid Windows Runtime type."); }; template <typename K, typename V, typename C> ref class MapView<K, V, C, true, false> { static_assert(Details::AlwaysFalse<K>::value, "Platform::Collections::MapView<K, V, C> requires V to be a valid Windows Runtime type."); }; template <typename K, typename V, typename C, bool, bool> ref class MapView sealed : public _COLLECTION_ATTRIBUTES Details::WFC::IMapView<K, V> { private: typedef typename Details::WrapMap<K, V, C>::type WrappedMap; typedef Details::IteratorForAnyMapView<K, V, WrappedMap> MyIterator; friend ref class Map<K, V, C>; internal: explicit MapView(const C& comp = C()) { Details::Init(m_ctr, m_map, comp); m_good_ctr = 0; } explicit MapView(const ::std::map<K, V, C>& m) { Details::Init(m_ctr, m_map, m.key_comp()); Details::EmplaceWrappedRange<K, V>(*m_map, m.begin(), m.end()); m_good_ctr = 0; } explicit MapView(::std::map<K, V, C>&& m) { Details::InitMoveMap<K, V>(m_ctr, m_map, ::std::move(m)); m_good_ctr = 0; } template <typename InIt> MapView(InIt first, InIt last, const C& comp = C()) { Details::Init(m_ctr, m_map, comp); Details::EmplaceWrappedRange<K, V>(*m_map, first, last); m_good_ctr = 0; } MapView(::std::initializer_list< ::std::pair<const K, V>> il, const C& comp = C()) { Details::Init(m_ctr, m_map, comp); Details::EmplaceWrappedRange<K, V>(*m_map, il.begin(), il.end()); m_good_ctr = 0; } public: virtual Details::WFC::IIterator<Details::WFC::IKeyValuePair<K, V>^>^ First() { Details::ValidateCounter(m_ctr, m_good_ctr); return ref new MyIterator(m_ctr, m_map); } virtual V Lookup(K key) { Details::ValidateCounter(m_ctr, m_good_ctr); auto i = m_map->find(Details::MakeWrap(key)); Details::ValidateBounds(i != m_map->end()); return Details::Unwrap(i->second); } virtual property unsigned int Size { virtual unsigned int get() { Details::ValidateCounter(m_ctr, m_good_ctr); return static_cast<unsigned int>(m_map->size()); } } virtual bool HasKey(K key) { Details::ValidateCounter(m_ctr, m_good_ctr); return m_map->find(Details::MakeWrap(key)) != m_map->end(); } virtual void Split(Details::WFC::IMapView<K, V>^ * firstPartition, Details::WFC::IMapView<K, V>^ * secondPartition) { *firstPartition = nullptr; *secondPartition = nullptr; Details::ValidateCounter(m_ctr, m_good_ctr); } private: MapView(const ::std::shared_ptr<unsigned int>& ctr, const ::std::shared_ptr<WrappedMap>& m) : m_ctr(ctr), m_map(m), m_good_ctr(*ctr) { } ::std::shared_ptr<unsigned int> m_ctr; ::std::shared_ptr<WrappedMap> m_map; unsigned int m_good_ctr; }; template <typename K, typename V, typename H, typename P> ref class UnorderedMapView<K, V, H, P, false, false> { static_assert(Details::AlwaysFalse<K>::value, "Platform::Collections::UnorderedMapView<K, V, H, P> requires K and V to be valid Windows Runtime types."); }; template <typename K, typename V, typename H, typename P> ref class UnorderedMapView<K, V, H, P, false, true> { static_assert(Details::AlwaysFalse<K>::value, "Platform::Collections::UnorderedMapView<K, V, H, P> requires K to be a valid Windows Runtime type."); }; template <typename K, typename V, typename H, typename P> ref class UnorderedMapView<K, V, H, P, true, false> { static_assert(Details::AlwaysFalse<K>::value, "Platform::Collections::UnorderedMapView<K, V, H, P> requires V to be a valid Windows Runtime type."); }; template <typename K, typename V, typename H, typename P, bool, bool> ref class UnorderedMapView sealed : public _COLLECTION_ATTRIBUTES Details::WFC::IMapView<K, V> { private: typedef typename Details::WrapUnorderedMap<K, V, H, P>::type WrappedMap; typedef Details::IteratorForAnyMapView<K, V, WrappedMap> MyIterator; friend ref class UnorderedMap<K, V, H, P>; internal: UnorderedMapView() { Details::Init(m_ctr, m_map); m_good_ctr = 0; } explicit UnorderedMapView(size_t n) { Details::Init(m_ctr, m_map, n, H(), P()); m_good_ctr = 0; } UnorderedMapView(size_t n, const H& h) { Details::Init(m_ctr, m_map, n, h, P()); m_good_ctr = 0; } UnorderedMapView(size_t n, const H& h, const P& p) { Details::Init(m_ctr, m_map, n, h, p); m_good_ctr = 0; } explicit UnorderedMapView(const ::std::unordered_map<K, V, H, P>& m) { Details::Init(m_ctr, m_map, m.bucket_count(), m.hash_function(), m.key_eq()); Details::EmplaceWrappedRange<K, V>(*m_map, m.begin(), m.end()); m_good_ctr = 0; } explicit UnorderedMapView(::std::unordered_map<K, V, H, P>&& m) { Details::InitMoveMap<K, V>(m_ctr, m_map, ::std::move(m)); m_good_ctr = 0; } template <typename InIt> UnorderedMapView(InIt first, InIt last) { Details::Init(m_ctr, m_map); Details::EmplaceWrappedRange<K, V>(*m_map, first, last); m_good_ctr = 0; } template <typename InIt> UnorderedMapView(InIt first, InIt last, size_t n) { Details::Init(m_ctr, m_map, n, H(), P()); Details::EmplaceWrappedRange<K, V>(*m_map, first, last); m_good_ctr = 0; } template <typename InIt> UnorderedMapView(InIt first, InIt last, size_t n, const H& h) { Details::Init(m_ctr, m_map, n, h, P()); Details::EmplaceWrappedRange<K, V>(*m_map, first, last); m_good_ctr = 0; } template <typename InIt> UnorderedMapView(InIt first, InIt last, size_t n, const H& h, const P& p) { Details::Init(m_ctr, m_map, n, h, p); Details::EmplaceWrappedRange<K, V>(*m_map, first, last); m_good_ctr = 0; } UnorderedMapView(::std::initializer_list< ::std::pair<const K, V>> il) { Details::Init(m_ctr, m_map); Details::EmplaceWrappedRange<K, V>(*m_map, il.begin(), il.end()); m_good_ctr = 0; } UnorderedMapView(::std::initializer_list< ::std::pair<const K, V>> il, size_t n) { Details::Init(m_ctr, m_map, n, H(), P()); Details::EmplaceWrappedRange<K, V>(*m_map, il.begin(), il.end()); m_good_ctr = 0; } UnorderedMapView(::std::initializer_list< ::std::pair<const K, V>> il, size_t n, const H& h) { Details::Init(m_ctr, m_map, n, h, P()); Details::EmplaceWrappedRange<K, V>(*m_map, il.begin(), il.end()); m_good_ctr = 0; } UnorderedMapView(::std::initializer_list< ::std::pair<const K, V>> il, size_t n, const H& h, const P& p) { Details::Init(m_ctr, m_map, n, h, p); Details::EmplaceWrappedRange<K, V>(*m_map, il.begin(), il.end()); m_good_ctr = 0; } public: virtual Details::WFC::IIterator<Details::WFC::IKeyValuePair<K, V>^>^ First() { Details::ValidateCounter(m_ctr, m_good_ctr); return ref new MyIterator(m_ctr, m_map); } virtual V Lookup(K key) { Details::ValidateCounter(m_ctr, m_good_ctr); auto i = m_map->find(Details::MakeWrap(key)); Details::ValidateBounds(i != m_map->end()); return Details::Unwrap(i->second); } virtual property unsigned int Size { virtual unsigned int get() { Details::ValidateCounter(m_ctr, m_good_ctr); return static_cast<unsigned int>(m_map->size()); } } virtual bool HasKey(K key) { Details::ValidateCounter(m_ctr, m_good_ctr); return m_map->find(Details::MakeWrap(key)) != m_map->end(); } virtual void Split(Details::WFC::IMapView<K, V>^ * firstPartition, Details::WFC::IMapView<K, V>^ * secondPartition) { *firstPartition = nullptr; *secondPartition = nullptr; Details::ValidateCounter(m_ctr, m_good_ctr); } private: UnorderedMapView(const ::std::shared_ptr<unsigned int>& ctr, const ::std::shared_ptr<WrappedMap>& m) : m_ctr(ctr), m_map(m), m_good_ctr(*ctr) { } ::std::shared_ptr<unsigned int> m_ctr; ::std::shared_ptr<WrappedMap> m_map; unsigned int m_good_ctr; }; template <typename K, typename V, typename C> ref class Map<K, V, C, false, false> { static_assert(Details::AlwaysFalse<K>::value, "Platform::Collections::Map<K, V, C> requires K and V to be valid Windows Runtime types."); }; template <typename K, typename V, typename C> ref class Map<K, V, C, false, true> { static_assert(Details::AlwaysFalse<K>::value, "Platform::Collections::Map<K, V, C> requires K to be a valid Windows Runtime type."); }; template <typename K, typename V, typename C> ref class Map<K, V, C, true, false> { static_assert(Details::AlwaysFalse<K>::value, "Platform::Collections::Map<K, V, C> requires V to be a valid Windows Runtime type."); }; template <typename K, typename V, typename C, bool, bool> ref class Map sealed : public _COLLECTION_ATTRIBUTES Details::WFC::IObservableMap<K, V> { private: typedef typename Details::WrapMap<K, V, C>::type WrappedMap; typedef Details::IteratorForAnyMapView<K, V, WrappedMap> MyIterator; typedef MapView<K, V, C> MyView; typedef Details::WFC::MapChangedEventHandler<K, V> WFC_Handler; internal: explicit Map(const C& comp = C()) { Details::Init(m_ctr, m_map, comp); m_observed = false; } explicit Map(const ::std::map<K, V, C>& m) { Details::Init(m_ctr, m_map, m.key_comp()); Details::EmplaceWrappedRange<K, V>(*m_map, m.begin(), m.end()); m_observed = false; } explicit Map(::std::map<K, V, C>&& m) { Details::InitMoveMap<K, V>(m_ctr, m_map, ::std::move(m)); m_observed = false; } template <typename InIt> Map(InIt first, InIt last, const C& comp = C()) { Details::Init(m_ctr, m_map, comp); Details::EmplaceWrappedRange<K, V>(*m_map, first, last); m_observed = false; } Map(::std::initializer_list< ::std::pair<const K, V>> il, const C& comp = C()) { Details::Init(m_ctr, m_map, comp); Details::EmplaceWrappedRange<K, V>(*m_map, il.begin(), il.end()); m_observed = false; } public: virtual Details::WFC::IIterator<Details::WFC::IKeyValuePair<K, V>^>^ First() { return ref new MyIterator(m_ctr, m_map); } virtual V Lookup(K key) { auto i = m_map->find(Details::MakeWrap(key)); Details::ValidateBounds(i != m_map->end()); return Details::Unwrap(i->second); } virtual property unsigned int Size { virtual unsigned int get() { return static_cast<unsigned int>(m_map->size()); } } virtual bool HasKey(K key) { return m_map->find(Details::MakeWrap(key)) != m_map->end(); } virtual Details::WFC::IMapView<K, V>^ GetView() { return ref new MyView(m_ctr, m_map); } virtual bool Insert(K key, V value) { try { Details::IncrementCounter(m_ctr); Details::ValidateSize(m_map->size() + 1); auto p = m_map->emplace(Details::MakeWrap(key), Details::MakeWrap(value)); if (p.second) { NotifyInserted(key); } else { p.first->second = value; NotifyChanged(key); } return !p.second; _COLLECTION_TRANSLATE } virtual void Remove(K key) { try { Details::IncrementCounter(m_ctr); Details::ValidateBounds(m_map->erase(Details::MakeWrap(key)) == 1); NotifyRemoved(key); _COLLECTION_TRANSLATE } virtual void Clear() { try { Details::IncrementCounter(m_ctr); m_map->clear(); NotifyReset(); _COLLECTION_TRANSLATE } virtual event WFC_Handler^ MapChanged { virtual Details::Token add(WFC_Handler^ e) { m_observed = true; return m_wfc_event += e; } virtual void remove(Details::Token t) { m_wfc_event -= t; } }; private: void NotifyReset() { if (m_observed) { m_wfc_event(this, ref new Details::MapChangedEventArgsReset<K>); } } void NotifyInserted(K key) { if (m_observed) { m_wfc_event(this, ref new Details::MapChangedEventArgs<K>(Details::WFC::CollectionChange::ItemInserted, key)); } } void NotifyRemoved(K key) { if (m_observed) { m_wfc_event(this, ref new Details::MapChangedEventArgs<K>(Details::WFC::CollectionChange::ItemRemoved, key)); } } void NotifyChanged(K key) { if (m_observed) { m_wfc_event(this, ref new Details::MapChangedEventArgs<K>(Details::WFC::CollectionChange::ItemChanged, key)); } } ::std::shared_ptr<unsigned int> m_ctr; ::std::shared_ptr<WrappedMap> m_map; bool m_observed; event WFC_Handler^ m_wfc_event; }; template <typename K, typename V, typename H, typename P> ref class UnorderedMap<K, V, H, P, false, false> { static_assert(Details::AlwaysFalse<K>::value, "Platform::Collections::UnorderedMap<K, V, H, P> requires K and V to be valid Windows Runtime types."); }; template <typename K, typename V, typename H, typename P> ref class UnorderedMap<K, V, H, P, false, true> { static_assert(Details::AlwaysFalse<K>::value, "Platform::Collections::UnorderedMap<K, V, H, P> requires K to be a valid Windows Runtime type."); }; template <typename K, typename V, typename H, typename P> ref class UnorderedMap<K, V, H, P, true, false> { static_assert(Details::AlwaysFalse<K>::value, "Platform::Collections::UnorderedMap<K, V, H, P> requires V to be a valid Windows Runtime type."); }; template <typename K, typename V, typename H, typename P, bool, bool> ref class UnorderedMap sealed : public _COLLECTION_ATTRIBUTES Details::WFC::IObservableMap<K, V> { private: typedef typename Details::WrapUnorderedMap<K, V, H, P>::type WrappedMap; typedef Details::IteratorForAnyMapView<K, V, WrappedMap> MyIterator; typedef UnorderedMapView<K, V, H, P> MyView; typedef Details::WFC::MapChangedEventHandler<K, V> WFC_Handler; internal: UnorderedMap() { Details::Init(m_ctr, m_map); m_observed = false; } explicit UnorderedMap(size_t n) { Details::Init(m_ctr, m_map, n, H(), P()); m_observed = false; } UnorderedMap(size_t n, const H& h) { Details::Init(m_ctr, m_map, n, h, P()); m_observed = false; } UnorderedMap(size_t n, const H& h, const P& p) { Details::Init(m_ctr, m_map, n, h, p); m_observed = false; } explicit UnorderedMap(const ::std::unordered_map<K, V, H, P>& m) { Details::Init(m_ctr, m_map, m.bucket_count(), m.hash_function(), m.key_eq()); Details::EmplaceWrappedRange<K, V>(*m_map, m.begin(), m.end()); m_observed = false; } explicit UnorderedMap(::std::unordered_map<K, V, H, P>&& m) { Details::InitMoveMap<K, V>(m_ctr, m_map, ::std::move(m)); m_observed = false; } template <typename InIt> UnorderedMap(InIt first, InIt last) { Details::Init(m_ctr, m_map); Details::EmplaceWrappedRange<K, V>(*m_map, first, last); m_observed = false; } template <typename InIt> UnorderedMap(InIt first, InIt last, size_t n) { Details::Init(m_ctr, m_map, n, H(), P()); Details::EmplaceWrappedRange<K, V>(*m_map, first, last); m_observed = false; } template <typename InIt> UnorderedMap(InIt first, InIt last, size_t n, const H& h) { Details::Init(m_ctr, m_map, n, h, P()); Details::EmplaceWrappedRange<K, V>(*m_map, first, last); m_observed = false; } template <typename InIt> UnorderedMap(InIt first, InIt last, size_t n, const H& h, const P& p) { Details::Init(m_ctr, m_map, n, h, p); Details::EmplaceWrappedRange<K, V>(*m_map, first, last); m_observed = false; } UnorderedMap(::std::initializer_list< ::std::pair<const K, V>> il) { Details::Init(m_ctr, m_map); Details::EmplaceWrappedRange<K, V>(*m_map, il.begin(), il.end()); m_observed = false; } UnorderedMap(::std::initializer_list< ::std::pair<const K, V>> il, size_t n) { Details::Init(m_ctr, m_map, n, H(), P()); Details::EmplaceWrappedRange<K, V>(*m_map, il.begin(), il.end()); m_observed = false; } UnorderedMap(::std::initializer_list< ::std::pair<const K, V>> il, size_t n, const H& h) { Details::Init(m_ctr, m_map, n, h, P()); Details::EmplaceWrappedRange<K, V>(*m_map, il.begin(), il.end()); m_observed = false; } UnorderedMap(::std::initializer_list< ::std::pair<const K, V>> il, size_t n, const H& h, const P& p) { Details::Init(m_ctr, m_map, n, h, p); Details::EmplaceWrappedRange<K, V>(*m_map, il.begin(), il.end()); m_observed = false; } public: virtual Details::WFC::IIterator<Details::WFC::IKeyValuePair<K, V>^>^ First() { return ref new MyIterator(m_ctr, m_map); } virtual V Lookup(K key) { auto i = m_map->find(Details::MakeWrap(key)); Details::ValidateBounds(i != m_map->end()); return Details::Unwrap(i->second); } virtual property unsigned int Size { virtual unsigned int get() { return static_cast<unsigned int>(m_map->size()); } } virtual bool HasKey(K key) { return m_map->find(Details::MakeWrap(key)) != m_map->end(); } virtual Details::WFC::IMapView<K, V>^ GetView() { return ref new MyView(m_ctr, m_map); } virtual bool Insert(K key, V value) { try { Details::IncrementCounter(m_ctr); Details::ValidateSize(m_map->size() + 1); auto p = m_map->emplace(Details::MakeWrap(key), Details::MakeWrap(value)); if (p.second) { NotifyInserted(key); } else { p.first->second = value; NotifyChanged(key); } return !p.second; _COLLECTION_TRANSLATE } virtual void Remove(K key) { try { Details::IncrementCounter(m_ctr); Details::ValidateBounds(m_map->erase(Details::MakeWrap(key)) == 1); NotifyRemoved(key); _COLLECTION_TRANSLATE } virtual void Clear() { try { Details::IncrementCounter(m_ctr); m_map->clear(); NotifyReset(); _COLLECTION_TRANSLATE } virtual event WFC_Handler^ MapChanged { virtual Details::Token add(WFC_Handler^ e) { m_observed = true; return m_wfc_event += e; } virtual void remove(Details::Token t) { m_wfc_event -= t; } }; private: void NotifyReset() { if (m_observed) { m_wfc_event(this, ref new Details::MapChangedEventArgsReset<K>); } } void NotifyInserted(K key) { if (m_observed) { m_wfc_event(this, ref new Details::MapChangedEventArgs<K>(Details::WFC::CollectionChange::ItemInserted, key)); } } void NotifyRemoved(K key) { if (m_observed) { m_wfc_event(this, ref new Details::MapChangedEventArgs<K>(Details::WFC::CollectionChange::ItemRemoved, key)); } } void NotifyChanged(K key) { if (m_observed) { m_wfc_event(this, ref new Details::MapChangedEventArgs<K>(Details::WFC::CollectionChange::ItemChanged, key)); } } ::std::shared_ptr<unsigned int> m_ctr; ::std::shared_ptr<WrappedMap> m_map; bool m_observed; event WFC_Handler^ m_wfc_event; }; template <typename X> class InputIterator; template <typename T> class VectorIterator; template <typename T> class VectorViewIterator; template <typename T> class BackInsertIterator; } // namespace Collections } // namespace Platform template <typename X> struct ::std::_Is_checked_helper< ::Platform::Collections::InputIterator<X>> : public ::std::true_type { }; template <typename T> struct ::std::_Is_checked_helper< ::Platform::Collections::VectorIterator<T>> : public ::std::true_type { }; template <typename T> struct ::std::_Is_checked_helper< ::Platform::Collections::VectorViewIterator<T>> : public ::std::true_type { }; template <typename T> struct ::std::_Is_checked_helper< ::Platform::Collections::BackInsertIterator<T>> : public ::std::true_type { }; namespace Platform { namespace Collections { template <typename X> class InputIterator { public: typedef ::std::input_iterator_tag iterator_category; typedef X value_type; typedef ptrdiff_t difference_type; typedef const X * pointer; typedef const X & reference; InputIterator() { } explicit InputIterator(Details::WFC::IIterator<X>^ iter) { if (iter->HasCurrent) { m_iter = iter; m_val = iter->Current; } } bool operator==(const InputIterator& other) const { return !!m_iter == !!other.m_iter; } bool operator!=(const InputIterator& other) const { return !(*this == other); } reference operator*() const { return m_val; } pointer operator->() const { return &m_val; } InputIterator& operator++() { if (m_iter->MoveNext()) { m_val = m_iter->Current; } else { m_iter = nullptr; } return *this; } InputIterator operator++(int) { InputIterator old(*this); ++*this; return old; } private: Details::WFC::IIterator<X>^ m_iter; X m_val; }; namespace Details { template <typename T> class VectorProxy { public: VectorProxy(WFC::IVector<T>^ v, ptrdiff_t n) : m_v(v), m_i(static_cast<unsigned int>(n)) { } VectorProxy& operator=(const VectorProxy& other) { m_v->SetAt(m_i, other.m_v->GetAt(other.m_i)); return *this; } VectorProxy& operator=(T t) { m_v->SetAt(m_i, t); return *this; } operator T() const { return m_v->GetAt(m_i); } T operator->() const { return m_v->GetAt(m_i); } void swap(const VectorProxy& other) const { T t1(m_v->GetAt(m_i)); T t2(other.m_v->GetAt(other.m_i)); m_v->SetAt(m_i, t2); other.m_v->SetAt(other.m_i, t1); } void swap(T& t) const { T temp(t); t = m_v->GetAt(m_i); m_v->SetAt(m_i, temp); } private: WFC::IVector<T>^ m_v; unsigned int m_i; }; template <typename T> inline void swap(const VectorProxy<T>& l, const VectorProxy<T>& r) { l.swap(r); } template <typename T> inline void swap(const VectorProxy<T>& p, T& t) { p.swap(t); } template <typename T> inline void swap(T& t, const VectorProxy<T>& p) { p.swap(t); } template <typename T> inline bool operator==(const VectorProxy<T>& l, const VectorProxy<T>& r) { return static_cast<T>(l) == static_cast<T>(r); } template <typename T> inline bool operator==(const VectorProxy<T>& l, const T& t) { return static_cast<T>(l) == t; } template <typename T> inline bool operator==(const T& t, const VectorProxy<T>& r) { return t == static_cast<T>(r); } template <typename T> inline bool operator!=(const VectorProxy<T>& l, const VectorProxy<T>& r) { return static_cast<T>(l) != static_cast<T>(r); } template <typename T> inline bool operator!=(const VectorProxy<T>& l, const T& t) { return static_cast<T>(l) != t; } template <typename T> inline bool operator!=(const T& t, const VectorProxy<T>& r) { return t != static_cast<T>(r); } template <typename T> inline bool operator<(const VectorProxy<T>& l, const VectorProxy<T>& r) { return static_cast<T>(l) < static_cast<T>(r); } template <typename T> inline bool operator<(const VectorProxy<T>& l, const T& t) { return static_cast<T>(l) < t; } template <typename T> inline bool operator<(const T& t, const VectorProxy<T>& r) { return t < static_cast<T>(r); } template <typename T> inline bool operator<=(const VectorProxy<T>& l, const VectorProxy<T>& r) { return static_cast<T>(l) <= static_cast<T>(r); } template <typename T> inline bool operator<=(const VectorProxy<T>& l, const T& t) { return static_cast<T>(l) <= t; } template <typename T> inline bool operator<=(const T& t, const VectorProxy<T>& r) { return t <= static_cast<T>(r); } template <typename T> inline bool operator>(const VectorProxy<T>& l, const VectorProxy<T>& r) { return static_cast<T>(l) > static_cast<T>(r); } template <typename T> inline bool operator>(const VectorProxy<T>& l, const T& t) { return static_cast<T>(l) > t; } template <typename T> inline bool operator>(const T& t, const VectorProxy<T>& r) { return t > static_cast<T>(r); } template <typename T> inline bool operator>=(const VectorProxy<T>& l, const VectorProxy<T>& r) { return static_cast<T>(l) >= static_cast<T>(r); } template <typename T> inline bool operator>=(const VectorProxy<T>& l, const T& t) { return static_cast<T>(l) >= t; } template <typename T> inline bool operator>=(const T& t, const VectorProxy<T>& r) { return t >= static_cast<T>(r); } template <typename T> class ArrowProxy { public: explicit ArrowProxy(T t) : m_val(t) { } const T * operator->() const { return &m_val; } private: T m_val; }; } // namespace Details template <typename T> class VectorIterator { public: typedef ::std::random_access_iterator_tag iterator_category; typedef T value_type; typedef ptrdiff_t difference_type; typedef Details::VectorProxy<T> * pointer; typedef Details::VectorProxy<T> reference; VectorIterator() : m_v(nullptr), m_i(0) { } explicit VectorIterator(Details::WFC::IVector<T>^ v) : m_v(v), m_i(0) { } reference operator*() const { return reference(m_v, m_i); } Details::ArrowProxy<T> operator->() const { return Details::ArrowProxy<T>(m_v->GetAt(static_cast<unsigned int>(m_i))); } reference operator[](difference_type n) const { return reference(m_v, m_i + n); } VectorIterator& operator++() { ++m_i; return *this; } VectorIterator& operator--() { --m_i; return *this; } VectorIterator operator++(int) { VectorIterator old(*this); ++*this; return old; } VectorIterator operator--(int) { VectorIterator old(*this); --*this; return old; } VectorIterator& operator+=(difference_type n) { m_i += n; return *this; } VectorIterator& operator-=(difference_type n) { m_i -= n; return *this; } VectorIterator operator+(difference_type n) const { VectorIterator ret(*this); ret += n; return ret; } VectorIterator operator-(difference_type n) const { VectorIterator ret(*this); ret -= n; return ret; } difference_type operator-(const VectorIterator& other) const { return m_i - other.m_i; } bool operator==(const VectorIterator& other) const { return m_i == other.m_i; } bool operator!=(const VectorIterator& other) const { return m_i != other.m_i; } bool operator<(const VectorIterator& other) const { return m_i < other.m_i; } bool operator>(const VectorIterator& other) const { return m_i > other.m_i; } bool operator<=(const VectorIterator& other) const { return m_i <= other.m_i; } bool operator>=(const VectorIterator& other) const { return m_i >= other.m_i; } private: Details::WFC::IVector<T>^ m_v; difference_type m_i; }; template <typename T> inline VectorIterator<T> operator+(ptrdiff_t n, const VectorIterator<T>& i) { return i + n; } template <typename T> class VectorViewIterator { public: typedef ::std::random_access_iterator_tag iterator_category; typedef T value_type; typedef ptrdiff_t difference_type; typedef T * pointer; typedef T reference; VectorViewIterator() : m_v(nullptr), m_i(0) { } explicit VectorViewIterator(Details::WFC::IVectorView<T>^ v) : m_v(v), m_i(0) { } reference operator*() const { return m_v->GetAt(static_cast<unsigned int>(m_i)); } Details::ArrowProxy<T> operator->() const { return Details::ArrowProxy<T>(m_v->GetAt(static_cast<unsigned int>(m_i))); } reference operator[](difference_type n) const { return m_v->GetAt(static_cast<unsigned int>(m_i + n)); } VectorViewIterator& operator++() { ++m_i; return *this; } VectorViewIterator& operator--() { --m_i; return *this; } VectorViewIterator operator++(int) { VectorViewIterator old(*this); ++*this; return old; } VectorViewIterator operator--(int) { VectorViewIterator old(*this); --*this; return old; } VectorViewIterator& operator+=(difference_type n) { m_i += n; return *this; } VectorViewIterator& operator-=(difference_type n) { m_i -= n; return *this; } VectorViewIterator operator+(difference_type n) const { VectorViewIterator ret(*this); ret += n; return ret; } VectorViewIterator operator-(difference_type n) const { VectorViewIterator ret(*this); ret -= n; return ret; } difference_type operator-(const VectorViewIterator& other) const { return m_i - other.m_i; } bool operator==(const VectorViewIterator& other) const { return m_i == other.m_i; } bool operator!=(const VectorViewIterator& other) const { return m_i != other.m_i; } bool operator<(const VectorViewIterator& other) const { return m_i < other.m_i; } bool operator>(const VectorViewIterator& other) const { return m_i > other.m_i; } bool operator<=(const VectorViewIterator& other) const { return m_i <= other.m_i; } bool operator>=(const VectorViewIterator& other) const { return m_i >= other.m_i; } private: Details::WFC::IVectorView<T>^ m_v; difference_type m_i; }; template <typename T> inline VectorViewIterator<T> operator+(ptrdiff_t n, const VectorViewIterator<T>& i) { return i + n; } template <typename T> class BackInsertIterator : public ::std::iterator< ::std::output_iterator_tag, void, void, void, void> { public: explicit BackInsertIterator(Details::WFC::IVector<T>^ v) : m_v(v) { } BackInsertIterator& operator=(const T& t) { m_v->Append(t); return *this; } BackInsertIterator& operator*() { return *this; } BackInsertIterator& operator++() { return *this; } BackInsertIterator operator++(int) { return *this; } private: Details::WFC::IVector<T>^ m_v; }; namespace Details { template <typename T, typename I> inline ::std::vector<T> ToVector(I^ v) { unsigned int size = v->Size; ::std::vector<T> ret(size); for (unsigned int actual = 0; actual < size; ) { Array<T>^ arr = ref new Array<T>(size - actual); unsigned int n = v->GetMany(actual, arr); if (n == 0) { throw ref new FailureException; } ::std::copy_n(arr->begin(), n, ret.begin() + actual); actual += n; } return ret; } } // namespace Details } // namespace Collections } // namespace Platform namespace Windows { namespace Foundation { namespace Collections { template <typename X> inline ::Platform::Collections::InputIterator<X> begin(IIterable<X>^ i) { return ::Platform::Collections::InputIterator<X>(i->First()); } template <typename X> inline ::Platform::Collections::InputIterator<X> end(IIterable<X>^) { return ::Platform::Collections::InputIterator<X>(); } template <typename T> inline ::Platform::Collections::VectorIterator<T> begin(IVector<T>^ v) { return ::Platform::Collections::VectorIterator<T>(v); } template <typename T> inline ::Platform::Collections::VectorIterator<T> end(IVector<T>^ v) { return ::Platform::Collections::VectorIterator<T>(v) + v->Size; } template <typename T> inline ::Platform::Collections::VectorViewIterator<T> begin(IVectorView<T>^ v) { return ::Platform::Collections::VectorViewIterator<T>(v); } template <typename T> inline ::Platform::Collections::VectorViewIterator<T> end(IVectorView<T>^ v) { return ::Platform::Collections::VectorViewIterator<T>(v) + v->Size; } template <typename T> inline ::std::vector<T> to_vector(IVector<T>^ v) { return ::Platform::Collections::Details::ToVector<T>(v); } template <typename T> inline ::std::vector<T> to_vector(IVectorView<T>^ v) { return ::Platform::Collections::Details::ToVector<T>(v); } template <typename T> inline ::Platform::Collections::BackInsertIterator<T> back_inserter(IVector<T>^ v) { return ::Platform::Collections::BackInsertIterator<T>(v); } template <typename T> inline ::Platform::Collections::BackInsertIterator<T> back_inserter(IObservableVector<T>^ v) { return ::Platform::Collections::BackInsertIterator<T>(v); } } // namespace Collections } // namespace Foundation } // namespace Windows namespace Platform { namespace Collections { template <typename T, typename E> inline BackInsertIterator<T> back_inserter(Vector<T, E>^ v) { return BackInsertIterator<T>(v); } } // namespace Collections } // namespace Platform template <> struct ::std::hash< ::Platform::String^> : public ::std::unary_function< ::Platform::String^, size_t> { size_t operator()(::Platform::String^ s) const { return ::std::_Hash_seq(reinterpret_cast<const unsigned char *>(s->Data()), s->Length() * sizeof(wchar_t)); } }; #undef _COLLECTION_ATTRIBUTES #undef _COLLECTION_TRANSLATE #undef _COLLECTION_WUXI #pragma warning(pop) #pragma pack(pop) #endif // RC_INVOKED #endif // _COLLECTION_H_