From 7eed858cac7e8ff78626bdc5d63a7f36ca8f8010 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 4 Mar 2015 16:33:51 +0200 Subject: Move roots and bases to appropriate scopes --- build/variable | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 1 deletion(-) (limited to 'build/variable') diff --git a/build/variable b/build/variable index 393ad47..ae4c7b3 100644 --- a/build/variable +++ b/build/variable @@ -8,9 +8,11 @@ #include #include // unique_ptr #include // move() +#include #include #include +#include #include #include @@ -62,9 +64,90 @@ namespace build { list_value (scope_type& s, names d): value (s), data (std::move (d)) {} + list_value (scope_type& s, std::string d) + : value (s) + { + data.emplace_back (std::move (d)); + } + + // Note: stored in name as a directory. + // + list_value (scope_type& s, path d) + : value (s) + { + data.emplace_back (std::move (d)); + } + names data; }; typedef std::unique_ptr list_value_ptr; + + // value_proxy + // + struct value_proxy + { + explicit operator bool () const {return p != nullptr && *p != nullptr;} + explicit operator value_ptr& () const {return *p;} + + // Get interface. See available specializations below. + // + template + T + as () const = delete; + + // Set interface. + // + const value_proxy& + operator= (value_ptr v) const + { + assert (v == nullptr || &v->scope == s); + *p = std::move (v); + return *this; + } + + const value_proxy& + operator= (std::string v) const + { + // In most cases this is used to initialize a new variable, so + // don't bother trying to optimize for the case where p is not + // NULL. + // + p->reset (new list_value (*s, std::move (v))); + return *this; + } + + // Note: stored in name as a directory. + // + const value_proxy& + operator= (path v) const + { + p->reset (new list_value (*s, std::move (v))); + return *this; + } + + // Implementation details. + // + explicit + value_proxy (value_ptr* p, scope* s): p (p), s (s) {} + + protected: + value_ptr* p; + scope* s; + }; + + template <> + list_value& value_proxy:: + as () const; + + template <> + const std::string& value_proxy:: + as () const; + + // Note: get the name's directory. + // + template <> + const path& value_proxy:: + as () const; } namespace std @@ -117,7 +200,28 @@ namespace build } }; - typedef prefix_map variable_map; + struct variable_map: prefix_map + { + typedef prefix_map base; + + value_proxy + operator[] (const std::string& v) + { + return operator[] (variable_pool.find (v)); + } + + value_proxy + operator[] (const variable& v) + { + return value_proxy (&base::operator[] (v), &scope_); + } + + explicit + variable_map (scope& s): scope_ (s) {} + + private: + scope& scope_; // Scope to which this map belongs (and all its value). + }; } #endif // BUILD_VARIABLE -- cgit v1.1