aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build2/algorithm.ixx4
-rw-r--r--build2/bin/rule.cxx6
-rw-r--r--build2/cc/common.cxx4
-rw-r--r--build2/cc/compile.cxx12
-rw-r--r--build2/cc/link.cxx26
-rw-r--r--build2/cc/msvc.cxx6
-rw-r--r--build2/cc/windows-rpath.cxx3
-rw-r--r--build2/cli/rule2
-rw-r--r--build2/cli/rule.cxx6
-rw-r--r--build2/install/rule.cxx11
-rw-r--r--build2/target43
-rw-r--r--build2/test/rule.cxx4
12 files changed, 67 insertions, 60 deletions
diff --git a/build2/algorithm.ixx b/build2/algorithm.ixx
index 0c171fd..b8c33d4 100644
--- a/build2/algorithm.ixx
+++ b/build2/algorithm.ixx
@@ -56,8 +56,8 @@ namespace build2
const string* ext,
const scope* scope)
{
- return static_cast<T&> (
- search (T::static_type, dir, out, name, ext, scope));
+ return search (
+ T::static_type, dir, out, name, ext, scope).template as<T> ();
}
pair<const rule*, match_result>
diff --git a/build2/bin/rule.cxx b/build2/bin/rule.cxx
index a73ad3d..9adb692 100644
--- a/build2/bin/rule.cxx
+++ b/build2/bin/rule.cxx
@@ -48,7 +48,7 @@ namespace build2
match_result lib_rule::
match (slock& ml, action act, target& xt, const string&) const
{
- lib& t (static_cast<lib&> (xt));
+ lib& t (xt.as<lib> ());
// @@ We have to re-query it on each match_only()!
@@ -104,7 +104,7 @@ namespace build2
recipe lib_rule::
apply (slock& ml, action act, target& xt) const
{
- lib& t (static_cast<lib&> (xt));
+ lib& t (xt.as<lib> ());
const match_data& md (t.data<match_data> ());
const string& type (md.type);
@@ -126,7 +126,7 @@ namespace build2
target_state lib_rule::
perform (action act, const target& xt)
{
- const lib& t (static_cast<const lib&> (xt));
+ const lib& t (xt.as<lib> ());
const match_data& md (t.data<match_data> ());
const string& type (md.type);
diff --git a/build2/cc/common.cxx b/build2/cc/common.cxx
index 654ff53..7b8499c 100644
--- a/build2/cc/common.cxx
+++ b/build2/cc/common.cxx
@@ -439,7 +439,7 @@ namespace build2
if (const lib* l = xt->is_a<lib> ())
xt = &link_member (*l, lo); // Pick liba{} or libs{}.
- return static_cast<const file&> (*xt);
+ return xt->as<file> ();
}
// Note that pk's scope should not be NULL (even if dir is absolute). If
@@ -563,7 +563,7 @@ namespace build2
trace));
assert (!exist || !p.second);
- r = static_cast<T*> (&p.first);
+ r = &p.first.template as<T> ();
};
auto search =[&a, &s,
diff --git a/build2/cc/compile.cxx b/build2/cc/compile.cxx
index 98d1218..5090f11 100644
--- a/build2/cc/compile.cxx
+++ b/build2/cc/compile.cxx
@@ -115,7 +115,7 @@ namespace build2
continue;
process_libraries (bs, lo, sys_lib_dirs,
- static_cast<const file&> (*pt), a,
+ pt->as<file> (), a,
nullptr, nullptr, optf);
}
}
@@ -155,7 +155,7 @@ namespace build2
continue;
process_libraries (bs, lo, sys_lib_dirs,
- static_cast<const file&> (*pt), a,
+ pt->as<file> (), a,
nullptr, nullptr, optf);
}
}
@@ -198,7 +198,7 @@ namespace build2
continue;
process_libraries (bs, lo, sys_lib_dirs,
- static_cast<const file&> (*pt), a,
+ pt->as<file> (), a,
nullptr, nullptr, optf);
}
}
@@ -208,7 +208,7 @@ namespace build2
{
tracer trace (x, "compile::apply");
- file& t (static_cast<file&> (xt));
+ file& t (xt.as<file> ());
const match_data& md (t.data<match_data> ());
const scope& bs (t.base_scope ());
@@ -1405,7 +1405,7 @@ namespace build2
target_state compile::
perform_update (action a, const target& xt) const
{
- const file& t (static_cast<const file&> (xt));
+ const file& t (xt.as<file> ());
// Update prerequisites and determine if any relevant ones render us
// out-of-date. Note that currently we treat all the prerequisites
@@ -1632,7 +1632,7 @@ namespace build2
target_state compile::
perform_clean (action a, const target& xt) const
{
- const file& t (static_cast<const file&> (xt));
+ const file& t (xt.as<file> ());
if (cid == "msvc")
return clean_extra (a, t, {".d", ".idb", ".pdb"});
diff --git a/build2/cc/link.cxx b/build2/cc/link.cxx
index 6c17037..2bdf8c1 100644
--- a/build2/cc/link.cxx
+++ b/build2/cc/link.cxx
@@ -297,7 +297,7 @@ namespace build2
lk = b;
append_ext (lk);
- libi& li (static_cast<libi&> (*ls.member));
+ libi& li (ls.member->as<libi> ());
lk = li.derive_path (move (lk), tsys == "mingw32" ? "a" : "lib");
}
else if (!v.empty ())
@@ -322,7 +322,7 @@ namespace build2
tracer trace (x, "link::apply");
- file& t (static_cast<file&> (xt));
+ file& t (xt.as<file> ());
const scope& bs (t.base_scope ());
const scope& rs (*bs.root_scope ());
@@ -341,7 +341,7 @@ namespace build2
else
t.member = &search (tt, t.dir, t.out, t.name, nullptr, nullptr);
- file& r (static_cast<file&> (*t.member));
+ file& r (t.member->as<file> ());
r.recipe (a, group_recipe);
return r;
};
@@ -541,7 +541,7 @@ namespace build2
//
if (group)
{
- obj& o (static_cast<obj&> (ot));
+ obj& o (ot.as<obj> ());
switch (lt)
{
@@ -680,7 +680,7 @@ namespace build2
// (see search_library() for details).
//
if (win && f->member != nullptr && f->is_a<libs> ())
- f = static_cast<const file*> (f->member.get ());
+ f = &f->member->as<file> ();
args.push_back (relative (f->path ()).string ());
}
@@ -727,7 +727,7 @@ namespace build2
// (see search_library() for details).
//
if (win && f->member != nullptr && f->is_a<libs> ())
- f = static_cast<const file*> (f->member.get ());
+ f = &f->member->as<file> ();
cs.append (f->path ().string ());
}
@@ -893,11 +893,11 @@ namespace build2
{
tracer trace (x, "link::perform_update");
+ const file& t (xt.as<file> ());
+
auto oop (a.outer_operation ());
bool for_install (oop == install_id || oop == uninstall_id);
- const file& t (static_cast<const file&> (xt));
-
const scope& bs (t.base_scope ());
const scope& rs (*bs.root_scope ());
@@ -1369,7 +1369,7 @@ namespace build2
// derived from the import library by changing the extension.
// Lucky for us -- there is no option to name it.
//
- auto& imp (static_cast<const file&> (*t.member));
+ auto& imp (t.member->as<file> ());
out2 = "/IMPLIB:" + relative (imp.path ()).string ();
args.push_back (out2.c_str ());
}
@@ -1379,9 +1379,9 @@ namespace build2
//
if (find_option ("/DEBUG", args, true))
{
+
auto& pdb (
- static_cast<const file&> (
- lt == otype::e ? *t.member : *t.member->member));
+ (lt == otype::e ? t.member : t.member->member)->as<file> ());
out1 = "/PDB:" + relative (pdb.path ()).string ();
args.push_back (out1.c_str ());
}
@@ -1415,7 +1415,7 @@ namespace build2
// On Windows libs{} is the DLL and its first ad hoc group
// member is the import library.
//
- auto& imp (static_cast<const file&> (*t.member));
+ auto& imp (t.member->as<file> ());
out = "-Wl,--out-implib=" + relative (imp.path ()).string ();
args.push_back (out.c_str ());
}
@@ -1629,7 +1629,7 @@ namespace build2
target_state link::
perform_clean (action a, const target& xt) const
{
- const file& t (static_cast<const file&> (xt));
+ const file& t (xt.as<file> ());
switch (link_type (t))
{
diff --git a/build2/cc/msvc.cxx b/build2/cc/msvc.cxx
index 86a7d38..94064ca 100644
--- a/build2/cc/msvc.cxx
+++ b/build2/cc/msvc.cxx
@@ -69,7 +69,7 @@ namespace build2
//
if (lt == otype::s && l.compare (0, 3, " ") == 0)
{
- path imp (static_cast<const file&> (*t.member).path ().leaf ());
+ path imp (t.member->as<file> ().path ().leaf ());
if (l.find (imp.string ()) != string::npos &&
l.find (imp.base ().string () + ".exp") != string::npos)
@@ -276,7 +276,7 @@ namespace build2
true, // Implied.
trace));
assert (!exist || !p.second);
- T& t (static_cast<T&> (p.first));
+ T& t (p.first.template as<T> ());
if (t.path ().empty ())
t.path (move (f));
@@ -340,7 +340,7 @@ namespace build2
true, // Implied.
trace));
assert (!exist || !p.second);
- r = static_cast<libs*> (&p.first);
+ r = &p.first.as<libs> ();
if (r->member == nullptr)
{
diff --git a/build2/cc/windows-rpath.cxx b/build2/cc/windows-rpath.cxx
index 94b1145..46a3d3a 100644
--- a/build2/cc/windows-rpath.cxx
+++ b/build2/cc/windows-rpath.cxx
@@ -137,8 +137,7 @@ namespace build2
//
const string* pdb (
l->member != nullptr && l->member->member != nullptr
- ? &static_cast<const file&> (
- *l->member->member).path ().string ()
+ ? &l->member->member->as<file> ().path ().string ()
: nullptr);
r.insert (windows_dll {f, pdb, string ()});
diff --git a/build2/cli/rule b/build2/cli/rule
index 1fbbde4..03fd471 100644
--- a/build2/cli/rule
+++ b/build2/cli/rule
@@ -14,6 +14,8 @@ namespace build2
{
namespace cli
{
+ // @@ Redo as two separate rules?
+ //
class compile: public rule
{
public:
diff --git a/build2/cli/rule.cxx b/build2/cli/rule.cxx
index 5dcec99..7928c5c 100644
--- a/build2/cli/rule.cxx
+++ b/build2/cli/rule.cxx
@@ -199,7 +199,7 @@ namespace build2
}
else
{
- cli_cxx& g (static_cast<cli_cxx&> (*xt.group));
+ cli_cxx& g (xt.group->as<cli_cxx> ());
build2::match (ml, a, g);
return group_recipe; // Execute the group's recipe.
}
@@ -230,7 +230,7 @@ namespace build2
target_state compile::
perform_update (action a, const target& xt)
{
- const cli_cxx& t (static_cast<const cli_cxx&> (xt));
+ const cli_cxx& t (xt.as<cli_cxx> ());
// Update prerequisites and determine if any relevant ones render us
// out-of-date. Note that currently we treat all the prerequisites
@@ -322,7 +322,7 @@ namespace build2
target_state compile::
perform_clean (action a, const target& xt)
{
- const cli_cxx& t (static_cast<const cli_cxx&> (xt));
+ const cli_cxx& t (xt.as<cli_cxx> ());
// The reverse order of update: first delete the files, then clean
// prerequisites. Also update timestamp in case there are operations
diff --git a/build2/install/rule.cxx b/build2/install/rule.cxx
index 3be7eef..3a5bd3d 100644
--- a/build2/install/rule.cxx
+++ b/build2/install/rule.cxx
@@ -614,7 +614,7 @@ namespace build2
target_state file_rule::
perform_install (action a, const target& xt) const
{
- const file& t (static_cast<const file&> (xt));
+ const file& t (xt.as<file> ());
assert (!t.path ().empty ()); // Should have been assigned by update.
auto install_target = [this] (const file& t, const path& p, bool verbose)
@@ -663,7 +663,7 @@ namespace build2
for (const target* m (t.member); m != nullptr; m = m->member)
{
if (const path* p = lookup_install<path> (*m, "install"))
- install_target (static_cast<const file&> (*m), *p, false);
+ install_target (m->as<file> (), *p, false);
}
// Finally install the target itself (since we got here we know the
@@ -872,7 +872,7 @@ namespace build2
target_state file_rule::
perform_uninstall (action a, const target& xt) const
{
- const file& t (static_cast<const file&> (xt));
+ const file& t (xt.as<file> ());
assert (!t.path ().empty ()); // Should have been assigned by update.
auto uninstall_target = [this] (
@@ -930,9 +930,8 @@ namespace build2
for (const target* m (t.member); m != nullptr; m = m->member)
{
if (const path* p = lookup_install<path> (*m, "install"))
- r |= uninstall_target (static_cast<const file&> (*m),
- *p,
- r != target_state::changed);
+ r |= uninstall_target (
+ m->as<file> (), *p, r != target_state::changed);
}
// Finally handle installable prerequisites.
diff --git a/build2/target b/build2/target
index 2eb6a2c..48c80e7 100644
--- a/build2/target
+++ b/build2/target
@@ -112,8 +112,6 @@ namespace build2
optional<string>* ext_; // Reference to value in target_key.
public:
- using action_type = build2::action;
-
// For targets that are in the src tree of a project we also keep the
// corresponding out directory. As a result we may end up with multiple
// targets for the same file if we are building multiple configurations of
@@ -240,6 +238,8 @@ namespace build2
}
public:
+ using action_type = build2::action;
+
// Reset the target before matching it to a rule. The default
// implementation clears the auxilary data and prerequisite_targets.
//
@@ -540,9 +540,12 @@ namespace build2
private:
recipe_type recipe_;
- // Target type info.
+ // Target type info and casting.
//
public:
+ bool
+ is_a (const target_type& tt) const {return type ().is_a (tt);}
+
template <typename T>
T*
is_a () {return dynamic_cast<T*> (this);}
@@ -551,8 +554,15 @@ namespace build2
const T*
is_a () const {return dynamic_cast<const T*> (this);}
- bool
- is_a (const target_type& tt) const {return type ().is_a (tt);}
+ // Unchecked cast.
+ //
+ template <typename T>
+ T&
+ as () {return static_cast<T&> (*this);}
+
+ template <typename T>
+ const T&
+ as () const {return static_cast<const T&> (*this);}
// Dynamic derivation to support define.
//
@@ -1074,14 +1084,13 @@ namespace build2
optional<string> ext,
tracer& t)
{
- return static_cast<T&> (
- insert (tt,
- move (dir),
- move (out),
- move (name),
- move (ext),
- true,
- t).first);
+ return insert (tt,
+ move (dir),
+ move (out),
+ move (name),
+ move (ext),
+ true,
+ t).first.template as<T> ();
}
template <typename T>
@@ -1092,8 +1101,7 @@ namespace build2
const optional<string>& ext,
tracer& t)
{
- return static_cast<T&> (
- insert (T::static_type, dir, out, name, ext, true, t).first);
+ return insert<T> (T::static_type, dir, out, name, ext, t);
}
template <typename T>
@@ -1103,8 +1111,7 @@ namespace build2
const string& name,
tracer& t)
{
- return static_cast<T&> (
- insert (T::static_type, dir, out, name, nullopt, true, t).first);
+ return insert<T> (dir, out, name, nullopt, t);
}
// Note: not MT-safe so can only be used during serial execution.
@@ -1149,7 +1156,7 @@ namespace build2
mtime (bool load = true) const
{
const mtime_target& t (state_ == target_state::group
- ? static_cast<const mtime_target&> (*group)
+ ? group->as<mtime_target> ()
: *this);
if (load && t.mtime_ == timestamp_unknown)
diff --git a/build2/test/rule.cxx b/build2/test/rule.cxx
index 38c24f9..35302e1 100644
--- a/build2/test/rule.cxx
+++ b/build2/test/rule.cxx
@@ -640,7 +640,7 @@ namespace build2
auto& pts (tt.prerequisite_targets);
if (pts.size () != 0 && pts[0] != nullptr)
{
- const file& it (static_cast<const file&> (*pts[0]));
+ const file& it (pts[0]->as<file> ());
assert (!it.path ().empty ()); // Should have been assigned by update.
args.push_back (it.path ().string ().c_str ());
}
@@ -660,7 +660,7 @@ namespace build2
process_path dpp;
if (pts.size () != 0 && pts[1] != nullptr)
{
- const file& ot (static_cast<const file&> (*pts[1]));
+ const file& ot (pts[1]->as<file> ());
assert (!ot.path ().empty ()); // Should have been assigned by update.
dpp = run_search (dp, true);