chromium/components/performance_manager/public/voting/voting.h

// Copyright 2020 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_PUBLIC_VOTING_VOTING_H_
#define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_VOTING_VOTING_H_

// Declares the various structures and formats associated with a templated
// voting system. This is templated on a vote type (e.g. a priority) and a vote
// context (e.g. a specific node type).
//
// There are 4 interrelated classes declared here:
//
// (1) Vote - A simple wrapper for a vote. This is a final concrete class.
// (2) VoteObserver - Destination for Votes. This is an interface.
// (3) VotingChannel - A mechanism by which a voter can submit votes to a
//     VoteObserver. this is a final concrete class.
// (4) VotingChannelFactory - Producer and tracker of VotingChannels, meant to
//     be owned by a VoteObserver, so it can issue VotingChannels associated
//     with the VoteObserver. This is a final concrete class.
//
// Voters register themselves with VoteObservers, which issues them a private
// VotingChannel using their VotingChannelFactory. Voters can then use their
// VotingChannel to submit new votes (SubmitVote()), change an existing vote
// (ChangeVote()) or invalidate an existing vote (InvalidateVote()).
//
// All votes submitted through a VotingChannel must be invalidated before the
// channel is destroyed, and all VotingChannels issued by a
// VotingChannelFactory must be destroyed before the factory is destroyed. This
// is all verified via debug checks.
//
// The VoteObserver will receive a notification that is tagged with the ID of
// originating VotingChannel every time a vote is submitted (OnVoteSubmitted()),
// changed (OnVoteChanged()) or invalidated (OnVoteInvalidated()).
//
// None of these objects are thread-safe, and they should all be used from a
// single sequence. In practice this will be the PM sequence.

#include <cstring>
#include <map>
#include <utility>

#include "base/check.h"
#include "base/check_op.h"
#include "base/containers/flat_map.h"
#include "base/dcheck_is_on.h"
#include "base/memory/raw_ptr.h"
#include "base/not_fatal_until.h"
#include "base/types/id_type.h"
#include "base/types/pass_key.h"

namespace performance_manager {
namespace voting {

// Contains a single vote. Specifically allows copying, etc, so as to be STL
// container friendly.
template <typename TContextType, typename TVoteType, TVoteType DefaultVote>
class Vote final {};

// Identifies a VotingChannel.
VoterId;

template <class VoteImpl>
class VoteObserver {};

template <class VoteImpl>
class VotingChannelFactory;

// A channel that a voter can use to submit votes to a VoteObserver. A move-only
// type so that it can't be shared by multiple voters. This must be destroyed
// before the issuing VotingChannelFactory.
template <class VoteImpl>
class VotingChannel {};

// A helper for creating VotingChannels that binds a unique VoterId (and
// passes the votes along to the VoteObserver with that VoterId), and a tracking
// token to ensure that the voter disconnects from the VoteObserver before it is
// itself destroyed. Implementations of VoteObservers should own an instance of
// this and use it to emit VotingChannels. This class will DCHECK in its
// destructor if there are outstanding VotingChannels at its death.
template <class VoteImpl>
class VotingChannelFactory final {};

/////////////////////////////////////////////////////////////////////
// Vote

template <typename ContextType, typename VoteType, VoteType DefaultVote>
Vote<ContextType, VoteType, DefaultVote>::Vote() = default;

template <typename ContextType, typename VoteType, VoteType DefaultVote>
Vote<ContextType, VoteType, DefaultVote>::Vote(VoteType vote,
                                               const char* reason)
    :{}

template <typename ContextType, typename VoteType, VoteType DefaultVote>
Vote<ContextType, VoteType, DefaultVote>::Vote(const Vote& rhs) = default;

template <typename ContextType, typename VoteType, VoteType DefaultVote>
Vote<ContextType, VoteType, DefaultVote>&
Vote<ContextType, VoteType, DefaultVote>::operator=(
    const Vote<ContextType, VoteType, DefaultVote>& rhs) = default;

template <typename ContextType, typename VoteType, VoteType DefaultVote>
Vote<ContextType, VoteType, DefaultVote>::~Vote() = default;

template <typename ContextType, typename VoteType, VoteType DefaultVote>
bool Vote<ContextType, VoteType, DefaultVote>::operator==(
    const Vote<ContextType, VoteType, DefaultVote>& vote) const {}

template <typename ContextType, typename VoteType, VoteType DefaultVote>
bool Vote<ContextType, VoteType, DefaultVote>::operator!=(
    const Vote<ContextType, VoteType, DefaultVote>& vote) const {}

template <typename ContextType, typename VoteType, VoteType DefaultVote>
bool Vote<ContextType, VoteType, DefaultVote>::IsValid() const {}

/////////////////////////////////////////////////////////////////////
// VoteObserver

template <class VoteImpl>
VoteObserver<VoteImpl>::~VoteObserver() = default;

/////////////////////////////////////////////////////////////////////
// VotingChannel

template <class VoteImpl>
VotingChannel<VoteImpl>::VotingChannel() = default;

template <class VoteImpl>
VotingChannel<VoteImpl>::VotingChannel(VotingChannel<VoteImpl>&& rhs) {}

template <class VoteImpl>
VotingChannel<VoteImpl>& VotingChannel<VoteImpl>::operator=(
    VotingChannel<VoteImpl>&& rhs) {}

template <class VoteImpl>
VotingChannel<VoteImpl>::~VotingChannel() {}

template <class VoteImpl>
void VotingChannel<VoteImpl>::SubmitVote(const ContextType* context,
                                         const VoteImpl& vote) {}

template <class VoteImpl>
void VotingChannel<VoteImpl>::ChangeVote(const ContextType* context,
                                         const VoteImpl& new_vote) {}

template <class VoteImpl>
void VotingChannel<VoteImpl>::InvalidateVote(const ContextType* context) {}

template <class VoteImpl>
bool VotingChannel<VoteImpl>::IsValid() const {}

template <class VoteImpl>
void VotingChannel<VoteImpl>::Reset() {}

template <class VoteImpl>
VotingChannel<VoteImpl>::VotingChannel(
    base::PassKey<VotingChannelFactory<VoteImpl>>,
    VotingChannelFactory<VoteImpl>* factory,
    VoterId<VoteImpl> voter_id)
    :{}

template <class VoteImpl>
void VotingChannel<VoteImpl>::Take(VotingChannel<VoteImpl>&& rhs) {}

/////////////////////////////////////////////////////////////////////
// VotingChannelFactory
template <class VoteImpl>
VotingChannelFactory<VoteImpl>::VotingChannelFactory(
    VoteObserver<VoteImpl>* observer)
    :{}

template <class VoteImpl>
VotingChannelFactory<VoteImpl>::~VotingChannelFactory() {}

template <class VoteImpl>
VotingChannel<VoteImpl> VotingChannelFactory<VoteImpl>::BuildVotingChannel() {}

template <class VoteImpl>
void VotingChannelFactory<VoteImpl>::OnVotingChannelDestroyed(
    base::PassKey<VotingChannel<VoteImpl>>) {}

}  // namespace voting
}  // namespace performance_manager

#endif  // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_VOTING_VOTING_H_