Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C++20 ranges support #900

Merged
merged 17 commits into from
Mar 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions build_test_all.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ call msbuild /p:Configuration=%target_configuration%,Platform=%target_platform%,
call msbuild /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% test\nuget\NugetTest.sln

call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test
call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test_cpp20
call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test_win7
call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test_fast
call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test_slow
Expand Down
22 changes: 22 additions & 0 deletions cppwinrt.sln
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_win7", "test\test_win7
{A91B8BF3-28E4-4D9E-8DBA-64B70E4F0270} = {A91B8BF3-28E4-4D9E-8DBA-64B70E4F0270}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_cpp20", "test\test_cpp20\test_cpp20.vcxproj", "{5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA}"
ProjectSection(ProjectDependencies) = postProject
{D613FB39-5035-4043-91E2-BAB323908AF4} = {D613FB39-5035-4043-91E2-BAB323908AF4}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Expand Down Expand Up @@ -435,6 +440,22 @@ Global
{2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Release|x64.Build.0 = Release|x64
{2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Release|x86.ActiveCfg = Release|Win32
{2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Release|x86.Build.0 = Release|Win32
{5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA}.Debug|ARM.ActiveCfg = Debug|ARM
{5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA}.Debug|ARM.Build.0 = Debug|ARM
{5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA}.Debug|ARM64.ActiveCfg = Debug|ARM64
{5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA}.Debug|ARM64.Build.0 = Debug|ARM64
{5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA}.Debug|x64.ActiveCfg = Debug|x64
{5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA}.Debug|x64.Build.0 = Debug|x64
{5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA}.Debug|x86.ActiveCfg = Debug|Win32
{5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA}.Debug|x86.Build.0 = Debug|Win32
{5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA}.Release|ARM.ActiveCfg = Release|ARM
{5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA}.Release|ARM.Build.0 = Release|ARM
{5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA}.Release|ARM64.ActiveCfg = Release|ARM64
{5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA}.Release|ARM64.Build.0 = Release|ARM64
{5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA}.Release|x64.ActiveCfg = Release|x64
{5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA}.Release|x64.Build.0 = Release|x64
{5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA}.Release|x86.ActiveCfg = Release|Win32
{5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -457,6 +478,7 @@ Global
{D48A96C2-8512-4CC3-B6E4-7CFF07ED8ED3} = {3C7EA5F8-6E8C-4376-B499-2CAF596384B0}
{08C40663-B6A3-481E-8755-AE32BAD99501} = {3C7EA5F8-6E8C-4376-B499-2CAF596384B0}
{2EF696B9-7F4A-410F-AE5C-5301565C0F08} = {3C7EA5F8-6E8C-4376-B499-2CAF596384B0}
{5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA} = {3C7EA5F8-6E8C-4376-B499-2CAF596384B0}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2783B8FD-EA3B-4D6B-9F81-662D289E02AA}
Expand Down
44 changes: 40 additions & 4 deletions cppwinrt/code_writers.h
Original file line number Diff line number Diff line change
Expand Up @@ -1283,13 +1283,18 @@ namespace cppwinrt
static_cast<D&>(*this) = nullptr;
}

return *this;
return static_cast<D&>(*this);
}

auto operator*() const
{
return Current();
}

void operator++(int)
{
++(*this);
}
)");
}
else if (type_name == "Windows.Storage.Streams.IBuffer")
Expand All @@ -1313,13 +1318,18 @@ namespace cppwinrt
static_cast<D&>(*this) = nullptr;
}

return *this;
return static_cast<D&>(*this);
}

T operator*() const
{
return Current();
}

void operator++(int)
{
++(*this);
}
)");
}
else if (type_name == "Windows.Foundation.Collections.IKeyValuePair`2")
Expand Down Expand Up @@ -1415,6 +1425,20 @@ namespace cppwinrt
{
w.write(R"( auto get() const;
auto wait_for(Windows::Foundation::TimeSpan const& timeout) const;
)");
}
else if (type_name == "Windows.Foundation.Collections.IIterable`1")
{
w.write(R"(
auto begin() const;
auto end() const;
)");
}
else if (type_name == "Windows.UI.Xaml.Interop.IBindableIterable")
{
w.write(R"(
auto begin() const;
auto end() const;
)");
}
}
Expand All @@ -1426,11 +1450,23 @@ namespace cppwinrt
if (type_name == "Windows.Foundation.Collections.IIterator`1")
{
w.write(R"(
using iterator_concept = std::input_iterator_tag;
using iterator_category = std::input_iterator_tag;
using value_type = T;
using difference_type = ptrdiff_t;
using pointer = T*;
using reference = T&;
using pointer = void;
using reference = T;
)");
}
else if (type_name == "Windows.UI.Xaml.Interop.IBindableIterator")
{
w.write(R"(
using iterator_concept = std::input_iterator_tag;
using iterator_category = std::input_iterator_tag;
using value_type = Windows::Foundation::IInspectable;
using difference_type = ptrdiff_t;
using pointer = void;
using reference = Windows::Foundation::IInspectable;
)");
}
else if (type_name == "Windows.Foundation.IReference`1")
Expand Down
1 change: 1 addition & 0 deletions cppwinrt/cppwinrt.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
<ClInclude Include="..\strings\base_identity.h" />
<ClInclude Include="..\strings\base_implements.h" />
<ClInclude Include="..\strings\base_includes.h" />
<ClInclude Include="..\strings\base_iterator.h" />
<ClInclude Include="..\strings\base_lock.h" />
<ClInclude Include="..\strings\base_macros.h" />
<ClInclude Include="..\strings\base_marshaler.h" />
Expand Down
3 changes: 3 additions & 0 deletions cppwinrt/cppwinrt.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@
<ClInclude Include="..\strings\base_coroutine_system_winui.h">
<Filter>strings</Filter>
</ClInclude>
<ClInclude Include="..\strings\base_iterator.h">
<Filter>strings</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="$(OutDir)version.rc" />
Expand Down
1 change: 1 addition & 0 deletions cppwinrt/file_writers.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ namespace cppwinrt
w.write(strings::base_chrono);
w.write(strings::base_security);
w.write(strings::base_std_hash);
w.write(strings::base_iterator);
w.write(strings::base_coroutine_threadpool);
w.write(strings::base_natvis);
w.write(strings::base_version);
Expand Down
1 change: 1 addition & 0 deletions run_tests.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ if "%target_platform%"=="" set target_platform=x64
if "%target_configuration%"=="" set target_configuration=Debug

call :run_test test
call :run_test test_cpp20
call :run_test test_win7
call :run_test test_fast
call :run_test test_slow
Expand Down
171 changes: 6 additions & 165 deletions strings/base_collections.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,174 +3,15 @@ namespace winrt::impl
{
namespace wfc = Windows::Foundation::Collections;

template <typename T>
struct fast_iterator
template <typename D, typename T>
auto consume_Windows_Foundation_Collections_IIterable<D, T>::begin() const
{
using iterator_category = std::input_iterator_tag;
using value_type = decltype(std::declval<T>().GetAt(0));
using difference_type = ptrdiff_t;
using pointer = value_type*;
using reference = value_type;

fast_iterator() noexcept : m_collection(nullptr), m_index(0) {}

fast_iterator(T const& collection, uint32_t const index) noexcept :
m_collection(&collection),
m_index(index)
{}

fast_iterator& operator++() noexcept
{
++m_index;
return*this;
}

fast_iterator operator++(int) noexcept
{
auto previous = *this;
++m_index;
return previous;
}

fast_iterator& operator--() noexcept
{
--m_index;
return*this;
}

fast_iterator operator--(int) noexcept
{
auto previous = *this;
--m_index;
return previous;
}

fast_iterator& operator+=(difference_type n) noexcept
{
m_index += static_cast<uint32_t>(n);
return*this;
}

fast_iterator operator+(difference_type n) const noexcept
{
return fast_iterator(*this) += n;
}

fast_iterator& operator-=(difference_type n) noexcept
{
return *this += -n;
}

fast_iterator operator-(difference_type n) const noexcept
{
return *this + -n;
}

difference_type operator-(fast_iterator const& other) const noexcept
{
return static_cast<difference_type>(m_index) - static_cast<difference_type>(other.m_index);
}

reference operator*() const
{
return m_collection->GetAt(m_index);
}

reference operator[](difference_type n) const
{
return m_collection->GetAt(m_index + static_cast<uint32_t>(n));
}

bool operator==(fast_iterator const& other) const noexcept
{
WINRT_ASSERT(m_collection == other.m_collection);
return m_index == other.m_index;
}

bool operator<(fast_iterator const& other) const noexcept
{
WINRT_ASSERT(m_collection == other.m_collection);
return m_index < other.m_index;
}

bool operator!=(fast_iterator const& other) const noexcept
{
return !(*this == other);
}

bool operator>(fast_iterator const& other) const noexcept
{
return !(*this < other);
}

bool operator<=(fast_iterator const& other) const noexcept
{
return !(*this > other);
}

bool operator>=(fast_iterator const& other) const noexcept
{
return !(*this < other);
}

private:

T const* m_collection{};
uint32_t m_index{};
};

template <typename T>
class has_GetAt
{
template <typename U, typename = decltype(std::declval<U>().GetAt(0))> static constexpr bool get_value(int) { return true; }
template <typename> static constexpr bool get_value(...) { return false; }

public:

static constexpr bool value = get_value<T>(0);
};

template <typename T, std::enable_if_t<!has_GetAt<T>::value, int> = 0>
auto begin(T const& collection) -> decltype(collection.First())
{
auto result = collection.First();

if (!result.HasCurrent())
{
return {};
}

return result;
}

template <typename T, std::enable_if_t<!has_GetAt<T>::value, int> = 0>
auto end([[maybe_unused]] T const& collection) noexcept -> decltype(collection.First())
{
return {};
return get_begin_iterator(static_cast<D const&>(*this));
}

template <typename T, std::enable_if_t<has_GetAt<T>::value, int> = 0>
fast_iterator<T> begin(T const& collection) noexcept
{
return { collection, 0 };
}

template <typename T, std::enable_if_t<has_GetAt<T>::value, int> = 0>
fast_iterator<T> end(T const& collection)
{
return { collection, collection.Size() };
}

template <typename T, std::enable_if_t<has_GetAt<T>::value, int> = 0>
auto rbegin(T const& collection)
{
return std::make_reverse_iterator(end(collection));
}

template <typename T, std::enable_if_t<has_GetAt<T>::value, int> = 0>
auto rend(T const& collection)
template <typename D, typename T>
auto consume_Windows_Foundation_Collections_IIterable<D, T>::end() const
{
return std::make_reverse_iterator(begin(collection));
return get_end_iterator(static_cast<D const&>(*this));
}

template <typename T>
Expand Down
Loading