From 9fb791e9fad6c63fc1dac49f4d05ae63b8a3db9b Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 5 Jan 2016 11:55:15 +0200 Subject: Rename build directory/namespace to build2 --- build2/algorithm.txx | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 build2/algorithm.txx (limited to 'build2/algorithm.txx') diff --git a/build2/algorithm.txx b/build2/algorithm.txx new file mode 100644 index 0000000..7b0e498 --- /dev/null +++ b/build2/algorithm.txx @@ -0,0 +1,58 @@ +// file : build2/algorithm.txx -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +namespace build2 +{ + template + T* + execute_prerequisites (action a, target& t, const timestamp& mt) + { + //@@ Can factor the bulk of it into a non-template code. Can + // either do a function template that will do dynamic_cast check + // or can scan the target type info myself. I think latter. + // + bool e (mt == timestamp_nonexistent); + T* r (nullptr); + + for (target* pt: t.prerequisite_targets) + { + if (pt == nullptr) // Skip ignored. + continue; + + target_state ts (execute (a, *pt)); + + if (!e) + { + // If this is an mtime-based target, then compare timestamps. + // + if (auto mpt = dynamic_cast (pt)) + { + timestamp mp (mpt->mtime ()); + + // What do we do if timestamps are equal? This can happen, for + // example, on filesystems that don't have subsecond resolution. + // There is not much we can do here except detect the case where + // the prerequisite was changed in this run which means the + // action must be executed on the target as well. + // + if (mt < mp || (mt == mp && ts == target_state::changed)) + e = true; + } + else + { + // Otherwise we assume the prerequisite is newer if it was changed. + // + if (ts == target_state::changed) + e = true; + } + } + + if (T* tmp = dynamic_cast (pt)) + r = tmp; + } + + assert (r != nullptr); + return e ? r : nullptr; + } +} -- cgit v1.1