aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2018-08-09 09:36:23 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2018-08-09 09:36:23 +0200
commit67b36b32e19e17db9b1e5c72deb8db7202a0f41b (patch)
tree6c8141f43232569ff930c401b40f74f130743696
parent4ce9366b563ceb4939403dbf498b6a5126661ee0 (diff)
Add support for returning optional<T> from (buildfile) function implementations
-rw-r--r--build2/function.hxx6
-rw-r--r--build2/variable.hxx7
-rw-r--r--build2/variable.ixx20
3 files changed, 32 insertions, 1 deletions
diff --git a/build2/function.hxx b/build2/function.hxx
index 139f1fa..5b84a69 100644
--- a/build2/function.hxx
+++ b/build2/function.hxx
@@ -46,12 +46,16 @@ namespace build2
// are conceptually "moved" and can be reused by the implementation.
//
// A function can also optionally receive the current scope by having the
- // first argument of the const scope* type. It may be NULL is the function
+ // first argument of the const scope* type. It may be NULL if the function
// is called out of any scope (e.g., command line).
//
// Note also that we don't pass the location to the function instead
// printing the info message pointing to the call site.
//
+ // A function can return value or anything that can be converted to value.
+ // In particular, if a function returns optional<T>, then the result will be
+ // either NULL or value of type T.
+ //
// Normally functions come in families that share a common qualification
// (e.g., string. or path.). The function_family class is a "registrar"
// that simplifies handling of function families. For example:
diff --git a/build2/variable.hxx b/build2/variable.hxx
index 401cc77..7a0e531 100644
--- a/build2/variable.hxx
+++ b/build2/variable.hxx
@@ -250,10 +250,17 @@ namespace build2
explicit
value (names); // Create untyped value.
+ explicit
+ value (optional<names>);
+
template <typename T>
explicit
value (T); // Create value of value_traits<T>::value_type type.
+ template <typename T>
+ explicit
+ value (optional<T>);
+
// Note: preserves type.
//
value&
diff --git a/build2/variable.ixx b/build2/variable.ixx
index 8c16559..bf5fb92 100644
--- a/build2/variable.ixx
+++ b/build2/variable.ixx
@@ -24,6 +24,14 @@ namespace build2
new (&data_) names (move (ns));
}
+ inline value::
+ value (optional<names> ns)
+ : type (nullptr), null (!ns), extra (0)
+ {
+ if (!null)
+ new (&data_) names (move (*ns));
+ }
+
template <typename T>
inline value::
value (T v)
@@ -33,6 +41,18 @@ namespace build2
null = false;
}
+ template <typename T>
+ inline value::
+ value (optional<T> v)
+ : type (&value_traits<T>::value_type), null (true), extra (0)
+ {
+ if (v)
+ {
+ value_traits<T>::assign (*this, move (*v));
+ null = false;
+ }
+ }
+
inline value& value::
operator= (reference_wrapper<value> v)
{