Created
September 28, 2022 10:04
-
-
Save Redchards/f6f5343a3545b8b550c00a387f95b14d to your computer and use it in GitHub Desktop.
Noodling about
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
```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