diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2016-01-05 11:55:15 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2016-01-05 11:55:15 +0200 |
commit | 9fb791e9fad6c63fc1dac49f4d05ae63b8a3db9b (patch) | |
tree | d60322d4382ca5f97b676c5abe2e39524f35eab4 /build2/target-type | |
parent | f159b1dac68c8714f7ba71ca168e3b695891aad9 (diff) |
Rename build directory/namespace to build2
Diffstat (limited to 'build2/target-type')
-rw-r--r-- | build2/target-type | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/build2/target-type b/build2/target-type new file mode 100644 index 0000000..52a45f4 --- /dev/null +++ b/build2/target-type @@ -0,0 +1,97 @@ +// file : build2/target-type -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef BUILD2_TARGET_TYPE +#define BUILD2_TARGET_TYPE + +#include <map> +#include <string> +#include <ostream> + +#include <build2/types> + +namespace build2 +{ + class scope; + class target; + class target_key; + class prerequisite_key; + + // 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 + { + 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. + + bool + is_a (const target_type&) const; // Defined in target.cxx + + template <typename T> + bool + is_a () const {return is_a (T::static_type);} + }; + + 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 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;} + + // Target type map. + // + struct target_type_ref + { + // Like reference_wrapper except it sometimes deletes the target type. + // + explicit + target_type_ref (const target_type& r): p_ (&r), d_ (false) {} + + explicit + 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 && d_) delete p_;} + + explicit operator const target_type& () const {return *p_;} + const target_type& get () const {return *p_;} + + private: + const target_type* p_; + bool d_; + }; + + using target_type_map_base = std::map<string, target_type_ref>; + + class target_type_map: public target_type_map_base + { + public: + void + insert (const target_type& tt) {emplace (tt.name, target_type_ref (tt));} + + template <typename T> + void + insert () {insert (T::static_type);} + }; +} + +#endif // BUILD2_TARGET_TYPE |