diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2016-11-16 10:53:39 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2016-11-18 17:30:47 +0200 |
commit | aeeedd32f8717d8c6a1886a5561a879059be87d0 (patch) | |
tree | cdd4c893e05a1e950f689443ac63f532df721352 | |
parent | a7efabf301f23364ac2335c80c5e1e712bc43204 (diff) |
Make names and vector<name> different types, add typed value constructor
-rw-r--r-- | build2/c/init.cxx | 8 | ||||
-rw-r--r-- | build2/cc/common.cxx | 2 | ||||
-rw-r--r-- | build2/cc/init.cxx | 8 | ||||
-rw-r--r-- | build2/cc/pkgconfig.cxx | 2 | ||||
-rw-r--r-- | build2/cxx/init.cxx | 8 | ||||
-rw-r--r-- | build2/name | 10 | ||||
-rw-r--r-- | build2/parser.cxx | 2 | ||||
-rw-r--r-- | build2/variable | 13 | ||||
-rw-r--r-- | build2/variable.ixx | 23 |
9 files changed, 49 insertions, 27 deletions
diff --git a/build2/c/init.cxx b/build2/c/init.cxx index 750c729..aaef186 100644 --- a/build2/c/init.cxx +++ b/build2/c/init.cxx @@ -147,10 +147,10 @@ namespace build2 v["cc.loptions"], v["cc.libs"], - v.insert<strings> ("c.export.poptions"), - v.insert<strings> ("c.export.coptions"), - v.insert<strings> ("c.export.loptions"), - v.insert<names> ("c.export.libs"), + v.insert<strings> ("c.export.poptions"), + v.insert<strings> ("c.export.coptions"), + v.insert<strings> ("c.export.loptions"), + v.insert<vector<name>> ("c.export.libs"), v["cc.export.poptions"], v["cc.export.coptions"], diff --git a/build2/cc/common.cxx b/build2/cc/common.cxx index 911fbfa..14201d4 100644 --- a/build2/cc/common.cxx +++ b/build2/cc/common.cxx @@ -264,7 +264,7 @@ namespace build2 &find_sysd, &find_lo, &sys, &sys_simple, &bs, &lo, this] (const lookup& lu) { - const names* ns (cast_null<names> (lu)); + const vector<name>* ns (cast_null<vector<name>> (lu)); if (ns == nullptr || ns->empty ()) return; diff --git a/build2/cc/init.cxx b/build2/cc/init.cxx index b9dc4c1..036d622 100644 --- a/build2/cc/init.cxx +++ b/build2/cc/init.cxx @@ -49,10 +49,10 @@ namespace build2 v.insert<strings> ("cc.loptions"); v.insert<strings> ("cc.libs"); - v.insert<strings> ("cc.export.poptions"); - v.insert<strings> ("cc.export.coptions"); - v.insert<strings> ("cc.export.loptions"); - v.insert<names> ("cc.export.libs"); + v.insert<strings> ("cc.export.poptions"); + v.insert<strings> ("cc.export.coptions"); + v.insert<strings> ("cc.export.loptions"); + v.insert<vector<name>> ("cc.export.libs"); // Hint variables (not overridable). // diff --git a/build2/cc/pkgconfig.cxx b/build2/cc/pkgconfig.cxx index 3a7bf82..580812c 100644 --- a/build2/cc/pkgconfig.cxx +++ b/build2/cc/pkgconfig.cxx @@ -260,7 +260,7 @@ namespace build2 const string& lstr, target& t) { strings lops; - names libs; + vector<name> libs; // Normally we will have zero or more -L's followed by one or more // -l's, with the first one being the library itself. But sometimes diff --git a/build2/cxx/init.cxx b/build2/cxx/init.cxx index 59d4cc6..92c0253 100644 --- a/build2/cxx/init.cxx +++ b/build2/cxx/init.cxx @@ -147,10 +147,10 @@ namespace build2 v["cc.loptions"], v["cc.libs"], - v.insert<strings> ("cxx.export.poptions"), - v.insert<strings> ("cxx.export.coptions"), - v.insert<strings> ("cxx.export.loptions"), - v.insert<names> ("cxx.export.libs"), + v.insert<strings> ("cxx.export.poptions"), + v.insert<strings> ("cxx.export.coptions"), + v.insert<strings> ("cxx.export.loptions"), + v.insert<vector<name>> ("cxx.export.libs"), v["cc.export.poptions"], v["cc.export.coptions"], diff --git a/build2/name b/build2/name index 12aa9dc..e079c9f 100644 --- a/build2/name +++ b/build2/name @@ -125,7 +125,15 @@ namespace build2 // Vector of names. // - using names = vector<name>; + // We make it a separate type rather than an alias for vector<name> in order + // to distinguish between untyped variable values (names) and typed ones + // (vector<name>). + // + struct names: vector<name> + { + using vector::vector; + }; + using names_view = vector_view<const name>; // The same semantics as to_stream(name). diff --git a/build2/parser.cxx b/build2/parser.cxx index bfbaa04..d095047 100644 --- a/build2/parser.cxx +++ b/build2/parser.cxx @@ -1497,7 +1497,7 @@ namespace build2 n == "strings" ? &value_traits<strings>::value_type : n == "paths" ? &value_traits<paths>::value_type : n == "dir_paths" ? &value_traits<dir_paths>::value_type : - n == "names" ? &value_traits<names>::value_type : + n == "names" ? &value_traits<vector<name>>::value_type : nullptr; } diff --git a/build2/variable b/build2/variable index 6bdc728..ab5586d 100644 --- a/build2/variable +++ b/build2/variable @@ -165,11 +165,18 @@ namespace build2 ~value () {*this = nullptr;} explicit - value (const value_type* t = nullptr): type (t), null (true), extra (0) {} + value (nullptr_t = nullptr): type (nullptr), null (true), extra (0) {} + + explicit + value (const value_type* t): type (t), null (true), extra (0) {} explicit value (names&&); // Create untyped value. + template <typename T> + explicit + value (T); // Create value of value_traits<T>::value_type type. + // Note: preserves type. // value& @@ -257,10 +264,12 @@ namespace build2 // Value cast. The first three expect the value to be not NULL. The cast // from lookup expects the value to aslo be defined. // + // Note that a cast to names expects the value to be untyped while a cast + // to vector<names> -- typed. + // // Why are these non-members? The cast is easier on the eyes and is also // consistent with the cast operators. The other two are for symmetry. // - // template <typename T> T& cast (value&); template <typename T> T&& cast (value&&); template <typename T> const T& cast (const value&); diff --git a/build2/variable.ixx b/build2/variable.ixx index 5c9118b..d054dd4 100644 --- a/build2/variable.ixx +++ b/build2/variable.ixx @@ -12,8 +12,9 @@ namespace build2 empty () const { assert (!null); - return type == nullptr ? as<names> ().empty () : - type->empty == nullptr ? false : type->empty (*this); + return type == nullptr + ? as<names> ().empty () + : type->empty == nullptr ? false : type->empty (*this); } inline value:: @@ -23,6 +24,15 @@ namespace build2 new (&data_) names (move (ns)); } + template <typename T> + inline value:: + value (T v) + : type (&value_traits<T>::value_type), null (true), extra (0) + { + value_traits<T>::assign (*this, move (v)); + null = false; + } + inline value& value:: operator= (reference_wrapper<value> v) { @@ -93,10 +103,7 @@ namespace build2 inline const names& cast (const value& v) { - // Note that it can still be a typed vector<names>. - // - assert (v && - (v.type == nullptr || v.type == &value_traits<names>::value_type)); + assert (v && v.type == nullptr); return v.as<names> (); } @@ -104,8 +111,7 @@ namespace build2 inline names& cast (value& v) { - assert (v && - (v.type == nullptr || v.type == &value_traits<names>::value_type)); + assert (v && v.type == nullptr); return v.as<names> (); } @@ -230,7 +236,6 @@ namespace build2 v.as<bool> () = x; else new (&v.data_) bool (x); - } inline void value_traits<bool>:: |