mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-20 00:51:42 +00:00
Replace SFINAE with concepts (#5361)
Concepts are cleaner to use and result in much better error messages for incorrect template use.
This commit is contained in:
@@ -5,9 +5,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <wpi/concepts.h>
|
||||
|
||||
#include "frc2/command/Command.h"
|
||||
#include "frc2/command/CommandPtr.h"
|
||||
|
||||
@@ -21,8 +22,7 @@ namespace frc2 {
|
||||
*
|
||||
* This class is provided by the NewCommands VendorDep
|
||||
*/
|
||||
template <typename Base, typename CRTP,
|
||||
typename = std::enable_if_t<std::is_base_of_v<Command, Base>>>
|
||||
template <std::derived_from<Command> Base, typename CRTP>
|
||||
class CommandHelper : public Base {
|
||||
using Base::Base;
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <wpi/concepts.h>
|
||||
|
||||
#include "frc2/command/CommandBase.h"
|
||||
|
||||
namespace frc2 {
|
||||
@@ -30,11 +32,11 @@ class CommandPtr final {
|
||||
explicit CommandPtr(std::unique_ptr<CommandBase>&& command)
|
||||
: m_ptr(std::move(command)) {}
|
||||
|
||||
template <class T, typename = std::enable_if_t<std::is_base_of_v<
|
||||
Command, std::remove_reference_t<T>>>>
|
||||
template <std::derived_from<Command> T>
|
||||
// NOLINTNEXTLINE (bugprone-forwarding-reference-overload)
|
||||
explicit CommandPtr(T&& command)
|
||||
: CommandPtr(std::make_unique<std::remove_reference_t<T>>(
|
||||
std::forward<T>(command))) {}
|
||||
: CommandPtr(
|
||||
std::make_unique<std::decay_t<T>>(std::forward<T>(command))) {}
|
||||
|
||||
CommandPtr(CommandPtr&&) = default;
|
||||
CommandPtr& operator=(CommandPtr&&) = default;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <networktables/NTSendable.h>
|
||||
#include <units/time.h>
|
||||
#include <wpi/FunctionExtras.h>
|
||||
#include <wpi/concepts.h>
|
||||
#include <wpi/deprecated.h>
|
||||
#include <wpi/sendable/SendableHelper.h>
|
||||
|
||||
@@ -175,16 +176,14 @@ class CommandScheduler final : public nt::NTSendable,
|
||||
* @param subsystem the subsystem whose default command will be set
|
||||
* @param defaultCommand the default command to associate with the subsystem
|
||||
*/
|
||||
template <class T, typename = std::enable_if_t<std::is_base_of_v<
|
||||
Command, std::remove_reference_t<T>>>>
|
||||
template <std::derived_from<Command> T>
|
||||
void SetDefaultCommand(Subsystem* subsystem, T&& defaultCommand) {
|
||||
if (!defaultCommand.HasRequirement(subsystem)) {
|
||||
throw FRC_MakeError(frc::err::CommandIllegalUse,
|
||||
"Default commands must require their subsystem!");
|
||||
}
|
||||
SetDefaultCommandImpl(subsystem,
|
||||
std::make_unique<std::remove_reference_t<T>>(
|
||||
std::forward<T>(defaultCommand)));
|
||||
SetDefaultCommandImpl(subsystem, std::make_unique<std::decay_t<T>>(
|
||||
std::forward<T>(defaultCommand)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <wpi/concepts.h>
|
||||
|
||||
#include "frc2/command/CommandPtr.h"
|
||||
#include "frc2/command/SelectCommand.h"
|
||||
|
||||
@@ -166,10 +168,10 @@ CommandPtr Either(CommandPtr&& onTrue, CommandPtr&& onFalse,
|
||||
* @param selector the selector function
|
||||
* @param commands map of commands to select from
|
||||
*/
|
||||
template <typename Key, class... Types>
|
||||
template <typename Key, std::convertible_to<CommandPtr>... CommandPtrs>
|
||||
[[nodiscard]]
|
||||
CommandPtr Select(std::function<Key()> selector,
|
||||
std::pair<Key, Types>&&... commands) {
|
||||
std::pair<Key, CommandPtrs>&&... commands) {
|
||||
std::vector<std::pair<Key, std::unique_ptr<Command>>> vec;
|
||||
|
||||
((void)vec.emplace_back(commands.first, std::move(commands.second).Unwrap()),
|
||||
@@ -185,7 +187,7 @@ namespace impl {
|
||||
/**
|
||||
* Create a vector of commands.
|
||||
*/
|
||||
template <typename... Args>
|
||||
template <std::convertible_to<CommandPtr>... Args>
|
||||
std::vector<CommandPtr> MakeVector(Args&&... args) {
|
||||
std::vector<CommandPtr> data;
|
||||
data.reserve(sizeof...(Args));
|
||||
@@ -204,10 +206,10 @@ CommandPtr Sequence(std::vector<CommandPtr>&& commands);
|
||||
/**
|
||||
* Runs a group of commands in series, one after the other.
|
||||
*/
|
||||
template <typename... Args>
|
||||
template <std::convertible_to<CommandPtr>... CommandPtrs>
|
||||
[[nodiscard]]
|
||||
CommandPtr Sequence(Args&&... commands) {
|
||||
return Sequence(impl::MakeVector(std::forward<Args>(commands)...));
|
||||
CommandPtr Sequence(CommandPtrs&&... commands) {
|
||||
return Sequence(impl::MakeVector(std::forward<CommandPtrs>(commands)...));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -221,10 +223,11 @@ CommandPtr RepeatingSequence(std::vector<CommandPtr>&& commands);
|
||||
* Runs a group of commands in series, one after the other. Once the last
|
||||
* command ends, the group is restarted.
|
||||
*/
|
||||
template <typename... Args>
|
||||
template <std::convertible_to<CommandPtr>... CommandPtrs>
|
||||
[[nodiscard]]
|
||||
CommandPtr RepeatingSequence(Args&&... commands) {
|
||||
return RepeatingSequence(impl::MakeVector(std::forward<Args>(commands)...));
|
||||
CommandPtr RepeatingSequence(CommandPtrs&&... commands) {
|
||||
return RepeatingSequence(
|
||||
impl::MakeVector(std::forward<CommandPtrs>(commands)...));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -238,10 +241,10 @@ CommandPtr Parallel(std::vector<CommandPtr>&& commands);
|
||||
* Runs a group of commands at the same time. Ends once all commands in the
|
||||
* group finish.
|
||||
*/
|
||||
template <typename... Args>
|
||||
template <std::convertible_to<CommandPtr>... CommandPtrs>
|
||||
[[nodiscard]]
|
||||
CommandPtr Parallel(Args&&... commands) {
|
||||
return Parallel(impl::MakeVector(std::forward<Args>(commands)...));
|
||||
CommandPtr Parallel(CommandPtrs&&... commands) {
|
||||
return Parallel(impl::MakeVector(std::forward<CommandPtrs>(commands)...));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -255,10 +258,10 @@ CommandPtr Race(std::vector<CommandPtr>&& commands);
|
||||
* Runs a group of commands at the same time. Ends once any command in the group
|
||||
* finishes, and cancels the others.
|
||||
*/
|
||||
template <typename... Args>
|
||||
template <std::convertible_to<CommandPtr>... CommandPtrs>
|
||||
[[nodiscard]]
|
||||
CommandPtr Race(Args&&... commands) {
|
||||
return Race(impl::MakeVector(std::forward<Args>(commands)...));
|
||||
CommandPtr Race(CommandPtrs&&... commands) {
|
||||
return Race(impl::MakeVector(std::forward<CommandPtrs>(commands)...));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -272,11 +275,11 @@ CommandPtr Deadline(CommandPtr&& deadline, std::vector<CommandPtr>&& others);
|
||||
* Runs a group of commands at the same time. Ends once a specific command
|
||||
* finishes, and cancels the others.
|
||||
*/
|
||||
template <typename... Args>
|
||||
template <std::convertible_to<CommandPtr>... CommandPtrs>
|
||||
[[nodiscard]]
|
||||
CommandPtr Deadline(CommandPtr&& deadline, Args&&... commands) {
|
||||
CommandPtr Deadline(CommandPtr&& deadline, CommandPtrs&&... commands) {
|
||||
return Deadline(std::move(deadline),
|
||||
impl::MakeVector(std::forward<Args>(commands)...));
|
||||
impl::MakeVector(std::forward<CommandPtrs>(commands)...));
|
||||
}
|
||||
|
||||
} // namespace cmd
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include <wpi/concepts.h>
|
||||
|
||||
#include "frc2/command/CommandBase.h"
|
||||
#include "frc2/command/CommandHelper.h"
|
||||
|
||||
@@ -35,16 +37,14 @@ class ConditionalCommand
|
||||
* @param onFalse the command to run if the condition is false
|
||||
* @param condition the condition to determine which command to run
|
||||
*/
|
||||
template <class T1, class T2,
|
||||
typename = std::enable_if_t<
|
||||
std::is_base_of_v<Command, std::remove_reference_t<T1>>>,
|
||||
typename = std::enable_if_t<
|
||||
std::is_base_of_v<Command, std::remove_reference_t<T2>>>>
|
||||
ConditionalCommand(T1&& onTrue, T2&& onFalse, std::function<bool()> condition)
|
||||
: ConditionalCommand(std::make_unique<std::remove_reference_t<T1>>(
|
||||
std::forward<T1>(onTrue)),
|
||||
std::make_unique<std::remove_reference_t<T2>>(
|
||||
std::forward<T2>(onFalse)),
|
||||
template <std::derived_from<Command> Command1,
|
||||
std::derived_from<Command> Command2>
|
||||
ConditionalCommand(Command1&& onTrue, Command2&& onFalse,
|
||||
std::function<bool()> condition)
|
||||
: ConditionalCommand(std::make_unique<std::decay_t<Command1>>(
|
||||
std::forward<Command1>(onTrue)),
|
||||
std::make_unique<std::decay_t<Command2>>(
|
||||
std::forward<Command2>(onFalse)),
|
||||
condition) {}
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,9 +10,13 @@
|
||||
#endif
|
||||
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <wpi/DecayedDerivedFrom.h>
|
||||
#include <wpi/concepts.h>
|
||||
|
||||
#include "frc2/command/CommandGroupBase.h"
|
||||
#include "frc2/command/CommandHelper.h"
|
||||
|
||||
@@ -50,11 +54,9 @@ class ParallelCommandGroup
|
||||
*
|
||||
* @param commands the commands to include in this composition.
|
||||
*/
|
||||
template <class... Types,
|
||||
typename = std::enable_if_t<std::conjunction_v<
|
||||
std::is_base_of<Command, std::remove_reference_t<Types>>...>>>
|
||||
explicit ParallelCommandGroup(Types&&... commands) {
|
||||
AddCommands(std::forward<Types>(commands)...);
|
||||
template <wpi::DecayedDerivedFrom<Command>... Commands>
|
||||
explicit ParallelCommandGroup(Commands&&... commands) {
|
||||
AddCommands(std::forward<Commands>(commands)...);
|
||||
}
|
||||
|
||||
ParallelCommandGroup(ParallelCommandGroup&& other) = default;
|
||||
@@ -65,13 +67,11 @@ class ParallelCommandGroup
|
||||
// Prevent template expansion from emulating copy ctor
|
||||
ParallelCommandGroup(ParallelCommandGroup&) = delete;
|
||||
|
||||
template <class... Types,
|
||||
typename = std::enable_if_t<std::conjunction_v<
|
||||
std::is_base_of<Command, std::remove_reference_t<Types>>...>>>
|
||||
void AddCommands(Types&&... commands) {
|
||||
template <wpi::DecayedDerivedFrom<Command>... Commands>
|
||||
void AddCommands(Commands&&... commands) {
|
||||
std::vector<std::unique_ptr<Command>> foo;
|
||||
((void)foo.emplace_back(std::make_unique<std::remove_reference_t<Types>>(
|
||||
std::forward<Types>(commands))),
|
||||
((void)foo.emplace_back(std::make_unique<std::decay_t<Commands>>(
|
||||
std::forward<Commands>(commands))),
|
||||
...);
|
||||
AddCommands(std::move(foo));
|
||||
}
|
||||
|
||||
@@ -10,9 +10,13 @@
|
||||
#endif
|
||||
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <wpi/DecayedDerivedFrom.h>
|
||||
#include <wpi/concepts.h>
|
||||
|
||||
#include "frc2/command/CommandGroupBase.h"
|
||||
#include "frc2/command/CommandHelper.h"
|
||||
|
||||
@@ -54,15 +58,11 @@ class ParallelDeadlineGroup
|
||||
* @param deadline the command that determines when the composition ends
|
||||
* @param commands the commands to be executed
|
||||
*/
|
||||
template <class T, class... Types,
|
||||
typename = std::enable_if_t<
|
||||
std::is_base_of_v<Command, std::remove_reference_t<T>>>,
|
||||
typename = std::enable_if_t<std::conjunction_v<
|
||||
std::is_base_of<Command, std::remove_reference_t<Types>>...>>>
|
||||
explicit ParallelDeadlineGroup(T&& deadline, Types&&... commands) {
|
||||
SetDeadline(std::make_unique<std::remove_reference_t<T>>(
|
||||
std::forward<T>(deadline)));
|
||||
AddCommands(std::forward<Types>(commands)...);
|
||||
template <wpi::DecayedDerivedFrom<Command> T,
|
||||
wpi::DecayedDerivedFrom<Command>... Commands>
|
||||
explicit ParallelDeadlineGroup(T&& deadline, Commands&&... commands) {
|
||||
SetDeadline(std::make_unique<std::decay_t<T>>(std::forward<T>(deadline)));
|
||||
AddCommands(std::forward<Commands>(commands)...);
|
||||
}
|
||||
|
||||
ParallelDeadlineGroup(ParallelDeadlineGroup&& other) = default;
|
||||
@@ -73,13 +73,11 @@ class ParallelDeadlineGroup
|
||||
// Prevent template expansion from emulating copy ctor
|
||||
ParallelDeadlineGroup(ParallelDeadlineGroup&) = delete;
|
||||
|
||||
template <class... Types,
|
||||
typename = std::enable_if_t<std::conjunction_v<
|
||||
std::is_base_of<Command, std::remove_reference_t<Types>>...>>>
|
||||
void AddCommands(Types&&... commands) {
|
||||
template <wpi::DecayedDerivedFrom<Command>... Commands>
|
||||
void AddCommands(Commands&&... commands) {
|
||||
std::vector<std::unique_ptr<Command>> foo;
|
||||
((void)foo.emplace_back(std::make_unique<std::remove_reference_t<Types>>(
|
||||
std::forward<Types>(commands))),
|
||||
((void)foo.emplace_back(std::make_unique<std::decay_t<Commands>>(
|
||||
std::forward<Commands>(commands))),
|
||||
...);
|
||||
AddCommands(std::move(foo));
|
||||
}
|
||||
|
||||
@@ -10,9 +10,13 @@
|
||||
#endif
|
||||
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <wpi/DecayedDerivedFrom.h>
|
||||
#include <wpi/concepts.h>
|
||||
|
||||
#include "frc2/command/CommandGroupBase.h"
|
||||
#include "frc2/command/CommandHelper.h"
|
||||
|
||||
@@ -40,11 +44,9 @@ class ParallelRaceGroup
|
||||
*/
|
||||
explicit ParallelRaceGroup(std::vector<std::unique_ptr<Command>>&& commands);
|
||||
|
||||
template <class... Types,
|
||||
typename = std::enable_if_t<std::conjunction_v<
|
||||
std::is_base_of<Command, std::remove_reference_t<Types>>...>>>
|
||||
explicit ParallelRaceGroup(Types&&... commands) {
|
||||
AddCommands(std::forward<Types>(commands)...);
|
||||
template <wpi::DecayedDerivedFrom<Command>... Commands>
|
||||
explicit ParallelRaceGroup(Commands&&... commands) {
|
||||
AddCommands(std::forward<Commands>(commands)...);
|
||||
}
|
||||
|
||||
ParallelRaceGroup(ParallelRaceGroup&& other) = default;
|
||||
@@ -55,11 +57,11 @@ class ParallelRaceGroup
|
||||
// Prevent template expansion from emulating copy ctor
|
||||
ParallelRaceGroup(ParallelRaceGroup&) = delete;
|
||||
|
||||
template <class... Types>
|
||||
void AddCommands(Types&&... commands) {
|
||||
template <wpi::DecayedDerivedFrom<Command>... Commands>
|
||||
void AddCommands(Commands&&... commands) {
|
||||
std::vector<std::unique_ptr<Command>> foo;
|
||||
((void)foo.emplace_back(std::make_unique<std::remove_reference_t<Types>>(
|
||||
std::forward<Types>(commands))),
|
||||
((void)foo.emplace_back(std::make_unique<std::decay_t<Commands>>(
|
||||
std::forward<Commands>(commands))),
|
||||
...);
|
||||
AddCommands(std::move(foo));
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include <wpi/concepts.h>
|
||||
|
||||
#include "frc2/command/CommandBase.h"
|
||||
#include "frc2/command/CommandHelper.h"
|
||||
|
||||
@@ -46,10 +48,9 @@ class PerpetualCommand : public CommandHelper<CommandBase, PerpetualCommand> {
|
||||
WPI_DEPRECATED(
|
||||
"PerpetualCommand violates the assumption that execute() doesn't get "
|
||||
"called after isFinished() returns true -- an assumption that should be "
|
||||
"valid."
|
||||
"This was unsafe/undefined behavior from the start, and RepeatCommand "
|
||||
"provides an easy way to achieve similar end results with slightly "
|
||||
"different (and safe) semantics.")
|
||||
"valid. This was unsafe/undefined behavior from the start, and "
|
||||
"RepeatCommand provides an easy way to achieve similar end results with "
|
||||
"slightly different (and safe) semantics.")
|
||||
explicit PerpetualCommand(std::unique_ptr<Command>&& command);
|
||||
WPI_IGNORE_DEPRECATED
|
||||
|
||||
@@ -60,18 +61,17 @@ class PerpetualCommand : public CommandHelper<CommandBase, PerpetualCommand> {
|
||||
*
|
||||
* @param command the command to run perpetually
|
||||
*/
|
||||
template <class T, typename = std::enable_if_t<std::is_base_of_v<
|
||||
Command, std::remove_reference_t<T>>>>
|
||||
template <std::derived_from<Command> T>
|
||||
WPI_DEPRECATED(
|
||||
"PerpetualCommand violates the assumption that execute() doesn't get "
|
||||
"called after isFinished() returns true -- an assumption that should be "
|
||||
"valid."
|
||||
"This was unsafe/undefined behavior from the start, and RepeatCommand "
|
||||
"provides an easy way to achieve similar end results with slightly "
|
||||
"different (and safe) semantics.")
|
||||
"called after isFinished() returns true -- an assumption that should "
|
||||
"be valid. This was unsafe/undefined behavior from the start, and "
|
||||
"RepeatCommand provides an easy way to achieve similar end results "
|
||||
"with slightly different (and safe) semantics.")
|
||||
// NOLINTNEXTLINE (bugprone-forwarding-reference-overload)
|
||||
explicit PerpetualCommand(T&& command)
|
||||
: PerpetualCommand(std::make_unique<std::remove_reference_t<T>>(
|
||||
std::forward<T>(command))) {}
|
||||
: PerpetualCommand(
|
||||
std::make_unique<std::decay_t<T>>(std::forward<T>(command))) {}
|
||||
WPI_UNIGNORE_DEPRECATED
|
||||
|
||||
PerpetualCommand(PerpetualCommand&& other) = default;
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include <wpi/concepts.h>
|
||||
|
||||
#include "frc2/command/CommandBase.h"
|
||||
#include "frc2/command/CommandHelper.h"
|
||||
|
||||
@@ -44,11 +46,11 @@ class RepeatCommand : public CommandHelper<CommandBase, RepeatCommand> {
|
||||
*
|
||||
* @param command the command to run repeatedly
|
||||
*/
|
||||
template <class T, typename = std::enable_if_t<std::is_base_of_v<
|
||||
Command, std::remove_reference_t<T>>>>
|
||||
template <std::derived_from<Command> T>
|
||||
// NOLINTNEXTLINE (bugprone-forwarding-reference-overload)
|
||||
explicit RepeatCommand(T&& command)
|
||||
: RepeatCommand(std::make_unique<std::remove_reference_t<T>>(
|
||||
std::forward<T>(command))) {}
|
||||
: RepeatCommand(
|
||||
std::make_unique<std::decay_t<T>>(std::forward<T>(command))) {}
|
||||
|
||||
RepeatCommand(RepeatCommand&& other) = default;
|
||||
|
||||
|
||||
@@ -11,11 +11,11 @@
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <wpi/concepts.h>
|
||||
#include <wpi/sendable/SendableBuilder.h>
|
||||
|
||||
#include "frc2/command/CommandBase.h"
|
||||
@@ -43,17 +43,15 @@ class SelectCommand : public CommandHelper<CommandBase, SelectCommand<Key>> {
|
||||
* @param commands the map of commands to choose from
|
||||
* @param selector the selector to determine which command to run
|
||||
*/
|
||||
template <class... Types,
|
||||
typename = std::enable_if_t<std::conjunction_v<
|
||||
std::is_base_of<Command, std::remove_reference_t<Types>>...>>>
|
||||
template <std::derived_from<Command>... Commands>
|
||||
explicit SelectCommand(std::function<Key()> selector,
|
||||
std::pair<Key, Types>... commands)
|
||||
std::pair<Key, Commands>... commands)
|
||||
: m_selector{std::move(selector)} {
|
||||
std::vector<std::pair<Key, std::unique_ptr<Command>>> foo;
|
||||
|
||||
((void)foo.emplace_back(commands.first,
|
||||
std::make_unique<std::remove_reference_t<Types>>(
|
||||
std::move(commands.second))),
|
||||
((void)foo.emplace_back(
|
||||
commands.first,
|
||||
std::make_unique<std::decay_t<Commands>>(std::move(commands.second))),
|
||||
...);
|
||||
|
||||
for (auto&& command : foo) {
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <wpi/DecayedDerivedFrom.h>
|
||||
#include <wpi/concepts.h>
|
||||
|
||||
#include "frc2/command/CommandGroupBase.h"
|
||||
#include "frc2/command/CommandHelper.h"
|
||||
|
||||
@@ -53,11 +56,9 @@ class SequentialCommandGroup
|
||||
*
|
||||
* @param commands the commands to include in this composition.
|
||||
*/
|
||||
template <class... Types,
|
||||
typename = std::enable_if_t<std::conjunction_v<
|
||||
std::is_base_of<Command, std::remove_reference_t<Types>>...>>>
|
||||
explicit SequentialCommandGroup(Types&&... commands) {
|
||||
AddCommands(std::forward<Types>(commands)...);
|
||||
template <wpi::DecayedDerivedFrom<Command>... Commands>
|
||||
explicit SequentialCommandGroup(Commands&&... commands) {
|
||||
AddCommands(std::forward<Commands>(commands)...);
|
||||
}
|
||||
|
||||
SequentialCommandGroup(SequentialCommandGroup&& other) = default;
|
||||
@@ -68,13 +69,11 @@ class SequentialCommandGroup
|
||||
// Prevent template expansion from emulating copy ctor
|
||||
SequentialCommandGroup(SequentialCommandGroup&) = delete;
|
||||
|
||||
template <class... Types,
|
||||
typename = std::enable_if_t<std::conjunction_v<
|
||||
std::is_base_of<Command, std::remove_reference_t<Types>>...>>>
|
||||
void AddCommands(Types&&... commands) {
|
||||
template <wpi::DecayedDerivedFrom<Command>... Commands>
|
||||
void AddCommands(Commands&&... commands) {
|
||||
std::vector<std::unique_ptr<Command>> foo;
|
||||
((void)foo.emplace_back(std::make_unique<std::remove_reference_t<Types>>(
|
||||
std::forward<Types>(commands))),
|
||||
((void)foo.emplace_back(std::make_unique<std::decay_t<Commands>>(
|
||||
std::forward<Commands>(commands))),
|
||||
...);
|
||||
AddCommands(std::move(foo));
|
||||
}
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <wpi/concepts.h>
|
||||
|
||||
#include "frc2/command/CommandScheduler.h"
|
||||
|
||||
namespace frc2 {
|
||||
@@ -65,8 +66,7 @@ class Subsystem {
|
||||
*
|
||||
* @param defaultCommand the default command to associate with this subsystem
|
||||
*/
|
||||
template <class T, typename = std::enable_if_t<std::is_base_of_v<
|
||||
Command, std::remove_reference_t<T>>>>
|
||||
template <std::derived_from<Command> T>
|
||||
void SetDefaultCommand(T&& defaultCommand) {
|
||||
CommandScheduler::GetInstance().SetDefaultCommand(
|
||||
this, std::forward<T>(defaultCommand));
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include <wpi/concepts.h>
|
||||
|
||||
#include "frc2/command/CommandBase.h"
|
||||
#include "frc2/command/CommandHelper.h"
|
||||
|
||||
@@ -39,11 +41,11 @@ class WrapperCommand : public CommandHelper<CommandBase, WrapperCommand> {
|
||||
* @param command the command being wrapped. Trying to directly schedule this
|
||||
* command or add it to a group will throw an exception.
|
||||
*/
|
||||
template <class T, typename = std::enable_if_t<std::is_base_of_v<
|
||||
Command, std::remove_reference_t<T>>>>
|
||||
template <std::derived_from<Command> T>
|
||||
// NOLINTNEXTLINE (bugprone-forwarding-reference-overload)
|
||||
explicit WrapperCommand(T&& command)
|
||||
: WrapperCommand(std::make_unique<std::remove_reference_t<T>>(
|
||||
std::forward<T>(command))) {}
|
||||
: WrapperCommand(
|
||||
std::make_unique<std::decay_t<T>>(std::forward<T>(command))) {}
|
||||
|
||||
WrapperCommand(WrapperCommand&& other) = default;
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <span>
|
||||
#include <utility>
|
||||
|
||||
#include <wpi/concepts.h>
|
||||
#include <wpi/deprecated.h>
|
||||
|
||||
#include "Trigger.h"
|
||||
@@ -65,8 +66,7 @@ class Button : public Trigger {
|
||||
* @return The trigger, for chained calls.
|
||||
* @deprecated Replace with Trigger::OnTrue()
|
||||
*/
|
||||
template <class T, typename = std::enable_if_t<std::is_base_of_v<
|
||||
Command, std::remove_reference_t<T>>>>
|
||||
template <std::derived_from<Command> T>
|
||||
WPI_DEPRECATED("Replace with Trigger#OnTrue()")
|
||||
Button WhenPressed(T&& command) {
|
||||
WhenActive(std::forward<T>(command));
|
||||
@@ -117,8 +117,7 @@ class Button : public Trigger {
|
||||
* @return The button, for chained calls.
|
||||
* @deprecated Replace with Trigger::WhileTrue(command.Repeatedly())
|
||||
*/
|
||||
template <class T, typename = std::enable_if_t<std::is_base_of_v<
|
||||
Command, std::remove_reference_t<T>>>>
|
||||
template <std::derived_from<Command> T>
|
||||
WPI_DEPRECATED("Replace with Trigger#WhileTrue(command.Repeatedly())")
|
||||
Button WhileHeld(T&& command) {
|
||||
WhileActiveContinous(std::forward<T>(command));
|
||||
@@ -169,8 +168,7 @@ class Button : public Trigger {
|
||||
* @return The button, for chained calls.
|
||||
* @deprecated Replace with Trigger::WhileTrue()
|
||||
*/
|
||||
template <class T, typename = std::enable_if_t<std::is_base_of_v<
|
||||
Command, std::remove_reference_t<T>>>>
|
||||
template <std::derived_from<Command> T>
|
||||
WPI_DEPRECATED("Replace with Trigger#WhileTrue()")
|
||||
Button WhenHeld(T&& command) {
|
||||
WhileActiveOnce(std::forward<T>(command));
|
||||
@@ -199,8 +197,7 @@ class Button : public Trigger {
|
||||
* @return The button, for chained calls.
|
||||
* @deprecated Replace with Trigger::OnFalse()
|
||||
*/
|
||||
template <class T, typename = std::enable_if_t<std::is_base_of_v<
|
||||
Command, std::remove_reference_t<T>>>>
|
||||
template <std::derived_from<Command> T>
|
||||
WPI_DEPRECATED("Replace with Trigger#OnFalse()")
|
||||
Button WhenReleased(T&& command) {
|
||||
WhenInactive(std::forward<T>(command));
|
||||
@@ -251,8 +248,7 @@ class Button : public Trigger {
|
||||
* @return The button, for chained calls.
|
||||
* @deprecated Replace with Trigger::ToggleOnTrue()
|
||||
*/
|
||||
template <class T, typename = std::enable_if_t<std::is_base_of_v<
|
||||
Command, std::remove_reference_t<T>>>>
|
||||
template <std::derived_from<Command> T>
|
||||
WPI_DEPRECATED("Replace with Trigger#ToggleOnTrue()")
|
||||
Button ToggleWhenPressed(T&& command) {
|
||||
ToggleWhenActive(std::forward<T>(command));
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <frc/event/EventLoop.h>
|
||||
#include <frc/filter/Debouncer.h>
|
||||
#include <units/time.h>
|
||||
#include <wpi/concepts.h>
|
||||
#include <wpi/deprecated.h>
|
||||
|
||||
#include "frc2/command/Command.h"
|
||||
@@ -226,12 +227,11 @@ class Trigger {
|
||||
* @return The trigger, for chained calls.
|
||||
* @deprecated Use OnTrue(Command) instead
|
||||
*/
|
||||
template <class T, typename = std::enable_if_t<std::is_base_of_v<
|
||||
Command, std::remove_reference_t<T>>>>
|
||||
template <std::derived_from<Command> T>
|
||||
WPI_DEPRECATED("Use OnTrue(Command) instead")
|
||||
Trigger WhenActive(T&& command) {
|
||||
m_loop->Bind([condition = m_condition, previous = m_condition(),
|
||||
command = std::make_unique<std::remove_reference_t<T>>(
|
||||
command = std::make_unique<std::decay_t<T>>(
|
||||
std::forward<T>(command))]() mutable {
|
||||
bool current = condition();
|
||||
|
||||
@@ -296,14 +296,13 @@ class Trigger {
|
||||
* @deprecated Use WhileTrue(Command) with RepeatCommand, or bind
|
||||
command::Schedule with IfHigh(std::function<void()>).
|
||||
*/
|
||||
template <class T, typename = std::enable_if_t<std::is_base_of_v<
|
||||
Command, std::remove_reference_t<T>>>>
|
||||
template <std::derived_from<Command> T>
|
||||
WPI_DEPRECATED(
|
||||
"Use WhileTrue(Command) with RepeatCommand, or bind command::Schedule "
|
||||
"with IfHigh(std::function<void()>).")
|
||||
Trigger WhileActiveContinous(T&& command) {
|
||||
m_loop->Bind([condition = m_condition, previous = m_condition(),
|
||||
command = std::make_unique<std::remove_reference_t<T>>(
|
||||
command = std::make_unique<std::decay_t<T>>(
|
||||
std::forward<T>(command))]() mutable {
|
||||
bool current = condition();
|
||||
|
||||
@@ -363,12 +362,11 @@ class Trigger {
|
||||
* @return The trigger, for chained calls.
|
||||
* @deprecated Use WhileTrue(Command) instead.
|
||||
*/
|
||||
template <class T, typename = std::enable_if_t<std::is_base_of_v<
|
||||
Command, std::remove_reference_t<T>>>>
|
||||
template <std::derived_from<Command> T>
|
||||
WPI_DEPRECATED("Use WhileTrue(Command) instead.")
|
||||
Trigger WhileActiveOnce(T&& command) {
|
||||
m_loop->Bind([condition = m_condition, previous = m_condition(),
|
||||
command = std::make_unique<std::remove_reference_t<T>>(
|
||||
command = std::make_unique<std::decay_t<T>>(
|
||||
std::forward<T>(command))]() mutable {
|
||||
bool current = condition();
|
||||
|
||||
@@ -405,12 +403,11 @@ class Trigger {
|
||||
* @return The trigger, for chained calls.
|
||||
* @deprecated Use OnFalse(Command) instead.
|
||||
*/
|
||||
template <class T, typename = std::enable_if_t<std::is_base_of_v<
|
||||
Command, std::remove_reference_t<T>>>>
|
||||
template <std::derived_from<Command> T>
|
||||
WPI_DEPRECATED("Use OnFalse(Command) instead.")
|
||||
Trigger WhenInactive(T&& command) {
|
||||
m_loop->Bind([condition = m_condition, previous = m_condition(),
|
||||
command = std::make_unique<std::remove_reference_t<T>>(
|
||||
command = std::make_unique<std::decay_t<T>>(
|
||||
std::forward<T>(command))]() mutable {
|
||||
bool current = condition();
|
||||
|
||||
@@ -471,12 +468,11 @@ class Trigger {
|
||||
* @return The trigger, for chained calls.
|
||||
* @deprecated Use ToggleOnTrue(Command) instead.
|
||||
*/
|
||||
template <class T, typename = std::enable_if_t<std::is_base_of_v<
|
||||
Command, std::remove_reference_t<T>>>>
|
||||
template <std::derived_from<Command> T>
|
||||
WPI_DEPRECATED("Use ToggleOnTrue(Command) instead.")
|
||||
Trigger ToggleWhenActive(T&& command) {
|
||||
m_loop->Bind([condition = m_condition, previous = m_condition(),
|
||||
command = std::make_unique<std::remove_reference_t<T>>(
|
||||
command = std::make_unique<std::decay_t<T>>(
|
||||
std::forward<T>(command))]() mutable {
|
||||
bool current = condition();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user