diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2024-11-04 07:44:34 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2024-11-04 07:44:34 +0200 |
commit | 74c9269e1363e33e4b3223a029049a13e6595e7e (patch) | |
tree | 1d360d56c9f04e976e8ed5700fe0fde0a1dd420b /libbuild2 | |
parent | 95da67852e7c837592a61fb44cd8acd325d16ba2 (diff) |
Redo group_prerequisites to use snapshots of prerequisites (GH issue #408)
It turns out both target and group prerequisites can be replaced during
dependency synthesis in more obscure cases.
Diffstat (limited to 'libbuild2')
-rw-r--r-- | libbuild2/prerequisite.cxx | 4 | ||||
-rw-r--r-- | libbuild2/prerequisite.hxx | 2 | ||||
-rw-r--r-- | libbuild2/target.cxx | 2 | ||||
-rw-r--r-- | libbuild2/target.hxx | 18 | ||||
-rw-r--r-- | libbuild2/target.ixx | 60 |
5 files changed, 54 insertions, 32 deletions
diff --git a/libbuild2/prerequisite.cxx b/libbuild2/prerequisite.cxx index bb77c9e..ec18665 100644 --- a/libbuild2/prerequisite.cxx +++ b/libbuild2/prerequisite.cxx @@ -91,4 +91,8 @@ namespace build2 return r; } + + // prerequisites + // + const prerequisites empty_prerequisites; } diff --git a/libbuild2/prerequisite.hxx b/libbuild2/prerequisite.hxx index 9b9cccf..008fc11 100644 --- a/libbuild2/prerequisite.hxx +++ b/libbuild2/prerequisite.hxx @@ -190,6 +190,8 @@ namespace build2 } using prerequisites = vector<prerequisite>; + + LIBBUILD2_SYMEXPORT extern const prerequisites empty_prerequisites; } #endif // LIBBUILD2_PREREQUISITE_HXX diff --git a/libbuild2/target.cxx b/libbuild2/target.cxx index 65e18d3..b915b25 100644 --- a/libbuild2/target.cxx +++ b/libbuild2/target.cxx @@ -76,8 +76,6 @@ namespace build2 // target // - const target::prerequisites_type target::empty_prerequisites_; - target:: ~target () { diff --git a/libbuild2/target.hxx b/libbuild2/target.hxx index ae45082..1b7b755 100644 --- a/libbuild2/target.hxx +++ b/libbuild2/target.hxx @@ -733,8 +733,6 @@ namespace build2 atomic<uint8_t> prerequisites_state_ {0}; prerequisites_type prerequisites_; - static const prerequisites_type empty_prerequisites_; - // Target-specific variables. // // See also rule-specific variables below. @@ -1488,9 +1486,9 @@ namespace build2 { public: explicit - group_prerequisites (const target& t); + group_prerequisites (const target&); - group_prerequisites (const target& t, const target* g); + group_prerequisites (const target&, const target* group); using prerequisites_type = target::prerequisites_type; using base_iterator = prerequisites_type::const_iterator; @@ -1504,8 +1502,8 @@ namespace build2 using iterator_category = std::bidirectional_iterator_tag; iterator () {} - iterator (const target* t, - const target* g, + iterator (const prerequisites_type* t, + const prerequisites_type* g, const prerequisites_type* c, base_iterator i): t_ (t), g_ (g), c_ (c), i_ (i) {} @@ -1534,8 +1532,8 @@ namespace build2 operator!= (const iterator& x, const iterator& y) {return !(x == y);} private: - const target* t_ = nullptr; - const target* g_ = nullptr; + const prerequisites_type* t_ = nullptr; + const prerequisites_type* g_ = nullptr; const prerequisites_type* c_ = nullptr; base_iterator i_; }; @@ -1558,8 +1556,8 @@ namespace build2 size () const; private: - const target& t_; - const target* g_; + const prerequisites_type* t_; // NULL if empty. + const prerequisites_type* g_; // NULL if no group or empty. }; // A member of a prerequisite. If 'member' is NULL, then this is the diff --git a/libbuild2/target.ixx b/libbuild2/target.ixx index f8ee975..1dc667d 100644 --- a/libbuild2/target.ixx +++ b/libbuild2/target.ixx @@ -207,7 +207,7 @@ namespace build2 { return prerequisites_state_.load (memory_order_acquire) == 2 ? prerequisites_ - : empty_prerequisites_; + : empty_prerequisites; } inline bool target:: @@ -491,44 +491,64 @@ namespace build2 // inline group_prerequisites:: group_prerequisites (const target& t) - : t_ (t), g_ (nullptr) + : t_ (nullptr), g_ (nullptr) { - if (const target* g = t_.group) + // Take "snapshot" of prerequisites, both for target and group. + // + const auto& ps (t.prerequisites ()); + if (!ps.empty ()) + t_ = &ps; + + if (const target* g = t.group) { - if (g->adhoc_member == nullptr && // Not ad hoc group member. - !g->prerequisites ().empty ()) - g_ = g; + if (g->adhoc_member == nullptr) // Not ad hoc group member. + { + const auto& ps (g->prerequisites ()); + if (!ps.empty ()) + g_ = &ps; + } } } inline group_prerequisites:: group_prerequisites (const target& t, const target* g) - : t_ (t), - g_ (g == nullptr || - g->prerequisites ().empty () - ? nullptr : g) + : t_ (nullptr), g_ (nullptr) { + const auto& ps (t.prerequisites ()); + if (!ps.empty ()) + t_ = &ps; + + if (g != nullptr) + { + const auto& ps (g->prerequisites ()); + if (!ps.empty ()) + g_ = &ps; + } } inline auto group_prerequisites:: begin () const -> iterator { - auto& c ((g_ != nullptr ? *g_ : t_).prerequisites ()); - return iterator (&t_, g_, &c, c.begin ()); + auto* c (g_ != nullptr ? g_ : + t_ != nullptr ? t_ : + &empty_prerequisites); + return iterator (t_, g_, c, c->begin ()); } inline auto group_prerequisites:: end () const -> iterator { - auto& c (t_.prerequisites ()); - return iterator (&t_, g_, &c, c.end ()); + auto* c (t_ != nullptr ? t_ : + g_ != nullptr ? g_ : + &empty_prerequisites); + return iterator (t_, g_, c, c->end ()); } inline size_t group_prerequisites:: size () const { - return t_.prerequisites ().size () + - (g_ != nullptr ? g_->prerequisites ().size () : 0); + return ((t_ != nullptr ? t_->size () : 0) + + (g_ != nullptr ? g_->size () : 0)); } // group_prerequisites::iterator @@ -536,9 +556,9 @@ namespace build2 inline auto group_prerequisites::iterator:: operator++ () -> iterator& { - if (++i_ == c_->end () && c_ != &t_->prerequisites ()) + if (++i_ == c_->end () && c_ == g_ && t_ != nullptr) { - c_ = &t_->prerequisites (); + c_ = t_; i_ = c_->begin (); } return *this; @@ -548,9 +568,9 @@ namespace build2 inline auto group_prerequisites::iterator:: operator-- () -> iterator& { - if (i_ == c_->begin () && c_ == &t_->prerequisites ()) + if (i_ == c_->begin () && c_ == t_) { - c_ = &g_->prerequisites (); + c_ = g_; i_ = c_->end (); } |