aboutsummaryrefslogtreecommitdiff
path: root/build2/variable.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-07-20 14:14:52 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-07-20 14:14:52 +0200
commitdf43058115b389f1375690812ad92301288f976f (patch)
treebb4196fef2bfddd8fe778b92e7d2d3ce58e68c73 /build2/variable.cxx
parent5c5a60a02ba1ddcb6782a938f3c892cda979d8fe (diff)
Implement support for <, >, <=, >= in eval context
Now can write: if ($build.version > 30000)
Diffstat (limited to 'build2/variable.cxx')
-rw-r--r--build2/variable.cxx62
1 files changed, 62 insertions, 0 deletions
diff --git a/build2/variable.cxx b/build2/variable.cxx
index 58076d4..78f9df8 100644
--- a/build2/variable.cxx
+++ b/build2/variable.cxx
@@ -280,6 +280,68 @@ namespace build2
return x.type->compare (x, y) == 0;
}
+ bool
+ operator< (const value& x, const value& y)
+ {
+ bool xn (x.null ());
+ bool yn (y.null ());
+
+ assert (x.type == y.type ||
+ (xn && x.type == nullptr) ||
+ (yn && y.type == nullptr));
+
+ // NULL value is always less than non-NULL and we assume that empty
+ // value is always less than non-empty.
+ //
+ if (x.state < y.state)
+ return true;
+ else if (x.state > y.state)
+ return false;
+ else if (x.state != value_state::filled) // Both are NULL or empty.
+ return false;
+
+ // Both are filled.
+ //
+ if (x.type == nullptr)
+ return x.as<names> () < y.as<names> ();
+
+ if (x.type->compare == nullptr)
+ return memcmp (&x.data_, &y.data_, x.type->size) < 0;
+
+ return x.type->compare (x, y) < 0;
+ }
+
+ bool
+ operator> (const value& x, const value& y)
+ {
+ bool xn (x.null ());
+ bool yn (y.null ());
+
+ assert (x.type == y.type ||
+ (xn && x.type == nullptr) ||
+ (yn && y.type == nullptr));
+
+ // NULL value is always less than non-NULL and we assume that empty
+ // value is always less than non-empty.
+ //
+ if (x.state > y.state)
+ return true;
+ else if (x.state < y.state)
+ return false;
+ else if (x.state != value_state::filled) // Both are NULL or empty.
+ return false;
+
+ // Both are filled.
+ //
+ if (x.type == nullptr)
+ return x.as<names> () > y.as<names> ();
+
+ if (x.type->compare == nullptr)
+ return memcmp (&x.data_, &y.data_, x.type->size) > 0;
+
+ return x.type->compare (x, y) > 0;
+ }
+
void
typify (value& v, const value_type& t, const variable* var)
{