// file : build/target-type -*- C++ -*- // copyright : Copyright (c) 2014-2015 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file #ifndef BUILD_TARGET_TYPE #define BUILD_TARGET_TYPE #include #include #include #include #include // compare_c_string #include namespace build { class scope; class target; class target_key; class prerequisite_key; // Target type. // struct target_type { std::type_index id; const char* name; const target_type* base; target* (*factory) (const target_type&, dir_path, string, const string*); const string& (*extension) (const target_key&, scope&); 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 template bool is_a () const {return is_a (typeid (T));} }; inline bool operator< (const target_type& x, const target_type& y) { return x.id < y.id; } inline std::ostream& 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). // explicit target_type_ref (const target_type& r): p_ (&r) { assert (p_->origin == nullptr); } explicit target_type_ref (unique_ptr&& p): p_ (p.release ()) { assert (p_->origin != nullptr); } ~target_type_ref () { if (p_ != nullptr && p_->origin != nullptr) 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_; }; using target_type_map_base = std::map; class target_type_map: public target_type_map_base { public: void insert (const target_type& tt) {emplace (tt.name, target_type_ref (tt));} template void insert () {insert (T::static_type);} }; } #endif // BUILD_TARGET_TYPE