Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explicit definition of all ctrs, operator= and dstrs #515

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions eventuals/builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ class Field;
template <typename Value_>
class Field<Value_, false> {
public:
Field() = default;

Field(const Field&) = default;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are some copy / move operations noexcept and others are not? I'd expect noexcept use to be consistent here: please document.

Glancing at code snippets below, I'd expect us to use noexcept everywhere we can.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we have noexcept on copy operations (unless I made a typo?).

https://clang.llvm.org/extra/clang-tidy/checks/performance/noexcept-move-constructor.html

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we have noexcept on copy operations (unless I made a typo?).

Why don't we have noexcept on our copy operations? Can our copy operations throw exceptions in a way that our move operation can't?

If not, it seems like our copy operations should also be noexcept.

Field(Field&&) noexcept = default;

Field& operator=(const Field&) = default;
Field& operator=(Field&&) noexcept = default;

virtual ~Field() = default;

template <typename... Args>
Expand All @@ -33,6 +41,12 @@ class Field<Value_, true> {
Field(Value_ value)
: value_(std::move(value)) {}

Field(const Field&) = default;
Field(Field&&) noexcept = default;

Field& operator=(const Field&) = default;
Field& operator=(Field&&) noexcept = default;

virtual ~Field() = default;

auto& value() & {
Expand Down Expand Up @@ -77,8 +91,12 @@ class FieldWithDefault<Value_, false> final : public Field<Value_, false> {
FieldWithDefault(Value&& value)
: default_(std::forward<Value>(value)) {}

FieldWithDefault(const FieldWithDefault&) = delete;
FieldWithDefault(FieldWithDefault&&) noexcept = default;

FieldWithDefault& operator=(const FieldWithDefault&) = delete;
FieldWithDefault& operator=(FieldWithDefault&&) noexcept = delete;

~FieldWithDefault() override = default;

template <typename... Args>
Expand Down Expand Up @@ -124,8 +142,12 @@ class FieldWithDefault<Value_, true> final : public Field<Value_, true> {
FieldWithDefault(Value&& value)
: Field<Value_, true>(std::forward<Value>(value)) {}

FieldWithDefault(const FieldWithDefault&) = delete;
FieldWithDefault(FieldWithDefault&&) noexcept = default;

FieldWithDefault& operator=(const FieldWithDefault&) = delete;
FieldWithDefault& operator=(FieldWithDefault&&) noexcept = delete;

~FieldWithDefault() override = default;
};

Expand All @@ -143,8 +165,12 @@ class RepeatedField<Value_, false> final : public Field<Value_, false> {
RepeatedField(Value&& value)
: default_(std::forward<Value>(value)) {}

RepeatedField(const RepeatedField&) = delete;
RepeatedField(RepeatedField&&) noexcept = default;

RepeatedField& operator=(const RepeatedField&) = delete;
RepeatedField& operator=(RepeatedField&&) noexcept = delete;

~RepeatedField() override = default;

template <typename... Args>
Expand Down Expand Up @@ -190,8 +216,12 @@ class RepeatedField<Value_, true> final : public Field<Value_, true> {
RepeatedField(Value&& value)
: Field<Value_, true>(std::forward<Value>(value)) {}

RepeatedField(const RepeatedField&) = delete;
RepeatedField(RepeatedField&&) noexcept = default;

RepeatedField& operator=(const RepeatedField&) = delete;
RepeatedField& operator=(RepeatedField&&) noexcept = delete;

~RepeatedField() override = default;

template <typename... Args>
Expand All @@ -205,6 +235,14 @@ class RepeatedField<Value_, true> final : public Field<Value_, true> {

class Builder {
public:
Builder() = default;

Builder(const Builder&) = default;
Builder(Builder&&) noexcept = default;

Builder& operator=(const Builder&) = default;
Builder& operator=(Builder&&) noexcept = default;

virtual ~Builder() = default;

protected:
Expand Down
35 changes: 26 additions & 9 deletions eventuals/callback.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,18 @@ struct Callback<R(Args...)> final {
this->operator=(std::move(f));
}

Callback(const Callback&) = delete;

Callback(Callback&& that) noexcept {
if (that.base_ != nullptr) {
base_ = that.base_->Move(&storage_);

// Set 'base_' to nullptr so we only destruct once.
that.base_ = nullptr;
}
}

Callback& operator=(const Callback&) = delete;
Callback& operator=(Callback&& that) noexcept {
if (this == &that) {
return *this;
Expand Down Expand Up @@ -77,15 +89,6 @@ struct Callback<R(Args...)> final {
return *this;
}

Callback(Callback&& that) noexcept {
if (that.base_ != nullptr) {
base_ = that.base_->Move(&storage_);

// Set 'base_' to nullptr so we only destruct once.
that.base_ = nullptr;
}
}

~Callback() {
if (base_ != nullptr) {
base_->~Base();
Expand All @@ -102,6 +105,14 @@ struct Callback<R(Args...)> final {
}

struct Base {
Base() = default;

Base(const Base&) = default;
Base(Base&&) noexcept = default;

Base& operator=(const Base&) = default;
Base& operator=(Base&&) noexcept = default;

virtual ~Base() = default;

virtual R Invoke(Args... args) = 0;
Expand All @@ -114,6 +125,12 @@ struct Callback<R(Args...)> final {
Handler(F f)
: f_(std::move(f)) {}

Handler(const Handler&) = default;
Handler(Handler&&) noexcept = default;

Handler& operator=(const Handler&) = default;
Handler& operator=(Handler&&) noexcept = default;

~Handler() override = default;

R Invoke(Args... args) override {
Expand Down
10 changes: 10 additions & 0 deletions eventuals/concurrent-ordered.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ struct _ReorderAdaptor final {
Continuation(K_ k)
: k_(std::move(k)) {}

Continuation(const Continuation&) = delete;
Continuation(Continuation&& that) noexcept = default;

Continuation& operator=(const Continuation&) = delete;
Continuation& operator=(Continuation&&) noexcept = delete;

~Continuation() override = default;

void Begin(TypeErasedStream& stream) {
Expand Down Expand Up @@ -150,6 +154,12 @@ struct _ConcurrentOrderedAdaptor final {
Continuation(K_ k)
: k_(std::move(k)) {}

Continuation(const Continuation&) = default;
Continuation(Continuation&&) noexcept = default;

Continuation& operator=(const Continuation&) = default;
Continuation& operator=(Continuation&&) noexcept = default;

~Continuation() override = default;

void Begin(TypeErasedStream& stream) {
Expand Down
27 changes: 25 additions & 2 deletions eventuals/concurrent.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,20 @@ struct _Concurrent final {
// that have completed but haven't yet been pruned (see
// 'CreateOrReuseFiber()').
struct TypeErasedFiber {
TypeErasedFiber() = default;

// Constructors and assignment operators are deleted, because
// 'Interrupt' class has std::atomic (which is not copyable/moveable),
// and doesn't provide its own copy/move constructors/assignment
// operators.
TypeErasedFiber(const TypeErasedFiber&) = delete;
TypeErasedFiber(TypeErasedFiber&&) noexcept = delete;

TypeErasedFiber& operator=(const TypeErasedFiber&) = delete;
TypeErasedFiber& operator=(TypeErasedFiber&&) = delete;

virtual ~TypeErasedFiber() = default;

void Reuse() {
done = false;
// Need to reinitialize the interrupt so that the
Expand All @@ -79,8 +93,6 @@ struct _Concurrent final {
new (&interrupt) class Interrupt();
}

virtual ~TypeErasedFiber() = default;

// A fiber indicates it is done with this boolean.
bool done = false;

Expand Down Expand Up @@ -432,6 +444,12 @@ struct _Concurrent final {
Adaptor(F_ f)
: f_(std::move(f)) {}

Adaptor(const Adaptor&) = default;
Adaptor(Adaptor&&) noexcept = default;

Adaptor& operator=(const Adaptor&) = default;
Adaptor& operator=(Adaptor&&) noexcept = default;

~Adaptor() override = default;

// Our typeful fiber includes the continuation 'K' that we'll
Expand Down Expand Up @@ -585,11 +603,16 @@ struct _Concurrent final {
: adaptor_(std::move(f)),
k_(std::move(k)) {}

Continuation(const Continuation&) = delete;

// NOTE: explicit move-constructor because of 'std::atomic_flag'.
Continuation(Continuation&& that) noexcept
: adaptor_(std::move(that.adaptor_.f_)),
k_(std::move(that.k_)) {}

Continuation& operator=(const Continuation&) = delete;
Continuation& operator=(Continuation&&) noexcept = delete;

~Continuation() override = default;

void Begin(TypeErasedStream& stream) {
Expand Down
14 changes: 14 additions & 0 deletions eventuals/do-all.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,20 @@ struct _DoAll final {
: k_(k),
interrupt_(interrupt) {}

Adaptor(const Adaptor&) = delete;

Adaptor(Adaptor&& that) noexcept
: k_(that.k_),
interrupt_(that.interrupt_) {
CHECK(that.counter_.load() == sizeof...(Eventuals_))
<< "moving after starting is illegal";
}

Adaptor& operator=(const Adaptor&) = delete;
Adaptor& operator=(Adaptor&&) noexcept = delete;

~Adaptor() = default;

K_& k_;
Interrupt& interrupt_;

Expand Down Expand Up @@ -190,13 +197,20 @@ struct _DoAll final {
: eventuals_(std::move(eventuals)),
k_(std::move(k)) {}

Continuation(const Continuation&) = delete;

Continuation(Continuation&& that) noexcept
: eventuals_(std::move(that.eventuals_)),
adaptor_(std::move(that.adaptor_)),
ks_(std::move(that.ks_)),
handler_(std::move(that.handler_)),
k_(std::move(that.k_)) {}

Continuation& operator=(const Continuation&) = delete;
Continuation& operator=(Continuation&&) noexcept = delete;

~Continuation() = default;

template <typename... Args>
void Start(Args&&...) {
adaptor_.emplace(k_, interrupt_);
Expand Down
31 changes: 29 additions & 2 deletions eventuals/event-loop.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,17 @@ class EventLoop final : public Scheduler {

class Clock final : public stout::enable_borrowable_from_this<Clock> {
public:
Clock(const Clock&) = delete;

Clock(EventLoop& loop)
: loop_(loop) {}

Clock(const Clock&) = delete;
Clock(Clock&&) noexcept = delete;

Clock& operator=(const Clock&) = delete;
Clock& operator=(Clock&&) noexcept = delete;

~Clock() override = default;

std::chrono::nanoseconds Now();

auto Timer(std::chrono::nanoseconds nanoseconds);
Expand Down Expand Up @@ -204,6 +210,8 @@ class EventLoop final : public Scheduler {
interrupt_context_(&clock_->loop(), "Timer (interrupt)"),
k_(std::move(k)) {}

Continuation(const Continuation&) = delete;

Continuation(Continuation&& that) noexcept
: clock_(std::move(that.clock_)),
nanoseconds_(std::move(that.nanoseconds_)),
Expand All @@ -214,6 +222,9 @@ class EventLoop final : public Scheduler {
CHECK(!handler_);
}

Continuation& operator=(const Continuation&) = delete;
Continuation& operator=(Continuation&&) noexcept = delete;

~Continuation() {
CHECK(!started_ || closed_);
}
Expand Down Expand Up @@ -462,7 +473,13 @@ class EventLoop final : public Scheduler {
static void ConstructDefaultAndRunForeverDetached();

EventLoop();

EventLoop(const EventLoop&) = delete;
EventLoop(EventLoop&&) noexcept = delete;

EventLoop& operator=(const EventLoop&) = delete;
EventLoop& operator=(EventLoop&&) noexcept = delete;

~EventLoop() override;

void RunForever();
Expand Down Expand Up @@ -555,6 +572,8 @@ class EventLoop final : public Scheduler {
interrupt_context_(&loop, "WaitForSignal (interrupt)"),
k_(std::move(k)) {}

Continuation(const Continuation&) = delete;

Continuation(Continuation&& that) noexcept
: loop_(that.loop_),
signum_(that.signum_),
Expand All @@ -565,6 +584,9 @@ class EventLoop final : public Scheduler {
CHECK(!handler_);
}

Continuation& operator=(const Continuation&) = delete;
Continuation& operator=(Continuation&&) noexcept = delete;

~Continuation() {
CHECK(!started_ || closed_);
}
Expand Down Expand Up @@ -775,6 +797,8 @@ class EventLoop final : public Scheduler {
interrupt_context_(&loop, "Poll (interrupt)"),
k_(std::move(k)) {}

Continuation(const Continuation&) = delete;

Continuation(Continuation&& that) noexcept
: loop_(that.loop_),
fd_(that.fd_),
Expand All @@ -786,6 +810,9 @@ class EventLoop final : public Scheduler {
CHECK(!handler_);
}

Continuation& operator=(const Continuation&) = delete;
Continuation& operator=(Continuation&&) noexcept = delete;

~Continuation() {
CHECK(!started_ || closed_);
}
Expand Down
5 changes: 5 additions & 0 deletions eventuals/eventual.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,11 @@ struct _Eventual {
stop_(std::move(stop)),
k_(std::move(k)) {}

Continuation(const Continuation&) = delete;
Continuation(Continuation&& that) noexcept = default;

Continuation& operator=(const Continuation&) = delete;

Continuation& operator=(Continuation&& that) noexcept {
if (this == &that) {
return *this;
Expand All @@ -97,6 +100,8 @@ struct _Eventual {
return *this;
}

~Continuation() = default;

template <typename... Args>
void Start(Args&&... args) {
static_assert(
Expand Down
Loading