chromium/services/tracing/public/cpp/perfetto/interning_index.h

// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SERVICES_TRACING_PUBLIC_CPP_PERFETTO_INTERNING_INDEX_H_
#define SERVICES_TRACING_PUBLIC_CPP_PERFETTO_INTERNING_INDEX_H_

#include <algorithm>
#include <array>
#include <cstdint>
#include <tuple>

#include "base/component_export.h"

namespace tracing {

// Value 0 is an invalid ID.
InterningID;

struct COMPONENT_EXPORT(TRACING_CPP) InterningIndexEntry {};

// Index is a template that finds the index (stored in |value|) of a type
// |ValueType| inside a |Tuple|. This is done at compile time since this is
// needed inside a std::get<>().
template <typename ValueType, typename Tuple>
struct Index;

Index<T, std::tuple<T, Types...>>;

Index<T, std::tuple<U, Types...>>;

// A TypeList holds a list of types, while SizeList holds a list of size_t
// integers.
//
// We can't just use a parameter pack to store these two informations because we
// can only have one parameter pack in a template (it absorbs all the types) and
// must be last. However we want users to be able to specify per type size
// limits to decrease memory usage. One of these lists aren't strictly needed
// (you could just have users enter the numbers (or types) as a parameter pack
// directly), but we use both so that when declaring a InterningIndex to
// declaration is readable and avoids surprising behaviour.
template <typename...>
struct TypeList {};
template <size_t...>
struct SizeList {};

// Interning index that associates interned values with interning IDs. It can
// track entries of different types within the same ID space, e.g. so that both
// copied strings and pointers to static strings can co-exist in the same index.
//
// The index will cache for a given ValueType and Size pair up to |Size| values
// after which it will start replacing them in a FIFO basis. All |Size|s must be
// a power of 2 for performance reasons (this is a compile time error if not).
//
// This definition just declares the type and template. Do not use this this
// directly, instead use the partial specialization below.
template <typename ValueTypes, typename Sizes>
class COMPONENT_EXPORT(TRACING_CPP) InterningIndex;
// Partially specalized so we can have two parameter packs which get nested
// inside their respective lists.
InterningIndex<TypeList<ValueTypes...>, SizeList<Sizes...>>;

}  // namespace tracing

#endif  // SERVICES_TRACING_PUBLIC_CPP_PERFETTO_INTERNING_INDEX_H_