uhd: Deprecate pimpl.hpp

This file promotes usage of std::shared_ptr for pimpl types, which is
not good practice. Also, it doesn't really do all that much: The macros
it defines are almost as long as their implementations.

Therefore, we remove its usage from UHD and replace it with standard
pointer types. For USRP1 and USRP2, usage of unique_ptr is not possible
without changing more of the implementation, so a shared_ptr is used.

The header itself is not removed, but the macros are declared
deprecated.
This commit is contained in:
Martin Braun 2025-06-23 14:55:33 +02:00 committed by Jörg Hofrichter
parent e970f76973
commit de0abb9844
8 changed files with 24 additions and 35 deletions

View File

@ -12,7 +12,6 @@
#include <uhd/usrp/dboard_id.hpp>
#include <uhd/usrp/dboard_iface.hpp>
#include <uhd/utils/noncopyable.hpp>
#include <uhd/utils/pimpl.hpp>
#include <memory>
namespace uhd { namespace usrp {
@ -34,7 +33,7 @@ public:
// structors
dboard_base(ctor_args_t);
virtual ~dboard_base() {}
virtual ~dboard_base();
// post-construction initializer
virtual void initialize() {}
@ -50,7 +49,8 @@ protected:
property_tree::sptr get_tx_subtree(void);
private:
UHD_PIMPL_DECL(impl) _impl;
struct impl;
std::unique_ptr<impl> _impl;
};
/*!

View File

@ -10,33 +10,18 @@
#include <uhd/config.hpp>
#include <memory>
/*! \file pimpl.hpp
* "Pimpl idiom" (pointer to implementation idiom).
* The UHD_PIMPL_* macros simplify code overhead for declaring and making pimpls.
/*! Make a declaration for a pimpl in a header file.
*
* Each pimpl is implemented as a shared pointer to the implementation:
* - The container class will not have to deallocate the pimpl.
* - The container class will use the pimpl as a regular pointer.
* - Usage: _impl->method(arg0, arg1)
* - Usage: _impl->member = value;
*
* \see http://en.wikipedia.org/wiki/Opaque_pointer
*/
/*!
* Make a declaration for a pimpl in a header file.
* - Usage: UHD_PIMPL_DECL(impl) _impl;
* \param _name the name of the pimpl class
* \deprecated This macro is deprecated and will be removed in a future release.
* Instead, directly declare the pimpl struct in the header file.
*/
#define UHD_PIMPL_DECL(_name) \
struct _name; \
std::shared_ptr<_name>
/*!
* Make an instance of a pimpl in a source file.
* - Usage: _impl = UHD_PIMPL_MAKE(impl, ());
* - Usage: _impl = UHD_PIMPL_MAKE(impl, (a0, a1));
* \param _name the name of the pimpl class
* \param _args the constructor args for the pimpl
/*! Make an instance of a pimpl in a source file.
*
* \deprecated This macro is deprecated and will be removed in a future release.
* Instead, directly instantiate the pimpl struct in the source file.
*/
#define UHD_PIMPL_MAKE(_name, _args) std::shared_ptr<_name>(new _name _args)
#define UHD_PIMPL_MAKE(_name, _args) std::make_shared<_name> _args

View File

@ -21,7 +21,6 @@
#include <uhd/types/stream_cmd.hpp>
#include <uhd/usrp/mboard_eeprom.hpp>
#include <uhd/usrp/subdev_spec.hpp>
#include <uhd/utils/pimpl.hpp>
#include <uhd/utils/tasks.hpp>
#include <uhdlib/usrp/common/ad9361_ctrl.hpp>
#include <uhdlib/usrp/common/ad936x_manager.hpp>

View File

@ -22,10 +22,12 @@ struct dboard_base::impl
dboard_base::dboard_base(ctor_args_t args)
{
_impl = UHD_PIMPL_MAKE(impl, ());
_impl = std::make_unique<impl>();
_impl->args = dboard_ctor_args_t::cast(args);
}
dboard_base::~dboard_base() = default;
std::string dboard_base::get_subdev_name(void)
{
return _impl->args.sd_name;

View File

@ -236,7 +236,7 @@ void usrp1_impl::io_impl::flush_send_buff(void)
**********************************************************************/
void usrp1_impl::io_init(void)
{
_io_impl = UHD_PIMPL_MAKE(io_impl, (_data_transport));
_io_impl = std::make_shared<io_impl>(_data_transport);
// init as disabled, then call the real function (uses restore)
this->enable_rx(false);

View File

@ -18,7 +18,6 @@
#include <uhd/usrp/dboard_manager.hpp>
#include <uhd/usrp/mboard_eeprom.hpp>
#include <uhd/usrp/subdev_spec.hpp>
#include <uhd/utils/pimpl.hpp>
#include <atomic>
#include <complex>
#include <memory>
@ -119,7 +118,10 @@ private:
const uhd::usrp::dboard_id_t&);
// handle io stuff
UHD_PIMPL_DECL(io_impl) _io_impl;
struct io_impl;
// pimpl is shared_ptr because the implementation of the dtor doesn't know
// the type of the io_impl, so it can't call the dtor directly.
std::shared_ptr<io_impl> _io_impl;
void io_init(void);
void rx_stream_on_off(bool);
void tx_stream_on_off(bool);

View File

@ -238,8 +238,7 @@ void usrp2_impl::io_impl::recv_pirate_loop(
**********************************************************************/
void usrp2_impl::io_init(void)
{
// create new io impl
_io_impl = UHD_PIMPL_MAKE(io_impl, ());
_io_impl = std::make_shared<io_impl>();
// init first so we dont have an access race
for (const std::string& mb : _mbc.keys()) {

View File

@ -23,7 +23,6 @@
#include <uhd/usrp/dboard_eeprom.hpp>
#include <uhd/usrp/dboard_manager.hpp>
#include <uhd/usrp/subdev_spec.hpp>
#include <uhd/utils/pimpl.hpp>
#include <uhdlib/usrp/cores/gpio_core_200.hpp>
#include <uhdlib/usrp/cores/rx_dsp_core_200.hpp>
#include <uhdlib/usrp/cores/rx_frontend_core_200.hpp>
@ -110,7 +109,10 @@ private:
// io impl methods and members
uhd::device_addr_t device_addr;
UHD_PIMPL_DECL(io_impl) _io_impl;
struct io_impl;
// pimpl is shared_ptr because the implementation of the dtor doesn't know
// the type of the io_impl, so it can't call the dtor directly.
std::shared_ptr<io_impl> _io_impl;
std::atomic<bool> _pirate_task_exit;
void io_init(void);
void update_tick_rate(const double rate);