diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2018-08-09 09:36:23 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2018-08-09 09:36:23 +0200 |
commit | 67b36b32e19e17db9b1e5c72deb8db7202a0f41b (patch) | |
tree | 6c8141f43232569ff930c401b40f74f130743696 | |
parent | 4ce9366b563ceb4939403dbf498b6a5126661ee0 (diff) |
Add support for returning optional<T> from (buildfile) function implementations
-rw-r--r-- | build2/function.hxx | 6 | ||||
-rw-r--r-- | build2/variable.hxx | 7 | ||||
-rw-r--r-- | build2/variable.ixx | 20 |
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) { |