From 10fd2aface4486fc7f873dd2b54a1c2073c0b434 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 1 Dec 2015 14:46:45 +0200 Subject: Reimplement define as dynamic derivation rather than alias New syntax: define cli: file The rationale is we need to be able to assign the file extension (using type/pattern-specific variables). And if it is an alias, we will assign it to the original target type. Note that we could still support aliases if we need to. Will need to bring back the id member in target_type that would normally point to itself but for an alias would point to the origin. --- build/target-type | 57 +++++++++++++++++++++++-------------------------------- 1 file changed, 24 insertions(+), 33 deletions(-) (limited to 'build/target-type') diff --git a/build/target-type b/build/target-type index 2c93455..e299fe2 100644 --- a/build/target-type +++ b/build/target-type @@ -8,9 +8,6 @@ #include #include #include -#include - -#include // compare_c_string #include @@ -23,9 +20,13 @@ namespace build // Target type. // + // Note that we assume there is always a single instance of this class + // for any target type. As a result, we can use address comparison to + // determine if two target types are the same. + // + // struct target_type { - std::type_index id; const char* name; const target_type* base; target* (*factory) (const target_type&, dir_path, string, const string*); @@ -33,60 +34,50 @@ namespace build target* (*search) (const prerequisite_key&); bool see_through; // A group with the default "see through" semantics. - const target_type* origin; // Original target if this is an alias. - bool - is_a (const std::type_index&) const; // Defined in target.cxx + is_a (const target_type&) const; // Defined in target.cxx template bool - is_a () const {return is_a (typeid (T));} + is_a () const {return is_a (T::static_type);} }; inline bool - operator< (const target_type& x, const target_type& y) - { - return x.id < y.id; - } + operator< (const target_type& x, const target_type& y) {return &x < &y;} + + inline bool + operator== (const target_type& x, const target_type& y) {return &x == &y;} + + inline bool + operator!= (const target_type& x, const target_type& y) {return &x != &y;} inline std::ostream& - operator<< (std::ostream& os, const target_type& tt) - { - return os << tt.name; - } + operator<< (std::ostream& os, const target_type& tt) {return os << tt.name;} // Target type map. // struct target_type_ref { - // Like reference_wrapper except it deletes the target type if it is - // an alias (aliases are always dynamically allocated). + // Like reference_wrapper except it sometimes deletes the target type. // explicit - target_type_ref (const target_type& r): p_ (&r) - { - assert (p_->origin == nullptr); - } + target_type_ref (const target_type& r): p_ (&r), d_ (false) {} explicit - target_type_ref (unique_ptr&& p): p_ (p.release ()) - { - assert (p_->origin != nullptr); - } + target_type_ref (unique_ptr&& p) + : p_ (p.release ()), d_ (true) {} + + target_type_ref (target_type_ref&& r) + : p_ (r.p_), d_ (r.d_) {r.p_ = nullptr;} - ~target_type_ref () - { - if (p_ != nullptr && p_->origin != nullptr) - delete p_; - } + ~target_type_ref () {if (p_ != nullptr && d_) delete p_;} explicit operator const target_type& () const {return *p_;} const target_type& get () const {return *p_;} - target_type_ref (target_type_ref&& r): p_ (r.p_) {r.p_ = nullptr;} - private: const target_type* p_; + bool d_; }; using target_type_map_base = std::map; -- cgit v1.1