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

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

View File

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

View File

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

View File

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