diff --git a/glass/src/lib/native/cpp/Storage.cpp b/glass/src/lib/native/cpp/Storage.cpp index add6203217..4a20ab5ce6 100644 --- a/glass/src/lib/native/cpp/Storage.cpp +++ b/glass/src/lib/native/cpp/Storage.cpp @@ -4,17 +4,16 @@ #include "glass/Storage.h" -#include - #include #include +#include #include using namespace glass; template bool ConvertFromString(To* out, std::string_view str) { - if constexpr (std::is_same_v) { + if constexpr (std::same_as) { if (str == "true") { *out = true; } else if (str == "false") { @@ -24,7 +23,7 @@ bool ConvertFromString(To* out, std::string_view str) { } else { return false; } - } else if constexpr (std::is_floating_point_v) { + } else if constexpr (std::floating_point) { if (auto val = wpi::parse_float(str)) { *out = val.value(); } else { diff --git a/glass/src/libnt/native/cpp/NetworkTables.cpp b/glass/src/libnt/native/cpp/NetworkTables.cpp index bd5647d347..d91ad26ee4 100644 --- a/glass/src/libnt/native/cpp/NetworkTables.cpp +++ b/glass/src/libnt/native/cpp/NetworkTables.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -82,9 +83,8 @@ static std::string IntegerArrayToString(std::span in) { return fmt::format("[{:d}]", fmt::join(in, ",")); } -template +template static std::string FloatArrayToString(std::span in) { - static_assert(std::is_same_v || std::is_same_v); return fmt::format("[{:.6f}]", fmt::join(in, ",")); } @@ -729,9 +729,8 @@ static bool StringToIntegerArray(std::string_view in, return true; } -template +template static bool StringToFloatArray(std::string_view in, std::vector* out) { - static_assert(std::is_same_v || std::is_same_v); in = wpi::trim(in); if (in.empty()) { return false; diff --git a/ntcore/src/main/native/cpp/net/WireDecoder.cpp b/ntcore/src/main/native/cpp/net/WireDecoder.cpp index e6474b2faa..224c5f5205 100644 --- a/ntcore/src/main/native/cpp/net/WireDecoder.cpp +++ b/ntcore/src/main/native/cpp/net/WireDecoder.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -104,12 +105,10 @@ static bool ObjGetStringArray(wpi::json::object_t& obj, std::string_view key, #endif template + requires(std::same_as || + std::same_as) static void WireDecodeTextImpl(std::string_view in, T& out, wpi::Logger& logger) { - static_assert(std::is_same_v || - std::is_same_v, - "T must be ClientMessageHandler or ServerMessageHandler"); - wpi::json j; try { j = wpi::json::parse(in); @@ -150,7 +149,7 @@ static void WireDecodeTextImpl(std::string_view in, T& out, goto err; } - if constexpr (std::is_same_v) { + if constexpr (std::same_as) { if (*method == PublishMsg::kMethodStr) { // name auto name = ObjGetString(*params, "name", &error); @@ -302,7 +301,7 @@ static void WireDecodeTextImpl(std::string_view in, T& out, error = fmt::format("unrecognized method '{}'", *method); goto err; } - } else if constexpr (std::is_same_v) { + } else if constexpr (std::same_as) { if (*method == AnnounceMsg::kMethodStr) { // name auto name = ObjGetString(*params, "name", &error); diff --git a/ntcore/src/main/native/include/networktables/NetworkTableValue.h b/ntcore/src/main/native/include/networktables/NetworkTableValue.h index 673a833eb4..7502ae3f81 100644 --- a/ntcore/src/main/native/include/networktables/NetworkTableValue.h +++ b/ntcore/src/main/native/include/networktables/NetworkTableValue.h @@ -12,10 +12,11 @@ #include #include #include -#include #include #include +#include + #include "ntcore_c.h" namespace nt { @@ -377,11 +378,10 @@ class Value final { * time) * @return The entry value */ - template ::value>::type> + template T> static Value MakeString(T&& value, int64_t time = 0) { Value val{NT_STRING, time, private_init{}}; - auto data = std::make_shared(std::forward(value)); + auto data = std::make_shared(std::forward(value)); val.m_val.data.v_string.str = const_cast(data->c_str()); val.m_val.data.v_string.len = data->size(); val.m_storage = std::move(data); @@ -414,11 +414,10 @@ class Value final { * time) * @return The entry value */ - template >::value>::type> + template > T> static Value MakeRaw(T&& value, int64_t time = 0) { Value val{NT_RAW, time, private_init{}}; - auto data = std::make_shared>(std::forward(value)); + auto data = std::make_shared>(std::forward(value)); val.m_val.data.v_raw.data = const_cast(data->data()); val.m_val.data.v_raw.size = data->size(); val.m_storage = std::move(data); diff --git a/ntcore/src/test/native/cpp/net/ServerImplTest.cpp b/ntcore/src/test/native/cpp/net/ServerImplTest.cpp index 770b525ad7..65ee7fd286 100644 --- a/ntcore/src/test/native/cpp/net/ServerImplTest.cpp +++ b/ntcore/src/test/native/cpp/net/ServerImplTest.cpp @@ -8,6 +8,8 @@ #include #include +#include + #include "../MockLogger.h" #include "../PubSubOptionsMatcher.h" #include "../SpanMatcher.h" @@ -99,12 +101,12 @@ static std::vector EncodeServerBinary(const T& msgs) { std::vector data; wpi::raw_uvector_ostream os{data}; for (auto&& msg : msgs) { - if constexpr (std::is_same_v) { + if constexpr (std::same_as) { if (auto m = std::get_if(&msg.contents)) { net::WireEncodeBinary(os, m->topic, m->value.time(), m->value); } - } else if constexpr (std::is_same_v) { + } else if constexpr (std::same_as) { if (auto m = std::get_if(&msg.contents)) { net::WireEncodeBinary(os, Handle{m->pubHandle}.GetIndex(), m->value.time(), m->value); diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/CommandHelper.h b/wpilibNewCommands/src/main/native/include/frc2/command/CommandHelper.h index 76ee6cd262..ca5764bf3a 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/CommandHelper.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/CommandHelper.h @@ -5,9 +5,10 @@ #pragma once #include -#include #include +#include + #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 >> +template Base, typename CRTP> class CommandHelper : public Base { using Base::Base; diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/CommandPtr.h b/wpilibNewCommands/src/main/native/include/frc2/command/CommandPtr.h index 2308b5d087..e329035115 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/CommandPtr.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/CommandPtr.h @@ -12,6 +12,8 @@ #include #include +#include + #include "frc2/command/CommandBase.h" namespace frc2 { @@ -30,11 +32,11 @@ class CommandPtr final { explicit CommandPtr(std::unique_ptr&& command) : m_ptr(std::move(command)) {} - template >>> + template T> + // NOLINTNEXTLINE (bugprone-forwarding-reference-overload) explicit CommandPtr(T&& command) - : CommandPtr(std::make_unique>( - std::forward(command))) {} + : CommandPtr( + std::make_unique>(std::forward(command))) {} CommandPtr(CommandPtr&&) = default; CommandPtr& operator=(CommandPtr&&) = default; diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/CommandScheduler.h b/wpilibNewCommands/src/main/native/include/frc2/command/CommandScheduler.h index c0c09c1140..1ccc157429 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/CommandScheduler.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/CommandScheduler.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -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 >>> + template 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::forward(defaultCommand))); + SetDefaultCommandImpl(subsystem, std::make_unique>( + std::forward(defaultCommand))); } /** diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/Commands.h b/wpilibNewCommands/src/main/native/include/frc2/command/Commands.h index a33b2d2b22..6f2963f107 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/Commands.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/Commands.h @@ -13,6 +13,8 @@ #include #include +#include + #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 +template ... CommandPtrs> [[nodiscard]] CommandPtr Select(std::function selector, - std::pair&&... commands) { + std::pair&&... commands) { std::vector>> vec; ((void)vec.emplace_back(commands.first, std::move(commands.second).Unwrap()), @@ -185,7 +187,7 @@ namespace impl { /** * Create a vector of commands. */ -template +template ... Args> std::vector MakeVector(Args&&... args) { std::vector data; data.reserve(sizeof...(Args)); @@ -204,10 +206,10 @@ CommandPtr Sequence(std::vector&& commands); /** * Runs a group of commands in series, one after the other. */ -template +template ... CommandPtrs> [[nodiscard]] -CommandPtr Sequence(Args&&... commands) { - return Sequence(impl::MakeVector(std::forward(commands)...)); +CommandPtr Sequence(CommandPtrs&&... commands) { + return Sequence(impl::MakeVector(std::forward(commands)...)); } /** @@ -221,10 +223,11 @@ CommandPtr RepeatingSequence(std::vector&& commands); * Runs a group of commands in series, one after the other. Once the last * command ends, the group is restarted. */ -template +template ... CommandPtrs> [[nodiscard]] -CommandPtr RepeatingSequence(Args&&... commands) { - return RepeatingSequence(impl::MakeVector(std::forward(commands)...)); +CommandPtr RepeatingSequence(CommandPtrs&&... commands) { + return RepeatingSequence( + impl::MakeVector(std::forward(commands)...)); } /** @@ -238,10 +241,10 @@ CommandPtr Parallel(std::vector&& commands); * Runs a group of commands at the same time. Ends once all commands in the * group finish. */ -template +template ... CommandPtrs> [[nodiscard]] -CommandPtr Parallel(Args&&... commands) { - return Parallel(impl::MakeVector(std::forward(commands)...)); +CommandPtr Parallel(CommandPtrs&&... commands) { + return Parallel(impl::MakeVector(std::forward(commands)...)); } /** @@ -255,10 +258,10 @@ CommandPtr Race(std::vector&& commands); * Runs a group of commands at the same time. Ends once any command in the group * finishes, and cancels the others. */ -template +template ... CommandPtrs> [[nodiscard]] -CommandPtr Race(Args&&... commands) { - return Race(impl::MakeVector(std::forward(commands)...)); +CommandPtr Race(CommandPtrs&&... commands) { + return Race(impl::MakeVector(std::forward(commands)...)); } /** @@ -272,11 +275,11 @@ CommandPtr Deadline(CommandPtr&& deadline, std::vector&& others); * Runs a group of commands at the same time. Ends once a specific command * finishes, and cancels the others. */ -template +template ... CommandPtrs> [[nodiscard]] -CommandPtr Deadline(CommandPtr&& deadline, Args&&... commands) { +CommandPtr Deadline(CommandPtr&& deadline, CommandPtrs&&... commands) { return Deadline(std::move(deadline), - impl::MakeVector(std::forward(commands)...)); + impl::MakeVector(std::forward(commands)...)); } } // namespace cmd diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/ConditionalCommand.h b/wpilibNewCommands/src/main/native/include/frc2/command/ConditionalCommand.h index 5957950c71..59621acb19 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/ConditionalCommand.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/ConditionalCommand.h @@ -8,6 +8,8 @@ #include #include +#include + #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 >>, - typename = std::enable_if_t< - std::is_base_of_v>>> - ConditionalCommand(T1&& onTrue, T2&& onFalse, std::function condition) - : ConditionalCommand(std::make_unique>( - std::forward(onTrue)), - std::make_unique>( - std::forward(onFalse)), + template Command1, + std::derived_from Command2> + ConditionalCommand(Command1&& onTrue, Command2&& onFalse, + std::function condition) + : ConditionalCommand(std::make_unique>( + std::forward(onTrue)), + std::make_unique>( + std::forward(onFalse)), condition) {} /** diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/ParallelCommandGroup.h b/wpilibNewCommands/src/main/native/include/frc2/command/ParallelCommandGroup.h index 943b62f37d..e13762b4fb 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/ParallelCommandGroup.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/ParallelCommandGroup.h @@ -10,9 +10,13 @@ #endif #include +#include #include #include +#include +#include + #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 >...>>> - explicit ParallelCommandGroup(Types&&... commands) { - AddCommands(std::forward(commands)...); + template ... Commands> + explicit ParallelCommandGroup(Commands&&... commands) { + AddCommands(std::forward(commands)...); } ParallelCommandGroup(ParallelCommandGroup&& other) = default; @@ -65,13 +67,11 @@ class ParallelCommandGroup // Prevent template expansion from emulating copy ctor ParallelCommandGroup(ParallelCommandGroup&) = delete; - template >...>>> - void AddCommands(Types&&... commands) { + template ... Commands> + void AddCommands(Commands&&... commands) { std::vector> foo; - ((void)foo.emplace_back(std::make_unique>( - std::forward(commands))), + ((void)foo.emplace_back(std::make_unique>( + std::forward(commands))), ...); AddCommands(std::move(foo)); } diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/ParallelDeadlineGroup.h b/wpilibNewCommands/src/main/native/include/frc2/command/ParallelDeadlineGroup.h index cfe4b3ef51..c41924fd88 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/ParallelDeadlineGroup.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/ParallelDeadlineGroup.h @@ -10,9 +10,13 @@ #endif #include +#include #include #include +#include +#include + #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 >>, - typename = std::enable_if_t>...>>> - explicit ParallelDeadlineGroup(T&& deadline, Types&&... commands) { - SetDeadline(std::make_unique>( - std::forward(deadline))); - AddCommands(std::forward(commands)...); + template T, + wpi::DecayedDerivedFrom... Commands> + explicit ParallelDeadlineGroup(T&& deadline, Commands&&... commands) { + SetDeadline(std::make_unique>(std::forward(deadline))); + AddCommands(std::forward(commands)...); } ParallelDeadlineGroup(ParallelDeadlineGroup&& other) = default; @@ -73,13 +73,11 @@ class ParallelDeadlineGroup // Prevent template expansion from emulating copy ctor ParallelDeadlineGroup(ParallelDeadlineGroup&) = delete; - template >...>>> - void AddCommands(Types&&... commands) { + template ... Commands> + void AddCommands(Commands&&... commands) { std::vector> foo; - ((void)foo.emplace_back(std::make_unique>( - std::forward(commands))), + ((void)foo.emplace_back(std::make_unique>( + std::forward(commands))), ...); AddCommands(std::move(foo)); } diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/ParallelRaceGroup.h b/wpilibNewCommands/src/main/native/include/frc2/command/ParallelRaceGroup.h index d5412cd7a7..79c897b648 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/ParallelRaceGroup.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/ParallelRaceGroup.h @@ -10,9 +10,13 @@ #endif #include +#include #include #include +#include +#include + #include "frc2/command/CommandGroupBase.h" #include "frc2/command/CommandHelper.h" @@ -40,11 +44,9 @@ class ParallelRaceGroup */ explicit ParallelRaceGroup(std::vector>&& commands); - template >...>>> - explicit ParallelRaceGroup(Types&&... commands) { - AddCommands(std::forward(commands)...); + template ... Commands> + explicit ParallelRaceGroup(Commands&&... commands) { + AddCommands(std::forward(commands)...); } ParallelRaceGroup(ParallelRaceGroup&& other) = default; @@ -55,11 +57,11 @@ class ParallelRaceGroup // Prevent template expansion from emulating copy ctor ParallelRaceGroup(ParallelRaceGroup&) = delete; - template - void AddCommands(Types&&... commands) { + template ... Commands> + void AddCommands(Commands&&... commands) { std::vector> foo; - ((void)foo.emplace_back(std::make_unique>( - std::forward(commands))), + ((void)foo.emplace_back(std::make_unique>( + std::forward(commands))), ...); AddCommands(std::move(foo)); } diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/PerpetualCommand.h b/wpilibNewCommands/src/main/native/include/frc2/command/PerpetualCommand.h index 297cb64f55..a0052d84be 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/PerpetualCommand.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/PerpetualCommand.h @@ -12,6 +12,8 @@ #include #include +#include + #include "frc2/command/CommandBase.h" #include "frc2/command/CommandHelper.h" @@ -46,10 +48,9 @@ class PerpetualCommand : public CommandHelper { 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); WPI_IGNORE_DEPRECATED @@ -60,18 +61,17 @@ class PerpetualCommand : public CommandHelper { * * @param command the command to run perpetually */ - template >>> + template 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::forward(command))) {} + : PerpetualCommand( + std::make_unique>(std::forward(command))) {} WPI_UNIGNORE_DEPRECATED PerpetualCommand(PerpetualCommand&& other) = default; diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/RepeatCommand.h b/wpilibNewCommands/src/main/native/include/frc2/command/RepeatCommand.h index 5d353b99a8..8e013b2472 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/RepeatCommand.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/RepeatCommand.h @@ -12,6 +12,8 @@ #include #include +#include + #include "frc2/command/CommandBase.h" #include "frc2/command/CommandHelper.h" @@ -44,11 +46,11 @@ class RepeatCommand : public CommandHelper { * * @param command the command to run repeatedly */ - template >>> + template T> + // NOLINTNEXTLINE (bugprone-forwarding-reference-overload) explicit RepeatCommand(T&& command) - : RepeatCommand(std::make_unique>( - std::forward(command))) {} + : RepeatCommand( + std::make_unique>(std::forward(command))) {} RepeatCommand(RepeatCommand&& other) = default; diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/SelectCommand.h b/wpilibNewCommands/src/main/native/include/frc2/command/SelectCommand.h index 7079afe18f..286851479a 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/SelectCommand.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/SelectCommand.h @@ -11,11 +11,11 @@ #include #include -#include #include #include #include +#include #include #include "frc2/command/CommandBase.h" @@ -43,17 +43,15 @@ class SelectCommand : public CommandHelper> { * @param commands the map of commands to choose from * @param selector the selector to determine which command to run */ - template >...>>> + template ... Commands> explicit SelectCommand(std::function selector, - std::pair... commands) + std::pair... commands) : m_selector{std::move(selector)} { std::vector>> foo; - ((void)foo.emplace_back(commands.first, - std::make_unique>( - std::move(commands.second))), + ((void)foo.emplace_back( + commands.first, + std::make_unique>(std::move(commands.second))), ...); for (auto&& command : foo) { diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/SequentialCommandGroup.h b/wpilibNewCommands/src/main/native/include/frc2/command/SequentialCommandGroup.h index ba85b6a37e..c301bfbfa2 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/SequentialCommandGroup.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/SequentialCommandGroup.h @@ -16,6 +16,9 @@ #include #include +#include +#include + #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 >...>>> - explicit SequentialCommandGroup(Types&&... commands) { - AddCommands(std::forward(commands)...); + template ... Commands> + explicit SequentialCommandGroup(Commands&&... commands) { + AddCommands(std::forward(commands)...); } SequentialCommandGroup(SequentialCommandGroup&& other) = default; @@ -68,13 +69,11 @@ class SequentialCommandGroup // Prevent template expansion from emulating copy ctor SequentialCommandGroup(SequentialCommandGroup&) = delete; - template >...>>> - void AddCommands(Types&&... commands) { + template ... Commands> + void AddCommands(Commands&&... commands) { std::vector> foo; - ((void)foo.emplace_back(std::make_unique>( - std::forward(commands))), + ((void)foo.emplace_back(std::make_unique>( + std::forward(commands))), ...); AddCommands(std::move(foo)); } diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/Subsystem.h b/wpilibNewCommands/src/main/native/include/frc2/command/Subsystem.h index 218c243616..7c1af4f21f 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/Subsystem.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/Subsystem.h @@ -4,9 +4,10 @@ #pragma once -#include #include +#include + #include "frc2/command/CommandScheduler.h" namespace frc2 { @@ -65,8 +66,7 @@ class Subsystem { * * @param defaultCommand the default command to associate with this subsystem */ - template >>> + template T> void SetDefaultCommand(T&& defaultCommand) { CommandScheduler::GetInstance().SetDefaultCommand( this, std::forward(defaultCommand)); diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/WrapperCommand.h b/wpilibNewCommands/src/main/native/include/frc2/command/WrapperCommand.h index 71dd02f1d5..c849e09ccc 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/WrapperCommand.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/WrapperCommand.h @@ -12,6 +12,8 @@ #include #include +#include + #include "frc2/command/CommandBase.h" #include "frc2/command/CommandHelper.h" @@ -39,11 +41,11 @@ class WrapperCommand : public CommandHelper { * @param command the command being wrapped. Trying to directly schedule this * command or add it to a group will throw an exception. */ - template >>> + template T> + // NOLINTNEXTLINE (bugprone-forwarding-reference-overload) explicit WrapperCommand(T&& command) - : WrapperCommand(std::make_unique>( - std::forward(command))) {} + : WrapperCommand( + std::make_unique>(std::forward(command))) {} WrapperCommand(WrapperCommand&& other) = default; diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/button/Button.h b/wpilibNewCommands/src/main/native/include/frc2/command/button/Button.h index 0142c44355..d2a68de810 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/button/Button.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/button/Button.h @@ -9,6 +9,7 @@ #include #include +#include #include #include "Trigger.h" @@ -65,8 +66,7 @@ class Button : public Trigger { * @return The trigger, for chained calls. * @deprecated Replace with Trigger::OnTrue() */ - template >>> + template T> WPI_DEPRECATED("Replace with Trigger#OnTrue()") Button WhenPressed(T&& command) { WhenActive(std::forward(command)); @@ -117,8 +117,7 @@ class Button : public Trigger { * @return The button, for chained calls. * @deprecated Replace with Trigger::WhileTrue(command.Repeatedly()) */ - template >>> + template T> WPI_DEPRECATED("Replace with Trigger#WhileTrue(command.Repeatedly())") Button WhileHeld(T&& command) { WhileActiveContinous(std::forward(command)); @@ -169,8 +168,7 @@ class Button : public Trigger { * @return The button, for chained calls. * @deprecated Replace with Trigger::WhileTrue() */ - template >>> + template T> WPI_DEPRECATED("Replace with Trigger#WhileTrue()") Button WhenHeld(T&& command) { WhileActiveOnce(std::forward(command)); @@ -199,8 +197,7 @@ class Button : public Trigger { * @return The button, for chained calls. * @deprecated Replace with Trigger::OnFalse() */ - template >>> + template T> WPI_DEPRECATED("Replace with Trigger#OnFalse()") Button WhenReleased(T&& command) { WhenInactive(std::forward(command)); @@ -251,8 +248,7 @@ class Button : public Trigger { * @return The button, for chained calls. * @deprecated Replace with Trigger::ToggleOnTrue() */ - template >>> + template T> WPI_DEPRECATED("Replace with Trigger#ToggleOnTrue()") Button ToggleWhenPressed(T&& command) { ToggleWhenActive(std::forward(command)); diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/button/Trigger.h b/wpilibNewCommands/src/main/native/include/frc2/command/button/Trigger.h index 6a93ca3f29..9d6e37e895 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/button/Trigger.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/button/Trigger.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "frc2/command/Command.h" @@ -226,12 +227,11 @@ class Trigger { * @return The trigger, for chained calls. * @deprecated Use OnTrue(Command) instead */ - template >>> + template T> WPI_DEPRECATED("Use OnTrue(Command) instead") Trigger WhenActive(T&& command) { m_loop->Bind([condition = m_condition, previous = m_condition(), - command = std::make_unique>( + command = std::make_unique>( std::forward(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). */ - template >>> + template T> WPI_DEPRECATED( "Use WhileTrue(Command) with RepeatCommand, or bind command::Schedule " "with IfHigh(std::function).") Trigger WhileActiveContinous(T&& command) { m_loop->Bind([condition = m_condition, previous = m_condition(), - command = std::make_unique>( + command = std::make_unique>( std::forward(command))]() mutable { bool current = condition(); @@ -363,12 +362,11 @@ class Trigger { * @return The trigger, for chained calls. * @deprecated Use WhileTrue(Command) instead. */ - template >>> + template T> WPI_DEPRECATED("Use WhileTrue(Command) instead.") Trigger WhileActiveOnce(T&& command) { m_loop->Bind([condition = m_condition, previous = m_condition(), - command = std::make_unique>( + command = std::make_unique>( std::forward(command))]() mutable { bool current = condition(); @@ -405,12 +403,11 @@ class Trigger { * @return The trigger, for chained calls. * @deprecated Use OnFalse(Command) instead. */ - template >>> + template T> WPI_DEPRECATED("Use OnFalse(Command) instead.") Trigger WhenInactive(T&& command) { m_loop->Bind([condition = m_condition, previous = m_condition(), - command = std::make_unique>( + command = std::make_unique>( std::forward(command))]() mutable { bool current = condition(); @@ -471,12 +468,11 @@ class Trigger { * @return The trigger, for chained calls. * @deprecated Use ToggleOnTrue(Command) instead. */ - template >>> + template T> WPI_DEPRECATED("Use ToggleOnTrue(Command) instead.") Trigger ToggleWhenActive(T&& command) { m_loop->Bind([condition = m_condition, previous = m_condition(), - command = std::make_unique>( + command = std::make_unique>( std::forward(command))]() mutable { bool current = condition(); diff --git a/wpilibNewCommands/src/test/native/cpp/frc2/command/make_vector.h b/wpilibNewCommands/src/test/native/cpp/frc2/command/make_vector.h index 05adf8ebfa..996ddba2aa 100644 --- a/wpilibNewCommands/src/test/native/cpp/frc2/command/make_vector.h +++ b/wpilibNewCommands/src/test/native/cpp/frc2/command/make_vector.h @@ -34,8 +34,12 @@ struct all_constructible_and_convertible std::is_constructible_v && std::is_convertible_v, all_constructible_and_convertible, std::false_type> {}; -template , int> = 0> +template +inline constexpr bool all_constructible_and_convertible_v = + all_constructible_and_convertible::value; + +template + requires(!std::is_trivially_copyable_v) std::vector make_vector_impl(Args&&... args) { std::vector vec; vec.reserve(sizeof...(Args)); @@ -44,19 +48,17 @@ std::vector make_vector_impl(Args&&... args) { return vec; } -template , int> = 0> +template + requires std::is_trivially_copyable_v std::vector make_vector_impl(Args&&... args) { return std::vector{std::forward(args)...}; } } // namespace detail -template < - typename T = void, typename... Args, - typename V = detail::vec_type_helper_t, - typename std::enable_if_t< - detail::all_constructible_and_convertible::value, int> = 0> +template > + requires detail::all_constructible_and_convertible_v std::vector make_vector(Args&&... args) { return detail::make_vector_impl(std::forward(args)...); } diff --git a/wpilibc/src/main/native/include/frc/Notifier.h b/wpilibc/src/main/native/include/frc/Notifier.h index bda685c928..2e48290be0 100644 --- a/wpilibc/src/main/native/include/frc/Notifier.h +++ b/wpilibc/src/main/native/include/frc/Notifier.h @@ -10,11 +10,11 @@ #include #include #include -#include #include #include #include +#include #include namespace frc { @@ -36,9 +36,8 @@ class Notifier { */ explicit Notifier(std::function handler); - template < - typename Callable, typename Arg, typename... Args, - typename = std::enable_if_t>> + template + requires std::invocable Notifier(Callable&& f, Arg&& arg, Args&&... args) : Notifier(std::bind(std::forward(f), std::forward(arg), std::forward(args)...)) {} @@ -59,6 +58,7 @@ class Notifier { explicit Notifier(int priority, std::function handler); template + requires std::invocable Notifier(int priority, Callable&& f, Arg&& arg, Args&&... args) : Notifier(priority, std::bind(std::forward(f), std::forward(arg), diff --git a/wpilibc/src/main/native/include/frc/smartdashboard/MechanismObject2d.h b/wpilibc/src/main/native/include/frc/smartdashboard/MechanismObject2d.h index c4185e7f88..0feeb645e5 100644 --- a/wpilibc/src/main/native/include/frc/smartdashboard/MechanismObject2d.h +++ b/wpilibc/src/main/native/include/frc/smartdashboard/MechanismObject2d.h @@ -8,11 +8,11 @@ #include #include #include -#include #include #include #include +#include #include "frc/Errors.h" @@ -62,9 +62,8 @@ class MechanismObject2d { * assignments and call chaining. * @throw if an object with the given name already exists. */ - template >> + template + requires std::convertible_to T* Append(std::string_view name, Args&&... args) { std::scoped_lock lock(m_mutex); auto& obj = m_objects[name]; diff --git a/wpilibc/src/main/native/include/frc/smartdashboard/SendableChooser.h b/wpilibc/src/main/native/include/frc/smartdashboard/SendableChooser.h index 855721e864..6efe03e5fa 100644 --- a/wpilibc/src/main/native/include/frc/smartdashboard/SendableChooser.h +++ b/wpilibc/src/main/native/include/frc/smartdashboard/SendableChooser.h @@ -8,6 +8,7 @@ #include #include +#include #include "frc/smartdashboard/SendableChooserBase.h" @@ -27,12 +28,9 @@ namespace frc { * @see SmartDashboard */ template + requires std::copy_constructible && std::default_initializable class SendableChooser : public SendableChooserBase { wpi::StringMap m_choices; - static_assert(std::is_copy_constructible_v, - "T must be copy-constructible!"); - static_assert(std::is_default_constructible_v, - "T must be default-constructible!"); template static U _unwrap_smart_ptr(const U& value); diff --git a/wpilibc/src/main/native/include/frc/smartdashboard/SendableChooser.inc b/wpilibc/src/main/native/include/frc/smartdashboard/SendableChooser.inc index e90542b96b..c15f5aa445 100644 --- a/wpilibc/src/main/native/include/frc/smartdashboard/SendableChooser.inc +++ b/wpilibc/src/main/native/include/frc/smartdashboard/SendableChooser.inc @@ -18,17 +18,20 @@ namespace frc { template + requires std::copy_constructible && std::default_initializable void SendableChooser::AddOption(std::string_view name, T object) { m_choices[name] = std::move(object); } template + requires std::copy_constructible && std::default_initializable void SendableChooser::SetDefaultOption(std::string_view name, T object) { m_defaultChoice = name; AddOption(name, std::move(object)); } template + requires std::copy_constructible && std::default_initializable auto SendableChooser::GetSelected() -> decltype(_unwrap_smart_ptr(m_choices[""])) { std::string selected = m_defaultChoice; @@ -46,6 +49,7 @@ auto SendableChooser::GetSelected() } template + requires std::copy_constructible && std::default_initializable void SendableChooser::InitSendable(nt::NTSendableBuilder& builder) { builder.SetSmartDashboardType("String Chooser"); { @@ -101,18 +105,21 @@ void SendableChooser::InitSendable(nt::NTSendableBuilder& builder) { } template + requires std::copy_constructible && std::default_initializable template U SendableChooser::_unwrap_smart_ptr(const U& value) { return value; } template + requires std::copy_constructible && std::default_initializable template U* SendableChooser::_unwrap_smart_ptr(const std::unique_ptr& value) { return value.get(); } template + requires std::copy_constructible && std::default_initializable template std::weak_ptr SendableChooser::_unwrap_smart_ptr( const std::shared_ptr& value) { diff --git a/wpimath/src/main/java/edu/wpi/first/math/kinematics/SwerveDriveKinematics.java b/wpimath/src/main/java/edu/wpi/first/math/kinematics/SwerveDriveKinematics.java index fa07880210..4d3a4c5e55 100644 --- a/wpimath/src/main/java/edu/wpi/first/math/kinematics/SwerveDriveKinematics.java +++ b/wpimath/src/main/java/edu/wpi/first/math/kinematics/SwerveDriveKinematics.java @@ -42,20 +42,21 @@ public class SwerveDriveKinematics { private Translation2d m_prevCoR = new Translation2d(); /** - * Constructs a swerve drive kinematics object. This takes in a variable number of wheel locations - * as Translation2d objects. The order in which you pass in the wheel locations is the same order - * that you will receive the module states when performing inverse kinematics. It is also expected - * that you pass in the module states in the same order when calling the forward kinematics - * methods. + * Constructs a swerve drive kinematics object. This takes in a variable number of module + * locations as Translation2d objects. The order in which you pass in the module locations is the + * same order that you will receive the module states when performing inverse kinematics. It is + * also expected that you pass in the module states in the same order when calling the forward + * kinematics methods. * - * @param wheelsMeters The locations of the wheels relative to the physical center of the robot. + * @param moduleTranslationsMeters The locations of the modules relative to the physical center of + * the robot. */ - public SwerveDriveKinematics(Translation2d... wheelsMeters) { - if (wheelsMeters.length < 2) { + public SwerveDriveKinematics(Translation2d... moduleTranslationsMeters) { + if (moduleTranslationsMeters.length < 2) { throw new IllegalArgumentException("A swerve drive requires at least two modules"); } - m_numModules = wheelsMeters.length; - m_modules = Arrays.copyOf(wheelsMeters, m_numModules); + m_numModules = moduleTranslationsMeters.length; + m_modules = Arrays.copyOf(moduleTranslationsMeters, m_numModules); m_moduleStates = new SwerveModuleState[m_numModules]; Arrays.fill(m_moduleStates, new SwerveModuleState()); m_inverseKinematics = new SimpleMatrix(m_numModules * 2, 3); @@ -163,21 +164,21 @@ public class SwerveDriveKinematics { * This method is often used for odometry -- determining the robot's position on the field using * data from the real-world speed and angle of each module on the robot. * - * @param wheelStates The state of the modules (as a SwerveModuleState type) as measured from + * @param moduleStates The state of the modules (as a SwerveModuleState type) as measured from * respective encoders and gyros. The order of the swerve module states should be same as * passed into the constructor of this class. * @return The resulting chassis speed. */ - public ChassisSpeeds toChassisSpeeds(SwerveModuleState... wheelStates) { - if (wheelStates.length != m_numModules) { + public ChassisSpeeds toChassisSpeeds(SwerveModuleState... moduleStates) { + if (moduleStates.length != m_numModules) { throw new IllegalArgumentException( - "Number of modules is not consistent with number of wheel locations provided in " + "Number of modules is not consistent with number of module locations provided in " + "constructor"); } var moduleStatesMatrix = new SimpleMatrix(m_numModules * 2, 1); for (int i = 0; i < m_numModules; i++) { - var module = wheelStates[i]; + var module = moduleStates[i]; moduleStatesMatrix.set(i * 2, 0, module.speedMetersPerSecond * module.angle.getCos()); moduleStatesMatrix.set(i * 2 + 1, module.speedMetersPerSecond * module.angle.getSin()); } @@ -194,21 +195,21 @@ public class SwerveDriveKinematics { * This method is often used for odometry -- determining the robot's position on the field using * data from the real-world speed and angle of each module on the robot. * - * @param wheelDeltas The latest change in position of the modules (as a SwerveModulePosition + * @param moduleDeltas The latest change in position of the modules (as a SwerveModulePosition * type) as measured from respective encoders and gyros. The order of the swerve module states * should be same as passed into the constructor of this class. * @return The resulting Twist2d. */ - public Twist2d toTwist2d(SwerveModulePosition... wheelDeltas) { - if (wheelDeltas.length != m_numModules) { + public Twist2d toTwist2d(SwerveModulePosition... moduleDeltas) { + if (moduleDeltas.length != m_numModules) { throw new IllegalArgumentException( - "Number of modules is not consistent with number of wheel locations provided in " + "Number of modules is not consistent with number of module locations provided in " + "constructor"); } var moduleDeltaMatrix = new SimpleMatrix(m_numModules * 2, 1); for (int i = 0; i < m_numModules; i++) { - var module = wheelDeltas[i]; + var module = moduleDeltas[i]; moduleDeltaMatrix.set(i * 2, 0, module.distanceMeters * module.angle.getCos()); moduleDeltaMatrix.set(i * 2 + 1, module.distanceMeters * module.angle.getSin()); } diff --git a/wpimath/src/main/native/include/frc/MathUtil.h b/wpimath/src/main/native/include/frc/MathUtil.h index 24bf857b27..7947061a81 100644 --- a/wpimath/src/main/native/include/frc/MathUtil.h +++ b/wpimath/src/main/native/include/frc/MathUtil.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include @@ -25,12 +26,11 @@ namespace frc { * be infinite. * @return The value after the deadband is applied. */ -template , units::traits::is_unit_t>>> +template + requires std::is_arithmetic_v || units::traits::is_unit_t_v T ApplyDeadband(T value, T deadband, T maxMagnitude = T{1.0}) { T magnitude; - if constexpr (std::is_floating_point_v) { + if constexpr (std::is_arithmetic_v) { magnitude = std::abs(value); } else { magnitude = units::math::abs(value); diff --git a/wpimath/src/main/native/include/frc/StateSpaceUtil.h b/wpimath/src/main/native/include/frc/StateSpaceUtil.h index 6e440b77a3..6c716e1790 100644 --- a/wpimath/src/main/native/include/frc/StateSpaceUtil.h +++ b/wpimath/src/main/native/include/frc/StateSpaceUtil.h @@ -8,9 +8,9 @@ #include #include #include -#include #include +#include #include #include "Eigen/Eigenvalues" @@ -96,8 +96,7 @@ bool IsStabilizableImpl(const Matrixd& A, * of the control inputs from no actuation. * @return State excursion or control effort cost matrix. */ -template ...>>> +template ... Ts> Matrixd MakeCostMatrix(Ts... tolerances) { Eigen::DiagonalMatrix result; detail::CostMatrixImpl(result.diagonal(), tolerances...); @@ -116,8 +115,7 @@ Matrixd MakeCostMatrix(Ts... tolerances) { * output measurement. * @return Process noise or measurement noise covariance matrix. */ -template ...>>> +template ... Ts> Matrixd MakeCovMatrix(Ts... stdDevs) { Eigen::DiagonalMatrix result; detail::CovMatrixImpl(result.diagonal(), stdDevs...); @@ -173,8 +171,7 @@ Matrixd MakeCovMatrix(const std::array& stdDevs) { return result; } -template ...>>> +template ... Ts> Matrixd MakeWhiteNoiseVector(Ts... stdDevs) { Matrixd result; detail::WhiteNoiseVectorImpl(result, stdDevs...); diff --git a/wpimath/src/main/native/include/frc/fmt/Eigen.h b/wpimath/src/main/native/include/frc/fmt/Eigen.h index 0c915abb57..e3f8f7499e 100644 --- a/wpimath/src/main/native/include/frc/fmt/Eigen.h +++ b/wpimath/src/main/native/include/frc/fmt/Eigen.h @@ -4,9 +4,8 @@ #pragma once -#include - #include +#include #include "Eigen/Core" #include "Eigen/SparseCore" @@ -16,12 +15,9 @@ * Eigen::SparseCompressedBase. */ template -struct fmt::formatter< - Derived, CharT, - std::enable_if_t< - std::is_base_of_v, Derived> || - std::is_base_of_v, Derived>, - void>> { + requires std::derived_from> || + std::derived_from> +struct fmt::formatter { constexpr auto parse(fmt::format_parse_context& ctx) { return m_underlying.parse(ctx); } diff --git a/wpimath/src/main/native/include/frc/kinematics/SwerveDriveKinematics.h b/wpimath/src/main/native/include/frc/kinematics/SwerveDriveKinematics.h index 0ebd51733b..48b7e102ea 100644 --- a/wpimath/src/main/native/include/frc/kinematics/SwerveDriveKinematics.h +++ b/wpimath/src/main/native/include/frc/kinematics/SwerveDriveKinematics.h @@ -5,10 +5,10 @@ #pragma once #include -#include #include #include +#include #include "Eigen/QR" #include "frc/EigenCore.h" @@ -49,23 +49,19 @@ class SwerveDriveKinematics { public: /** * Constructs a swerve drive kinematics object. This takes in a variable - * number of wheel locations as Translation2ds. The order in which you pass in - * the wheel locations is the same order that you will receive the module + * number of module locations as Translation2ds. The order in which you pass + * in the module locations is the same order that you will receive the module * states when performing inverse kinematics. It is also expected that you * pass in the module states in the same order when calling the forward * kinematics methods. * - * @param wheel The location of the first wheel relative to the physical - * center of the robot. - * @param wheels The locations of the other wheels relative to the physical - * center of the robot. + * @param moduleTranslations The locations of the modules relative to the + * physical center of the robot. */ - template - explicit SwerveDriveKinematics(Translation2d wheel, Wheels&&... wheels) - : m_modules{wheel, wheels...}, m_moduleStates(wpi::empty_array) { - static_assert(sizeof...(wheels) >= 1, - "A swerve drive requires at least two modules"); - + template ... ModuleTranslations> + requires(sizeof...(ModuleTranslations) == NumModules) + explicit SwerveDriveKinematics(ModuleTranslations&&... moduleTranslations) + : m_modules{moduleTranslations...}, m_moduleStates(wpi::empty_array) { for (size_t i = 0; i < NumModules; i++) { // clang-format off m_inverseKinematics.template block<2, 3>(i * 2, 0) << @@ -81,8 +77,8 @@ class SwerveDriveKinematics { } explicit SwerveDriveKinematics( - const wpi::array& wheels) - : m_modules{wheels}, m_moduleStates(wpi::empty_array) { + const wpi::array& modules) + : m_modules{modules}, m_moduleStates(wpi::empty_array) { for (size_t i = 0; i < NumModules; i++) { // clang-format off m_inverseKinematics.template block<2, 3>(i * 2, 0) << @@ -140,17 +136,18 @@ class SwerveDriveKinematics { * the robot's position on the field using data from the real-world speed and * angle of each module on the robot. * - * @param wheelStates The state of the modules (as a SwerveModuleState type) + * @param moduleStates The state of the modules (as a SwerveModuleState type) * as measured from respective encoders and gyros. The order of the swerve * module states should be same as passed into the constructor of this class. * * @return The resulting chassis speed. */ - template - requires(std::is_same_v, - SwerveModuleState> && - ...) - ChassisSpeeds ToChassisSpeeds(ModuleStates&&... wheelStates) const; + template ... ModuleStates> + requires(sizeof...(ModuleStates) == NumModules) + ChassisSpeeds ToChassisSpeeds(ModuleStates&&... moduleStates) const { + return this->ToChassisSpeeds( + wpi::array{moduleStates...}); + } /** * Performs forward kinematics to return the resulting chassis state from the @@ -174,15 +171,19 @@ class SwerveDriveKinematics { * determining the robot's position on the field using data from the * real-world position delta and angle of each module on the robot. * - * @param wheelDeltas The latest change in position of the modules (as a + * @param moduleDeltas The latest change in position of the modules (as a * SwerveModulePosition type) as measured from respective encoders and gyros. * The order of the swerve module states should be same as passed into the * constructor of this class. * * @return The resulting Twist2d. */ - template - Twist2d ToTwist2d(ModuleDeltas&&... wheelDeltas) const; + template ... ModuleDeltas> + requires(sizeof...(ModuleDeltas) == NumModules) + Twist2d ToTwist2d(ModuleDeltas&&... moduleDeltas) const { + return this->ToTwist2d( + wpi::array{moduleDeltas...}); + } /** * Performs forward kinematics to return the resulting Twist2d from the @@ -190,7 +191,7 @@ class SwerveDriveKinematics { * determining the robot's position on the field using data from the * real-world position delta and angle of each module on the robot. * - * @param wheelDeltas The latest change in position of the modules (as a + * @param moduleDeltas The latest change in position of the modules (as a * SwerveModulePosition type) as measured from respective encoders and gyros. * The order of the swerve module states should be same as passed into the * constructor of this class. @@ -198,7 +199,7 @@ class SwerveDriveKinematics { * @return The resulting Twist2d. */ Twist2d ToTwist2d( - wpi::array wheelDeltas) const; + wpi::array moduleDeltas) const; /** * Renormalizes the wheel speeds if any individual speed is above the diff --git a/wpimath/src/main/native/include/frc/kinematics/SwerveDriveKinematics.inc b/wpimath/src/main/native/include/frc/kinematics/SwerveDriveKinematics.inc index 0c15496fa5..e0ae222537 100644 --- a/wpimath/src/main/native/include/frc/kinematics/SwerveDriveKinematics.inc +++ b/wpimath/src/main/native/include/frc/kinematics/SwerveDriveKinematics.inc @@ -13,9 +13,9 @@ namespace frc { -template -SwerveDriveKinematics(Translation2d, Wheels...) - -> SwerveDriveKinematics<1 + sizeof...(Wheels)>; +template +SwerveDriveKinematics(ModuleTranslation, ModuleTranslations...) + -> SwerveDriveKinematics<1 + sizeof...(ModuleTranslations)>; template wpi::array @@ -64,22 +64,6 @@ SwerveDriveKinematics::ToSwerveModuleStates( return m_moduleStates; } -template -template - requires(std::is_same_v, - SwerveModuleState> && - ...) -ChassisSpeeds SwerveDriveKinematics::ToChassisSpeeds( - ModuleStates&&... wheelStates) const { - static_assert(sizeof...(wheelStates) == NumModules, - "Number of modules is not consistent with number of wheel " - "locations provided in constructor."); - - wpi::array moduleStates{wheelStates...}; - - return this->ToChassisSpeeds(moduleStates); -} - template ChassisSpeeds SwerveDriveKinematics::ToChassisSpeeds( const wpi::array& moduleStates) const { @@ -99,19 +83,6 @@ ChassisSpeeds SwerveDriveKinematics::ToChassisSpeeds( units::radians_per_second_t{chassisSpeedsVector(2)}}; } -template -template -Twist2d SwerveDriveKinematics::ToTwist2d( - ModuleDeltas&&... wheelDeltas) const { - static_assert(sizeof...(wheelDeltas) == NumModules, - "Number of modules is not consistent with number of wheel " - "locations provided in constructor."); - - wpi::array moduleDeltas{wheelDeltas...}; - - return this->ToTwist2d(moduleDeltas); -} - template Twist2d SwerveDriveKinematics::ToTwist2d( wpi::array moduleDeltas) const { diff --git a/wpimath/src/main/native/include/frc/system/plant/LinearSystemId.h b/wpimath/src/main/native/include/frc/system/plant/LinearSystemId.h index 3e69545272..a57cc6a4e0 100644 --- a/wpimath/src/main/native/include/frc/system/plant/LinearSystemId.h +++ b/wpimath/src/main/native/include/frc/system/plant/LinearSystemId.h @@ -7,6 +7,7 @@ #include #include +#include #include "frc/system/LinearSystem.h" #include "frc/system/plant/DCMotor.h" @@ -76,9 +77,9 @@ class WPILIB_DLLEXPORT LinearSystemId { * @param kA The acceleration gain, in volts/(unit/sec²). * @throws std::domain_error if kV <= 0 or kA <= 0. */ - template || - std::is_same_v>> + template + requires std::same_as || + std::same_as static LinearSystem<1, 1, 1> IdentifyVelocitySystem( decltype(1_V / Velocity_t(1)) kV, decltype(1_V / Acceleration_t(1)) kA) { @@ -117,9 +118,9 @@ class WPILIB_DLLEXPORT LinearSystemId { * * @throws std::domain_error if kV <= 0 or kA <= 0. */ - template || - std::is_same_v>> + template + requires std::same_as || + std::same_as static LinearSystem<2, 1, 1> IdentifyPositionSystem( decltype(1_V / Velocity_t(1)) kV, decltype(1_V / Acceleration_t(1)) kA) { diff --git a/wpimath/src/main/native/include/frc/trajectory/TrajectoryConfig.h b/wpimath/src/main/native/include/frc/trajectory/TrajectoryConfig.h index b1a0b5260a..640e735be7 100644 --- a/wpimath/src/main/native/include/frc/trajectory/TrajectoryConfig.h +++ b/wpimath/src/main/native/include/frc/trajectory/TrajectoryConfig.h @@ -9,6 +9,7 @@ #include #include +#include #include "frc/kinematics/DifferentialDriveKinematics.h" #include "frc/kinematics/MecanumDriveKinematics.h" @@ -74,8 +75,7 @@ class WPILIB_DLLEXPORT TrajectoryConfig { * Adds a user-defined constraint to the trajectory. * @param constraint The user-defined constraint. */ - template >> + template Constraint> void AddConstraint(Constraint constraint) { m_constraints.emplace_back(std::make_unique(constraint)); } diff --git a/wpimath/src/main/native/include/frc/trajectory/constraint/EllipticalRegionConstraint.h b/wpimath/src/main/native/include/frc/trajectory/constraint/EllipticalRegionConstraint.h index f9f0d2e301..a6421eeba3 100644 --- a/wpimath/src/main/native/include/frc/trajectory/constraint/EllipticalRegionConstraint.h +++ b/wpimath/src/main/native/include/frc/trajectory/constraint/EllipticalRegionConstraint.h @@ -6,6 +6,8 @@ #include +#include + #include "frc/geometry/Rotation2d.h" #include "frc/geometry/Translation2d.h" #include "frc/trajectory/constraint/TrajectoryConstraint.h" @@ -15,8 +17,7 @@ namespace frc { /** * Enforces a particular constraint only within an elliptical region. */ -template >> +template Constraint> class EllipticalRegionConstraint : public TrajectoryConstraint { public: /** diff --git a/wpimath/src/main/native/include/frc/trajectory/constraint/RectangularRegionConstraint.h b/wpimath/src/main/native/include/frc/trajectory/constraint/RectangularRegionConstraint.h index 18522fef02..c592fd5a42 100644 --- a/wpimath/src/main/native/include/frc/trajectory/constraint/RectangularRegionConstraint.h +++ b/wpimath/src/main/native/include/frc/trajectory/constraint/RectangularRegionConstraint.h @@ -6,6 +6,8 @@ #include +#include + #include "frc/geometry/Rotation2d.h" #include "frc/geometry/Translation2d.h" #include "frc/trajectory/constraint/TrajectoryConstraint.h" @@ -14,8 +16,7 @@ namespace frc { /** * Enforces a particular constraint only within a rectangular region. */ -template >> +template Constraint> class RectangularRegionConstraint : public TrajectoryConstraint { public: /** diff --git a/wpinet/src/main/native/include/wpinet/uv/AsyncFunction.h b/wpinet/src/main/native/include/wpinet/uv/AsyncFunction.h index 915daa2070..ea5715851c 100644 --- a/wpinet/src/main/native/include/wpinet/uv/AsyncFunction.h +++ b/wpinet/src/main/native/include/wpinet/uv/AsyncFunction.h @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -127,7 +128,7 @@ class AsyncFunction final auto loop = m_loop.lock(); if (loop->IsClosing()) { - if constexpr (std::is_same_v) { + if constexpr (std::same_as) { return m_promises.MakeReadyFuture(); } else { return m_promises.MakeReadyFuture({}); diff --git a/wpiutil/src/main/native/include/wpi/DecayedDerivedFrom.h b/wpiutil/src/main/native/include/wpi/DecayedDerivedFrom.h new file mode 100644 index 0000000000..9409481a60 --- /dev/null +++ b/wpiutil/src/main/native/include/wpi/DecayedDerivedFrom.h @@ -0,0 +1,18 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +#pragma once + +#include + +#include "wpi/concepts.h" + +namespace wpi { + +template +concept DecayedDerivedFrom = + std::derived_from, std::decay_t> && + std::convertible_to*, std::decay_t*>; + +} // namespace wpi diff --git a/wpiutil/src/main/native/include/wpi/array.h b/wpiutil/src/main/native/include/wpi/array.h index cfbb7b028f..60c6373ef9 100644 --- a/wpiutil/src/main/native/include/wpi/array.h +++ b/wpiutil/src/main/native/include/wpi/array.h @@ -9,6 +9,8 @@ #include #include +#include "wpi/concepts.h" + namespace wpi { struct empty_array_t {}; @@ -26,11 +28,10 @@ class array : public std::array { public: constexpr explicit array(empty_array_t) {} - template + template ... Ts> + requires(1 + sizeof...(Ts) == N) constexpr array(T arg, Ts&&... args) // NOLINT - : std::array{std::forward(arg), std::forward(args)...} { - static_assert(1 + sizeof...(args) == N, "Dimension mismatch"); - } + : std::array{std::forward(arg), std::forward(args)...} {} constexpr array(const array&) = default; constexpr array& operator=(const array&) = default; @@ -56,33 +57,32 @@ class array : public std::array { } }; -template -array(T, Ts...) -> array && ...), T>, - 1 + sizeof...(Ts)>; +template ... Ts> +array(T, Ts...) -> array; } // namespace wpi template + requires(I < N) constexpr T& get(wpi::array& arr) noexcept { - static_assert(I < N, "array index is within bounds"); return std::get(static_cast>(arr)); } template + requires(I < N) constexpr T&& get(wpi::array&& arr) noexcept { - static_assert(I < N, "array index is within bounds"); return std::move(std::get(arr)); } template + requires(I < N) constexpr const T& get(const wpi::array& arr) noexcept { - static_assert(I < N, "array index is within bounds"); return std::get(static_cast>(arr)); } template + requires(I < N) constexpr const T&& get(const wpi::array&& arr) noexcept { - static_assert(I < N, "array index is within bounds"); return std::move(std::get(arr)); } @@ -94,8 +94,8 @@ struct tuple_size> : public integral_constant {}; // Partial specialization for wpi::array template + requires(I < N) struct tuple_element> { - static_assert(I < N, "index is out of bounds"); using type = T; }; } // namespace std diff --git a/wpiutil/src/main/native/include/wpi/concepts.h b/wpiutil/src/main/native/include/wpi/concepts.h new file mode 100644 index 0000000000..f17b919253 --- /dev/null +++ b/wpiutil/src/main/native/include/wpi/concepts.h @@ -0,0 +1,57 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +#pragma once + +#include + +#if defined(__APPLE__) && !defined(__cpp_lib_concepts) + +#include +#include +#include + +namespace std { + +template +concept constructible_from = + is_nothrow_destructible_v && is_constructible_v; + +template +concept convertible_to = is_convertible_v && + requires { static_cast(declval()); }; + +template +concept move_constructible = constructible_from && convertible_to; + +template +concept copy_constructible = + move_constructible && constructible_from && + convertible_to && constructible_from && + convertible_to && constructible_from && + convertible_to; + +template +concept default_initializable = + constructible_from && requires { T{}; } && requires { ::new T; }; + +template +concept derived_from = + is_base_of_v && + is_convertible_v; + +template +concept floating_point = is_floating_point_v; + +template +concept integral = is_integral_v; + +template +concept invocable = requires(F&& f, Args&&... args) { + invoke(forward(f), forward(args)...); +}; + +} // namespace std + +#endif // defined(__APPLE__) && !defined(__cpp_lib_concepts) diff --git a/wpiutil/src/main/native/include/wpi/jni_util.h b/wpiutil/src/main/native/include/wpi/jni_util.h index 8d50fdd11e..6ed58891ce 100644 --- a/wpiutil/src/main/native/include/wpi/jni_util.h +++ b/wpiutil/src/main/native/include/wpi/jni_util.h @@ -11,7 +11,6 @@ #include #include #include -#include #include #include @@ -20,6 +19,7 @@ #include "wpi/SmallString.h" #include "wpi/SmallVector.h" #include "wpi/StringExtras.h" +#include "wpi/concepts.h" #include "wpi/mutex.h" #include "wpi/raw_ostream.h" @@ -219,9 +219,8 @@ class JArrayRefInner { template class JArrayRefInner { public: - template >> + template + requires(sizeof(U) == sizeof(jlong) && std::integral) operator std::span() const { // NOLINT auto arr = static_cast(this)->array(); if (arr.empty()) { @@ -397,46 +396,38 @@ inline jstring MakeJString(JNIEnv* env, std::string_view str) { // details for MakeJIntArray namespace detail { -/** - * Slow path (get primitive array and set individual elements). - * - * This is used if the input type is not an integer of the same size (note - * signed/unsigned is ignored). - */ -template ::value && sizeof(jint) == sizeof(T))> +template struct ConvertIntArray { static jintArray ToJava(JNIEnv* env, std::span arr) { - jintArray jarr = env->NewIntArray(arr.size()); - if (!jarr) { - return nullptr; + if constexpr (sizeof(T) == sizeof(jint) && std::integral) { + // Fast path (use SetIntArrayRegion). + jintArray jarr = env->NewIntArray(arr.size()); + if (!jarr) { + return nullptr; + } + env->SetIntArrayRegion(jarr, 0, arr.size(), + reinterpret_cast(arr.data())); + return jarr; + } else { + // Slow path (get primitive array and set individual elements). + // + // This is used if the input type is not an integer of the same size (note + // signed/unsigned is ignored). + jintArray jarr = env->NewIntArray(arr.size()); + if (!jarr) { + return nullptr; + } + jint* elements = + static_cast(env->GetPrimitiveArrayCritical(jarr, nullptr)); + if (!elements) { + return nullptr; + } + for (size_t i = 0; i < arr.size(); ++i) { + elements[i] = static_cast(arr[i]); + } + env->ReleasePrimitiveArrayCritical(jarr, elements, 0); + return jarr; } - jint* elements = - static_cast(env->GetPrimitiveArrayCritical(jarr, nullptr)); - if (!elements) { - return nullptr; - } - for (size_t i = 0; i < arr.size(); ++i) { - elements[i] = static_cast(arr[i]); - } - env->ReleasePrimitiveArrayCritical(jarr, elements, 0); - return jarr; - } -}; - -/** - * Fast path (use SetIntArrayRegion). - */ -template -struct ConvertIntArray { - static jintArray ToJava(JNIEnv* env, std::span arr) { - jintArray jarr = env->NewIntArray(arr.size()); - if (!jarr) { - return nullptr; - } - env->SetIntArrayRegion(jarr, 0, arr.size(), - reinterpret_cast(arr.data())); - return jarr; } }; @@ -574,9 +565,9 @@ WPI_JNI_MAKEJARRAY(jdouble, Double) #undef WPI_JNI_MAKEJARRAY -template >> +template + requires(sizeof(typename T::value_type) == sizeof(jlong) && + std::integral) inline jlongArray MakeJLongArray(JNIEnv* env, const T& arr) { jlongArray jarr = env->NewLongArray(arr.size()); if (!jarr) { diff --git a/wpiutil/src/main/native/include/wpi/priority_queue.h b/wpiutil/src/main/native/include/wpi/priority_queue.h index 1aeef188a9..8be6aafea2 100644 --- a/wpiutil/src/main/native/include/wpi/priority_queue.h +++ b/wpiutil/src/main/native/include/wpi/priority_queue.h @@ -10,6 +10,8 @@ #include #include +#include "wpi/concepts.h" + namespace wpi { /** @@ -22,11 +24,9 @@ namespace wpi { */ template , typename Compare = std::less> + requires std::same_as class priority_queue { public: - static_assert(std::is_same_v, - "value_type must be the same as the underlying container"); - using value_type = typename Sequence::value_type; using reference = typename Sequence::reference; using const_reference = typename Sequence::const_reference; @@ -34,10 +34,9 @@ class priority_queue { using container_type = Sequence; using value_compare = Compare; - template {} && - std::is_default_constructible{}>> + template + requires std::default_initializable && + std::default_initializable priority_queue() {} priority_queue(const Compare& comp, const Sequence& c) : c(c), comp(comp) {