Skip to content

Instantly share code, notes, and snippets.

@jonwis
Last active December 12, 2023 17:33
Show Gist options
  • Save jonwis/50b3151075956916249cd99b19ff6c44 to your computer and use it in GitHub Desktop.
Save jonwis/50b3151075956916249cd99b19ff6c44 to your computer and use it in GitHub Desktop.
Direct value set
#pragma once
#include <variant>
#include <vector>
#include <map>
#include <span>
#include <string_view>
namespace winrt::App2App
{
using direct_value_set_init = std::variant <
std::monostate,
uint8_t,
uint16_t,
uint32_t,
uint64_t,
int16_t,
int32_t,
int64_t,
winrt::Windows::Foundation::DateTime,
std::wstring_view,
winrt::guid const*,
float,
double,
winrt::Windows::Foundation::IInspectable,
std::span<uint8_t>,
std::span<uint16_t>,
std::span<uint32_t>,
std::span<uint64_t>,
std::span<int16_t>,
std::span<int32_t>,
std::span<int64_t>,
std::span<winrt::Windows::Foundation::DateTime>,
std::span<winrt::hstring>,
std::span<winrt::guid>,
std::span<float>,
std::span<double>,
std::span<winrt::Windows::Foundation::IInspectable>
> ;
using direct_value_set_stored = std::variant <
std::monostate,
uint8_t,
uint16_t,
uint32_t,
uint64_t,
int16_t,
int32_t,
int64_t,
winrt::Windows::Foundation::DateTime,
winrt::hstring,
winrt::guid,
float,
double,
winrt::Windows::Foundation::IInspectable,
winrt::com_array<uint8_t>,
winrt::com_array<uint16_t>,
winrt::com_array<uint32_t>,
winrt::com_array<uint64_t>,
winrt::com_array<int16_t>,
winrt::com_array<int32_t>,
winrt::com_array<int64_t>,
winrt::com_array<winrt::Windows::Foundation::DateTime>,
winrt::com_array<winrt::hstring>,
winrt::com_array<winrt::guid>,
winrt::com_array<float>,
winrt::com_array<double>,
winrt::com_array<winrt::Windows::Foundation::IInspectable>
> ;
struct direct_value_set_pair
{
std::wstring_view name;
direct_value_set_init value;
};
// From https://stackoverflow.com/questions/47203255/convert-stdvariant-to-another-stdvariant-with-super-set-of-types
template <class... Args>
struct variant_cast_proxy
{
std::variant<Args...> v;
template <class... ToArgs>
operator std::variant<ToArgs...>() const
{
return std::visit([](auto&& arg) -> std::variant<ToArgs...> { return arg; },
v);
}
};
template <class... Args>
auto variant_cast(const std::variant<Args...>& v) -> variant_cast_proxy<Args...>
{
return { v };
}
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
struct direct_value_set :
winrt::implements<direct_value_set, IDirectValueSet>,
std::map<winrt::hstring, direct_value_set_stored>
{
using map_t = std::map<winrt::hstring, direct_value_set_stored>;
direct_value_set() = default;
direct_value_set(std::initializer_list<direct_value_set_pair> list)
{
for (auto const& [k, v] : list)
{
std::visit(overloaded{
[&] <typename T>(std::span<T> const& m) { emplace(k, winrt::com_array<T>{m.begin(), m.end()}); },
[&](std::wstring_view const& m) { emplace(k, winrt::hstring{m}); },
[&](winrt::guid const* m) { emplace(k, *m); },
[&](auto&& m) { emplace(k, m); }
}, v);
}
}
direct_value_set(direct_value_set const& src) = default;
static IDirectValueSet make(std::initializer_list<direct_value_set_pair> list)
{
return winrt::make<direct_value_set>(list);
}
IDirectValueSet Clone()
{
return winrt::make<direct_value_set>(*this);
}
template<typename T> bool try_get(winrt::hstring const& name, T& value)
{
auto v = find(name);
if (v != end())
{
value = std::get<std::decay_t<T>>(v->second);
return true;
}
else
{
return false;
}
}
template<typename T> bool try_get_array(winrt::hstring const& name, winrt::com_array<T>& value)
{
auto v = find(name);
if (v != end())
{
auto const& array = std::get<winrt::com_array<std::decay_t<T>>>(v->second);
value = winrt::com_array<T>{array.begin(), array.end()};
return true;
}
else
{
return false;
}
}
template<typename T> auto copy_array(winrt::com_array<T> const& a)
{
return winrt::com_array<T>(a.begin(), a.end());
}
auto GetUInt8(winrt::hstring const& name) { return std::get<uint8_t>(this->at(name)); }
auto GetUInt16(winrt::hstring const& name) { return std::get<uint16_t>(this->at(name)); }
auto GetUInt32(winrt::hstring const& name) { return std::get<uint32_t>(this->at(name)); }
auto GetUInt64(winrt::hstring const& name) { return std::get<uint64_t>(this->at(name)); }
auto GetInt16(winrt::hstring const& name) { return std::get<int16_t>(this->at(name)); }
auto GetInt32(winrt::hstring const& name) { return std::get<int32_t>(this->at(name)); }
auto GetInt64(winrt::hstring const& name) { return std::get<int64_t>(this->at(name)); }
auto GetDateTime(winrt::hstring const& name) { return std::get<winrt::Windows::Foundation::DateTime>(this->at(name)); }
auto GetString(winrt::hstring const& name) { return std::get<winrt::hstring>(this->at(name)); }
auto GetGuid(winrt::hstring const& name) { return std::get<winrt::guid>(this->at(name)); }
auto GetSingle(winrt::hstring const& name) { return std::get<float>(this->at(name)); }
auto GetDouble(winrt::hstring const& name) { return std::get<double>(this->at(name)); }
auto GetObject(winrt::hstring const& name) { return std::get<winrt::Windows::Foundation::IInspectable>(this->at(name)); }
bool TryGetUInt8(winrt::hstring const& name, uint8_t& value) { return try_get(name, value); }
bool TryGetUInt16(winrt::hstring const& name, uint16_t& value) { return try_get(name, value); }
bool TryGetUInt32(winrt::hstring const& name, uint32_t& value) { return try_get(name, value); }
bool TryGetUInt64(winrt::hstring const& name, uint64_t& value) { return try_get(name, value); }
bool TryGetInt16(winrt::hstring const& name, int16_t& value) { return try_get(name, value); }
bool TryGetInt32(winrt::hstring const& name, int32_t& value) { return try_get(name, value); }
bool TryGetInt64(winrt::hstring const& name, int64_t& value) { return try_get(name, value); }
bool TryGetDateTime(winrt::hstring const& name, winrt::Windows::Foundation::DateTime& value) { return try_get(name, value); }
bool TryGetString(winrt::hstring const& name, winrt::hstring& value) { return try_get(name, value); }
bool TryGetGuid(winrt::hstring const& name, winrt::guid& value) { return try_get(name, value); }
bool TryGetSingle(winrt::hstring const& name, float& value) { return try_get(name, value); }
bool TryGetDouble(winrt::hstring const& name, double& value) { return try_get(name, value); }
bool TryGetObject(winrt::hstring const& name, winrt::Windows::Foundation::IInspectable& value) { return try_get(name, value); }
auto GetUInt8Array(winrt::hstring const& name) { return copy_array(std::get<winrt::com_array<uint8_t>>(this->at(name))); }
auto GetUInt16Array(winrt::hstring const& name) { return copy_array(std::get<winrt::com_array<uint16_t>>(this->at(name))); }
auto GetUInt32Array(winrt::hstring const& name) { return copy_array(std::get<winrt::com_array<uint32_t>>(this->at(name))); }
auto GetUInt64Array(winrt::hstring const& name) { return copy_array(std::get<winrt::com_array<uint64_t>>(this->at(name))); }
auto GetInt16Array(winrt::hstring const& name) { return copy_array(std::get<winrt::com_array<int16_t>>(this->at(name))); }
auto GetInt32Array(winrt::hstring const& name) { return copy_array(std::get<winrt::com_array<int32_t>>(this->at(name))); }
auto GetInt64Array(winrt::hstring const& name) { return copy_array(std::get<winrt::com_array<int64_t>>(this->at(name))); }
auto GetStringArray(winrt::hstring const& name) { return copy_array(std::get<winrt::com_array<winrt::hstring>>(this->at(name))); }
auto GetGuidArray(winrt::hstring const& name) { return copy_array(std::get<winrt::com_array<winrt::guid>>(this->at(name))); }
auto GetDateTimeArray(winrt::hstring const& name) { return copy_array(std::get<winrt::com_array<winrt::Windows::Foundation::DateTime>>(this->at(name))); }
auto GetSingleArray(winrt::hstring const& name) { return copy_array(std::get<winrt::com_array<float>>(this->at(name))); }
auto GetDoubleArray(winrt::hstring const& name) { return copy_array(std::get<winrt::com_array<double>>(this->at(name))); }
auto GetObjectArray(winrt::hstring const& name) { return copy_array(std::get<winrt::com_array<winrt::Windows::Foundation::IInspectable>>(this->at(name))); }
bool TryGetUInt8Array(winrt::hstring const& name, winrt::com_array<uint8_t>& value) { return try_get_array(name, value); }
bool TryGetUInt16Array(winrt::hstring const& name, winrt::com_array<uint16_t>& value) { return try_get_array(name, value); }
bool TryGetUInt32Array(winrt::hstring const& name, winrt::com_array<uint32_t>& value) { return try_get_array(name, value); }
bool TryGetUInt64Array(winrt::hstring const& name, winrt::com_array<uint64_t>& value) { return try_get_array(name, value); }
bool TryGetInt16Array(winrt::hstring const& name, winrt::com_array<int16_t>& value) { return try_get_array(name, value); }
bool TryGetInt32Array(winrt::hstring const& name, winrt::com_array<int32_t>& value) { return try_get_array(name, value); }
bool TryGetInt64Array(winrt::hstring const& name, winrt::com_array<int64_t>& value) { return try_get_array(name, value); }
bool TryGetDateTimeArray(winrt::hstring const& name, winrt::com_array<winrt::Windows::Foundation::DateTime>& value) { return try_get_array(name, value); }
bool TryGetStringArray(winrt::hstring const& name, winrt::com_array<winrt::hstring>& value) { return try_get_array(name, value); }
bool TryGetGuidArray(winrt::hstring const& name, winrt::com_array<winrt::guid>& value) { return try_get_array(name, value); }
bool TryGetSingleArray(winrt::hstring const& name, winrt::com_array<float>& value) { return try_get_array(name, value); }
bool TryGetDoubleArray(winrt::hstring const& name, winrt::com_array<double>& value) { return try_get_array(name, value); }
bool TryGetObjectArray(winrt::hstring const& name, winrt::com_array<winrt::Windows::Foundation::IInspectable>& value) { return try_get_array(name, value); }
};
}
/*
Here's some powershell to run to generate this type
cls
$typeList = @(
"UInt8",
"UInt16",
"UInt32",
"UInt64",
# "Int8", -- not a valid type
"Int16",
"Int32",
"Int64",
"String",
"Guid",
"Single",
"Double",
"Windows.Foundation.DateTime", # - be sure to fix this one up afterwards
"Object");
foreach ($t in $typelist) {
# "void Set$t(String key, $t value);"
# "void Set$($t)Array(String key, $t[] value);"
"$t Get$t(String key);"
"Boolean TryGet$t(String key, out $t value);"
"$t[] Get$($t)Array(String key);"
"Boolean TryGet$($t)Array(String key, out $t[] value);"
""
}
*/
namespace App2App
{
interface IDirectValueSet
{
UInt8 GetUInt8(String key);
Boolean TryGetUInt8(String key, out UInt8 value);
UInt8[] GetUInt8Array(String key);
Boolean TryGetUInt8Array(String key, out UInt8[] value);
UInt16 GetUInt16(String key);
Boolean TryGetUInt16(String key, out UInt16 value);
UInt16[] GetUInt16Array(String key);
Boolean TryGetUInt16Array(String key, out UInt16[] value);
UInt32 GetUInt32(String key);
Boolean TryGetUInt32(String key, out UInt32 value);
UInt32[] GetUInt32Array(String key);
Boolean TryGetUInt32Array(String key, out UInt32[] value);
UInt64 GetUInt64(String key);
Boolean TryGetUInt64(String key, out UInt64 value);
UInt64[] GetUInt64Array(String key);
Boolean TryGetUInt64Array(String key, out UInt64[] value);
Int16 GetInt16(String key);
Boolean TryGetInt16(String key, out Int16 value);
Int16[] GetInt16Array(String key);
Boolean TryGetInt16Array(String key, out Int16[] value);
Int32 GetInt32(String key);
Boolean TryGetInt32(String key, out Int32 value);
Int32[] GetInt32Array(String key);
Boolean TryGetInt32Array(String key, out Int32[] value);
Int64 GetInt64(String key);
Boolean TryGetInt64(String key, out Int64 value);
Int64[] GetInt64Array(String key);
Boolean TryGetInt64Array(String key, out Int64[] value);
String GetString(String key);
Boolean TryGetString(String key, out String value);
String[] GetStringArray(String key);
Boolean TryGetStringArray(String key, out String[] value);
Guid GetGuid(String key);
Boolean TryGetGuid(String key, out Guid value);
Guid[] GetGuidArray(String key);
Boolean TryGetGuidArray(String key, out Guid[] value);
Single GetSingle(String key);
Boolean TryGetSingle(String key, out Single value);
Single[] GetSingleArray(String key);
Boolean TryGetSingleArray(String key, out Single[] value);
Double GetDouble(String key);
Boolean TryGetDouble(String key, out Double value);
Double[] GetDoubleArray(String key);
Boolean TryGetDoubleArray(String key, out Double[] value);
Windows.Foundation.DateTime GetDateTime(String key);
Boolean TryGetDateTime(String key, out Windows.Foundation.DateTime value);
Windows.Foundation.DateTime[] GetDateTimeArray(String key);
Boolean TryGetDateTimeArray(String key, out Windows.Foundation.DateTime[] value);
Object GetObject(String key);
Boolean TryGetObject(String key, out Object value);
Object[] GetObjectArray(String key);
Boolean TryGetObjectArray(String key, out Object[] value);
IDirectValueSet Clone();
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment