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:
Tyler Veness
2023-06-07 09:50:09 -07:00
committed by GitHub
parent d57d1a4598
commit 91cbcea841
42 changed files with 397 additions and 361 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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)));
}
/**

View File

@@ -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

View File

@@ -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) {}
/**

View File

@@ -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));
}

View File

@@ -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));
}

View File

@@ -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));
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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));
}

View File

@@ -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));

View File

@@ -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;

View File

@@ -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));

View File

@@ -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();