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.ixx | 370 +++++++++++++++++++++------------------------------- 1 file changed, 148 insertions(+), 222 deletions(-) (limited to 'build2/variable.ixx') diff --git a/build2/variable.ixx b/build2/variable.ixx index e7d5654..6b59c72 100644 --- a/build2/variable.ixx +++ b/build2/variable.ixx @@ -8,11 +8,17 @@ namespace build2 { // value // + inline bool value:: + empty () const + { + assert (!null); + return type == nullptr ? as ().empty () : + type->empty == nullptr ? false : type->empty (*this); + } + inline value:: value (names&& ns) - : type (nullptr), - state (ns.empty () ? value_state::empty : value_state::filled), - extra (0) + : type (nullptr), null (false), extra (0) { new (&data_) names (move (ns)); } @@ -43,10 +49,8 @@ namespace build2 type = &value_traits::value_type; } - state = value_traits::assign (*this, move (v)) - ? value_state::filled - : value_state::empty; - + value_traits::assign (*this, move (v)); + null = false; return *this; } @@ -54,18 +58,15 @@ namespace build2 inline value& value:: operator+= (T v) { - assert (type == &value_traits::value_type || - (type == nullptr && null ())); + assert (type == &value_traits::value_type || (type == nullptr && null)); // Prepare the receiving value. // if (type == nullptr) type = &value_traits::value_type; - state = value_traits::append (*this, move (v)) - ? value_state::filled - : value_state::empty; - + value_traits::append (*this, move (v)); + null = false; return *this; } @@ -94,7 +95,7 @@ namespace build2 { // Note that it can still be a typed vector. // - assert (!v.null () && + assert (v && (v.type == nullptr || v.type == &value_traits::value_type)); return v.as (); } @@ -103,7 +104,7 @@ namespace build2 inline names& cast (value& v) { - assert (!v.null () && + assert (v && (v.type == nullptr || v.type == &value_traits::value_type)); return v.as (); } @@ -112,7 +113,7 @@ namespace build2 inline const T& cast (const value& v) { - assert (!v.null ()); + assert (v); // Find base if any. // @@ -129,7 +130,7 @@ namespace build2 inline T& cast (value& v) { - assert (!v.null () && v.type == &value_traits::value_type); + assert (v && v.type == &value_traits::value_type); return *static_cast (v.type->cast == nullptr ? static_cast (&v.data_) : const_cast (v.type->cast (v, v.type))); @@ -191,7 +192,7 @@ namespace build2 inline names_view reverse (const value& v, names& storage) { - assert (!v.null () && + assert (v && storage.empty () && (v.type == nullptr || v.type->reverse != nullptr)); return v.type == nullptr ? v.as () : v.type->reverse (v, storage); @@ -222,28 +223,25 @@ namespace build2 // bool value // - inline bool value_traits:: + inline void value_traits:: assign (value& v, bool x) { - if (v.null ()) - new (&v.data_) bool (x); - else + if (v) v.as () = x; + else + new (&v.data_) bool (x); - return true; } - inline bool value_traits:: + inline void value_traits:: append (value& v, bool x) { // Logical OR. // - if (v.null ()) - new (&v.data_) bool (x); - else + if (v) v.as () = v.as () || x; - - return true; + else + new (&v.data_) bool (x); } inline int value_traits:: @@ -254,28 +252,24 @@ namespace build2 // uint64_t value // - inline bool value_traits:: + inline void value_traits:: assign (value& v, uint64_t x) { - if (v.null ()) - new (&v.data_) uint64_t (x); - else + if (v) v.as () = x; - - return true; + else + new (&v.data_) uint64_t (x); } - inline bool value_traits:: + inline void value_traits:: append (value& v, uint64_t x) { // ADD. // - if (v.null ()) - new (&v.data_) uint64_t (x); - else + if (v) v.as () += x; - - return true; + else + new (&v.data_) uint64_t (x); } inline int value_traits:: @@ -286,57 +280,45 @@ namespace build2 // string value // - inline bool value_traits:: + inline void value_traits:: assign (value& v, string&& x) { - string* p; - - if (v.null ()) - p = new (&v.data_) string (move (x)); + if (v) + v.as () = move (x); else - p = &(v.as () = move (x)); - - return !p->empty (); + new (&v.data_) string (move (x)); } - inline bool value_traits:: + inline void value_traits:: append (value& v, string&& x) { - string* p; - - if (v.null ()) - p = new (&v.data_) string (move (x)); - else + if (v) { - p = &v.as (); + string& s (v.as ()); - if (p->empty ()) - p->swap (x); + if (s.empty ()) + s.swap (x); else - *p += x; + s += x; } - - return !p->empty (); + else + new (&v.data_) string (move (x)); } - inline bool value_traits:: + inline void value_traits:: prepend (value& v, string&& x) { - string* p; - - if (v.null ()) - p = new (&v.data_) string (move (x)); - else + if (v) { - p = &v.as (); + string& s (v.as ()); - if (!p->empty ()) - x += *p; + if (!s.empty ()) + x += s; - p->swap (x); + s.swap (x); } - - return !p->empty (); + else + new (&v.data_) string (move (x)); } inline int value_traits:: @@ -347,57 +329,45 @@ namespace build2 // path value // - inline bool value_traits:: + inline void value_traits:: assign (value& v, path&& x) { - path* p; - - if (v.null ()) - p = new (&v.data_) path (move (x)); + if (v) + v.as () = move (x); else - p = &(v.as () = move (x)); - - return !p->empty (); + new (&v.data_) path (move (x)); } - inline bool value_traits:: + inline void value_traits:: append (value& v, path&& x) { - path* p; - - if (v.null ()) - p = new (&v.data_) path (move (x)); - else + if (v) { - p = &v.as (); + path& p (v.as ()); - if (p->empty ()) - p->swap (x); + if (p.empty ()) + p.swap (x); else - *p /= x; + p /= x; } - - return !p->empty (); + else + new (&v.data_) path (move (x)); } - inline bool value_traits:: + inline void value_traits:: prepend (value& v, path&& x) { - path* p; - - if (v.null ()) - p = new (&v.data_) path (move (x)); - else + if (v) { - p = &v.as (); + path& p (v.as ()); - if (!p->empty ()) - x /= *p; + if (!p.empty ()) + x /= p; - p->swap (x); + p.swap (x); } - - return !p->empty (); + else + new (&v.data_) path (move (x)); } inline int value_traits:: @@ -408,57 +378,45 @@ namespace build2 // dir_path value // - inline bool value_traits:: + inline void value_traits:: assign (value& v, dir_path&& x) { - dir_path* p; - - if (v.null ()) - p = new (&v.data_) dir_path (move (x)); + if (v) + v.as () = move (x); else - p = &(v.as () = move (x)); - - return !p->empty (); + new (&v.data_) dir_path (move (x)); } - inline bool value_traits:: + inline void value_traits:: append (value& v, dir_path&& x) { - dir_path* p; - - if (v.null ()) - p = new (&v.data_) dir_path (move (x)); - else + if (v) { - p = &v.as (); + dir_path& p (v.as ()); - if (p->empty ()) - p->swap (x); + if (p.empty ()) + p.swap (x); else - *p /= x; + p /= x; } - - return !p->empty (); + else + new (&v.data_) dir_path (move (x)); } - inline bool value_traits:: + inline void value_traits:: prepend (value& v, dir_path&& x) { - dir_path* p; - - if (v.null ()) - p = new (&v.data_) dir_path (move (x)); - else + if (v) { - p = &v.as (); + dir_path& p (v.as ()); - if (!p->empty ()) - x /= *p; + if (!p.empty ()) + x /= p; - p->swap (x); + p.swap (x); } - - return !p->empty (); + else + new (&v.data_) dir_path (move (x)); } inline int value_traits:: @@ -469,37 +427,29 @@ namespace build2 // abs_dir_path value // - inline bool value_traits:: + inline void value_traits:: assign (value& v, abs_dir_path&& x) { - abs_dir_path* p; - - if (v.null ()) - p = new (&v.data_) abs_dir_path (move (x)); + if (v) + v.as () = move (x); else - p = &(v.as () = move (x)); - - return !p->empty (); + new (&v.data_) abs_dir_path (move (x)); } - inline bool value_traits:: + inline void value_traits:: append (value& v, abs_dir_path&& x) { - abs_dir_path* p; - - if (v.null ()) - p = new (&v.data_) abs_dir_path (move (x)); - else + if (v) { - p = &v.as (); + abs_dir_path& p (v.as ()); - if (p->empty ()) - p->swap (x); + if (p.empty ()) + p.swap (x); else - *p /= x; + p /= x; } - - return !p->empty (); + else + new (&v.data_) abs_dir_path (move (x)); } inline int value_traits:: @@ -510,17 +460,13 @@ namespace build2 // name value // - inline bool value_traits:: + inline void value_traits:: assign (value& v, name&& x) { - name* p; - - if (v.null ()) - p = new (&v.data_) name (move (x)); + if (v) + v.as () = move (x); else - p = &(v.as () = move (x)); - - return !p->empty (); + new (&v.data_) name (move (x)); } inline int value_traits:: @@ -532,105 +478,85 @@ namespace build2 // vector value // template - inline bool value_traits>:: + inline void value_traits>:: assign (value& v, vector&& x) { - vector* p; - - if (v.null ()) - p = new (&v.data_) vector (move (x)); + if (v) + v.as> () = move (x); else - p = &(v.as> () = move (x)); - - return !p->empty (); + new (&v.data_) vector (move (x)); } template - inline bool value_traits>:: + inline void value_traits>:: append (value& v, vector&& x) { - vector* p; - - if (v.null ()) - p = new (&v.data_) vector (move (x)); - else + if (v) { - p = &v.as> (); + vector& p (v.as> ()); - if (p->empty ()) - p->swap (x); + if (p.empty ()) + p.swap (x); else - p->insert (p->end (), - make_move_iterator (x.begin ()), - make_move_iterator (x.end ())); + p.insert (p.end (), + make_move_iterator (x.begin ()), + make_move_iterator (x.end ())); } - - return !p->empty (); + else + new (&v.data_) vector (move (x)); } template - inline bool value_traits>:: + inline void value_traits>:: prepend (value& v, vector&& x) { - vector* p; - - if (v.null ()) - p = new (&v.data_) vector (move (x)); - else + if (v) { - p = &v.as> (); + vector& p (v.as> ()); - if (!p->empty ()) + if (!p.empty ()) x.insert (x.end (), - make_move_iterator (p->begin ()), - make_move_iterator (p->end ())); + make_move_iterator (p.begin ()), + make_move_iterator (p.end ())); - p->swap (x); + p.swap (x); } - - return !p->empty (); + else + new (&v.data_) vector (move (x)); } // map value // template - inline bool value_traits>:: + inline void value_traits>:: assign (value& v, map&& x) { - map* p; - - if (v.null ()) - p = new (&v.data_) map (move (x)); + if (v) + v.as> () = move (x); else - p = &(v.as> () = move (x)); - - return !p->empty (); + new (&v.data_) map (move (x)); } template - inline bool value_traits>:: + inline void value_traits>:: append (value& v, map&& x) { - map* p; - - if (v.null ()) - p = new (&v.data_) map (move (x)); - else + if (v) { - p = &v.as> (); + map& m (v.as> ()); - if (p->empty ()) - p->swap (x); + if (m.empty ()) + m.swap (x); else // Note that this will only move values. Keys (being const) are still // copied. // - p->insert (p->end (), - make_move_iterator (x.begin ()), - make_move_iterator (x.end ())); + m.insert (m.end (), + make_move_iterator (x.begin ()), + make_move_iterator (x.end ())); } - - return !p->empty (); + else + new (&v.data_) map (move (x)); } // variable_pool -- cgit v1.1