Skip to content

Instantly share code, notes, and snippets.

@Redchards
Created September 28, 2022 10:04
Show Gist options
  • Save Redchards/f6f5343a3545b8b550c00a387f95b14d to your computer and use it in GitHub Desktop.
Save Redchards/f6f5343a3545b8b550c00a387f95b14d to your computer and use it in GitHub Desktop.
Noodling about
```c++
template<class V>
using AvialMap = std::map<std::string, V>;
namespace Meta
{
template<class, uint8_t depth>
struct RecursiveMapDepthAux : std::integral_constant<uint8_t, depth>
{};
template<class K, class V, uint8_t depth>
struct RecursiveMapDepthAux<std::map<K, V>, depth> : RecursiveMapDepthAux<V, depth + 1>
{};
template<class V>
struct RecursiveMapDepth : RecursiveMapDepthAux<V, 0>
{};
template<class T>
struct Identity
{
using type = T;
};
template<class V, size_t depth>
struct RecAvialMapBuilder : Identity<AvialMap<typename RecAvialMapBuilder<V, depth - 1>::type>>
{};
template<class V>
struct RecAvialMapBuilder<V, 0> : Identity<AvialMap<V>>
{};
}
template<class K, class V>
struct SparseTensor;
template<class K, class V>
struct SparseTensorLayer : std::variant<K, std::map<K, SparseTensor<K, V>>>
{
template<class FromK, class FromV>
static SparseTensorLayer<K, V> from(const std::map<FromK, FromV>& src_map);
template<class TVal>
static SparseTensorLayer<K, V> from(const TVal& val);
};
template<class K, class V>
struct SparseTensor
{
uint8_t depth;
SparseTensorLayer<K, V> layer;
template<class FromK, class FromV>
static SparseTensor<K, V> from(const std::map<FromK, FromV>& src_map);
};
template<class K, class V>
template<class FromK, class FromV>
auto SparseTensorLayer<K, V>::from(const std::map<FromK, FromV>& src_map)
-> SparseTensorLayer<K, V>
{
std::map<K, SparseTensor<K, V>> layer_map;
std::transform(src_map.begin(), src_map.end(), std::inserter(layer_map, layer_map.end()), [](const auto& item)
{
auto& [key, value] = item;
constexpr uint8_t current_depth = Meta::RecursiveMapDepth<FromV>::value;
return std::make_pair(key, SparseTensor{ current_depth, SparseTensorLayer<K, V>::from(value) });
});
return SparseTensorLayer{ layer_map };
}
template<class K, class V>
template<class TVal>
auto SparseTensorLayer<K, V>::from(const TVal& val)
-> SparseTensorLayer<K, V>
{
return SparseTensorLayer{ val };
}
template<class K, class V>
template<class FromK, class FromV>
auto SparseTensor<K, V>::from(const std::map<FromK, FromV>& src_map)
-> SparseTensor<K, V>
{
constexpr uint8_t current_depth = Meta::RecursiveMapDepth<std::map<FromK, FromV>>::value;
return SparseTensor{ current_depth, SparseTensorLayer<K, V>::from(src_map) };
}
template<class V, size_t depth>
using RecAvialMap = Meta::RecAvialMapBuilder<V, depth>::type;
int main()
{
auto my_map = RecAvialMap<std::string, 2> {
{"Key1", RecAvialMap<std::string, 1> {
{ "SubKey1", AvialMap<std::string> {
{ "SubSubKey1", "Val1"},
{ "SubSubKey2", "Val2"}
}},
{ "SubKey2", AvialMap<std::string> {
{ "SubSubKey1", "SuperVal1"}
}}
}},
{"Key2", RecAvialMap<std::string, 1> {
{ "SubKey1", AvialMap<std::string> {
{ "SubSubKey1", "Val1"},
{ "SubSubKey2", "Val2"},
{ "SubSubKey3", "Val3"},
{ "SubSubKey4", "Val4"}
}},
{ "SubKey2", AvialMap<std::string> {
{ "SubSubKey1", "SuperVal1"}
}}
}}
};
auto my_tensor = SparseTensor<std::string, std::string>::from(my_map);
return 0;
}```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment