From de15b95d09d00821aa23e96a0c3e827689c27a58 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 20 Jul 2016 16:18:29 +0200 Subject: Switch to dynamic empty() implementation in variable value The current model fell apart when we modified values directly. --- build2/variable.txx | 77 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 34 deletions(-) (limited to 'build2/variable.txx') diff --git a/build2/variable.txx b/build2/variable.txx index a86a936..f1335b4 100644 --- a/build2/variable.txx +++ b/build2/variable.txx @@ -35,8 +35,15 @@ namespace build2 l.as () = r.as (); } - template + template bool + default_empty (const value& v) + { + return value_traits::empty (v.as ()); + } + + template + void simple_assign (value& v, names&& ns, const variable* var) { size_t n (ns.size ()); @@ -45,11 +52,13 @@ namespace build2 { try { - return value_traits::assign ( + value_traits::assign ( v, (n == 0 ? T () : value_traits::convert (move (ns.front ()), nullptr))); + + return; } catch (const invalid_argument&) {} // Fall through. } @@ -68,7 +77,7 @@ namespace build2 } template - bool + void simple_append (value& v, names&& ns, const variable* var) { size_t n (ns.size ()); @@ -77,11 +86,13 @@ namespace build2 { try { - return value_traits::append ( + value_traits::append ( v, (n == 0 ? T () : value_traits::convert (move (ns.front ()), nullptr))); + + return; } catch (const invalid_argument&) {} // Fall through. } @@ -100,7 +111,7 @@ namespace build2 } template - bool + void simple_prepend (value& v, names&& ns, const variable* var) { size_t n (ns.size ()); @@ -109,11 +120,13 @@ namespace build2 { try { - return value_traits::prepend ( + value_traits::prepend ( v, (n == 0 ? T () : value_traits::convert (move (ns.front ()), nullptr))); + + return; } catch (const invalid_argument&) {} // Fall through. } @@ -150,12 +163,12 @@ namespace build2 // template - bool + void vector_append (value& v, names&& ns, const variable* var) { - vector* p (v.null () - ? new (&v.data_) vector () - : &v.as> ()); + vector& p (v + ? v.as> () + : *new (&v.data_) vector ()); // Convert each element to T while merging pairs. // @@ -183,7 +196,7 @@ namespace build2 try { - p->push_back (value_traits::convert (move (n), r)); + p.push_back (value_traits::convert (move (n), r)); } catch (const invalid_argument&) { @@ -200,22 +213,20 @@ namespace build2 dr << " in variable " << var->name; } } - - return !p->empty (); } template - bool + void vector_assign (value& v, names&& ns, const variable* var) { - if (!v.null ()) + if (v) v.as> ().clear (); - return vector_append (v, move (ns), var); + vector_append (v, move (ns), var); } template - bool + void vector_prepend (value& v, names&& ns, const variable* var) { // Reduce to append. @@ -223,21 +234,19 @@ namespace build2 vector t; vector* p; - if (v.null ()) - p = new (&v.data_) vector (); - else + if (v) { p = &v.as> (); p->swap (t); } + else + p = new (&v.data_) vector (); vector_append (v, move (ns), var); p->insert (p->end (), make_move_iterator (t.begin ()), make_move_iterator (t.end ())); - - return !p->empty (); } template @@ -294,20 +303,21 @@ namespace build2 &vector_prepend, &vector_reverse, nullptr, // No cast (cast data_ directly). - &vector_compare + &vector_compare, + &default_empty> }; // map value // template - bool + void map_append (value& v, names&& ns, const variable* var) { using std::map; - map* p (v.null () - ? new (&v.data_) map () - : &v.as> ()); + map& p (v + ? v.as> () + : *new (&v.data_) map ()); // Verify we have a sequence of pairs and convert each lhs/rhs to K/V. // @@ -348,7 +358,7 @@ namespace build2 { V v (value_traits::convert (move (r), nullptr)); - p->emplace (move (k), move (v)); + p.emplace (move (k), move (v)); } catch (const invalid_argument&) { @@ -372,20 +382,18 @@ namespace build2 dr << " in variable " << var->name; } } - - return !p->empty (); } template - bool + void map_assign (value& v, names&& ns, const variable* var) { using std::map; - if (!v.null ()) + if (v) v.as> ().clear (); - return map_append (v, move (ns), var); + map_append (v, move (ns), var); } template @@ -455,6 +463,7 @@ namespace build2 &map_append, // Prepend is the same as append. &map_reverse, nullptr, // No cast (cast data_ directly). - &map_compare + &map_compare, + &default_empty> }; } -- cgit v1.1