Skip to content

Commit

Permalink
Use copy-swap idiom for the copy and move constructor/assignment oper…
Browse files Browse the repository at this point in the history
…ations
  • Loading branch information
saikishor committed Jan 21, 2025
1 parent 78cd70c commit 715ab29
Showing 1 changed file with 36 additions and 52 deletions.
88 changes: 36 additions & 52 deletions hardware_interface/include/hardware_interface/handle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#ifndef HARDWARE_INTERFACE__HANDLE_HPP_
#define HARDWARE_INTERFACE__HANDLE_HPP_

#include <algorithm>
#include <limits>
#include <memory>
#include <mutex>
Expand Down Expand Up @@ -72,69 +73,22 @@ class Handle
{
}

Handle(const Handle & other) noexcept
{
std::unique_lock<std::shared_mutex> lock(other.handle_mutex_);
std::unique_lock<std::shared_mutex> lock_this(handle_mutex_);
prefix_name_ = other.prefix_name_;
interface_name_ = other.interface_name_;
handle_name_ = other.handle_name_;
value_ = other.value_;
if (std::holds_alternative<std::monostate>(value_))
{
value_ptr_ = other.value_ptr_;
}
else
{
value_ptr_ = std::get_if<double>(&value_);
}
}

Handle(Handle && other) noexcept
{
std::unique_lock<std::shared_mutex> lock(other.handle_mutex_);
std::unique_lock<std::shared_mutex> lock_this(handle_mutex_);
prefix_name_ = std::move(other.prefix_name_);
interface_name_ = std::move(other.interface_name_);
handle_name_ = std::move(other.handle_name_);
value_ = std::move(other.value_);
value_ptr_ = std::move(other.value_ptr_);
}
Handle(const Handle & other) noexcept { copy(other); }

Handle & operator=(const Handle & other)
{
if (this != &other)
{
std::unique_lock<std::shared_mutex> lock(other.handle_mutex_);
std::unique_lock<std::shared_mutex> lock_this(handle_mutex_);
prefix_name_ = other.prefix_name_;
interface_name_ = other.interface_name_;
handle_name_ = other.handle_name_;
value_ = other.value_;
if (std::holds_alternative<std::monostate>(value_))
{
value_ptr_ = other.value_ptr_;
}
else
{
value_ptr_ = std::get_if<double>(&value_);
}
copy(other);
}
return *this;
}

Handle(Handle && other) noexcept { swap(*this, other); }

Handle & operator=(Handle && other)
{
if (this != &other)
{
std::unique_lock<std::shared_mutex> lock(other.handle_mutex_);
std::unique_lock<std::shared_mutex> lock_this(handle_mutex_);
prefix_name_ = std::move(other.prefix_name_);
interface_name_ = std::move(other.interface_name_);
handle_name_ = std::move(other.handle_name_);
value_ = std::move(other.value_);
value_ptr_ = std::move(other.value_ptr_);
}
swap(*this, other);
return *this;
}

Expand Down Expand Up @@ -201,6 +155,36 @@ class Handle
// END
}

private:
void copy(const Handle & other) noexcept
{
std::unique_lock<std::shared_mutex> lock(other.handle_mutex_);
std::unique_lock<std::shared_mutex> lock_this(handle_mutex_);
prefix_name_ = other.prefix_name_;
interface_name_ = other.interface_name_;
handle_name_ = other.handle_name_;
value_ = other.value_;
if (std::holds_alternative<std::monostate>(value_))
{
value_ptr_ = other.value_ptr_;
}
else
{
value_ptr_ = std::get_if<double>(&value_);
}
}

void swap(Handle & first, Handle & second) noexcept
{
std::unique_lock<std::shared_mutex> lock(first.handle_mutex_);
std::unique_lock<std::shared_mutex> lock_this(second.handle_mutex_);
std::swap(first.prefix_name_, second.prefix_name_);
std::swap(first.interface_name_, second.interface_name_);
std::swap(first.handle_name_, second.handle_name_);
std::swap(first.value_, second.value_);
std::swap(first.value_ptr_, second.value_ptr_);
}

protected:
std::string prefix_name_;
std::string interface_name_;
Expand Down

0 comments on commit 715ab29

Please sign in to comment.