aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/variable.txx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2024-05-20 12:23:58 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2024-05-20 12:23:58 +0200
commitfd94c6f239d2436b6152935b4c99217129953a5d (patch)
treec9ebef4ec79371ae02d24a9817797baa3447f20b /libbuild2/variable.txx
parent2fc53c801eb551154f0a2aa96522cf3182a65b7a (diff)
Add convert_to_base<T>(value) variants that allow derive-to-base conversion
Diffstat (limited to 'libbuild2/variable.txx')
-rw-r--r--libbuild2/variable.txx35
1 files changed, 35 insertions, 0 deletions
diff --git a/libbuild2/variable.txx b/libbuild2/variable.txx
index 0b831e9..a1ee340 100644
--- a/libbuild2/variable.txx
+++ b/libbuild2/variable.txx
@@ -38,6 +38,11 @@ namespace build2
{
if (v.type == nullptr)
return convert<T> (move (v).as<names> ());
+ //
+ // Note that while it may be tempting to use is_a() here like in cast(),
+ // the implications are unclear (i.e., we may end up relaxing things we
+ // don't want to). So we have the convert_to_base() variants instead.
+ //
else if (v.type == &value_traits<T>::value_type)
return move (v).as<T> ();
}
@@ -61,6 +66,36 @@ namespace build2
}
template <typename T>
+ T
+ convert_to_base (value&& v)
+ {
+ if (v)
+ {
+ if (v.type == nullptr)
+ return convert<T> (move (v).as<names> ());
+ else if (v.type->is_a<T> ())
+ return move (v).as<T> ();
+ }
+
+ convert_throw (v ? v.type : nullptr, value_traits<T>::value_type);
+ }
+
+ template <typename T>
+ T
+ convert_to_base (const value& v)
+ {
+ if (v)
+ {
+ if (v.type == nullptr)
+ return convert<T> (names (v.as<names> ()));
+ else if (v.type->is_a<T> ())
+ return v.as<T> ();
+ }
+
+ convert_throw (v ? v.type : nullptr, value_traits<T>::value_type);
+ }
+
+ template <typename T>
void
default_dtor (value& v)
{