#pragma once #include #include "schema.hpp" #include "crc32.hpp" namespace saw { template struct hash_literal { static constexpr uint32_t apply(uint32_t seed){ constexpr std::string_view view = lit.view(); return hash::update(seed, view); } }; template struct schema_hash_seed { static constexpr uint32_t apply(uint32_t seed){ return hash_literal::apply(seed); } }; template<> struct schema_hash_seed { using Schema = schema::SignedInteger; static constexpr uint32_t apply(uint32_t seed){ return hash_literal::apply(seed); } }; template<> struct schema_hash_seed { using Schema = schema::UnsignedInteger; static constexpr uint32_t apply(uint32_t seed){ return hash_literal::apply(seed); } }; template<> struct schema_hash_seed { using Schema = schema::FloatingPoint; static constexpr uint32_t apply(uint32_t seed){ return hash_literal::apply(seed); } }; template<> struct schema_hash_seed { using Schema = schema::String; static constexpr uint32_t apply(uint32_t seed){ return hash_literal::apply(seed); } }; template struct schema_hash_seed> { using Schema = schema::Primitive; static constexpr uint32_t apply(uint32_t seed){ seed = hash_literal::apply(seed); seed = schema_hash_seed

::apply(seed); uint64_t val = N; std::array dat{ static_cast(val >> 0), static_cast(val >> 8), static_cast(val >> 16), static_cast(val >> 24), static_cast(val >> 32), static_cast(val >> 40), static_cast(val >> 48), static_cast(val >> 56) }; seed = hash::update(seed, &dat[0], dat.size()); return seed; } }; template struct schema_hash_seed> { using Schema = schema::Array; static constexpr uint32_t apply(uint32_t seed){ seed = hash_literal::apply(seed); seed = schema_hash_seed::apply(seed); uint64_t val = N; std::array dat{ static_cast(val >> 0), static_cast(val >> 8), static_cast(val >> 16), static_cast(val >> 24), static_cast(val >> 32), static_cast(val >> 40), static_cast(val >> 48), static_cast(val >> 56) }; seed = hash::update(seed, &dat[0], dat.size()); return seed; } }; template struct schema_hash_seed> { using Schema = schema::Tuple; template static constexpr uint32_t apply_ele(uint32_t seed){ using Type = typename parameter_pack_type::type; seed = schema_hash_seed::apply(seed); if constexpr ( (i+1) < sizeof...(T) ){ return apply_ele(seed); } return seed; } static constexpr uint32_t apply(uint32_t seed){ seed = hash_literal::apply(seed); if constexpr (sizeof...(T) > 0){ seed = apply_ele<0>(seed); } return seed; } }; template struct schema_hash_seed> { template static constexpr uint32_t apply_ele(uint32_t seed){ using Type = typename parameter_pack_type::type; seed = schema_hash_seed::apply(seed); if constexpr ( (i+1u) < sizeof...(T) ){ return apply_ele(seed); } return seed; } static constexpr uint32_t apply(uint32_t seed){ seed = hash_literal::name>::apply(seed); if constexpr (sizeof...(T)>0u){ seed = apply_ele<0u>(seed); } return seed; } }; template struct schema_hash_seed> { using Schema = schema::Member; static constexpr uint32_t apply(uint32_t seed){ seed = hash_literal::apply(seed); seed = schema_hash_seed::apply(seed); seed = hash_literal::apply(seed); return seed; } }; template struct schema_hash_seed> { using Schema = schema::Struct; template static constexpr uint32_t apply_ele(uint32_t seed){ using MemberT = typename parameter_pack_type::type; seed = schema_hash_seed::apply(seed); if constexpr ( (i+1) < sizeof...(Members) ){ return apply_ele(seed); } return seed; } static constexpr uint32_t apply(uint32_t seed){ seed = hash_literal::apply(seed); if constexpr (sizeof...(Members) > 0){ seed = apply_ele<0>(seed); } return seed; } }; template struct schema_hash_seed> { using Schema = schema::Function; static constexpr uint32_t apply(uint32_t seed){ seed = hash_literal::apply(seed); seed = schema_hash_seed::apply(seed); seed = schema_hash_seed::apply(seed); return seed; } }; template struct schema_hash_seed...>> { using Schema = schema::Interface...>; template static constexpr uint32_t apply_ele(uint32_t seed){ using Type = typename parameter_pack_type::type; constexpr string_literal Lit = parameter_key_pack_type::literal; using MemberT = schema::Member; seed = schema_hash_seed::apply(seed); if constexpr ( (i+1) < sizeof...(T) ){ return apply_ele(seed); } return seed; } static constexpr uint32_t apply(uint32_t seed){ seed = hash_literal::apply(seed); if constexpr ( sizeof...(T) > 0){ seed = apply_ele<0>(seed); } return seed; } }; template struct schema_hash { static constexpr uint32_t apply() { constexpr uint32_t seed = 0; return schema_hash_seed::apply(seed); } }; }