コンパイル時にunorderd_mapもどき
ユーザインタフェースに互換性はないですし、作りこんで無いですが、とりあえず機能的には最低限使えるんじゃないかなと思います。
先頭から順に要素を探索するので同一キーで異なる値を登録した場合も、必ず最初に登録した要素が返ります。
失敗する可能性のある処理なので、探索結果(true or false)とその値のpairを返しています。
falseの場合の値は未定義です。
#include <sprout/array.hpp> #include <sprout/string.hpp> #include <sprout/utility.hpp> #include <sprout/index_tuple.hpp> template<class T1, class T2, std::size_t size = 1> struct unorderd_map { constexpr unorderd_map(T1 key, T2 value, sprout::array<std::size_t, size - 1> prev_hash = {}, sprout::array<T2, size - 1> prev_data = {} ) : hash(make_hash(sprout::hash_value(key), prev_hash, sprout::index_range<0, size - 1>::make())), data(make_value(value, prev_data, sprout::index_range<0, size - 1>::make())) {} public: const sprout::array<std::size_t, size> hash; const sprout::array<T2, size> data; private: const T2* none = nullptr; public: constexpr unorderd_map<T1, T2, size + 1> operator()(T1 key, T2 value) const { return unorderd_map<T1, T2, size + 1>(key, value, hash, data); } constexpr sprout::pair<bool, T2> operator[](T1 arg) const { return get_impl(sprout::hash_value(arg), 0); } private: template<sprout::index_t... Indices> static constexpr sprout::array<std::size_t, size> make_hash(const std::size_t arg, const sprout::array<std::size_t, size - 1> prev, sprout::index_tuple<Indices...>) { return sprout::array<std::size_t, size>{{prev[Indices]..., arg}}; } template<sprout::index_t... Indices> static constexpr sprout::array<T2, size> make_value(const T2 arg, const sprout::array<T2, size - 1> prev, sprout::index_tuple<Indices...>) { return sprout::array<T2, size>{{prev[Indices]..., arg}}; } constexpr sprout::pair<bool, T2> get_impl(const std::size_t target, const std::size_t step) const { return step < size ? target == hash[step] ? sprout::make_pair(true, data[step]) : get_impl(target, step + 1) : sprout::make_pair(false, *none) ; } }; int main() { constexpr auto test = unorderd_map<sprout::string<100>, int>("foo", 1)("bar", 10)("hoge", 100)("fuga", 1000); static_assert(test["foo"].first && test["foo"].second == 1, ""); static_assert(test["bar"].first && test["bar"].second == 10, ""); static_assert(test["hoge"].first && test["hoge"].second == 100, ""); static_assert(test["fuga"].first && test["fuga"].second == 1000, ""); }