diff --git a/hal/include/HAL/cpp/make_unique.h b/hal/include/HAL/cpp/make_unique.h new file mode 100644 index 0000000000..94c7428a66 --- /dev/null +++ b/hal/include/HAL/cpp/make_unique.h @@ -0,0 +1,47 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) FIRST 2016. 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. */ +/*----------------------------------------------------------------------------*/ + +#pragma once + +// Define make_unique for C++11-only compilers +#if __cplusplus == 201103L +#include + +#include +#include +#include +namespace std { +template +struct _Unique_if { + typedef unique_ptr _Single_object; +}; + +template +struct _Unique_if { + typedef unique_ptr _Unknown_bound; +}; + +template +struct _Unique_if { + typedef void _Known_bound; +}; + +template +typename _Unique_if::_Single_object make_unique(Args&&... args) { + return unique_ptr(new T(std::forward(args)...)); +} + +template +typename _Unique_if::_Unknown_bound make_unique(size_t n) { + typedef typename remove_extent::type U; + return unique_ptr(new U[n]()); +} + +template +typename _Unique_if::_Known_bound make_unique(Args&&...) = delete; +} // namespace std +#endif diff --git a/hal/include/HAL/handles/DigitalHandleResource.h b/hal/include/HAL/handles/DigitalHandleResource.h index 778ff364e9..7cc70bc573 100644 --- a/hal/include/HAL/handles/DigitalHandleResource.h +++ b/hal/include/HAL/handles/DigitalHandleResource.h @@ -14,6 +14,7 @@ #include "HAL/Errors.h" #include "HAL/Types.h" +#include "HAL/cpp/make_unique.h" #include "HAL/cpp/priority_mutex.h" #include "HAL/handles/HandlesInternal.h" @@ -39,27 +40,20 @@ class DigitalHandleResource { DigitalHandleResource(const DigitalHandleResource&) = delete; DigitalHandleResource operator=(const DigitalHandleResource&) = delete; DigitalHandleResource(); - ~DigitalHandleResource(); THandle Allocate(int16_t index, HAL_HandleEnum enumValue, int32_t* status); std::shared_ptr Get(THandle handle, HAL_HandleEnum enumValue); void Free(THandle handle, HAL_HandleEnum enumValue); private: // Dynamic array to shrink HAL file size. - std::shared_ptr* m_structures; - priority_mutex* m_handleMutexes; + std::unique_ptr[]> m_structures; + std::unique_ptr m_handleMutexes; }; template DigitalHandleResource::DigitalHandleResource() { - m_structures = new std::shared_ptr[size]; - m_handleMutexes = new priority_mutex[size]; -} - -template -DigitalHandleResource::~DigitalHandleResource() { - delete[] m_structures; - delete[] m_handleMutexes; + m_structures = std::make_unique[]>(size); + m_handleMutexes = std::make_unique(size); } template diff --git a/hal/include/HAL/handles/IndexedHandleResource.h b/hal/include/HAL/handles/IndexedHandleResource.h index c19fdab53c..29a7061b01 100644 --- a/hal/include/HAL/handles/IndexedHandleResource.h +++ b/hal/include/HAL/handles/IndexedHandleResource.h @@ -14,6 +14,7 @@ #include "HAL/Errors.h" #include "HAL/Types.h" +#include "HAL/cpp/make_unique.h" #include "HAL/cpp/priority_mutex.h" #include "HAL/handles/HandlesInternal.h" @@ -40,31 +41,22 @@ class IndexedHandleResource { IndexedHandleResource(const IndexedHandleResource&) = delete; IndexedHandleResource operator=(const IndexedHandleResource&) = delete; IndexedHandleResource(); - ~IndexedHandleResource(); THandle Allocate(int16_t index, int32_t* status); std::shared_ptr Get(THandle handle); void Free(THandle handle); private: // Dynamic array to shrink HAL file size. - std::shared_ptr* m_structures; - priority_mutex* m_handleMutexes; + std::unique_ptr[]> m_structures; + std::unique_ptr m_handleMutexes; }; template IndexedHandleResource::IndexedHandleResource() { - m_structures = new std::shared_ptr[size]; - m_handleMutexes = new priority_mutex[size]; -} - -template -IndexedHandleResource::~IndexedHandleResource() { - delete[] m_structures; - delete[] m_handleMutexes; + m_structures = std::make_unique[]>(size); + m_handleMutexes = std::make_unique(size); } template #include "HAL/Types.h" +#include "HAL/cpp/make_unique.h" #include "HAL/cpp/priority_mutex.h" #include "HAL/handles/HandlesInternal.h" @@ -39,15 +40,14 @@ class LimitedClassedHandleResource { LimitedClassedHandleResource operator=(const LimitedClassedHandleResource&) = delete; LimitedClassedHandleResource(); - ~LimitedClassedHandleResource(); THandle Allocate(std::shared_ptr toSet); std::shared_ptr Get(THandle handle); void Free(THandle handle); private: // Dynamic array to shrink HAL file size. - std::shared_ptr* m_structures; - priority_mutex* m_handleMutexes; + std::unique_ptr[]> m_structures; + std::unique_ptr m_handleMutexes; priority_mutex m_allocateMutex; }; @@ -55,16 +55,8 @@ template LimitedClassedHandleResource::LimitedClassedHandleResource() { - m_structures = new std::shared_ptr[size]; - m_handleMutexes = new priority_mutex[size]; -} - -template -LimitedClassedHandleResource::~LimitedClassedHandleResource() { - delete[] m_structures; - delete[] m_handleMutexes; + m_structures = std::make_unique[]>(size); + m_handleMutexes = std::make_unique(size); } template #include "HAL/Types.h" +#include "HAL/cpp/make_unique.h" #include "HAL/cpp/priority_mutex.h" #include "HandlesInternal.h" @@ -37,15 +38,14 @@ class LimitedHandleResource { LimitedHandleResource(const LimitedHandleResource&) = delete; LimitedHandleResource operator=(const LimitedHandleResource&) = delete; LimitedHandleResource(); - ~LimitedHandleResource(); THandle Allocate(); std::shared_ptr Get(THandle handle); void Free(THandle handle); private: // Dynamic array to shrink HAL file size. - std::shared_ptr* m_structures; - priority_mutex* m_handleMutexes; + std::unique_ptr[]> m_structures; + std::unique_ptr m_handleMutexes; priority_mutex m_allocateMutex; }; @@ -53,16 +53,8 @@ template LimitedHandleResource::LimitedHandleResource() { - m_structures = new std::shared_ptr[size]; - m_handleMutexes = new priority_mutex[size]; -} - -template -LimitedHandleResource::~LimitedHandleResource() { - delete[] m_structures; - delete[] m_handleMutexes; + m_structures = std::make_unique[]>(size); + m_handleMutexes = std::make_unique(size); } template pin = static_cast(pin); if (HAL_IsAccumulatorChannel(handle, status)) { - analog_port->accumulator = tAccumulator::create(pin, status); + analog_port->accumulator.reset(tAccumulator::create(pin, status)); } else { analog_port->accumulator = nullptr; } @@ -67,7 +67,6 @@ void HAL_FreeAnalogInputPort(HAL_AnalogInputHandle analog_port_handle) { if (!port) return; // no status, so no need to check for a proper free. analogInputHandles.Free(analog_port_handle); - delete port->accumulator; } /** diff --git a/hal/lib/athena/AnalogInternal.cpp b/hal/lib/athena/AnalogInternal.cpp index eb3cd15391..b4730a9f76 100644 --- a/hal/lib/athena/AnalogInternal.cpp +++ b/hal/lib/athena/AnalogInternal.cpp @@ -14,8 +14,8 @@ namespace hal { priority_recursive_mutex analogRegisterWindowMutex; -tAI* analogInputSystem = nullptr; -tAO* analogOutputSystem = nullptr; +std::unique_ptr analogInputSystem; +std::unique_ptr analogOutputSystem; IndexedHandleResource @@ -31,8 +31,8 @@ bool analogSystemInitialized = false; void initializeAnalog(int32_t* status) { std::lock_guard sync(analogRegisterWindowMutex); if (analogSystemInitialized) return; - analogInputSystem = tAI::create(status); - analogOutputSystem = tAO::create(status); + analogInputSystem.reset(tAI::create(status)); + analogOutputSystem.reset(tAO::create(status)); setAnalogNumChannelsToActivate(kNumAnalogInputs); HAL_SetAnalogSampleRate(kDefaultSampleRate, status); analogSystemInitialized = true; diff --git a/hal/lib/athena/AnalogInternal.h b/hal/lib/athena/AnalogInternal.h index 5d076e3b3b..2c9f2f2fb6 100644 --- a/hal/lib/athena/AnalogInternal.h +++ b/hal/lib/athena/AnalogInternal.h @@ -22,13 +22,13 @@ constexpr int32_t kDefaultAverageBits = 7; constexpr double kDefaultSampleRate = 50000.0; static const uint32_t kAccumulatorChannels[] = {0, 1}; -extern tAI* analogInputSystem; -extern tAO* analogOutputSystem; +extern std::unique_ptr analogInputSystem; +extern std::unique_ptr analogOutputSystem; extern priority_recursive_mutex analogRegisterWindowMutex; struct AnalogPort { uint8_t pin; - tAccumulator* accumulator; + std::unique_ptr accumulator; }; extern IndexedHandleResource trigger; HAL_AnalogInputHandle analogHandle; uint8_t index; }; @@ -53,7 +53,7 @@ HAL_AnalogTriggerHandle HAL_InitializeAnalogTrigger( *index = trigger->index; // TODO: if (index == ~0ul) { CloneError(triggers); return; } - trigger->trigger = tAnalogTrigger::create(trigger->index, status); + trigger->trigger.reset(tAnalogTrigger::create(trigger->index, status)); trigger->trigger->writeSourceSelect_Channel(analog_port->pin, status); return handle; } @@ -66,7 +66,6 @@ void HAL_CleanAnalogTrigger(HAL_AnalogTriggerHandle analog_trigger_handle, } analogTriggerHandles.Free(analog_trigger_handle); // caller owns the analog input handle. - delete trigger->trigger; } void HAL_SetAnalogTriggerLimitsRaw( diff --git a/hal/lib/athena/Compressor.cpp b/hal/lib/athena/Compressor.cpp index dffebcfded..c0531968f7 100644 --- a/hal/lib/athena/Compressor.cpp +++ b/hal/lib/athena/Compressor.cpp @@ -43,10 +43,9 @@ HAL_Bool HAL_GetCompressor(HAL_CompressorHandle compressor_handle, *status = HAL_HANDLE_ERROR; return false; } - PCM* module = PCM_modules[index]; bool value; - *status = module->GetCompressor(value); + *status = PCM_modules[index]->GetCompressor(value); return value; } @@ -59,9 +58,8 @@ void HAL_SetCompressorClosedLoopControl(HAL_CompressorHandle compressor_handle, *status = HAL_HANDLE_ERROR; return; } - PCM* module = PCM_modules[index]; - *status = module->SetClosedLoopControl(value); + *status = PCM_modules[index]->SetClosedLoopControl(value); } HAL_Bool HAL_GetCompressorClosedLoopControl( @@ -72,10 +70,9 @@ HAL_Bool HAL_GetCompressorClosedLoopControl( *status = HAL_HANDLE_ERROR; return false; } - PCM* module = PCM_modules[index]; bool value; - *status = module->GetClosedLoopControl(value); + *status = PCM_modules[index]->GetClosedLoopControl(value); return value; } @@ -88,10 +85,9 @@ HAL_Bool HAL_GetCompressorPressureSwitch(HAL_CompressorHandle compressor_handle, *status = HAL_HANDLE_ERROR; return false; } - PCM* module = PCM_modules[index]; bool value; - *status = module->GetPressure(value); + *status = PCM_modules[index]->GetPressure(value); return value; } @@ -104,10 +100,9 @@ double HAL_GetCompressorCurrent(HAL_CompressorHandle compressor_handle, *status = HAL_HANDLE_ERROR; return 0; } - PCM* module = PCM_modules[index]; float value; - *status = module->GetCompressorCurrent(value); + *status = PCM_modules[index]->GetCompressorCurrent(value); return value; } @@ -119,10 +114,9 @@ HAL_Bool HAL_GetCompressorCurrentTooHighFault( *status = HAL_HANDLE_ERROR; return false; } - PCM* module = PCM_modules[index]; bool value; - *status = module->GetCompressorCurrentTooHighFault(value); + *status = PCM_modules[index]->GetCompressorCurrentTooHighFault(value); return value; } @@ -134,10 +128,9 @@ HAL_Bool HAL_GetCompressorCurrentTooHighStickyFault( *status = HAL_HANDLE_ERROR; return false; } - PCM* module = PCM_modules[index]; bool value; - *status = module->GetCompressorCurrentTooHighStickyFault(value); + *status = PCM_modules[index]->GetCompressorCurrentTooHighStickyFault(value); return value; } @@ -149,10 +142,9 @@ HAL_Bool HAL_GetCompressorShortedStickyFault( *status = HAL_HANDLE_ERROR; return false; } - PCM* module = PCM_modules[index]; bool value; - *status = module->GetCompressorShortedStickyFault(value); + *status = PCM_modules[index]->GetCompressorShortedStickyFault(value); return value; } @@ -164,10 +156,9 @@ HAL_Bool HAL_GetCompressorShortedFault(HAL_CompressorHandle compressor_handle, *status = HAL_HANDLE_ERROR; return false; } - PCM* module = PCM_modules[index]; bool value; - *status = module->GetCompressorShortedFault(value); + *status = PCM_modules[index]->GetCompressorShortedFault(value); return value; } @@ -179,10 +170,9 @@ HAL_Bool HAL_GetCompressorNotConnectedStickyFault( *status = HAL_HANDLE_ERROR; return false; } - PCM* module = PCM_modules[index]; bool value; - *status = module->GetCompressorNotConnectedStickyFault(value); + *status = PCM_modules[index]->GetCompressorNotConnectedStickyFault(value); return value; } @@ -194,10 +184,9 @@ HAL_Bool HAL_GetCompressorNotConnectedFault( *status = HAL_HANDLE_ERROR; return false; } - PCM* module = PCM_modules[index]; bool value; - *status = module->GetCompressorNotConnectedFault(value); + *status = PCM_modules[index]->GetCompressorNotConnectedFault(value); return value; } diff --git a/hal/lib/athena/Counter.cpp b/hal/lib/athena/Counter.cpp index 5080b6e068..28de802168 100644 --- a/hal/lib/athena/Counter.cpp +++ b/hal/lib/athena/Counter.cpp @@ -17,7 +17,7 @@ using namespace hal; namespace { struct Counter { - tCounter* counter; + std::unique_ptr counter; uint8_t index; }; } @@ -42,7 +42,7 @@ HAL_CounterHandle HAL_InitializeCounter(HAL_Counter_Mode mode, int32_t* index, counter->index = static_cast(getHandleIndex(handle)); *index = counter->index; - counter->counter = tCounter::create(counter->index, status); + counter->counter.reset(tCounter::create(counter->index, status)); counter->counter->writeConfig_Mode(mode, status); counter->counter->writeTimerConfig_AverageSize(1, status); return handle; @@ -53,7 +53,6 @@ void HAL_FreeCounter(HAL_CounterHandle counter_handle, int32_t* status) { if (counter == nullptr) { // don't throw status as unneccesary return; } - delete counter->counter; counterHandles.Free(counter_handle); } diff --git a/hal/lib/athena/DigitalInternal.cpp b/hal/lib/athena/DigitalInternal.cpp index de591c2a57..531618aacd 100644 --- a/hal/lib/athena/DigitalInternal.cpp +++ b/hal/lib/athena/DigitalInternal.cpp @@ -23,9 +23,9 @@ namespace hal { // Create a mutex to protect changes to the DO PWM config priority_recursive_mutex digitalPwmMutex; -tDIO* digitalSystem = nullptr; -tRelay* relaySystem = nullptr; -tPWM* pwmSystem = nullptr; +std::unique_ptr digitalSystem; +std::unique_ptr relaySystem; +std::unique_ptr pwmSystem; bool digitalSystemsInitialized = false; @@ -39,17 +39,17 @@ DigitalHandleResourcewriteValue_Forward(0, status); relaySystem->writeValue_Reverse(0, status); // PWM Setup - pwmSystem = tPWM::create(status); + pwmSystem.reset(tPWM::create(status)); // Make sure that the 9403 IONode has had a chance to initialize before // continuing. diff --git a/hal/lib/athena/DigitalInternal.h b/hal/lib/athena/DigitalInternal.h index 68b03aff79..9d78d15a62 100644 --- a/hal/lib/athena/DigitalInternal.h +++ b/hal/lib/athena/DigitalInternal.h @@ -55,9 +55,9 @@ constexpr int32_t kPwmDisabled = 0; // Create a mutex to protect changes to the DO PWM config extern priority_recursive_mutex digitalPwmMutex; -extern tDIO* digitalSystem; -extern tRelay* relaySystem; -extern tPWM* pwmSystem; +extern std::unique_ptr digitalSystem; +extern std::unique_ptr relaySystem; +extern std::unique_ptr pwmSystem; extern bool digitalSystemsInitialized; diff --git a/hal/lib/athena/FPGAEncoder.cpp b/hal/lib/athena/FPGAEncoder.cpp index a86a27fc18..be2764c7f6 100644 --- a/hal/lib/athena/FPGAEncoder.cpp +++ b/hal/lib/athena/FPGAEncoder.cpp @@ -7,6 +7,8 @@ #include "FPGAEncoder.h" +#include + #include "DigitalInternal.h" #include "HAL/handles/LimitedHandleResource.h" #include "PortsInternal.h" @@ -15,7 +17,7 @@ using namespace hal; namespace { struct Encoder { - tEncoder* encoder; + std::unique_ptr encoder; uint8_t index; }; } @@ -64,7 +66,7 @@ HAL_FPGAEncoderHandle HAL_InitializeFPGAEncoder( encoder->index = static_cast(getHandleIndex(handle)); *index = encoder->index; // TODO: if (index == ~0ul) { CloneError(quadEncoders); return; } - encoder->encoder = tEncoder::create(encoder->index, status); + encoder->encoder.reset(tEncoder::create(encoder->index, status)); encoder->encoder->writeConfig_ASource_Module(routingModuleA, status); encoder->encoder->writeConfig_ASource_Channel(routingPinA, status); encoder->encoder->writeConfig_ASource_AnalogTrigger(routingAnalogTriggerA, @@ -88,7 +90,6 @@ void HAL_FreeFPGAEncoder(HAL_FPGAEncoderHandle fpga_encoder_handle, *status = HAL_HANDLE_ERROR; return; } - delete encoder->encoder; } /** diff --git a/hal/lib/athena/HALAthena.cpp b/hal/lib/athena/HALAthena.cpp index 7b08fda605..fc0085c109 100644 --- a/hal/lib/athena/HALAthena.cpp +++ b/hal/lib/athena/HALAthena.cpp @@ -27,8 +27,8 @@ #include "ctre/ctre.h" #include "visa/visa.h" -static tGlobal* global = nullptr; -static tSysWatchdog* watchdog = nullptr; +static std::unique_ptr global; +static std::unique_ptr watchdog; static priority_mutex timeMutex; static uint32_t timeEpoch = 0; @@ -271,8 +271,8 @@ int32_t HAL_Initialize(int32_t mode) { nLoadOut::kTargetClass_RoboRIO; int32_t status = 0; - global = tGlobal::create(&status); - watchdog = tSysWatchdog::create(&status); + global.reset(tGlobal::create(&status)); + watchdog.reset(tSysWatchdog::create(&status)); std::atexit(HALCleanupAtExit); diff --git a/hal/lib/athena/Interrupts.cpp b/hal/lib/athena/Interrupts.cpp index 71db14b193..434a74595b 100644 --- a/hal/lib/athena/Interrupts.cpp +++ b/hal/lib/athena/Interrupts.cpp @@ -13,6 +13,7 @@ #include "DigitalInternal.h" #include "HAL/Errors.h" +#include "HAL/cpp/make_unique.h" #include "HAL/handles/HandlesInternal.h" #include "HAL/handles/LimitedHandleResource.h" #include "PortsInternal.h" @@ -20,10 +21,9 @@ using namespace hal; namespace { -// FIXME: why is this internal? struct Interrupt { - tInterrupt* anInterrupt; - tInterruptManager* manager; + std::unique_ptr anInterrupt; + std::unique_ptr manager; }; } @@ -43,9 +43,9 @@ HAL_InterruptHandle HAL_InitializeInterrupts(HAL_Bool watcher, auto anInterrupt = interruptHandles.Get(handle); uint32_t interruptIndex = static_cast(getHandleIndex(handle)); // Expects the calling leaf class to allocate an interrupt index. - anInterrupt->anInterrupt = tInterrupt::create(interruptIndex, status); + anInterrupt->anInterrupt.reset(tInterrupt::create(interruptIndex, status)); anInterrupt->anInterrupt->writeConfig_WaitForAck(false, status); - anInterrupt->manager = new tInterruptManager( + anInterrupt->manager = std::make_unique( (1u << interruptIndex) | (1u << (interruptIndex + 8u)), watcher, status); return handle; } @@ -58,8 +58,6 @@ void HAL_CleanInterrupts(HAL_InterruptHandle interrupt_handle, return; } interruptHandles.Free(interrupt_handle); - delete anInterrupt->anInterrupt; - delete anInterrupt->manager; } /** diff --git a/hal/lib/athena/Notifier.cpp b/hal/lib/athena/Notifier.cpp index 3693971b6f..c22e5b9105 100644 --- a/hal/lib/athena/Notifier.cpp +++ b/hal/lib/athena/Notifier.cpp @@ -16,6 +16,7 @@ #include "ChipObject.h" #include "HAL/HAL.h" +#include "HAL/cpp/make_unique.h" #include "HAL/cpp/priority_mutex.h" #include "HAL/handles/UnlimitedHandleResource.h" @@ -23,8 +24,8 @@ static const uint32_t kTimerInterruptNumber = 28; static priority_mutex notifierInterruptMutex; static priority_recursive_mutex notifierMutex; -static tAlarm* notifierAlarm = nullptr; -static tInterruptManager* notifierManager = nullptr; +static std::unique_ptr notifierAlarm; +static std::unique_ptr notifierManager; static uint64_t closestTrigger = UINT64_MAX; namespace { @@ -35,7 +36,7 @@ struct Notifier { uint64_t triggerTime = UINT64_MAX; }; } -static std::shared_ptr notifiers = nullptr; +static std::shared_ptr notifiers; static std::atomic_flag notifierAtexitRegistered = ATOMIC_FLAG_INIT; static std::atomic_int notifierRefCount{0}; @@ -120,12 +121,12 @@ HAL_NotifierHandle HAL_InitializeNotifier(void (*process)(uint64_t, void*), std::lock_guard sync(notifierInterruptMutex); // create manager and alarm if not already created if (!notifierManager) { - notifierManager = - new tInterruptManager(1 << kTimerInterruptNumber, false, status); + notifierManager = std::make_unique( + 1 << kTimerInterruptNumber, false, status); notifierManager->registerHandler(alarmCallback, nullptr, status); notifierManager->enable(status); } - if (!notifierAlarm) notifierAlarm = tAlarm::create(status); + if (!notifierAlarm) notifierAlarm.reset(tAlarm::create(status)); } std::lock_guard sync(notifierMutex); @@ -157,12 +158,10 @@ void HAL_CleanNotifier(HAL_NotifierHandle notifier_handle, int32_t* status) { // if this was the last notifier, clean up alarm and manager if (notifierAlarm) { notifierAlarm->writeEnable(false, status); - delete notifierAlarm; notifierAlarm = nullptr; } if (notifierManager) { notifierManager->disable(status); - delete notifierManager; notifierManager = nullptr; } closestTrigger = UINT64_MAX; diff --git a/hal/lib/athena/PCMInternal.cpp b/hal/lib/athena/PCMInternal.cpp index 0a2676f674..f5e9671016 100644 --- a/hal/lib/athena/PCMInternal.cpp +++ b/hal/lib/athena/PCMInternal.cpp @@ -9,10 +9,11 @@ #include "HAL/Errors.h" #include "HAL/Solenoid.h" +#include "HAL/cpp/make_unique.h" #include "PortsInternal.h" namespace hal { -PCM* PCM_modules[kNumPCMModules] = {nullptr}; +std::unique_ptr PCM_modules[kNumPCMModules]; void initializePCM(int32_t module, int32_t* status) { if (!HAL_CheckSolenoidModule(module)) { @@ -20,7 +21,7 @@ void initializePCM(int32_t module, int32_t* status) { return; } if (!PCM_modules[module]) { - PCM_modules[module] = new PCM(module); + PCM_modules[module] = std::make_unique(module); } } } // namespace hal diff --git a/hal/lib/athena/PCMInternal.h b/hal/lib/athena/PCMInternal.h index 309b0301c4..299a72bb60 100644 --- a/hal/lib/athena/PCMInternal.h +++ b/hal/lib/athena/PCMInternal.h @@ -8,13 +8,28 @@ #pragma once #include +#include +#include "HAL/Errors.h" #include "HAL/Ports.h" +#include "HAL/Solenoid.h" #include "PortsInternal.h" #include "ctre/PCM.h" namespace hal { -extern PCM* PCM_modules[kNumPCMModules]; +extern std::unique_ptr PCM_modules[kNumPCMModules]; + +static inline bool checkPCMInit(int32_t module, int32_t* status) { + if (!HAL_CheckSolenoidModule(module)) { + *status = RESOURCE_OUT_OF_RANGE; + return false; + } + if (!PCM_modules[module]) { + *status = INCOMPATIBLE_STATE; + return false; + } + return true; +} void initializePCM(int32_t module, int32_t* status); -} +} // namespace hal diff --git a/hal/lib/athena/PDP.cpp b/hal/lib/athena/PDP.cpp index f2f68314bd..dd49f4d3a9 100644 --- a/hal/lib/athena/PDP.cpp +++ b/hal/lib/athena/PDP.cpp @@ -7,14 +7,29 @@ #include "HAL/PDP.h" +#include + #include "HAL/Errors.h" #include "HAL/Ports.h" +#include "HAL/cpp/make_unique.h" #include "PortsInternal.h" #include "ctre/PDP.h" using namespace hal; -static PDP* pdp[kNumPDPModules] = {nullptr}; +static std::unique_ptr pdp[kNumPDPModules]; + +static inline bool checkPDPInit(int32_t module, int32_t* status) { + if (!HAL_CheckPDPModule(module)) { + *status = RESOURCE_OUT_OF_RANGE; + return false; + } + if (!pdp[module]) { + *status = INCOMPATIBLE_STATE; + return false; + } + return true; +} extern "C" { @@ -24,7 +39,7 @@ void HAL_InitializePDP(int32_t module, int32_t* status) { return; } if (!pdp[module]) { - pdp[module] = new PDP(module); + pdp[module] = std::make_unique(module); } } @@ -33,10 +48,7 @@ HAL_Bool HAL_CheckPDPModule(int32_t module) { } double HAL_GetPDPTemperature(int32_t module, int32_t* status) { - if (!HAL_CheckPDPModule(module)) { - *status = PARAMETER_OUT_OF_RANGE; - return 0.0; - } + if (!checkPDPInit(module, status)) return 0; double temperature; @@ -46,10 +58,7 @@ double HAL_GetPDPTemperature(int32_t module, int32_t* status) { } double HAL_GetPDPVoltage(int32_t module, int32_t* status) { - if (!HAL_CheckPDPModule(module)) { - *status = PARAMETER_OUT_OF_RANGE; - return 0.0; - } + if (!checkPDPInit(module, status)) return 0; double voltage; @@ -60,10 +69,7 @@ double HAL_GetPDPVoltage(int32_t module, int32_t* status) { double HAL_GetPDPChannelCurrent(int32_t module, int32_t channel, int32_t* status) { - if (!HAL_CheckPDPModule(module)) { - *status = PARAMETER_OUT_OF_RANGE; - return 0.0; - } + if (!checkPDPInit(module, status)) return 0; double current; @@ -73,10 +79,7 @@ double HAL_GetPDPChannelCurrent(int32_t module, int32_t channel, } double HAL_GetPDPTotalCurrent(int32_t module, int32_t* status) { - if (!HAL_CheckPDPModule(module)) { - *status = PARAMETER_OUT_OF_RANGE; - return 0.0; - } + if (!checkPDPInit(module, status)) return 0; double current; @@ -86,10 +89,7 @@ double HAL_GetPDPTotalCurrent(int32_t module, int32_t* status) { } double HAL_GetPDPTotalPower(int32_t module, int32_t* status) { - if (!HAL_CheckPDPModule(module)) { - *status = PARAMETER_OUT_OF_RANGE; - return 0.0; - } + if (!checkPDPInit(module, status)) return 0; double power; @@ -99,10 +99,7 @@ double HAL_GetPDPTotalPower(int32_t module, int32_t* status) { } double HAL_GetPDPTotalEnergy(int32_t module, int32_t* status) { - if (!HAL_CheckPDPModule(module)) { - *status = PARAMETER_OUT_OF_RANGE; - return 0.0; - } + if (!checkPDPInit(module, status)) return 0; double energy; @@ -112,19 +109,13 @@ double HAL_GetPDPTotalEnergy(int32_t module, int32_t* status) { } void HAL_ResetPDPTotalEnergy(int32_t module, int32_t* status) { - if (!HAL_CheckPDPModule(module)) { - *status = PARAMETER_OUT_OF_RANGE; - return; - } + if (!checkPDPInit(module, status)) return; *status = pdp[module]->ResetEnergy(); } void HAL_ClearPDPStickyFaults(int32_t module, int32_t* status) { - if (!HAL_CheckPDPModule(module)) { - *status = PARAMETER_OUT_OF_RANGE; - return; - } + if (!checkPDPInit(module, status)) return; *status = pdp[module]->ClearStickyFaults(); } diff --git a/hal/lib/athena/Power.cpp b/hal/lib/athena/Power.cpp index 50d6c11c84..16a0e8b10b 100644 --- a/hal/lib/athena/Power.cpp +++ b/hal/lib/athena/Power.cpp @@ -7,13 +7,15 @@ #include "HAL/Power.h" +#include + #include "ChipObject.h" -static tPower* power = nullptr; +static std::unique_ptr power; static void initializePower(int32_t* status) { if (power == nullptr) { - power = tPower::create(status); + power.reset(tPower::create(status)); } } diff --git a/hal/lib/athena/SPI.cpp b/hal/lib/athena/SPI.cpp index a1e9aa7c2d..5a03afbc4f 100644 --- a/hal/lib/athena/SPI.cpp +++ b/hal/lib/athena/SPI.cpp @@ -12,6 +12,7 @@ #include "DigitalInternal.h" #include "HAL/DIO.h" #include "HAL/HAL.h" +#include "HAL/cpp/make_unique.h" #include "HAL/cpp/priority_mutex.h" #include "spilib/spi-lib.h" @@ -72,8 +73,7 @@ struct SPIAccumulator { bool is_signed; // is data field signed? bool big_endian; // is response big endian? }; -SPIAccumulator* spiAccumulators[5] = {nullptr, nullptr, nullptr, nullptr, - nullptr}; +std::unique_ptr spiAccumulators[5]; /* * Initialize the spi port. Opens the port if necessary and saves the handle. @@ -403,8 +403,9 @@ void HAL_InitSPIAccumulator(int32_t port, int32_t period, int32_t cmd, HAL_Bool big_endian, int32_t* status) { std::lock_guard sync(spiGetMutex(port)); if (port > 4) return; - if (!spiAccumulators[port]) spiAccumulators[port] = new SPIAccumulator(); - SPIAccumulator* accum = spiAccumulators[port]; + if (!spiAccumulators[port]) + spiAccumulators[port] = std::make_unique(); + SPIAccumulator* accum = spiAccumulators[port].get(); if (big_endian) { for (int i = xfer_size - 1; i >= 0; --i) { accum->cmd[i] = cmd & 0xff; @@ -442,14 +443,13 @@ void HAL_InitSPIAccumulator(int32_t port, int32_t period, int32_t cmd, */ void HAL_FreeSPIAccumulator(int32_t port, int32_t* status) { std::lock_guard sync(spiGetMutex(port)); - SPIAccumulator* accum = spiAccumulators[port]; + SPIAccumulator* accum = spiAccumulators[port].get(); if (!accum) { *status = NULL_PARAMETER; return; } HAL_NotifierHandle handle = accum->notifier.exchange(0); HAL_CleanNotifier(handle, status); - delete accum; spiAccumulators[port] = nullptr; } @@ -458,7 +458,7 @@ void HAL_FreeSPIAccumulator(int32_t port, int32_t* status) { */ void HAL_ResetSPIAccumulator(int32_t port, int32_t* status) { std::lock_guard sync(spiGetMutex(port)); - SPIAccumulator* accum = spiAccumulators[port]; + SPIAccumulator* accum = spiAccumulators[port].get(); if (!accum) { *status = NULL_PARAMETER; return; @@ -480,7 +480,7 @@ void HAL_ResetSPIAccumulator(int32_t port, int32_t* status) { void HAL_SetSPIAccumulatorCenter(int32_t port, int32_t center, int32_t* status) { std::lock_guard sync(spiGetMutex(port)); - SPIAccumulator* accum = spiAccumulators[port]; + SPIAccumulator* accum = spiAccumulators[port].get(); if (!accum) { *status = NULL_PARAMETER; return; @@ -494,7 +494,7 @@ void HAL_SetSPIAccumulatorCenter(int32_t port, int32_t center, void HAL_SetSPIAccumulatorDeadband(int32_t port, int32_t deadband, int32_t* status) { std::lock_guard sync(spiGetMutex(port)); - SPIAccumulator* accum = spiAccumulators[port]; + SPIAccumulator* accum = spiAccumulators[port].get(); if (!accum) { *status = NULL_PARAMETER; return; @@ -507,7 +507,7 @@ void HAL_SetSPIAccumulatorDeadband(int32_t port, int32_t deadband, */ int32_t HAL_GetSPIAccumulatorLastValue(int32_t port, int32_t* status) { std::lock_guard sync(spiGetMutex(port)); - SPIAccumulator* accum = spiAccumulators[port]; + SPIAccumulator* accum = spiAccumulators[port].get(); if (!accum) { *status = NULL_PARAMETER; return 0; @@ -522,7 +522,7 @@ int32_t HAL_GetSPIAccumulatorLastValue(int32_t port, int32_t* status) { */ int64_t HAL_GetSPIAccumulatorValue(int32_t port, int32_t* status) { std::lock_guard sync(spiGetMutex(port)); - SPIAccumulator* accum = spiAccumulators[port]; + SPIAccumulator* accum = spiAccumulators[port].get(); if (!accum) { *status = NULL_PARAMETER; return 0; @@ -540,7 +540,7 @@ int64_t HAL_GetSPIAccumulatorValue(int32_t port, int32_t* status) { */ int64_t HAL_GetSPIAccumulatorCount(int32_t port, int32_t* status) { std::lock_guard sync(spiGetMutex(port)); - SPIAccumulator* accum = spiAccumulators[port]; + SPIAccumulator* accum = spiAccumulators[port].get(); if (!accum) { *status = NULL_PARAMETER; return 0; @@ -573,7 +573,7 @@ double HAL_GetSPIAccumulatorAverage(int32_t port, int32_t* status) { void HAL_GetSPIAccumulatorOutput(int32_t port, int64_t* value, int64_t* count, int32_t* status) { std::lock_guard sync(spiGetMutex(port)); - SPIAccumulator* accum = spiAccumulators[port]; + SPIAccumulator* accum = spiAccumulators[port].get(); if (!accum) { *status = NULL_PARAMETER; *value = 0; diff --git a/hal/lib/athena/Solenoid.cpp b/hal/lib/athena/Solenoid.cpp index 556ec0538d..9dfa1a0a17 100644 --- a/hal/lib/athena/Solenoid.cpp +++ b/hal/lib/athena/Solenoid.cpp @@ -97,10 +97,7 @@ HAL_Bool HAL_GetSolenoid(HAL_SolenoidHandle solenoid_port_handle, } int32_t HAL_GetAllSolenoids(int32_t module, int32_t* status) { - if (module >= kNumPCMModules) { - *status = PARAMETER_OUT_OF_RANGE; - return 0; - } + if (!checkPCMInit(module, status)) return 0; uint8_t value; *status = PCM_modules[module]->GetAllSolenoids(value); @@ -120,10 +117,7 @@ void HAL_SetSolenoid(HAL_SolenoidHandle solenoid_port_handle, HAL_Bool value, } int32_t HAL_GetPCMSolenoidBlackList(int32_t module, int32_t* status) { - if (module >= kNumPCMModules) { - *status = PARAMETER_OUT_OF_RANGE; - return 0; - } + if (!checkPCMInit(module, status)) return 0; UINT8 value; *status = PCM_modules[module]->GetSolenoidBlackList(value); @@ -131,10 +125,7 @@ int32_t HAL_GetPCMSolenoidBlackList(int32_t module, int32_t* status) { return value; } HAL_Bool HAL_GetPCMSolenoidVoltageStickyFault(int32_t module, int32_t* status) { - if (module >= kNumPCMModules) { - *status = PARAMETER_OUT_OF_RANGE; - return false; - } + if (!checkPCMInit(module, status)) return 0; bool value; *status = PCM_modules[module]->GetSolenoidStickyFault(value); @@ -142,10 +133,7 @@ HAL_Bool HAL_GetPCMSolenoidVoltageStickyFault(int32_t module, int32_t* status) { return value; } HAL_Bool HAL_GetPCMSolenoidVoltageFault(int32_t module, int32_t* status) { - if (module >= kNumPCMModules) { - *status = PARAMETER_OUT_OF_RANGE; - return false; - } + if (!checkPCMInit(module, status)) return false; bool value; *status = PCM_modules[module]->GetSolenoidFault(value); @@ -153,10 +141,7 @@ HAL_Bool HAL_GetPCMSolenoidVoltageFault(int32_t module, int32_t* status) { return value; } void HAL_ClearAllPCMStickyFaults(int32_t module, int32_t* status) { - if (module >= kNumPCMModules) { - *status = PARAMETER_OUT_OF_RANGE; - return; - } + if (!checkPCMInit(module, status)) return; *status = PCM_modules[module]->ClearStickyFaults(); } diff --git a/wpilibc/shared/include/Base.h b/wpilibc/shared/include/Base.h index 71a8d1d9db..1564aeb533 100644 --- a/wpilibc/shared/include/Base.h +++ b/wpilibc/shared/include/Base.h @@ -7,6 +7,8 @@ #pragma once +#include "HAL/cpp/make_unique.h" + // MSVC 2013 doesn't allow "= default" on move constructors, but since we are // (currently) only actually using the move constructors in non-MSVC situations // (ie, wpilibC++Devices), we can just ignore it in MSVC. @@ -76,42 +78,3 @@ struct HasBeenMoved { std::atomic moved{false}; operator bool() const { return moved; } }; - -// Define make_unique for C++11-only compilers -#if __cplusplus == 201103L -#include - -#include -#include -#include -namespace std { -template -struct _Unique_if { - typedef unique_ptr _Single_object; -}; - -template -struct _Unique_if { - typedef unique_ptr _Unknown_bound; -}; - -template -struct _Unique_if { - typedef void _Known_bound; -}; - -template -typename _Unique_if::_Single_object make_unique(Args&&... args) { - return unique_ptr(new T(std::forward(args)...)); -} - -template -typename _Unique_if::_Unknown_bound make_unique(size_t n) { - typedef typename remove_extent::type U; - return unique_ptr(new U[n]()); -} - -template -typename _Unique_if::_Known_bound make_unique(Args&&...) = delete; -} // namespace std -#endif