blob: cb58711e28513be2c43527ada9e578847bc8f2fd [file] [log] [blame]
// Copyright 2022 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef DAWNNATIVE_CACHE_KEY_H_
#define DAWNNATIVE_CACHE_KEY_H_
#include <string>
#include <vector>
#include "dawn/common/Compiler.h"
namespace dawn::native {
using CacheKey = std::vector<uint8_t>;
// Overridable serializer struct that should be implemented for cache key serializable
// types/classes.
template <typename T, typename SFINAE = void>
struct CacheKeySerializer {
static void Serialize(CacheKey* key, const T& t);
};
// Specialized overload for integral types. Note that we are currently serializing as a string
// to avoid handling null termiantors.
template <typename Integer>
struct CacheKeySerializer<Integer, std::enable_if_t<std::is_integral_v<Integer>>> {
static void Serialize(CacheKey* key, const Integer i) {
std::string str = std::to_string(i);
key->insert(key->end(), str.begin(), str.end());
}
};
// Specialized overload for floating point types. Note that we are currently serializing as a
// string to avoid handling null termiantors.
template <typename Float>
struct CacheKeySerializer<Float, std::enable_if_t<std::is_floating_point_v<Float>>> {
static void Serialize(CacheKey* key, const Float f) {
std::string str = std::to_string(f);
key->insert(key->end(), str.begin(), str.end());
}
};
// Specialized overload for string literals. Note we drop the null-terminator.
template <size_t N>
struct CacheKeySerializer<char[N]> {
static void Serialize(CacheKey* key, const char (&t)[N]) {
std::string len = std::to_string(N - 1);
key->insert(key->end(), len.begin(), len.end());
key->push_back('"');
key->insert(key->end(), t, t + N - 1);
key->push_back('"');
}
};
// Helper template function that defers to underlying static functions.
template <typename T>
void SerializeInto(CacheKey* key, const T& t) {
CacheKeySerializer<T>::Serialize(key, t);
}
// Given list of arguments of types with a free implementation of SerializeIntoImpl in the
// dawn::native namespace, serializes each argument and appends them to the CacheKey while
// prepending member ids before each argument.
template <typename... Ts>
CacheKey GetCacheKey(const Ts&... inputs) {
CacheKey key;
key.push_back('{');
int memberId = 0;
auto Serialize = [&](const auto& input) {
std::string memberIdStr = (memberId == 0 ? "" : ",") + std::to_string(memberId) + ":";
key.insert(key.end(), memberIdStr.begin(), memberIdStr.end());
SerializeInto(&key, input);
memberId++;
};
(Serialize(inputs), ...);
key.push_back('}');
return key;
}
} // namespace dawn::native
#endif // DAWNNATIVE_CACHE_KEY_H_