mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-24 01:31:46 +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:
@@ -10,11 +10,11 @@
|
||||
#include <functional>
|
||||
#include <string_view>
|
||||
#include <thread>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <hal/Types.h>
|
||||
#include <units/time.h>
|
||||
#include <wpi/concepts.h>
|
||||
#include <wpi/mutex.h>
|
||||
|
||||
namespace frc {
|
||||
@@ -36,9 +36,8 @@ class Notifier {
|
||||
*/
|
||||
explicit Notifier(std::function<void()> handler);
|
||||
|
||||
template <
|
||||
typename Callable, typename Arg, typename... Args,
|
||||
typename = std::enable_if_t<std::is_invocable_v<Callable, Arg, Args...>>>
|
||||
template <typename Callable, typename Arg, typename... Args>
|
||||
requires std::invocable<Callable, Arg, Args...>
|
||||
Notifier(Callable&& f, Arg&& arg, Args&&... args)
|
||||
: Notifier(std::bind(std::forward<Callable>(f), std::forward<Arg>(arg),
|
||||
std::forward<Args>(args)...)) {}
|
||||
@@ -59,6 +58,7 @@ class Notifier {
|
||||
explicit Notifier(int priority, std::function<void()> handler);
|
||||
|
||||
template <typename Callable, typename Arg, typename... Args>
|
||||
requires std::invocable<Callable, Arg, Args...>
|
||||
Notifier(int priority, Callable&& f, Arg&& arg, Args&&... args)
|
||||
: Notifier(priority,
|
||||
std::bind(std::forward<Callable>(f), std::forward<Arg>(arg),
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <networktables/NetworkTable.h>
|
||||
#include <wpi/StringMap.h>
|
||||
#include <wpi/concepts.h>
|
||||
|
||||
#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 <typename T, typename... Args,
|
||||
typename =
|
||||
std::enable_if_t<std::is_convertible_v<T*, MechanismObject2d*>>>
|
||||
template <typename T, typename... Args>
|
||||
requires std::convertible_to<T*, MechanismObject2d*>
|
||||
T* Append(std::string_view name, Args&&... args) {
|
||||
std::scoped_lock lock(m_mutex);
|
||||
auto& obj = m_objects[name];
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <string_view>
|
||||
|
||||
#include <wpi/StringMap.h>
|
||||
#include <wpi/concepts.h>
|
||||
|
||||
#include "frc/smartdashboard/SendableChooserBase.h"
|
||||
|
||||
@@ -27,12 +28,9 @@ namespace frc {
|
||||
* @see SmartDashboard
|
||||
*/
|
||||
template <class T>
|
||||
requires std::copy_constructible<T> && std::default_initializable<T>
|
||||
class SendableChooser : public SendableChooserBase {
|
||||
wpi::StringMap<T> m_choices;
|
||||
static_assert(std::is_copy_constructible_v<T>,
|
||||
"T must be copy-constructible!");
|
||||
static_assert(std::is_default_constructible_v<T>,
|
||||
"T must be default-constructible!");
|
||||
|
||||
template <class U>
|
||||
static U _unwrap_smart_ptr(const U& value);
|
||||
|
||||
@@ -18,17 +18,20 @@
|
||||
namespace frc {
|
||||
|
||||
template <class T>
|
||||
requires std::copy_constructible<T> && std::default_initializable<T>
|
||||
void SendableChooser<T>::AddOption(std::string_view name, T object) {
|
||||
m_choices[name] = std::move(object);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
requires std::copy_constructible<T> && std::default_initializable<T>
|
||||
void SendableChooser<T>::SetDefaultOption(std::string_view name, T object) {
|
||||
m_defaultChoice = name;
|
||||
AddOption(name, std::move(object));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
requires std::copy_constructible<T> && std::default_initializable<T>
|
||||
auto SendableChooser<T>::GetSelected()
|
||||
-> decltype(_unwrap_smart_ptr(m_choices[""])) {
|
||||
std::string selected = m_defaultChoice;
|
||||
@@ -46,6 +49,7 @@ auto SendableChooser<T>::GetSelected()
|
||||
}
|
||||
|
||||
template <class T>
|
||||
requires std::copy_constructible<T> && std::default_initializable<T>
|
||||
void SendableChooser<T>::InitSendable(nt::NTSendableBuilder& builder) {
|
||||
builder.SetSmartDashboardType("String Chooser");
|
||||
{
|
||||
@@ -101,18 +105,21 @@ void SendableChooser<T>::InitSendable(nt::NTSendableBuilder& builder) {
|
||||
}
|
||||
|
||||
template <class T>
|
||||
requires std::copy_constructible<T> && std::default_initializable<T>
|
||||
template <class U>
|
||||
U SendableChooser<T>::_unwrap_smart_ptr(const U& value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
requires std::copy_constructible<T> && std::default_initializable<T>
|
||||
template <class U>
|
||||
U* SendableChooser<T>::_unwrap_smart_ptr(const std::unique_ptr<U>& value) {
|
||||
return value.get();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
requires std::copy_constructible<T> && std::default_initializable<T>
|
||||
template <class U>
|
||||
std::weak_ptr<U> SendableChooser<T>::_unwrap_smart_ptr(
|
||||
const std::shared_ptr<U>& value) {
|
||||
|
||||
Reference in New Issue
Block a user