// file : build/algorithm.txx -*- C++ -*- // copyright : Copyright (c) 2014-2015 Code Synthesis Tools CC // license : MIT; see accompanying LICENSE file namespace build { 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. // T* r (nullptr); bool e (mt == timestamp_nonexistent); for (const prerequisite& p: t.prerequisites) { if (p.target == nullptr) // Skip ignored. continue; target& pt (*p.target); 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 (r == nullptr) r = dynamic_cast (&pt); } assert (r != nullptr); return e ? r : nullptr; } }