diff options
Diffstat (limited to 'build')
-rw-r--r-- | build/algorithm.cxx | 2 | ||||
-rw-r--r-- | build/bin/target.cxx | 28 | ||||
-rw-r--r-- | build/cli/target.cxx | 8 | ||||
-rw-r--r-- | build/cxx/target.cxx | 24 | ||||
-rw-r--r-- | build/dump.cxx | 4 | ||||
-rw-r--r-- | build/parser.cxx | 43 | ||||
-rw-r--r-- | build/prerequisite | 1 | ||||
-rw-r--r-- | build/rule-map | 5 | ||||
-rw-r--r-- | build/target | 7 | ||||
-rw-r--r-- | build/target-key | 5 | ||||
-rw-r--r-- | build/target-type | 57 | ||||
-rw-r--r-- | build/target.cxx | 48 |
12 files changed, 83 insertions, 149 deletions
diff --git a/build/algorithm.cxx b/build/algorithm.cxx index 6c3374e..461d8d2 100644 --- a/build/algorithm.cxx +++ b/build/algorithm.cxx @@ -111,7 +111,7 @@ namespace build if (ttm->empty ()) continue; // Empty map for this operation id. - auto i (ttm->find (tt->id)); + auto i (ttm->find (tt)); if (i == ttm->end () || i->second.empty ()) continue; // No rules registered for this target type. diff --git a/build/bin/target.cxx b/build/bin/target.cxx index c2c5e05..6f2d7b5 100644 --- a/build/bin/target.cxx +++ b/build/bin/target.cxx @@ -24,14 +24,12 @@ namespace build const target_type obja::static_type { - typeid (obja), "obja", &file::static_type, &obja_factory, nullptr, &search_target, // Note: not _file(); don't look for an existing file. - false, - nullptr + false }; static target* @@ -48,14 +46,12 @@ namespace build const target_type objso::static_type { - typeid (objso), "objso", &file::static_type, &objso_factory, nullptr, &search_target, // Note: not _file(); don't look for an existing file. - false, - nullptr + false }; static target* @@ -76,26 +72,22 @@ namespace build const target_type obj::static_type { - typeid (obj), "obj", &target::static_type, &obj_factory, nullptr, &search_target, - false, - nullptr + false }; const target_type exe::static_type { - typeid (exe), "exe", &file::static_type, &target_factory<exe>, nullptr, &search_file, - false, - nullptr + false }; static target* @@ -125,14 +117,12 @@ namespace build constexpr const char a_ext[] = "a"; const target_type liba::static_type { - typeid (liba), "liba", &file::static_type, &liba_factory, &target_extension_fix<a_ext>, &search_file, - false, - nullptr + false }; static target* @@ -150,14 +140,12 @@ namespace build constexpr const char so_ext[] = "so"; const target_type libso::static_type { - typeid (libso), "libso", &file::static_type, &libso_factory, &target_extension_fix<so_ext>, &search_file, - false, - nullptr + false }; // lib @@ -187,14 +175,12 @@ namespace build const target_type lib::static_type { - typeid (lib), "lib", &target::static_type, &lib_factory, nullptr, &search_target, - false, - nullptr + false }; } } diff --git a/build/cli/target.cxx b/build/cli/target.cxx index 0666335..a480633 100644 --- a/build/cli/target.cxx +++ b/build/cli/target.cxx @@ -18,14 +18,12 @@ namespace build constexpr const char cli_ext[] = "cli"; const target_type cli::static_type { - typeid (cli), "cli", &file::static_type, &target_factory<cli>, &target_extension_fix<cli_ext>, &search_file, - false, - nullptr + false }; // cli.cxx @@ -66,14 +64,12 @@ namespace build const target_type cli_cxx::static_type { - typeid (cli_cxx), "cli.cxx", &mtime_target::static_type, &cli_cxx_factory, nullptr, &search_target, - true, // "See through" default iteration mode. - nullptr + true // "See through" default iteration mode. }; } } diff --git a/build/cxx/target.cxx b/build/cxx/target.cxx index e3d98e7..c8680b7 100644 --- a/build/cxx/target.cxx +++ b/build/cxx/target.cxx @@ -13,79 +13,67 @@ namespace build constexpr const char hxx_ext_var[] = "hxx.ext"; const target_type hxx::static_type { - typeid (hxx), "hxx", &file::static_type, &target_factory<hxx>, &target_extension_var<hxx_ext_var>, &search_file, - false, - nullptr + false }; constexpr const char ixx_ext_var[] = "ixx.ext"; const target_type ixx::static_type { - typeid (ixx), "ixx", &file::static_type, &target_factory<ixx>, &target_extension_var<ixx_ext_var>, &search_file, - false, - nullptr + false }; constexpr const char txx_ext_var[] = "txx.ext"; const target_type txx::static_type { - typeid (txx), "txx", &file::static_type, &target_factory<txx>, &target_extension_var<txx_ext_var>, &search_file, - false, - nullptr + false }; constexpr const char cxx_ext_var[] = "cxx.ext"; const target_type cxx::static_type { - typeid (cxx), "cxx", &file::static_type, &target_factory<cxx>, &target_extension_var<cxx_ext_var>, &search_file, - false, - nullptr + false }; constexpr const char h_ext_var[] = "h.ext"; const target_type h::static_type { - typeid (h), "h", &file::static_type, &target_factory<h>, &target_extension_var<h_ext_var>, &search_file, - false, - nullptr + false }; constexpr const char c_ext_var[] = "c.ext"; const target_type c::static_type { - typeid (c), "c", &file::static_type, &target_factory<c>, &target_extension_var<c_ext_var>, &search_file, - false, - nullptr + false }; } } diff --git a/build/dump.cxx b/build/dump.cxx index 7f4502e..62e032b 100644 --- a/build/dump.cxx +++ b/build/dump.cxx @@ -56,12 +56,12 @@ namespace build os << endl << ind; - if (t.id != target::static_type.id) + if (t != target::static_type) os << t.name << '{'; os << p; - if (t.id != target::static_type.id) + if (t != target::static_type) os << '}'; os << ':'; diff --git a/build/parser.cxx b/build/parser.cxx index 4981347..05c79db 100644 --- a/build/parser.cxx +++ b/build/parser.cxx @@ -808,58 +808,57 @@ namespace build } static target* - alias_factory (const target_type& tt, dir_path d, string n, const string* e) + derived_factory (const target_type& t, dir_path d, string n, const string* e) { - assert (tt.origin != nullptr); - target* r (tt.origin->factory (*tt.origin, move (d), move (n), e)); - r->alias_type = &tt; + target* r (t.base->factory (*t.base, move (d), move (n), e)); + r->derived_type = &t; return r; } void parser:: define (token& t, token_type& tt) { - // define <alias>=<name> + // define <derived>: <base> // - // See tests/define/buildfile. + // See tests/define. // if (next (t, tt) != type::name) fail (t) << "expected name instead of " << t << " in target type " << "definition"; - string a (move (t.value)); - const location al (get_location (t, &path_)); + string dn (move (t.value)); + const location dnl (get_location (t, &path_)); - if (next (t, tt) != type::equal) - fail (t) << "expected '=' instead of " << t << " in target type " + if (next (t, tt) != type::colon) + fail (t) << "expected ':' instead of " << t << " in target type " << "definition"; next (t, tt); if (tt == type::name) { - // Alias. + // Target. // - const string& n (t.value); - const target_type* ntt (scope_->find_target_type (n)); + const string& bn (t.value); + const target_type* bt (scope_->find_target_type (bn)); - if (ntt == nullptr) - fail (t) << "unknown target type " << n; + if (bt == nullptr) + fail (t) << "unknown target type " << bn; - unique_ptr<target_type> att (new target_type (*ntt)); - att->factory = &alias_factory; - att->origin = ntt->origin != nullptr ? ntt->origin : ntt; + unique_ptr<target_type> dt (new target_type (*bt)); + dt->base = bt; + dt->factory = &derived_factory; - target_type& ratt (*att); // Save non-const reference to the object. + target_type& rdt (*dt); // Save a non-const reference to the object. - auto pr (scope_->target_types.emplace (a, target_type_ref (move (att)))); + auto pr (scope_->target_types.emplace (dn, target_type_ref (move (dt)))); if (!pr.second) - fail (al) << "target type " << a << " already define in this scope"; + fail (dnl) << "target type " << dn << " already define in this scope"; // Patch the alias name to use the map's key storage. // - ratt.name = pr.first->first.c_str (); + rdt.name = pr.first->first.c_str (); next (t, tt); // Get newline. } diff --git a/build/prerequisite b/build/prerequisite index f91a199..3022e44 100644 --- a/build/prerequisite +++ b/build/prerequisite @@ -10,7 +10,6 @@ #include <iosfwd> #include <utility> // move #include <cassert> -#include <typeindex> #include <functional> // reference_wrapper #include <build/types> diff --git a/build/rule-map b/build/rule-map index 0ce49e7..d262ecd 100644 --- a/build/rule-map +++ b/build/rule-map @@ -9,7 +9,6 @@ #include <vector> #include <string> #include <memory> // unique_ptr -#include <typeindex> #include <functional> // reference_wrapper #include <butl/prefix-map> @@ -22,7 +21,7 @@ namespace build class rule; using target_type_rule_map = std::map< - std::type_index, // Target type. + const target_type*, butl::prefix_map<std::string, // Rule hint. std::reference_wrapper<rule>, '.'>>; @@ -41,7 +40,7 @@ namespace build if (oid >= map_.size ()) map_.resize ((oid < 3 ? 3 : oid) + 1); - map_[oid][typeid (T)].emplace (hint, r); + map_[oid][&T::static_type].emplace (hint, r); } // Return NULL if not found. diff --git a/build/target b/build/target index a1c7880..66daa66 100644 --- a/build/target +++ b/build/target @@ -354,15 +354,14 @@ namespace build const T* is_a () const {return dynamic_cast<const T*> (this);} - // An alias target type should be the same as its target type except - // for the name. + // Dynamic derivation to support define. // - const target_type* alias_type = nullptr; + const target_type* derived_type = nullptr; const target_type& type () const { - return alias_type != nullptr ? *alias_type : dynamic_type (); + return derived_type != nullptr ? *derived_type : dynamic_type (); } virtual const target_type& dynamic_type () const = 0; diff --git a/build/target-key b/build/target-key index f49efb2..526a33a 100644 --- a/build/target-key +++ b/build/target-key @@ -8,7 +8,6 @@ #include <map> #include <string> #include <ostream> -#include <typeindex> #include <functional> // reference_wrapper #include <butl/utility> // compare_c_string @@ -31,8 +30,8 @@ namespace build friend bool operator< (const target_key& x, const target_key& y) { - const std::type_index& xt (x.type->id); - const std::type_index& yt (y.type->id); + const target_type* xt (x.type); + const target_type* yt (y.type); //@@ TODO: use compare() to compare once. 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 <map> #include <string> #include <ostream> -#include <typeindex> - -#include <butl/utility> // compare_c_string #include <build/types> @@ -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 <typename T> 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<target_type>&& p): p_ (p.release ()) - { - assert (p_->origin != nullptr); - } + target_type_ref (unique_ptr<target_type>&& 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<string, target_type_ref>; diff --git a/build/target.cxx b/build/target.cxx index 649e570..7c45e3e 100644 --- a/build/target.cxx +++ b/build/target.cxx @@ -20,10 +20,10 @@ namespace build // target_type // bool target_type:: - is_a (const type_index& id) const + is_a (const target_type& tt) const { for (const target_type* p (this); p != nullptr; p = p->base) - if (p->id == id) + if (*p == tt) return true; return false; @@ -440,38 +440,32 @@ namespace build const target_type target::static_type { - typeid (target), "target", nullptr, nullptr, nullptr, &search_target, - false, - nullptr + false }; const target_type mtime_target::static_type { - typeid (mtime_target), "mtime_target", &target::static_type, nullptr, nullptr, &search_target, - false, - nullptr + false }; const target_type path_target::static_type { - typeid (path_target), "path_target", &mtime_target::static_type, nullptr, nullptr, &search_target, - false, - nullptr + false }; template <typename T> @@ -490,50 +484,42 @@ namespace build constexpr const char file_ext[] = ""; const target_type file::static_type { - typeid (file), "file", &path_target::static_type, &file_factory<file>, &target_extension_fix<file_ext>, &search_file, - false, - nullptr + false }; const target_type alias::static_type { - typeid (alias), "alias", &target::static_type, &target_factory<alias>, nullptr, // Should never need. &search_alias, - false, - nullptr + false }; const target_type dir::static_type { - typeid (dir), "dir", &alias::static_type, &target_factory<dir>, nullptr, // Should never need. &search_alias, - false, - nullptr + false }; const target_type fsdir::static_type { - typeid (fsdir), "fsdir", &target::static_type, &target_factory<fsdir>, nullptr, // Should never need. &search_target, - false, - nullptr + false }; static const std::string& @@ -547,27 +533,23 @@ namespace build const target_type buildfile::static_type { - typeid (buildfile), "buildfile", &file::static_type, &file_factory<buildfile>, &buildfile_target_extension, &search_file, - false, - nullptr + false }; constexpr const char doc_ext[] = ""; const target_type doc::static_type { - typeid (doc), "doc", &file::static_type, &file_factory<doc>, &target_extension_fix<doc_ext>, &search_file, - false, - nullptr + false }; static target* @@ -581,26 +563,22 @@ namespace build const target_type man::static_type { - typeid (man), "man", &doc::static_type, &man_factory, nullptr, // Should be specified explicitly. &search_file, - false, - nullptr + false }; constexpr const char man1_ext[] = "1"; const target_type man1::static_type { - typeid (man1), "man1", &man::static_type, &file_factory<man1>, &target_extension_fix<man1_ext>, &search_file, - false, - nullptr + false }; } |