From 977d07a3ae47ef204665d1eda2d642e5064724f3 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 24 Jun 2019 12:01:19 +0200 Subject: Split build system into library and driver --- libbuild2/target-key.hxx | 106 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 libbuild2/target-key.hxx (limited to 'libbuild2/target-key.hxx') diff --git a/libbuild2/target-key.hxx b/libbuild2/target-key.hxx new file mode 100644 index 0000000..e23991d --- /dev/null +++ b/libbuild2/target-key.hxx @@ -0,0 +1,106 @@ +// file : libbuild2/target-key.hxx -*- C++ -*- +// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef LIBBUILD2_TARGET_KEY_HXX +#define LIBBUILD2_TARGET_KEY_HXX + +#include +#include // strcmp() + +#include // compare_c_string + +#include +#include + +#include + +#include + +namespace build2 +{ + // Light-weight (by being shallow-pointing) target key. + // + class target_key + { + public: + const target_type* const type; + const dir_path* const dir; // Can be relative if part of prerequisite_key. + const dir_path* const out; // Can be relative if part of prerequisite_key. + const string* const name; + mutable optional ext; // Absent - unspecified, empty - none. + + template + bool is_a () const {return type->is_a ();} + bool is_a (const target_type& tt) const {return type->is_a (tt);} + }; + + inline bool + operator== (const target_key& x, const target_key& y) + { + if (x.type != y.type || + *x.dir != *y.dir || + *x.out != *y.out || + *x.name != *y.name) + return false; + + // Unless fixed, unspecified and specified extensions are assumed equal. + // + const target_type& tt (*x.type); + + if (tt.fixed_extension == nullptr) + return !x.ext || !y.ext || *x.ext == *y.ext; + else + { + // Note that for performance reasons here we use the specified extension + // without calling fixed_extension(). + // + const char* xe (x.ext + ? x.ext->c_str () + : tt.fixed_extension (x, nullptr /* root scope */)); + + const char* ye (y.ext + ? y.ext->c_str () + : tt.fixed_extension (y, nullptr /* root scope */)); + + return strcmp (xe, ye) == 0; + } + } + + inline bool + operator!= (const target_key& x, const target_key& y) {return !(x == y);} + + // If the target type has a custom print function, call that. Otherwise, + // call to_stream(). Both are defined in target.cxx. + // + LIBBUILD2_SYMEXPORT ostream& + operator<< (ostream&, const target_key&); + + LIBBUILD2_SYMEXPORT ostream& + to_stream (ostream&, const target_key&, optional = nullopt); +} + +namespace std +{ + // Note that we ignore the extension when calculating the hash because of + // its special "unspecified" logic (see operator== above). + // + template <> + struct hash + { + using argument_type = build2::target_key; + using result_type = size_t; + + size_t + operator() (const build2::target_key& k) const noexcept + { + return build2::combine_hash ( + hash () (k.type), + hash () (*k.dir), + hash () (*k.out), + hash () (*k.name)); + } + }; +} + +#endif // LIBBUILD2_TARGET_KEY_HXX -- cgit v1.1