Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
212 changes: 183 additions & 29 deletions strings/base_collections_base.h

Large diffs are not rendered by default.

17 changes: 12 additions & 5 deletions strings/base_collections_input_map.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@

namespace winrt::impl
{
template <typename K, typename V, typename Container>
struct input_map :
implements<input_map<K, V, Container>, wfc::IMap<K, V>, wfc::IMapView<K, V>, wfc::IIterable<wfc::IKeyValuePair<K, V>>>,
map_base<input_map<K, V, Container>, K, V>
template <typename K, typename V, typename Container, typename ThreadingBase>
struct map_impl :
implements<map_impl<K, V, Container, ThreadingBase>, wfc::IMap<K, V>, wfc::IMapView<K, V>, wfc::IIterable<wfc::IKeyValuePair<K, V>>>,
map_base<map_impl<K, V, Container, ThreadingBase>, K, V>,
ThreadingBase
{
static_assert(std::is_same_v<Container, std::remove_reference_t<Container>>, "Must be constructed with rvalue.");

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

Expand All @@ -22,11 +23,17 @@ namespace winrt::impl
return m_values;
}

using ThreadingBase::acquire_shared;
using ThreadingBase::acquire_exclusive;

private:

Container m_values;
};

template <typename K, typename V, typename Container>
using input_map = map_impl<K, V, Container, single_threaded_collection_base>;

template <typename K, typename V, typename Container>
auto make_input_map(Container&& values)
{
Expand Down
17 changes: 12 additions & 5 deletions strings/base_collections_input_vector.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@

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

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

Expand All @@ -22,10 +23,16 @@ namespace winrt::impl
return m_values;
}

using ThreadingBase::acquire_shared;
using ThreadingBase::acquire_exclusive;

private:

Container m_values;
};

template <typename T, typename Container>
using input_vector = vector_impl<T, Container, single_threaded_collection_base>;
}

WINRT_EXPORT namespace winrt::param
Expand Down
57 changes: 53 additions & 4 deletions strings/base_collections_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@
namespace winrt::impl
{
template <typename K, typename V, typename Container>
struct observable_map :
implements<observable_map<K, V, Container>, wfc::IObservableMap<K, V>, wfc::IMap<K, V>, wfc::IMapView<K, V>, wfc::IIterable<wfc::IKeyValuePair<K, V>>>,
observable_map_base<observable_map<K, V, Container>, K, V>
using multi_threaded_map = map_impl<K, V, Container, multi_threaded_collection_base>;

template <typename K, typename V, typename Container, typename ThreadingBase>
struct observable_map_impl :
implements<observable_map_impl<K, V, Container, ThreadingBase>, wfc::IObservableMap<K, V>, wfc::IMap<K, V>, wfc::IMapView<K, V>, wfc::IIterable<wfc::IKeyValuePair<K, V>>>,
observable_map_base<observable_map_impl<K, V, Container, ThreadingBase>, K, V>,
ThreadingBase
{
static_assert(std::is_same_v<Container, std::remove_reference_t<Container>>, "Must be constructed with rvalue.");

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

Expand All @@ -22,10 +26,19 @@ namespace winrt::impl
return m_values;
}

using ThreadingBase::acquire_shared;
using ThreadingBase::acquire_exclusive;

private:

Container m_values;
};

template <typename K, typename V, typename Container>
using observable_map = observable_map_impl<K, V, Container, single_threaded_collection_base>;

template <typename K, typename V, typename Container>
using multi_threaded_observable_map = observable_map_impl<K, V, Container, multi_threaded_collection_base>;
}

WINRT_EXPORT namespace winrt
Expand All @@ -48,6 +61,24 @@ WINRT_EXPORT namespace winrt
return make<impl::input_map<K, V, std::unordered_map<K, V, Hash, KeyEqual, Allocator>>>(std::move(values));
}

template <typename K, typename V, typename Compare = std::less<K>, typename Allocator = std::allocator<std::pair<K const, V>>>
Windows::Foundation::Collections::IMap<K, V> multi_threaded_map()
{
return make<impl::multi_threaded_map<K, V, std::map<K, V, Compare, Allocator>>>(std::map<K, V, Compare, Allocator>{});
}

template <typename K, typename V, typename Compare = std::less<K>, typename Allocator = std::allocator<std::pair<K const, V>>>
Windows::Foundation::Collections::IMap<K, V> multi_threaded_map(std::map<K, V, Compare, Allocator>&& values)
{
return make<impl::multi_threaded_map<K, V, std::map<K, V, Compare, Allocator>>>(std::move(values));
}

template <typename K, typename V, typename Hash = std::hash<K>, typename KeyEqual = std::equal_to<K>, typename Allocator = std::allocator<std::pair<K const, V>>>
Windows::Foundation::Collections::IMap<K, V> multi_threaded_map(std::unordered_map<K, V, Hash, KeyEqual, Allocator>&& values)
{
return make<impl::multi_threaded_map<K, V, std::unordered_map<K, V, Hash, KeyEqual, Allocator>>>(std::move(values));
}

template <typename K, typename V, typename Compare = std::less<K>, typename Allocator = std::allocator<std::pair<K const, V>>>
Windows::Foundation::Collections::IObservableMap<K, V> single_threaded_observable_map()
{
Expand All @@ -65,6 +96,24 @@ WINRT_EXPORT namespace winrt
{
return make<impl::observable_map<K, V, std::unordered_map<K, V, Hash, KeyEqual, Allocator>>>(std::move(values));
}

template <typename K, typename V, typename Compare = std::less<K>, typename Allocator = std::allocator<std::pair<K const, V>>>
Windows::Foundation::Collections::IObservableMap<K, V> multi_threaded_observable_map()
{
return make<impl::multi_threaded_observable_map<K, V, std::map<K, V, Compare, Allocator>>>(std::map<K, V, Compare, Allocator>{});
}

template <typename K, typename V, typename Compare = std::less<K>, typename Allocator = std::allocator<std::pair<K const, V>>>
Windows::Foundation::Collections::IObservableMap<K, V> multi_threaded_observable_map(std::map<K, V, Compare, Allocator>&& values)
{
return make<impl::multi_threaded_observable_map<K, V, std::map<K, V, Compare, Allocator>>>(std::move(values));
}

template <typename K, typename V, typename Hash = std::hash<K>, typename KeyEqual = std::equal_to<K>, typename Allocator = std::allocator<std::pair<K const, V>>>
Windows::Foundation::Collections::IObservableMap<K, V> multi_threaded_observable_map(std::unordered_map<K, V, Hash, KeyEqual, Allocator>&& values)
{
return make<impl::multi_threaded_observable_map<K, V, std::unordered_map<K, V, Hash, KeyEqual, Allocator>>>(std::move(values));
}
}

namespace std
Expand Down
77 changes: 59 additions & 18 deletions strings/base_collections_vector.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@

namespace winrt::impl
{
template <typename Container>
template <typename T, typename Container>
using multi_threaded_vector = vector_impl<T, Container, multi_threaded_collection_base>;

template <typename Container, typename ThreadingBase = single_threaded_collection_base>
struct inspectable_observable_vector :
observable_vector_base<inspectable_observable_vector<Container>, Windows::Foundation::IInspectable>,
implements<inspectable_observable_vector<Container>,
wfc::IObservableVector<Windows::Foundation::IInspectable>, wfc::IVector<Windows::Foundation::IInspectable>, wfc::IVectorView<Windows::Foundation::IInspectable>, wfc::IIterable<Windows::Foundation::IInspectable>>
observable_vector_base<inspectable_observable_vector<Container, ThreadingBase>, Windows::Foundation::IInspectable>,
implements<inspectable_observable_vector<Container, ThreadingBase>,
wfc::IObservableVector<Windows::Foundation::IInspectable>, wfc::IVector<Windows::Foundation::IInspectable>, wfc::IVectorView<Windows::Foundation::IInspectable>, wfc::IIterable<Windows::Foundation::IInspectable>>,
ThreadingBase
{
static_assert(std::is_same_v<Container, std::remove_reference_t<Container>>, "Must be constructed with rvalue.");

Expand All @@ -23,23 +27,30 @@ namespace winrt::impl
return m_values;
}

using ThreadingBase::acquire_shared;
using ThreadingBase::acquire_exclusive;

private:

Container m_values;
};

template <typename T, typename Container>
template <typename Container>
using multi_threaded_inspectable_observable_vector = inspectable_observable_vector<Container, multi_threaded_collection_base>;

template <typename T, typename Container, typename ThreadingBase = single_threaded_collection_base>
struct convertible_observable_vector :
observable_vector_base<convertible_observable_vector<T, Container>, T>,
implements<convertible_observable_vector<T, Container>,
observable_vector_base<convertible_observable_vector<T, Container, ThreadingBase>, T>,
implements<convertible_observable_vector<T, Container, ThreadingBase>,
wfc::IObservableVector<T>, wfc::IVector<T>, wfc::IVectorView<T>, wfc::IIterable<T>,
wfc::IObservableVector<Windows::Foundation::IInspectable>, wfc::IVector<Windows::Foundation::IInspectable>, wfc::IVectorView<Windows::Foundation::IInspectable>, wfc::IIterable<Windows::Foundation::IInspectable>>
wfc::IObservableVector<Windows::Foundation::IInspectable>, wfc::IVector<Windows::Foundation::IInspectable>, wfc::IVectorView<Windows::Foundation::IInspectable>, wfc::IIterable<Windows::Foundation::IInspectable>>,
ThreadingBase
{
static_assert(!std::is_same_v<T, Windows::Foundation::IInspectable>);
static_assert(std::is_same_v<Container, std::remove_reference_t<Container>>, "Must be constructed with rvalue.");

using container_type = convertible_observable_vector<T, Container>;
using base_type = observable_vector_base<convertible_observable_vector<T, Container>, T>;
using container_type = convertible_observable_vector<T, Container, ThreadingBase>;
using base_type = observable_vector_base<convertible_observable_vector<T, Container, ThreadingBase>, T>;

explicit convertible_observable_vector(Container&& values) : m_values(std::forward<Container>(values))
{
Expand All @@ -55,6 +66,9 @@ namespace winrt::impl
return m_values;
}

using ThreadingBase::acquire_shared;
using ThreadingBase::acquire_exclusive;

auto First()
{
struct result
Expand All @@ -68,6 +82,7 @@ namespace winrt::impl

operator wfc::IIterator<Windows::Foundation::IInspectable>()
{
auto guard = container->acquire_shared();
return make<iterator>(container);
}
};
Expand Down Expand Up @@ -115,6 +130,7 @@ namespace winrt::impl

uint32_t GetMany(uint32_t const startIndex, array_view<Windows::Foundation::IInspectable> values) const
{
auto guard = this->acquire_shared();
if (startIndex >= m_values.size())
{
return 0;
Expand Down Expand Up @@ -202,11 +218,6 @@ namespace winrt::impl
impl::collection_version::iterator_type,
implements<iterator, Windows::Foundation::Collections::IIterator<Windows::Foundation::IInspectable>>
{
void abi_enter()
{
check_version(*m_owner);
}

explicit iterator(container_type* const container) noexcept :
impl::collection_version::iterator_type(*container),
m_current(container->get_container().begin()),
Expand All @@ -217,6 +228,8 @@ namespace winrt::impl

Windows::Foundation::IInspectable Current() const
{
auto guard = m_owner->acquire_shared();
check_version(*m_owner);
if (m_current == m_end)
{
throw hresult_out_of_bounds();
Expand All @@ -225,23 +238,29 @@ namespace winrt::impl
return box_value(*m_current);
}

bool HasCurrent() const noexcept
bool HasCurrent() const
{
auto guard = m_owner->acquire_shared();
check_version(*m_owner);
return m_current != m_end;
}

bool MoveNext() noexcept
bool MoveNext()
{
auto guard = m_owner->acquire_exclusive();
check_version(*m_owner);
if (m_current != m_end)
{
++m_current;
}

return HasCurrent();
return m_current != m_end;
}

uint32_t GetMany(array_view<Windows::Foundation::IInspectable> values)
{
auto guard = m_owner->acquire_exclusive();
check_version(*m_owner);
uint32_t const actual = (std::min)(static_cast<uint32_t>(std::distance(m_current, m_end)), values.size());

std::transform(m_current, m_current + actual, values.begin(), [&](auto && value)
Expand All @@ -262,6 +281,9 @@ namespace winrt::impl

Container m_values;
};

template <typename T, typename Container>
using multi_threaded_convertible_observable_vector = convertible_observable_vector<T, Container, multi_threaded_collection_base>;
}

WINRT_EXPORT namespace winrt
Expand All @@ -272,6 +294,12 @@ WINRT_EXPORT namespace winrt
return make<impl::input_vector<T, std::vector<T, Allocator>>>(std::move(values));
}

template <typename T, typename Allocator = std::allocator<T>>
Windows::Foundation::Collections::IVector<T> multi_threaded_vector(std::vector<T, Allocator>&& values = {})
{
return make<impl::multi_threaded_vector<T, std::vector<T, Allocator>>>(std::move(values));
}

template <typename T, typename Allocator = std::allocator<T>>
Windows::Foundation::Collections::IObservableVector<T> single_threaded_observable_vector(std::vector<T, Allocator>&& values = {})
{
Expand All @@ -284,4 +312,17 @@ WINRT_EXPORT namespace winrt
return make<impl::convertible_observable_vector<T, std::vector<T, Allocator>>>(std::move(values));
}
}

template <typename T, typename Allocator = std::allocator<T>>
Windows::Foundation::Collections::IObservableVector<T> multi_threaded_observable_vector(std::vector<T, Allocator>&& values = {})
{
if constexpr (std::is_same_v<T, Windows::Foundation::IInspectable>)
{
return make<impl::multi_threaded_inspectable_observable_vector<std::vector<T, Allocator>>>(std::move(values));
}
else
{
return make<impl::multi_threaded_convertible_observable_vector<T, std::vector<T, Allocator>>>(std::move(values));
}
}
}
21 changes: 21 additions & 0 deletions strings/base_lock.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ WINRT_EXPORT namespace winrt
m_mutex.lock();
}

slim_lock_guard(slim_lock_guard const&) = delete;

~slim_lock_guard() noexcept
{
m_mutex.unlock();
Expand All @@ -67,6 +69,25 @@ WINRT_EXPORT namespace winrt
slim_mutex& m_mutex;
};

struct slim_shared_lock_guard
{
explicit slim_shared_lock_guard(slim_mutex& m) noexcept :
m_mutex(m)
{
m_mutex.lock_shared();
}

slim_shared_lock_guard(slim_shared_lock_guard const&) = delete;

~slim_shared_lock_guard() noexcept
{
m_mutex.unlock_shared();
}

private:
slim_mutex& m_mutex;
};

struct slim_condition_variable
{
slim_condition_variable(slim_condition_variable const&) = delete;
Expand Down
Loading