From b3b14171766089890b9e1b44935ed5dbc233c5f8 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Tue, 13 Dec 2022 22:03:02 +0300 Subject: Add noexcept to move constructors and move assignment operators --- libbuild2/algorithm.hxx | 4 ++-- libbuild2/algorithm.ixx | 4 ++-- libbuild2/cc/pkgconfig.hxx | 8 ++++---- libbuild2/context.hxx | 4 ++-- libbuild2/context.ixx | 4 ++-- libbuild2/file-cache.hxx | 8 ++++---- libbuild2/file-cache.ixx | 8 ++++---- libbuild2/parser.cxx | 12 ++++++------ libbuild2/prerequisite.hxx | 10 ++++++++-- libbuild2/scheduler.hxx | 20 ++++++++++++++------ libbuild2/script/parser.cxx | 2 +- libbuild2/script/parser.hxx | 2 +- libbuild2/script/regex.hxx | 12 ++++++------ libbuild2/target-type.hxx | 2 +- libbuild2/types.hxx | 4 ++-- libbuild2/types.ixx | 4 ++-- libbuild2/variable.cxx | 4 +++- libbuild2/variable.hxx | 12 +++++++++--- 18 files changed, 73 insertions(+), 51 deletions(-) diff --git a/libbuild2/algorithm.hxx b/libbuild2/algorithm.hxx index 9a6a56b..aa0ec44 100644 --- a/libbuild2/algorithm.hxx +++ b/libbuild2/algorithm.hxx @@ -203,8 +203,8 @@ namespace build2 // Movable-only type with move-assignment only to NULL lock. // target_lock () = default; - target_lock (target_lock&&); - target_lock& operator= (target_lock&&); + target_lock (target_lock&&) noexcept; + target_lock& operator= (target_lock&&) noexcept; target_lock (const target_lock&) = delete; target_lock& operator= (const target_lock&) = delete; diff --git a/libbuild2/algorithm.ixx b/libbuild2/algorithm.ixx index 3c6c2fa..b87a535 100644 --- a/libbuild2/algorithm.ixx +++ b/libbuild2/algorithm.ixx @@ -284,7 +284,7 @@ namespace build2 } inline target_lock:: - target_lock (target_lock&& x) + target_lock (target_lock&& x) noexcept : action (x.action), target (x.target), offset (x.offset) { if (target != nullptr) @@ -304,7 +304,7 @@ namespace build2 } inline target_lock& target_lock:: - operator= (target_lock&& x) + operator= (target_lock&& x) noexcept { if (this != &x) { diff --git a/libbuild2/cc/pkgconfig.hxx b/libbuild2/cc/pkgconfig.hxx index 7959da1..a1bcdee 100644 --- a/libbuild2/cc/pkgconfig.hxx +++ b/libbuild2/cc/pkgconfig.hxx @@ -56,8 +56,8 @@ namespace build2 // Movable-only type. // - pkgconfig (pkgconfig&&); - pkgconfig& operator= (pkgconfig&&); + pkgconfig (pkgconfig&&) noexcept; + pkgconfig& operator= (pkgconfig&&) noexcept; pkgconfig (const pkgconfig&) = delete; pkgconfig& operator= (const pkgconfig&) = delete; @@ -95,7 +95,7 @@ namespace build2 } inline pkgconfig:: - pkgconfig (pkgconfig&& p) + pkgconfig (pkgconfig&& p) noexcept : path (move (p.path)), client_ (p.client_), pkg_ (p.pkg_) @@ -105,7 +105,7 @@ namespace build2 } inline pkgconfig& pkgconfig:: - operator= (pkgconfig&& p) + operator= (pkgconfig&& p) noexcept { if (this != &p) { diff --git a/libbuild2/context.hxx b/libbuild2/context.hxx index 27c3cc0..bb8f31f 100644 --- a/libbuild2/context.hxx +++ b/libbuild2/context.hxx @@ -834,8 +834,8 @@ namespace build2 // Note: move-assignable to empty only. // - wait_guard (wait_guard&&); - wait_guard& operator= (wait_guard&&); + wait_guard (wait_guard&&) noexcept; + wait_guard& operator= (wait_guard&&) noexcept; wait_guard (const wait_guard&) = delete; wait_guard& operator= (const wait_guard&) = delete; diff --git a/libbuild2/context.ixx b/libbuild2/context.ixx index 4f86c28..95c5416 100644 --- a/libbuild2/context.ixx +++ b/libbuild2/context.ixx @@ -31,7 +31,7 @@ namespace build2 } inline wait_guard:: - wait_guard (wait_guard&& x) + wait_guard (wait_guard&& x) noexcept : ctx (x.ctx), start_count (x.start_count), task_count (x.task_count), @@ -41,7 +41,7 @@ namespace build2 } inline wait_guard& wait_guard:: - operator= (wait_guard&& x) + operator= (wait_guard&& x) noexcept { if (&x != this) { diff --git a/libbuild2/file-cache.hxx b/libbuild2/file-cache.hxx index e31517e..98c2b67 100644 --- a/libbuild2/file-cache.hxx +++ b/libbuild2/file-cache.hxx @@ -119,9 +119,9 @@ namespace build2 // Move-to-NULL-only type. // - write (write&&); + write (write&&) noexcept; write (const write&) = delete; - write& operator= (write&&); + write& operator= (write&&) noexcept; write& operator= (const write&) = delete; ~write (); @@ -145,9 +145,9 @@ namespace build2 // Move-to-NULL-only type. // - read (read&&); + read (read&&) noexcept; read (const read&) = delete; - read& operator= (read&&); + read& operator= (read&&) noexcept; read& operator= (const read&) = delete; ~read (); diff --git a/libbuild2/file-cache.ixx b/libbuild2/file-cache.ixx index 026f3fd..99be5ad 100644 --- a/libbuild2/file-cache.ixx +++ b/libbuild2/file-cache.ixx @@ -109,14 +109,14 @@ namespace build2 } inline file_cache::write:: - write (write&& e) + write (write&& e) noexcept : entry_ (e.entry_) { e.entry_ = nullptr; } inline file_cache::write& file_cache::write:: - operator= (write&& e) + operator= (write&& e) noexcept { if (this != &e) { @@ -136,14 +136,14 @@ namespace build2 } inline file_cache::read:: - read (read&& e) + read (read&& e) noexcept : entry_ (e.entry_) { e.entry_ = nullptr; } inline file_cache::read& file_cache::read:: - operator= (read&& e) + operator= (read&& e) noexcept { if (this != &e) { diff --git a/libbuild2/parser.cxx b/libbuild2/parser.cxx index 2507a02..5128979 100644 --- a/libbuild2/parser.cxx +++ b/libbuild2/parser.cxx @@ -88,8 +88,8 @@ namespace build2 // Note: move-assignable to empty only. // - enter_scope (enter_scope&& x) {*this = move (x);} - enter_scope& operator= (enter_scope&& x) + enter_scope (enter_scope&& x) noexcept {*this = move (x);} + enter_scope& operator= (enter_scope&& x) noexcept { if (this != &x) { @@ -208,8 +208,8 @@ namespace build2 // Note: move-assignable to empty only. // - enter_target (enter_target&& x) {*this = move (x);} - enter_target& operator= (enter_target&& x) { + enter_target (enter_target&& x) noexcept {*this = move (x);} + enter_target& operator= (enter_target&& x) noexcept { p_ = x.p_; t_ = x.t_; x.p_ = nullptr; return *this;} enter_target (const enter_target&) = delete; @@ -240,8 +240,8 @@ namespace build2 // Note: move-assignable to empty only. // - enter_prerequisite (enter_prerequisite&& x) {*this = move (x);} - enter_prerequisite& operator= (enter_prerequisite&& x) { + enter_prerequisite (enter_prerequisite&& x) noexcept {*this = move (x);} + enter_prerequisite& operator= (enter_prerequisite&& x) noexcept { p_ = x.p_; r_ = x.r_; x.p_ = nullptr; return *this;} enter_prerequisite (const enter_prerequisite&) = delete; diff --git a/libbuild2/prerequisite.hxx b/libbuild2/prerequisite.hxx index 33efed0..2f63056 100644 --- a/libbuild2/prerequisite.hxx +++ b/libbuild2/prerequisite.hxx @@ -63,6 +63,8 @@ namespace build2 // Note that the lookup is often ad hoc (see bin.whole as an example). // But see also parser::lookup_variable() if adding something here. // + // @@ PERF: redo as vector so can make move constructor noexcept. + // public: variable_map vars; @@ -138,7 +140,10 @@ namespace build2 is_a (const target_type_type& tt) const {return type.is_a (tt);} public: - prerequisite (prerequisite&& x) + // Note that we have the noexcept specification even though vars + // (std::map) could potentially throw. + // + prerequisite (prerequisite&& x) noexcept : proj (move (x.proj)), type (x.type), dir (move (x.dir)), @@ -147,7 +152,8 @@ namespace build2 ext (move (x.ext)), scope (x.scope), target (x.target.load (memory_order_relaxed)), - vars (move (x.vars), *this, false /* shared */) {} + vars (move (x.vars), *this, false /* shared */) + {} prerequisite (const prerequisite& x, memory_order o = memory_order_consume) : proj (x.proj), diff --git a/libbuild2/scheduler.hxx b/libbuild2/scheduler.hxx index dc18859..c34d41b 100644 --- a/libbuild2/scheduler.hxx +++ b/libbuild2/scheduler.hxx @@ -247,8 +247,12 @@ namespace build2 alloc_guard (): n (0), s_ (nullptr) {} alloc_guard (scheduler& s, size_t m): n (s.allocate (m)), s_ (&s) {} - alloc_guard (alloc_guard&& x): n (x.n), s_ (x.s_) {x.s_ = nullptr;} - alloc_guard& operator= (alloc_guard&& x) + + alloc_guard (alloc_guard&& x) noexcept + : n (x.n), s_ (x.s_) {x.s_ = nullptr;} + + alloc_guard& + operator= (alloc_guard&& x) noexcept { if (&x != this) { @@ -357,8 +361,12 @@ namespace build2 { tune_guard (): s_ (nullptr), o_ (0) {} tune_guard (scheduler& s, size_t ma): s_ (&s), o_ (s_->tune (ma)) {} - tune_guard (tune_guard&& x): s_ (x.s_), o_ (x.o_) {x.s_ = nullptr;} - tune_guard& operator= (tune_guard&& x) + + tune_guard (tune_guard&& x) noexcept + : s_ (x.s_), o_ (x.o_) {x.s_ = nullptr;} + + tune_guard& + operator= (tune_guard&& x) noexcept { if (&x != this) { @@ -426,8 +434,8 @@ namespace build2 { explicit monitor_guard (scheduler* s = nullptr): s_ (s) {} - monitor_guard (monitor_guard&& x): s_ (x.s_) {x.s_ = nullptr;} - monitor_guard& operator= (monitor_guard&& x) + monitor_guard (monitor_guard&& x) noexcept: s_ (x.s_) {x.s_ = nullptr;} + monitor_guard& operator= (monitor_guard&& x) noexcept { if (&x != this) { diff --git a/libbuild2/script/parser.cxx b/libbuild2/script/parser.cxx index 0be22a6..ae6da76 100644 --- a/libbuild2/script/parser.cxx +++ b/libbuild2/script/parser.cxx @@ -2763,7 +2763,7 @@ namespace build2 } parser::parsed_doc:: - parsed_doc (parsed_doc&& d) + parsed_doc (parsed_doc&& d) noexcept : re (d.re), end_line (d.end_line), end_column (d.end_column) { if (re) diff --git a/libbuild2/script/parser.hxx b/libbuild2/script/parser.hxx index 91f50bf..cadf909 100644 --- a/libbuild2/script/parser.hxx +++ b/libbuild2/script/parser.hxx @@ -140,7 +140,7 @@ namespace build2 parsed_doc (string, uint64_t line, uint64_t column); parsed_doc (regex_lines&&, uint64_t line, uint64_t column); - parsed_doc (parsed_doc&&); // Note: move constuctible-only type. + parsed_doc (parsed_doc&&) noexcept; // Note: move constuctible-only type. ~parsed_doc (); }; diff --git a/libbuild2/script/regex.hxx b/libbuild2/script/regex.hxx index f6cf566..3c49b31 100644 --- a/libbuild2/script/regex.hxx +++ b/libbuild2/script/regex.hxx @@ -271,8 +271,8 @@ namespace build2 template struct line_char_cmp : public std::enable_if::value || - (std::is_enum::value && - !std::is_same::value)> {}; + (std::is_enum::value && + !std::is_same::value)> {}; template ::type> bool @@ -470,10 +470,10 @@ namespace std is (mask m, char_type c) const { return m == - (c.type () == line_type::special && c.special () >= 0 && - build2::digit (static_cast (c.special ())) - ? digit - : 0); + (c.type () == line_type::special && c.special () >= 0 && + build2::digit (static_cast (c.special ())) + ? digit + : 0); } const char_type* diff --git a/libbuild2/target-type.hxx b/libbuild2/target-type.hxx index eae2caf..16f07fa 100644 --- a/libbuild2/target-type.hxx +++ b/libbuild2/target-type.hxx @@ -248,7 +248,7 @@ namespace build2 target_type_ref (unique_ptr&& p) : p_ (p.release ()), d_ (true) {} - target_type_ref (target_type_ref&& r) + target_type_ref (target_type_ref&& r) noexcept : p_ (r.p_), d_ (r.d_) {r.p_ = nullptr;} ~target_type_ref () {if (p_ != nullptr && d_) delete p_;} diff --git a/libbuild2/types.hxx b/libbuild2/types.hxx index bf412a3..20b10de 100644 --- a/libbuild2/types.hxx +++ b/libbuild2/types.hxx @@ -511,9 +511,9 @@ namespace build2 location_value (const location&); - location_value (location_value&&); + location_value (location_value&&) noexcept; location_value (const location_value&); - location_value& operator= (location_value&&); + location_value& operator= (location_value&&) noexcept; location_value& operator= (const location_value&); }; diff --git a/libbuild2/types.ixx b/libbuild2/types.ixx index 750c8c7..bf44cff 100644 --- a/libbuild2/types.ixx +++ b/libbuild2/types.ixx @@ -43,7 +43,7 @@ namespace build2 } inline location_value:: - location_value (location_value&& l) + location_value (location_value&& l) noexcept : location (l.line, l.column), file (std::move (l.file)) { @@ -58,7 +58,7 @@ namespace build2 } inline location_value& location_value:: - operator= (location_value&& l) + operator= (location_value&& l) noexcept { if (this != &l) { diff --git a/libbuild2/variable.cxx b/libbuild2/variable.cxx index fefea98..260d664 100644 --- a/libbuild2/variable.cxx +++ b/libbuild2/variable.cxx @@ -47,7 +47,7 @@ namespace build2 } value:: - value (value&& v) + value (value&& v) noexcept : type (v.type), null (v.null), extra (v.extra) { if (!null) @@ -99,6 +99,8 @@ namespace build2 if (null) new (&data_) names (move (v).as ()); else + // Note: can throw (see small_vector for details). + // as () = move (v).as (); } else if (auto f = null ? type->copy_ctor : type->copy_assign) diff --git a/libbuild2/variable.hxx b/libbuild2/variable.hxx index 2942f1c..8a0adf8 100644 --- a/libbuild2/variable.hxx +++ b/libbuild2/variable.hxx @@ -358,9 +358,13 @@ namespace build2 value& operator= (nullptr_t) {if (!null) reset (); return *this;} - value (value&&); + // Note that we have the noexcept specification even though copy_ctor() + // could potentially throw (for example, for std::map). + // + value (value&&) noexcept; + explicit value (const value&); - value& operator= (value&&); + value& operator= (value&&); // Note: can throw for untyped RHS. value& operator= (const value&); value& operator= (reference_wrapper); value& operator= (reference_wrapper); @@ -1859,7 +1863,7 @@ namespace build2 variable_map (const variable_map&, const prerequisite&, bool shared = false); variable_map& - operator= (variable_map&& v) {m_ = move (v.m_); return *this;} + operator= (variable_map&& v) noexcept {m_ = move (v.m_); return *this;} variable_map& operator= (const variable_map& v) {m_ = v.m_; return *this;} @@ -1870,6 +1874,8 @@ namespace build2 variable_map (context& c, bool shared) : shared_ (shared), owner_ (owner::context), ctx (&c) {} + // Note: std::map's move constructor can throw. + // variable_map (variable_map&& v) : shared_ (v.shared_), owner_ (v.owner_), ctx (v.ctx), m_ (move (v.m_)) { -- cgit v1.1