From 6e91cb7cdb0c4f000a79d20d8578890d56bcdc84 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 22 Jan 2021 08:39:10 +0200 Subject: Add support for optional pair halves in variable values --- libbuild2/variable.hxx | 122 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 91 insertions(+), 31 deletions(-) (limited to 'libbuild2/variable.hxx') diff --git a/libbuild2/variable.hxx b/libbuild2/variable.hxx index a671978..a9dde7f 100644 --- a/libbuild2/variable.hxx +++ b/libbuild2/variable.hxx @@ -610,6 +610,9 @@ namespace build2 // static const build2::value_type value_type; // }; + template + struct value_traits: value_traits {}; + // Convert name to a simple value. Throw invalid_argument (with a message) // if the name is not a valid representation of value (in which case the // name remains unchanged for diagnostics). The second version is called for @@ -897,6 +900,9 @@ namespace build2 // half of a pair). If both are empty then this is an empty value (and not a // pair of two empties). // + // @@ Maybe we should redo this with optional<> to signify which half can + // be missing? + // template <> struct LIBBUILD2_SYMEXPORT value_traits { @@ -1004,9 +1010,67 @@ namespace build2 static const build2::value_type value_type; }; + // optional + // + // This is an incomplete implementation meant to provide enough support only + // to be usable as elements of containers. + // + template + struct value_traits> + { + static int compare (const optional&, const optional&); + }; + + // pair + // + // Either F or S can be optional making the corresponding half of the + // pair optional. + // + // This is an incomplete implementation meant to provide enough support only + // to be usable as elements of containers. + // + template + struct pair_value_traits + { + static pair + convert (name&&, name*, const char*, const char*, const variable*); + + static void + reverse (const F&, const S&, names&); + }; + + template + struct pair_value_traits> + { + static pair> + convert (name&&, name*, const char*, const char*, const variable*); + + static void + reverse (const F&, const optional&, names&); + }; + + template + struct pair_value_traits, S> + { + static pair, S> + convert (name&&, name*, const char*, const char*, const variable*); + + static void + reverse (const optional&, const S&, names&); + }; + + template + struct value_traits>: pair_value_traits + { + static int compare (const pair&, const pair&); + }; + // vector // template + struct vector_value_type; + + template struct value_traits> { static_assert (sizeof (vector) <= value::size_, "insufficient space"); @@ -1018,20 +1082,17 @@ namespace build2 static bool empty (const vector& x) {return x.empty ();} static const vector empty_instance; - - // Make sure these are static-initialized together. Failed that VC will - // make sure it's done in the wrong order. - // - struct value_type_ex: build2::value_type - { - string type_name; - value_type_ex (value_type&&); - }; - static const value_type_ex value_type; + static const vector_value_type value_type; }; // vector> // + // Either K or V can be optional making the corresponding half of the + // pair optional. + // + template + struct pair_vector_value_type; + template struct value_traits>> { @@ -1045,20 +1106,16 @@ namespace build2 static bool empty (const vector>& x) {return x.empty ();} static const vector> empty_instance; - - // Make sure these are static-initialized together. Failed that VC will - // make sure it's done in the wrong order. - // - struct value_type_ex: build2::value_type - { - string type_name; - value_type_ex (value_type&&); - }; - static const value_type_ex value_type; + static const pair_vector_value_type value_type; }; // map // + // Either K or V can be optional making the key or value optional. + // + template + struct map_value_type; + template struct value_traits> { @@ -1073,16 +1130,7 @@ namespace build2 static bool empty (const map& x) {return x.empty ();} static const map empty_instance; - - // Make sure these are static-initialized together. Failed that VC will - // make sure it's done in the wrong order. - // - struct value_type_ex: build2::value_type - { - string type_name; - value_type_ex (value_type&&); - }; - static const value_type_ex value_type; + static const map_value_type value_type; }; // Explicitly pre-instantiate and export value_traits templates for @@ -1102,10 +1150,22 @@ namespace build2 value_traits>>; extern template struct LIBBUILD2_DECEXPORT + value_traits>>>; + + extern template struct LIBBUILD2_DECEXPORT + value_traits, string>>>; + + extern template struct LIBBUILD2_DECEXPORT value_traits>; extern template struct LIBBUILD2_DECEXPORT - value_traits>; + value_traits>>; + + extern template struct LIBBUILD2_DECEXPORT + value_traits, string>>; + + extern template struct LIBBUILD2_DECEXPORT + value_traits>; // var_subprojects // Project-wide (as opposed to global) variable overrides (see context ctor // for details). -- cgit v1.1