chromium/components/performance_manager/graph/node_inline_data.h

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

#ifndef COMPONENTS_PERFORMANCE_MANAGER_GRAPH_NODE_INLINE_DATA_H_
#define COMPONENTS_PERFORMANCE_MANAGER_GRAPH_NODE_INLINE_DATA_H_

#include <utility>

#include "base/types/pass_key.h"
#include "components/performance_manager/graph/node_inline_data_impl.h"

namespace performance_manager {

// Helper classes for defining a user data class that is associated with nodes
// in the graph. At most one instance of each type of data may exist per node
// in the graph.
//
// An instance of node inline data has to be specifically permitted to be
// associated with individual node types, with this being enforced at compile
// time via the type system. A storage type must be specified which may be one
// of the following:
//
// - NodeInlineData<T>: Directly stored as a member in the node.
//
// - SparseNodeInlineData<T>: Stored in a unique_ptr<> as a member in the node.
//
// If the data is needed for most instances of a node type and for effectively
// the entire lifetime of the node, use NodeInlineData<T>.
//
// If the data is needed for most instances of a node type, but only for a
// relatively small portion of the node's lifetime, use
// SparseNodeInlineData<T>. The type will be stored as a member on the node, and
// as such it will be slightly faster to access but will always occupy its
// memory footprint, whether it is created or not.
//
// If the data is *not* needed for most instances of a node type, use
// NodeAttachedData<T> (See node_attached_data.h). The type will be stored in a
// unique_ptr, and will thus less memory is allocated when the type is not
// created.
//
// The functionality of this file is intended to be used as follows:
//
// First, add your data type to the node type (or types) that you want to
// associate your data with.
//
// For example:
//
// -- process_node_impl.h --
//
// class ProcessNodeImpl : (...)
//      (...)
//      public SupportsNodeInlineData<DataType1,
//                                    DataType2,
//                           ---->    YourDataType>    <----
//
// -- process_node_impl.h --
//
// Second, derive your data type from one of NodeInlineData<T> or
// SparseNodeInlineData<T>:
//
// -- your_data_type.h --
//
// class YourDataType : public SparseNodeInlineData<YourDataType> {
//  (...)
// };
//
// -- your_data_type.h --
//
// Once defined, your type instance can be created like so:
//
//   YourDataType& your_data_type = YourDataType::Create(node_impl, ..args..);
//
// If the instance already exists, you can access it using Get():
//
//   YourDataType& your_data_type = YourDataType::Get(node_impl);
//
// Optionally, you can preemptively destroy the instance once it is no longer
// needed:
//
//   YourDataType::Destroy(node_impl);

template <class T>
class NodeInlineData {};

template <class T>
class SparseNodeInlineData : public NodeInlineData<T> {};

// Derived by node implementation classes to provide access to inline data.
// Private through the use of base::PassKey so that only the relevant
// NodeInlineData<T> can use it.
template <class... Ts>
class SupportsNodeInlineData {};

///////////////////////////////////////////////////////////
// Everything below this point is implementation detail! //
///////////////////////////////////////////////////////////

// Implementation of NodeInlineData<T>:

// static
template <class T>
template <class NodeImplClass>
bool NodeInlineData<T>::Exists(NodeImplClass* node) {}

// static
template <class T>
template <class NodeImplClass>
T& NodeInlineData<T>::Get(NodeImplClass* node) {}

// static
template <class T>
template <class NodeImplClass, class... Args>
T& NodeInlineData<T>::Create(NodeImplClass* node, Args&&... args) {}

// static
template <class T>
template <class NodeImplClass>
void NodeInlineData<T>::Destroy(NodeImplClass* node) {}

// Implementation of SupportsNodeInlineData<Ts...>:

template <class... Ts>
template <class T>
bool SupportsNodeInlineData<Ts...>::NodeDataExists(
    base::PassKey<NodeInlineData<T>>) {}

template <class... Ts>
template <class T>
T& SupportsNodeInlineData<Ts...>::GetNodeData(
    base::PassKey<NodeInlineData<T>>) {}

template <class... Ts>
template <class T, class... Args>
T& SupportsNodeInlineData<Ts...>::CreateNodeData(
    base::PassKey<NodeInlineData<T>>,
    Args&&... args) {}

template <class... Ts>
template <class T>
void SupportsNodeInlineData<Ts...>::DestroyNodeData(
    base::PassKey<NodeInlineData<T>>) {}

template <class... Ts>
void SupportsNodeInlineData<Ts...>::DestroyNodeInlineDataStorage() {}

template <class... Ts>
template <class T>
internal::Storage<T>& SupportsNodeInlineData<Ts...>::GetStorage() {}

}  // namespace performance_manager

#endif  // COMPONENTS_PERFORMANCE_MANAGER_GRAPH_NODE_INLINE_DATA_H_