aboutsummaryrefslogtreecommitdiff
path: root/build2
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-11-16 10:53:39 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-11-18 17:30:47 +0200
commitaeeedd32f8717d8c6a1886a5561a879059be87d0 (patch)
treecdd4c893e05a1e950f689443ac63f532df721352 /build2
parenta7efabf301f23364ac2335c80c5e1e712bc43204 (diff)
Make names and vector<name> different types, add typed value constructor
Diffstat (limited to 'build2')
-rw-r--r--build2/c/init.cxx8
-rw-r--r--build2/cc/common.cxx2
-rw-r--r--build2/cc/init.cxx8
-rw-r--r--build2/cc/pkgconfig.cxx2
-rw-r--r--build2/cxx/init.cxx8
-rw-r--r--build2/name10
-rw-r--r--build2/parser.cxx2
-rw-r--r--build2/variable13
-rw-r--r--build2/variable.ixx23
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>::