STLdoc
STLdocumentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
collection.h
Go to the documentation of this file.
1 /***
2 * collection.h - Windows Runtime Collection/Iterator Wrappers
3 *
4 * Copyright (c) Microsoft Corporation. All rights reserved.
5 ****/
6 
7 #pragma once
8 
9 #ifndef _COLLECTION_H_
10 #define _COLLECTION_H_
11 
12 #ifndef RC_INVOKED
13 
14 #ifndef __cplusplus_winrt
15  #error collection.h requires the /ZW compiler option.
16 #endif
17 
18 #include <stddef.h>
19 #include <algorithm>
20 #include <array>
21 #include <exception>
22 #include <functional>
23 #include <iterator>
24 #include <map>
25 #include <memory>
26 #include <new>
27 #include <type_traits>
28 #include <unordered_map>
29 #include <utility>
30 #include <vector>
31 #include <agile.h>
32 
33 #define _COLLECTION_ATTRIBUTES [::Platform::Metadata::RuntimeClassName] [::Windows::Foundation::Metadata::Default]
34 
35 #define _COLLECTION_TRANSLATE \
36 } catch (const ::std::bad_alloc&) { \
37  throw ref new OutOfMemoryException; \
38 } catch (const ::std::exception&) { \
39  throw ref new FailureException; \
40 }
41 
42 #ifndef _COLLECTION_WUXI
43  #define _COLLECTION_WUXI 1
44 #endif
45 
46 #ifdef _WIN64
47  #pragma pack(push, 16)
48 #else
49  #pragma pack(push, 8)
50 #endif
51 
52 #pragma warning(push, 4)
53 
54 #pragma warning(disable: 4451) // Usage of ref class 'Meow' inside this context can lead to invalid marshaling of object across contexts
55 
56 namespace Platform {
57  namespace Collections {
58  namespace Details {
59  namespace WFC = ::Windows::Foundation::Collections;
60 
61 #if _COLLECTION_WUXI
62  namespace WUXI = ::Windows::UI::Xaml::Interop;
63 #endif // _COLLECTION_WUXI
64 
65  typedef ::Windows::Foundation::EventRegistrationToken Token;
66 
67  inline void ValidateBounds(bool b) {
68  if (!b) {
69  throw ref new OutOfBoundsException;
70  }
71  }
72 
73  inline void ValidateCounter(const ::std::shared_ptr<unsigned int>& ctr, unsigned int good_ctr) {
74  if (*ctr != good_ctr) {
75  throw ref new ChangedStateException;
76  }
77  }
78 
79  inline void ValidateSize(size_t n) {
80  if (n > 0x7FFFFFFFUL) {
81  throw ref new OutOfMemoryException;
82  }
83  }
84 
85  template <typename T> struct AlwaysFalse
86  : public ::std::false_type { };
87 
88  template <typename T> struct Wrap {
89  typedef T type;
90  };
91 
92  template <typename T> struct Wrap<T^>
93  : public ::std::conditional<__is_winrt_agile(T), T^, Agile<T^>> { };
94 
95  template <typename T> inline const T& MakeWrap(const T& t) {
96  return t;
97  }
98 
99  template <typename T> inline typename ::std::enable_if<!__is_winrt_agile(T), Agile<T^>>::type MakeWrap(T^ const & t) {
100  return Agile<T^>(t);
101  }
102 
103  template <typename T> inline const T& Unwrap(const T& t) {
104  return t;
105  }
106 
107  template <typename T> inline T^ Unwrap(const Agile<T^>& a) {
108  return a.Get();
109  }
110 
111  template <typename T, typename U> struct VectorEnableIf
112  : public ::std::enable_if< ::std::is_same<T, U>::value || ::std::is_same<typename Wrap<T>::type, U>::value, void **> { };
113 
114  template <typename X> inline void Init(::std::shared_ptr<unsigned int>& ctr, ::std::shared_ptr<X>& sp) {
115  try {
116  ctr = ::std::make_shared<unsigned int>(0);
117  sp = ::std::make_shared<X>();
119  }
120 
121  template <typename X, typename A> inline void Init(::std::shared_ptr<unsigned int>& ctr, ::std::shared_ptr<X>& sp, A&& a) {
122  try {
123  ctr = ::std::make_shared<unsigned int>(0);
124  sp = ::std::make_shared<X>(::std::forward<A>(a));
125 
126  ValidateSize(sp->size());
128  }
129 
130  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) {
131  try {
132  ctr = ::std::make_shared<unsigned int>(0);
133  sp = ::std::make_shared<X>(::std::forward<A>(a), ::std::forward<B>(b));
134 
135  ValidateSize(sp->size());
137  }
138 
139  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) {
140  try {
141  ctr = ::std::make_shared<unsigned int>(0);
142  sp = ::std::make_shared<X>(::std::forward<A>(a), ::std::forward<B>(b), ::std::forward<C>(c));
143 
144  ValidateSize(sp->size());
146  }
147 
148  template <typename X, typename A> inline void InitMoveVector(::std::shared_ptr<unsigned int>& ctr, ::std::shared_ptr<X>& sp, A&& a) {
149  Init(ctr, sp, a.begin(), a.end());
150  }
151 
152  template <typename X> inline void InitMoveVector(::std::shared_ptr<unsigned int>& ctr, ::std::shared_ptr<X>& sp, X&& x) {
153  Init(ctr, sp, ::std::move(x));
154  }
155 
156  template <typename K, typename V, typename M, typename InIt> inline void EmplaceWrappedRange(M& m, InIt first, InIt last) {
157  for ( ; first != last; ++first) {
158  ::std::pair<const K, V> p(*first);
159 
160  m.emplace(MakeWrap(p.first), MakeWrap(p.second));
161  }
162  }
163 
164  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) {
165  Init(ctr, sp, a.key_comp());
166 
167  EmplaceWrappedRange<K, V>(*sp, a.begin(), a.end());
168  }
169 
170  template <typename K, typename V, typename X> inline void InitMoveMap(::std::shared_ptr<unsigned int>& ctr, ::std::shared_ptr<X>& sp, X&& x) {
171  Init(ctr, sp, ::std::move(x));
172  }
173 
174  inline void IncrementCounter(::std::shared_ptr<unsigned int>& ctr) {
175  if (++*ctr == static_cast<unsigned int>(-1)) {
176  // Wraparound is imminent! Create a fresh counter.
177  ctr = ::std::make_shared<unsigned int>(0);
178  }
179  }
180 
181  ref class VectorChangedEventArgs sealed : public _COLLECTION_ATTRIBUTES WFC::IVectorChangedEventArgs {
182  internal:
183  VectorChangedEventArgs(WFC::CollectionChange change, unsigned int index)
184  : m_change(change), m_index(index) { }
185 
186  public:
187  virtual property WFC::CollectionChange CollectionChange {
188  virtual WFC::CollectionChange get() {
189  return m_change;
190  }
191  }
192 
193  virtual property unsigned int Index {
194  virtual unsigned int get() {
195  if (m_change == WFC::CollectionChange::Reset) {
196  throw ref new FailureException;
197  }
198 
199  return m_index;
200  }
201  }
202 
203  private:
204  WFC::CollectionChange m_change;
205  unsigned int m_index;
206  };
207 
208  template <typename K> ref class MapChangedEventArgsReset sealed : public _COLLECTION_ATTRIBUTES WFC::IMapChangedEventArgs<K> {
209  public:
210  virtual property WFC::CollectionChange CollectionChange {
211  virtual WFC::CollectionChange get() {
212  return WFC::CollectionChange::Reset;
213  }
214  }
215 
216  virtual property K Key {
217  virtual K get() {
218  throw ref new FailureException;
219  }
220  }
221  };
222 
223  template <typename K> ref class MapChangedEventArgs sealed : public _COLLECTION_ATTRIBUTES WFC::IMapChangedEventArgs<K> {
224  internal:
225  MapChangedEventArgs(WFC::CollectionChange change, K key)
226  : m_change(change), m_key(key) { }
227 
228  public:
229  virtual property WFC::CollectionChange CollectionChange {
230  virtual WFC::CollectionChange get() {
231  return m_change;
232  }
233  }
234 
235  virtual property K Key {
236  virtual K get() {
237  return Unwrap(m_key);
238  }
239  }
240 
241  private:
242  WFC::CollectionChange m_change;
243  typename Wrap<K>::type m_key;
244  };
245 
246  template <typename T, typename E> inline bool VectorIndexOf(const ::std::vector<typename Wrap<T>::type>& v, T value, unsigned int * index) {
247  auto pred = [&](const typename Wrap<T>::type& elem) { return E()(Unwrap(elem), value); };
248 
249  *index = static_cast<unsigned int>(::std::find_if(v.begin(), v.end(), pred) - v.begin());
250 
251  return *index < v.size();
252  }
253 
254 #if _COLLECTION_WUXI
255  template <typename T> struct is_hat : public ::std::false_type { };
256 
257  template <typename U> struct is_hat<U^> : public ::std::true_type { };
258 
259  template <typename T, typename E> inline bool VectorBindableIndexOf(::std::false_type, const ::std::vector<typename Wrap<T>::type>& v, Object^ o, unsigned int * index) {
260  IBox<T>^ ib = dynamic_cast<IBox<T>^>(o);
261 
262  if (ib) {
263  return VectorIndexOf<T, E>(v, ib->Value, index);
264  } else {
265  *index = static_cast<unsigned int>(v.size());
266  return false;
267  }
268  }
269 
270  template <typename T, typename E> inline bool VectorBindableIndexOf(::std::true_type, const ::std::vector<typename Wrap<T>::type>& v, Object^ o, unsigned int * index) {
271  T t = dynamic_cast<T>(o);
272 
273  if (!o || t) {
274  return VectorIndexOf<T, E>(v, t, index);
275  } else {
276  *index = static_cast<unsigned int>(v.size());
277  return false;
278  }
279  }
280 
281  template <typename T, typename E> inline bool VectorBindableIndexOf(const ::std::vector<typename Wrap<T>::type>& v, Object^ o, unsigned int * index) {
282  return VectorBindableIndexOf<T, E>(is_hat<T>(), v, o, index);
283  }
284 #endif // _COLLECTION_WUXI
285 
286  template <typename T> inline unsigned int VectorGetMany(const ::std::vector<typename Wrap<T>::type>& v, unsigned int startIndex, WriteOnlyArray<T>^ dest) {
287  unsigned int capacity = dest->Length;
288 
289  unsigned int actual = static_cast<unsigned int>(v.size()) - startIndex;
290 
291  if (actual > capacity) {
292  actual = capacity;
293  }
294 
295  for (unsigned int i = 0; i < actual; ++i) {
296  dest->set(i, Unwrap(v[startIndex + i]));
297  }
298 
299  return actual;
300  }
301 
302  template <typename T> ref class IteratorForVectorView sealed
303  : public _COLLECTION_ATTRIBUTES WFC::IIterator<T>
304 #if _COLLECTION_WUXI
305  , public WUXI::IBindableIterator
306 #endif // _COLLECTION_WUXI
307  {
308  private:
309  typedef ::std::vector<typename Wrap<T>::type> WrappedVector;
310  typedef WFC::IIterator<T> WFC_Base;
311 
312 #if _COLLECTION_WUXI
313  typedef WUXI::IBindableIterator WUXI_Base;
314 #endif // _COLLECTION_WUXI
315 
316  internal:
317  IteratorForVectorView(const ::std::shared_ptr<unsigned int>& ctr, const ::std::shared_ptr<WrappedVector>& vec)
318  : m_ctr(ctr), m_vec(vec), m_good_ctr(*ctr), m_index(0) { }
319 
320  public:
321  virtual property T Current {
322  virtual T get() = WFC_Base::Current::get {
323  ValidateCounter(m_ctr, m_good_ctr);
324 
325  ValidateBounds(m_index < m_vec->size());
326 
327  return Unwrap((*m_vec)[m_index]);
328  }
329  }
330 
331  virtual property bool HasCurrent {
332  virtual bool get() {
333  ValidateCounter(m_ctr, m_good_ctr);
334 
335  return m_index < m_vec->size();
336  }
337  }
338 
339  virtual bool MoveNext() {
340  ValidateCounter(m_ctr, m_good_ctr);
341 
342  ValidateBounds(m_index < m_vec->size());
343 
344  ++m_index;
345  return m_index < m_vec->size();
346  }
347 
348  virtual unsigned int GetMany(WriteOnlyArray<T>^ dest) {
349  ValidateCounter(m_ctr, m_good_ctr);
350 
351  unsigned int actual = VectorGetMany(*m_vec, m_index, dest);
352 
353  m_index += actual;
354 
355  return actual;
356  }
357 
358  private:
359 
360 #if _COLLECTION_WUXI
361  virtual Object^ BindableCurrent() = WUXI_Base::Current::get {
362  return Current;
363  }
364 #endif // _COLLECTION_WUXI
365 
366  ::std::shared_ptr<unsigned int> m_ctr;
367  ::std::shared_ptr<WrappedVector> m_vec;
368  unsigned int m_good_ctr;
369  unsigned int m_index;
370  };
371  } // namespace Details
372 
373  template <typename T, typename E = ::std::equal_to<T>, bool = __is_valid_winrt_type(T)> ref class Vector;
374  template <typename T, typename E = ::std::equal_to<T>, bool = __is_valid_winrt_type(T)> ref class VectorView;
375 
376  template <typename T, typename E> ref class VectorView<T, E, false> {
377  static_assert(Details::AlwaysFalse<T>::value, "Platform::Collections::VectorView<T, E> requires T to be a valid Windows Runtime type.");
378  };
379 
380  template <typename T, typename E, bool> ref class VectorView sealed
381  : public _COLLECTION_ATTRIBUTES Details::WFC::IVectorView<T>
382 #if _COLLECTION_WUXI
383  , public Details::WUXI::IBindableVectorView
384 #endif // _COLLECTION_WUXI
385  {
386  private:
387  typedef ::std::vector<typename Details::Wrap<T>::type> WrappedVector;
388  typedef Details::WFC::IVectorView<T> WFC_Base;
389 
390 #if _COLLECTION_WUXI
391  typedef Details::WUXI::IBindableVectorView WUXI_Base;
392 #endif // _COLLECTION_WUXI
393 
394  internal:
395  VectorView() {
396  Details::Init(m_ctr, m_vec);
397 
398  m_good_ctr = 0;
399  }
400 
401  explicit VectorView(unsigned int size) {
402  Details::Init(m_ctr, m_vec, size);
403 
404  m_good_ctr = 0;
405  }
406 
407  VectorView(unsigned int size, T value) {
408  Details::Init(m_ctr, m_vec, size, Details::MakeWrap(value));
409 
410  m_good_ctr = 0;
411  }
412 
413  template <typename U> explicit VectorView(const ::std::vector<U>& v, typename Details::VectorEnableIf<T, U>::type = nullptr) {
414  Details::Init(m_ctr, m_vec, v.begin(), v.end());
415 
416  m_good_ctr = 0;
417  }
418 
419  template <typename U> explicit VectorView(::std::vector<U>&& v, typename Details::VectorEnableIf<T, U>::type = nullptr) {
420  Details::InitMoveVector(m_ctr, m_vec, ::std::move(v));
421 
422  m_good_ctr = 0;
423  }
424 
425  VectorView(const T * ptr, unsigned int size) {
426  Details::Init(m_ctr, m_vec, ptr, ptr + size);
427 
428  m_good_ctr = 0;
429  }
430 
431  template <size_t N> explicit VectorView(const T (&arr)[N]) {
432  Details::Init(m_ctr, m_vec, arr, arr + N);
433 
434  m_good_ctr = 0;
435  }
436 
437  template <size_t N> explicit VectorView(const ::std::array<T, N>& a) {
438  Details::Init(m_ctr, m_vec, a.begin(), a.end());
439 
440  m_good_ctr = 0;
441  }
442 
443  explicit VectorView(const Array<T>^ arr) {
444  Details::Init(m_ctr, m_vec, arr->begin(), arr->end());
445 
446  m_good_ctr = 0;
447  }
448 
449  template <typename InIt> VectorView(InIt first, InIt last) {
450  // SFINAE is unnecessary here.
451 
452  Details::Init(m_ctr, m_vec, first, last);
453 
454  m_good_ctr = 0;
455  }
456 
457  VectorView(::std::initializer_list<T> il) {
458  Details::Init(m_ctr, m_vec, il.begin(), il.end());
459 
460  m_good_ctr = 0;
461  }
462 
463  public:
464  virtual Details::WFC::IIterator<T>^ First() = WFC_Base::First {
465  Details::ValidateCounter(m_ctr, m_good_ctr);
466 
467  return ref new Details::IteratorForVectorView<T>(m_ctr, m_vec);
468  }
469 
470  virtual T GetAt(unsigned int index) = WFC_Base::GetAt {
471  Details::ValidateCounter(m_ctr, m_good_ctr);
472 
473  Details::ValidateBounds(index < m_vec->size());
474 
475  return Details::Unwrap((*m_vec)[index]);
476  }
477 
478  virtual property unsigned int Size {
479  virtual unsigned int get() {
480  Details::ValidateCounter(m_ctr, m_good_ctr);
481 
482  return static_cast<unsigned int>(m_vec->size());
483  }
484  }
485 
486  virtual bool IndexOf(T value, unsigned int * index) = WFC_Base::IndexOf {
487  *index = 0;
488 
489  Details::ValidateCounter(m_ctr, m_good_ctr);
490 
491  return Details::VectorIndexOf<T, E>(*m_vec, value, index);
492  }
493 
494  virtual unsigned int GetMany(unsigned int startIndex, WriteOnlyArray<T>^ dest) {
495  Details::ValidateCounter(m_ctr, m_good_ctr);
496 
497  Details::ValidateBounds(startIndex <= m_vec->size());
498 
499  return Details::VectorGetMany(*m_vec, startIndex, dest);
500  }
501 
502  private:
503  friend ref class Vector<T, E>;
504 
505  VectorView(const ::std::shared_ptr<unsigned int>& ctr, const ::std::shared_ptr<WrappedVector>& vec)
506  : m_ctr(ctr), m_vec(vec), m_good_ctr(*ctr) { }
507 
508 #if _COLLECTION_WUXI
509  virtual Details::WUXI::IBindableIterator^ BindableFirst() = WUXI_Base::First {
510  return safe_cast<Details::WUXI::IBindableIterator^>(First());
511  }
512 
513  virtual Object^ BindableGetAt(unsigned int index) = WUXI_Base::GetAt {
514  return GetAt(index);
515  }
516 
517  virtual bool BindableIndexOf(Object^ value, unsigned int * index) = WUXI_Base::IndexOf {
518  *index = 0;
519 
520  Details::ValidateCounter(m_ctr, m_good_ctr);
521 
522  return Details::VectorBindableIndexOf<T, E>(*m_vec, value, index);
523  }
524 #endif // _COLLECTION_WUXI
525 
526  ::std::shared_ptr<unsigned int> m_ctr;
527  ::std::shared_ptr<WrappedVector> m_vec;
528  unsigned int m_good_ctr;
529  };
530 
531  template <typename T, typename E> ref class Vector<T, E, false> {
532  static_assert(Details::AlwaysFalse<T>::value, "Platform::Collections::Vector<T, E> requires T to be a valid Windows Runtime type.");
533  };
534 
535  template <typename T, typename E, bool> ref class Vector sealed
536  : public _COLLECTION_ATTRIBUTES Details::WFC::IObservableVector<T>
537 #if _COLLECTION_WUXI
538  , public Details::WUXI::IBindableObservableVector
539 #endif // _COLLECTION_WUXI
540  {
541  private:
542  typedef ::std::vector<typename Details::Wrap<T>::type> WrappedVector;
543  typedef Details::WFC::IObservableVector<T> WFC_Base;
544  typedef Details::WFC::VectorChangedEventHandler<T> WFC_Handler;
545 
546 #if _COLLECTION_WUXI
547  typedef Details::WUXI::IBindableObservableVector WUXI_Base;
548  typedef Details::WUXI::BindableVectorChangedEventHandler WUXI_Handler;
549 #endif // _COLLECTION_WUXI
550 
551  internal:
552  Vector() {
553  Details::Init(m_ctr, m_vec);
554 
555  m_observed = false;
556  }
557 
558  explicit Vector(unsigned int size) {
559  Details::Init(m_ctr, m_vec, size);
560 
561  m_observed = false;
562  }
563 
564  Vector(unsigned int size, T value) {
565  Details::Init(m_ctr, m_vec, size, Details::MakeWrap(value));
566 
567  m_observed = false;
568  }
569 
570  template <typename U> explicit Vector(const ::std::vector<U>& v, typename Details::VectorEnableIf<T, U>::type = nullptr) {
571  Details::Init(m_ctr, m_vec, v.begin(), v.end());
572 
573  m_observed = false;
574  }
575 
576  template <typename U> explicit Vector(::std::vector<U>&& v, typename Details::VectorEnableIf<T, U>::type = nullptr) {
577  Details::InitMoveVector(m_ctr, m_vec, ::std::move(v));
578 
579  m_observed = false;
580  }
581 
582  Vector(const T * ptr, unsigned int size) {
583  Details::Init(m_ctr, m_vec, ptr, ptr + size);
584 
585  m_observed = false;
586  }
587 
588  template <size_t N> explicit Vector(const T (&arr)[N]) {
589  Details::Init(m_ctr, m_vec, arr, arr + N);
590 
591  m_observed = false;
592  }
593 
594  template <size_t N> explicit Vector(const ::std::array<T, N>& a) {
595  Details::Init(m_ctr, m_vec, a.begin(), a.end());
596 
597  m_observed = false;
598  }
599 
600  explicit Vector(const Array<T>^ arr) {
601  Details::Init(m_ctr, m_vec, arr->begin(), arr->end());
602 
603  m_observed = false;
604  }
605 
606  template <typename InIt> Vector(InIt first, InIt last) {
607  // SFINAE is unnecessary here.
608 
609  Details::Init(m_ctr, m_vec, first, last);
610 
611  m_observed = false;
612  }
613 
614  Vector(::std::initializer_list<T> il) {
615  Details::Init(m_ctr, m_vec, il.begin(), il.end());
616 
617  m_observed = false;
618  }
619 
620  public:
621  virtual Details::WFC::IIterator<T>^ First() = WFC_Base::First {
622  return ref new Details::IteratorForVectorView<T>(m_ctr, m_vec);
623  }
624 
625  virtual T GetAt(unsigned int index) = WFC_Base::GetAt {
626  Details::ValidateBounds(index < m_vec->size());
627 
628  return Details::Unwrap((*m_vec)[index]);
629  }
630 
631  virtual property unsigned int Size {
632  virtual unsigned int get() {
633  return static_cast<unsigned int>(m_vec->size());
634  }
635  }
636 
637  virtual bool IndexOf(T value, unsigned int * index) = WFC_Base::IndexOf {
638  *index = 0;
639 
640  return Details::VectorIndexOf<T, E>(*m_vec, value, index);
641  }
642 
643  virtual unsigned int GetMany(unsigned int startIndex, WriteOnlyArray<T>^ dest) {
644  Details::ValidateBounds(startIndex <= m_vec->size());
645 
646  return Details::VectorGetMany(*m_vec, startIndex, dest);
647  }
648 
649  virtual Details::WFC::IVectorView<T>^ GetView() = WFC_Base::GetView {
650  return ref new VectorView<T, E>(m_ctr, m_vec);
651  }
652 
653  virtual void SetAt(unsigned int index, T item) = WFC_Base::SetAt {
654  try {
655  Details::IncrementCounter(m_ctr);
656 
657  Details::ValidateBounds(index < m_vec->size());
658 
659  (*m_vec)[index] = item;
660 
661  NotifyChanged(index);
663  }
664 
665  virtual void InsertAt(unsigned int index, T item) = WFC_Base::InsertAt {
666  try {
667  Details::IncrementCounter(m_ctr);
668 
669  Details::ValidateBounds(index <= m_vec->size());
670 
671  Details::ValidateSize(m_vec->size() + 1);
672 
673  Emplace(m_vec->begin() + index, item, ::std::is_same<T, bool>());
674 
675  NotifyInserted(index);
677  }
678 
679  virtual void Append(T item) = WFC_Base::Append {
680  try {
681  Details::IncrementCounter(m_ctr);
682 
683  size_t n = m_vec->size();
684 
685  Details::ValidateSize(n + 1);
686 
687  EmplaceBack(item, ::std::is_same<T, bool>());
688 
689  NotifyInserted(static_cast<unsigned int>(n));
691  }
692 
693  virtual void RemoveAt(unsigned int index) {
694  try {
695  Details::IncrementCounter(m_ctr);
696 
697  Details::ValidateBounds(index < m_vec->size());
698 
699  m_vec->erase(m_vec->begin() + index);
700 
701  NotifyRemoved(index);
703  }
704 
705  virtual void RemoveAtEnd() {
706  try {
707  Details::IncrementCounter(m_ctr);
708 
709  Details::ValidateBounds(!m_vec->empty());
710 
711  m_vec->pop_back();
712 
713  NotifyRemoved(static_cast<unsigned int>(m_vec->size()));
715  }
716 
717  virtual void Clear() {
718  try {
719  Details::IncrementCounter(m_ctr);
720 
721  m_vec->clear();
722 
723  NotifyReset();
725  }
726 
727  virtual void ReplaceAll(const Array<T>^ arr) {
728  try {
729  Details::IncrementCounter(m_ctr);
730 
731  Details::ValidateSize(arr->Length);
732 
733  m_vec->assign(arr->begin(), arr->end());
734 
735  NotifyReset();
737  }
738 
739  virtual event WFC_Handler^ VectorChanged {
740  virtual Details::Token add(WFC_Handler^ e) = WFC_Base::VectorChanged::add {
741  m_observed = true;
742  return m_wfc_event += e;
743  }
744 
745  virtual void remove(Details::Token t) = WFC_Base::VectorChanged::remove {
746  m_wfc_event -= t;
747  }
748  };
749 
750  private:
751  template <typename A, typename B> void Emplace(A&& a, B&& b, ::std::false_type) {
752  m_vec->emplace(::std::forward<A>(a), ::std::forward<B>(b));
753  }
754 
755  template <typename A, typename B> void Emplace(A&& a, B&& b, ::std::true_type) {
756  m_vec->insert(::std::forward<A>(a), ::std::forward<B>(b));
757  }
758 
759  template <typename A> void EmplaceBack(A&& a, ::std::false_type) {
760  m_vec->emplace_back(::std::forward<A>(a));
761  }
762 
763  template <typename A> void EmplaceBack(A&& a, ::std::true_type) {
764  m_vec->push_back(::std::forward<A>(a));
765  }
766 
767  void Notify(Details::WFC::CollectionChange change, unsigned int index) {
768  if (m_observed) {
769  auto args = ref new Details::VectorChangedEventArgs(change, index);
770  m_wfc_event(this, args);
771 
772 #if _COLLECTION_WUXI
773  m_wuxi_event(this, args);
774 #endif // _COLLECTION_WUXI
775 
776  }
777  }
778 
779  void NotifyReset() {
780  Notify(Details::WFC::CollectionChange::Reset, 0);
781  }
782 
783  void NotifyInserted(unsigned int index) {
784  Notify(Details::WFC::CollectionChange::ItemInserted, index);
785  }
786 
787  void NotifyRemoved(unsigned int index) {
788  Notify(Details::WFC::CollectionChange::ItemRemoved, index);
789  }
790 
791  void NotifyChanged(unsigned int index) {
792  Notify(Details::WFC::CollectionChange::ItemChanged, index);
793  }
794 
795 #if _COLLECTION_WUXI
796  virtual Details::WUXI::IBindableIterator^ BindableFirst() = WUXI_Base::First {
797  return safe_cast<Details::WUXI::IBindableIterator^>(First());
798  }
799 
800  virtual Object^ BindableGetAt(unsigned int index) = WUXI_Base::GetAt {
801  return GetAt(index);
802  }
803 
804  virtual bool BindableIndexOf(Object^ value, unsigned int * index) = WUXI_Base::IndexOf {
805  *index = 0;
806 
807  return Details::VectorBindableIndexOf<T, E>(*m_vec, value, index);
808  }
809 
810  virtual Details::WUXI::IBindableVectorView^ BindableGetView() = WUXI_Base::GetView {
811  return safe_cast<Details::WUXI::IBindableVectorView^>(GetView());
812  }
813 
814  virtual void BindableSetAt(unsigned int index, Object^ item) = WUXI_Base::SetAt {
815  SetAt(index, safe_cast<T>(item));
816  }
817 
818  virtual void BindableInsertAt(unsigned int index, Object^ item) = WUXI_Base::InsertAt {
819  InsertAt(index, safe_cast<T>(item));
820  }
821 
822  virtual void BindableAppend(Object^ item) = WUXI_Base::Append {
823  Append(safe_cast<T>(item));
824  }
825 
826  virtual Details::Token BindableEventAdd(WUXI_Handler^ e) = WUXI_Base::VectorChanged::add {
827  m_observed = true;
828  return m_wuxi_event += e;
829  }
830 
831  virtual void BindableEventRemove(Details::Token t) = WUXI_Base::VectorChanged::remove {
832  m_wuxi_event -= t;
833  }
834 #endif // _COLLECTION_WUXI
835 
836  ::std::shared_ptr<unsigned int> m_ctr;
837  ::std::shared_ptr<WrappedVector> m_vec;
838  bool m_observed;
839 
840  event WFC_Handler^ m_wfc_event;
841 
842 #if _COLLECTION_WUXI
843  event WUXI_Handler^ m_wuxi_event;
844 #endif // _COLLECTION_WUXI
845 
846  };
847 
848 
849  namespace Details {
850  template <typename K, typename V> ref class KeyValuePair sealed : public _COLLECTION_ATTRIBUTES WFC::IKeyValuePair<K, V> {
851  internal:
852  KeyValuePair(const typename Wrap<K>::type& key, const typename Wrap<V>::type& value)
853  : m_key(key), m_value(value) { }
854 
855  public:
856  virtual property K Key {
857  virtual K get() {
858  return Unwrap(m_key);
859  }
860  }
861 
862  virtual property V Value {
863  virtual V get() {
864  return Unwrap(m_value);
865  }
866  }
867 
868  private:
869  typename Wrap<K>::type m_key;
870  typename Wrap<V>::type m_value;
871  };
872 
873  template <typename K, typename F, bool = ::std::is_same<typename Wrap<K>::type, K>::value> class WrapFunc {
874  public:
875  typedef F type;
876  };
877 
878  template <typename K, typename F> class WrapFunc<K, F, false> {
879  public:
880  typedef WrapFunc type;
881 
882  WrapFunc(const F& func)
883  : m_func(func) { }
884 
885  size_t operator()(const Agile<K>& k) const {
886  return m_func(k.Get());
887  }
888 
889  bool operator()(const Agile<K>& l, const Agile<K>& r) const {
890  return m_func(l.Get(), r.Get());
891  }
892 
893  private:
894  F m_func;
895  };
896 
897  template <typename K, typename V, typename C> struct WrapMap {
898  typedef ::std::map<typename Wrap<K>::type, typename Wrap<V>::type, typename WrapFunc<K, C>::type> type;
899  };
900 
901  template <typename K, typename V, typename H, typename P> struct WrapUnorderedMap {
902  typedef ::std::unordered_map<typename Wrap<K>::type, typename Wrap<V>::type, typename WrapFunc<K, H>::type, typename WrapFunc<K, P>::type> type;
903  };
904 
905  template <typename K, typename V, typename WrappedMap> ref class IteratorForAnyMapView sealed : public _COLLECTION_ATTRIBUTES WFC::IIterator<WFC::IKeyValuePair<K, V>^> {
906 
907  internal:
908  IteratorForAnyMapView(const ::std::shared_ptr<unsigned int>& ctr, const ::std::shared_ptr<WrappedMap>& m)
909  : m_ctr(ctr), m_map(m), m_good_ctr(*ctr), m_iter(m->begin()) { }
910 
911  public:
912  virtual property WFC::IKeyValuePair<K, V>^ Current {
913  virtual WFC::IKeyValuePair<K, V>^ get() {
914  ValidateCounter(m_ctr, m_good_ctr);
915 
916  ValidateBounds(m_iter != m_map->end());
917 
918  return ref new KeyValuePair<K, V>(m_iter->first, m_iter->second);
919  }
920  }
921 
922  virtual property bool HasCurrent {
923  virtual bool get() {
924  ValidateCounter(m_ctr, m_good_ctr);
925 
926  return m_iter != m_map->end();
927  }
928  }
929 
930  virtual bool MoveNext() {
931  ValidateCounter(m_ctr, m_good_ctr);
932 
933  ValidateBounds(m_iter != m_map->end());
934 
935  ++m_iter;
936  return m_iter != m_map->end();
937  }
938 
939  virtual unsigned int GetMany(WriteOnlyArray<WFC::IKeyValuePair<K, V>^>^ dest) {
940  ValidateCounter(m_ctr, m_good_ctr);
941 
942  unsigned int capacity = dest->Length;
943 
944  unsigned int actual = 0;
945 
946  while (capacity > 0 && m_iter != m_map->end()) {
947  dest->set(actual, ref new KeyValuePair<K, V>(m_iter->first, m_iter->second));
948  ++m_iter;
949  --capacity;
950  ++actual;
951  }
952 
953  return actual;
954  }
955 
956  private:
957  ::std::shared_ptr<unsigned int> m_ctr;
958  ::std::shared_ptr<WrappedMap> m_map;
959  unsigned int m_good_ctr;
960  typename WrappedMap::const_iterator m_iter;
961  };
962  } // namespace Details
963 
964  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;
965  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;
966  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;
967  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;
968 
969  template <typename K, typename V, typename C> ref class MapView<K, V, C, false, false> {
970  static_assert(Details::AlwaysFalse<K>::value, "Platform::Collections::MapView<K, V, C> requires K and V to be valid Windows Runtime types.");
971  };
972 
973  template <typename K, typename V, typename C> ref class MapView<K, V, C, false, true> {
974  static_assert(Details::AlwaysFalse<K>::value, "Platform::Collections::MapView<K, V, C> requires K to be a valid Windows Runtime type.");
975  };
976 
977  template <typename K, typename V, typename C> ref class MapView<K, V, C, true, false> {
978  static_assert(Details::AlwaysFalse<K>::value, "Platform::Collections::MapView<K, V, C> requires V to be a valid Windows Runtime type.");
979  };
980 
981  template <typename K, typename V, typename C, bool, bool> ref class MapView sealed : public _COLLECTION_ATTRIBUTES Details::WFC::IMapView<K, V> {
982  private:
983  typedef typename Details::WrapMap<K, V, C>::type WrappedMap;
984  typedef Details::IteratorForAnyMapView<K, V, WrappedMap> MyIterator;
985  friend ref class Map<K, V, C>;
986 
987  internal:
988  explicit MapView(const C& comp = C()) {
989  Details::Init(m_ctr, m_map, comp);
990 
991  m_good_ctr = 0;
992  }
993 
994  explicit MapView(const ::std::map<K, V, C>& m) {
995  Details::Init(m_ctr, m_map, m.key_comp());
996 
997  Details::EmplaceWrappedRange<K, V>(*m_map, m.begin(), m.end());
998 
999  m_good_ctr = 0;
1000  }
1001 
1002  explicit MapView(::std::map<K, V, C>&& m) {
1003  Details::InitMoveMap<K, V>(m_ctr, m_map, ::std::move(m));
1004 
1005  m_good_ctr = 0;
1006  }
1007 
1008  template <typename InIt> MapView(InIt first, InIt last, const C& comp = C()) {
1009  Details::Init(m_ctr, m_map, comp);
1010 
1011  Details::EmplaceWrappedRange<K, V>(*m_map, first, last);
1012 
1013  m_good_ctr = 0;
1014  }
1015 
1016  MapView(::std::initializer_list< ::std::pair<const K, V>> il, const C& comp = C()) {
1017  Details::Init(m_ctr, m_map, comp);
1018 
1019  Details::EmplaceWrappedRange<K, V>(*m_map, il.begin(), il.end());
1020 
1021  m_good_ctr = 0;
1022  }
1023 
1024  public:
1025  virtual Details::WFC::IIterator<Details::WFC::IKeyValuePair<K, V>^>^ First() {
1026  Details::ValidateCounter(m_ctr, m_good_ctr);
1027 
1028  return ref new MyIterator(m_ctr, m_map);
1029  }
1030 
1031  virtual V Lookup(K key) {
1032  Details::ValidateCounter(m_ctr, m_good_ctr);
1033 
1034  auto i = m_map->find(Details::MakeWrap(key));
1035 
1036  Details::ValidateBounds(i != m_map->end());
1037 
1038  return Details::Unwrap(i->second);
1039  }
1040 
1041  virtual property unsigned int Size {
1042  virtual unsigned int get() {
1043  Details::ValidateCounter(m_ctr, m_good_ctr);
1044 
1045  return static_cast<unsigned int>(m_map->size());
1046  }
1047  }
1048 
1049  virtual bool HasKey(K key) {
1050  Details::ValidateCounter(m_ctr, m_good_ctr);
1051 
1052  return m_map->find(Details::MakeWrap(key)) != m_map->end();
1053  }
1054 
1055  virtual void Split(Details::WFC::IMapView<K, V>^ * firstPartition, Details::WFC::IMapView<K, V>^ * secondPartition) {
1056  *firstPartition = nullptr;
1057  *secondPartition = nullptr;
1058 
1059  Details::ValidateCounter(m_ctr, m_good_ctr);
1060  }
1061 
1062  private:
1063  MapView(const ::std::shared_ptr<unsigned int>& ctr, const ::std::shared_ptr<WrappedMap>& m)
1064  : m_ctr(ctr), m_map(m), m_good_ctr(*ctr) { }
1065 
1066  ::std::shared_ptr<unsigned int> m_ctr;
1067  ::std::shared_ptr<WrappedMap> m_map;
1068  unsigned int m_good_ctr;
1069  };
1070 
1071  template <typename K, typename V, typename H, typename P> ref class UnorderedMapView<K, V, H, P, false, false> {
1072  static_assert(Details::AlwaysFalse<K>::value, "Platform::Collections::UnorderedMapView<K, V, H, P> requires K and V to be valid Windows Runtime types.");
1073  };
1074 
1075  template <typename K, typename V, typename H, typename P> ref class UnorderedMapView<K, V, H, P, false, true> {
1076  static_assert(Details::AlwaysFalse<K>::value, "Platform::Collections::UnorderedMapView<K, V, H, P> requires K to be a valid Windows Runtime type.");
1077  };
1078 
1079  template <typename K, typename V, typename H, typename P> ref class UnorderedMapView<K, V, H, P, true, false> {
1080  static_assert(Details::AlwaysFalse<K>::value, "Platform::Collections::UnorderedMapView<K, V, H, P> requires V to be a valid Windows Runtime type.");
1081  };
1082 
1083  template <typename K, typename V, typename H, typename P, bool, bool> ref class UnorderedMapView sealed
1084  : public _COLLECTION_ATTRIBUTES Details::WFC::IMapView<K, V> {
1085  private:
1086  typedef typename Details::WrapUnorderedMap<K, V, H, P>::type WrappedMap;
1087  typedef Details::IteratorForAnyMapView<K, V, WrappedMap> MyIterator;
1088  friend ref class UnorderedMap<K, V, H, P>;
1089 
1090  internal:
1091  UnorderedMapView() {
1092  Details::Init(m_ctr, m_map);
1093 
1094  m_good_ctr = 0;
1095  }
1096 
1097  explicit UnorderedMapView(size_t n) {
1098  Details::Init(m_ctr, m_map, n, H(), P());
1099 
1100  m_good_ctr = 0;
1101  }
1102 
1103  UnorderedMapView(size_t n, const H& h) {
1104  Details::Init(m_ctr, m_map, n, h, P());
1105 
1106  m_good_ctr = 0;
1107  }
1108 
1109  UnorderedMapView(size_t n, const H& h, const P& p) {
1110  Details::Init(m_ctr, m_map, n, h, p);
1111 
1112  m_good_ctr = 0;
1113  }
1114 
1115  explicit UnorderedMapView(const ::std::unordered_map<K, V, H, P>& m) {
1116  Details::Init(m_ctr, m_map, m.bucket_count(), m.hash_function(), m.key_eq());
1117 
1118  Details::EmplaceWrappedRange<K, V>(*m_map, m.begin(), m.end());
1119 
1120  m_good_ctr = 0;
1121  }
1122 
1123  explicit UnorderedMapView(::std::unordered_map<K, V, H, P>&& m) {
1124  Details::InitMoveMap<K, V>(m_ctr, m_map, ::std::move(m));
1125 
1126  m_good_ctr = 0;
1127  }
1128 
1129  template <typename InIt> UnorderedMapView(InIt first, InIt last) {
1130  Details::Init(m_ctr, m_map);
1131 
1132  Details::EmplaceWrappedRange<K, V>(*m_map, first, last);
1133 
1134  m_good_ctr = 0;
1135  }
1136 
1137  template <typename InIt> UnorderedMapView(InIt first, InIt last, size_t n) {
1138  Details::Init(m_ctr, m_map, n, H(), P());
1139 
1140  Details::EmplaceWrappedRange<K, V>(*m_map, first, last);
1141 
1142  m_good_ctr = 0;
1143  }
1144 
1145  template <typename InIt> UnorderedMapView(InIt first, InIt last, size_t n, const H& h) {
1146  Details::Init(m_ctr, m_map, n, h, P());
1147 
1148  Details::EmplaceWrappedRange<K, V>(*m_map, first, last);
1149 
1150  m_good_ctr = 0;
1151  }
1152 
1153  template <typename InIt> UnorderedMapView(InIt first, InIt last, size_t n, const H& h, const P& p) {
1154  Details::Init(m_ctr, m_map, n, h, p);
1155 
1156  Details::EmplaceWrappedRange<K, V>(*m_map, first, last);
1157 
1158  m_good_ctr = 0;
1159  }
1160 
1161  UnorderedMapView(::std::initializer_list< ::std::pair<const K, V>> il) {
1162  Details::Init(m_ctr, m_map);
1163 
1164  Details::EmplaceWrappedRange<K, V>(*m_map, il.begin(), il.end());
1165 
1166  m_good_ctr = 0;
1167  }
1168 
1169  UnorderedMapView(::std::initializer_list< ::std::pair<const K, V>> il, size_t n) {
1170  Details::Init(m_ctr, m_map, n, H(), P());
1171 
1172  Details::EmplaceWrappedRange<K, V>(*m_map, il.begin(), il.end());
1173 
1174  m_good_ctr = 0;
1175  }
1176 
1177  UnorderedMapView(::std::initializer_list< ::std::pair<const K, V>> il, size_t n, const H& h) {
1178  Details::Init(m_ctr, m_map, n, h, P());
1179 
1180  Details::EmplaceWrappedRange<K, V>(*m_map, il.begin(), il.end());
1181 
1182  m_good_ctr = 0;
1183  }
1184 
1185  UnorderedMapView(::std::initializer_list< ::std::pair<const K, V>> il, size_t n, const H& h, const P& p) {
1186  Details::Init(m_ctr, m_map, n, h, p);
1187 
1188  Details::EmplaceWrappedRange<K, V>(*m_map, il.begin(), il.end());
1189 
1190  m_good_ctr = 0;
1191  }
1192 
1193  public:
1194  virtual Details::WFC::IIterator<Details::WFC::IKeyValuePair<K, V>^>^ First() {
1195  Details::ValidateCounter(m_ctr, m_good_ctr);
1196 
1197  return ref new MyIterator(m_ctr, m_map);
1198  }
1199 
1200  virtual V Lookup(K key) {
1201  Details::ValidateCounter(m_ctr, m_good_ctr);
1202 
1203  auto i = m_map->find(Details::MakeWrap(key));
1204 
1205  Details::ValidateBounds(i != m_map->end());
1206 
1207  return Details::Unwrap(i->second);
1208  }
1209 
1210  virtual property unsigned int Size {
1211  virtual unsigned int get() {
1212  Details::ValidateCounter(m_ctr, m_good_ctr);
1213 
1214  return static_cast<unsigned int>(m_map->size());
1215  }
1216  }
1217 
1218  virtual bool HasKey(K key) {
1219  Details::ValidateCounter(m_ctr, m_good_ctr);
1220 
1221  return m_map->find(Details::MakeWrap(key)) != m_map->end();
1222  }
1223 
1224  virtual void Split(Details::WFC::IMapView<K, V>^ * firstPartition, Details::WFC::IMapView<K, V>^ * secondPartition) {
1225  *firstPartition = nullptr;
1226  *secondPartition = nullptr;
1227 
1228  Details::ValidateCounter(m_ctr, m_good_ctr);
1229  }
1230 
1231  private:
1232  UnorderedMapView(const ::std::shared_ptr<unsigned int>& ctr, const ::std::shared_ptr<WrappedMap>& m)
1233  : m_ctr(ctr), m_map(m), m_good_ctr(*ctr) { }
1234 
1235  ::std::shared_ptr<unsigned int> m_ctr;
1236  ::std::shared_ptr<WrappedMap> m_map;
1237  unsigned int m_good_ctr;
1238  };
1239 
1240  template <typename K, typename V, typename C> ref class Map<K, V, C, false, false> {
1241  static_assert(Details::AlwaysFalse<K>::value, "Platform::Collections::Map<K, V, C> requires K and V to be valid Windows Runtime types.");
1242  };
1243 
1244  template <typename K, typename V, typename C> ref class Map<K, V, C, false, true> {
1245  static_assert(Details::AlwaysFalse<K>::value, "Platform::Collections::Map<K, V, C> requires K to be a valid Windows Runtime type.");
1246  };
1247 
1248  template <typename K, typename V, typename C> ref class Map<K, V, C, true, false> {
1249  static_assert(Details::AlwaysFalse<K>::value, "Platform::Collections::Map<K, V, C> requires V to be a valid Windows Runtime type.");
1250  };
1251 
1252  template <typename K, typename V, typename C, bool, bool> ref class Map sealed : public _COLLECTION_ATTRIBUTES Details::WFC::IObservableMap<K, V> {
1253  private:
1254  typedef typename Details::WrapMap<K, V, C>::type WrappedMap;
1255  typedef Details::IteratorForAnyMapView<K, V, WrappedMap> MyIterator;
1256  typedef MapView<K, V, C> MyView;
1257  typedef Details::WFC::MapChangedEventHandler<K, V> WFC_Handler;
1258 
1259  internal:
1260  explicit Map(const C& comp = C()) {
1261  Details::Init(m_ctr, m_map, comp);
1262 
1263  m_observed = false;
1264  }
1265 
1266  explicit Map(const ::std::map<K, V, C>& m) {
1267  Details::Init(m_ctr, m_map, m.key_comp());
1268 
1269  Details::EmplaceWrappedRange<K, V>(*m_map, m.begin(), m.end());
1270 
1271  m_observed = false;
1272  }
1273 
1274  explicit Map(::std::map<K, V, C>&& m) {
1275  Details::InitMoveMap<K, V>(m_ctr, m_map, ::std::move(m));
1276 
1277  m_observed = false;
1278  }
1279 
1280  template <typename InIt> Map(InIt first, InIt last, const C& comp = C()) {
1281  Details::Init(m_ctr, m_map, comp);
1282 
1283  Details::EmplaceWrappedRange<K, V>(*m_map, first, last);
1284 
1285  m_observed = false;
1286  }
1287 
1288  Map(::std::initializer_list< ::std::pair<const K, V>> il, const C& comp = C()) {
1289  Details::Init(m_ctr, m_map, comp);
1290 
1291  Details::EmplaceWrappedRange<K, V>(*m_map, il.begin(), il.end());
1292 
1293  m_observed = false;
1294  }
1295 
1296  public:
1297  virtual Details::WFC::IIterator<Details::WFC::IKeyValuePair<K, V>^>^ First() {
1298  return ref new MyIterator(m_ctr, m_map);
1299  }
1300 
1301  virtual V Lookup(K key) {
1302  auto i = m_map->find(Details::MakeWrap(key));
1303 
1304  Details::ValidateBounds(i != m_map->end());
1305 
1306  return Details::Unwrap(i->second);
1307  }
1308 
1309  virtual property unsigned int Size {
1310  virtual unsigned int get() {
1311  return static_cast<unsigned int>(m_map->size());
1312  }
1313  }
1314 
1315  virtual bool HasKey(K key) {
1316  return m_map->find(Details::MakeWrap(key)) != m_map->end();
1317  }
1318 
1319  virtual Details::WFC::IMapView<K, V>^ GetView() {
1320  return ref new MyView(m_ctr, m_map);
1321  }
1322 
1323  virtual bool Insert(K key, V value) {
1324  try {
1325  Details::IncrementCounter(m_ctr);
1326 
1327  Details::ValidateSize(m_map->size() + 1);
1328 
1329  auto p = m_map->emplace(Details::MakeWrap(key), Details::MakeWrap(value));
1330 
1331  if (p.second) {
1332  NotifyInserted(key);
1333  } else {
1334  p.first->second = value;
1335  NotifyChanged(key);
1336  }
1337 
1338  return !p.second;
1340  }
1341 
1342  virtual void Remove(K key) {
1343  try {
1344  Details::IncrementCounter(m_ctr);
1345 
1346  Details::ValidateBounds(m_map->erase(Details::MakeWrap(key)) == 1);
1347 
1348  NotifyRemoved(key);
1350  }
1351 
1352  virtual void Clear() {
1353  try {
1354  Details::IncrementCounter(m_ctr);
1355 
1356  m_map->clear();
1357 
1358  NotifyReset();
1360  }
1361 
1362  virtual event WFC_Handler^ MapChanged {
1363  virtual Details::Token add(WFC_Handler^ e) {
1364  m_observed = true;
1365  return m_wfc_event += e;
1366  }
1367 
1368  virtual void remove(Details::Token t) {
1369  m_wfc_event -= t;
1370  }
1371  };
1372 
1373  private:
1374  void NotifyReset() {
1375  if (m_observed) {
1376  m_wfc_event(this, ref new Details::MapChangedEventArgsReset<K>);
1377  }
1378  }
1379 
1380  void NotifyInserted(K key) {
1381  if (m_observed) {
1382  m_wfc_event(this, ref new Details::MapChangedEventArgs<K>(Details::WFC::CollectionChange::ItemInserted, key));
1383  }
1384  }
1385 
1386  void NotifyRemoved(K key) {
1387  if (m_observed) {
1388  m_wfc_event(this, ref new Details::MapChangedEventArgs<K>(Details::WFC::CollectionChange::ItemRemoved, key));
1389  }
1390  }
1391 
1392  void NotifyChanged(K key) {
1393  if (m_observed) {
1394  m_wfc_event(this, ref new Details::MapChangedEventArgs<K>(Details::WFC::CollectionChange::ItemChanged, key));
1395  }
1396  }
1397 
1398  ::std::shared_ptr<unsigned int> m_ctr;
1399  ::std::shared_ptr<WrappedMap> m_map;
1400  bool m_observed;
1401 
1402  event WFC_Handler^ m_wfc_event;
1403  };
1404 
1405  template <typename K, typename V, typename H, typename P> ref class UnorderedMap<K, V, H, P, false, false> {
1406  static_assert(Details::AlwaysFalse<K>::value, "Platform::Collections::UnorderedMap<K, V, H, P> requires K and V to be valid Windows Runtime types.");
1407  };
1408 
1409  template <typename K, typename V, typename H, typename P> ref class UnorderedMap<K, V, H, P, false, true> {
1410  static_assert(Details::AlwaysFalse<K>::value, "Platform::Collections::UnorderedMap<K, V, H, P> requires K to be a valid Windows Runtime type.");
1411  };
1412 
1413  template <typename K, typename V, typename H, typename P> ref class UnorderedMap<K, V, H, P, true, false> {
1414  static_assert(Details::AlwaysFalse<K>::value, "Platform::Collections::UnorderedMap<K, V, H, P> requires V to be a valid Windows Runtime type.");
1415  };
1416 
1417  template <typename K, typename V, typename H, typename P, bool, bool> ref class UnorderedMap sealed : public _COLLECTION_ATTRIBUTES Details::WFC::IObservableMap<K, V> {
1418  private:
1419  typedef typename Details::WrapUnorderedMap<K, V, H, P>::type WrappedMap;
1420  typedef Details::IteratorForAnyMapView<K, V, WrappedMap> MyIterator;
1421  typedef UnorderedMapView<K, V, H, P> MyView;
1422  typedef Details::WFC::MapChangedEventHandler<K, V> WFC_Handler;
1423 
1424  internal:
1425  UnorderedMap() {
1426  Details::Init(m_ctr, m_map);
1427 
1428  m_observed = false;
1429  }
1430 
1431  explicit UnorderedMap(size_t n) {
1432  Details::Init(m_ctr, m_map, n, H(), P());
1433 
1434  m_observed = false;
1435  }
1436 
1437  UnorderedMap(size_t n, const H& h) {
1438  Details::Init(m_ctr, m_map, n, h, P());
1439 
1440  m_observed = false;
1441  }
1442 
1443  UnorderedMap(size_t n, const H& h, const P& p) {
1444  Details::Init(m_ctr, m_map, n, h, p);
1445 
1446  m_observed = false;
1447  }
1448 
1449  explicit UnorderedMap(const ::std::unordered_map<K, V, H, P>& m) {
1450  Details::Init(m_ctr, m_map, m.bucket_count(), m.hash_function(), m.key_eq());
1451 
1452  Details::EmplaceWrappedRange<K, V>(*m_map, m.begin(), m.end());
1453 
1454  m_observed = false;
1455  }
1456 
1457  explicit UnorderedMap(::std::unordered_map<K, V, H, P>&& m) {
1458  Details::InitMoveMap<K, V>(m_ctr, m_map, ::std::move(m));
1459 
1460  m_observed = false;
1461  }
1462 
1463  template <typename InIt> UnorderedMap(InIt first, InIt last) {
1464  Details::Init(m_ctr, m_map);
1465 
1466  Details::EmplaceWrappedRange<K, V>(*m_map, first, last);
1467 
1468  m_observed = false;
1469  }
1470 
1471  template <typename InIt> UnorderedMap(InIt first, InIt last, size_t n) {
1472  Details::Init(m_ctr, m_map, n, H(), P());
1473 
1474  Details::EmplaceWrappedRange<K, V>(*m_map, first, last);
1475 
1476  m_observed = false;
1477  }
1478 
1479  template <typename InIt> UnorderedMap(InIt first, InIt last, size_t n, const H& h) {
1480  Details::Init(m_ctr, m_map, n, h, P());
1481 
1482  Details::EmplaceWrappedRange<K, V>(*m_map, first, last);
1483 
1484  m_observed = false;
1485  }
1486 
1487  template <typename InIt> UnorderedMap(InIt first, InIt last, size_t n, const H& h, const P& p) {
1488  Details::Init(m_ctr, m_map, n, h, p);
1489 
1490  Details::EmplaceWrappedRange<K, V>(*m_map, first, last);
1491 
1492  m_observed = false;
1493  }
1494 
1495  UnorderedMap(::std::initializer_list< ::std::pair<const K, V>> il) {
1496  Details::Init(m_ctr, m_map);
1497 
1498  Details::EmplaceWrappedRange<K, V>(*m_map, il.begin(), il.end());
1499 
1500  m_observed = false;
1501  }
1502 
1503  UnorderedMap(::std::initializer_list< ::std::pair<const K, V>> il, size_t n) {
1504  Details::Init(m_ctr, m_map, n, H(), P());
1505 
1506  Details::EmplaceWrappedRange<K, V>(*m_map, il.begin(), il.end());
1507 
1508  m_observed = false;
1509  }
1510 
1511  UnorderedMap(::std::initializer_list< ::std::pair<const K, V>> il, size_t n, const H& h) {
1512  Details::Init(m_ctr, m_map, n, h, P());
1513 
1514  Details::EmplaceWrappedRange<K, V>(*m_map, il.begin(), il.end());
1515 
1516  m_observed = false;
1517  }
1518 
1519  UnorderedMap(::std::initializer_list< ::std::pair<const K, V>> il, size_t n, const H& h, const P& p) {
1520  Details::Init(m_ctr, m_map, n, h, p);
1521 
1522  Details::EmplaceWrappedRange<K, V>(*m_map, il.begin(), il.end());
1523 
1524  m_observed = false;
1525  }
1526 
1527  public:
1528  virtual Details::WFC::IIterator<Details::WFC::IKeyValuePair<K, V>^>^ First() {
1529  return ref new MyIterator(m_ctr, m_map);
1530  }
1531 
1532  virtual V Lookup(K key) {
1533  auto i = m_map->find(Details::MakeWrap(key));
1534 
1535  Details::ValidateBounds(i != m_map->end());
1536 
1537  return Details::Unwrap(i->second);
1538  }
1539 
1540  virtual property unsigned int Size {
1541  virtual unsigned int get() {
1542  return static_cast<unsigned int>(m_map->size());
1543  }
1544  }
1545 
1546  virtual bool HasKey(K key) {
1547  return m_map->find(Details::MakeWrap(key)) != m_map->end();
1548  }
1549 
1550  virtual Details::WFC::IMapView<K, V>^ GetView() {
1551  return ref new MyView(m_ctr, m_map);
1552  }
1553 
1554  virtual bool Insert(K key, V value) {
1555  try {
1556  Details::IncrementCounter(m_ctr);
1557 
1558  Details::ValidateSize(m_map->size() + 1);
1559 
1560  auto p = m_map->emplace(Details::MakeWrap(key), Details::MakeWrap(value));
1561 
1562  if (p.second) {
1563  NotifyInserted(key);
1564  } else {
1565  p.first->second = value;
1566  NotifyChanged(key);
1567  }
1568 
1569  return !p.second;
1571  }
1572 
1573  virtual void Remove(K key) {
1574  try {
1575  Details::IncrementCounter(m_ctr);
1576 
1577  Details::ValidateBounds(m_map->erase(Details::MakeWrap(key)) == 1);
1578 
1579  NotifyRemoved(key);
1581  }
1582 
1583  virtual void Clear() {
1584  try {
1585  Details::IncrementCounter(m_ctr);
1586 
1587  m_map->clear();
1588 
1589  NotifyReset();
1591  }
1592 
1593  virtual event WFC_Handler^ MapChanged {
1594  virtual Details::Token add(WFC_Handler^ e) {
1595  m_observed = true;
1596  return m_wfc_event += e;
1597  }
1598 
1599  virtual void remove(Details::Token t) {
1600  m_wfc_event -= t;
1601  }
1602  };
1603 
1604  private:
1605  void NotifyReset() {
1606  if (m_observed) {
1607  m_wfc_event(this, ref new Details::MapChangedEventArgsReset<K>);
1608  }
1609  }
1610 
1611  void NotifyInserted(K key) {
1612  if (m_observed) {
1613  m_wfc_event(this, ref new Details::MapChangedEventArgs<K>(Details::WFC::CollectionChange::ItemInserted, key));
1614  }
1615  }
1616 
1617  void NotifyRemoved(K key) {
1618  if (m_observed) {
1619  m_wfc_event(this, ref new Details::MapChangedEventArgs<K>(Details::WFC::CollectionChange::ItemRemoved, key));
1620  }
1621  }
1622 
1623  void NotifyChanged(K key) {
1624  if (m_observed) {
1625  m_wfc_event(this, ref new Details::MapChangedEventArgs<K>(Details::WFC::CollectionChange::ItemChanged, key));
1626  }
1627  }
1628 
1629  ::std::shared_ptr<unsigned int> m_ctr;
1630  ::std::shared_ptr<WrappedMap> m_map;
1631  bool m_observed;
1632 
1633  event WFC_Handler^ m_wfc_event;
1634  };
1635 
1636 
1637  template <typename X> class InputIterator;
1638  template <typename T> class VectorIterator;
1639  template <typename T> class VectorViewIterator;
1640  template <typename T> class BackInsertIterator;
1641  } // namespace Collections
1642 } // namespace Platform
1643 
1644 template <typename X> struct ::std::_Is_checked_helper< ::Platform::Collections::InputIterator<X>>
1646 
1647 template <typename T> struct ::std::_Is_checked_helper< ::Platform::Collections::VectorIterator<T>>
1649 
1650 template <typename T> struct ::std::_Is_checked_helper< ::Platform::Collections::VectorViewIterator<T>>
1652 
1653 template <typename T> struct ::std::_Is_checked_helper< ::Platform::Collections::BackInsertIterator<T>>
1655 
1656 namespace Platform {
1657  namespace Collections {
1658  template <typename X> class InputIterator {
1659  public:
1660  typedef ::std::input_iterator_tag iterator_category;
1661  typedef X value_type;
1662  typedef ptrdiff_t difference_type;
1663  typedef const X * pointer;
1664  typedef const X & reference;
1665 
1666  InputIterator() { }
1667 
1668  explicit InputIterator(Details::WFC::IIterator<X>^ iter) {
1669  if (iter->HasCurrent) {
1670  m_iter = iter;
1671  m_val = iter->Current;
1672  }
1673  }
1674 
1675  bool operator==(const InputIterator& other) const {
1676  return !!m_iter == !!other.m_iter;
1677  }
1678 
1679  bool operator!=(const InputIterator& other) const {
1680  return !(*this == other);
1681  }
1682 
1683  reference operator*() const {
1684  return m_val;
1685  }
1686 
1687  pointer operator->() const {
1688  return &m_val;
1689  }
1690 
1691  InputIterator& operator++() {
1692  if (m_iter->MoveNext()) {
1693  m_val = m_iter->Current;
1694  } else {
1695  m_iter = nullptr;
1696  }
1697 
1698  return *this;
1699  }
1700 
1701  InputIterator operator++(int) {
1702  InputIterator old(*this);
1703  ++*this;
1704  return old;
1705  }
1706 
1707  private:
1708  Details::WFC::IIterator<X>^ m_iter;
1709  X m_val;
1710  };
1711 
1712  namespace Details {
1713  template <typename T> class VectorProxy {
1714  public:
1715  VectorProxy(WFC::IVector<T>^ v, ptrdiff_t n)
1716  : m_v(v), m_i(static_cast<unsigned int>(n)) { }
1717 
1718  VectorProxy& operator=(const VectorProxy& other) {
1719  m_v->SetAt(m_i, other.m_v->GetAt(other.m_i));
1720  return *this;
1721  }
1722 
1723  VectorProxy& operator=(T t) {
1724  m_v->SetAt(m_i, t);
1725  return *this;
1726  }
1727 
1728  operator T() const {
1729  return m_v->GetAt(m_i);
1730  }
1731 
1732  T operator->() const {
1733  return m_v->GetAt(m_i);
1734  }
1735 
1736  void swap(const VectorProxy& other) const {
1737  T t1(m_v->GetAt(m_i));
1738  T t2(other.m_v->GetAt(other.m_i));
1739 
1740  m_v->SetAt(m_i, t2);
1741  other.m_v->SetAt(other.m_i, t1);
1742  }
1743 
1744  void swap(T& t) const {
1745  T temp(t);
1746  t = m_v->GetAt(m_i);
1747  m_v->SetAt(m_i, temp);
1748  }
1749 
1750  private:
1751  WFC::IVector<T>^ m_v;
1752  unsigned int m_i;
1753  };
1754 
1755  template <typename T> inline void swap(const VectorProxy<T>& l, const VectorProxy<T>& r) {
1756  l.swap(r);
1757  }
1758 
1759  template <typename T> inline void swap(const VectorProxy<T>& p, T& t) {
1760  p.swap(t);
1761  }
1762 
1763  template <typename T> inline void swap(T& t, const VectorProxy<T>& p) {
1764  p.swap(t);
1765  }
1766 
1767  template <typename T> inline bool operator==(const VectorProxy<T>& l, const VectorProxy<T>& r) {
1768  return static_cast<T>(l) == static_cast<T>(r);
1769  }
1770 
1771  template <typename T> inline bool operator==(const VectorProxy<T>& l, const T& t) {
1772  return static_cast<T>(l) == t;
1773  }
1774 
1775  template <typename T> inline bool operator==(const T& t, const VectorProxy<T>& r) {
1776  return t == static_cast<T>(r);
1777  }
1778 
1779  template <typename T> inline bool operator!=(const VectorProxy<T>& l, const VectorProxy<T>& r) {
1780  return static_cast<T>(l) != static_cast<T>(r);
1781  }
1782 
1783  template <typename T> inline bool operator!=(const VectorProxy<T>& l, const T& t) {
1784  return static_cast<T>(l) != t;
1785  }
1786 
1787  template <typename T> inline bool operator!=(const T& t, const VectorProxy<T>& r) {
1788  return t != static_cast<T>(r);
1789  }
1790 
1791  template <typename T> inline bool operator<(const VectorProxy<T>& l, const VectorProxy<T>& r) {
1792  return static_cast<T>(l) < static_cast<T>(r);
1793  }
1794 
1795  template <typename T> inline bool operator<(const VectorProxy<T>& l, const T& t) {
1796  return static_cast<T>(l) < t;
1797  }
1798 
1799  template <typename T> inline bool operator<(const T& t, const VectorProxy<T>& r) {
1800  return t < static_cast<T>(r);
1801  }
1802 
1803  template <typename T> inline bool operator<=(const VectorProxy<T>& l, const VectorProxy<T>& r) {
1804  return static_cast<T>(l) <= static_cast<T>(r);
1805  }
1806 
1807  template <typename T> inline bool operator<=(const VectorProxy<T>& l, const T& t) {
1808  return static_cast<T>(l) <= t;
1809  }
1810 
1811  template <typename T> inline bool operator<=(const T& t, const VectorProxy<T>& r) {
1812  return t <= static_cast<T>(r);
1813  }
1814 
1815  template <typename T> inline bool operator>(const VectorProxy<T>& l, const VectorProxy<T>& r) {
1816  return static_cast<T>(l) > static_cast<T>(r);
1817  }
1818 
1819  template <typename T> inline bool operator>(const VectorProxy<T>& l, const T& t) {
1820  return static_cast<T>(l) > t;
1821  }
1822 
1823  template <typename T> inline bool operator>(const T& t, const VectorProxy<T>& r) {
1824  return t > static_cast<T>(r);
1825  }
1826 
1827  template <typename T> inline bool operator>=(const VectorProxy<T>& l, const VectorProxy<T>& r) {
1828  return static_cast<T>(l) >= static_cast<T>(r);
1829  }
1830 
1831  template <typename T> inline bool operator>=(const VectorProxy<T>& l, const T& t) {
1832  return static_cast<T>(l) >= t;
1833  }
1834 
1835  template <typename T> inline bool operator>=(const T& t, const VectorProxy<T>& r) {
1836  return t >= static_cast<T>(r);
1837  }
1838 
1839  template <typename T> class ArrowProxy {
1840  public:
1841  explicit ArrowProxy(T t)
1842  : m_val(t) { }
1843 
1844  const T * operator->() const {
1845  return &m_val;
1846  }
1847 
1848  private:
1849  T m_val;
1850  };
1851  } // namespace Details
1852 
1853  template <typename T> class VectorIterator {
1854  public:
1855  typedef ::std::random_access_iterator_tag iterator_category;
1856  typedef T value_type;
1857  typedef ptrdiff_t difference_type;
1858  typedef Details::VectorProxy<T> * pointer;
1859  typedef Details::VectorProxy<T> reference;
1860 
1861  VectorIterator()
1862  : m_v(nullptr), m_i(0) { }
1863 
1864  explicit VectorIterator(Details::WFC::IVector<T>^ v)
1865  : m_v(v), m_i(0) { }
1866 
1867  reference operator*() const {
1868  return reference(m_v, m_i);
1869  }
1870 
1871  Details::ArrowProxy<T> operator->() const {
1872  return Details::ArrowProxy<T>(m_v->GetAt(static_cast<unsigned int>(m_i)));
1873  }
1874 
1875  reference operator[](difference_type n) const {
1876  return reference(m_v, m_i + n);
1877  }
1878 
1879  VectorIterator& operator++() {
1880  ++m_i;
1881  return *this;
1882  }
1883 
1884  VectorIterator& operator--() {
1885  --m_i;
1886  return *this;
1887  }
1888 
1889  VectorIterator operator++(int) {
1890  VectorIterator old(*this);
1891  ++*this;
1892  return old;
1893  }
1894 
1895  VectorIterator operator--(int) {
1896  VectorIterator old(*this);
1897  --*this;
1898  return old;
1899  }
1900 
1901  VectorIterator& operator+=(difference_type n) {
1902  m_i += n;
1903  return *this;
1904  }
1905 
1906  VectorIterator& operator-=(difference_type n) {
1907  m_i -= n;
1908  return *this;
1909  }
1910 
1911  VectorIterator operator+(difference_type n) const {
1912  VectorIterator ret(*this);
1913  ret += n;
1914  return ret;
1915  }
1916 
1917  VectorIterator operator-(difference_type n) const {
1918  VectorIterator ret(*this);
1919  ret -= n;
1920  return ret;
1921  }
1922 
1923  difference_type operator-(const VectorIterator& other) const {
1924  return m_i - other.m_i;
1925  }
1926 
1927  bool operator==(const VectorIterator& other) const {
1928  return m_i == other.m_i;
1929  }
1930 
1931  bool operator!=(const VectorIterator& other) const {
1932  return m_i != other.m_i;
1933  }
1934 
1935  bool operator<(const VectorIterator& other) const {
1936  return m_i < other.m_i;
1937  }
1938 
1939  bool operator>(const VectorIterator& other) const {
1940  return m_i > other.m_i;
1941  }
1942 
1943  bool operator<=(const VectorIterator& other) const {
1944  return m_i <= other.m_i;
1945  }
1946 
1947  bool operator>=(const VectorIterator& other) const {
1948  return m_i >= other.m_i;
1949  }
1950 
1951  private:
1952  Details::WFC::IVector<T>^ m_v;
1953  difference_type m_i;
1954  };
1955 
1956  template <typename T> inline VectorIterator<T> operator+(ptrdiff_t n, const VectorIterator<T>& i) {
1957  return i + n;
1958  }
1959 
1960  template <typename T> class VectorViewIterator {
1961  public:
1962  typedef ::std::random_access_iterator_tag iterator_category;
1963  typedef T value_type;
1964  typedef ptrdiff_t difference_type;
1965  typedef T * pointer;
1966  typedef T reference;
1967 
1968  VectorViewIterator()
1969  : m_v(nullptr), m_i(0) { }
1970 
1971  explicit VectorViewIterator(Details::WFC::IVectorView<T>^ v)
1972  : m_v(v), m_i(0) { }
1973 
1974  reference operator*() const {
1975  return m_v->GetAt(static_cast<unsigned int>(m_i));
1976  }
1977 
1978  Details::ArrowProxy<T> operator->() const {
1979  return Details::ArrowProxy<T>(m_v->GetAt(static_cast<unsigned int>(m_i)));
1980  }
1981 
1982  reference operator[](difference_type n) const {
1983  return m_v->GetAt(static_cast<unsigned int>(m_i + n));
1984  }
1985 
1986  VectorViewIterator& operator++() {
1987  ++m_i;
1988  return *this;
1989  }
1990 
1991  VectorViewIterator& operator--() {
1992  --m_i;
1993  return *this;
1994  }
1995 
1996  VectorViewIterator operator++(int) {
1997  VectorViewIterator old(*this);
1998  ++*this;
1999  return old;
2000  }
2001 
2002  VectorViewIterator operator--(int) {
2003  VectorViewIterator old(*this);
2004  --*this;
2005  return old;
2006  }
2007 
2008  VectorViewIterator& operator+=(difference_type n) {
2009  m_i += n;
2010  return *this;
2011  }
2012 
2013  VectorViewIterator& operator-=(difference_type n) {
2014  m_i -= n;
2015  return *this;
2016  }
2017 
2018  VectorViewIterator operator+(difference_type n) const {
2019  VectorViewIterator ret(*this);
2020  ret += n;
2021  return ret;
2022  }
2023 
2024  VectorViewIterator operator-(difference_type n) const {
2025  VectorViewIterator ret(*this);
2026  ret -= n;
2027  return ret;
2028  }
2029 
2030  difference_type operator-(const VectorViewIterator& other) const {
2031  return m_i - other.m_i;
2032  }
2033 
2034  bool operator==(const VectorViewIterator& other) const {
2035  return m_i == other.m_i;
2036  }
2037 
2038  bool operator!=(const VectorViewIterator& other) const {
2039  return m_i != other.m_i;
2040  }
2041 
2042  bool operator<(const VectorViewIterator& other) const {
2043  return m_i < other.m_i;
2044  }
2045 
2046  bool operator>(const VectorViewIterator& other) const {
2047  return m_i > other.m_i;
2048  }
2049 
2050  bool operator<=(const VectorViewIterator& other) const {
2051  return m_i <= other.m_i;
2052  }
2053 
2054  bool operator>=(const VectorViewIterator& other) const {
2055  return m_i >= other.m_i;
2056  }
2057 
2058  private:
2059  Details::WFC::IVectorView<T>^ m_v;
2060  difference_type m_i;
2061  };
2062 
2063  template <typename T> inline VectorViewIterator<T> operator+(ptrdiff_t n, const VectorViewIterator<T>& i) {
2064  return i + n;
2065  }
2066 
2067  template <typename T> class BackInsertIterator
2068  : public ::std::iterator< ::std::output_iterator_tag, void, void, void, void> {
2069  public:
2070  explicit BackInsertIterator(Details::WFC::IVector<T>^ v) : m_v(v) { }
2071 
2072  BackInsertIterator& operator=(const T& t) {
2073  m_v->Append(t);
2074  return *this;
2075  }
2076 
2077  BackInsertIterator& operator*() {
2078  return *this;
2079  }
2080 
2081  BackInsertIterator& operator++() {
2082  return *this;
2083  }
2084 
2085  BackInsertIterator operator++(int) {
2086  return *this;
2087  }
2088 
2089  private:
2090  Details::WFC::IVector<T>^ m_v;
2091  };
2092 
2093  namespace Details {
2094  template <typename T, typename I> inline ::std::vector<T> ToVector(I^ v) {
2095  unsigned int size = v->Size;
2096 
2097  ::std::vector<T> ret(size);
2098 
2099  for (unsigned int actual = 0; actual < size; ) {
2100  Array<T>^ arr = ref new Array<T>(size - actual);
2101 
2102  unsigned int n = v->GetMany(actual, arr);
2103 
2104  if (n == 0) {
2105  throw ref new FailureException;
2106  }
2107 
2108  ::std::copy_n(arr->begin(), n, ret.begin() + actual);
2109 
2110  actual += n;
2111  }
2112 
2113  return ret;
2114  }
2115  } // namespace Details
2116  } // namespace Collections
2117 } // namespace Platform
2118 
2119 namespace Windows {
2120  namespace Foundation {
2121  namespace Collections {
2122  template <typename X> inline ::Platform::Collections::InputIterator<X> begin(IIterable<X>^ i) {
2123  return ::Platform::Collections::InputIterator<X>(i->First());
2124  }
2125 
2126  template <typename X> inline ::Platform::Collections::InputIterator<X> end(IIterable<X>^) {
2127  return ::Platform::Collections::InputIterator<X>();
2128  }
2129 
2130  template <typename T> inline ::Platform::Collections::VectorIterator<T> begin(IVector<T>^ v) {
2131  return ::Platform::Collections::VectorIterator<T>(v);
2132  }
2133 
2134  template <typename T> inline ::Platform::Collections::VectorIterator<T> end(IVector<T>^ v) {
2135  return ::Platform::Collections::VectorIterator<T>(v) + v->Size;
2136  }
2137 
2138  template <typename T> inline ::Platform::Collections::VectorViewIterator<T> begin(IVectorView<T>^ v) {
2139  return ::Platform::Collections::VectorViewIterator<T>(v);
2140  }
2141 
2142  template <typename T> inline ::Platform::Collections::VectorViewIterator<T> end(IVectorView<T>^ v) {
2143  return ::Platform::Collections::VectorViewIterator<T>(v) + v->Size;
2144  }
2145 
2146  template <typename T> inline ::std::vector<T> to_vector(IVector<T>^ v) {
2147  return ::Platform::Collections::Details::ToVector<T>(v);
2148  }
2149 
2150  template <typename T> inline ::std::vector<T> to_vector(IVectorView<T>^ v) {
2151  return ::Platform::Collections::Details::ToVector<T>(v);
2152  }
2153 
2154  template <typename T> inline ::Platform::Collections::BackInsertIterator<T> back_inserter(IVector<T>^ v) {
2155  return ::Platform::Collections::BackInsertIterator<T>(v);
2156  }
2157 
2158  template <typename T> inline ::Platform::Collections::BackInsertIterator<T> back_inserter(IObservableVector<T>^ v) {
2159  return ::Platform::Collections::BackInsertIterator<T>(v);
2160  }
2161  } // namespace Collections
2162  } // namespace Foundation
2163 } // namespace Windows
2164 
2165 namespace Platform {
2166  namespace Collections {
2167  template <typename T, typename E> inline BackInsertIterator<T> back_inserter(Vector<T, E>^ v) {
2168  return BackInsertIterator<T>(v);
2169  }
2170  } // namespace Collections
2171 } // namespace Platform
2172 
2173 template <> struct ::std::hash< ::Platform::String^>
2174  : public ::std::unary_function< ::Platform::String^, size_t> {
2175 
2176  size_t operator()(::Platform::String^ s) const {
2177  return ::std::_Hash_seq(reinterpret_cast<const unsigned char *>(s->Data()), s->Length() * sizeof(wchar_t));
2178  }
2179 };
2180 
2181 #undef _COLLECTION_ATTRIBUTES
2182 #undef _COLLECTION_TRANSLATE
2183 #undef _COLLECTION_WUXI
2184 
2185 #pragma warning(pop)
2186 #pragma pack(pop)
2187 
2188 #endif // RC_INVOKED
2189 
2190 #endif // _COLLECTION_H_
Definition: agile.h:22
_OutIt copy_n(_InIt _First, _Diff _Count, _OutIt _Dest)
Definition: xutility:2208
_Tuple_type< _Rank > operator*(const _Tuple_type< _Rank > &_Lhs, typename _Tuple_type< _Rank >::value_type _Rhs) __GPU
Definition: amp.h:870
_Ty & get(array< _Ty, _Size > &_Arr) _NOEXCEPT
Definition: array:506
virtual property __TBoxValue Value
Definition: vccorlib.h:1557
_FwdIt remove(_FwdIt _First, _FwdIt _Last, const _Ty &_Val)
Definition: algorithm:1741
back_insert_iterator< _Container > back_inserter(_Container &_Cont)
Definition: iterator:69
const ::default::char16 * end(::Platform::String^__strArg)
Definition: vccorlib.h:1949
__m128d m
Definition: dvec.h:71
_OutIt move(_InIt _First, _InIt _Last, _OutIt _Dest)
Definition: xutility:2447
T & operator+=(T &lhs, SafeInt< U, E > rhs)
Definition: safeint.h:1439
reference_wrapper< _Ty > ref(_Ty &_Val) _NOEXCEPT
Definition: xrefwrap:691
integral_constant< bool, false > false_type
Definition: xtr1common:48
const ::default::char16 * begin(::Platform::String^__strArg)
Definition: vccorlib.h:1944
_STD_BEGIN size_t _Hash_seq(const unsigned char *_First, size_t _Count)
Definition: xstddef:279
int i[4]
Definition: dvec.h:70
bool operator!=(const Agile< U > &a, nullptr_t)
Definition: agile.h:440
Definition: vccorlib.h:112
unsigned short wchar_t
Definition: crtdefs.h:536
_W64 int ptrdiff_t
Definition: crtdefs.h:530
_InIt find_if(_InIt _First, _InIt _Last, _Pr _Pred)
Definition: algorithm:51
_Tuple_type< _Rank > operator+(const _Tuple_type< _Rank > &_Lhs, const _Tuple_type< _Rank > &_Rhs) __GPU
Definition: amp.h:822
void swap(array< _Ty, _Size > &_Left, array< _Ty, _Size > &_Right) _NOEXCEPT_OP(_NOEXCEPT_OP(_Left.swap(_Right)))
Definition: array:429
bool operator<(const WeakReference &__aArg, const WeakReference &__bArg)
Definition: vccorlib.h:2793
bool operator<=(const unorm &_Lhs, const unorm &_Rhs) __GPU
Definition: amp_short_vectors.h:480
_Tuple_type< _Rank > operator-(const _Tuple_type< _Rank > &_Lhs, const _Tuple_type< _Rank > &_Rhs) __GPU
Definition: amp.h:830
integral_constant< bool, true > true_type
Definition: xtr1common:47
#define _COLLECTION_TRANSLATE
Definition: collection.h:35
bool operator==(nullptr_t, const Agile< U > &a)
Definition: agile.h:434
bool operator>=(const unorm &_Lhs, const unorm &_Rhs) __GPU
Definition: amp_short_vectors.h:470
#define _COLLECTION_ATTRIBUTES
Definition: collection.h:33
#define I
Definition: complex.h:70
bool operator>(const unorm &_Lhs, const unorm &_Rhs) __GPU
Definition: amp_short_vectors.h:450
T & operator-=(T &lhs, SafeInt< U, E > rhs)
Definition: safeint.h:1448