Skip to content

Commit af66d8d

Browse files
authored
[CODE HEALTH] Fix clang-tidy warnings in nostd files (#3924)
1 parent 1b3733f commit af66d8d

6 files changed

Lines changed: 75 additions & 13 deletions

File tree

api/include/opentelemetry/nostd/function_ref.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ class function_ref<R(Args...)>
3737
void BindTo(F &f) noexcept
3838
{
3939
callable_ = static_cast<void *>(std::addressof(f));
40-
invoker_ = [](void *callable, Args... args) -> R {
40+
// Args... matches the referenced signature and is forwarded as such.
41+
// NOLINTNEXTLINE(performance-unnecessary-value-param)
42+
invoker_ = [](void *callable, Args... args) -> R {
4143
return (*static_cast<FunctionPointer<F>>(callable))(std::forward<Args>(args)...);
4244
};
4345
}
@@ -78,14 +80,21 @@ class function_ref<R(Args...)>
7880
int>::type = 0>
7981
function_ref(F &&f)
8082
{
83+
// Binding by named variable here intentionally keeps function_ref non-owning.
84+
// NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward)
8185
BindTo(f); // not forward
8286
}
8387

8488
function_ref(std::nullptr_t) {}
8589

86-
function_ref(const function_ref &) noexcept = default;
87-
function_ref(function_ref &&) noexcept = default;
90+
~function_ref() = default;
91+
function_ref(const function_ref &) noexcept = default;
92+
function_ref(function_ref &&) noexcept = default;
93+
function_ref &operator=(const function_ref &) noexcept = default;
94+
function_ref &operator=(function_ref &&) noexcept = default;
8895

96+
// Args... is part of the function signature and forwarded to invoker_.
97+
// NOLINTNEXTLINE(performance-unnecessary-value-param)
8998
R operator()(Args... args) const { return invoker_(callable_, std::forward<Args>(args)...); }
9099

91100
explicit operator bool() const { return invoker_; }

api/include/opentelemetry/nostd/shared_ptr.h

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ class shared_ptr
4747

4848
shared_ptr_wrapper(std::shared_ptr<T> &&ptr) noexcept : ptr_{std::move(ptr)} {}
4949

50+
shared_ptr_wrapper(const shared_ptr_wrapper &) = default;
51+
shared_ptr_wrapper &operator=(const shared_ptr_wrapper &) = default;
52+
shared_ptr_wrapper(shared_ptr_wrapper &&) = default;
53+
shared_ptr_wrapper &operator=(shared_ptr_wrapper &&) = default;
54+
5055
virtual ~shared_ptr_wrapper() {}
5156

5257
virtual void CopyTo(PlacementBuffer &buffer) const noexcept
@@ -98,20 +103,20 @@ class shared_ptr
98103
typename std::enable_if<std::is_convertible<U *, pointer>::value>::type * = nullptr>
99104
shared_ptr(shared_ptr<U> &&other) noexcept
100105
{
101-
other.wrapper().template MoveTo<T>(buffer_);
106+
std::move(other).wrapper().template MoveTo<T>(buffer_);
102107
}
103108

104109
shared_ptr(const shared_ptr &other) noexcept { other.wrapper().CopyTo(buffer_); }
105110

106111
shared_ptr(unique_ptr<T> &&other) noexcept
107112
{
108-
std::shared_ptr<T> ptr_(other.release());
113+
std::shared_ptr<T> ptr_(std::move(other).release());
109114
new (buffer_.data) shared_ptr_wrapper{std::move(ptr_)};
110115
}
111116

112117
shared_ptr(std::unique_ptr<T> &&other) noexcept
113118
{
114-
std::shared_ptr<T> ptr_(other.release());
119+
std::shared_ptr<T> ptr_(std::move(other).release());
115120
new (buffer_.data) shared_ptr_wrapper{std::move(ptr_)};
116121
}
117122

@@ -155,10 +160,15 @@ class shared_ptr
155160

156161
void swap(shared_ptr<T> &other) noexcept
157162
{
158-
shared_ptr<T> tmp{std::move(other)};
163+
if (this == &other)
164+
{
165+
return;
166+
}
159167

160-
wrapper().MoveTo(other.buffer_);
161-
tmp.wrapper().MoveTo(buffer_);
168+
// Swap the live wrapper objects (object-level swap), not the raw
169+
// PlacementBuffer bytes. This preserves object lifetime correctness and
170+
// avoids moving `other` as an object.
171+
std::swap(wrapper(), other.wrapper());
162172
}
163173

164174
template <typename U>

api/include/opentelemetry/nostd/span.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,14 @@ class span
165165

166166
span(const span &) noexcept = default;
167167

168+
~span() noexcept = default;
169+
170+
span(span &&) noexcept = default;
171+
168172
span &operator=(const span &) noexcept = default;
169173

174+
span &operator=(span &&) noexcept = default;
175+
170176
bool empty() const noexcept { return Extent == 0; }
171177

172178
T *data() const noexcept { return data_; }
@@ -247,8 +253,14 @@ class span<T, dynamic_extent>
247253

248254
span(const span &) noexcept = default;
249255

256+
~span() noexcept = default;
257+
258+
span(span &&) noexcept = default;
259+
250260
span &operator=(const span &) noexcept = default;
251261

262+
span &operator=(span &&) noexcept = default;
263+
252264
bool empty() const noexcept { return extent_ == 0; }
253265

254266
T *data() const noexcept { return data_; }

api/include/opentelemetry/nostd/unique_ptr.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,17 @@ class unique_ptr
5656

5757
unique_ptr(unique_ptr &&other) noexcept : ptr_{other.release()} {}
5858

59+
unique_ptr(const unique_ptr &) = delete;
60+
unique_ptr &operator=(const unique_ptr &) = delete;
61+
5962
template <class U,
6063
typename std::enable_if<std::is_convertible<U *, pointer>::value>::type * = nullptr>
61-
unique_ptr(unique_ptr<U> &&other) noexcept : ptr_{other.release()}
64+
unique_ptr(unique_ptr<U> &&other) noexcept : ptr_{std::move(other).release()}
6265
{}
6366

6467
template <class U,
6568
typename std::enable_if<std::is_convertible<U *, pointer>::value>::type * = nullptr>
66-
unique_ptr(std::unique_ptr<U> &&other) noexcept : ptr_{other.release()}
69+
unique_ptr(std::unique_ptr<U> &&other) noexcept : ptr_{std::move(other).release()}
6770
{}
6871

6972
~unique_ptr() { reset(); }
@@ -84,15 +87,15 @@ class unique_ptr
8487
typename std::enable_if<std::is_convertible<U *, pointer>::value>::type * = nullptr>
8588
unique_ptr &operator=(unique_ptr<U> &&other) noexcept
8689
{
87-
reset(other.release());
90+
reset(std::move(other).release());
8891
return *this;
8992
}
9093

9194
template <class U,
9295
typename std::enable_if<std::is_convertible<U *, pointer>::value>::type * = nullptr>
9396
unique_ptr &operator=(std::unique_ptr<U> &&other) noexcept
9497
{
95-
reset(other.release());
98+
reset(std::move(other).release());
9699
return *this;
97100
}
98101

api/include/opentelemetry/nostd/variant.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ OPENTELEMETRY_END_NAMESPACE
5151

5252
# include "opentelemetry/nostd/internal/absl/base/options.h"
5353

54+
// Forward declarations needed by the local Abseil snapshot bridge.
55+
// NOLINTBEGIN(abseil-no-namespace)
5456
namespace absl
5557
{
5658
namespace OTABSL_OPTION_NAMESPACE_NAME
@@ -61,6 +63,7 @@ template <typename... Ts>
6163
class variant;
6264
} // namespace OTABSL_OPTION_NAMESPACE_NAME
6365
} // namespace absl
66+
// NOLINTEND(abseil-no-namespace)
6467

6568
# include "opentelemetry/nostd/internal/absl/types/variant.h"
6669

api/test/nostd/shared_ptr_test.cc

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,31 @@ TEST(SharedPtrTest, Swap)
166166
EXPECT_EQ(ptr2.get(), value1);
167167
}
168168

169+
TEST(SharedPtrTest, SwapSelfNoOp)
170+
{
171+
struct TestStruct
172+
{
173+
explicit TestStruct(int &destruct_count) noexcept : destruct_count_{&destruct_count} {}
174+
175+
~TestStruct() { ++(*destruct_count_); }
176+
177+
int *destruct_count_;
178+
};
179+
180+
int destruct_count{0};
181+
182+
{
183+
shared_ptr<TestStruct> ptr{std::make_shared<TestStruct>(destruct_count)};
184+
auto *ptr_before = ptr.get();
185+
186+
ptr.swap(ptr);
187+
188+
EXPECT_EQ(ptr.get(), ptr_before);
189+
}
190+
191+
EXPECT_EQ(destruct_count, 1);
192+
}
193+
169194
TEST(SharedPtrTest, Comparison)
170195
{
171196
shared_ptr<int> ptr1{new int{123}};

0 commit comments

Comments
 (0)