From 9891b20350021ce41a950645dd76df20a45c92cc Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 2 Dec 2015 11:37:15 +0200 Subject: Implement optional module loading The syntax is: using? cli Now each module use results in two bool variables: .loaded and .configured. Also implement variable visibility (the above two variables are limited to project). --- build/variable | 82 +++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 21 deletions(-) (limited to 'build/variable') diff --git a/build/variable b/build/variable index 7976ab9..061004c 100644 --- a/build/variable +++ b/build/variable @@ -7,10 +7,8 @@ #include #include -#include #include // nullptr_t -#include // move(), pair, make_pair() -#include +#include // pair, make_pair() #include #include // hash, reference_wrapper #include // conditional, is_reference, remove_reference, etc. @@ -19,6 +17,8 @@ #include #include +#include + #include namespace build @@ -37,19 +37,23 @@ namespace build bool (*const append) (names&, names, const variable&); }; + enum class variable_visibility + { + scope, // This scope (no outer scopes). + project, // This project (no outer projects). + normal // All outer scopes. + }; + // variable // // The two variables are considered the same if they have the same name. // struct variable { - explicit - variable (std::string n, const value_type* t = nullptr, char p = '\0') - : name (std::move (n)), pairs (p), type (t) {} - std::string name; - char pairs; - const value_type* type; // If NULL, then not (yet) typed. + const value_type* type; // If NULL, then not (yet) typed. + variable_visibility visibility; + char pairs; // Pair symbold or '\0' if not used. }; inline bool @@ -616,13 +620,40 @@ namespace build { // variable_pool // - using variable_set_base = std::unordered_set; - struct variable_set: private variable_set_base + using variable_pool_base = std::unordered_set; + struct variable_pool: private variable_pool_base { const variable& - find (std::string name, const build::value_type* t = nullptr, char p = '\0') + find (string name, const build::value_type* t = nullptr, char p = '\0') { - auto r (emplace (std::move (name), t, p)); + return find (name, nullptr, t, p); + } + + const variable& + find (string name, + variable_visibility v, + const build::value_type* t = nullptr, + char p = '\0') + { + return find (name, &v, t, p); + } + + using variable_pool_base::clear; + + private: + const variable& + find (string name, + const variable_visibility* vv, + const build::value_type* t, + char p) + { + auto r ( + insert ( + variable { + std::move (name), + t, + vv != nullptr ? *vv : variable_visibility::normal, + p})); const variable& v (*r.first); // Update type? @@ -630,16 +661,25 @@ namespace build if (!r.second && t != nullptr && v.type != t) { assert (v.type == nullptr); - const_cast (v).type = t; // Ok, not changing the key. + const_cast (v).type = t; // Not changing the key. + } + + // Change visibility? While this might at first seem like a bad idea, + // it can happen that the variable lookup happens before any values + // were set, in which case the variable will be entered with the + // default visibility. + // + if (!r.second && vv != nullptr && v.visibility != *vv) + { + assert (v.visibility == variable_visibility::normal); // Default. + const_cast (v).visibility = *vv; // Not changing the key. } return v; } - - using variable_set_base::clear; }; - extern variable_set variable_pool; + extern variable_pool var_pool; // variable_map // @@ -696,7 +736,7 @@ namespace build lookup operator[] (const std::string& name) const { - return operator[] (variable_pool.find (name)); + return operator[] (var_pool.find (name)); } // Non-const lookup. Only exposed on the map directly. @@ -710,7 +750,7 @@ namespace build lookup operator[] (const std::string& name) { - return operator[] (variable_pool.find (name)); + return operator[] (var_pool.find (name)); } // The second member in the pair indicates whether the new @@ -733,13 +773,13 @@ namespace build std::pair, bool> assign (const std::string& name) { - return assign (variable_pool.find (name)); + return assign (var_pool.find (name)); } std::pair find_namespace (const std::string& ns) const { - auto r (m_.find_prefix (variable_pool.find (ns))); + auto r (m_.find_prefix (var_pool.find (ns))); return std::make_pair (const_iterator (r.first), const_iterator (r.second)); } -- cgit v1.1