[wpiutil,hal] Move C++ Handle wrapper to wpiutil (#8935)

Also move WPI_Handle typedef to its own header (util/Handle.h).
This commit is contained in:
Peter Johnson
2026-06-01 13:57:25 -07:00
committed by GitHub
parent 3d982f81dd
commit 3f0d7bc2c4
24 changed files with 126 additions and 127 deletions

View File

@@ -0,0 +1,19 @@
// 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 <stdint.h>
#define WPI_INVALID_HANDLE 0
/**
* Generic handle for all WPI handle-based interfaces.
*
* Handle data layout:
* - Bits 0-23: Type-specific
* - Bits 24-30: Type
* - Bit 31: Error
*/
typedef int32_t WPI_Handle; // NOLINT

View File

@@ -0,0 +1,61 @@
// 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 <stdint.h>
#include <concepts>
#include "wpi/util/Handle.h"
namespace wpi::util {
/**
* A move-only C++ wrapper around a WPI handle.
* Will free the handle if FreeFunction is provided
*/
template <typename CType, auto FreeFunction = nullptr,
auto CInvalid = WPI_INVALID_HANDLE>
requires std::same_as<decltype(FreeFunction), std::nullptr_t> ||
std::invocable<decltype(FreeFunction), CType>
class Handle {
public:
Handle() = default;
/*implicit*/ Handle(CType val) : m_handle(val) {} // NOLINT
Handle(const Handle&) = delete;
Handle& operator=(const Handle&) = delete;
Handle(Handle&& rhs) : m_handle(rhs.m_handle) {
rhs.m_handle = static_cast<CType>(CInvalid);
}
Handle& operator=(Handle&& rhs) {
if (this != &rhs) {
if constexpr (std::invocable<decltype(FreeFunction), CType>) {
if (m_handle != static_cast<CType>(CInvalid)) {
FreeFunction(m_handle);
}
}
}
m_handle = rhs.m_handle;
rhs.m_handle = static_cast<CType>(CInvalid);
return *this;
}
~Handle() {
if constexpr (std::invocable<decltype(FreeFunction), CType>) {
if (m_handle != static_cast<CType>(CInvalid)) {
FreeFunction(m_handle);
}
}
}
operator CType() const { return m_handle; } // NOLINT
private:
CType m_handle = static_cast<CType>(CInvalid);
};
} // namespace wpi::util

View File

@@ -4,15 +4,7 @@
#pragma once
/**
* Generic handle for all WPI handle-based interfaces.
*
* Handle data layout:
* - Bits 0-23: Type-specific
* - Bits 24-30: Type
* - Bit 31: Error
*/
typedef unsigned int WPI_Handle; // NOLINT
#include "wpi/util/Handle.h"
/** An event handle. */
typedef WPI_Handle WPI_EventHandle; // NOLINT