mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-23 01:21:42 +00:00
Refactor HAL handle move construction/assignment (#1845)
A templated hal::Handle class is used to wrap handles to make them move-only. This eliminates a lot of boilerplate move constructor/assignment code in the main WPILib classes. HAL_SPIPort and HAL_I2CPort are also wrapped. The wrapper class does not implement destruction. This would require the wrapper class to be handle-specific (rather than generic) and would result in more code added than it removed, plus would add header dependencies on more HAL headers. In addition, some HAL handle release functions are more complex (e.g. have return values) and can't be easily mapped to a destructor.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2018 FIRST. All Rights Reserved. */
|
||||
/* Copyright (c) 2018-2019 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
@@ -21,4 +21,15 @@
|
||||
HAL_ENUM(HAL_I2CPort) { HAL_I2C_kInvalid = -1, HAL_I2C_kOnboard, HAL_I2C_kMXP };
|
||||
// clang-format on
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace hal {
|
||||
|
||||
/**
|
||||
* A move-only C++ wrapper around HAL_I2CPort.
|
||||
* Does not ensure destruction.
|
||||
*/
|
||||
using I2CPort = Handle<HAL_I2CPort, HAL_I2C_kInvalid>;
|
||||
|
||||
} // namespace hal
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2018 FIRST. All Rights Reserved. */
|
||||
/* Copyright (c) 2018-2019 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
@@ -27,4 +27,16 @@ HAL_ENUM(HAL_SPIPort) {
|
||||
HAL_SPI_kMXP
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace hal {
|
||||
|
||||
/**
|
||||
* A move-only C++ wrapper around HAL_SPIPort.
|
||||
* Does not ensure destruction.
|
||||
*/
|
||||
using SPIPort = Handle<HAL_SPIPort, HAL_SPI_kInvalid>;
|
||||
|
||||
} // namespace hal
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
|
||||
/* Copyright (c) 2016-2019 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
@@ -62,4 +62,37 @@ typedef int32_t HAL_Bool;
|
||||
typedef int32_t name; \
|
||||
enum name
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace hal {
|
||||
|
||||
/**
|
||||
* A move-only C++ wrapper around a HAL handle.
|
||||
* Does not ensure destruction.
|
||||
*/
|
||||
template <typename CType, int32_t CInvalid = HAL_kInvalidHandle>
|
||||
class Handle {
|
||||
public:
|
||||
Handle() = default;
|
||||
/*implicit*/ Handle(CType val) : m_handle(val) {} // NOLINT(runtime/explicit)
|
||||
|
||||
Handle(const Handle&) = delete;
|
||||
Handle& operator=(const Handle&) = delete;
|
||||
|
||||
Handle(Handle&& rhs) : m_handle(rhs.m_handle) { rhs.m_handle = CInvalid; }
|
||||
|
||||
Handle& operator=(Handle&& rhs) {
|
||||
m_handle = rhs.m_handle;
|
||||
rhs.m_handle = CInvalid;
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator CType() const { return m_handle; }
|
||||
|
||||
private:
|
||||
CType m_handle = CInvalid;
|
||||
};
|
||||
|
||||
} // namespace hal
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
Reference in New Issue
Block a user